[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