from .functions import * # # UI # def draw_subpanel(layout, prefs, menu_name, label, icon): box = layout.box() row = box.row() row.alignment = "LEFT" row.prop( prefs, menu_name, icon="TRIA_DOWN" if getattr(prefs, menu_name) else "TRIA_RIGHT", icon_only=True, emboss=False, ) row.label(text=label, icon=icon) return box, getattr(prefs, menu_name) # class GOO_PT_main_panel(bpy.types.Panel): """Creates a Panel in the scene context of the properties editor""" bl_idname = "GOO_PT_main_panel" bl_label = "Goo Animation Tools" bl_space_type = "VIEW_3D" bl_region_type = "UI" bl_category = "Goo Animation Tools" def draw(self, context): layout = self.layout class GP_PT_goophys_panel(Panel): """Creates a Panel in the scene context of the properties editor""" bl_idname = "GP_PT_goophys_panel" bl_label = "Goo Physics" bl_parent_id = "GOO_PT_main_panel" bl_space_type = "VIEW_3D" bl_region_type = "UI" bl_category = "Goo Animation Tools" bl_order = 1 def draw(self, context): layout = self.layout pb = context.active_pose_bone scn = context.scene prefs = context.preferences.addons["goo_physics"].preferences if pb is not None: box = layout.box() if (pb.gp_has_sb_physics or pb.gp_has_cl_physics or pb.gp_has_gn_physics or pb.gp_has_jg_physics) == False: row = box.row(align=True) row.label(text="Mode:") row = box.row(align=True) row.prop(prefs, "gp_physics_type", text="") if prefs.gp_physics_type == "GEO_NODES": row = box.row(align=True) row.operator( "goophys.add_geonodes_physics_to_selected", text="Add Physics", ) row.scale_y = 2.5 if prefs.gp_physics_type == "SIMP_SOFTBODY": row = box.row(align=True) row.operator( "goophys.add_soft_physics_to_selected", text="Add Physics", ) row.scale_y = 2.5 if prefs.gp_physics_type == "CLOTH": row = box.row(align=True) row.operator( "goophys.add_cloth_physics_to_selected", text="Add Physics", ) row.scale_y = 2.5 if prefs.gp_physics_type == "JIGGLE": row = box.row(align=True) row.operator( "goophys.add_jiggle_physics_to_selected", text="Add Physics", ) row.scale_y = 2.5 row = box.row(align=True) row.alignment = "CENTER" row.prop(prefs, "gp_physics_active", text="Physics Active") row.alignment = "CENTER" else: # row = box.row(align=True) row.operator( "goophys.remove_physics_from_selected", text="Remove Physics from Selected Bones", ) row.scale_y = 1.5 row = box.row(align=True) row.operator("goophys.bake_physics", text="Bake Bone Physics") row.scale_y = 2 box = layout.box() row = box.row(align=True) row.operator("goophys.select_dynamic_bones", text="Select Physics Bones") row = box.row(align=True) row.operator("goophys.select_last_dynamic_bones", text="Select Last Bone in Chains") row = box.row(align=True) row.alignment = "CENTER" row.prop(prefs, "gp_physics_active", text="Physics Active") row.alignment = "CENTER" # box = layout.box() if pb.gp_has_cl_physics: label = "Cloth Physics Settings" icon = "MOD_CLOTH" row = box.row(align=True) row.label(text="Presets:") row = box.row(align=True) row.prop(prefs, "cl_presets", text="") row.operator("goophys.add_preset", text="", icon="ADD") row.operator("goophys.delete_preset", text="", icon="REMOVE") row = box.row(align=True) row.operator("goophys.apply_preset", text="Apply Preset") if pb.gp_has_sb_physics: label = "Soft Body Physics Settings" icon = "MOD_SOFT" row = box.row(align=True) row.label(text="Presets:") row = box.row(align=True) row.prop(prefs, "sb_presets", text="") row.operator("goophys.add_preset", text="", icon="ADD") row.operator("goophys.delete_preset", text="", icon="REMOVE") row = box.row(align=True) row.operator("goophys.apply_preset", text="Apply Preset") if pb.gp_has_jg_physics: label = "Jiggle Physics Settings" icon = "MOD_SCREW" row = box.row(align=True) row.label(text="Presets:") row = box.row(align=True) row.prop(prefs, "jg_presets", text="") row.operator("goophys.add_preset", text="", icon="ADD") row.operator("goophys.delete_preset", text="", icon="REMOVE") row = box.row(align=True) row.operator("goophys.apply_preset", text="Apply Preset") if pb.gp_has_gn_physics: label = "Geo Nodes Physics Settings" icon = "GEOMETRY_NODES" row = box.row(align=True) row.label(text="Presets:") row = box.row(align=True) row.prop(prefs, "gn_presets", text="") row.operator("goophys.add_preset", text="", icon="ADD") row.operator("goophys.delete_preset", text="", icon="REMOVE") row = box.row(align=True) row.operator("goophys.apply_preset", text="Apply Preset") boxx, expanded = draw_subpanel(box, prefs, "settings_menu", label, icon) if expanded: if pb.gp_has_cl_physics: row = boxx.row(align=True) row.prop(prefs, "apply_to_all_chains") boxxx, expanded = draw_subpanel(boxx, prefs, "chain_menu", "Chain Settings", "RESTRICT_INSTANCED_OFF") if expanded: boxxxx, expanded = draw_subpanel(boxxx, prefs, "cl_time_menu", "Time", "TIME") if expanded: row = boxxxx.row(align=True) row.prop(pb, "gp_chain_speed", text="Sim Speed") boxxxx, expanded = draw_subpanel(boxxx, prefs, "cl_physical_menu", "Physical", "MOD_SOLIDIFY") if expanded: row = boxxxx.row(align=True) row.prop(pb, "gp_chain_mass", text="Sim Mass") row = boxxxx.row(align=True) row.prop(pb, "gp_chain_gravity", text="Gravity") boxxxx, expanded = draw_subpanel(boxxx, prefs, "cl_structure_menu", "Structure", "SELECT_INTERSECT") if expanded: row = boxxxx.row(align=True) row.prop(pb, "gp_chain_air_dampening", text="Sim Air Dampening") row = boxxxx.row(align=True) row.prop(pb, "gp_chain_bend_damping", text="Sim Bend Damping") boxxxx, expanded = draw_subpanel(boxxx, prefs, "cl_collision_menu", "Collision", "MOD_PHYSICS") if expanded: row = boxxxx.row(align=True) row.prop(pb, "gp_chain_use_collision", text="Use Collision") if pb.gp_chain_use_collision: row = boxxxx.row(align=True) row.prop(pb, "gp_chain_collision_dist", text="Collision Distance") row = boxxxx.row(align=True) row.operator( "goophys.refresh_collision_collection", text="Refresh Collision Objects") if pb.gp_chain_limit_collision: row = boxxxx.row(align=True) row.operator( "goophys.limit_to_type", text="Set Collisions to All") else: row = boxxxx.row(align=True) row.operator( "goophys.limit_to_type", text="Limit Collisions to Collection") row = boxx.row(align=True) row.prop(prefs, "apply_to_all_bones") boxxx, expanded = draw_subpanel(boxx, prefs, "bone_menu", "Bone Settings", "BONE_DATA") if expanded: row = boxxx.row(align=True) row.prop(pb, "gp_sim_influence", text="Sim Influence") row = boxxx.row(align=True) row.operator( "goophys.apply_falloff_to_selected", text="Apply Linear Sim Influence Falloff", ).type = 0 row = boxxx.row(align=True) row.operator( "goophys.apply_falloff_to_selected", text="Apply Quadratic Sim Influence Falloff", ).type = 1 if pb.gp_has_sb_physics: row = boxx.row(align=True) row.prop(prefs, "apply_to_all_bones") boxxx, expanded = draw_subpanel(boxx, prefs, "bone_menu", "Bone Settings", "BONE_DATA") if expanded: boxxxx, expanded = draw_subpanel(boxxx, prefs, "sb_time_menu", "Time", "TIME") if expanded: row = boxxxx.row(align=True) row.prop(pb, "gp_sim_speed", text="Sim Speed") boxxxx, expanded = draw_subpanel(boxxx, prefs, "sb_physical_menu", "Physical", "MOD_SOLIDIFY") if expanded: row = boxxxx.row(align=True) row.prop(pb, "gp_sim_friction", text="Sim Friction") row = boxxxx.row(align=True) row.prop(pb, "gp_sim_mass", text="Sim Mass") row = boxxxx.row(align=True) row.prop(pb, "gp_sim_gravity", text="Gravity") boxxxx, expanded = draw_subpanel(boxxx, prefs, "sb_structure_menu", "Structure", "SELECT_INTERSECT") if expanded: row = boxxxx.row(align=True) row.prop(pb, "gp_sim_stiffness", text="Sim Stiffness") row = boxxxx.row(align=True) row.prop(pb, "gp_sim_damping", text="Sim Damping") row = boxxxx.row(align=True) row.prop(pb, "gp_sim_strength", text="Sim Strength") boxxxx, expanded = draw_subpanel(boxxx, prefs, "sb_collision_menu", "Collision", "MOD_PHYSICS") if expanded: row = boxxxx.row(align=True) row.prop(pb, "gp_sim_use_collision", text="Use Collision") row = boxxxx.row(align=True) row.operator( "goophys.refresh_collision_collection", text="Refresh Collision Objects") if pb.gp_sim_limit_collision: row = boxxxx.row(align=True) row.operator( "goophys.limit_to_type", text="Set Collisions to All") else: row = boxxxx.row(align=True) row.operator( "goophys.limit_to_type", text="Limit Collisions to Collection") row = boxxx.row(align=True) row.prop(pb, "gp_sim_influence", text="Sim Influence") row = boxxx.row(align=True) row.operator( "goophys.apply_falloff_to_selected", text="Apply Linear Sim Influence Falloff", ).type = 0 row = boxxx.row(align=True) row.operator( "goophys.apply_falloff_to_selected", text="Apply Quadratic Sim Influence Falloff", ).type = 1 if pb.gp_has_jg_physics: row = boxx.row(align=True) row.prop(prefs, "apply_to_all_bones") boxxx, expanded = draw_subpanel(boxx, prefs, "bone_menu", "Bone Settings", "BONE_DATA") if expanded: boxxxx, expanded = draw_subpanel(boxxx, prefs, "sb_time_menu", "Time", "TIME") if expanded: row = boxxxx.row(align=True) row.prop(pb, "gp_sim_speed", text="Sim Speed") boxxxx, expanded = draw_subpanel(boxxx, prefs, "sb_physical_menu", "Physical", "MOD_SOLIDIFY") if expanded: row = boxxxx.row(align=True) row.prop(pb, "gp_sim_friction", text="Sim Friction") row = boxxxx.row(align=True) row.prop(pb, "gp_sim_mass", text="Sim Mass") row = boxxxx.row(align=True) row.prop(pb, "gp_sim_gravity", text="Gravity") boxxxx, expanded = draw_subpanel(boxxx, prefs, "jg_physical_menu", "Physical", "MOD_SOLIDIFY") if expanded: row = boxxxx.row(align=True) row.prop(pb, "gp_sim_stiffness", text="Sim Stiffness") row = boxxxx.row(align=True) row.prop(pb, "gp_sim_damping", text="Sim Damping") boxxxx, expanded = draw_subpanel(boxxx, prefs, "jg_collision_menu", "Collision", "MOD_PHYSICS") if expanded: row = boxxxx.row(align=True) row.prop(pb, "gp_sim_use_collision", text="Use Collision") row = boxxxx.row(align=True) row.operator( "goophys.refresh_collision_collection", text="Refresh Collision Objects") if pb.gp_sim_limit_collision: row = boxxxx.row(align=True) row.operator( "goophys.limit_to_type", text="Set Collisions to All") else: row = boxxxx.row(align=True) row.operator( "goophys.limit_to_type", text="Limit Collisions to Collection") row = boxxx.row(align=True) row.prop(pb, "gp_sim_influence", text="Sim Influence") if pb.gp_has_gn_physics: row = boxx.row(align=True) row.prop(prefs, "apply_to_all_chains") boxxx, expanded = draw_subpanel(boxx, prefs, "chain_menu", "Chain Settings", "RESTRICT_INSTANCED_OFF") if expanded: boxxxx, expanded = draw_subpanel(boxxx, prefs, "gn_general_menu", "General", "OUTLINER_DATA_GP_LAYER") if expanded: row = boxxxx.row(align=True) row.prop(pb, "gp_chain_velocity", text="Velocity Scaler") row = boxxxx.row(align=True) row.prop(pb, "gp_chain_dampening", text="Velocity Dampening") row = boxxxx.row(align=True) row.prop(pb, "gp_chain_gravity", text="Gravity") row = boxxxx.row(align=True) row.prop(pb, "gp_chain_root_falloff", text="Root Falloff") boxxxx, expanded = draw_subpanel(boxxx, prefs, "gn_stiff_menu", "Stiffness", "AUTOMERGE_ON") if expanded: row = boxxxx.row(align=True) row.prop(pb, "gp_chain_stiffness", text="Stiffness") row = boxxxx.row(align=True) row.prop( pb, "gp_chain_stiff_end_fac", text="Tip Stiffness Factor" ) boxxxxx, expanded = draw_subpanel(boxxxx, prefs, "gn_stiff_adv_menu", "Advanced Stiffness", "CON_TRANSLIKE") if expanded: row = boxxxxx.row(align=True) row.prop( pb, "gp_chain_stiff_vel_fac", text="Stiffness Velocity Factor" ) row = boxxxxx.row(align=True) row.prop( pb, "gp_chain_stiff_vel_min", text="Stiffness Velocity Min" ) row = boxxxxx.row(align=True) row.prop( pb, "gp_chain_stiff_vel_max", text="Stiffness Velocity Max" ) boxxxx, expanded = draw_subpanel(boxxx, prefs, "gn_wind_menu", "Wind", "FORCE_WIND") if expanded: has_wind = False ob = bpy.data.objects.get(pb.gp_sim_object) mod = None if ob: mod = ob.modifiers.get("GP_Nodes Sim") if mod: has_wind = get_geo_nodes_input(mod, "Wind Object") is not None if has_wind == False: row = boxxxx.row(align=True) row.operator( "goophys.add_wind_objects", text="Add Wind Controller to Chains" ) row.scale_y = 2.0 boxxxx.separator() if mod is not None: wind_ob_ctr, wind_ob_str = get_geo_nodes_input_str(mod, "Wind Object") row = boxxxx.row(align=True) row.prop(wind_ob_ctr, wind_ob_str, text="Wind Controller") else: row = boxxxx.row(align=True) row.prop(pb, "gp_chain_wind_strength", text="Wind Strength") row = boxxxx.row(align=True) row.prop(pb, "gp_chain_wind_noise_strength", text="Wind Noise Strength") row = boxxxx.row(align=True) row.prop(pb, "gp_chain_wind_noise_scale", text="Wind Noise Scale") boxxxx.separator() if mod is not None: wind_ob_ctr, wind_ob_str = get_geo_nodes_input_str(mod, "Wind Object") row = boxxxx.row(align=True) row.prop(wind_ob_ctr, wind_ob_str, text="Wind Controller") row = boxxxx.row(align=True) row.operator( "goophys.copy_active_wind_controller", text="Copy Controller to Selected Chains", ) row.scale_y = 1.5 row = boxxxx.row(align=True) row.operator( "goophys.remove_wind_objects", text="Remove Controller from Chains" ) row.scale_y = 2.0 boxxxx, expanded = draw_subpanel(boxxx, prefs, "gn_collision_menu", "Collision", "MOD_PHYSICS") if expanded: row = boxxxx.row(align=True) row.prop(pb, "gp_chain_use_collision", text="Use Collision") if pb.gp_chain_use_collision: row = boxxxx.row(align=True) row.prop(pb, "gp_chain_collision_dist", text="Collision Distance") row = boxxxx.row(align=True) row.prop( pb, "gp_chain_collision_friction", text="Collision Friction" ) row = boxxxx.row(align=True) row.operator( "goophys.refresh_collision_collection", text="Refresh Collision Objects") if pb.gp_chain_limit_collision: row = boxxxx.row(align=True) row.operator( "goophys.limit_to_type", text="Set Collisions to All") else: row = boxxxx.row(align=True) row.operator( "goophys.limit_to_type", text="Limit Collisions to Collection") row = boxx.row(align=True) row.prop(prefs, "apply_to_all_bones") boxxx, expanded = draw_subpanel(boxx, prefs, "bone_menu", "Bone Settings", "BONE_DATA") if expanded: row = boxxx.row(align=True) row.prop(pb, "gp_sim_influence", text="Sim Influence") row = boxxx.row(align=True) row.operator( "goophys.apply_falloff_to_selected", text="Apply Linear Sim Influence Falloff", ).type = 0 row = boxxx.row(align=True) row.operator( "goophys.apply_falloff_to_selected", text="Apply Quadratic Sim Influence Falloff", ).type = 1 # elif context.mode == "POSE": box = layout.box() row = box.row(align=True) row.operator("goophys.select_dynamic_bones", text="Select Physics Bones") row = box.row(align=True) row.operator("goophys.select_last_dynamic_bones", text="Select Last Bone in Chains") row = box.row(align=True) row.alignment = "CENTER" row.prop(prefs, "gp_physics_active", text="Physics Active") row.alignment = "CENTER" class GP_PT_goophys_collider_panel(Panel): """Creates a Panel in the scene context of the properties editor""" bl_idname = "GP_PT_goophys_collider_panel" bl_label = "Colliders" bl_parent_id = "GP_PT_goophys_panel" bl_space_type = "VIEW_3D" bl_region_type = "UI" bl_category = "Goo Animation Tools" bl_order = 1 @classmethod def poll(cls, context): return context.active_object and context.mode == "OBJECT" def draw(self, context): layout = self.layout row = layout.row(align=True) row.operator( "goophys.add_collider", text="Collider From Selected Objects" ) row = layout.row(align=True) row.operator( "goophys.colliders_from_mesh", text="Colliders From Mesh Deform Weights" ) class GP_PT_goophys_advanced_panel(Panel): """Creates a Panel in the scene context of the properties editor""" bl_idname = "GP_PT_goophys_advanced_panel" bl_label = "Advanced" bl_parent_id = "GP_PT_goophys_panel" bl_space_type = "VIEW_3D" bl_region_type = "UI" bl_category = "Goo Animation Tools" bl_options = {"DEFAULT_CLOSED"} bl_order = 2 @classmethod def poll(cls, context): return context.active_object and context.mode == "POSE" def draw(self, context): layout = self.layout prefs = context.preferences.addons["goo_physics"].preferences row = layout.row(align=True) row.label(text="Bone Map Presets:") row = layout.row(align=True) row.prop(prefs, "bm_presets", text="") row.operator("goophys.add_bone_map_preset", text="", icon="ADD") row.operator("goophys.delete_bone_map_preset", text="", icon="REMOVE") row = layout.row(align=True) row.operator("goophys.apply_bone_map_preset", text="Apply Bone Map Preset") class GP_PT_goophys_trouble_panel(Panel): """Creates a Panel in the scene context of the properties editor""" bl_idname = "GP_PT_goophys_trouble_panel" bl_label = "Troubleshooting" bl_parent_id = "GP_PT_goophys_panel" bl_space_type = "VIEW_3D" bl_region_type = "UI" bl_category = "Goo Animation Tools" bl_options = {"DEFAULT_CLOSED"} bl_order = 3 def draw(self, context): layout = self.layout row = layout.row(align=True) row.operator("goophys.sync_frame_range", text="Sync Frame Range") row = layout.row(align=True) row.operator( "goophys.refresh_physics_status", text="Refresh Bone Physics Status" ) # # # _classes = [ GP_PT_goophys_panel, GP_PT_goophys_collider_panel, GP_PT_goophys_advanced_panel, GP_PT_goophys_trouble_panel, ] _register, _unregister = register_classes_factory(_classes) def register(): if hasattr(bpy.types, "GOO_PT_main_panel") == False: bpy.utils.register_class(GOO_PT_main_panel) _register() def unregister(): _unregister()