[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [3689] contrib/py/scripts/addons/ mesh_insert_edge_ring.py: initial comit of insert_edge_ring

Florian Meyer florianfelix at web.de
Thu Aug 30 22:56:16 CEST 2012


Revision: 3689
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=3689
Author:   testscreenings
Date:     2012-08-30 20:56:16 +0000 (Thu, 30 Aug 2012)
Log Message:
-----------
initial comit of insert_edge_ring

Added Paths:
-----------
    contrib/py/scripts/addons/mesh_insert_edge_ring.py

Added: contrib/py/scripts/addons/mesh_insert_edge_ring.py
===================================================================
--- contrib/py/scripts/addons/mesh_insert_edge_ring.py	                        (rev 0)
+++ contrib/py/scripts/addons/mesh_insert_edge_ring.py	2012-08-30 20:56:16 UTC (rev 3689)
@@ -0,0 +1,374 @@
+#Simplified BSD License
+#
+#Copyright (c) 2012, Florian Meyer
+#tstscr at web.de
+#All rights reserved.
+#
+#Redistribution and use in source and binary forms, with or without
+#modification, are permitted provided that the following conditions are met: 
+#
+#1. Redistributions of source code must retain the above copyright notice, this
+#   list of conditions and the following disclaimer. 
+#2. Redistributions in binary form must reproduce the above copyright notice,
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution. 
+#
+#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+#ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+#DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+#ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+#(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+#LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+#ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+#SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#################################################################
+bl_info = {
+    "name": "Insert Edge Ring",
+    "author": "tstscr (tstscr at web.de)",
+    "version": (1, 0),
+    "blender": (2, 6, 4),
+    "location": "View3D > Edge Specials > Insert edge ring (Ctrl Alt R)",
+    "description": "Insert an edge ring along the selected edge loop",
+    "warning": "",
+    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Mesh/Insert_Edge_Ring",
+    "tracker_url": "",
+    "category": "Mesh"}
+###########################################################################
+import bpy, bmesh, math
+from bpy.types import Operator
+from bpy.props import FloatProperty, BoolProperty, EnumProperty
+from mathutils import Vector
+from collections import deque
+from bmesh.utils import vert_separate
+###########################################################################
+def update(bme):
+    bme.verts.index_update()
+    bme.edges.index_update()
+
+def selected_edges(component, invert=False):
+    def is_vert(vert):
+        if invert:
+            return [e for e in component.link_edges if not e.select]
+        return [e for e in component.link_edges if e.select]
+    if type(component) == bmesh.types.BMVert:
+        return is_vert(component)
+    if type(component) == bmesh.types.BMEdge:
+        edges = []
+        for vert in component.verts:
+            edges.extend(is_vert(vert))
+        if component in edges:
+            edges.remove(component)
+        return edges
+
+def edge_loop_from(v_start):
+    
+    def walk(vert, vert_loop=deque()):
+        #print('from', vert.index)
+        edges_select = selected_edges(vert)
+        #print('length edges_select', len(edges_select))
+        if not vert_loop:
+            #print('inserting %d into vert_loop' %vert.index)
+            vert_loop.append(vert)
+        
+        for edge in edges_select:
+            other_vert = edge.other_vert(vert)
+            #print('other_vert %d' %other_vert.index)
+            
+            edge_is_valid = True
+            if edge.is_boundary \
+            or other_vert in vert_loop \
+            or len(edges_select) > 2 \
+            or len(selected_edges(other_vert)) > 2:
+                #print('is not valid')
+                edge_is_valid = False
+            
+            if edge_is_valid:
+                if vert == vert_loop[-1]:
+                    #print('appending %d' %other_vert.index)
+                    vert_loop.append(other_vert)
+                else:
+                    #print('prepending %d' %other_vert.index)
+                    vert_loop.appendleft(other_vert)
+                    
+                walk(other_vert, vert_loop)
+        
+        return vert_loop
+    #####################################
+    v_loop = walk(v_start)
+    #print('returning', [v.index for v in v_loop])
+    return v_loop
+
+
+def collect_edge_loops(bme):
+    edge_loops = []
+    verts_to_consider = [v for v in bme.verts if v.select]
+    
+    while verts_to_consider:
+        
+        v_start = verts_to_consider[-1]
+        #print('\nverts_to_consider', [v.index for v in verts_to_consider])
+        edge_loop = edge_loop_from(v_start)
+        #update(bme)
+        #print('edge_loop', [v.index for v in edge_loop])
+        for v in edge_loop:
+            try:
+                verts_to_consider.remove(v)
+            except:
+                print('tried to remove vert %d from verts_to_consider. \
+                       Failed somehow' %v.index)
+        
+        if len(edge_loop) >= 3:
+            edge_loops.append(edge_loop)
+        else:
+            for v in edge_loop:
+                v.select = False
+    
+    if not verts_to_consider:
+        #print('no more verts_to_consider')
+        pass
+    
+    return edge_loops
+
+
+def insert_edge_ring(self, context):
+    def split_edge_loop(vert_loop):
+        other_loop = deque()
+        new_loop = deque()
+        for vert in vert_loop:
+            #print('OPERATING ON VERT', vert.index)
+            edges = selected_edges(vert)
+            v_new = bmesh.utils.vert_separate(vert, edges)
+            #print('RIPPING vert %d into' %vert.index, [v.index for v in v_new][:], \
+            #       'along edges', [e.index for e in edges])
+            if not closed:
+                if len(v_new) == 2:
+                    other_loop.append([v for v in v_new if v != vert][0])
+                else:
+                    other_loop.append(vert)
+            
+            if closed:
+                if not new_loop:
+                    #print('start_new_loop')
+                    new_loop.append(v_new[0])
+                    other_loop.append(v_new[1])
+                else:
+                    neighbours = [e.other_vert(v_new[0]) for e in v_new[0].link_edges]
+                    #print('neighbours', [n.index for n in neighbours])
+                    for n in neighbours:
+                        if n in new_loop and v_new[0] not in new_loop:
+                            #print('v_detect')
+                            new_loop.append(v_new[0])
+                            other_loop.append(v_new[1])
+                        if n in other_loop and v_new[0] not in other_loop:
+                            #print('v_not_detect')
+                            new_loop.append(v_new[1])
+                            other_loop.append(v_new[0])
+                
+        return other_loop, new_loop
+    
+    def move_verts(vert_loop, other_vert_loop):
+        
+        ### Offsets ###
+        def calc_offsets():
+            #print('\nCALCULATING OFFSETS')
+            offset = {}
+            for i, vert in enumerate(vert_loop):
+                edges_select = selected_edges(vert)
+                edges_unselect = selected_edges(vert, invert=True)
+                
+                vert_opposite = other_vert_loop[i]
+                edges_select_opposite = selected_edges(vert_opposite)
+                edges_unselect_opposite = selected_edges(vert_opposite, invert=True)
+                
+                ### MESH END VERT
+                if vert == other_vert_loop[0] or vert == other_vert_loop[-1]:
+                    #print('vert %d is start-end in middle of mesh, \
+                    #       does not need moving\n' %vert.index)
+                    continue
+                
+                ### BOUNDARY VERT
+                if len(edges_select) == 1:
+                    #print('verts %d  %d are on boundary' \
+                    #%(vert.index, other_vert_loop[i].index))
+                    border_edge = [e for e in edges_unselect if e.is_boundary][0]
+                    off = (border_edge.other_vert(vert).co - vert.co).normalized()
+                    if self.direction == 'LEFT':
+                        off *= 0
+                    offset[vert] = off
+                    #opposite vert
+                    border_edge_opposite = [e for e in edges_unselect_opposite \
+                                            if e.is_boundary][0]
+                    off = (border_edge_opposite.other_vert(vert_opposite).co \
+                           - vert_opposite.co).normalized()
+                    if self.direction == 'RIGHT':
+                        off *= 0
+                    offset[vert_opposite] = off
+                    continue
+                
+                ### MIDDLE VERT
+                if len(edges_select) == 2:
+                    #print('\nverts %d  %d are in middle of loop' \
+                    #%(vert.index, other_vert_loop[i].index))
+                    tangents = [e.calc_tangent(e.link_loops[0]) for e in edges_select]
+                    off = (tangents[0] + tangents[1]).normalized()
+                    angle = tangents[0].angle(tangents[1])
+                    if self.even:
+                        off += off * angle * 0.263910
+                    if self.direction == 'LEFT':
+                        off *= 0
+                    offset[vert] = off
+                    #opposite vert
+                    tangents = [e.calc_tangent(e.link_loops[0]) \
+                                for e in edges_select_opposite]
+                    off = (tangents[0] + tangents[1]).normalized()
+                    #angle= tangents[0].angle(tangents[1])
+                    if self.even:
+                        off += off * angle * 0.263910
+                    if self.direction == 'RIGHT':
+                        off *= 0
+                    offset[vert_opposite] = off
+                    continue
+            
+            return offset
+        
+        ### Moving ###
+        def move(offsets):
+            #print('\nMOVING VERTS')
+            for vert in offsets:

@@ Diff output truncated at 10240 characters. @@


More information about the Bf-extensions-cvs mailing list