[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [25420] trunk/blender/release/scripts: Update 2.4x script: UV Follow active quads initial port thanks to Michael Williamson, added operator option, reporting, menu, edge length option myself.

Campbell Barton ideasman42 at gmail.com
Wed Dec 16 22:27:07 CET 2009


Revision: 25420
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=25420
Author:   campbellbarton
Date:     2009-12-16 22:27:07 +0100 (Wed, 16 Dec 2009)

Log Message:
-----------
Update 2.4x script: UV Follow active quads initial port thanks to Michael Williamson, added operator option, reporting, menu, edge length option myself.

Modified Paths:
--------------
    trunk/blender/release/scripts/modules/bpy_types.py
    trunk/blender/release/scripts/op/uvcalc_follow_active.py

Modified: trunk/blender/release/scripts/modules/bpy_types.py
===================================================================
--- trunk/blender/release/scripts/modules/bpy_types.py	2009-12-16 21:23:09 UTC (rev 25419)
+++ trunk/blender/release/scripts/modules/bpy_types.py	2009-12-16 21:27:07 UTC (rev 25420)
@@ -243,7 +243,83 @@
         edge_face_count_dict = self.edge_face_count_dict
         return [edge_face_count_dict.get(ed.key, 0) for ed in mesh.edges]
 
+    def edge_loops(self, faces=None, seams=()):
+        '''
+        Edge loops defined by faces
 
+        Takes me.faces or a list of faces and returns the edge loops
+        These edge loops are the edges that sit between quads, so they dont touch
+        1 quad, note: not connected will make 2 edge loops, both only containing 2 edges.
+
+        return a list of edge key lists
+        [ [(0,1), (4, 8), (3,8)], ...]
+
+        optionaly, seams are edge keys that will be removed
+        '''
+
+        OTHER_INDEX = 2,3,0,1 # opposite face index
+        
+        if faces is None:
+            faces= self.faces
+
+        edges = {}
+
+        for f in faces:
+#            if len(f) == 4:
+            if f.verts_raw[3] != 0:
+                edge_keys = f.edge_keys
+                for i, edkey in enumerate(f.edge_keys):
+                    edges.setdefault(edkey, []).append(edge_keys[OTHER_INDEX[i]])
+    
+        for edkey in seams:
+            edges[edkey] = []
+    
+        # Collect edge loops here
+        edge_loops = []    
+    
+        for edkey, ed_adj in edges.items():
+            if 0 <len(ed_adj) < 3: # 1 or 2
+                # Seek the first edge
+                context_loop = [edkey, ed_adj[0]]
+                edge_loops.append(context_loop)
+                if len(ed_adj) == 2:
+                    other_dir = ed_adj[1]
+                else:
+                    other_dir = None
+            
+                ed_adj[:] = []
+            
+                flipped = False
+            
+                while 1:
+                    # from knowing the last 2, look for th next.
+                    ed_adj = edges[context_loop[-1]]
+                    if len(ed_adj) != 2:
+                    
+                        if other_dir and flipped==False: # the original edge had 2 other edges
+                            flipped = True # only flip the list once
+                            context_loop.reverse()
+                            ed_adj[:] = []
+                            context_loop.append(other_dir) # save 1 lookiup
+                        
+                            ed_adj = edges[context_loop[-1]]
+                            if len(ed_adj) != 2:
+                                ed_adj[:] = []
+                                break
+                        else:
+                            ed_adj[:] = []
+                            break
+                
+                    i = ed_adj.index(context_loop[-2])
+                    context_loop.append( ed_adj[ not  i] )
+                
+                    # Dont look at this again
+                    ed_adj[:] = []
+
+    
+        return edge_loops
+
+
 class MeshEdge(StructRNA):
     __slots__ = ()
 

Modified: trunk/blender/release/scripts/op/uvcalc_follow_active.py
===================================================================
--- trunk/blender/release/scripts/op/uvcalc_follow_active.py	2009-12-16 21:23:09 UTC (rev 25419)
+++ trunk/blender/release/scripts/op/uvcalc_follow_active.py	2009-12-16 21:27:07 UTC (rev 25420)
@@ -1,58 +1,42 @@
-#!BPY
-"""
-Name: 'Follow Active (quads)'
-Blender: 242
-Group: 'UVCalculation'
-Tooltip: 'Follow from active quads.'
-"""
-__author__ = "Campbell Barton"
-__url__ = ("blender", "blenderartists.org")
-__version__ = "1.0 2006/02/07"
-
-__bpydoc__ = """\
-This script sets the UV mapping and image of selected faces from adjacent unselected faces.
-
-for full docs see...
-http://mediawiki.blender.org/index.php/Scripts/Manual/UV_Calculate/Follow_active_quads
-"""
-
-# ***** BEGIN GPL LICENSE BLOCK *****
+# ##### BEGIN GPL LICENSE BLOCK #####
 #
-# Script copyright (C) Campbell J Barton
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
 #
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-# --------------------------------------------------------------------------
+# ##### END GPL LICENSE BLOCK #####
 
+# <pep8 compliant>
 
-from Blender import *
+#for full docs see...
+# http://mediawiki.blender.org/index.php/Scripts/Manual/UV_Calculate/Follow_active_quads
+
 import bpy
-import BPyMesh
 
-def extend(EXTEND_MODE,ob):
-	if EXTEND_MODE == -1:
-		return
-	me = ob.getData(mesh=1)
+def extend(obj, operator, EXTEND_MODE):
+	me = obj.data
 	me_verts = me.verts
-		# Toggle Edit mode
-	is_editmode = Window.EditMode()
+	# script will fail without UVs
+	if not me.active_uv_texture:
+		me.add_uv_texture()
+	
+
+	# Toggle Edit mode
+	is_editmode = (obj.mode == 'EDIT')
 	if is_editmode:
-		Window.EditMode(0)
-	Window.WaitCursor(1)
-	t = sys.time()
+		bpy.ops.object.mode_set(mode='OBJECT')
+
+	#t = sys.time()
 	edge_average_lengths = {}
 	
 	OTHER_INDEX = 2,3,0,1
@@ -65,17 +49,22 @@
 		'''
 		
 		def face_edge_vs(vi):
-			# assunme a quad
+			# assume a quad
 			return [(vi[0], vi[1]), (vi[1], vi[2]), (vi[2], vi[3]), (vi[3], vi[0])]
-		
-		uvs_source = face_source.uv
-		uvs_target = face_target.uv
-		
-		vidx_source = [v.index for v in face_source] 
-		vidx_target = [v.index for v in face_target]
-		
+	
+		vidx_source = face_source.verts 
+		vidx_target = face_target.verts
+
+		faceUVsource = me.active_uv_texture.data[face_source.index]
+		uvs_source = [faceUVsource.uv1,faceUVsource.uv2,faceUVsource.uv3,faceUVsource.uv4] 
+
+		faceUVtarget = me.active_uv_texture.data[face_target.index]
+		uvs_target = [faceUVtarget.uv1,faceUVtarget.uv2,faceUVtarget.uv3,faceUVtarget.uv4] 
+
 		# vertex index is the key, uv is the value
+
 		uvs_vhash_source = dict( [ (vindex, uvs_source[i]) for i, vindex in enumerate(vidx_source)] )
+
 		uvs_vhash_target = dict( [ (vindex, uvs_target[i]) for i, vindex in enumerate(vidx_target)] )
 		
 		edge_idxs_source = face_edge_vs(vidx_source)
@@ -87,9 +76,9 @@
 		edge_key_swap = edge_key[1], edge_key[0]
 		
 		try:	source_matching_edge = edge_idxs_source.index(edge_key)
-		except:	source_matching_edge = edge_idxs_source.index(edge_key_swap)
+		except: source_matching_edge = edge_idxs_source.index(edge_key_swap)
 		try:	target_matching_edge = edge_idxs_target.index(edge_key)
-		except:	target_matching_edge = edge_idxs_target.index(edge_key_swap)
+		except: target_matching_edge = edge_idxs_target.index(edge_key_swap)
 		
 
 		
@@ -111,7 +100,7 @@
 
 		# Set the 2 UV's on the target face that are not touching
 		# for this we need to do basic expaning on the source faces UV's
-		if EXTEND_MODE == 2:
+		if EXTEND_MODE == 'LENGTH':
 			
 			try: # divide by zero is possible
 				'''
@@ -138,16 +127,17 @@
 			# same as above but with no factor
 			uvs_vhash_target[edgepair_outer_target[iB]][:] = uvs_vhash_source[edgepair_inner_source[0]] + (uvs_vhash_source[edgepair_inner_source[0]] - uvs_vhash_source[edgepair_outer_source[1]])
 			uvs_vhash_target[edgepair_outer_target[iA]][:] = uvs_vhash_source[edgepair_inner_source[1]] + (uvs_vhash_source[edgepair_inner_source[1]] - uvs_vhash_source[edgepair_outer_source[0]])
+
+
+	if me.active_uv_texture == None:
+		me.add_uv_texture
 	
-	if not me.faceUV:
-		me.faceUV= True
-	
-	face_act = 	me.activeFace
+	face_act =  me.faces.active
 	if face_act == -1:
-		Draw.PupMenu('ERROR: No active face')
+		operator.report({'ERROR'}, "No active face.")
 		return
 	
-	face_sel= [f for f in me.faces if len(f) == 4 and f.sel]
+	face_sel= [f for f in me.faces if len(f.verts) == 4 and f.selected]
 	
 	face_act_local_index = -1
 	for i, f in enumerate(face_sel):
@@ -156,12 +146,12 @@
 			break
 	
 	if face_act_local_index == -1:
-		Draw.PupMenu('ERROR: Active face not selected')
+		operator.report({'ERROR'}, "Active face not selected.")
 		return
 	
 	
 	
-	# Modes
+	# Modes 
 	# 0 unsearched
 	# 1:mapped, use search from this face. - removed!!
 	# 2:all siblings have been searched. dont search again.
@@ -174,12 +164,12 @@
 	for i, f in enumerate(face_sel):
 		for edkey in f.edge_keys:
 			try:	edge_faces[edkey].append(i)
-			except:	edge_faces[edkey] = [i]
+			except: edge_faces[edkey] = [i]
 	
-	SEAM = Mesh.EdgeFlags.SEAM
+	#SEAM = me.edges.seam
 	
-	if EXTEND_MODE == 2:
-		edge_loops = BPyMesh.getFaceLoopEdges(face_sel, [ed.key for ed in me.edges if ed.flag & SEAM] )
+	if EXTEND_MODE == 'LENGTH':
+		edge_loops = me.edge_loops(face_sel, [ed.key for ed in me.edges if ed.seam] )
 		me_verts = me.verts
 		for loop in edge_loops:
 			looplen = [0.0]
@@ -192,18 +182,18 @@
 	
 	# remove seams, so we dont map accross seams.
 	for ed in me.edges:
-		if ed.flag & SEAM:
+		if ed.seam:
 			# remove the edge pair if we can
 			try:	del edge_faces[ed.key]
-			except:	pass
+			except: pass
 	# Done finding seams
 	
 	
 	# face connectivity - faces around each face
 	# only store a list of indicies for each face.
-	face_faces = [[] for i in xrange(len(face_sel))]

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list