[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [1149] contrib/py/scripts/addons/ mesh_bridge.py: Version 1.4.0

Bart Crouch bartius.crouch at gmail.com
Thu Nov 11 14:16:24 CET 2010


Revision: 1149
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-extensions&revision=1149
Author:   crouch
Date:     2010-11-11 14:16:24 +0100 (Thu, 11 Nov 2010)

Log Message:
-----------
Version 1.4.0
Major restructuring of code is done.
Should be stable.

Modified Paths:
--------------
    contrib/py/scripts/addons/mesh_bridge.py

Modified: contrib/py/scripts/addons/mesh_bridge.py
===================================================================
--- contrib/py/scripts/addons/mesh_bridge.py	2010-11-11 10:41:05 UTC (rev 1148)
+++ contrib/py/scripts/addons/mesh_bridge.py	2010-11-11 13:16:24 UTC (rev 1149)
@@ -16,9 +16,7 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
-# <pep8 compliant>
 
-
 """
 Bridge
 
@@ -26,23 +24,23 @@
 - Select a mesh and go into editmode
 - Select two or more edge-loops
 - Press Ctrl+F
-- Select the Bridge option
+- Select the Bridge or Loft option
 """
 
 
 bl_addon_info = {
     'name': 'Bridge',
     'author': 'Bartius Crouch',
-    'version': (1,1,0),
-    'blender': (2,5,4),
-    'api': 31878,
+    'version': (1, 4, 0),
+    'blender': (2, 5, 5),
+    'api': 32738,
     'location': 'View3D > Ctrl+F > Bridge',
-    'warning': '', # used for warning icon and text in addons panel
-    'description': 'Connect two or more loops of vertices.',
-    'wiki_url': 'http://wiki.blender.org/index.php/Extensions:Py/'\
-         'Scripts/',
-    'tracker_url': 'https://projects.blender.org/tracker/index.php?'\
-	    'func=detail&aid=23889&group_id=153&atid=467',
+    'warning': '',
+    'description': 'Bridge two, or loft several, loops of vertices.',
+    'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.5/Py/'\
+        'Scripts/Modeling/Bridge',
+    'tracker_url': 'http://projects.blender.org/tracker/index.php?'\
+        'func=detail&aid=23889&group_id=153&atid=468',
     'category': 'Mesh'}
 
 
@@ -51,14 +49,37 @@
 
 
 # gather initial data
-def initialise():
+def initialise(interpolation):
     global_undo = bpy.context.user_preferences.edit.use_global_undo
     bpy.context.user_preferences.edit.use_global_undo = False
     bpy.ops.object.mode_set(mode = 'OBJECT')
     mesh = bpy.context.active_object.data
-    return global_undo, mesh
+    old_selected_faces = [face.index for face in mesh.faces if face.select and not face.hide]
+    
+    smooth = False
+    if mesh.faces:
+        if sum([face.use_smooth for face in mesh.faces])/len(mesh.faces) >= 0.5:
+            smooth = True
 
+    if interpolation == 'cubic':
+        # dictionary with the edge-key as key
+        # and a list of connected valid faces as value
+        face_blacklist = [face.index for face in mesh.faces if face.select or face.hide]
+        edge_faces = dict([[edge.key, []] for edge in mesh.edges if not edge.hide])
+        for face in mesh.faces:
+            if face.index in face_blacklist:
+                continue
+            for key in face.edge_keys:
+                edge_faces[key].append(face)
+        # dictionary with the edge-key as key and edge as value
+        edgekey_to_edge = dict([[edge.key, edge] for edge in mesh.edges if edge.select and not edge.hide])
+    else:
+        edge_faces = False
+        edgekey_to_edge = False
+    
+    return global_undo, mesh, old_selected_faces, smooth, edge_faces, edgekey_to_edge
 
+
 # clean up and set settings back to original state
 def terminate(global_undo):
     bpy.ops.object.mode_set(mode = 'EDIT')
@@ -67,7 +88,17 @@
 
 # return a list of 2 non-connected loops (vertex indices), or False
 def get_selection(mesh):
-    selected_edges = [edge.key for edge in mesh.edges if edge.select and not edge.hide]
+    # create list of internal edges, which should be skipped
+    eks_of_selected_faces = [item for sublist in [face.edge_keys for face in mesh.faces if face.select and not face.hide] for item in sublist]
+    edge_count = {}
+    for ek in eks_of_selected_faces:
+        if ek in edge_count:
+            edge_count[ek] += 1
+        else:
+            edge_count[ek] = 1
+    internal_edges = [ek for ek in edge_count if edge_count[ek]>1]
+    
+    selected_edges = [edge.key for edge in mesh.edges if edge.select and not edge.hide and edge.key not in internal_edges]
     vert_connections = {}
     loops = []
     # dict with vertex index as key, list of connected vertices as value
@@ -79,12 +110,12 @@
                 if len(vert_connections[key[i]]) == 2:
                     return False
                 vert_connections[key[i]].append(key[1-i])
-
+    
     while len(vert_connections) > 0:
         loop = [iter(vert_connections.keys()).__next__()]
         growing = True
         sides_left = True
-        
+
         while growing:
             # no more connection data for current vertex
             if loop[-1] not in vert_connections:
@@ -93,41 +124,31 @@
                     sides_left = False
                 else:
                     growing = False
-            # test first possible connection
-            elif vert_connections[loop[-1]][-1] not in loop:
-                new_vert = vert_connections[loop[-1]].pop()
-                if len(vert_connections[loop[-1]]) == 0:
-                    del vert_connections[loop[-1]]
-                if new_vert in vert_connections:
-                    # remove connection both ways
-                    if loop[-1] in vert_connections[new_vert]:
-                        if len(vert_connections[new_vert]) == 1:
-                            del vert_connections[new_vert]
-                        else:
-                            vert_connections[new_vert].remove(loop[-1])
-                loop.append(new_vert)
-            # test second possible connection
-            elif len(vert_connections[loop[-1]]) > 1:
-                if vert_connections[loop[-1]][-2] not in loop:
-                    new_vert = vert_connections[loop[-1]].pop(-2)
-                    if len(vert_connections[loop[-1]]) == 0:
-                        del vert_connections[loop[-1]]
-                    if new_vert in vert_connections:
+            else:
+                extended = False
+                for connection_index, connecting_vertex in enumerate(vert_connections[loop[-1]]):
+                    if connecting_vertex not in loop:
+                        vert_connections[loop[-1]].pop(connection_index)
+                        if len(vert_connections[loop[-1]]) == 0:
+                            del vert_connections[loop[-1]]
                         # remove connection both ways
-                        if loop[-1] in vert_connections[new_vert]:
-                            if len(vert_connections[new_vert]) == 1:
-                                del vert_connections[new_vert]
+                        if connecting_vertex in vert_connections:
+                            if len(vert_connections[connecting_vertex]) == 1:
+                                del vert_connections[connecting_vertex]
                             else:
-                                vert_connections[new_vert].remove(loop[-1])
-                    loop.append(new_vert)
-            # found one end of the loop, continue with next
-            elif sides_left == True:
-                loop.reverse()
-                sides_left = False
-            # found both ends of the loop, stop growing
-            elif sides_left == False:
-                growing = False
-
+                                vert_connections[connecting_vertex].remove(loop[-1])
+                        loop.append(connecting_vertex)
+                        extended = True
+                        break
+                if not extended:
+                    # found one end of the loop, continue with next
+                    if sides_left == True:
+                        loop.reverse()
+                        sides_left = False
+                    # found both ends of the loop, stop growing
+                    elif sides_left == False:
+                        growing = False
+                    
         # check for circular
         if loop[0] in vert_connections:
             if loop[-1] in vert_connections[loop[0]]:
@@ -138,6 +159,8 @@
                     vert_connections[loop[0]].remove(loop[-1])
                 if len(vert_connections[loop[-1]]) == 1:
                     del vert_connections[loop[-1]]
+                else:
+                    vert_connections[loop[-1]].remove(loop[-1])
                 loop = [loop, True]
             else:
                 # not circular
@@ -186,66 +209,188 @@
     return loops
 
 
-# calculate faces (list of lists, vertex indices) that need to be added
-def calculate_faces(mesh, loops, mode, reverse):
-    faces = []
+# match up loops in pairs, used for multi-input bridging
+def match_loops(mesh, loops):
+    # calculate average loop normals and centers
+    normals = []
+    centers = []
+    for vertices, circular in loops:
+        normal = mathutils.Vector([0, 0, 0])
+        center = mathutils.Vector([0, 0, 0])
+        for vertex in vertices:
+            normal += mesh.vertices[vertex].normal
+            center += mesh.vertices[vertex].co
+        normals.append(normal / len(vertices) / 10)
+        centers.append(center / len(vertices))
+    
+    # possible matches if loop normals are faced towards the center of the other loop
+    matches = dict([[i, []] for i in range(len(loops))])
+    matches_amount = 0
+    for i in range(len(loops) + 1):
+        for j in range(i+1, len(loops)):
+            if (centers[i] - centers[j]).length > (centers[i] - (centers[j] + normals[j])).length and \
+            (centers[j] - centers[i]).length > (centers[j] - (centers[i] + normals[i])).length:
+                matches_amount += 1
+                matches[i].append([(centers[i] - centers[j]).length, i, j])
+                matches[j].append([(centers[i] - centers[j]).length, j, i])
+    # if no loops face each other, just make matches between all the loops
+    if matches_amount == 0:
+        for i in range(len(loops) + 1):
+            for j in range(i+1, len(loops)):
+                matches[i].append([(centers[i] - centers[j]).length, i, j])
+                matches[j].append([(centers[i] - centers[j]).length, j, i])
+    for key, value in matches.items():
+        value.sort()
+
+    # make matches based on distance between centers and number of vertices in loops
+    new_order = []
+    for loop_index in range(len(loops)):
+        if loop_index in new_order:
+            continue
+        loop_matches = matches[loop_index]
+        if not loop_matches:
+            continue
+        shortest_distance = loop_matches[0][0]
+        shortest_distance *= 1.1
+        loop_matches = [[abs(len(loops[loop_index][0])-len(loops[loop[2]][0])), loop[0], loop[1], loop[2]] for loop in loop_matches if loop[0] < shortest_distance]

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list