From 92f588b7604b0816f035370eb4f384c1baa87f60 Mon Sep 17 00:00:00 2001 From: Colin Basnett Date: Wed, 11 May 2022 17:12:29 -0700 Subject: [PATCH 1/3] Initial commit for WYSIWYG export. Modifiers are automatically applied. --- src/builder.py | 43 ++++++++++++++++++++++++++++++------------- src/exporter.py | 3 +++ 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/builder.py b/src/builder.py index bddd780..5e38bac 100644 --- a/src/builder.py +++ b/src/builder.py @@ -12,6 +12,7 @@ class ASEBuilderError(Exception): class ASEBuilderOptions(object): def __init__(self): self.scale = 1.0 + self.use_raw_mesh_data = False class ASEBuilder(object): @@ -19,17 +20,31 @@ class ASEBuilder(object): ase = ASE() main_geometry_object = None - for obj in context.selected_objects: - if obj is None or obj.type != 'MESH': + for selected_object in context.selected_objects: + if selected_object is None or selected_object.type != 'MESH': continue - mesh_data = obj.data + # Evaluate the mesh after modifiers are applied + if options.use_raw_mesh_data: + mesh_object = selected_object + mesh_data = mesh_object.data + else: + depsgraph = context.evaluated_depsgraph_get() + bm = bmesh.new() + bm.from_object(selected_object, depsgraph) + mesh_data = bpy.data.meshes.new('') + bm.to_mesh(mesh_data) + del bm + mesh_object = bpy.data.objects.new('', mesh_data) + mesh_object.matrix_world = selected_object.matrix_world - if not is_collision_name(obj.name) and main_geometry_object is not None: + # TODO: copy the materials + + if not is_collision_name(mesh_object.name) and main_geometry_object is not None: geometry_object = main_geometry_object else: geometry_object = ASEGeometryObject() - geometry_object.name = obj.name + geometry_object.name = mesh_object.name if not geometry_object.is_collision: main_geometry_object = geometry_object ase.geometry_objects.append(geometry_object) @@ -37,25 +52,27 @@ class ASEBuilder(object): if geometry_object.is_collision: # Test that collision meshes are manifold and convex. bm = bmesh.new() - bm.from_mesh(obj.data) + bm.from_mesh(mesh_object.data) for edge in bm.edges: if not edge.is_manifold: - raise ASEBuilderError(f'Collision mesh \'{obj.name}\' is not manifold') + del bm + raise ASEBuilderError(f'Collision mesh \'{selected_object.name}\' is not manifold') if not edge.is_convex: - raise ASEBuilderError(f'Collision mesh \'{obj.name}\' is not convex') + del bm + raise ASEBuilderError(f'Collision mesh \'{selected_object.name}\' is not convex') - if not geometry_object.is_collision and len(mesh_data.materials) == 0: - raise ASEBuilderError(f'Mesh \'{obj.name}\' must have at least one material') + if not geometry_object.is_collision and len(selected_object.data.materials) == 0: + raise ASEBuilderError(f'Mesh \'{selected_object.name}\' must have at least one material') - vertex_transform = Matrix.Scale(options.scale, 4) @ Matrix.Rotation(math.pi, 4, 'Z') @ obj.matrix_world + vertex_transform = Matrix.Scale(options.scale, 4) @ Matrix.Rotation(math.pi, 4, 'Z') @ mesh_object.matrix_world for vertex_index, vertex in enumerate(mesh_data.vertices): geometry_object.vertices.append(vertex_transform @ vertex.co) material_indices = [] if not geometry_object.is_collision: - for mesh_material_index, material in enumerate(mesh_data.materials): + for mesh_material_index, material in enumerate(selected_object.data.materials): if material is None: - raise ASEBuilderError(f'Material slot {mesh_material_index + 1} for mesh \'{obj.name}\' cannot be empty') + raise ASEBuilderError(f'Material slot {mesh_material_index + 1} for mesh \'{selected_object.name}\' cannot be empty') try: # Reuse existing material entries for duplicates material_index = ase.materials.index(material.name) diff --git a/src/exporter.py b/src/exporter.py index 5a78312..68eee1c 100644 --- a/src/exporter.py +++ b/src/exporter.py @@ -24,6 +24,7 @@ class ASE_OT_ExportOperator(bpy.types.Operator, bpy_extras.io_utils.ExportHelper ('U', 'Unreal', '')), name='Units' ) + use_raw_mesh_data: BoolProperty(default=False, name='Raw Mesh Data') units_scale = { 'M': 60.352, @@ -33,10 +34,12 @@ class ASE_OT_ExportOperator(bpy.types.Operator, bpy_extras.io_utils.ExportHelper def draw(self, context): layout = self.layout layout.prop(self, 'units', expand=False) + layout.prop(self, 'use_raw_mesh_data') def execute(self, context): options = ASEBuilderOptions() options.scale = self.units_scale[self.units] + options.use_raw_mesh_data = self.use_raw_mesh_data try: ase = ASEBuilder().build(context, options) ASEWriter().write(self.filepath, ase) From 77f5aa21a51dcbc0e9df5b7e329e04f4fdcf0587 Mon Sep 17 00:00:00 2001 From: Colin Basnett Date: Mon, 16 May 2022 17:29:10 -0700 Subject: [PATCH 2/3] Removed defunct comment --- src/builder.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/builder.py b/src/builder.py index 5e38bac..b587d94 100644 --- a/src/builder.py +++ b/src/builder.py @@ -38,8 +38,6 @@ class ASEBuilder(object): mesh_object = bpy.data.objects.new('', mesh_data) mesh_object.matrix_world = selected_object.matrix_world - # TODO: copy the materials - if not is_collision_name(mesh_object.name) and main_geometry_object is not None: geometry_object = main_geometry_object else: From e2e3905e2e02f12f2c1bf77d62319b036455c8d2 Mon Sep 17 00:00:00 2001 From: Colin Basnett Date: Fri, 20 May 2022 16:40:55 -0700 Subject: [PATCH 3/3] Fixed a bug where collision meshes would not properly be exported in WYSIWYG mode --- src/builder.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/builder.py b/src/builder.py index b587d94..449b7c6 100644 --- a/src/builder.py +++ b/src/builder.py @@ -38,11 +38,11 @@ class ASEBuilder(object): mesh_object = bpy.data.objects.new('', mesh_data) mesh_object.matrix_world = selected_object.matrix_world - if not is_collision_name(mesh_object.name) and main_geometry_object is not None: + if not is_collision_name(selected_object.name) and main_geometry_object is not None: geometry_object = main_geometry_object else: geometry_object = ASEGeometryObject() - geometry_object.name = mesh_object.name + geometry_object.name = selected_object.name if not geometry_object.is_collision: main_geometry_object = geometry_object ase.geometry_objects.append(geometry_object)