Fix T42000: STL export scale incorrect.

Not a bug, in fact, more like a feature request.
Added an option to take into account scene's scale on both export and import time.

Also added scaling/axis conversion to importer.
This commit is contained in:
Bastien Montagne 2014-10-07 16:15:53 +02:00
parent 54eaab823a
commit e6b174a3b6
Notes: blender-bot 2023-02-14 20:03:09 +01:00
Referenced by issue #42000, STL export scale incorrect.
2 changed files with 77 additions and 14 deletions

View File

@ -90,13 +90,59 @@ class ImportSTL(Operator, ImportHelper):
subtype='DIR_PATH',
)
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,
)
use_scene_unit = BoolProperty(
name="Scene Unit",
description="Apply current scene's unit (as defined by unit scale) to imported data",
default=False,
)
def execute(self, context):
from . import stl_utils
from . import blender_utils
from mathutils import Matrix
paths = [os.path.join(self.directory, name.name)
for name in self.files]
scene = context.scene
# Take into account scene's unit scale, so that 1 inch in Blender gives 1 inch elsewhere! See T42000.
global_scale = self.global_scale
if scene.unit_settings.system != 'NONE' and self.use_scene_unit:
global_scale /= scene.unit_settings.scale_length
global_matrix = axis_conversion(from_forward=self.axis_forward,
from_up=self.axis_up,
).to_4x4() * Matrix.Scale(global_scale, 4)
if not paths:
paths.append(self.filepath)
@ -109,7 +155,7 @@ class ImportSTL(Operator, ImportHelper):
for path in paths:
objName = bpy.path.display_name(os.path.basename(path))
tris, pts = stl_utils.read_stl(path)
blender_utils.create_and_link_mesh(objName, tris, pts)
blender_utils.create_and_link_mesh(objName, tris, pts, global_matrix)
return {'FINISHED'}
@ -122,17 +168,6 @@ class ExportSTL(Operator, ExportHelper):
filename_ext = ".stl"
filter_glob = StringProperty(default="*.stl", options={'HIDDEN'})
ascii = BoolProperty(
name="Ascii",
description="Save the file in ASCII file format",
default=False,
)
use_mesh_modifiers = BoolProperty(
name="Apply Modifiers",
description="Apply the modifiers before saving",
default=True,
)
axis_forward = EnumProperty(
name="Forward",
items=(('X', "X Forward", ""),
@ -161,6 +196,23 @@ class ExportSTL(Operator, ExportHelper):
default=1.0,
)
use_scene_unit = BoolProperty(
name="Scene Unit",
description="Apply current scene's unit (as defined by unit scale) to exported data",
default=True,
)
ascii = BoolProperty(
name="Ascii",
description="Save the file in ASCII file format",
default=False,
)
use_mesh_modifiers = BoolProperty(
name="Apply Modifiers",
description="Apply the modifiers before saving",
default=False,
)
def execute(self, context):
from . import stl_utils
from . import blender_utils
@ -171,12 +223,20 @@ class ExportSTL(Operator, ExportHelper):
"global_scale",
"check_existing",
"filter_glob",
"use_scene_unit",
"use_mesh_modifiers",
))
scene = context.scene
# Take into account scene's unit scale, so that 1 inch in Blender gives 1 inch elsewhere! See T42000.
global_scale = self.global_scale
if scene.unit_settings.system != 'NONE' and self.use_scene_unit:
global_scale *= scene.unit_settings.scale_length
global_matrix = axis_conversion(to_forward=self.axis_forward,
to_up=self.axis_up,
).to_4x4() * Matrix.Scale(self.global_scale, 4)
).to_4x4() * Matrix.Scale(global_scale, 4)
faces = itertools.chain.from_iterable(
blender_utils.faces_from_mesh(ob, global_matrix, self.use_mesh_modifiers)

View File

@ -21,11 +21,14 @@
import bpy
def create_and_link_mesh(name, faces, points):
def create_and_link_mesh(name, faces, points, global_matrix):
"""
Create a blender mesh and object called name from a list of
*points* and *faces* and link it in the current scene.
"""
from mathutils import Vector
points = tuple(global_matrix * Vector(p) for p in points)
mesh = bpy.data.meshes.new(name)
mesh.from_pydata(points, [], faces)