diff --git a/io_mesh_ply/__init__.py b/io_mesh_ply/__init__.py index 92b0bbdd0f010113f9a5392316b5c55db1ed347b..d7b8ff7ee4b2bf8f64d62dee41a2f27aded1cf91 100644 --- a/io_mesh_ply/__init__.py +++ b/io_mesh_ply/__init__.py @@ -46,8 +46,16 @@ if "bpy" in locals(): import os import bpy -from bpy.props import CollectionProperty, StringProperty, BoolProperty -from bpy_extras.io_utils import ImportHelper, ExportHelper +from bpy.props import (CollectionProperty, + StringProperty, + BoolProperty, + EnumProperty, + FloatProperty, + ) +from bpy_extras.io_utils import (ImportHelper, + ExportHelper, + axis_conversion, + ) class ImportPLY(bpy.types.Operator, ImportHelper): @@ -110,17 +118,60 @@ class ExportPLY(bpy.types.Operator, ExportHelper): use_colors = BoolProperty( name="Vertex Colors", description="Export the active vertex color layer", - default=True) + default=True, + ) + + axis_forward = EnumProperty( + name="Forward", + items=(('X', "X Forward", ""), + ('Y', "Y Forward", ""), + ('Z', "Z Forward", ""), + ('-X', "-X Forward", ""), + ('-Y', "-Y Forward", ""), + ('-Z', "-Z Forward", ""), + ), + default='Y', + ) + axis_up = EnumProperty( + name="Up", + items=(('X', "X Up", ""), + ('Y', "Y Up", ""), + ('Z', "Z Up", ""), + ('-X', "-X Up", ""), + ('-Y', "-Y Up", ""), + ('-Z', "-Z Up", ""), + ), + default='Z', + ) + global_scale = FloatProperty( + name="Scale", + min=0.01, max=1000.0, + default=1.0, + ) @classmethod def poll(cls, context): return context.active_object != None def execute(self, context): + from . import export_ply + + from mathutils import Matrix + + keywords = self.as_keywords(ignore=("axis_forward", + "axis_up", + "global_scale", + "check_existing", + "filter_glob", + )) + global_matrix = axis_conversion(to_forward=self.axis_forward, + to_up=self.axis_up, + ).to_4x4() * Matrix.Scale(self.global_scale, 4) + keywords["global_matrix"] = global_matrix + filepath = self.filepath filepath = bpy.path.ensure_ext(filepath, self.filename_ext) - from . import export_ply - keywords = self.as_keywords(ignore=("check_existing", "filter_glob")) + return export_ply.save(self, context, **keywords) def draw(self, context): @@ -133,6 +184,10 @@ class ExportPLY(bpy.types.Operator, ExportHelper): row.prop(self, "use_uv_coords") row.prop(self, "use_colors") + layout.prop(self, "axis_forward") + layout.prop(self, "axis_up") + layout.prop(self, "global_scale") + def menu_func_import(self, context): self.layout.operator(ImportPLY.bl_idname, text="Stanford (.ply)") diff --git a/io_mesh_ply/export_ply.py b/io_mesh_ply/export_ply.py index 4ef8b5fbc91c8db4a5f01868e250038c089cc5d6..d4db57107f13d2faec59c180b68617ffcc1a7aeb 100644 --- a/io_mesh_ply/export_ply.py +++ b/io_mesh_ply/export_ply.py @@ -189,13 +189,15 @@ def save(operator, use_normals=True, use_uv_coords=True, use_colors=True, + global_matrix=None ): scene = context.scene obj = context.active_object - if not obj: - raise Exception("Error, Select 1 active object") + if global_matrix is None: + from mathutils import Matrix + global_matrix = Matrix() if bpy.ops.object.mode_set.poll(): bpy.ops.object.mode_set(mode='OBJECT') @@ -208,7 +210,7 @@ def save(operator, if not mesh: raise Exception("Error, could not get mesh data from active object") - mesh.transform(obj.matrix_world) + mesh.transform(global_matrix * obj.matrix_world) if use_normals: mesh.calc_normals() diff --git a/io_mesh_stl/__init__.py b/io_mesh_stl/__init__.py index cb0badc5f6862cacdcf31f4cdca07326b0886abe..5260b5c0c08a63600c2213b740abae86b643d6ae 100644 --- a/io_mesh_stl/__init__.py +++ b/io_mesh_stl/__init__.py @@ -58,8 +58,16 @@ if "bpy" in locals(): import os import bpy -from bpy.props import StringProperty, BoolProperty, CollectionProperty -from bpy_extras.io_utils import ExportHelper, ImportHelper +from bpy.props import (StringProperty, + BoolProperty, + CollectionProperty, + EnumProperty, + FloatProperty, + ) +from bpy_extras.io_utils import (ImportHelper, + ExportHelper, + axis_conversion, + ) from bpy.types import Operator, OperatorFileListElement @@ -126,13 +134,46 @@ class ExportSTL(Operator, ExportHelper): default=True, ) + axis_forward = EnumProperty( + name="Forward", + items=(('X', "X Forward", ""), + ('Y', "Y Forward", ""), + ('Z', "Z Forward", ""), + ('-X', "-X Forward", ""), + ('-Y', "-Y Forward", ""), + ('-Z', "-Z Forward", ""), + ), + default='Y', + ) + axis_up = EnumProperty( + name="Up", + items=(('X', "X Up", ""), + ('Y', "Y Up", ""), + ('Z', "Z Up", ""), + ('-X', "-X Up", ""), + ('-Y', "-Y Up", ""), + ('-Z', "-Z Up", ""), + ), + default='Z', + ) + global_scale = FloatProperty( + name="Scale", + min=0.01, max=1000.0, + default=1.0, + ) + def execute(self, context): from . import stl_utils from . import blender_utils import itertools + from mathutils import Matrix + + global_matrix = axis_conversion(to_forward=self.axis_forward, + to_up=self.axis_up, + ).to_4x4() * Matrix.Scale(self.global_scale, 4) faces = itertools.chain.from_iterable( - blender_utils.faces_from_mesh(ob, self.use_mesh_modifiers) + blender_utils.faces_from_mesh(ob, global_matrix, self.use_mesh_modifiers) for ob in context.selected_objects) stl_utils.write_stl(self.filepath, faces, self.ascii) diff --git a/io_mesh_stl/blender_utils.py b/io_mesh_stl/blender_utils.py index 1de66f2098aed0a968e865efb877d973c4b13375..a13277adaf0931f25b51cae8afc91e6d8097e61f 100644 --- a/io_mesh_stl/blender_utils.py +++ b/io_mesh_stl/blender_utils.py @@ -42,7 +42,7 @@ def create_and_link_mesh(name, faces, points): obj.select = True -def faces_from_mesh(ob, use_mesh_modifiers=False, triangulate=True): +def faces_from_mesh(ob, global_matrix, use_mesh_modifiers=False, triangulate=True): """ From an object, return a generator over a list of faces. @@ -65,7 +65,7 @@ def faces_from_mesh(ob, use_mesh_modifiers=False, triangulate=True): except RuntimeError: raise StopIteration - mesh.transform(ob.matrix_world) + mesh.transform(global_matrix * ob.matrix_world) if triangulate: # From a list of faces, return the face triangulated if needed. diff --git a/io_scene_obj/__init__.py b/io_scene_obj/__init__.py index 60a43168ba1a5237e7c8229c848c46e1ce7ca205..34c736ad6b88a3616b7223acca2efe9cc0d82575 100644 --- a/io_scene_obj/__init__.py +++ b/io_scene_obj/__init__.py @@ -46,8 +46,8 @@ from bpy.props import (BoolProperty, StringProperty, EnumProperty, ) -from bpy_extras.io_utils import (ExportHelper, - ImportHelper, +from bpy_extras.io_utils import (ImportHelper, + ExportHelper, path_reference_mode, axis_conversion, ) @@ -302,7 +302,6 @@ class ExportOBJ(bpy.types.Operator, ExportHelper): ), default='-Z', ) - axis_up = EnumProperty( name="Up", items=(('X', "X Up", ""), diff --git a/io_scene_vrml2/__init__.py b/io_scene_vrml2/__init__.py index 7e02d6b0a413efe0f2e007c3a23cfeb6ff55800c..02f5073cc885655dd5281b0121962708398a2cb3 100644 --- a/io_scene_vrml2/__init__.py +++ b/io_scene_vrml2/__init__.py @@ -39,8 +39,16 @@ if "bpy" in locals(): import os import bpy -from bpy.props import CollectionProperty, StringProperty, BoolProperty, EnumProperty -from bpy_extras.io_utils import ExportHelper, path_reference_mode, axis_conversion +from bpy.props import (CollectionProperty, + StringProperty, + BoolProperty, + EnumProperty, + FloatProperty, + ) +from bpy_extras.io_utils import (ExportHelper, + path_reference_mode, + axis_conversion, + ) class ExportVRML(bpy.types.Operator, ExportHelper): """Export mesh objects as a VRML2, """ \ @@ -101,6 +109,11 @@ class ExportVRML(bpy.types.Operator, ExportHelper): ), default='Y', ) + global_scale = FloatProperty( + name="Scale", + min=0.01, max=1000.0, + default=1.0, + ) path_mode = path_reference_mode @@ -110,20 +123,24 @@ class ExportVRML(bpy.types.Operator, ExportHelper): return (obj is not None) and obj.type == 'MESH' def execute(self, context): - filepath = self.filepath - filepath = bpy.path.ensure_ext(filepath, self.filename_ext) from . import export_vrml2 + from mathutils import Matrix keywords = self.as_keywords(ignore=("axis_forward", "axis_up", + "global_scale", "check_existing", "filter_glob", )) + global_matrix = axis_conversion(to_forward=self.axis_forward, to_up=self.axis_up, - ).to_4x4() + ).to_4x4() * Matrix.Scale(self.global_scale, 4) keywords["global_matrix"] = global_matrix + filepath = self.filepath + filepath = bpy.path.ensure_ext(filepath, self.filename_ext) + return export_vrml2.save(self, context, **keywords) def draw(self, context): @@ -140,6 +157,7 @@ class ExportVRML(bpy.types.Operator, ExportHelper): row.prop(self, "color_type") layout.prop(self, "axis_forward") layout.prop(self, "axis_up") + layout.prop(self, "global_scale") layout.prop(self, "path_mode") diff --git a/object_print3d_utils/__init__.py b/object_print3d_utils/__init__.py index ad080d1ee4e512b852d7c69ccc501c186aea5c46..2e0dbb7df0eb6ac22eada4efce63b19e143f25d7 100644 --- a/object_print3d_utils/__init__.py +++ b/object_print3d_utils/__init__.py @@ -71,6 +71,11 @@ class Print3DSettings(PropertyGroup): description="Copies textures on export to the output path", default=False, ) + use_apply_scale = BoolProperty( + name="Apply Scale", + description="Applies scene scale setting on export", + default=False, + ) export_path = StringProperty( name="Export Directory", description="Path to directory where the files are created", diff --git a/object_print3d_utils/export.py b/object_print3d_utils/export.py index 4c582f8a1e7ef1f7f919d0bebf61e8d310ca49d2..d0eeca3f186028a6a83ee5b60805c5b3feca2487 100644 --- a/object_print3d_utils/export.py +++ b/object_print3d_utils/export.py @@ -51,13 +51,15 @@ def image_copy_guess(filepath, objects): def write_mesh(context, info, report_cb): scene = context.scene + unit = scene.unit_settings print_3d = scene.print_3d obj_base = scene.object_bases.active obj = obj_base.object export_format = print_3d.export_format - path_mode = 'COPY' if print_3d.use_export_texture else 'AUTO' + global_scale = unit.scale_length if (unit.system != 'NONE' and print_3d.use_apply_scale) else 1.0 + path_mode = 'COPY' if print_3d.use_export_texture else 'AUTO' context_override = context.copy() @@ -120,6 +122,7 @@ def write_mesh(context, info, report_cb): filepath=filepath, ascii=False, use_mesh_modifiers=True, + global_scale=global_scale, ) elif export_format == 'PLY': addon_ensure("io_mesh_ply") @@ -128,6 +131,7 @@ def write_mesh(context, info, report_cb): context_override, filepath=filepath, use_mesh_modifiers=True, + global_scale=global_scale, ) elif export_format == 'X3D': addon_ensure("io_scene_x3d") @@ -138,6 +142,7 @@ def write_mesh(context, info, report_cb): use_mesh_modifiers=True, use_selection=True, path_mode=path_mode, + global_scale=global_scale, ) elif export_format == 'WRL': addon_ensure("io_scene_vrml2") @@ -148,6 +153,7 @@ def write_mesh(context, info, report_cb): use_mesh_modifiers=True, use_selection=True, path_mode=path_mode, + global_scale=global_scale, ) elif export_format == 'OBJ': addon_ensure("io_scene_obj") @@ -158,6 +164,7 @@ def write_mesh(context, info, report_cb): use_mesh_modifiers=True, use_selection=True, path_mode=path_mode, + global_scale=global_scale, ) else: assert(0) diff --git a/object_print3d_utils/ui.py b/object_print3d_utils/ui.py index 25a72c9378fe7557f379541016d5da54b733ef4e..9a141dd7b6ebbff12c29b011769f33a4e16d36f5 100644 --- a/object_print3d_utils/ui.py +++ b/object_print3d_utils/ui.py @@ -109,10 +109,12 @@ class Print3DToolBar: # col.operator("mesh.print3d_clean_thin", text="Wall Thickness") col = layout.column() - col.label("Export Directory:") + rowsub = col.row(align=True) + rowsub.label("Export Path:") + rowsub.prop(print_3d, "use_apply_scale", text="", icon='MAN_SCALE') + rowsub.prop(print_3d, "use_export_texture", text="", icon='FILE_IMAGE') rowsub = col.row() rowsub.prop(print_3d, "export_path", text="") - rowsub.prop(print_3d, "use_export_texture", text="", icon='FILE_IMAGE') rowsub = col.row(align=True) rowsub.prop(print_3d, "export_format", text="")