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

图1 下载的案例文件

该案例中粒子动画过程如下图2:

图2 案例动画效果

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

 #Boids for Py4D by smart-page.netimport c4dimport mathimport random#environmentminx = -2000maxx = 2000miny = 1000maxy = 3000minz = -2000maxz = 2000#boids paramsboids_number    = 100target_maxspeed = 60boid_maxspeed   = 50boid_distance   = 200frame = Nonerand = Nonetarget = c4d.Vector()targetvec = c4d.Vector(0)bpos = Nonebvel = Nonedef main():global tpglobal docglobal frameglobal bposglobal bvelframe = 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 +=xv = 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:continuev += boid_pos - b_posv /= len(tp.GetParticles())return (bvel[c] -v) / 100def rule2(c):d = 0k = 0for i, b_pos in enumerate(bpos):if (b_pos - bpos[c]).GetLength() < boid_distance:k += 1pos = bpos[c]dif = (pos - b_pos)if dif.GetLength() >= 0: dif = math.sqrt(boid_distance) - difelif dif.GetLength() < 0: dif = -math.sqrt(boid_distance) - difd += dif if k == 0: returnreturn bvel[c] - d / 4def rule3(c):v = c4d.Vector()for i in bpos:v += bvel[c]v /= len(tp.GetParticles())return bvel[c] + v / 30def rule4(c):return (target - bpos[c]) / 100def movetarget():global targetglobal targetvecrand = random.Random(1)rand.seed(frame) if target.x < minx or target.y < miny or target.z < minz: targetvec.x += rand.random() * target_maxspeedtargetvec.y += rand.random() * target_maxspeedtargetvec.z += rand.random() * target_maxspeedif target.x > maxx or target.y > maxy or target.z > maxz:targetvec.x -= rand.random() * target_maxspeedtargetvec.y -= rand.random() * target_maxspeedtargetvec.z -= rand.random() * target_maxspeedtargetvec = limitspeed(targetvec, target_maxspeed)target += targetvecdef limitspeed(v, speed):if v.GetLength() > speed:v = v*(speed / v.GetLength())return v

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

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

# Boids for Py4D by smart-page.netimport 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 tpglobal docglobal 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 = 0i=1for 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=1for 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 ivel = 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:

图4 添加的外部文件

具体添加过程如下:
1)选中python标签,如下图所示。

2)然后,进入用户数据管理器,如下图所示。

3)接着,增加一个data,如下图所示。

4)在数据类型(Data Type)中选择“Filename”,如下图所示。

5)保存。然后,去选择电脑上txt文件。如下图所示。

6)最关键一步,鼠标左键按住托动data到python脚本中,将数据赋给一个变量。如下图中所示,外部数据源赋给了变量filename。

7)最后,渲染的结果展示。
用昆虫构成快速奔跑的马:

昆虫构成猛犸象:

昆虫构成鲨鱼

