Changeset View
Changeset View
Standalone View
Standalone View
io_mesh_stl/__init__.py
| Show First 20 Lines • Show All 237 Lines • ▼ Show 20 Lines | class ExportSTL(Operator, ExportHelper): | ||||
| ) | ) | ||||
| batch_mode: EnumProperty( | batch_mode: EnumProperty( | ||||
| name="Batch Mode", | name="Batch Mode", | ||||
| items=( | items=( | ||||
| ('OFF', "Off", "All data in one file"), | ('OFF', "Off", "All data in one file"), | ||||
| ('OBJECT', "Object", "Each object as a file"), | ('OBJECT', "Object", "Each object as a file"), | ||||
| ), | ), | ||||
| ) | ) | ||||
| use_global_frame: BoolProperty( | |||||
| name="Use Global Frame", | |||||
| description="Export geometry in the global frame (True), or the object's local frame (False)", | |||||
| default=True, | |||||
| ) | |||||
| @property | @property | ||||
| def check_extension(self): | def check_extension(self): | ||||
| return self.batch_mode == 'OFF' | return self.batch_mode == 'OFF' | ||||
campbellbarton: No need for a default. The property should only be used when it's set. | |||||
| def execute(self, context): | def execute(self, context): | ||||
| import os | import os | ||||
| import itertools | import itertools | ||||
| from mathutils import Matrix | from mathutils import Matrix | ||||
| from . import stl_utils | from . import stl_utils | ||||
| from . import blender_utils | from . import blender_utils | ||||
| keywords = self.as_keywords( | keywords = self.as_keywords( | ||||
| ignore=( | ignore=( | ||||
| "axis_forward", | "axis_forward", | ||||
| "axis_up", | "axis_up", | ||||
| "use_selection", | "use_selection", | ||||
| "global_scale", | "global_scale", | ||||
| "check_existing", | "check_existing", | ||||
| "filter_glob", | "filter_glob", | ||||
| "use_scene_unit", | "use_scene_unit", | ||||
| "use_mesh_modifiers", | "use_mesh_modifiers", | ||||
| "batch_mode" | "batch_mode", | ||||
| "use_global_frame" | |||||
| ), | ), | ||||
| ) | ) | ||||
| scene = context.scene | scene = context.scene | ||||
| if self.use_selection: | if self.use_selection: | ||||
| data_seq = context.selected_objects | data_seq = context.selected_objects | ||||
| else: | else: | ||||
| data_seq = scene.objects | data_seq = scene.objects | ||||
| # Take into account scene's unit scale, so that 1 inch in Blender gives 1 inch elsewhere! See T42000. | # Take into account scene's unit scale, so that 1 inch in Blender gives 1 inch elsewhere! See T42000. | ||||
| global_scale = self.global_scale | global_scale = self.global_scale | ||||
| if scene.unit_settings.system != 'NONE' and self.use_scene_unit: | if scene.unit_settings.system != 'NONE' and self.use_scene_unit: | ||||
| global_scale *= scene.unit_settings.scale_length | global_scale *= scene.unit_settings.scale_length | ||||
| if self.use_global_frame: | |||||
| global_matrix = axis_conversion( | global_matrix = axis_conversion( | ||||
| to_forward=self.axis_forward, | to_forward=self.axis_forward, | ||||
| to_up=self.axis_up, | to_up=self.axis_up, | ||||
| ).to_4x4() @ Matrix.Scale(global_scale, 4) | ).to_4x4() @ Matrix.Scale(global_scale, 4) | ||||
| else: | |||||
| # Don't adjust orientation if using local (object) coordinates | |||||
| global_matrix = Matrix.Scale(global_scale, 4) | |||||
| if self.batch_mode == 'OFF': | if self.batch_mode == 'OFF': | ||||
| faces = itertools.chain.from_iterable( | faces = itertools.chain.from_iterable( | ||||
| blender_utils.faces_from_mesh(ob, global_matrix, self.use_mesh_modifiers) | blender_utils.faces_from_mesh(ob, global_matrix, self.use_mesh_modifiers, self.use_global_frame) | ||||
| for ob in data_seq) | for ob in data_seq) | ||||
| stl_utils.write_stl(faces=faces, **keywords) | stl_utils.write_stl(faces=faces, **keywords) | ||||
| elif self.batch_mode == 'OBJECT': | elif self.batch_mode == 'OBJECT': | ||||
| prefix = os.path.splitext(self.filepath)[0] | prefix = os.path.splitext(self.filepath)[0] | ||||
| keywords_temp = keywords.copy() | keywords_temp = keywords.copy() | ||||
| for ob in data_seq: | for ob in data_seq: | ||||
| faces = blender_utils.faces_from_mesh(ob, global_matrix, self.use_mesh_modifiers) | faces = blender_utils.faces_from_mesh(ob, global_matrix, self.use_mesh_modifiers, self.use_global_frame) | ||||
| keywords_temp["filepath"] = prefix + bpy.path.clean_name(ob.name) + ".stl" | keywords_temp["filepath"] = prefix + bpy.path.clean_name(ob.name) + ".stl" | ||||
| stl_utils.write_stl(faces=faces, **keywords_temp) | stl_utils.write_stl(faces=faces, **keywords_temp) | ||||
| return {'FINISHED'} | return {'FINISHED'} | ||||
| def draw(self, context): | def draw(self, context): | ||||
| pass | pass | ||||
| ▲ Show 20 Lines • Show All 67 Lines • ▼ Show 20 Lines | def draw(self, context): | ||||
| layout.use_property_decorate = False # No animation. | layout.use_property_decorate = False # No animation. | ||||
| sfile = context.space_data | sfile = context.space_data | ||||
| operator = sfile.active_operator | operator = sfile.active_operator | ||||
| layout.prop(operator, "global_scale") | layout.prop(operator, "global_scale") | ||||
| layout.prop(operator, "use_scene_unit") | layout.prop(operator, "use_scene_unit") | ||||
| layout.prop(operator, "use_global_frame") | |||||
| if operator.use_global_frame: | |||||
| layout.prop(operator, "axis_forward") | layout.prop(operator, "axis_forward") | ||||
| layout.prop(operator, "axis_up") | layout.prop(operator, "axis_up") | ||||
| class STL_PT_export_geometry(bpy.types.Panel): | class STL_PT_export_geometry(bpy.types.Panel): | ||||
| bl_space_type = 'FILE_BROWSER' | bl_space_type = 'FILE_BROWSER' | ||||
| bl_region_type = 'TOOL_PROPS' | bl_region_type = 'TOOL_PROPS' | ||||
| bl_label = "Geometry" | bl_label = "Geometry" | ||||
| bl_parent_id = "FILE_PT_operator" | bl_parent_id = "FILE_PT_operator" | ||||
| ▲ Show 20 Lines • Show All 56 Lines • Show Last 20 Lines | |||||
No need for a default. The property should only be used when it's set.