From 90c30944807f4aabe5bdee18799b4e3a8bac8f81 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 6 May 2013 07:04:51 +0000 Subject: add scale to bounds, scale to volume - to the 3d toolbox --- object_print3d_utils/operators.py | 101 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 97 insertions(+), 4 deletions(-) (limited to 'object_print3d_utils/operators.py') diff --git a/object_print3d_utils/operators.py b/object_print3d_utils/operators.py index 76d2dc6e..6e5a380a 100644 --- a/object_print3d_utils/operators.py +++ b/object_print3d_utils/operators.py @@ -49,6 +49,7 @@ def clean_float(text): # --------- # Mesh Info + class Print3DInfoVolume(Operator): """Report the volume of the active mesh""" bl_idname = "mesh.print3d_info_volume" @@ -67,7 +68,7 @@ class Print3DInfoVolume(Operator): info = [] info.append(("Volume: %s³" % clean_float("%.4f" % volume), None)) - info.append(("%s cm³" % clean_float("%.4f" % ((volume * (scale * scale * scale)) / (0.01 * 0.01 * 0.01) )), + info.append(("%s cm³" % clean_float("%.4f" % ((volume * (scale * scale * scale)) / (0.01 * 0.01 * 0.01))), None)) report.update(*info) @@ -139,7 +140,6 @@ class Print3DCheckSolid(Operator): return execute_check(self, context) - class Print3DCheckIntersections(Operator): """Check geometry for self intersections""" bl_idname = "mesh.print3d_check_intersect" @@ -236,7 +236,6 @@ class Print3DCheckThick(Operator): info.append(("Thin Faces: %d" % len(faces_error), (bmesh.types.BMFace, faces_error))) - def execute(self, context): return execute_check(self, context) @@ -461,7 +460,6 @@ class Print3DSelectReport(Operator): bmesh.types.BMFace: "faces", } - def execute(self, context): obj = context.edit_object info = report.info() @@ -488,6 +486,101 @@ class Print3DSelectReport(Operator): return {'FINISHED'} +# ----------- +# Scale to... + +def _scale(scale, report=None): + if scale != 1.0: + bpy.ops.transform.resize(value=(scale,) * 3, + mirror=False, proportional='DISABLED', + snap=False, + texture_space=False) + if report is not None: + report({'INFO'}, "Scaled by %s" % clean_float("%.6f" % scale)) + + +class Print3DScaleToVolume(Operator): + """Scale edit-mesh or selected-objects to a set volume""" + bl_idname = "mesh.print3d_scale_to_volume" + bl_label = "Scale to Volume" + bl_options = {'REGISTER', 'UNDO'} + + volume_init = FloatProperty( + options={'HIDDEN'}, + ) + volume = FloatProperty( + name="Volume", + unit='VOLUME', + min=0.0, max=100000.0, + ) + + def execute(self, context): + import math + scale = math.pow(self.volume, 1 / 3) / math.pow(self.volume_init, 1 / 3) + self.report({'INFO'}, "Scaled by %s" % clean_float("%.6f" % scale)) + _scale(scale, self.report) + return {'FINISHED'} + + def invoke(self, context, event): + + def calc_volume(obj): + bm = mesh_helpers.bmesh_copy_from_object(obj, apply_modifiers=True) + volume = mesh_helpers.bmesh_calc_volume_signed(bm) + bm.free() + return volume + + if context.mode == 'EDIT_MESH': + volume = calc_volume(context.edit_object) + else: + volume = sum(calc_volume(obj) for obj in context.selected_editable_objects + if obj.type == 'MESH') + + self.volume_init = self.volume = abs(volume) + + wm = context.window_manager + return wm.invoke_props_dialog(self) + + +class Print3DScaleToBounds(Operator): + """Scale edit-mesh or selected-objects to fit within a maximum length""" + bl_idname = "mesh.print3d_scale_to_bounds" + bl_label = "Scale to Bounds" + bl_options = {'REGISTER', 'UNDO'} + + length_init = FloatProperty( + options={'HIDDEN'}, + ) + length = FloatProperty( + name="Length Limit", + unit='LENGTH', + min=0.0, max=100000.0, + ) + + def execute(self, context): + scale = self.length / self.length_init + _scale(scale, self.report) + return {'FINISHED'} + + def invoke(self, context, event): + from mathutils import Vector + + def calc_length(vecs): + return max((max(v[i] for v in vecs) - min(v[i] for v in vecs)) for i in range(3)) + + if context.mode == 'EDIT_MESH': + length = calc_length([Vector(v) * obj.matrix_world + for v in context.edit_object.bound_box]) + else: + length = calc_length([Vector(v) * obj.matrix_world + for obj in context.selected_editable_objects + if obj.type == 'MESH' for v in obj.bound_box]) + + self.length_init = self.length = length + + wm = context.window_manager + return wm.invoke_props_dialog(self) + + # ------ # Export -- cgit v1.2.3