# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
bl_info = {
"name": "Particles animation",
"author": "Leonid Desyatkov",
"version": (1,0,0),
"blender": (2, 76, 0),
"location": "Particles prop / Cache",
"description": "Particles dupli objects animation (size and rotate)",
"category": "Particles"}
import bpy
from bpy.types import Operator
from bpy.app.handlers import persistent
from math import degrees
import os
class PARTICLE_OT_bake_transform(Operator):
bl_idname = "particle.duplianimbake"
bl_label = "Bake duplis transform"
def execute(self, context):
scene = context.scene
ob = context.object
fs=scene.frame_start
fc=scene.frame_current
fe=scene.frame_end
if ob.particle_systems:
pSys = ob.particle_systems.active
pSysName = ob.name+pSys.name
parts = pSys.particles
lifetime = int(pSys.settings.lifetime)
dobject=pSys.settings.dupli_object
alives = {}
for k,v in enumerate(parts):
alives[k]=0
transes = []
for i in range(1,lifetime+2):
scene.frame_set(i, 0.0)
dmatrix=dobject.matrix_world
scale = dmatrix.to_scale()[:]
rotate = tuple([e for e in dmatrix.to_3x3().to_euler()])
transes.append((scale[0],scale[1],scale[2],rotate[0],rotate[1],rotate[2]))
for i in range(fs,fe):
scene.frame_set(i, 0.0)
bakeFile = open("/tmp/%s%s.bda"%(pSysName,i),"w")
for k,v in enumerate(parts):
if v.alive_state == 'ALIVE':
alives[k] += 1
for key in alives:
sx,sy,sz,rx,ry,rz = transes[alives[key]][:]
bakeFile.write('%s %.6f %.6f %.6f %.6f %.6f %.6f\n'%(key,sx,sy,sz,rx,ry,rz))
bakeFile.close()
scene.frame_set(fc, 0.0)
return {'FINISHED'}
@persistent
def particles_transform(dummy):
scene = bpy.context.scene
fc=str(scene.frame_current)
for ob in scene.objects:
if ob.type == 'MESH' and ob.particle_systems:
for pSys in ob.particle_systems:
fileName = ob.name+pSys.name+fc
if os.path.exists("/tmp/%s.bda"%fileName):
for line in open("/tmp/%s.bda"%fileName):
s=line.split()
n,sx,sy,sz,rx,ry,rz=s[:]
pSys.particles[int(n)].size = (float(sx))
pSys.particles[int(n)].rotation = (float(rx),float(ry),float(rz),0)
bpy.app.handlers.frame_change_pre.append(particles_transform)
def menu_func(self, context):
self.layout.operator("particle.duplianimbake")
def register():
bpy.types.PARTICLE_PT_cache.append(menu_func)
bpy.utils.register_module(__name__)
def unregister():
bpy.types.PARTICLE_PT_cache.remove(menu_func)
bpy.utils.unregister_module(__name__)
if __name__ == "__main__":
register()
Принцип действия таков: