Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2013-05-06 11:04:51 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-05-06 11:04:51 +0400
commit90c30944807f4aabe5bdee18799b4e3a8bac8f81 (patch)
treea0a5a9575d56f6a576783df7b38d329815abc02a
parentf18b4f55dd8ecc66c08caca211975e948a40acd2 (diff)
add scale to bounds, scale to volume - to the 3d toolbox
-rw-r--r--object_print3d_utils/__init__.py3
-rw-r--r--object_print3d_utils/mesh_helpers.py10
-rw-r--r--object_print3d_utils/operators.py101
-rw-r--r--object_print3d_utils/ui.py12
4 files changed, 119 insertions, 7 deletions
diff --git a/object_print3d_utils/__init__.py b/object_print3d_utils/__init__.py
index fbaec5ab..7ba258a2 100644
--- a/object_print3d_utils/__init__.py
+++ b/object_print3d_utils/__init__.py
@@ -137,6 +137,9 @@ classes = (
operators.Print3DSelectReport,
+ operators.Print3DScaleToVolume,
+ operators.Print3DScaleToBounds,
+
operators.Print3DExport,
Print3DSettings,
diff --git a/object_print3d_utils/mesh_helpers.py b/object_print3d_utils/mesh_helpers.py
index a9bd3c75..faf16d2e 100644
--- a/object_print3d_utils/mesh_helpers.py
+++ b/object_print3d_utils/mesh_helpers.py
@@ -98,6 +98,16 @@ def bmesh_calc_volume(bm):
for f in bm.faces)))
+def bmesh_calc_volume_signed(bm):
+ """
+ Calculate the volume of a triangulated bmesh.
+ """
+ def tri_signed_volume(p1, p2, p3):
+ return p1.dot(p2.cross(p3)) / 6.0
+ return sum((tri_signed_volume(*(v.co for v in f.verts))
+ for f in bm.faces))
+
+
def bmesh_calc_area(bm):
"""
Calculate the surface area.
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
diff --git a/object_print3d_utils/ui.py b/object_print3d_utils/ui.py
index 9a141dd7..84c3b3f7 100644
--- a/object_print3d_utils/ui.py
+++ b/object_print3d_utils/ui.py
@@ -71,9 +71,9 @@ class Print3DToolBar:
row = layout.row()
row.label("Statistics:")
- col = layout.column(align=True)
- col.operator("mesh.print3d_info_volume", text="Volume")
- col.operator("mesh.print3d_info_area", text="Area")
+ rowsub = layout.row(align=True)
+ rowsub.operator("mesh.print3d_info_volume", text="Volume")
+ rowsub.operator("mesh.print3d_info_area", text="Area")
row = layout.row()
row.label("Checks:")
@@ -108,6 +108,12 @@ class Print3DToolBar:
# XXX TODO
# col.operator("mesh.print3d_clean_thin", text="Wall Thickness")
+ row = layout.row()
+ row.label("Scale To:")
+ rowsub = layout.row(align=True)
+ rowsub.operator("mesh.print3d_scale_to_volume", text="Volume")
+ rowsub.operator("mesh.print3d_scale_to_bounds", text="Bounds")
+
col = layout.column()
rowsub = col.row(align=True)
rowsub.label("Export Path:")