[Bf-extensions-cvs] [c6c1130b] master: mesh_tools; add mesh_edges_length
meta-androcto
noreply at git.blender.org
Sun Jun 2 11:00:56 CEST 2019
Commit: c6c1130bd6e64576b10c363226a78f0628899ca0
Author: meta-androcto
Date: Sun Jun 2 19:00:38 2019 +1000
Branches: master
https://developer.blender.org/rBACc6c1130bd6e64576b10c363226a78f0628899ca0
mesh_tools; add mesh_edges_length
===================================================================
M mesh_tools/__init__.py
A mesh_tools/mesh_edges_length.py
===================================================================
diff --git a/mesh_tools/__init__.py b/mesh_tools/__init__.py
index 28bef77f..e82908c5 100644
--- a/mesh_tools/__init__.py
+++ b/mesh_tools/__init__.py
@@ -46,7 +46,7 @@ if "bpy" in locals():
importlib.reload(mesh_edge_roundifier)
importlib.reload(mesh_edgetools)
importlib.reload(mesh_edges_floor_plan)
-
+ importlib.reload(mesh_edges_length)
else:
from . import mesh_offset_edges
@@ -58,6 +58,7 @@ else:
from . import mesh_edge_roundifier
from . import mesh_edgetools
from . import mesh_edges_floor_plan
+ from . import mesh_edges_length
import bmesh
@@ -944,6 +945,8 @@ class VIEW3D_PT_edit_mesh_tools(Panel):
row = col_top.row(align=True)
row.operator('mesh.edge_roundifier', text="Edge Roundify")
row = col_top.row(align=True)
+ row.operator('object.mesh_edge_length_set', text="Set Edge Length")
+ row = col_top.row(align=True)
row.operator('mesh.edges_floor_plan', text="Edges Floor Plan")
row = col_top.row(align=True)
row.operator("mesh.extrude_edges_move", text="Extrude Edges")
@@ -1120,7 +1123,7 @@ def register():
mesh_edge_roundifier.register()
mesh_edgetools.register()
mesh_edges_floor_plan.register()
-
+ mesh_edges_length.register()
# unregistering and removing menus
def unregister():
@@ -1142,6 +1145,7 @@ def unregister():
mesh_edge_roundifier.unregister()
mesh_edgetools.unregister()
mesh_edges_floor_plan.unregister()
+ mesh_edges_length.unregister()
if __name__ == "__main__":
register()
diff --git a/mesh_tools/mesh_edges_length.py b/mesh_tools/mesh_edges_length.py
new file mode 100644
index 00000000..f4f1d067
--- /dev/null
+++ b/mesh_tools/mesh_edges_length.py
@@ -0,0 +1,341 @@
+# gpl author: Giuseppe De Marco [BlenderLab] inspired by NirenYang
+
+bl_info = {
+ "name": "Set edges length",
+ "description": "Edges length",
+ "author": "Giuseppe De Marco [BlenderLab] inspired by NirenYang",
+ "version": (0, 1, 0),
+ "blender": (2, 71, 0),
+ "location": "Toolbar > Tools > Mesh Tools: set Length(Shit+Alt+E)",
+ "warning": "",
+ "wiki_url": "",
+ "category": "Mesh",
+ }
+
+import bpy
+import bmesh
+from mathutils import Vector
+from bpy.types import Operator
+from bpy.props import (
+ FloatProperty,
+ EnumProperty,
+ )
+
+# GLOBALS
+edge_length_debug = False
+_error_message = "Please select at least one edge to fill select history"
+_error_message_2 = "Edges with shared vertices are not allowed. Please, use scale instead"
+
+# Note : Refactor - removed all the operators apart from LengthSet
+# and merged the other ones as options of length (lijenstina)
+
+
+def get_edge_vector(edge):
+ verts = (edge.verts[0].co, edge.verts[1].co)
+ vector = verts[1] - verts[0]
+
+ return vector
+
+
+def get_selected(bmesh_obj, geometry_type):
+ # geometry type should be edges, verts or faces
+ selected = []
+
+ for i in getattr(bmesh_obj, geometry_type):
+ if i.select:
+ selected.append(i)
+ return tuple(selected)
+
+
+def get_center_vector(verts):
+ # verts = [Vector((x,y,z)), Vector((x,y,z))]
+
+ center_vector = Vector((((verts[1][0] + verts[0][0]) / 2.),
+ ((verts[1][1] + verts[0][1]) / 2.),
+ ((verts[1][2] + verts[0][2]) / 2.)))
+ return center_vector
+
+
+class LengthSet(Operator):
+ bl_idname = "object.mesh_edge_length_set"
+ bl_label = "Set edge length"
+ bl_description = ("Change one selected edge length by a specified target,\n"
+ "existing length and different modes\n"
+ "Note: works only with Edges that not share a vertex")
+ bl_options = {'REGISTER', 'UNDO'}
+
+ old_length: FloatProperty(
+ name="Original length",
+ options={'HIDDEN'},
+ )
+ set_length_type: EnumProperty(
+ items=[
+ ('manual', "Manual",
+ "Input manually the desired Target Length"),
+ ('existing', "Existing Length",
+ "Use existing geometry Edges' characteristics"),
+ ],
+ name="Set Type of Input",
+ )
+ target_length: FloatProperty(
+ name="Target Length",
+ description="Input a value for an Edges Length target",
+ default=1.00,
+ unit='LENGTH',
+ precision=5
+ )
+ existing_length: EnumProperty(
+ items=[
+ ('min', "Shortest",
+ "Set all to shortest Edge of selection"),
+ ('max', "Longest",
+ "Set all to the longest Edge of selection"),
+ ('average', "Average",
+ "Set all to the average Edge length of selection"),
+ ('active', "Active",
+ "Set all to the active Edge's one\n"
+ "Needs a selection to be done in Edge Select mode"),
+ ],
+ name="Existing length"
+ )
+ mode: EnumProperty(
+ items=[
+ ('fixed', "Fixed", "Fixed"),
+ ('increment', "Increment", "Increment"),
+ ('decrement', "Decrement", "Decrement"),
+ ],
+ name="Mode"
+ )
+ behaviour: EnumProperty(
+ items=[
+ ('proportional', "Proportional",
+ "Move vertex locations proportionally to the center of the Edge"),
+ ('clockwise', "Clockwise",
+ "Compute the Edges' vertex locations in a clockwise fashion"),
+ ('unclockwise', "Counterclockwise",
+ "Compute the Edges' vertex locations in a counterclockwise fashion"),
+ ],
+ name="Resize behavior"
+ )
+
+ originary_edge_length_dict = {}
+ edge_lengths = []
+ selected_edges = ()
+
+ @classmethod
+ def poll(cls, context):
+ return (context.edit_object and context.object.type == 'MESH')
+
+ def check(self, context):
+ return True
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.label(text="Original Active length is: {:.3f}".format(self.old_length))
+
+ layout.label(text="Input Mode:")
+ layout.prop(self, "set_length_type", expand=True)
+ if self.set_length_type == 'manual':
+ layout.prop(self, "target_length")
+ else:
+ layout.prop(self, "existing_length", text="")
+
+ layout.label(text="Mode:")
+ layout.prop(self, "mode", text="")
+
+ layout.label(text="Resize Behavior:")
+ layout.prop(self, "behaviour", text="")
+
+ def get_existing_edge_length(self, bm):
+ if self.existing_length != "active":
+ if self.existing_length == "min":
+ return min(self.edge_lengths)
+ if self.existing_length == "max":
+ return max(self.edge_lengths)
+ elif self.existing_length == "average":
+ return sum(self.edge_lengths) / float(len(self.selected_edges))
+ else:
+ bm.edges.ensure_lookup_table()
+ active_edge_length = None
+
+ for elem in reversed(bm.select_history):
+ if isinstance(elem, bmesh.types.BMEdge):
+ active_edge_length = elem.calc_length()
+ break
+ return active_edge_length
+
+ return 0.0
+
+ def invoke(self, context, event):
+ wm = context.window_manager
+
+ obj = context.edit_object
+ bm = bmesh.from_edit_mesh(obj.data)
+
+ bpy.ops.mesh.select_mode(type="EDGE")
+ self.selected_edges = get_selected(bm, 'edges')
+
+ if self.selected_edges:
+ vertex_set = []
+
+ for edge in self.selected_edges:
+ vector = get_edge_vector(edge)
+
+ if edge.verts[0].index not in vertex_set:
+ vertex_set.append(edge.verts[0].index)
+ else:
+ self.report({'ERROR_INVALID_INPUT'}, _error_message_2)
+ return {'CANCELLED'}
+
+ if edge.verts[1].index not in vertex_set:
+ vertex_set.append(edge.verts[1].index)
+ else:
+ self.report({'ERROR_INVALID_INPUT'}, _error_message_2)
+ return {'CANCELLED'}
+
+ # warning, it's a constant !
+ verts_index = ''.join((str(edge.verts[0].index), str(edge.verts[1].index)))
+ self.originary_edge_length_dict[verts_index] = vector
+ self.edge_lengths.append(vector.length)
+ self.old_length = vector.length
+ else:
+ self.report({'ERROR'}, _error_message)
+ return {'CANCELLED'}
+
+ if edge_length_debug:
+ self.report({'INFO'}, str(self.originary_edge_length_dict))
+
+ if bpy.context.scene.unit_settings.system == 'IMPERIAL':
+ # imperial to metric conversion
+ vector.length = (0.9144 * vector.length) / 3
+
+ self.target_length = vector.length
+
+ return wm.invoke_props_dialog(self)
+
+ def execute(self, context):
+
+ bpy.ops.mesh.select_mode(type="EDGE")
+ self.context = context
+
+ obj = context.edit_object
+ bm = bmesh.from_edit_mesh(obj.data)
+
+ self.selected_edges = get_selected(bm, 'edges')
+
+ if not self.selected_edges:
+ self.report({'ERROR'}, _error_message)
+ return {'CANCELLED'}
+
+ for edge in self.selected_edges:
+ vector = get_edge_vector(edge)
+ # what we should see in original length dialog field
+ self.old_length = vector.length
+
+ if self.set_length_type == 'manual':
+ vector.length = abs(self.target_length)
+ else:
+ get_lengths = self.get_existing_edge_length(bm)
+ # check for edit mode
+ if not get_lengths:
+ self.report({'WARNING'},
+ "Operation Cancelled. "
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-extensions-cvs
mailing list