0
$\begingroup$

I am trying to simulate a projectile leaving a barrel. To do so, I have a cylinder (representing the barrel), an icosphere (representing the projectile), and a plane (which will serve as emitter). A python script to realise those components reads

import bpy

# Create barrel
r_barrel = .5
h_barrel = 1.5
offset_barrel = 0.5 * h_barrel
bpy.ops.mesh.primitive_cylinder_add(radius=r_barrel, depth=h_barrel, location=(0,0,offset_barrel))
cannon_barrel = bpy.context.object
cannon_barrel.name = "Cannon_Barrel"

# Create sphere for projectile
bpy.ops.object.empty_add(type="SPHERE", location=1.5*cannon_barrel.location, radius=r_barrel)
emitter_constraint = bpy.context.object
emitter_constraint.name = "Emitter_Constraint"
emitter_constraint.parent = cannon_barrel
emitter_constraint.matrix_parent_inverse = cannon_barrel.matrix_world.inverted()

# Create particle emitter
bpy.ops.mesh.primitive_plane_add(size=2*r_barrel, location=emitter_constraint.location)
cannon_emitter = bpy.context.object
cannon_emitter.name = "Cannon_Emitter"
bpy.ops.object.constraint_add(type = "COPY_LOCATION")
cannon_emitter.constraints["Copy Location"].target = bpy.data.objects[emitter_constraint.name]
bpy.ops.object.constraint_add(type = "COPY_ROTATION")
cannon_emitter.constraints["Copy Rotation"].target = bpy.data.objects[emitter_constraint.name]

# Create an icosphere
bpy.ops.mesh.primitive_ico_sphere_add(radius=r_barrel, location=(2,2,0))
cannon_ball = bpy.context.object
cannon_ball.name = "Cannon_Ball"

I would like to create a function taking a given object as input (in this case, cannon_emitter), adds a particle system to it, and substitute the icosphere for the cannonball, i.e. something reading like (the following, of course, DOES NOT WORK)

def assign_particle_system(in_obj, assign_obj):
    in_obj.space_data.context = "PARTICLES"
    in_obj.particle_system_add()
    in_obj.particles["Cannon_Ball_Emitter"].name = "Cannon_Ball_Emitter"
    in_obj.particles["Cannon_Ball_Emitter"].emit_from = "FACE"
    in_obj.particles["Cannon_Ball_Emitter"].userjit = 1
    in_obj.particles["Cannon_Ball_Emitter"].normal_factor = 15
    in_obj.particles["Cannon_Ball_Emitter"].physics_type = "NEWTON"
    in_obj.particles["Cannon_Ball_Emitter"].mass = 1
    in_obj.particles["Cannon_Ball_Emitter"].integrator = "MIDPOINT"
    in_obj.particles["Cannon_Ball_Emitter"].timestep = 1/24
    in_obj.show_instancer_for_render = False
    in_obj.particles["Cannon_Ball_Emitter"].instance_object = bpy.data.objects[assign_obj.name] # substitute the icosphere for the cannonball
    in_obj.particles["Cannon_Ball_Emitter"].particle_size = 1

How can I implement the method taking an object to which a particle system is added, and another object for the substitution?

$\endgroup$

1 Answer 1

0
$\begingroup$

I managed to create such a function in the end. It reads something like this (other parameters can, of course, be passed for more flexibility)

def create_particle_system(emitter, substitute_projectile) -> None:
    bpy.context.view_layer.objects.active = bpy.data.objects[emitter.name]
    bpy.ops.object.particle_system_add()
    bpy.data.objects[emitter.name].particle_systems["ParticleSystem"].settings.name = "Cannon_Ball_Emitter"
    bpy.data.objects[emitter.name].particle_systems["ParticleSystem"].parent = bpy.data.objects[emitter.name]
    bpy.data.particles["Cannon_Ball_Emitter"].type = "EMITTER"
    bpy.data.particles["Cannon_Ball_Emitter"].count = 4
    bpy.data.particles["Cannon_Ball_Emitter"].lifetime = 200
    bpy.data.particles["Cannon_Ball_Emitter"].emit_from = "FACE"
    bpy.data.particles["Cannon_Ball_Emitter"].userjit = 1
    bpy.data.particles["Cannon_Ball_Emitter"].normal_factor = 7.5
    bpy.data.particles["Cannon_Ball_Emitter"].physics_type = "NEWTON"
    bpy.data.particles["Cannon_Ball_Emitter"].integrator = "MIDPOINT"
    bpy.data.particles["Cannon_Ball_Emitter"].timestep = 1/bpy.data.scenes["Scene"].render.fps
    bpy.context.object.show_instancer_for_render = False
    bpy.data.particles["Cannon_Ball_Emitter"].render_type = "OBJECT"
    bpy.data.particles["Cannon_Ball_Emitter"].instance_object = bpy.data.objects[substitute_projectile.name]
    bpy.data.particles["Cannon_Ball_Emitter"].particle_size = 1
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .