Question (again, sorry) about Blender

Hey everyone,

So I posted a topic a couple of days ago about how I can bake particle systems into animations and I received this link- animation - Convert particle system to animated meshes - Blender Stack Exchange. I was also given a link to this- Sketchfab Community Blog - » Baking Particles for Sketchfab (Blender Edition). I have used the updated version of the code and have gotten some results, but not the results I was looking for. I have a collection attached to the particle system so I have a variety in my particles. This code only works for the object render setting. Additionally, After selecting my system and my particle mesh and run the code, I get squares that look like the image below. I was wondering if there’s anyway to use a collection with this, and if not, how do I make it so it looks like the object I have selected instead of the squares that are showing up?

Hi Calfan!
Not an exact solution of getting collections to work with that script for baking particles. But I ran into similar problems and the workaround was changing my objects from object render setting several time and bake them separately. But yes! Would have been cooler if we could just use a collection. And I don’t face the problem you stated. The objects I used as particles show up just fine. I used the following script on blender 3.1.2 (that thread had some updated version of the script)

import bpy

Set these to False if you don’t want to key that property.

KEYFRAME_LOCATION = True
KEYFRAME_ROTATION = True
KEYFRAME_SCALE = True
KEYFRAME_VISIBILITY = True # Viewport and render visibility.

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
particles_coll = bpy.data.collections.new(name=“particles”)
bpy.context.scene.collection.children.link(particles_coll)

for i, _ in enumerate(ps.particles):
    dupli = bpy.data.objects.new(
                name="particle.{:03d}".format(i),
                object_data=mesh)
    particles_coll.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):
print(“frame {} processed”.format(frame))
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
if p.alive_state == ‘ALIVE’:
vis = True
else:
vis = False
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_viewport = not(vis) # <<<-- this was called “hide” in <= 2.79
obj.hide_render = not(vis)

def keyframe_obj(obj):
# Keyframe location, rotation, scale and visibility if specified.
if KEYFRAME_LOCATION:
obj.keyframe_insert(“location”)
if KEYFRAME_ROTATION:
obj.keyframe_insert(“rotation_quaternion”)
if KEYFRAME_SCALE:
obj.keyframe_insert(“scale”)
if KEYFRAME_VISIBILITY:
obj.keyframe_insert(“hide_viewport”) # <<<-- this was called “hide” in <= 2.79
obj.keyframe_insert(“hide_render”)

def main():
#in 2.8 you need to evaluate the Dependency graph in order to get data from animation, modifiers, etc
depsgraph = bpy.context.evaluated_depsgraph_get()

# Assume only 2 objects are selected.
# The active object should be the one with the particle system.
ps_obj = bpy.context.object
ps_obj_evaluated = depsgraph.objects[ ps_obj.name ]
obj = [obj for obj in bpy.context.selected_objects if obj != ps_obj][0]
ps = ps_obj_evaluated.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()

1 Like