From f3e8af003933a61e80b9064ec7f2d67218fb6a05 Mon Sep 17 00:00:00 2001 From: Matthias Patscheider Date: Mon, 26 Jun 2023 11:09:31 +0300 Subject: [PATCH 01/23] Support Curves --- auto_Convex/add_bounding_auto_convex.py | 2 ++ collider_conversion/conversion_operators.py | 2 ++ collider_shapes/add_bounding_box.py | 4 ++++ collider_shapes/add_bounding_capsule.py | 3 +++ collider_shapes/add_bounding_convex_hull.py | 3 +++ collider_shapes/add_bounding_cylinder.py | 3 +++ collider_shapes/add_bounding_primitive.py | 21 +++++++++++++++++---- collider_shapes/add_bounding_sphere.py | 3 +++ collider_shapes/add_collision_mesh.py | 2 ++ collider_shapes/add_minimum_bounding_box.py | 2 ++ 10 files changed, 41 insertions(+), 4 deletions(-) diff --git a/auto_Convex/add_bounding_auto_convex.py b/auto_Convex/add_bounding_auto_convex.py index 2a1f762..9d3f078 100644 --- a/auto_Convex/add_bounding_auto_convex.py +++ b/auto_Convex/add_bounding_auto_convex.py @@ -144,6 +144,8 @@ def execute(self, context): # skip if invalid object if not self.is_valid_object(obj): continue + if obj and obj.type in self.valid_object_types: + obj = self.convert_to_mesh(context, obj) context.view_layer.objects.active = obj diff --git a/collider_conversion/conversion_operators.py b/collider_conversion/conversion_operators.py index 62fd16f..8c02eba 100644 --- a/collider_conversion/conversion_operators.py +++ b/collider_conversion/conversion_operators.py @@ -129,6 +129,8 @@ def execute(self, context): # skip if invalid object if not self.is_valid_object(obj): continue + if obj and obj.type in self.valid_object_types: + obj = self.convert_to_mesh(context, obj) new_collider = obj.copy() new_collider.data = obj.data.copy() diff --git a/collider_shapes/add_bounding_box.py b/collider_shapes/add_bounding_box.py index 4d6b5f0..8505fde 100644 --- a/collider_shapes/add_bounding_box.py +++ b/collider_shapes/add_bounding_box.py @@ -127,6 +127,10 @@ def execute(self, context): if not self.is_valid_object(obj): continue + if obj and obj.type in self.valid_object_types: + print('ZZZZZZZZZZZZZZZZZZZZZZZZZ') + obj = self.convert_to_mesh(context, obj) + context.view_layer.objects.active = obj bounding_box_data = {} diff --git a/collider_shapes/add_bounding_capsule.py b/collider_shapes/add_bounding_capsule.py index 51fd4c5..5959f2d 100644 --- a/collider_shapes/add_bounding_capsule.py +++ b/collider_shapes/add_bounding_capsule.py @@ -87,6 +87,9 @@ def execute(self, context): if not self.is_valid_object(obj): continue + if obj and obj.type in self.valid_object_types: + obj = self.convert_to_mesh(context, obj) + context.view_layer.objects.active = obj bounding_capsule_data = {} diff --git a/collider_shapes/add_bounding_convex_hull.py b/collider_shapes/add_bounding_convex_hull.py index 0ebd5e2..99d6007 100644 --- a/collider_shapes/add_bounding_convex_hull.py +++ b/collider_shapes/add_bounding_convex_hull.py @@ -55,6 +55,9 @@ def execute(self, context): if not self.is_valid_object(obj): continue + if obj and obj.type in self.valid_object_types: + obj = self.convert_to_mesh(context, obj) + convex_collision_data = {} if self.obj_mode == "EDIT": diff --git a/collider_shapes/add_bounding_cylinder.py b/collider_shapes/add_bounding_cylinder.py index 8206a70..02f0c11 100644 --- a/collider_shapes/add_bounding_cylinder.py +++ b/collider_shapes/add_bounding_cylinder.py @@ -264,6 +264,9 @@ def execute(self, context): if not self.is_valid_object(obj): continue + if obj and obj.type in self.valid_object_types: + obj = self.convert_to_mesh(context, obj) + bounding_cylinder_data = {} if self.obj_mode == 'EDIT': diff --git a/collider_shapes/add_bounding_primitive.py b/collider_shapes/add_bounding_primitive.py index b82ba55..6e68670 100644 --- a/collider_shapes/add_bounding_primitive.py +++ b/collider_shapes/add_bounding_primitive.py @@ -779,10 +779,9 @@ def mesh_from_selection(obj, use_modifiers=False): return mesh - @staticmethod - def is_valid_object(obj): + def is_valid_object(self, obj): """Is the object valid to be used as a base mesh for collider generation""" - if obj is None or obj.type != "MESH": + if obj is None or obj.type not in self.valid_object_types: return False return True @@ -854,6 +853,18 @@ def print_generation_time(shape, time): print(shape) print("Time elapsed: ", str(time)) + def convert_to_mesh(self, context, object): + deg = context.evaluated_depsgraph_get() + me = bpy.data.meshes.new_from_object(object.evaluated_get(deg), depsgraph=deg) + + new_obj = bpy.data.objects.new(object.name + "_mesh", me) + context.collection.objects.link(new_obj) + + new_obj.matrix_world = object.matrix_world + context.view_layer.objects.active = new_obj + + return new_obj + def primitive_postprocessing(self, context, bounding_object, base_object_collections): colSettings = context.scene.collider_tools @@ -1057,11 +1068,13 @@ def __init__(self): self.use_recenter_origin = False self.use_custom_rotation = False + self.valid_object_types = ['CURVE', 'SURFACE', 'FONT', 'META'] + @classmethod def poll(cls, context): count = 0 for obj in context.selected_objects: - if obj.type == 'MESH': + if obj.type in ['MESH', 'CURVE', 'SURFACE', 'FONT', 'META']: count = count + 1 return count > 0 diff --git a/collider_shapes/add_bounding_sphere.py b/collider_shapes/add_bounding_sphere.py index fcdde0d..09f4544 100644 --- a/collider_shapes/add_bounding_sphere.py +++ b/collider_shapes/add_bounding_sphere.py @@ -174,6 +174,9 @@ def execute(self, context): if not self.is_valid_object(obj): continue + if obj and obj.type in self.valid_object_types: + obj = self.convert_to_mesh(context, obj) + initial_mod_state = {} context.view_layer.objects.active = obj scene = context.scene diff --git a/collider_shapes/add_collision_mesh.py b/collider_shapes/add_collision_mesh.py index 5f9868a..000a163 100644 --- a/collider_shapes/add_collision_mesh.py +++ b/collider_shapes/add_collision_mesh.py @@ -59,6 +59,8 @@ def execute(self, context): # skip if invalid object if not self.is_valid_object(obj): continue + if obj and obj.type in self.valid_object_types: + obj = self.convert_to_mesh(context, obj) mesh_collider_data = {} diff --git a/collider_shapes/add_minimum_bounding_box.py b/collider_shapes/add_minimum_bounding_box.py index 6226943..aa0861a 100644 --- a/collider_shapes/add_minimum_bounding_box.py +++ b/collider_shapes/add_minimum_bounding_box.py @@ -153,6 +153,8 @@ def execute(self, context): # skip if invalid object if not self.is_valid_object(obj): continue + if obj and obj.type in self.valid_object_types: + obj = self.convert_to_mesh(context, obj) bounding_box_data = {} From 99aa76df41ad21bd7da510ae712ce38defbf9689 Mon Sep 17 00:00:00 2001 From: Matthias Patscheider Date: Mon, 26 Jun 2023 11:41:13 +0300 Subject: [PATCH 02/23] Revert "Support Curves" This reverts commit f3e8af003933a61e80b9064ec7f2d67218fb6a05. --- auto_Convex/add_bounding_auto_convex.py | 2 -- collider_conversion/conversion_operators.py | 2 -- collider_shapes/add_bounding_box.py | 4 ---- collider_shapes/add_bounding_capsule.py | 3 --- collider_shapes/add_bounding_convex_hull.py | 3 --- collider_shapes/add_bounding_cylinder.py | 3 --- collider_shapes/add_bounding_primitive.py | 21 ++++----------------- collider_shapes/add_bounding_sphere.py | 3 --- collider_shapes/add_collision_mesh.py | 2 -- collider_shapes/add_minimum_bounding_box.py | 2 -- 10 files changed, 4 insertions(+), 41 deletions(-) diff --git a/auto_Convex/add_bounding_auto_convex.py b/auto_Convex/add_bounding_auto_convex.py index 9d3f078..2a1f762 100644 --- a/auto_Convex/add_bounding_auto_convex.py +++ b/auto_Convex/add_bounding_auto_convex.py @@ -144,8 +144,6 @@ def execute(self, context): # skip if invalid object if not self.is_valid_object(obj): continue - if obj and obj.type in self.valid_object_types: - obj = self.convert_to_mesh(context, obj) context.view_layer.objects.active = obj diff --git a/collider_conversion/conversion_operators.py b/collider_conversion/conversion_operators.py index 8c02eba..62fd16f 100644 --- a/collider_conversion/conversion_operators.py +++ b/collider_conversion/conversion_operators.py @@ -129,8 +129,6 @@ def execute(self, context): # skip if invalid object if not self.is_valid_object(obj): continue - if obj and obj.type in self.valid_object_types: - obj = self.convert_to_mesh(context, obj) new_collider = obj.copy() new_collider.data = obj.data.copy() diff --git a/collider_shapes/add_bounding_box.py b/collider_shapes/add_bounding_box.py index 8505fde..4d6b5f0 100644 --- a/collider_shapes/add_bounding_box.py +++ b/collider_shapes/add_bounding_box.py @@ -127,10 +127,6 @@ def execute(self, context): if not self.is_valid_object(obj): continue - if obj and obj.type in self.valid_object_types: - print('ZZZZZZZZZZZZZZZZZZZZZZZZZ') - obj = self.convert_to_mesh(context, obj) - context.view_layer.objects.active = obj bounding_box_data = {} diff --git a/collider_shapes/add_bounding_capsule.py b/collider_shapes/add_bounding_capsule.py index 5959f2d..51fd4c5 100644 --- a/collider_shapes/add_bounding_capsule.py +++ b/collider_shapes/add_bounding_capsule.py @@ -87,9 +87,6 @@ def execute(self, context): if not self.is_valid_object(obj): continue - if obj and obj.type in self.valid_object_types: - obj = self.convert_to_mesh(context, obj) - context.view_layer.objects.active = obj bounding_capsule_data = {} diff --git a/collider_shapes/add_bounding_convex_hull.py b/collider_shapes/add_bounding_convex_hull.py index 99d6007..0ebd5e2 100644 --- a/collider_shapes/add_bounding_convex_hull.py +++ b/collider_shapes/add_bounding_convex_hull.py @@ -55,9 +55,6 @@ def execute(self, context): if not self.is_valid_object(obj): continue - if obj and obj.type in self.valid_object_types: - obj = self.convert_to_mesh(context, obj) - convex_collision_data = {} if self.obj_mode == "EDIT": diff --git a/collider_shapes/add_bounding_cylinder.py b/collider_shapes/add_bounding_cylinder.py index 02f0c11..8206a70 100644 --- a/collider_shapes/add_bounding_cylinder.py +++ b/collider_shapes/add_bounding_cylinder.py @@ -264,9 +264,6 @@ def execute(self, context): if not self.is_valid_object(obj): continue - if obj and obj.type in self.valid_object_types: - obj = self.convert_to_mesh(context, obj) - bounding_cylinder_data = {} if self.obj_mode == 'EDIT': diff --git a/collider_shapes/add_bounding_primitive.py b/collider_shapes/add_bounding_primitive.py index 6e68670..b82ba55 100644 --- a/collider_shapes/add_bounding_primitive.py +++ b/collider_shapes/add_bounding_primitive.py @@ -779,9 +779,10 @@ def mesh_from_selection(obj, use_modifiers=False): return mesh - def is_valid_object(self, obj): + @staticmethod + def is_valid_object(obj): """Is the object valid to be used as a base mesh for collider generation""" - if obj is None or obj.type not in self.valid_object_types: + if obj is None or obj.type != "MESH": return False return True @@ -853,18 +854,6 @@ def print_generation_time(shape, time): print(shape) print("Time elapsed: ", str(time)) - def convert_to_mesh(self, context, object): - deg = context.evaluated_depsgraph_get() - me = bpy.data.meshes.new_from_object(object.evaluated_get(deg), depsgraph=deg) - - new_obj = bpy.data.objects.new(object.name + "_mesh", me) - context.collection.objects.link(new_obj) - - new_obj.matrix_world = object.matrix_world - context.view_layer.objects.active = new_obj - - return new_obj - def primitive_postprocessing(self, context, bounding_object, base_object_collections): colSettings = context.scene.collider_tools @@ -1068,13 +1057,11 @@ def __init__(self): self.use_recenter_origin = False self.use_custom_rotation = False - self.valid_object_types = ['CURVE', 'SURFACE', 'FONT', 'META'] - @classmethod def poll(cls, context): count = 0 for obj in context.selected_objects: - if obj.type in ['MESH', 'CURVE', 'SURFACE', 'FONT', 'META']: + if obj.type == 'MESH': count = count + 1 return count > 0 diff --git a/collider_shapes/add_bounding_sphere.py b/collider_shapes/add_bounding_sphere.py index 09f4544..fcdde0d 100644 --- a/collider_shapes/add_bounding_sphere.py +++ b/collider_shapes/add_bounding_sphere.py @@ -174,9 +174,6 @@ def execute(self, context): if not self.is_valid_object(obj): continue - if obj and obj.type in self.valid_object_types: - obj = self.convert_to_mesh(context, obj) - initial_mod_state = {} context.view_layer.objects.active = obj scene = context.scene diff --git a/collider_shapes/add_collision_mesh.py b/collider_shapes/add_collision_mesh.py index 000a163..5f9868a 100644 --- a/collider_shapes/add_collision_mesh.py +++ b/collider_shapes/add_collision_mesh.py @@ -59,8 +59,6 @@ def execute(self, context): # skip if invalid object if not self.is_valid_object(obj): continue - if obj and obj.type in self.valid_object_types: - obj = self.convert_to_mesh(context, obj) mesh_collider_data = {} diff --git a/collider_shapes/add_minimum_bounding_box.py b/collider_shapes/add_minimum_bounding_box.py index aa0861a..6226943 100644 --- a/collider_shapes/add_minimum_bounding_box.py +++ b/collider_shapes/add_minimum_bounding_box.py @@ -153,8 +153,6 @@ def execute(self, context): # skip if invalid object if not self.is_valid_object(obj): continue - if obj and obj.type in self.valid_object_types: - obj = self.convert_to_mesh(context, obj) bounding_box_data = {} From 137ce3c5eacd0eb9d3ff0ba4aff33324f7634833 Mon Sep 17 00:00:00 2001 From: Matthias Patscheider Date: Mon, 26 Jun 2023 11:43:21 +0300 Subject: [PATCH 03/23] Revert "Revert "Support Curves"" This reverts commit 99aa76df41ad21bd7da510ae712ce38defbf9689. --- auto_Convex/add_bounding_auto_convex.py | 2 ++ collider_conversion/conversion_operators.py | 2 ++ collider_shapes/add_bounding_box.py | 4 ++++ collider_shapes/add_bounding_capsule.py | 3 +++ collider_shapes/add_bounding_convex_hull.py | 3 +++ collider_shapes/add_bounding_cylinder.py | 3 +++ collider_shapes/add_bounding_primitive.py | 21 +++++++++++++++++---- collider_shapes/add_bounding_sphere.py | 3 +++ collider_shapes/add_collision_mesh.py | 2 ++ collider_shapes/add_minimum_bounding_box.py | 2 ++ 10 files changed, 41 insertions(+), 4 deletions(-) diff --git a/auto_Convex/add_bounding_auto_convex.py b/auto_Convex/add_bounding_auto_convex.py index 2a1f762..9d3f078 100644 --- a/auto_Convex/add_bounding_auto_convex.py +++ b/auto_Convex/add_bounding_auto_convex.py @@ -144,6 +144,8 @@ def execute(self, context): # skip if invalid object if not self.is_valid_object(obj): continue + if obj and obj.type in self.valid_object_types: + obj = self.convert_to_mesh(context, obj) context.view_layer.objects.active = obj diff --git a/collider_conversion/conversion_operators.py b/collider_conversion/conversion_operators.py index 62fd16f..8c02eba 100644 --- a/collider_conversion/conversion_operators.py +++ b/collider_conversion/conversion_operators.py @@ -129,6 +129,8 @@ def execute(self, context): # skip if invalid object if not self.is_valid_object(obj): continue + if obj and obj.type in self.valid_object_types: + obj = self.convert_to_mesh(context, obj) new_collider = obj.copy() new_collider.data = obj.data.copy() diff --git a/collider_shapes/add_bounding_box.py b/collider_shapes/add_bounding_box.py index 4d6b5f0..8505fde 100644 --- a/collider_shapes/add_bounding_box.py +++ b/collider_shapes/add_bounding_box.py @@ -127,6 +127,10 @@ def execute(self, context): if not self.is_valid_object(obj): continue + if obj and obj.type in self.valid_object_types: + print('ZZZZZZZZZZZZZZZZZZZZZZZZZ') + obj = self.convert_to_mesh(context, obj) + context.view_layer.objects.active = obj bounding_box_data = {} diff --git a/collider_shapes/add_bounding_capsule.py b/collider_shapes/add_bounding_capsule.py index 51fd4c5..5959f2d 100644 --- a/collider_shapes/add_bounding_capsule.py +++ b/collider_shapes/add_bounding_capsule.py @@ -87,6 +87,9 @@ def execute(self, context): if not self.is_valid_object(obj): continue + if obj and obj.type in self.valid_object_types: + obj = self.convert_to_mesh(context, obj) + context.view_layer.objects.active = obj bounding_capsule_data = {} diff --git a/collider_shapes/add_bounding_convex_hull.py b/collider_shapes/add_bounding_convex_hull.py index 0ebd5e2..99d6007 100644 --- a/collider_shapes/add_bounding_convex_hull.py +++ b/collider_shapes/add_bounding_convex_hull.py @@ -55,6 +55,9 @@ def execute(self, context): if not self.is_valid_object(obj): continue + if obj and obj.type in self.valid_object_types: + obj = self.convert_to_mesh(context, obj) + convex_collision_data = {} if self.obj_mode == "EDIT": diff --git a/collider_shapes/add_bounding_cylinder.py b/collider_shapes/add_bounding_cylinder.py index 8206a70..02f0c11 100644 --- a/collider_shapes/add_bounding_cylinder.py +++ b/collider_shapes/add_bounding_cylinder.py @@ -264,6 +264,9 @@ def execute(self, context): if not self.is_valid_object(obj): continue + if obj and obj.type in self.valid_object_types: + obj = self.convert_to_mesh(context, obj) + bounding_cylinder_data = {} if self.obj_mode == 'EDIT': diff --git a/collider_shapes/add_bounding_primitive.py b/collider_shapes/add_bounding_primitive.py index b82ba55..6e68670 100644 --- a/collider_shapes/add_bounding_primitive.py +++ b/collider_shapes/add_bounding_primitive.py @@ -779,10 +779,9 @@ def mesh_from_selection(obj, use_modifiers=False): return mesh - @staticmethod - def is_valid_object(obj): + def is_valid_object(self, obj): """Is the object valid to be used as a base mesh for collider generation""" - if obj is None or obj.type != "MESH": + if obj is None or obj.type not in self.valid_object_types: return False return True @@ -854,6 +853,18 @@ def print_generation_time(shape, time): print(shape) print("Time elapsed: ", str(time)) + def convert_to_mesh(self, context, object): + deg = context.evaluated_depsgraph_get() + me = bpy.data.meshes.new_from_object(object.evaluated_get(deg), depsgraph=deg) + + new_obj = bpy.data.objects.new(object.name + "_mesh", me) + context.collection.objects.link(new_obj) + + new_obj.matrix_world = object.matrix_world + context.view_layer.objects.active = new_obj + + return new_obj + def primitive_postprocessing(self, context, bounding_object, base_object_collections): colSettings = context.scene.collider_tools @@ -1057,11 +1068,13 @@ def __init__(self): self.use_recenter_origin = False self.use_custom_rotation = False + self.valid_object_types = ['CURVE', 'SURFACE', 'FONT', 'META'] + @classmethod def poll(cls, context): count = 0 for obj in context.selected_objects: - if obj.type == 'MESH': + if obj.type in ['MESH', 'CURVE', 'SURFACE', 'FONT', 'META']: count = count + 1 return count > 0 diff --git a/collider_shapes/add_bounding_sphere.py b/collider_shapes/add_bounding_sphere.py index fcdde0d..09f4544 100644 --- a/collider_shapes/add_bounding_sphere.py +++ b/collider_shapes/add_bounding_sphere.py @@ -174,6 +174,9 @@ def execute(self, context): if not self.is_valid_object(obj): continue + if obj and obj.type in self.valid_object_types: + obj = self.convert_to_mesh(context, obj) + initial_mod_state = {} context.view_layer.objects.active = obj scene = context.scene diff --git a/collider_shapes/add_collision_mesh.py b/collider_shapes/add_collision_mesh.py index 5f9868a..000a163 100644 --- a/collider_shapes/add_collision_mesh.py +++ b/collider_shapes/add_collision_mesh.py @@ -59,6 +59,8 @@ def execute(self, context): # skip if invalid object if not self.is_valid_object(obj): continue + if obj and obj.type in self.valid_object_types: + obj = self.convert_to_mesh(context, obj) mesh_collider_data = {} diff --git a/collider_shapes/add_minimum_bounding_box.py b/collider_shapes/add_minimum_bounding_box.py index 6226943..aa0861a 100644 --- a/collider_shapes/add_minimum_bounding_box.py +++ b/collider_shapes/add_minimum_bounding_box.py @@ -153,6 +153,8 @@ def execute(self, context): # skip if invalid object if not self.is_valid_object(obj): continue + if obj and obj.type in self.valid_object_types: + obj = self.convert_to_mesh(context, obj) bounding_box_data = {} From a3f17a06fdaefd7e0027e0c395e82ea17f72efef Mon Sep 17 00:00:00 2001 From: Matthias Patscheider Date: Mon, 26 Jun 2023 19:40:31 +0300 Subject: [PATCH 04/23] save original state --- collider_conversion/__init__.py | 10 +- collider_conversion/conversion_operators.py | 273 -------------------- collider_conversion/convert_to_collider.py | 136 ++++++++++ collider_conversion/convert_to_mesh.py | 88 +++++++ collider_conversion/regenerate_name.py | 53 ++++ collider_shapes/add_bounding_box.py | 11 +- collider_shapes/add_bounding_primitive.py | 34 ++- 7 files changed, 315 insertions(+), 290 deletions(-) delete mode 100644 collider_conversion/conversion_operators.py create mode 100644 collider_conversion/convert_to_collider.py create mode 100644 collider_conversion/convert_to_mesh.py create mode 100644 collider_conversion/regenerate_name.py diff --git a/collider_conversion/__init__.py b/collider_conversion/__init__.py index be50811..8410911 100644 --- a/collider_conversion/__init__.py +++ b/collider_conversion/__init__.py @@ -1,9 +1,11 @@ -from . import conversion_operators +from . import convert_to_collider +from . import convert_to_mesh +from . import regenerate_name classes = ( - conversion_operators.OBJECT_OT_convert_to_collider, - conversion_operators.OBJECT_OT_convert_to_mesh, - conversion_operators.OBJECT_OT_regenerate_name, + convert_to_collider.OBJECT_OT_convert_to_collider, + convert_to_mesh.OBJECT_OT_convert_to_mesh, + regenerate_name.OBJECT_OT_regenerate_name, ) diff --git a/collider_conversion/conversion_operators.py b/collider_conversion/conversion_operators.py deleted file mode 100644 index 8c02eba..0000000 --- a/collider_conversion/conversion_operators.py +++ /dev/null @@ -1,273 +0,0 @@ -import bpy -from bpy.types import Operator - -from ..collider_shapes.add_bounding_primitive import OBJECT_OT_add_bounding_object -from ..pyshics_materials.material_functions import assign_physics_material, create_material, remove_materials - -default_shape = 'box_shape' -default_group = 'USER_01' - - -class OBJECT_OT_regenerate_name(Operator): - """Regenerate selected collider names based on preset""" - bl_idname = "object.regenerate_name" - bl_label = "Regenerate Name" - bl_description = 'Regenerate selected collider names based on preset' - - @classmethod - def poll(cls, context): - - # Convert is only supported in object mode - if context.mode != 'OBJECT': - return False - - count = 0 - for obj in context.selected_objects: - if obj.type == 'MESH': - count = count + 1 - return count > 0 - - def execute(self, context): - prefs = context.preferences.addons[__package__.split('.')[0]].preferences - - for obj in context.selected_objects.copy(): - - # skip if invalid object - if obj is None or obj.type != "MESH": - continue - - if prefs.replace_name: - basename = prefs.obj_basename - elif obj.parent: - basename = obj.parent.name - else: - basename = obj.name - - # get collider shape and group and set to default there is no previous data - shape_identifier = default_shape if obj.get('collider_shape') is None else obj.get('collider_shape') - user_group = default_group if obj.get('collider_group') is None else obj.get('collider_group') - - new_name = OBJECT_OT_add_bounding_object.class_collider_name(shape_identifier, user_group, - basename=basename) - obj.name = new_name - OBJECT_OT_add_bounding_object.set_data_name(obj, new_name, "_data") - - return {'FINISHED'} - - -class OBJECT_OT_convert_to_collider(OBJECT_OT_add_bounding_object, Operator): - """Convert existing objects to be a collider""" - bl_idname = "object.convert_to_collider" - bl_label = "Mesh to Collider" - bl_description = 'Convert selected meshes to colliders' - - @classmethod - def poll(cls, context): - # Convert is only supported in object mode - return False if context.mode != 'OBJECT' else super().poll(context) - - def __init__(self): - super().__init__() - self.use_shape_change = True - self.use_decimation = True - self.is_mesh_to_collider = True - # self.use_creation_mode = False - self.shape = 'mesh_shape' - self.use_keep_original_materials = True - - def invoke(self, context, event): - super().invoke(context, event) - - self.collider_shapes_idx = 3 - self.collider_shapes = ['box_shape', 'sphere_shape', 'capsule_shape', 'convex_shape', - 'mesh_shape'] - - self.shape = self.collider_shapes[self.collider_shapes_idx] - - return {'RUNNING_MODAL'} - - def modal(self, context, event): - status = super().modal(context, event) - if status == {'FINISHED'}: - return {'FINISHED'} - if status == {'CANCELLED'}: - return {'CANCELLED'} - if status == {'PASS_THROUGH'}: - return {'PASS_THROUGH'} - - - elif event.type == 'Q' and event.value == 'RELEASE': - # toggle through display modes - self.collider_shapes_idx = (self.collider_shapes_idx + 1) % len(self.collider_shapes) - self.shape = self.collider_shapes[self.collider_shapes_idx] - for collider in self.new_colliders_list: - if collider: - collider['collider_shape'] = self.shape - self.update_names() - - return {'RUNNING_MODAL'} - - def store_initial_obj_state(self, obj, collections): - dic = {} - dic['obj'] = obj - col_list = [col.name for col in collections] - dic['users_collection'] = col_list - - return dic - - def execute(self, context): - # CLEANUP and INIT - super().execute(context) - - self.original_obj_data = [] - collider_data = [] - user_collections = [] - - # Create the bounding geometry, depending on edit or object mode. - for obj in self.selected_objects: - - # skip if invalid object - if not self.is_valid_object(obj): - continue - if obj and obj.type in self.valid_object_types: - obj = self.convert_to_mesh(context, obj) - - new_collider = obj.copy() - new_collider.data = obj.data.copy() - user_collections = obj.users_collection - - # New collider to scene - bpy.context.collection.objects.link(new_collider) - - # store initial state for operation cancel - self.original_obj_data.append(self.store_initial_obj_state(obj, user_collections)) - - - for collection in obj.users_collection: - collection.objects.unlink(obj) - - prefs = context.preferences.addons[__package__.split('.')[0]].preferences - - if prefs.replace_name: - basename = prefs.obj_basename - elif obj.parent: - basename = obj.parent.name - else: - basename = obj.name - - mesh_collider_data = {} - mesh_collider_data['basename'] = basename - mesh_collider_data['new_collider'] = new_collider - collider_data.append(mesh_collider_data) - - if self.creation_mode[self.creation_mode_idx] == 'INDIVIDUAL': - for mesh_collider_data in collider_data: - basename = mesh_collider_data['basename'] - new_collider = mesh_collider_data['new_collider'] - - self.primitive_postprocessing(context, new_collider, user_collections) - self.new_colliders_list.append(new_collider) - super().set_collider_name(new_collider, basename) - - else: # self.creation_mode[self.creation_mode_idx] == 'SELECTION': - bpy.ops.object.select_all(action='DESELECT') - last_selected = None - for mesh_collider_data in collider_data: - basename = mesh_collider_data['basename'] - new_collider = mesh_collider_data['new_collider'] - new_collider.select_set(True) - - context.view_layer.objects.active = new_collider - bpy.ops.object.join() - - self.primitive_postprocessing(context, new_collider, user_collections) - self.new_colliders_list.append(new_collider) - super().set_collider_name(new_collider, basename) - - - elapsed_time = self.get_time_elapsed() - super().print_generation_time("Convert to Collider", elapsed_time) - self.report({'INFO'}, f"Convert to Collider: {float(elapsed_time)}") - - return {'RUNNING_MODAL'} - - -class OBJECT_OT_convert_to_mesh(Operator): - """Convert selected colliders to mesh objects""" - bl_idname = "object.convert_to_mesh" - bl_label = "Collider to Mesh" - bl_description = 'Convert selected colliders to meshes' - - my_string: bpy.props.StringProperty(name="Mesh Name", default='Mesh') - - def invoke(self, context, event): - wm = context.window_manager - return wm.invoke_props_dialog(self) - - def draw(self, context): - scene = context.scene - layout = self.layout - col = layout.column() - - row = col.row() - row.prop(self, "my_string") - - row = col.row() - row.prop(scene, "DefaultMeshMaterial", text='Material') - - @classmethod - def poll(cls, context): - - # Convert is only supported in object mode - if context.mode != 'OBJECT': - return False - - # Objects need to be selected - count = 0 - for obj in context.selected_objects: - if obj.type == 'MESH': - count = count + 1 - return count > 0 - - def execute(self, context): - colSettings = context.scene.collider_tools - count = 0 - - for obj in bpy.context.selected_objects.copy(): - if obj.get('isCollider'): - count += 1 - # Reste object properties to regular mesh - obj['isCollider'] = False - obj.color = (1, 1, 1, 1) - obj.name = OBJECT_OT_add_bounding_object.unique_name(self.my_string) - obj.display_type = 'TEXTURED' - - # replace collision material - remove_materials(obj) - if colSettings.defaultMeshMaterial: - assign_physics_material(obj, colSettings.defaultMeshMaterial.name) - else: - default_material = create_material('Material', (1, 1, 1, 1)) - colSettings.defaultMeshMaterial = default_material - assign_physics_material(obj, default_material.name) - - # remove from collision collection - prefs = context.preferences.addons[__package__.split('.')[0]].preferences - collection_name = prefs.col_collection_name - - # remove from collision collection - for collection in bpy.data.collections: - if collection.name == collection_name: - if obj.name in collection.objects: - collection.objects.unlink(obj) - - # add to default scene collection if the object is not part of any collection anymore - if len(obj.users_collection) == 0: - bpy.context.scene.collection.objects.link(obj) - - if count == 0: - self.report({'WARNING'}, 'No collider selected for conversion') - else: - self.report({'INFO'}, f"{count} colliders have been converted") - - return {'FINISHED'} diff --git a/collider_conversion/convert_to_collider.py b/collider_conversion/convert_to_collider.py new file mode 100644 index 0000000..7226f4d --- /dev/null +++ b/collider_conversion/convert_to_collider.py @@ -0,0 +1,136 @@ +import bpy +from bpy.types import Operator + +from ..collider_shapes.add_bounding_primitive import OBJECT_OT_add_bounding_object +default_shape = 'box_shape' +default_group = 'USER_01' + + +class OBJECT_OT_convert_to_collider(OBJECT_OT_add_bounding_object, Operator): + """Convert existing objects to be a collider""" + bl_idname = "object.convert_to_collider" + bl_label = "Mesh to Collider" + bl_description = 'Convert selected meshes to colliders' + + @classmethod + def poll(cls, context): + # Convert is only supported in object mode + return False if context.mode != 'OBJECT' else super().poll(context) + + def __init__(self): + super().__init__() + self.use_shape_change = True + self.use_decimation = True + self.is_mesh_to_collider = True + # self.use_creation_mode = False + self.shape = 'mesh_shape' + self.use_keep_original_materials = True + + def invoke(self, context, event): + super().invoke(context, event) + + self.collider_shapes_idx = 3 + self.collider_shapes = ['box_shape', 'sphere_shape', 'capsule_shape', 'convex_shape', + 'mesh_shape'] + + self.shape = self.collider_shapes[self.collider_shapes_idx] + + return {'RUNNING_MODAL'} + + def modal(self, context, event): + status = super().modal(context, event) + if status == {'FINISHED'}: + return {'FINISHED'} + if status == {'CANCELLED'}: + return {'CANCELLED'} + if status == {'PASS_THROUGH'}: + return {'PASS_THROUGH'} + + + elif event.type == 'Q' and event.value == 'RELEASE': + # toggle through display modes + self.collider_shapes_idx = (self.collider_shapes_idx + 1) % len(self.collider_shapes) + self.shape = self.collider_shapes[self.collider_shapes_idx] + for collider in self.new_colliders_list: + if collider: + collider['collider_shape'] = self.shape + self.update_names() + + return {'RUNNING_MODAL'} + + def execute(self, context): + # CLEANUP and INIT + super().execute(context) + + collider_data = [] + user_collections = [] + + # Create the bounding geometry, depending on edit or object mode. + for obj in self.selected_objects: + + # skip if invalid object + if not self.is_valid_object(obj): + continue + if obj and obj.type in self.valid_object_types: + obj = self.convert_to_mesh(context, obj) + + new_collider = obj.copy() + new_collider.data = obj.data.copy() + user_collections = obj.users_collection + + # New collider to scene + bpy.context.collection.objects.link(new_collider) + + # store initial state for operation cancel + self.original_obj_data.append(self.store_initial_obj_state(obj, user_collections)) + + + for collection in obj.users_collection: + collection.objects.unlink(obj) + + prefs = context.preferences.addons[__package__.split('.')[0]].preferences + + if prefs.replace_name: + basename = prefs.obj_basename + elif obj.parent: + basename = obj.parent.name + else: + basename = obj.name + + mesh_collider_data = {} + mesh_collider_data['basename'] = basename + mesh_collider_data['new_collider'] = new_collider + collider_data.append(mesh_collider_data) + + if self.creation_mode[self.creation_mode_idx] == 'INDIVIDUAL': + for mesh_collider_data in collider_data: + basename = mesh_collider_data['basename'] + new_collider = mesh_collider_data['new_collider'] + + self.primitive_postprocessing(context, new_collider, user_collections) + self.new_colliders_list.append(new_collider) + super().set_collider_name(new_collider, basename) + + else: # self.creation_mode[self.creation_mode_idx] == 'SELECTION': + bpy.ops.object.select_all(action='DESELECT') + last_selected = None + for mesh_collider_data in collider_data: + basename = mesh_collider_data['basename'] + new_collider = mesh_collider_data['new_collider'] + new_collider.select_set(True) + + context.view_layer.objects.active = new_collider + bpy.ops.object.join() + + self.primitive_postprocessing(context, new_collider, user_collections) + self.new_colliders_list.append(new_collider) + super().set_collider_name(new_collider, basename) + + + elapsed_time = self.get_time_elapsed() + super().print_generation_time("Convert to Collider", elapsed_time) + self.report({'INFO'}, f"Convert to Collider: {float(elapsed_time)}") + + return {'RUNNING_MODAL'} + + diff --git a/collider_conversion/convert_to_mesh.py b/collider_conversion/convert_to_mesh.py new file mode 100644 index 0000000..00f1af3 --- /dev/null +++ b/collider_conversion/convert_to_mesh.py @@ -0,0 +1,88 @@ +import bpy +from bpy.types import Operator + +from ..collider_shapes.add_bounding_primitive import OBJECT_OT_add_bounding_object +from ..pyshics_materials.material_functions import assign_physics_material, create_material, remove_materials + +default_shape = 'box_shape' +default_group = 'USER_01' + +class OBJECT_OT_convert_to_mesh(Operator): + """Convert selected colliders to mesh objects""" + bl_idname = "object.convert_to_mesh" + bl_label = "Collider to Mesh" + bl_description = 'Convert selected colliders to meshes' + + my_string: bpy.props.StringProperty(name="Mesh Name", default='Mesh') + + def invoke(self, context, event): + wm = context.window_manager + return wm.invoke_props_dialog(self) + + def draw(self, context): + scene = context.scene + layout = self.layout + col = layout.column() + + row = col.row() + row.prop(self, "my_string") + + row = col.row() + row.prop(scene, "DefaultMeshMaterial", text='Material') + + @classmethod + def poll(cls, context): + + # Convert is only supported in object mode + if context.mode != 'OBJECT': + return False + + # Objects need to be selected + count = 0 + for obj in context.selected_objects: + if obj.type == 'MESH': + count = count + 1 + return count > 0 + + def execute(self, context): + colSettings = context.scene.collider_tools + count = 0 + + for obj in bpy.context.selected_objects.copy(): + if obj.get('isCollider'): + count += 1 + # Reste object properties to regular mesh + obj['isCollider'] = False + obj.color = (1, 1, 1, 1) + obj.name = OBJECT_OT_add_bounding_object.unique_name(self.my_string) + obj.display_type = 'TEXTURED' + + # replace collision material + remove_materials(obj) + if colSettings.defaultMeshMaterial: + assign_physics_material(obj, colSettings.defaultMeshMaterial.name) + else: + default_material = create_material('Material', (1, 1, 1, 1)) + colSettings.defaultMeshMaterial = default_material + assign_physics_material(obj, default_material.name) + + # remove from collision collection + prefs = context.preferences.addons[__package__.split('.')[0]].preferences + collection_name = prefs.col_collection_name + + # remove from collision collection + for collection in bpy.data.collections: + if collection.name == collection_name: + if obj.name in collection.objects: + collection.objects.unlink(obj) + + # add to default scene collection if the object is not part of any collection anymore + if len(obj.users_collection) == 0: + bpy.context.scene.collection.objects.link(obj) + + if count == 0: + self.report({'WARNING'}, 'No collider selected for conversion') + else: + self.report({'INFO'}, f"{count} colliders have been converted") + + return {'FINISHED'} \ No newline at end of file diff --git a/collider_conversion/regenerate_name.py b/collider_conversion/regenerate_name.py new file mode 100644 index 0000000..1603fa9 --- /dev/null +++ b/collider_conversion/regenerate_name.py @@ -0,0 +1,53 @@ +from bpy.types import Operator + +from ..collider_shapes.add_bounding_primitive import OBJECT_OT_add_bounding_object + +default_shape = 'box_shape' +default_group = 'USER_01' + + +class OBJECT_OT_regenerate_name(Operator): + """Regenerate selected collider names based on preset""" + bl_idname = "object.regenerate_name" + bl_label = "Regenerate Name" + bl_description = 'Regenerate selected collider names based on preset' + + @classmethod + def poll(cls, context): + + # Convert is only supported in object mode + if context.mode != 'OBJECT': + return False + + count = 0 + for obj in context.selected_objects: + if obj.type == 'MESH': + count = count + 1 + return count > 0 + + def execute(self, context): + prefs = context.preferences.addons[__package__.split('.')[0]].preferences + + for obj in context.selected_objects.copy(): + + # skip if invalid object + if obj is None or obj.type != "MESH": + continue + + if prefs.replace_name: + basename = prefs.obj_basename + elif obj.parent: + basename = obj.parent.name + else: + basename = obj.name + + # get collider shape and group and set to default there is no previous data + shape_identifier = default_shape if obj.get('collider_shape') is None else obj.get('collider_shape') + user_group = default_group if obj.get('collider_group') is None else obj.get('collider_group') + + new_name = OBJECT_OT_add_bounding_object.class_collider_name(shape_identifier, user_group, + basename=basename) + obj.name = new_name + OBJECT_OT_add_bounding_object.set_data_name(obj, new_name, "_data") + + return {'FINISHED'} diff --git a/collider_shapes/add_bounding_box.py b/collider_shapes/add_bounding_box.py index 8505fde..48c718e 100644 --- a/collider_shapes/add_bounding_box.py +++ b/collider_shapes/add_bounding_box.py @@ -128,8 +128,15 @@ def execute(self, context): continue if obj and obj.type in self.valid_object_types: - print('ZZZZZZZZZZZZZZZZZZZZZZZZZ') - obj = self.convert_to_mesh(context, obj) + if obj.type is not 'MESH': + + # store initial state for operation cancel + original_obj = obj + user_collections = original_obj.users_collection + self.original_obj_data.append(self.store_initial_obj_state(original_obj, user_collections)) + + # convert meshes + obj = self.convert_to_mesh(context, obj) context.view_layer.objects.active = obj bounding_box_data = {} diff --git a/collider_shapes/add_bounding_primitive.py b/collider_shapes/add_bounding_primitive.py index 6e68670..ef448e5 100644 --- a/collider_shapes/add_bounding_primitive.py +++ b/collider_shapes/add_bounding_primitive.py @@ -853,6 +853,15 @@ def print_generation_time(shape, time): print(shape) print("Time elapsed: ", str(time)) + @staticmethod + def store_initial_obj_state(obj, collections): + dic = {} + dic['obj'] = obj + col_list = [col.name for col in collections] + dic['users_collection'] = col_list + + return dic + def convert_to_mesh(self, context, object): deg = context.evaluated_depsgraph_get() me = bpy.data.meshes.new_from_object(object.evaluated_get(deg), depsgraph=deg) @@ -993,16 +1002,6 @@ def cancel_cleanup(self, context): objs = bpy.data.objects objs.remove(collider_obj, do_unlink=True) - - for data in self.original_obj_data: - # Assign unlinked data to user groups - original_obj = data['obj'] - original_user_groups = data['users_collection'] - - bpy.context.collection.objects.link(original_obj) - for col in original_user_groups: - self.add_to_collections(original_obj, col) - # All other operators else: # Remove previously created collisions @@ -1012,6 +1011,16 @@ def cancel_cleanup(self, context): objs = bpy.data.objects objs.remove(obj, do_unlink=True) + # delete original data + for data in self.original_obj_data: + # Assign unlinked data to user groups + original_obj = data['obj'] + original_user_groups = data['users_collection'] + + bpy.context.collection.objects.link(original_obj) + for col in original_user_groups: + self.add_to_collections(original_obj, col) + context.space_data.shading.color_type = self.original_color_type try: @@ -1068,7 +1077,7 @@ def __init__(self): self.use_recenter_origin = False self.use_custom_rotation = False - self.valid_object_types = ['CURVE', 'SURFACE', 'FONT', 'META'] + self.valid_object_types = ['MESH', 'CURVE', 'SURFACE', 'FONT', 'META'] @classmethod def poll(cls, context): @@ -1485,6 +1494,9 @@ def execute(self, context): self.remove_objects(self.new_colliders_list) self.new_colliders_list = [] + # original data to be restored on cancelation or deleted on accept + self.original_obj_data = [] + # reset previously stored displace modifiers when creating a new object self.displace_modifiers = [] From c1fa43b549f66a09371c9d1078e27b92acf14966 Mon Sep 17 00:00:00 2001 From: Matthias Patscheider Date: Mon, 26 Jun 2023 19:45:55 +0300 Subject: [PATCH 05/23] Split mesh operation --- auto_Convex/add_bounding_auto_convex.py | 49 +------------------------ bmesh_operations/mesh_edit.py | 47 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 48 deletions(-) create mode 100644 bmesh_operations/mesh_edit.py diff --git a/auto_Convex/add_bounding_auto_convex.py b/auto_Convex/add_bounding_auto_convex.py index 9d3f078..1b5b334 100644 --- a/auto_Convex/add_bounding_auto_convex.py +++ b/auto_Convex/add_bounding_auto_convex.py @@ -7,54 +7,7 @@ from bpy.types import Operator from ..collider_shapes.add_bounding_primitive import OBJECT_OT_add_bounding_object - - -def bmesh_join(list_of_bmeshes, list_of_matrices, normal_update=False): - # sourcery skip: use-contextlib-suppress - """ takes as input a list of bm references and outputs a single merged bmesh - allows an additional 'normal_update=True' to force _normal_ calculations. - """ - bm = bmesh.new() - add_vert = bm.verts.new - add_face = bm.faces.new - add_edge = bm.edges.new - - for bm_to_add, matrix in zip(list_of_bmeshes, list_of_matrices): - bm_to_add.transform(matrix) - - for bm_to_add in list_of_bmeshes: - offset = len(bm.verts) - - for v in bm_to_add.verts: - add_vert(v.co) - - bm.verts.index_update() - bm.verts.ensure_lookup_table() - - if bm_to_add.faces: - for face in bm_to_add.faces: - add_face(tuple(bm.verts[i.index + offset] for i in face.verts)) - bm.faces.index_update() - - if bm_to_add.edges: - for edge in bm_to_add.edges: - edge_seq = tuple(bm.verts[i.index + offset] - for i in edge.verts) - try: - add_edge(edge_seq) - except ValueError: - # edge exists! - pass - bm.edges.index_update() - - if normal_update: - bm.normal_update() - - me = bpy.data.meshes.new("joined_mesh") - bm.to_mesh(me) - - return me - +from ..bmesh_operations.mesh_edit import bmesh_join class VHACD_OT_convex_decomposition(OBJECT_OT_add_bounding_object, Operator): bl_idname = 'collision.vhacd' diff --git a/bmesh_operations/mesh_edit.py b/bmesh_operations/mesh_edit.py new file mode 100644 index 0000000..49d4a6d --- /dev/null +++ b/bmesh_operations/mesh_edit.py @@ -0,0 +1,47 @@ +import bpy, bmesh + +def bmesh_join(list_of_bmeshes, list_of_matrices, normal_update=False): + # sourcery skip: use-contextlib-suppress + """ takes as input a list of bm references and outputs a single merged bmesh + allows an additional 'normal_update=True' to force _normal_ calculations. + """ + bm = bmesh.new() + add_vert = bm.verts.new + add_face = bm.faces.new + add_edge = bm.edges.new + + for bm_to_add, matrix in zip(list_of_bmeshes, list_of_matrices): + bm_to_add.transform(matrix) + + for bm_to_add in list_of_bmeshes: + offset = len(bm.verts) + + for v in bm_to_add.verts: + add_vert(v.co) + + bm.verts.index_update() + bm.verts.ensure_lookup_table() + + if bm_to_add.faces: + for face in bm_to_add.faces: + add_face(tuple(bm.verts[i.index + offset] for i in face.verts)) + bm.faces.index_update() + + if bm_to_add.edges: + for edge in bm_to_add.edges: + edge_seq = tuple(bm.verts[i.index + offset] + for i in edge.verts) + try: + add_edge(edge_seq) + except ValueError: + # edge exists! + pass + bm.edges.index_update() + + if normal_update: + bm.normal_update() + + me = bpy.data.meshes.new("joined_mesh") + bm.to_mesh(me) + + return me \ No newline at end of file From 4fc991b20161cf601de1459ed3198dd4257231d7 Mon Sep 17 00:00:00 2001 From: Matthias Patscheider Date: Tue, 27 Jun 2023 09:57:15 +0300 Subject: [PATCH 06/23] update --- bmesh_operations/__init__.py | 0 bmesh_operations/box_creation.py | 63 ++++++++++++++ .../capsule_generation.py | 0 .../capsule_height_radius.py | 0 collider_shapes/add_bounding_box.py | 84 +++---------------- collider_shapes/add_bounding_capsule.py | 4 +- collider_shapes/add_bounding_primitive.py | 7 +- pyshics_materials/__init__.py | 7 +- 8 files changed, 82 insertions(+), 83 deletions(-) create mode 100644 bmesh_operations/__init__.py create mode 100644 bmesh_operations/box_creation.py rename {collider_shapes => bmesh_operations}/capsule_generation.py (100%) rename {collider_shapes => bmesh_operations}/capsule_height_radius.py (100%) diff --git a/bmesh_operations/__init__.py b/bmesh_operations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bmesh_operations/box_creation.py b/bmesh_operations/box_creation.py new file mode 100644 index 0000000..8c70b91 --- /dev/null +++ b/bmesh_operations/box_creation.py @@ -0,0 +1,63 @@ +import bmesh +import bpy + +from bpy_extras.object_utils import object_data_add + + +tmp_name = 'box_collider' + +# vertex indizes defining the faces of the cube +face_order = [ + (0, 1, 2, 3), + (4, 7, 6, 5), + (0, 4, 5, 1), + (1, 5, 6, 2), + (2, 6, 7, 3), + (4, 0, 3, 7), +] + + +def add_box_object(context, vertices): + """Generate a new object from the given vertices""" + + global tmp_name + + verts = vertices + edges = [] + faces = [[0, 1, 2, 3], [7, 6, 5, 4], [5, 6, 2, 1], [0, 3, 7, 4], [3, 2, 6, 7], [4, 5, 1, 0]] + + mesh = bpy.data.meshes.new(name=tmp_name) + mesh.from_pydata(verts, edges, faces) + + return object_data_add(context, mesh, operator=None, name=None) + + +def verts_faces_to_bbox_collider(self, context, verts_loc): + """Create box collider for selected mesh area in edit mode""" + + global tmp_name + + # add new mesh + mesh = bpy.data.meshes.new(tmp_name) + bm = bmesh.new() + + # create mesh vertices + for v_co in verts_loc: + bm.verts.new(v_co) + + # connect vertices to faces + bm.verts.ensure_lookup_table() + for f_idx in face_order: + bm.faces.new([bm.verts[i] for i in f_idx]) + + # update bmesh to draw properly in viewport + bm.to_mesh(mesh) + mesh.update() + + # create new object from mesh and link it to collection + new_collider = bpy.data.objects.new(tmp_name, mesh) + + root_collection = context.scene.collection + root_collection.objects.link(new_collider) + + return new_collider \ No newline at end of file diff --git a/collider_shapes/capsule_generation.py b/bmesh_operations/capsule_generation.py similarity index 100% rename from collider_shapes/capsule_generation.py rename to bmesh_operations/capsule_generation.py diff --git a/collider_shapes/capsule_height_radius.py b/bmesh_operations/capsule_height_radius.py similarity index 100% rename from collider_shapes/capsule_height_radius.py rename to bmesh_operations/capsule_height_radius.py diff --git a/collider_shapes/add_bounding_box.py b/collider_shapes/add_bounding_box.py index 48c718e..0381ee3 100644 --- a/collider_shapes/add_bounding_box.py +++ b/collider_shapes/add_bounding_box.py @@ -1,67 +1,11 @@ -import bmesh import bpy from bpy.types import Operator -from bpy_extras.object_utils import object_data_add from .add_bounding_primitive import OBJECT_OT_add_bounding_object - +from ..bmesh_operations.box_creation import verts_faces_to_bbox_collider tmp_name = 'box_collider' -# vertex indizes defining the faces of the cube -face_order = [ - (0, 1, 2, 3), - (4, 7, 6, 5), - (0, 4, 5, 1), - (1, 5, 6, 2), - (2, 6, 7, 3), - (4, 0, 3, 7), -] - - -def add_box_object(context, vertices): - """Generate a new object from the given vertices""" - - global tmp_name - - verts = vertices - edges = [] - faces = [[0, 1, 2, 3], [7, 6, 5, 4], [5, 6, 2, 1], [0, 3, 7, 4], [3, 2, 6, 7], [4, 5, 1, 0]] - - mesh = bpy.data.meshes.new(name=tmp_name) - mesh.from_pydata(verts, edges, faces) - - return object_data_add(context, mesh, operator=None, name=None) - - -def verts_faces_to_bbox_collider(self, context, verts_loc, faces): - """Create box collider for selected mesh area in edit mode""" - global tmp_name - - # add new mesh - mesh = bpy.data.meshes.new(tmp_name) - bm = bmesh.new() - - # create mesh vertices - for v_co in verts_loc: - bm.verts.new(v_co) - - # connect vertices to faces - bm.verts.ensure_lookup_table() - for f_idx in faces: - bm.faces.new([bm.verts[i] for i in f_idx]) - - # update bmesh to draw properly in viewport - bm.to_mesh(mesh) - mesh.update() - - # create new object from mesh and link it to collection - new_collider = bpy.data.objects.new(tmp_name, mesh) - - root_collection = context.scene.collection - root_collection.objects.link(new_collider) - - return new_collider class OBJECT_OT_add_bounding_box(OBJECT_OT_add_bounding_object, Operator): @@ -92,8 +36,6 @@ def modal(self, context, event): if status == {'PASS_THROUGH'}: return {'PASS_THROUGH'} - colSettings = context.scene.collider_tools - # change bounding object settings if event.type == 'G' and event.value == 'RELEASE': self.my_space = 'GLOBAL' @@ -114,29 +56,28 @@ def execute(self, context): # CLEANUP and INIT super().execute(context) - colSettings = context.scene.collider_tools - # List for storing dictionaries of data used to generate the collision meshes collider_data = [] verts_co = [] # Create the bounding geometry, depending on edit or object mode. - for obj in self.selected_objects: + for base_ob in self.selected_objects: # skip if invalid object - if not self.is_valid_object(obj): + if not self.is_valid_object(base_ob): continue - if obj and obj.type in self.valid_object_types: - if obj.type is not 'MESH': + if base_ob and base_ob.type in self.valid_object_types: + if base_ob.type == 'MESH': + obj = base_ob + else: # store initial state for operation cancel - original_obj = obj - user_collections = original_obj.users_collection - self.original_obj_data.append(self.store_initial_obj_state(original_obj, user_collections)) + user_collections = base_ob.users_collection + self.original_obj_data.append(self.store_initial_obj_state(base_ob, user_collections)) # convert meshes - obj = self.convert_to_mesh(context, obj) + obj = self.convert_to_mesh(context, base_ob) context.view_layer.objects.active = obj bounding_box_data = {} @@ -156,7 +97,7 @@ def execute(self, context): verts_loc, center_point = self.generate_bounding_box(co) # store data needed to generate a bounding box in a dictionary - bounding_box_data['parent'] = obj + bounding_box_data['parent'] = base_ob bounding_box_data['verts_loc'] = verts_loc bounding_box_data['center_point'] = center_point @@ -177,8 +118,7 @@ def execute(self, context): verts_loc = bounding_box_data['verts_loc'] center_point = bounding_box_data['center_point'] - global face_order - new_collider = verts_faces_to_bbox_collider(self, context, verts_loc, face_order) + new_collider = verts_faces_to_bbox_collider(self, context, verts_loc) scene = context.scene if self.my_space == 'LOCAL': diff --git a/collider_shapes/add_bounding_capsule.py b/collider_shapes/add_bounding_capsule.py index 5959f2d..8bada0a 100644 --- a/collider_shapes/add_bounding_capsule.py +++ b/collider_shapes/add_bounding_capsule.py @@ -1,7 +1,7 @@ import bpy from bpy.types import Operator -from mathutils import Matrix, Vector -from . import capsule_generation as Capsule +from mathutils import Vector +from ..bmesh_operations import capsule_generation as Capsule from math import radians from .utilities import get_sca_matrix, get_rot_matrix, get_loc_matrix diff --git a/collider_shapes/add_bounding_primitive.py b/collider_shapes/add_bounding_primitive.py index ef448e5..36bf910 100644 --- a/collider_shapes/add_bounding_primitive.py +++ b/collider_shapes/add_bounding_primitive.py @@ -1017,9 +1017,10 @@ def cancel_cleanup(self, context): original_obj = data['obj'] original_user_groups = data['users_collection'] - bpy.context.collection.objects.link(original_obj) - for col in original_user_groups: - self.add_to_collections(original_obj, col) + if self.is_mesh_to_collider: + bpy.context.collection.objects.link(original_obj) + for col in original_user_groups: + self.add_to_collections(original_obj, col) context.space_data.shading.color_type = self.original_color_type diff --git a/pyshics_materials/__init__.py b/pyshics_materials/__init__.py index 5055944..f188c1e 100644 --- a/pyshics_materials/__init__.py +++ b/pyshics_materials/__init__.py @@ -13,17 +13,13 @@ physics_materials.MATERIAL_OT_physics_material_random_color, ) -# def defaultActive(): -# mat = material_functions.create_default_material() -# return mat + def register(): scene = bpy.types.Scene scene.use_physics_tag = bpy.props.BoolProperty(name="Filter", default=False) - # scene.active_physics_material = bpy.props.StringProperty(name="Active Physics Material", default="") materialType = bpy.types.Material - #scene.active_physics_material = bpy.props.PointerProperty(name="My Node", default=defaultActive(), type=materialType) scene.active_physics_material = bpy.props.PointerProperty(name="My Node", type=materialType) materialType.edit = bpy.props.BoolProperty(name="Manipulate", default=False) @@ -36,7 +32,6 @@ def register(): def unregister(): - wm = bpy.types.WindowManager materialType = bpy.types.Material from bpy.utils import unregister_class From 0fabd5c9a1cd5a5e73ea633e9ead179bdf003968 Mon Sep 17 00:00:00 2001 From: Matthias Patscheider Date: Tue, 27 Jun 2023 11:17:37 +0300 Subject: [PATCH 07/23] remove tmp objects --- collider_shapes/add_bounding_box.py | 2 +- collider_shapes/add_bounding_primitive.py | 20 ++++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/collider_shapes/add_bounding_box.py b/collider_shapes/add_bounding_box.py index 0381ee3..1abe826 100644 --- a/collider_shapes/add_bounding_box.py +++ b/collider_shapes/add_bounding_box.py @@ -75,9 +75,9 @@ def execute(self, context): # store initial state for operation cancel user_collections = base_ob.users_collection self.original_obj_data.append(self.store_initial_obj_state(base_ob, user_collections)) - # convert meshes obj = self.convert_to_mesh(context, base_ob) + self.tmp_meshes.append(obj) context.view_layer.objects.active = obj bounding_box_data = {} diff --git a/collider_shapes/add_bounding_primitive.py b/collider_shapes/add_bounding_primitive.py index 36bf910..df3e790 100644 --- a/collider_shapes/add_bounding_primitive.py +++ b/collider_shapes/add_bounding_primitive.py @@ -609,7 +609,9 @@ def set_collisions_wire_preview(self, mode): @staticmethod def remove_objects(list): - '''Remove previously created collisions''' + '''Remove list of objects''' + print(str(list)) + if len(list) > 0: for ob in list: if ob: @@ -996,11 +998,7 @@ def get_time_elapsed(self): def cancel_cleanup(self, context): if self.is_mesh_to_collider: if self.new_colliders_list: - for collider_obj in self.new_colliders_list: - # Remove previously created collisions - if collider_obj: - objs = bpy.data.objects - objs.remove(collider_obj, do_unlink=True) + self.remove_objects(self.new_colliders_list) # All other operators else: @@ -1011,6 +1009,9 @@ def cancel_cleanup(self, context): objs = bpy.data.objects objs.remove(obj, do_unlink=True) + # Delete temporary objects + self.remove_objects(self.tmp_meshes) + # delete original data for data in self.original_obj_data: # Assign unlinked data to user groups @@ -1115,6 +1116,7 @@ def invoke(self, context, event): # General init settings self.new_colliders_list = [] + self.tmp_meshes = [] self.col_rotation_matrix_list = [] self.col_center_loc_list = [] @@ -1268,6 +1270,9 @@ def modal(self, context, event): else: obj.show_wire = False + # Delete temporary generated meshes + self.remove_objects(self.tmp_meshes) + try: bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW') except ValueError: @@ -1492,8 +1497,11 @@ def execute(self, context): print("AttributeError: bug #328") # Remove objects from previous generation + self.remove_objects(self.tmp_meshes) self.remove_objects(self.new_colliders_list) self.new_colliders_list = [] + self.original_obj_data = [] + self.tmp_meshes = [] # original data to be restored on cancelation or deleted on accept self.original_obj_data = [] From 7763f4d3423387719806762a9224e25e156edf73 Mon Sep 17 00:00:00 2001 From: Matthias Patscheider Date: Tue, 27 Jun 2023 11:23:53 +0300 Subject: [PATCH 08/23] Support additional generation types --- auto_Convex/add_bounding_auto_convex.py | 18 ++++++++++++++---- collider_conversion/convert_to_collider.py | 18 ++++++++++++++---- collider_shapes/add_bounding_capsule.py | 17 +++++++++++++---- collider_shapes/add_bounding_convex_hull.py | 17 +++++++++++++---- collider_shapes/add_bounding_cylinder.py | 17 +++++++++++++---- collider_shapes/add_bounding_sphere.py | 17 +++++++++++++---- collider_shapes/add_collision_mesh.py | 18 ++++++++++++++---- collider_shapes/add_minimum_bounding_box.py | 18 ++++++++++++++---- 8 files changed, 108 insertions(+), 32 deletions(-) diff --git a/auto_Convex/add_bounding_auto_convex.py b/auto_Convex/add_bounding_auto_convex.py index 1b5b334..3f46dbe 100644 --- a/auto_Convex/add_bounding_auto_convex.py +++ b/auto_Convex/add_bounding_auto_convex.py @@ -92,13 +92,23 @@ def execute(self, context): meshes = [] matrices = [] - for obj in self.selected_objects: + for base_ob in self.selected_objects: # skip if invalid object - if not self.is_valid_object(obj): + if not self.is_valid_object(base_ob): continue - if obj and obj.type in self.valid_object_types: - obj = self.convert_to_mesh(context, obj) + + if base_ob and base_ob.type in self.valid_object_types: + if base_ob.type == 'MESH': + obj = base_ob + + else: + # store initial state for operation cancel + user_collections = base_ob.users_collection + self.original_obj_data.append(self.store_initial_obj_state(base_ob, user_collections)) + # convert meshes + obj = self.convert_to_mesh(context, base_ob) + self.tmp_meshes.append(obj) context.view_layer.objects.active = obj diff --git a/collider_conversion/convert_to_collider.py b/collider_conversion/convert_to_collider.py index 7226f4d..e0762a8 100644 --- a/collider_conversion/convert_to_collider.py +++ b/collider_conversion/convert_to_collider.py @@ -66,13 +66,23 @@ def execute(self, context): user_collections = [] # Create the bounding geometry, depending on edit or object mode. - for obj in self.selected_objects: + for base_ob in self.selected_objects: # skip if invalid object - if not self.is_valid_object(obj): + if not self.is_valid_object(base_ob): continue - if obj and obj.type in self.valid_object_types: - obj = self.convert_to_mesh(context, obj) + + if base_ob and base_ob.type in self.valid_object_types: + if base_ob.type == 'MESH': + obj = base_ob + + else: + # store initial state for operation cancel + user_collections = base_ob.users_collection + self.original_obj_data.append(self.store_initial_obj_state(base_ob, user_collections)) + # convert meshes + obj = self.convert_to_mesh(context, base_ob) + self.tmp_meshes.append(obj) new_collider = obj.copy() new_collider.data = obj.data.copy() diff --git a/collider_shapes/add_bounding_capsule.py b/collider_shapes/add_bounding_capsule.py index 8bada0a..f1416ba 100644 --- a/collider_shapes/add_bounding_capsule.py +++ b/collider_shapes/add_bounding_capsule.py @@ -81,14 +81,23 @@ def execute(self, context): verts_co = [] # Create the bounding geometry, depending on edit or object mode. - for obj in self.selected_objects: + for base_ob in self.selected_objects: # skip if invalid object - if not self.is_valid_object(obj): + if not self.is_valid_object(base_ob): continue - if obj and obj.type in self.valid_object_types: - obj = self.convert_to_mesh(context, obj) + if base_ob and base_ob.type in self.valid_object_types: + if base_ob.type == 'MESH': + obj = base_ob + + else: + # store initial state for operation cancel + user_collections = base_ob.users_collection + self.original_obj_data.append(self.store_initial_obj_state(base_ob, user_collections)) + # convert meshes + obj = self.convert_to_mesh(context, base_ob) + self.tmp_meshes.append(obj) context.view_layer.objects.active = obj bounding_capsule_data = {} diff --git a/collider_shapes/add_bounding_convex_hull.py b/collider_shapes/add_bounding_convex_hull.py index 99d6007..6eb41ba 100644 --- a/collider_shapes/add_bounding_convex_hull.py +++ b/collider_shapes/add_bounding_convex_hull.py @@ -49,14 +49,23 @@ def execute(self, context): verts_co = [] # Duplicate original meshes to convert to collider - for obj in self.selected_objects: + for base_ob in self.selected_objects: # skip if invalid object - if not self.is_valid_object(obj): + if not self.is_valid_object(base_ob): continue - if obj and obj.type in self.valid_object_types: - obj = self.convert_to_mesh(context, obj) + if base_ob and base_ob.type in self.valid_object_types: + if base_ob.type == 'MESH': + obj = base_ob + + else: + # store initial state for operation cancel + user_collections = base_ob.users_collection + self.original_obj_data.append(self.store_initial_obj_state(base_ob, user_collections)) + # convert meshes + obj = self.convert_to_mesh(context, base_ob) + self.tmp_meshes.append(obj) convex_collision_data = {} diff --git a/collider_shapes/add_bounding_cylinder.py b/collider_shapes/add_bounding_cylinder.py index 02f0c11..6f85c8f 100644 --- a/collider_shapes/add_bounding_cylinder.py +++ b/collider_shapes/add_bounding_cylinder.py @@ -258,14 +258,23 @@ def execute(self, context): collider_data = [] verts_co = [] - for obj in context.selected_objects.copy(): + for base_ob in self.selected_objects: # skip if invalid object - if not self.is_valid_object(obj): + if not self.is_valid_object(base_ob): continue - if obj and obj.type in self.valid_object_types: - obj = self.convert_to_mesh(context, obj) + if base_ob and base_ob.type in self.valid_object_types: + if base_ob.type == 'MESH': + obj = base_ob + + else: + # store initial state for operation cancel + user_collections = base_ob.users_collection + self.original_obj_data.append(self.store_initial_obj_state(base_ob, user_collections)) + # convert meshes + obj = self.convert_to_mesh(context, base_ob) + self.tmp_meshes.append(obj) bounding_cylinder_data = {} diff --git a/collider_shapes/add_bounding_sphere.py b/collider_shapes/add_bounding_sphere.py index 09f4544..a58706f 100644 --- a/collider_shapes/add_bounding_sphere.py +++ b/collider_shapes/add_bounding_sphere.py @@ -168,14 +168,23 @@ def execute(self, context): verts_co = [] # Create the bounding geometry, depending on edit or object mode. - for obj in self.selected_objects: + for base_ob in self.selected_objects: # skip if invalid object - if not self.is_valid_object(obj): + if not self.is_valid_object(base_ob): continue - if obj and obj.type in self.valid_object_types: - obj = self.convert_to_mesh(context, obj) + if base_ob and base_ob.type in self.valid_object_types: + if base_ob.type == 'MESH': + obj = base_ob + + else: + # store initial state for operation cancel + user_collections = base_ob.users_collection + self.original_obj_data.append(self.store_initial_obj_state(base_ob, user_collections)) + # convert meshes + obj = self.convert_to_mesh(context, base_ob) + self.tmp_meshes.append(obj) initial_mod_state = {} context.view_layer.objects.active = obj diff --git a/collider_shapes/add_collision_mesh.py b/collider_shapes/add_collision_mesh.py index 000a163..3458aa3 100644 --- a/collider_shapes/add_collision_mesh.py +++ b/collider_shapes/add_collision_mesh.py @@ -54,13 +54,23 @@ def execute(self, context): collider_data = [] - for obj in self.selected_objects: + for base_ob in self.selected_objects: # skip if invalid object - if not self.is_valid_object(obj): + if not self.is_valid_object(base_ob): continue - if obj and obj.type in self.valid_object_types: - obj = self.convert_to_mesh(context, obj) + + if base_ob and base_ob.type in self.valid_object_types: + if base_ob.type == 'MESH': + obj = base_ob + + else: + # store initial state for operation cancel + user_collections = base_ob.users_collection + self.original_obj_data.append(self.store_initial_obj_state(base_ob, user_collections)) + # convert meshes + obj = self.convert_to_mesh(context, base_ob) + self.tmp_meshes.append(obj) mesh_collider_data = {} diff --git a/collider_shapes/add_minimum_bounding_box.py b/collider_shapes/add_minimum_bounding_box.py index aa0861a..0c160cf 100644 --- a/collider_shapes/add_minimum_bounding_box.py +++ b/collider_shapes/add_minimum_bounding_box.py @@ -148,13 +148,23 @@ def execute(self, context): verts_co = [] # Create the bounding geometry, depending on edit or object mode. - for obj in self.selected_objects: + for base_ob in self.selected_objects: # skip if invalid object - if not self.is_valid_object(obj): + if not self.is_valid_object(base_ob): continue - if obj and obj.type in self.valid_object_types: - obj = self.convert_to_mesh(context, obj) + + if base_ob and base_ob.type in self.valid_object_types: + if base_ob.type == 'MESH': + obj = base_ob + + else: + # store initial state for operation cancel + user_collections = base_ob.users_collection + self.original_obj_data.append(self.store_initial_obj_state(base_ob, user_collections)) + # convert meshes + obj = self.convert_to_mesh(context, base_ob) + self.tmp_meshes.append(obj) bounding_box_data = {} From f03bfdd1a2106ce923d6f38f71e7346c3d2737bc Mon Sep 17 00:00:00 2001 From: Matthias Patscheider Date: Tue, 27 Jun 2023 15:23:50 +0300 Subject: [PATCH 09/23] #71 Support more object types --- auto_Convex/add_bounding_auto_convex.py | 2 +- collider_shapes/add_bounding_capsule.py | 2 +- collider_shapes/add_bounding_convex_hull.py | 2 +- collider_shapes/add_bounding_cylinder.py | 2 +- collider_shapes/add_bounding_sphere.py | 2 +- collider_shapes/add_collision_mesh.py | 2 +- collider_shapes/add_minimum_bounding_box.py | 2 +- ui/properties_panels.py | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/auto_Convex/add_bounding_auto_convex.py b/auto_Convex/add_bounding_auto_convex.py index 3f46dbe..744288d 100644 --- a/auto_Convex/add_bounding_auto_convex.py +++ b/auto_Convex/add_bounding_auto_convex.py @@ -124,7 +124,7 @@ def execute(self, context): if self.creation_mode[self.creation_mode_idx] == 'INDIVIDUAL': convex_collision_data = {} - convex_collision_data['parent'] = obj + convex_collision_data['parent'] = base_ob convex_collision_data['mesh'] = new_mesh collider_data.append(convex_collision_data) diff --git a/collider_shapes/add_bounding_capsule.py b/collider_shapes/add_bounding_capsule.py index f1416ba..162821d 100644 --- a/collider_shapes/add_bounding_capsule.py +++ b/collider_shapes/add_bounding_capsule.py @@ -141,7 +141,7 @@ def execute(self, context): # store data needed to generate a bounding box in a dictionary - bounding_capsule_data['parent'] = obj + bounding_capsule_data['parent'] = base_ob bounding_capsule_data['verts_loc'] = coordinates bounding_capsule_data['center_point'] = [center[0], center[1], center[2]] collider_data.append(bounding_capsule_data) diff --git a/collider_shapes/add_bounding_convex_hull.py b/collider_shapes/add_bounding_convex_hull.py index 6eb41ba..befa450 100644 --- a/collider_shapes/add_bounding_convex_hull.py +++ b/collider_shapes/add_bounding_convex_hull.py @@ -82,7 +82,7 @@ def execute(self, context): if self.creation_mode[self.creation_mode_idx] == 'INDIVIDUAL': # duplicate object - convex_collision_data['parent'] = obj + convex_collision_data['parent'] = base_ob convex_collision_data['verts_loc'] = ws_vtx_co collider_data.append(convex_collision_data) diff --git a/collider_shapes/add_bounding_cylinder.py b/collider_shapes/add_bounding_cylinder.py index 6f85c8f..a576b37 100644 --- a/collider_shapes/add_bounding_cylinder.py +++ b/collider_shapes/add_bounding_cylinder.py @@ -329,7 +329,7 @@ def execute(self, context): nsphere = welzl(np.array(coordinates)) radius = np.sqrt(nsphere.sqradius) - bounding_cylinder_data['parent'] = obj + bounding_cylinder_data['parent'] = base_ob bounding_cylinder_data['radius'] = radius bounding_cylinder_data['depth'] = depth bounding_cylinder_data['center_point'] = [ diff --git a/collider_shapes/add_bounding_sphere.py b/collider_shapes/add_bounding_sphere.py index a58706f..0e7f7f5 100644 --- a/collider_shapes/add_bounding_sphere.py +++ b/collider_shapes/add_bounding_sphere.py @@ -204,7 +204,7 @@ def execute(self, context): if self.creation_mode[self.creation_mode_idx] == 'INDIVIDUAL': bounding_sphere_data['mid_point'], bounding_sphere_data['radius'] = self.calculate_bounding_sphere(obj, used_vertices) - bounding_sphere_data['parent'] = obj + bounding_sphere_data['parent'] = base_ob collider_data.append(bounding_sphere_data) else: # if self.creation_mode[self.creation_mode_idx] == 'SELECTION': diff --git a/collider_shapes/add_collision_mesh.py b/collider_shapes/add_collision_mesh.py index 3458aa3..efb6628 100644 --- a/collider_shapes/add_collision_mesh.py +++ b/collider_shapes/add_collision_mesh.py @@ -87,7 +87,7 @@ def execute(self, context): continue scene = context.scene - mesh_collider_data['parent'] = obj + mesh_collider_data['parent'] = base_ob mesh_collider_data['new_collider'] = new_collider collider_data.append(mesh_collider_data) diff --git a/collider_shapes/add_minimum_bounding_box.py b/collider_shapes/add_minimum_bounding_box.py index 0c160cf..eff083b 100644 --- a/collider_shapes/add_minimum_bounding_box.py +++ b/collider_shapes/add_minimum_bounding_box.py @@ -187,7 +187,7 @@ def execute(self, context): # used_vertices uses local space. # store data needed to generate a bounding box in a dictionary - bounding_box_data['parent'] = obj + bounding_box_data['parent'] = base_ob bounding_box_data['verts_loc'] = ws_vtx_co collider_data.append(bounding_box_data) diff --git a/ui/properties_panels.py b/ui/properties_panels.py index 2a63e46..43b9df9 100644 --- a/ui/properties_panels.py +++ b/ui/properties_panels.py @@ -519,7 +519,7 @@ class BUTTON_OT_auto_convex(bpy.types.Operator): def poll(cls, context): count = 0 for obj in context.selected_objects: - if obj.type == 'MESH': + if obj.type in ['MESH', 'CURVE', 'SURFACE', 'FONT', 'META']: count = count + 1 return count > 0 From 1c780d6547b7014469eb763371f46407acf10a55 Mon Sep 17 00:00:00 2001 From: Matthias Patscheider Date: Tue, 27 Jun 2023 15:43:34 +0300 Subject: [PATCH 10/23] keep material does work --- collider_shapes/add_bounding_primitive.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/collider_shapes/add_bounding_primitive.py b/collider_shapes/add_bounding_primitive.py index df3e790..29f66b9 100644 --- a/collider_shapes/add_bounding_primitive.py +++ b/collider_shapes/add_bounding_primitive.py @@ -1338,7 +1338,10 @@ def modal(self, context, event): ob = objinfo['obj'] collections = objinfo['users_collection'] for col in collections: - bpy.data.collections[col].objects.link(ob) + try: + bpy.data.collections[col].objects.link(ob) + except: + pass self.execute(context) From b928b88a057aaede9707c6ebec33453650e67be0 Mon Sep 17 00:00:00 2001 From: Matthias Patscheider Date: Tue, 27 Jun 2023 18:41:45 +0300 Subject: [PATCH 11/23] first steps --- collider_shapes/add_bounding_box.py | 2 +- collider_shapes/add_bounding_primitive.py | 21 ++++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/collider_shapes/add_bounding_box.py b/collider_shapes/add_bounding_box.py index 1abe826..6af216d 100644 --- a/collider_shapes/add_bounding_box.py +++ b/collider_shapes/add_bounding_box.py @@ -76,7 +76,7 @@ def execute(self, context): user_collections = base_ob.users_collection self.original_obj_data.append(self.store_initial_obj_state(base_ob, user_collections)) # convert meshes - obj = self.convert_to_mesh(context, base_ob) + obj = self.convert_to_mesh(context, base_ob, use_modifiers=self.my_use_modifier_stack) self.tmp_meshes.append(obj) context.view_layer.objects.active = obj diff --git a/collider_shapes/add_bounding_primitive.py b/collider_shapes/add_bounding_primitive.py index 29f66b9..6619cdf 100644 --- a/collider_shapes/add_bounding_primitive.py +++ b/collider_shapes/add_bounding_primitive.py @@ -864,16 +864,27 @@ def store_initial_obj_state(obj, collections): return dic - def convert_to_mesh(self, context, object): + + @staticmethod + def convert_to_mesh(context, object, use_modifiers = False): + mods=[] + + for mod in object.modifiers: + mods.append({"mod":mod, "show_viewport":mod.show_viewport, "show_in_editmode": mod.show_in_editmode}) + + + mod.show_viewport = use_modifiers + mod.show_in_editmode = use_modifiers + deg = context.evaluated_depsgraph_get() me = bpy.data.meshes.new_from_object(object.evaluated_get(deg), depsgraph=deg) - new_obj = bpy.data.objects.new(object.name + "_mesh", me) context.collection.objects.link(new_obj) - new_obj.matrix_world = object.matrix_world - context.view_layer.objects.active = new_obj - + # for mod in mods: + # modifier = mod["mod"] + # modifier.show_viewport = mod["show_viewport"] + # modifier.show_in_editmode = mod["show_in_editmode"] return new_obj def primitive_postprocessing(self, context, bounding_object, base_object_collections): From 7e310d890cf94cb7e56c1f0b178c86e06cbd85a1 Mon Sep 17 00:00:00 2001 From: Matthias Patscheider Date: Tue, 27 Jun 2023 18:52:16 +0300 Subject: [PATCH 12/23] modifier improvement --- collider_shapes/add_bounding_primitive.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/collider_shapes/add_bounding_primitive.py b/collider_shapes/add_bounding_primitive.py index 6619cdf..05d7057 100644 --- a/collider_shapes/add_bounding_primitive.py +++ b/collider_shapes/add_bounding_primitive.py @@ -871,8 +871,6 @@ def convert_to_mesh(context, object, use_modifiers = False): for mod in object.modifiers: mods.append({"mod":mod, "show_viewport":mod.show_viewport, "show_in_editmode": mod.show_in_editmode}) - - mod.show_viewport = use_modifiers mod.show_in_editmode = use_modifiers @@ -881,10 +879,13 @@ def convert_to_mesh(context, object, use_modifiers = False): new_obj = bpy.data.objects.new(object.name + "_mesh", me) context.collection.objects.link(new_obj) - # for mod in mods: - # modifier = mod["mod"] - # modifier.show_viewport = mod["show_viewport"] - # modifier.show_in_editmode = mod["show_in_editmode"] + for mod in mods: + modifier = mod["mod"] + modifier.show_viewport = mod["show_viewport"] + modifier.show_in_editmode = mod["show_in_editmode"] + + new_obj.matrix_world = object.matrix_world + context.view_layer.objects.active = new_obj return new_obj def primitive_postprocessing(self, context, bounding_object, base_object_collections): From 659285613f2d7ded876dec8479f4a6ae7ec6315e Mon Sep 17 00:00:00 2001 From: Matthias Patscheider Date: Wed, 28 Jun 2023 10:27:56 +0300 Subject: [PATCH 13/23] support modifiers --- auto_Convex/add_bounding_auto_convex.py | 2 +- collider_conversion/convert_to_collider.py | 2 +- collider_shapes/add_bounding_capsule.py | 2 +- collider_shapes/add_bounding_convex_hull.py | 2 +- collider_shapes/add_bounding_cylinder.py | 2 +- collider_shapes/add_bounding_sphere.py | 2 +- collider_shapes/add_collision_mesh.py | 2 +- collider_shapes/add_minimum_bounding_box.py | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/auto_Convex/add_bounding_auto_convex.py b/auto_Convex/add_bounding_auto_convex.py index 744288d..b03f194 100644 --- a/auto_Convex/add_bounding_auto_convex.py +++ b/auto_Convex/add_bounding_auto_convex.py @@ -107,7 +107,7 @@ def execute(self, context): user_collections = base_ob.users_collection self.original_obj_data.append(self.store_initial_obj_state(base_ob, user_collections)) # convert meshes - obj = self.convert_to_mesh(context, base_ob) + obj = self.convert_to_mesh(context, base_ob, use_modifiers=self.my_use_modifier_stack) self.tmp_meshes.append(obj) context.view_layer.objects.active = obj diff --git a/collider_conversion/convert_to_collider.py b/collider_conversion/convert_to_collider.py index e0762a8..c28b486 100644 --- a/collider_conversion/convert_to_collider.py +++ b/collider_conversion/convert_to_collider.py @@ -81,7 +81,7 @@ def execute(self, context): user_collections = base_ob.users_collection self.original_obj_data.append(self.store_initial_obj_state(base_ob, user_collections)) # convert meshes - obj = self.convert_to_mesh(context, base_ob) + obj = self.convert_to_mesh(context, base_ob, use_modifiers=self.my_use_modifier_stack) self.tmp_meshes.append(obj) new_collider = obj.copy() diff --git a/collider_shapes/add_bounding_capsule.py b/collider_shapes/add_bounding_capsule.py index 162821d..1505f18 100644 --- a/collider_shapes/add_bounding_capsule.py +++ b/collider_shapes/add_bounding_capsule.py @@ -96,7 +96,7 @@ def execute(self, context): user_collections = base_ob.users_collection self.original_obj_data.append(self.store_initial_obj_state(base_ob, user_collections)) # convert meshes - obj = self.convert_to_mesh(context, base_ob) + obj = self.convert_to_mesh(context, base_ob, use_modifiers=self.my_use_modifier_stack) self.tmp_meshes.append(obj) context.view_layer.objects.active = obj diff --git a/collider_shapes/add_bounding_convex_hull.py b/collider_shapes/add_bounding_convex_hull.py index befa450..ba1b332 100644 --- a/collider_shapes/add_bounding_convex_hull.py +++ b/collider_shapes/add_bounding_convex_hull.py @@ -64,7 +64,7 @@ def execute(self, context): user_collections = base_ob.users_collection self.original_obj_data.append(self.store_initial_obj_state(base_ob, user_collections)) # convert meshes - obj = self.convert_to_mesh(context, base_ob) + obj = self.convert_to_mesh(context, base_ob, use_modifiers=self.my_use_modifier_stack) self.tmp_meshes.append(obj) convex_collision_data = {} diff --git a/collider_shapes/add_bounding_cylinder.py b/collider_shapes/add_bounding_cylinder.py index a576b37..2afc1f7 100644 --- a/collider_shapes/add_bounding_cylinder.py +++ b/collider_shapes/add_bounding_cylinder.py @@ -273,7 +273,7 @@ def execute(self, context): user_collections = base_ob.users_collection self.original_obj_data.append(self.store_initial_obj_state(base_ob, user_collections)) # convert meshes - obj = self.convert_to_mesh(context, base_ob) + obj = self.convert_to_mesh(context, base_ob, use_modifiers=self.my_use_modifier_stack) self.tmp_meshes.append(obj) bounding_cylinder_data = {} diff --git a/collider_shapes/add_bounding_sphere.py b/collider_shapes/add_bounding_sphere.py index 0e7f7f5..719c58c 100644 --- a/collider_shapes/add_bounding_sphere.py +++ b/collider_shapes/add_bounding_sphere.py @@ -183,7 +183,7 @@ def execute(self, context): user_collections = base_ob.users_collection self.original_obj_data.append(self.store_initial_obj_state(base_ob, user_collections)) # convert meshes - obj = self.convert_to_mesh(context, base_ob) + obj = self.convert_to_mesh(context, base_ob, use_modifiers=self.my_use_modifier_stack) self.tmp_meshes.append(obj) initial_mod_state = {} diff --git a/collider_shapes/add_collision_mesh.py b/collider_shapes/add_collision_mesh.py index efb6628..190d0c7 100644 --- a/collider_shapes/add_collision_mesh.py +++ b/collider_shapes/add_collision_mesh.py @@ -69,7 +69,7 @@ def execute(self, context): user_collections = base_ob.users_collection self.original_obj_data.append(self.store_initial_obj_state(base_ob, user_collections)) # convert meshes - obj = self.convert_to_mesh(context, base_ob) + obj = self.convert_to_mesh(context, base_ob, use_modifiers=self.my_use_modifier_stack) self.tmp_meshes.append(obj) mesh_collider_data = {} diff --git a/collider_shapes/add_minimum_bounding_box.py b/collider_shapes/add_minimum_bounding_box.py index eff083b..7fb0e8a 100644 --- a/collider_shapes/add_minimum_bounding_box.py +++ b/collider_shapes/add_minimum_bounding_box.py @@ -163,7 +163,7 @@ def execute(self, context): user_collections = base_ob.users_collection self.original_obj_data.append(self.store_initial_obj_state(base_ob, user_collections)) # convert meshes - obj = self.convert_to_mesh(context, base_ob) + obj = self.convert_to_mesh(context, base_ob, use_modifiers=self.my_use_modifier_stack) self.tmp_meshes.append(obj) bounding_box_data = {} From 71eff0411bb3ba452a684738bac3dd23114eccf8 Mon Sep 17 00:00:00 2001 From: Matthias Patscheider Date: Thu, 29 Jun 2023 14:30:29 +0300 Subject: [PATCH 14/23] Add temporary collection for temp mesh --- collider_shapes/add_bounding_box.py | 1 + collider_shapes/add_bounding_primitive.py | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/collider_shapes/add_bounding_box.py b/collider_shapes/add_bounding_box.py index 6af216d..1546a61 100644 --- a/collider_shapes/add_bounding_box.py +++ b/collider_shapes/add_bounding_box.py @@ -79,6 +79,7 @@ def execute(self, context): obj = self.convert_to_mesh(context, base_ob, use_modifiers=self.my_use_modifier_stack) self.tmp_meshes.append(obj) + context.view_layer.objects.active = obj bounding_box_data = {} diff --git a/collider_shapes/add_bounding_primitive.py b/collider_shapes/add_bounding_primitive.py index 05d7057..c8ec7be 100644 --- a/collider_shapes/add_bounding_primitive.py +++ b/collider_shapes/add_bounding_primitive.py @@ -802,6 +802,14 @@ def add_to_collections(obj, collection_name): except RuntimeError as err: pass + return col + + @staticmethod + def remove_empty_collection(collection_name): + if collection_name in bpy.data.collections: + collection = bpy.data.collections[collection_name] + if len(collection.objects) == 0: + bpy.data.collections.remove(collection) @staticmethod def set_collections(obj, collections): """link an object to a collection""" @@ -865,8 +873,8 @@ def store_initial_obj_state(obj, collections): return dic - @staticmethod - def convert_to_mesh(context, object, use_modifiers = False): + @classmethod + def convert_to_mesh(cls, context, object, use_modifiers = False): mods=[] for mod in object.modifiers: @@ -877,7 +885,8 @@ def convert_to_mesh(context, object, use_modifiers = False): deg = context.evaluated_depsgraph_get() me = bpy.data.meshes.new_from_object(object.evaluated_get(deg), depsgraph=deg) new_obj = bpy.data.objects.new(object.name + "_mesh", me) - context.collection.objects.link(new_obj) + col = cls.add_to_collections(new_obj, 'tmp_mesh') + col.color_tag = 'COLOR_03' for mod in mods: modifier = mod["mod"] @@ -1023,6 +1032,7 @@ def cancel_cleanup(self, context): # Delete temporary objects self.remove_objects(self.tmp_meshes) + self.remove_empty_collection('tmp_mesh') # delete original data for data in self.original_obj_data: @@ -1284,6 +1294,7 @@ def modal(self, context, event): # Delete temporary generated meshes self.remove_objects(self.tmp_meshes) + self.remove_empty_collection('tmp_mesh') try: bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW') @@ -1514,6 +1525,7 @@ def execute(self, context): # Remove objects from previous generation self.remove_objects(self.tmp_meshes) self.remove_objects(self.new_colliders_list) + self.remove_empty_collection('tmp_mesh') self.new_colliders_list = [] self.original_obj_data = [] self.tmp_meshes = [] From 204de97a4ed8eeb38bc4ad64d6ce7acd5965bf42 Mon Sep 17 00:00:00 2001 From: Matthias Patscheider Date: Thu, 29 Jun 2023 14:39:25 +0300 Subject: [PATCH 15/23] #71 Fix Crash in Edit mode for box collider --- collider_shapes/add_bounding_box.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/collider_shapes/add_bounding_box.py b/collider_shapes/add_bounding_box.py index 1546a61..83c7822 100644 --- a/collider_shapes/add_bounding_box.py +++ b/collider_shapes/add_bounding_box.py @@ -83,9 +83,9 @@ def execute(self, context): context.view_layer.objects.active = obj bounding_box_data = {} - if self.obj_mode == "EDIT": + # EDIT is only supported for 'MESH' type objects and only if the active object is a 'MESH'. + if self.obj_mode == "EDIT" and base_ob.type == 'MESH' and self.active_obj.type == 'MESH': used_vertices = self.get_vertices_Edit(obj, use_modifiers=self.my_use_modifier_stack) - else: # self.obj_mode == "OBJECT": used_vertices = self.get_vertices_Object(obj, use_modifiers=self.my_use_modifier_stack) From e1a5c83157489a0a55b5815ba33169e97636130a Mon Sep 17 00:00:00 2001 From: Matthias Patscheider Date: Thu, 29 Jun 2023 14:44:57 +0300 Subject: [PATCH 16/23] Fix edit mode generation for additional collider generation types --- auto_Convex/add_bounding_auto_convex.py | 2 +- collider_shapes/add_bounding_capsule.py | 2 +- collider_shapes/add_bounding_convex_hull.py | 2 +- collider_shapes/add_bounding_cylinder.py | 2 +- collider_shapes/add_bounding_sphere.py | 2 +- collider_shapes/add_collision_mesh.py | 2 +- collider_shapes/add_minimum_bounding_box.py | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/auto_Convex/add_bounding_auto_convex.py b/auto_Convex/add_bounding_auto_convex.py index b03f194..2288e8c 100644 --- a/auto_Convex/add_bounding_auto_convex.py +++ b/auto_Convex/add_bounding_auto_convex.py @@ -112,7 +112,7 @@ def execute(self, context): context.view_layer.objects.active = obj - if self.obj_mode == "EDIT": + if self.obj_mode == "EDIT" and base_ob.type == 'MESH' and self.active_obj.type == 'MESH': new_mesh = self.get_mesh_Edit( obj, use_modifiers=self.my_use_modifier_stack) else: # mode == "OBJECT": diff --git a/collider_shapes/add_bounding_capsule.py b/collider_shapes/add_bounding_capsule.py index 1505f18..b34b56d 100644 --- a/collider_shapes/add_bounding_capsule.py +++ b/collider_shapes/add_bounding_capsule.py @@ -102,7 +102,7 @@ def execute(self, context): context.view_layer.objects.active = obj bounding_capsule_data = {} - if self.obj_mode == "EDIT": + if self.obj_mode == "EDIT" and base_ob.type == 'MESH' and self.active_obj.type == 'MESH': used_vertices = self.get_vertices_Edit(obj, use_modifiers=self.my_use_modifier_stack) else: # self.obj_mode == "OBJECT": diff --git a/collider_shapes/add_bounding_convex_hull.py b/collider_shapes/add_bounding_convex_hull.py index ba1b332..9ccb450 100644 --- a/collider_shapes/add_bounding_convex_hull.py +++ b/collider_shapes/add_bounding_convex_hull.py @@ -69,7 +69,7 @@ def execute(self, context): convex_collision_data = {} - if self.obj_mode == "EDIT": + if self.obj_mode == "EDIT" and base_ob.type == 'MESH' and self.active_obj.type == 'MESH': used_vertices = self.get_vertices_Edit(obj, use_modifiers=self.my_use_modifier_stack) else: # self.obj_mode == "OBJECT": diff --git a/collider_shapes/add_bounding_cylinder.py b/collider_shapes/add_bounding_cylinder.py index 2afc1f7..2608309 100644 --- a/collider_shapes/add_bounding_cylinder.py +++ b/collider_shapes/add_bounding_cylinder.py @@ -278,7 +278,7 @@ def execute(self, context): bounding_cylinder_data = {} - if self.obj_mode == 'EDIT': + if self.obj_mode == "EDIT" and base_ob.type == 'MESH' and self.active_obj.type == 'MESH': used_vertices = self.get_vertices_Edit( obj, use_modifiers=self.my_use_modifier_stack) else: diff --git a/collider_shapes/add_bounding_sphere.py b/collider_shapes/add_bounding_sphere.py index 719c58c..f1a2f79 100644 --- a/collider_shapes/add_bounding_sphere.py +++ b/collider_shapes/add_bounding_sphere.py @@ -190,7 +190,7 @@ def execute(self, context): context.view_layer.objects.active = obj scene = context.scene - if self.obj_mode == "EDIT": + if self.obj_mode == "EDIT" and base_ob.type == 'MESH' and self.active_obj.type == 'MESH': used_vertices = self.get_vertices_Edit(obj, use_modifiers=self.my_use_modifier_stack) else: # mode == "OBJECT": diff --git a/collider_shapes/add_collision_mesh.py b/collider_shapes/add_collision_mesh.py index 190d0c7..f7b8c74 100644 --- a/collider_shapes/add_collision_mesh.py +++ b/collider_shapes/add_collision_mesh.py @@ -74,7 +74,7 @@ def execute(self, context): mesh_collider_data = {} - if self.obj_mode == "EDIT": + if self.obj_mode == "EDIT" and base_ob.type == 'MESH' and self.active_obj.type == 'MESH': new_mesh = self.get_mesh_Edit(obj, use_modifiers=self.my_use_modifier_stack) new_collider = bpy.data.objects.new("", new_mesh) diff --git a/collider_shapes/add_minimum_bounding_box.py b/collider_shapes/add_minimum_bounding_box.py index 7fb0e8a..fd7ae95 100644 --- a/collider_shapes/add_minimum_bounding_box.py +++ b/collider_shapes/add_minimum_bounding_box.py @@ -168,7 +168,7 @@ def execute(self, context): bounding_box_data = {} - if self.obj_mode == "EDIT": + if self.obj_mode == "EDIT" and base_ob.type == 'MESH' and self.active_obj.type == 'MESH': used_vertices = self.get_vertices_Edit(obj, use_modifiers=self.my_use_modifier_stack) else: # self.obj_mode == "OBJECT": From dacbb9c362351f4abce891c3fc0733fd429a1874 Mon Sep 17 00:00:00 2001 From: Matthias Patscheider Date: Thu, 29 Jun 2023 16:57:01 +0300 Subject: [PATCH 17/23] Add debug option --- collider_shapes/add_bounding_box.py | 2 +- collider_shapes/add_bounding_primitive.py | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/collider_shapes/add_bounding_box.py b/collider_shapes/add_bounding_box.py index 83c7822..d52f269 100644 --- a/collider_shapes/add_bounding_box.py +++ b/collider_shapes/add_bounding_box.py @@ -83,7 +83,7 @@ def execute(self, context): context.view_layer.objects.active = obj bounding_box_data = {} - # EDIT is only supported for 'MESH' type objects and only if the active object is a 'MESH'. + # EDIT is only supported for 'MESH' type objects and only if the active object is a 'MESH' if self.obj_mode == "EDIT" and base_ob.type == 'MESH' and self.active_obj.type == 'MESH': used_vertices = self.get_vertices_Edit(obj, use_modifiers=self.my_use_modifier_stack) else: # self.obj_mode == "OBJECT": diff --git a/collider_shapes/add_bounding_primitive.py b/collider_shapes/add_bounding_primitive.py index c8ec7be..fc2a8fa 100644 --- a/collider_shapes/add_bounding_primitive.py +++ b/collider_shapes/add_bounding_primitive.py @@ -1031,8 +1031,9 @@ def cancel_cleanup(self, context): objs.remove(obj, do_unlink=True) # Delete temporary objects - self.remove_objects(self.tmp_meshes) - self.remove_empty_collection('tmp_mesh') + if self.prefs.debug == False: + self.remove_objects(self.tmp_meshes) + self.remove_empty_collection('tmp_mesh') # delete original data for data in self.original_obj_data: @@ -1293,8 +1294,9 @@ def modal(self, context, event): obj.show_wire = False # Delete temporary generated meshes - self.remove_objects(self.tmp_meshes) - self.remove_empty_collection('tmp_mesh') + if self.prefs.debug == False: + self.remove_objects(self.tmp_meshes) + self.remove_empty_collection('tmp_mesh') try: bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW') From 1cb04794d05baf9832e52ae8cdfdbdddc1483f03 Mon Sep 17 00:00:00 2001 From: Matthias Patscheider Date: Thu, 29 Jun 2023 17:31:20 +0300 Subject: [PATCH 18/23] #71 Fix offset issue for bbox --- collider_shapes/add_bounding_box.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/collider_shapes/add_bounding_box.py b/collider_shapes/add_bounding_box.py index d52f269..2372061 100644 --- a/collider_shapes/add_bounding_box.py +++ b/collider_shapes/add_bounding_box.py @@ -99,6 +99,7 @@ def execute(self, context): # store data needed to generate a bounding box in a dictionary bounding_box_data['parent'] = base_ob + bounding_box_data['mtx_world'] = base_ob.matrix_world.copy() bounding_box_data['verts_loc'] = verts_loc bounding_box_data['center_point'] = center_point @@ -111,6 +112,7 @@ def execute(self, context): if self.creation_mode[self.creation_mode_idx] == 'SELECTION': collider_data = self.selection_bbox_data(verts_co) + bpy.ops.object.mode_set(mode='OBJECT') for bounding_box_data in collider_data: @@ -118,14 +120,15 @@ def execute(self, context): parent = bounding_box_data['parent'] verts_loc = bounding_box_data['verts_loc'] center_point = bounding_box_data['center_point'] + mtx_world = bounding_box_data['mtx_world'] new_collider = verts_faces_to_bbox_collider(self, context, verts_loc) scene = context.scene if self.my_space == 'LOCAL': - new_collider.parent = parent + new_collider.matrix_world = mtx_world # align collider with parent - new_collider.matrix_world = parent.matrix_world + self.custom_set_parent(context, parent, new_collider) self.use_recenter_origin = False else: # self.my_space == 'GLOBAL': @@ -156,7 +159,8 @@ def selection_bbox_data(self, verts_co): verts_co = self.transform_vertex_space(ws_vtx_co, self.active_obj) bbox_verts, center_point = self.generate_bounding_box(verts_co) + mtx_world = self.active_obj.matrix_world - bounding_box_data = {'parent': self.active_obj, 'verts_loc': bbox_verts, 'center_point': center_point} + bounding_box_data = {'parent': self.active_obj, 'verts_loc': bbox_verts, 'center_point': center_point, 'mtx_world': mtx_world} return [bounding_box_data] From c8b6faf7333c7dba8f9559fe0689656715746569 Mon Sep 17 00:00:00 2001 From: Matthias Patscheider Date: Thu, 29 Jun 2023 17:55:34 +0300 Subject: [PATCH 19/23] #71 Fix offset for Mesh --- collider_shapes/add_collision_mesh.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/collider_shapes/add_collision_mesh.py b/collider_shapes/add_collision_mesh.py index f7b8c74..cd77975 100644 --- a/collider_shapes/add_collision_mesh.py +++ b/collider_shapes/add_collision_mesh.py @@ -88,6 +88,7 @@ def execute(self, context): scene = context.scene mesh_collider_data['parent'] = base_ob + mesh_collider_data['mtx_world'] = base_ob.matrix_world.copy() mesh_collider_data['new_collider'] = new_collider collider_data.append(mesh_collider_data) @@ -97,16 +98,18 @@ def execute(self, context): for mesh_collider_data in collider_data: parent = mesh_collider_data['parent'] new_collider = mesh_collider_data['new_collider'] + mtx_world = mesh_collider_data['mtx_world'] context.scene.collection.objects.link(new_collider) self.shape_suffix = self.prefs.mesh_shape # create collision meshes + new_collider.matrix_world = mtx_world self.custom_set_parent(context, parent, new_collider) self.remove_all_modifiers(context, new_collider) # align objects - new_collider.matrix_world = parent.matrix_world + #new_collider.matrix_world = parent.matrix_world super().set_collider_name(new_collider, parent.name) From 6368b21ac48ec233e3916e1f96e010c307d0440b Mon Sep 17 00:00:00 2001 From: Matthias Patscheider Date: Thu, 29 Jun 2023 18:13:07 +0300 Subject: [PATCH 20/23] #71 fix offset auto convex --- auto_Convex/add_bounding_auto_convex.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/auto_Convex/add_bounding_auto_convex.py b/auto_Convex/add_bounding_auto_convex.py index 2288e8c..ef4e4f0 100644 --- a/auto_Convex/add_bounding_auto_convex.py +++ b/auto_Convex/add_bounding_auto_convex.py @@ -71,8 +71,7 @@ def execute(self, context): # CLEANUP super().execute(context) - overwrite_path = self.overwrite_executable_path( - self.prefs.executable_path) + overwrite_path = self.overwrite_executable_path(self.prefs.executable_path) vhacd_exe = self.prefs.default_executable_path if not overwrite_path else overwrite_path data_path = self.set_temp_data_path(self.prefs.data_path) @@ -125,6 +124,7 @@ def execute(self, context): if self.creation_mode[self.creation_mode_idx] == 'INDIVIDUAL': convex_collision_data = {} convex_collision_data['parent'] = base_ob + convex_collision_data['mtx_world'] = base_ob.matrix_world.copy() convex_collision_data['mesh'] = new_mesh collider_data.append(convex_collision_data) @@ -136,6 +136,7 @@ def execute(self, context): if self.creation_mode[self.creation_mode_idx] == 'SELECTION': convex_collision_data = {} convex_collision_data['parent'] = self.active_obj + convex_collision_data['mtx_world'] = self.active_obj.matrix_world.copy() bmeshes = [] @@ -155,6 +156,7 @@ def execute(self, context): for convex_collision_data in collider_data: parent = convex_collision_data['parent'] mesh = convex_collision_data['mesh'] + mtx_world = convex_collision_data['mtx_world'] joined_obj = bpy.data.objects.new('debug_joined_mesh', mesh.copy()) bpy.context.scene.collection.objects.link(joined_obj) @@ -267,6 +269,7 @@ def execute(self, context): convex_collisions_data = {} convex_collisions_data['colliders'] = imported convex_collisions_data['parent'] = parent + convex_collisions_data['mtx_world'] = parent.matrix_world.copy() convex_decomposition_data.append(convex_collisions_data) context.view_layer.objects.active = self.active_obj @@ -274,18 +277,18 @@ def execute(self, context): for convex_collisions_data in convex_decomposition_data: convex_collision = convex_collisions_data['colliders'] parent = convex_collisions_data['parent'] + mtx_world = convex_collisions_data['mtx_world'] for new_collider in convex_collision: new_collider.name = super().collider_name(basename=parent.name) - self.custom_set_parent(context, parent, new_collider) - if self.creation_mode[self.creation_mode_idx] == 'INDIVIDUAL': - new_collider.matrix_world = parent.matrix_world - # Apply rotation and scale for custom origin to work. + new_collider.matrix_world = mtx_world self.apply_transform( new_collider, rotation=True, scale=True) + self.custom_set_parent(context, parent, new_collider) + collections = parent.users_collection self.primitive_postprocessing( context, new_collider, collections) From 0fa11fadcaed6dfdc37edaf882d9e70e9081413a Mon Sep 17 00:00:00 2001 From: Matthias Patscheider Date: Thu, 29 Jun 2023 18:25:42 +0300 Subject: [PATCH 21/23] Hide tmp collection during creation --- collider_shapes/add_bounding_primitive.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/collider_shapes/add_bounding_primitive.py b/collider_shapes/add_bounding_primitive.py index fc2a8fa..a96f348 100644 --- a/collider_shapes/add_bounding_primitive.py +++ b/collider_shapes/add_bounding_primitive.py @@ -789,14 +789,16 @@ def is_valid_object(self, obj): # Collections @staticmethod - def add_to_collections(obj, collection_name): + def add_to_collections(obj, collection_name, hide=False): """Add an object to a collection""" if collection_name not in bpy.data.collections: collection = bpy.data.collections.new(collection_name) bpy.context.scene.collection.children.link(collection) col = bpy.data.collections[collection_name] - + if hide: + col.hide_viewport = True + col.hide_render = True try: col.objects.link(obj) except RuntimeError as err: @@ -885,7 +887,7 @@ def convert_to_mesh(cls, context, object, use_modifiers = False): deg = context.evaluated_depsgraph_get() me = bpy.data.meshes.new_from_object(object.evaluated_get(deg), depsgraph=deg) new_obj = bpy.data.objects.new(object.name + "_mesh", me) - col = cls.add_to_collections(new_obj, 'tmp_mesh') + col = cls.add_to_collections(new_obj, 'tmp_mesh', hide=False) col.color_tag = 'COLOR_03' for mod in mods: From c812c17e181b57d453cf8819c67d2af638f2d1c6 Mon Sep 17 00:00:00 2001 From: Matthias Patscheider Date: Thu, 29 Jun 2023 19:16:02 +0300 Subject: [PATCH 22/23] Add use modifiers to convert to + rename 'Object to Collider' --- collider_conversion/convert_to_collider.py | 16 +++++++++++--- collider_shapes/add_bounding_primitive.py | 25 ++++++++++++++++------ 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/collider_conversion/convert_to_collider.py b/collider_conversion/convert_to_collider.py index c28b486..a7fb382 100644 --- a/collider_conversion/convert_to_collider.py +++ b/collider_conversion/convert_to_collider.py @@ -9,7 +9,7 @@ class OBJECT_OT_convert_to_collider(OBJECT_OT_add_bounding_object, Operator): """Convert existing objects to be a collider""" bl_idname = "object.convert_to_collider" - bl_label = "Mesh to Collider" + bl_label = "Object to Collider" bl_description = 'Convert selected meshes to colliders' @classmethod @@ -22,9 +22,9 @@ def __init__(self): self.use_shape_change = True self.use_decimation = True self.is_mesh_to_collider = True - # self.use_creation_mode = False self.shape = 'mesh_shape' self.use_keep_original_materials = True + self.use_modifier_stack = True def invoke(self, context, event): super().invoke(context, event) @@ -46,6 +46,9 @@ def modal(self, context, event): if status == {'PASS_THROUGH'}: return {'PASS_THROUGH'} + if event.type == 'P' and event.value == 'RELEASE': + self.my_use_modifier_stack = not self.my_use_modifier_stack + self.execute(context) elif event.type == 'Q' and event.value == 'RELEASE': # toggle through display modes @@ -75,8 +78,15 @@ def execute(self, context): if base_ob and base_ob.type in self.valid_object_types: if base_ob.type == 'MESH': obj = base_ob + mods = self.store_obj_mod_in_dic(obj) - else: + for mod in obj.modifiers: + mod.show_viewport = self.use_modifier_stack + mod.show_in_editmode = self.use_modifier_stack + + self.restore_obj_mod_from_dic(mods) + + else: # other object types like curves, surfaces, texts ... # store initial state for operation cancel user_collections = base_ob.users_collection self.original_obj_data.append(self.store_initial_obj_state(base_ob, user_collections)) diff --git a/collider_shapes/add_bounding_primitive.py b/collider_shapes/add_bounding_primitive.py index a96f348..66fe84c 100644 --- a/collider_shapes/add_bounding_primitive.py +++ b/collider_shapes/add_bounding_primitive.py @@ -874,13 +874,27 @@ def store_initial_obj_state(obj, collections): return dic + @staticmethod + def store_obj_mod_in_dic(object): + mods = [] + + for mod in object.modifiers: + mods.append({"mod":mod, "show_viewport":mod.show_viewport, "show_in_editmode": mod.show_in_editmode}) + + return mods + + @staticmethod + def restore_obj_mod_from_dic(modifier_dic): + for mod_entry in modifier_dic: + modifier = mod_entry["mod"] + modifier.show_viewport = mod_entry["show_viewport"] + modifier.show_in_editmode = mod_entry["show_in_editmode"] @classmethod def convert_to_mesh(cls, context, object, use_modifiers = False): - mods=[] + mods = cls.store_obj_mod_in_dic(object) for mod in object.modifiers: - mods.append({"mod":mod, "show_viewport":mod.show_viewport, "show_in_editmode": mod.show_in_editmode}) mod.show_viewport = use_modifiers mod.show_in_editmode = use_modifiers @@ -890,10 +904,7 @@ def convert_to_mesh(cls, context, object, use_modifiers = False): col = cls.add_to_collections(new_obj, 'tmp_mesh', hide=False) col.color_tag = 'COLOR_03' - for mod in mods: - modifier = mod["mod"] - modifier.show_viewport = mod["show_viewport"] - modifier.show_in_editmode = mod["show_in_editmode"] + cls.restore_obj_mod_from_dic(mods) new_obj.matrix_world = object.matrix_world context.view_layer.objects.active = new_obj @@ -1201,7 +1212,7 @@ def invoke(self, context, event): self.collision_groups = collider_groups self.collision_group_idx = self.collision_groups.index(colSettings.default_user_group) - # Mesh to Collider + # Object to Collider self.original_obj_data = [] # display settings From f36cce59bfba38629812a14714e39e2440a37fad Mon Sep 17 00:00:00 2001 From: Matthias Patscheider Date: Thu, 29 Jun 2023 19:21:09 +0300 Subject: [PATCH 23/23] Update convert_to_collider.py --- collider_conversion/convert_to_collider.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collider_conversion/convert_to_collider.py b/collider_conversion/convert_to_collider.py index a7fb382..f11bb0c 100644 --- a/collider_conversion/convert_to_collider.py +++ b/collider_conversion/convert_to_collider.py @@ -96,7 +96,7 @@ def execute(self, context): new_collider = obj.copy() new_collider.data = obj.data.copy() - user_collections = obj.users_collection + user_collections = base_ob.users_collection # New collider to scene bpy.context.collection.objects.link(new_collider)