Hey, new to blender, a brilliant script by Jasper van Nieuwenhuizen converts each frame of a particle system into mesh instances that are animated based on the loc/rot/scale of the original particle system.
I’m trying to modify his code to apply to my hair particle system that uses objects as strands.
I can’t get his code to keyframe the loc/rot/scale of the hair particles properly to my meshes.
What particle information am I getting wrong?
Individual meshes are generating fine, keyframes are being generated for each frame, but the rotation, location and scale are wrong… AND, the animated loc/rot/scale of the mesh isn’t changing to match the baked loc/rot/scale changes of the hair/particles (or, is there already a feature that converts baked hair particles into ANIMATED meshes inside of blender that I’m unaware of?)
The code works by selecting the proxy object first, and then selecting the particle system second (so that it is active).
import bpy
def create_objects_for_particles(ps, obj):
# Duplicate the given object for every particle and return the duplicates.
# Use instances instead of full copies.
obj_list = []
mesh = obj.data
for i, _ in enumerate(ps.particles):
dupli = bpy.data.objects.new(
name="particle.{:03d}".format(i),
object_data=mesh)
bpy.context.scene.objects.link(dupli)
obj_list.append(dupli)
return obj_list
def match_and_keyframe_objects(ps, obj_list, start_frame, end_frame):
# Match and keyframe the objects to the particles for every frame in the
# given range.
for frame in range(start_frame, end_frame + 1):
bpy.context.scene.frame_set(frame)
for p, obj in zip(ps.particles, obj_list):
match_object_to_particle(p, obj)
keyframe_obj(obj)
def match_object_to_particle(p, obj):
# Match the location, rotation, scale and visibility of the object to
# the particle.
loc = p.location
rot = p.rotation
size = p.size
vis = True
obj.location = loc
# Set rotation mode to quaternion to match particle rotation.
obj.rotation_mode = 'QUATERNION'
obj.rotation_quaternion = rot
obj.scale = (size, size, size)
obj.hide = False
obj.hide_render = False
def keyframe_obj(obj):
# Keyframe location, rotation, scale and visibility if specified.
obj.keyframe_insert("location")
obj.keyframe_insert("rotation_quaternion")
obj.keyframe_insert("scale")
def main():
# Assume only 2 objects are selected.
# The active object should be the one with the particle system.
ps_obj = bpy.context.object
obj = [obj for obj in bpy.context.selected_objects if obj != ps_obj][0]
ps = ps_obj.particle_systems[0] # Assume only 1 particle system is present.
start_frame = bpy.context.scene.frame_start
end_frame = bpy.context.scene.frame_end
obj_list = create_objects_for_particles(ps, obj)
match_and_keyframe_objects(ps, obj_list, start_frame, end_frame)
if __name__ == '__main__':
main()
I believe that the hair matrix information is in the {co}, but I’m wondering how to integrate that information back into loc/rot/scale coordinates for meshes like the code found above.
import bpy
object = bpy.context.object
hairs = object.particle_systems[0].particles
for i, h in enumerate(hairs):
print('hair number {i}:'.format(i=i))
for i, hv in enumerate(h.hair_keys):
print(' vertex {i} coordinates: {co}'.format(i=i, co=hv.co))
Thanks guys, I’m not sure where stuff like this is found in the blender wiki.
(I’m trying to attach a sample file but having trouble with the baked 100MB .blend upload at the moment… so you can try here, if I’m allowed to use outside links: https://drive.google.com/file/d/0Bz5b6wnIua9EUExIclJRRmJ0djA/view?usp=sharing )