热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C4D通过python导入外部.txt文件数据驱动物体

最近做了一个粒子动画,需要把关键帧数据导入C4D中去渲染。国内不好找这方面的资源,有点资源也收费,希望这个工作对相关人员有帮助。根据C4D官方网发布的SDK案例URL(https:

最近做了一个粒子动画,需要把关键帧数据导入C4D中去渲染。国内不好找这方面的资源,有点资源也收费,希望这个工作对相关人员有帮助。根据C4D官方网发布的SDK案例 URL(https://github.com/PluginCafe/cinema4d_py_sdk/tree/824760b6aa2e6405f17b92a128ddba4f3c43ea70))。参照其中有一个做了一个导入关键帧动画数据,用python脚本导入非常方便。该案例如下图1所示:
《C4D 通过python导入外部.txt文件数据驱动物体》
图1 下载的案例文件

该案例中粒子动画过程如下图2:
《C4D 通过python导入外部.txt文件数据驱动物体》
图2 案例动画效果

该案例中,粒子的坐标与方向是在python中写好函数生成, 其python脚本如下Code1:
code 1:

#Boids for Py4D by smart-page.net
import c4d
import math
import random

#environment
minx = -2000
maxx = 2000
miny = 1000
maxy = 3000
minz = -2000
maxz = 2000

#boids params
boids_number = 100
target_maxspeed = 60
boid_maxspeed = 50
boid_distance = 200

frame = None
rand = None
target = c4d.Vector()
targetvec = c4d.Vector(0)

bpos = None
bvel = None

def main():
global tp
global doc
global frame
global bpos
global bvel

frame = doc.GetTime().GetFrame(doc.GetFps())
if frame==0:
tp.FreeAllParticles()
tp.AllocParticles(boids_number)

lt = c4d.BaseTime(1000)

bpos = []
bvel = []

for i in tp.GetParticles():
tp.SetLife(i, lt)

bpos.append(tp.Position(i))
bvel.append(tp.Velocity(i))

moveboids(i)

set_target()
movetarget()


def set_target():

v = c4d.Vector()

for x in bpos:
v +=x

v = v / len(tp.GetParticles())

op[c4d.ID_USERDATA, 1].SetRelPos(v) def moveboids(c):

bvel[c] += rule1(c) + rule2(c) + rule3(c) + rule4(c)
bvel[c] = limitspeed(bvel[c], boid_maxspeed)

tp.SetVelocity(c, bvel[c])

vel=bvel[c].GetNormalized()

side = c4d.Vector(c4d.Vector(0,1,0).Cross(vel)).GetNormalized()
up = vel.Cross(side)
m = c4d.Matrix(c4d.Vector(0), side, up, vel)

tp.SetAlignment(c, m)
tp.SetPosition(c, bpos[c] + bvel[c])


def rule1(c):

v = c4d.Vector()

for i, b_pos in enumerate(bpos):
boid_pos = bpos[c]

if b_pos == boid_pos:
continue

v += boid_pos - b_pos

v /= len(tp.GetParticles())

return (bvel[c] -v) / 100


def rule2(c):

d = 0
k = 0

for i, b_pos in enumerate(bpos):
if (b_pos - bpos[c]).GetLength() k += 1
pos = bpos[c]
dif = (pos - b_pos)

if dif.GetLength() >= 0:
dif = math.sqrt(boid_distance) - dif
elif dif.GetLength() <0:
dif = -math.sqrt(boid_distance) - dif

d += dif

if k == 0: return

return bvel[c] - d / 4


def rule3(c):

v = c4d.Vector()

for i in bpos:
v += bvel[c]

v /= len(tp.GetParticles())

return bvel[c] + v / 30


def rule4(c):

return (target - bpos[c]) / 100


def movetarget():

global target
global targetvec

rand = random.Random(1)
rand.seed(frame)

if target.x targetvec.x += rand.random() * target_maxspeed
targetvec.y += rand.random() * target_maxspeed
targetvec.z += rand.random() * target_maxspeed

if target.x > maxx or target.y > maxy or target.z > maxz:
targetvec.x -= rand.random() * target_maxspeed
targetvec.y -= rand.random() * target_maxspeed
targetvec.z -= rand.random() * target_maxspeed

targetvec = limitspeed(targetvec, target_maxspeed)

target += targetvec


def limitspeed(v, speed):

if v.GetLength() > speed:
v = v*(speed / v.GetLength())

return v

当然我不需要这些函数,粒子的位置与方向数据从外部txt文件导入。我的数据已经通过opengl计算好,记录成文本文件。文件格式内容示例如下图3所示:
《C4D 通过python导入外部.txt文件数据驱动物体》图3 外部数据

图3中每一帧中有多行数据,每一帧的第一行是提示文字用来表示第几帧,后续每一行数据赋给一个粒子。一行数据有6个,前3个为坐标、后3个为方向。现在只需将文件导入,并分析出每一帧中的数据,将每一帧中每一行数据分别赋给粒子。将案例中的代码修改,并得到下面的示例代码Code2:
code 2:

# Boids for Py4D by smart-page.net
import c4d
import math
import random
# boids params
boids_number = 100 #粒子数量
currentframe = None #当前动画帧
frame_step = boids_number+1 #导入的文件中每一帧的数据,+1是把"frameX"这一行也算上
frame_total = 0
def main():
global tp
global doc
global currentframe
currentframe = doc.GetTime().GetFrame(doc.GetFps()) #获取当前帧
if currentframe == 0:
tp.FreeAllParticles()
tp.AllocParticles(boids_number) #生成粒子
lt = c4d.BaseTime(1000) #粒子的生命
filename = op[c4d.ID_USERDATA, 2] #读入的数据,本文后面解释如何添加该数据
with open(filename, 'r') as fn: # 分析打开的外部文件
lines = fn.readlines()
frame_total = int(len(lines) / frame_step)
frame = 0
i=1
for frame in range(frame_total):
if frame == currentframe:
t_lines = lines[frame * frame_step:frame * frame_step + frame_step - 1] #以frame_step为步长提取每一帧的数据。或许还有更好的方法,暂时没去优化。
if i == tp.GetParticles():
i=1
for line in t_lines:
if line == t_lines[0]: #将每一帧的第一行提示文字过滤掉。
print(line)
continue
else:
x, y, z, dx, dy, dz = line.split()
#print(x, y, z, dx, dy, dz)
pos = c4d.Vector(float(x), float(y) , float(z)) #粒子的坐标
vol = c4d.Vector(float(dx) , float(dy), float(dz) ) #粒子的方向

tp.SetLife(i, lt) # set life time for particle i

vel = vol.GetNormalized() #下面几行是将方向向量作用到粒子
side = c4d.Vector(c4d.Vector(0, 1, 0).Cross(vel)).GetNormalized()
up = vel.Cross(side)
m = c4d.Matrix(c4d.Vector(0), side, up, vel)
tp.SetAlignment(i, m)

tp.SetPosition(i,pos) # set postion(x,y,z)
#tp.SetVelocity(i,vol)
i=i+1
c4d.EventAdd()
if __name__=='__main__':
main()

文件导入时只需在C4D中添加文件,如下图4:
《C4D 通过python导入外部.txt文件数据驱动物体》
图4 添加的外部文件

具体添加过程如下:
1)选中python标签,如下图所示。
《C4D 通过python导入外部.txt文件数据驱动物体》
2)然后,进入用户数据管理器,如下图所示。
《C4D 通过python导入外部.txt文件数据驱动物体》

3)接着,增加一个data,如下图所示。
《C4D 通过python导入外部.txt文件数据驱动物体》
4)在数据类型(Data Type)中选择“Filename”,如下图所示。
《C4D 通过python导入外部.txt文件数据驱动物体》
5)保存。然后,去选择电脑上txt文件。如下图所示。
《C4D 通过python导入外部.txt文件数据驱动物体》
6)最关键一步,鼠标左键按住托动data到python脚本中,将数据赋给一个变量。如下图中所示,外部数据源赋给了变量filename。
《C4D 通过python导入外部.txt文件数据驱动物体》
7)最后,渲染的结果展示。
用昆虫构成快速奔跑的马:
《C4D 通过python导入外部.txt文件数据驱动物体》
昆虫构成猛犸象:
《C4D 通过python导入外部.txt文件数据驱动物体》
昆虫构成鲨鱼
《C4D 通过python导入外部.txt文件数据驱动物体》
终于发表了论文(欢迎引用,谢谢):
Chen Q, Luo G, Tong Y, et al. Shape‐constrained flying insects animation[J]. Computer Animation and Virtual Worlds, 2019: e1902.
论文DEMO:https://www.youtube.com/watch?v=4SfVb3ZEQAw

C4D 开发人员支持文档URL(Python: https://developers.maxon.net/docs/Cinema4DPythonSDK/html/index.html)。

TP particle 开发文档参见:https://public.niklasrosenstein.com/cinema4d/docs/python/R13.058/modules/c4d.modules/thinkingparticles/TP_MasterSystem/index.html。

That’s all. 希望对相关人员有帮助。


推荐阅读
  • 超级简单加解密工具的方案和功能
    本文介绍了一个超级简单的加解密工具的方案和功能。该工具可以读取文件头,并根据特定长度进行加密,加密后将加密部分写入源文件。同时,该工具也支持解密操作。加密和解密过程是可逆的。本文还提到了一些相关的功能和使用方法,并给出了Python代码示例。 ... [详细]
  • 十大经典排序算法动图演示+Python实现
    本文介绍了十大经典排序算法的原理、演示和Python实现。排序算法分为内部排序和外部排序,常见的内部排序算法有插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。文章还解释了时间复杂度和稳定性的概念,并提供了相关的名词解释。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 无损压缩算法专题——LZSS算法实现
    本文介绍了基于无损压缩算法专题的LZSS算法实现。通过Python和C两种语言的代码实现了对任意文件的压缩和解压功能。详细介绍了LZSS算法的原理和实现过程,以及代码中的注释。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
  • 浏览器中的异常检测算法及其在深度学习中的应用
    本文介绍了在浏览器中进行异常检测的算法,包括统计学方法和机器学习方法,并探讨了异常检测在深度学习中的应用。异常检测在金融领域的信用卡欺诈、企业安全领域的非法入侵、IT运维中的设备维护时间点预测等方面具有广泛的应用。通过使用TensorFlow.js进行异常检测,可以实现对单变量和多变量异常的检测。统计学方法通过估计数据的分布概率来计算数据点的异常概率,而机器学习方法则通过训练数据来建立异常检测模型。 ... [详细]
  • 预备知识可参考我整理的博客Windows编程之线程:https:www.cnblogs.comZhuSenlinp16662075.htmlWindows编程之线程同步:https ... [详细]
  • 开源Keras Faster RCNN模型介绍及代码结构解析
    本文介绍了开源Keras Faster RCNN模型的环境需求和代码结构,包括FasterRCNN源码解析、RPN与classifier定义、data_generators.py文件的功能以及损失计算。同时提供了该模型的开源地址和安装所需的库。 ... [详细]
  • Python使用Pillow包生成验证码图片的方法
    本文介绍了使用Python中的Pillow包生成验证码图片的方法。通过随机生成数字和符号,并添加干扰象素,生成一幅验证码图片。需要配置好Python环境,并安装Pillow库。代码实现包括导入Pillow包和随机模块,定义随机生成字母、数字和字体颜色的函数。 ... [详细]
  • STL迭代器的种类及其功能介绍
    本文介绍了标准模板库(STL)定义的五种迭代器的种类和功能。通过图表展示了这几种迭代器之间的关系,并详细描述了各个迭代器的功能和使用方法。其中,输入迭代器用于从容器中读取元素,输出迭代器用于向容器中写入元素,正向迭代器是输入迭代器和输出迭代器的组合。本文的目的是帮助读者更好地理解STL迭代器的使用方法和特点。 ... [详细]
  • 本文介绍了安全性要求高的真正密码随机数生成器的概念和原理。首先解释了统计学意义上的伪随机数和真随机数的区别,以及伪随机数在密码学安全中的应用。然后讨论了真随机数的定义和产生方法,并指出了实际情况下真随机数的不可预测性和复杂性。最后介绍了随机数生成器的概念和方法。 ... [详细]
  • Python的参数解析argparse模块的学习
    本文介绍了Python中参数解析的重要模块argparse的学习内容。包括位置参数和可选参数的定义和使用方式,以及add_argument()函数的详细参数关键字解释。同时还介绍了命令行参数的操作和可接受数量的设置,其中包括整数类型的参数。通过学习本文内容,可以更好地理解和使用argparse模块进行参数解析。 ... [详细]
  • Python教学练习二Python1-12练习二一、判断季节用户输入月份,判断这个月是哪个季节?3,4,5月----春 ... [详细]
author-avatar
多米音乐_34473808
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有