[Bf-extensions-cvs] [ccfde7b] master: Snap Utilities Line: Calculate the nearest edges in a loop (instead of using the selection operator)
Germano Cavalcante
noreply at git.blender.org
Mon Apr 10 02:00:15 CEST 2017
Commit: ccfde7b1b8462f7e8a82f89b6dd075d0d4c6f2bd
Author: Germano Cavalcante
Date: Sun Apr 9 20:59:44 2017 -0300
Branches: master
https://developer.blender.org/rBAccfde7b1b8462f7e8a82f89b6dd075d0d4c6f2bd
Snap Utilities Line: Calculate the nearest edges in a loop (instead of using the selection operator)
In addition to indentation and rearrangement of some functions
===================================================================
M mesh_snap_utilities_line.py
===================================================================
diff --git a/mesh_snap_utilities_line.py b/mesh_snap_utilities_line.py
index 749c5e1..0079b8b 100644
--- a/mesh_snap_utilities_line.py
+++ b/mesh_snap_utilities_line.py
@@ -55,15 +55,15 @@ from bpy.props import (
def get_units_info(scale, unit_system, separate_units):
if unit_system == 'METRIC':
- scale_steps = ((1000, 'km'), (1, 'm'), (1 / 100, 'cm'),
- (1 / 1000, 'mm'), (1 / 1000000, '\u00b5m'))
+ scale_steps = ((1000, 'km'), (1, 'm'), (1 / 100, 'cm'),
+ (1 / 1000, 'mm'), (1 / 1000000, '\u00b5m'))
elif unit_system == 'IMPERIAL':
- scale_steps = ((5280, 'mi'), (1, '\''),
- (1 / 12, '"'), (1 / 12000, 'thou'))
- scale /= 0.3048 # BU to feet
+ scale_steps = ((5280, 'mi'), (1, '\''),
+ (1 / 12, '"'), (1 / 12000, 'thou'))
+ scale /= 0.3048 # BU to feet
else:
- scale_steps = ((1, ' BU'),)
- separate_units = False
+ scale_steps = ((1, ' BU'),)
+ separate_units = False
return (scale, scale_steps, separate_units)
@@ -73,26 +73,27 @@ def convert_distance(val, units_info, precision=5):
sval = val * scale
idx = 0
while idx < len(scale_steps) - 1:
- if sval >= scale_steps[idx][0]:
- break
- idx += 1
+ if sval >= scale_steps[idx][0]:
+ break
+ idx += 1
factor, suffix = scale_steps[idx]
sval /= factor
if not separate_units or idx == len(scale_steps) - 1:
- dval = str(round(sval, precision)) + suffix
+ dval = str(round(sval, precision)) + suffix
else:
- ival = int(sval)
- dval = str(round(ival, precision)) + suffix
- fval = sval - ival
+ ival = int(sval)
+ dval = str(round(ival, precision)) + suffix
+ fval = sval - ival
+ idx += 1
+ while idx < len(scale_steps):
+ fval *= scale_steps[idx - 1][0] / scale_steps[idx][0]
+ if fval >= 1:
+ dval += ' ' \
+ + ("%.1f" % fval) \
+ + scale_steps[idx][1]
+ break
idx += 1
- while idx < len(scale_steps):
- fval *= scale_steps[idx - 1][0] / scale_steps[idx][0]
- if fval >= 1:
- dval += ' ' \
- + ("%.1f" % fval) \
- + scale_steps[idx][1]
- break
- idx += 1
+
return dval
@@ -166,6 +167,38 @@ def out_Location(rv3d, region, orig, vector):
return hit
+def get_closest_edge(bm, point, dist):
+ r_edge = None
+ for edge in bm.edges:
+ v1 = edge.verts[0].co
+ v2 = edge.verts[1].co
+ # Test the BVH (AABB) first
+ for i in range(3):
+ if v1[i] <= v2[i]:
+ isect = v1[i] - dist <= point[i] <= v2[i] + dist
+ else:
+ isect = v2[i] - dist <= point[i] <= v1[i] + dist
+
+ if not isect:
+ break
+ else:
+ ret = intersect_point_line(point, v1, v2)
+
+ if ret[1] < 0.0:
+ tmp = v1
+ elif ret[1] > 1.0:
+ tmp = v2
+ else:
+ tmp = ret[0]
+
+ new_dist = (point - tmp).length
+ if new_dist <= dist:
+ dist = new_dist
+ r_edge = edge
+
+ return r_edge
+
+
class SnapCache():
bvert = None
vco = None
@@ -242,11 +275,11 @@ def snap_utilities(
cache.v2dmid = location_3d_to_region_2d(region, rv3d, cache.vmid)
if previous_vert and previous_vert not in bm_geom.verts:
- pvert_co = obj_matrix_world * previous_vert.co
- perp_point = intersect_point_line(pvert_co, cache.v0, cache.v1)
- cache.vperp = perp_point[0]
- # factor = point_perpendicular[1]
- cache.v2dperp = location_3d_to_region_2d(region, rv3d, perp_point[0])
+ pvert_co = obj_matrix_world * previous_vert.co
+ perp_point = intersect_point_line(pvert_co, cache.v0, cache.v1)
+ cache.vperp = perp_point[0]
+ # factor = point_perpendicular[1]
+ cache.v2dperp = location_3d_to_region_2d(region, rv3d, perp_point[0])
# else: cache.v2dperp = None
@@ -273,9 +306,8 @@ def snap_utilities(
is_increment = True
r_type = 'EDGE'
- fac = fac_nearest_to_segment_2d(mcursor, cache.v2d0, cache.v2d1)
- fac *= cache.v2d0.z / cache.v2d1.z # convert to fac3d
- r_loc = cache.v0 + fac * (cache.v1 - cache.v0)
+ orig, view_vector = region_2d_to_orig_and_view_vector(region, rv3d, mcursor)
+ r_loc = intersect_line_line(cache.v0, cache.v1, orig, orig + view_vector)[0]
elif isinstance(bm_geom, bmesh.types.BMFace):
is_increment = True
@@ -284,7 +316,7 @@ def snap_utilities(
if cache.bface != bm_geom:
cache.bface = bm_geom
cache.fmid = obj_matrix_world * bm_geom.calc_center_median()
- cache.fnor = bm_geom.normal * obj_matrix_world.inverted()
+ cache.fnor = bm_geom.normal * obj_matrix_world
orig, view_vector = region_2d_to_orig_and_view_vector(region, rv3d, mcursor)
end = orig + view_vector
@@ -302,6 +334,9 @@ def snap_utilities(
face_index = -1
if cache.out_obj is None:
+ ## TODO: The Scene.raycast also tests the edited object.
+ # This is highly inefficient because the edited object
+ # does not keep DerivedMesh which forces rebuilding the bvhtree.
result, r_loc, normal, face_index, cache.out_obj, cache.out_obmat = scene.ray_cast(orig, view_vector)
if result:
r_type = 'FACE'
@@ -354,7 +389,7 @@ def snap_utilities(
is_increment = False
r_loc = intersect_point_line(r_loc, constrain[0], constrain[1])[0]
else:
- r_loc = intersect_line_line(constrain[0], constrain[1], orig, end)[0]
+ r_loc = intersect_line_line(constrain[0], constrain[1], orig, orig + view_vector)[0]
elif not r_loc:
r_loc = out_Location(rv3d, region, orig, view_vector)
@@ -371,117 +406,153 @@ def snap_utilities(
return r_loc, r_type, bm_geom, r_len
-def get_isolated_edges(bmvert):
+def get_loose_linked_edges(bmvert):
linked = [e for e in bmvert.link_edges if not e.link_faces]
for e in linked:
linked += [le for v in e.verts if not v.link_faces for le in v.link_edges if le not in linked]
return linked
-def draw_line(self, obj, Bmesh, bm_geom, location):
+def draw_line(self, obj, bm, bm_geom, location):
if not hasattr(self, 'list_verts'):
self.list_verts = []
if not hasattr(self, 'list_edges'):
self.list_edges = []
- if not hasattr(self, 'list_faces'):
- self.list_faces = []
+ update_edit_mesh = False
+ tessface = False
if bm_geom is None:
- vertices = (bmesh.ops.create_vert(Bmesh, co=(location)))
- self.list_verts.append(vertices['vert'][0])
+ vert = bm.verts.new(location)
+ self.list_verts.append(vert)
elif isinstance(bm_geom, bmesh.types.BMVert):
- if (bm_geom.co - location).length < .01:
+ if (bm_geom.co - location).length_squared < .001:
if self.list_verts == [] or self.list_verts[-1] != bm_geom:
self.list_verts.append(bm_geom)
else:
- vertices = bmesh.ops.create_vert(Bmesh, co=(location))
- self.list_verts.append(vertices['vert'][0])
+ vert = bm.verts.new(location)
+ self.list_verts.append(vert)
elif isinstance(bm_geom, bmesh.types.BMEdge):
self.list_edges.append(bm_geom)
- vector_p0_l = (bm_geom.verts[0].co - location)
- vector_p1_l = (bm_geom.verts[1].co - location)
- cross = vector_p0_l.cross(vector_p1_l) / bm_geom.calc_length()
+ ret = intersect_point_line(location, bm_geom.verts[0].co, bm_geom.verts[1].co)
- if cross < Vector((0.001, 0, 0)): # or round(vector_p0_l.angle(vector_p1_l), 2) == 3.14:
- factor = vector_p0_l.length / bm_geom.calc_length()
- vertex0 = bmesh.utils.edge_split(bm_geom, bm_geom.verts[0], factor)
- self.list_verts.append(vertex0[1])
- # self.list_edges.append(vertex0[0])
+ if (ret[0] - location).length_squared < .001:
+ if ret[1] == 0.0:
+ vert = bm_geom.verts[0]
+ elif ret[1] == 1.0:
+ vert = bm_geom.verts[1]
+ else:
+ edge, vert = bmesh.utils.edge_split(bm_geom, bm_geom.verts[0], ret[1])
+ self.list_verts.append(vert)
+ # self.list_edges.append(edge)
else: # constrain point is near
- vertices = bmesh.ops.create_vert(Bmesh, co=(location))
- self.list_verts.append(vertices['vert'][0])
+ vert = bm.verts.new(location)
+ self.list_verts.append(vert)
elif isinstance(bm_geom, bmesh.types.BMFace):
self.list_faces.append(bm_geom)
- vertices = (bmesh.ops.create_vert(Bmesh, co=(location)))
- self.list_verts.append(vertices['vert'][0])
+ vert = bm.verts.new(location)
+ self.list_verts.append(vert)
# draw, split and create face
if len(self.list_verts) >= 2:
- V1 = self.list_verts[-2]
- V2 = self.list_verts[-1]
- # V2_link_verts = [x for y in [a.verts for a in V2.link_edges] for x in y if x != V2]
- for edge in V2.link_edges:
- if V1 in edge.verts:
+ v1, v2 = self.list_verts[-2:]
+ # v2_link_verts = [x for y in [a.verts for a in v2.link_edges] for x in y if x != v2]
+ for edge in v2.link_edges:
+ if v1 in edge.verts:
self.list_edges.append(edge)
break
- else: # if V1 not in V2_link_verts:
- if not V2.l
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-extensions-cvs
mailing list