[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