Created
November 30, 2018 17:34
-
-
Save patmo141/e81a94226d135e56ea049c60977664da to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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