Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
class INDEFPHYS_physics_scene(bpy.types.Operator):
'''Take selected objects into a separate scene for physics simulation'''
bl_idname = "indefphys.add_physics_scene"
bl_label = "Physics Scene for Simulation"
bl_options = {'REGISTER','UNDO'}
@classmethod
def poll(self,context):
if context.scene.name == "Physics Sim":
return False
else:
return True
def execute(self, context):
obs = [ob for ob in context.selected_objects]
if "Physics Sim" not in bpy.data.scenes:
pscene = bpy.data.scenes.new("Physics Sim")
else:
pscene = bpy.data.scenes["Physics Sim"]
#TODO Clear existing objects and any physics cache
for ob in pscene.objects:
pscene.objects.unlink(ob)
ob.user_clear()
bpy.data.objects.remove(ob)
context.screen.scene = pscene
context.scene.frame_set(0)
for ob in obs:
#new_ob = bpy.data.objects.new(ob.name[0:2]+'_p', ob.data)
pscene.objects.link(ob)
ob.select = True
bpy.ops.object.make_single_user(type='SELECTED_OBJECTS', object = True, obdata = False)
bpy.ops.object.visual_transform_apply()
return {'FINISHED'}
class INDEFPHYS_OT_physics_setup(bpy.types.Operator):
'''Make objects rigid bodies for physics simulation'''
bl_idname = "indefphys.physics_sim_setup"
bl_label = "Setup Physics for Simulation"
bl_options = {'REGISTER','UNDO'}
@classmethod
def poll(self,context):
if context.scene.name == 'Physics Sim':
return True
else:
return False
def execute(self, context):
context.scene.use_gravity = False
#clear existing rigidbody
if context.scene.rigidbody_world:
bpy.ops.rigidbody.world_remove()
bpy.ops.rigidbody.world_add()
else:
bpy.ops.rigidbody.world_add()
#potentially adjust these values
rbw = context.scene.rigidbody_world
rbw.solver_iterations = 15
rbw.point_cache.frame_end = 500 #more time for sim.
context.scene.frame_end = 500
context.scene.frame_set(0)
obs = [ob for ob in context.selected_objects]
bpy.ops.object.select_all(action = 'DESELECT')
for ob in obs:
context.scene.objects.active = ob
ob.select = True
if not ob.rigid_body:
bpy.ops.rigidbody.object_add()
else:
bpy.ops.rigidbody.object_remove()
bpy.ops.rigidbody.object_add()
ob.lock_rotations_4d = True
ob.lock_rotation[0] = True
ob.lock_rotation[1] = True
ob.lock_rotation[2] = True
ob.lock_rotation_w = True
rb = ob.rigid_body
rb.friction = .1
rb.use_margin = True
rb.collision_margin = .05
rb.collision_shape = 'CONVEX_HULL'
rb.restitution = 0
rb.linear_damping = 1
rb.angular_damping = .9
rb.mass = 3
ob.select = False
return {'FINISHED'}
class INDEFPHYS_OT_add_forcefields(bpy.types.Operator):
'''Add forcefields to selected objects'''
bl_idname = "indefphys.add_forcefields"
bl_label = "Add Forcefields All"
bl_options = {'REGISTER','UNDO'}
@classmethod
def poll(self,context):
if context.scene.name == 'Physics Sim':
return True
else:
return False
def execute(self, context):
obs = [ob for ob in context.selected_objects]
bpy.ops.object.select_all(action = 'DESELECT')
for ob in obs:
if ob.type != 'MESH': continue
empty = bpy.data.objects.new(ob.name[0:2] + 'force', None)
context.scene.objects.link(empty)
context.scene.objects.active = empty
empty.parent = ob
empty.matrix_world = ob.matrix_world
empty.select = True
bpy.ops.object.forcefield_toggle()
empty.field.strength = -1000
empty.field.falloff_type = 'SPHERE'
empty.field.use_radial_min = True
empty.field.use_radial_max = True
empty.field.radial_min = ob.dimensions[0]/1.8
empty.field.radial_max = 10
empty.select = False
return {'FINISHED'}
class INDEFPHYS_OT_limit_movements(bpy.types.Operator):
'''Add constraints to limit movements in simulation'''
bl_idname = "indefphys.limit_physics_movements"
bl_label = "Limit Physics Movements"
bl_options = {'REGISTER','UNDO'}
buc_ling = bpy.props.FloatProperty(name = 'Facial/Lingual', default = 2)
mes_dis = bpy.props.FloatProperty(name = 'Mesial/Distal', default = 2)
occlusal = bpy.props.FloatProperty(name = 'Occluso/Gingival', default = 0)
@classmethod
def poll(self,context):
if context.scene.name == 'Physics Sim':
return True
else:
return False
def invoke(self,context,event):
return context.window_manager.invoke_props_dialog(self, width=300, height=20)
def execute(self, context):
context.scene.frame_set(0)
obs = [ob for ob in context.selected_objects]
#bpy.ops.object.select_all(action = 'DESELECT')
for ob in obs:
if ob.type != 'MESH': continue
if 'Limit Location' not in ob.constraints:
limit = ob.constraints.new('LIMIT_LOCATION')
else:
limit = ob.constraints['Limit Location']
ob.constraints.remove(limit)
limit = ob.constraints.new('LIMIT_LOCATION')
imx = ob.matrix_world.inverted()
world_loc = ob.matrix_world.to_translation()
rot = ob.matrix_world.to_quaternion()
X = world_loc.dot(rot * Vector((1,0,0)))
Y = world_loc.dot(rot * Vector((0,1,0)))
Z = world_loc.dot(rot * Vector((0,0,1)))
limit.use_min_x = True
limit.use_min_y = True
limit.use_min_z = True
limit.use_max_x = True
limit.use_max_y = True
limit.use_max_z = True
limit.use_transform_limit = False
limit.owner_space = 'LOCAL'
limit.min_x, limit.max_x = X-self.mes_dis, X+self.mes_dis
limit.min_y, limit.max_y = Y-self.buc_ling, Y+self.buc_ling
limit.min_z, limit.max_z = Z-self.occlusal, Z+self.occlusal
return {'FINISHED'}
class INDEFPHYS_OT_unlimit_movements(bpy.types.Operator):
'''Removes limitations'''
bl_idname = "indefphys.unlimit_physics_movements"
bl_label = "Unlimit Physics Movements"
bl_options = {'REGISTER','UNDO'}
buc_ling = bpy.props.FloatProperty(name = 'Facial/Lingual', default = 2)
mes_dis = bpy.props.FloatProperty(name = 'Mesial/Distal', default = 2)
occlusal = bpy.props.FloatProperty(name = 'Occluso/Gingival', default = 0)
@classmethod
def poll(self,context):
if context.scene.name == 'Physics Sim':
return True
else:
return False
def invoke(self,context,event):
return context.window_manager.invoke_props_dialog(self, width=300, height=20)
def execute(self, context):
context.scene.frame_set(0)
obs = [ob for ob in context.selected_objects]
#bpy.ops.object.select_all(action = 'DESELECT')
for ob in obs:
if ob.type != 'MESH': continue
if 'Limit Location' in ob.constraints:
limit = ob.constraints['Limit Location']
ob.constraints.remove(limit)
return {'FINISHED'}
class INDEFPHYS_OT_lock_movements(bpy.types.Operator):
'''Prevent Selected objects from moving in any direction '''
bl_idname = "indefphys.lock_physics_movements"
bl_label = "Lock Physics Movements"
bl_options = {'REGISTER','UNDO'}
@classmethod
def poll(self,context):
if context.scene.name == 'Physics Sim':
return True
else:
return False
def execute(self, context):
obs = [ob for ob in context.selected_objects]
for ob in obs:
if ob.type != 'MESH': continue
ob.lock_location[0], ob.lock_location[1], ob.lock_location[2] = True, True, True
return {'FINISHED'}
class INDEFPHYS_OT_unlock_movements(bpy.types.Operator):
'''Allows Selected Teeth to move in any direction '''
bl_idname = "indefphys.unlock_physics_movements"
bl_label = "Unlock Physics Movements"
bl_options = {'REGISTER','UNDO'}
@classmethod
def poll(self,context):
if context.scene.name == 'Physics Sim':
return True
else:
return False
def execute(self, context):
obs = [ob for ob in context.selected_objects]
for ob in obs:
if ob.type != 'MESH': continue
ob.lock_location[0], ob.lock_location[1], ob.lock_location[2] = False, False, False
return {'FINISHED'}
class INDEFPHYS_OT_keep_simulation_result(bpy.types.Operator):
'''Kepe results of simulation at current frame, and apply back to design scene '''
bl_idname = "indefphys.keep_simulation_results"
bl_label = "Keep Simulation Results"
bl_options = {'REGISTER','UNDO'}
@classmethod
def poll(self,context):
if context.scene.name == 'Physics Sim':
return True
else:
return False
def execute(self, context):
other_scenes = [sce for sce in bpy.data.scenes if sce.name != 'Physics Sim']
scene = other_scenes[0]
for ob in context.scene.objects:
ob.select = True
context.scene.objects.active = ob
#this ruins the phys simulation but OH WELL!
bpy.ops.object.visual_transform_apply()
for pob in bpy.data.scenes['Physics Sim'].objects:
for ob in scene.objects:
if pob.data == ob.data:
ob.matrix_world = pob.matrix_world
#todo, trash all the objects and physics sim
#switch back to the old scene
context.screen.scene = scene
return {'FINISHED'}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.