终于发表了论文(欢迎引用,谢谢):
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. 希望对相关人员有帮助。

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

  1. python导入处理txt文件-python读取大文件踩过的坑——读取txt文件词向量

    在读取https://github.com/Embedding/Chinese-Word-Vectors中的中文词向量时,选择了一个有3G多的txt文件,之前在做词向量时用的是word2vec,所以直 ...

  2. python导入处理txt文件-python怎么处理txt

    ·导入文件处理模块import os ·检测路径是否存在,存在则返回True,不存在则返回Falseos.path.exists("demo.txt") ·如果你要创建一个文件并要 ...

  3. python怎么导入txt_(python文件转excle)python如何将txt文件导入excel

    python 怎么把excel转成pdf 推荐的方法都是的: 方法一:使用虚拟打印机pdf factory,而且其他文件只要是能印,选择这个虚拟打印机,都可以做成PDF文件,很简单实用: 方法二:使用 ...

  4. python导入txt文件并绘图-Python实现读取txt文件中的数据并绘制出图形操作示例

    本文实例讲述了Python实现读取txt文件中的数据并绘制出图形操作.分享给大家供大家参考,具体如下: 下面的是某一文本文件中的数据. 6.1101,17.592 5.5277,9.1302 8.51 ...

  5. python导入txt文件并绘图-Python实现读取txt文件并画三维图简单代码示例

    记忆力差的孩子得勤做笔记! 刚接触python,最近又需要画一个三维图,然后就找了一大堆资料,看的人头昏脑胀的,今天终于解决了!好了,废话不多说,直接上代码! #由三个一维坐标画三维散点 #codin ...

  6. python导入外部包_您会喜欢的10个外部Python软件包

    python导入外部包 by Adam Goldschmidt 亚当·戈德施密特(Adam Goldschmidt) 您会喜欢的10个外部Python软件包 (10 External Python p ...

  7. python怎么读取sav格式_利用Python读取外部数据文件

    利用Python读取外部数据文件 [color=rgb(0, 0, 0) !important]刘顺祥 [color=rgb(0, 0, 0) !important]摘要: 不论是数据分析,数据可视化 ...

  8. python读取所有txt文件_python如何批量读取txt文件

    python批量读取txt文件的方法:首先导入系统模块:然后将文件夹路径更改为需要批量读取的txt文件存放的路径:再调用系统模块得到该文件夹下的所有文件名称:最后遍历文件夹,读取txt文件. 如果文件 ...

  9. 怎么退出python命令行cd找到txt文档_《python怎么读取txt文件》

    python怎么创建一个txt文件 python怎么创建txt文件的方法. 如下参考: 1.首用内置的空闲编辑器编辑(单击并选择copy),如下图所示. 2.您可以下载记事本和其他编辑软件,以支持多种 ...

  10. Struts2中导入外部xml文件出现Included file cannot be found错误!

    Struts.xml 文件中导入外部xml文件,需要在Struts.xml文件中加入include元素. ch3.xml文件位于ch3目录中.ch3.xml是一个标准的Struts2配置文件 路径千万 ...

最新文章

  1. 腾讯提结合ACNet进行细粒度分类,效果达到最新SOTA | CVPR 2020
  2. 技术详解 | 如何用GAN实现阴影检测和阴影去除?
  3. [Linux学习]Linux下进程通讯之共享内存
  4. jquery之empty()与remove([expr])区别
  5. win32汇编系统函数简单小示例图解
  6. php 接口日志,PHP 开发 APP 接口--错误日志接口
  7. Error: Cannot create file “D:xampp\xampp-controlin“.拒绝访问。
  8. HTML|CSS之布局相关总结
  9. charles iPhone抓包步骤 Fiddler
  10. 4.1 API : MultinomialNB、GaussianNB、BernoulliNB
  11. oracle异常:主动抛出自定义异常+捕获指定异常
  12. Luogu P1967 货车运输 倍增+最大生成树
  13. 理解数据类型与数学运算:摄氏温度与华氏温度的相互转换
  14. UNIX网络编程卷一 学习笔记 第一章 简介
  15. 计算机无法安装新字体,如何解决XP系统中无法安装新字体
  16. 信息技术 用计算机做科学实验报告,8.用计算机做科学实验.doc
  17. matlab 求矩阵各行的平均值
  18. 安装oracle提示javaw,为什么oracle 9i 安装时,setup exe javaw exe进程消失
  19. 推推:产品的规划和商业化分析
  20. django账户管理系统admin

热门文章

  1. uni-app入门到项目实战
  2. 关于面试总结6-SQL经典面试题
  3. OSEK标准ISO_17356汇总介绍
  4. 金融大数据风控建模实战(一)智能风控背景
  5. MATLAB 排序函数(先按第一列排序(主排序)然后再按第二列排序(次排序))
  6. Gromacs动力学模拟
  7. 操作系统之多道程序设计
  8. 端到端无人驾驶文献学习:ChauffeurNet: Learning to Drive by Imitating the Best and Synthesizing the Worst
  9. 过滤器(Filter)与拦截器(Interceptor )区别
  10. 带经纬度的水印相机_经纬度生成小工具(仿水印相机)