diff options
author | Campbell Barton <ideasman42@gmail.com> | 2005-12-19 00:41:50 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2005-12-19 00:41:50 +0300 |
commit | 4a027d8124fb9fd52e78fa8cfc9412821dec5900 (patch) | |
tree | 8b11b89e788a0169459b76b42d82d9445d7ed862 /release | |
parent | c9de5c5b0595dfebc09dd48b276ca22e62ed2f2c (diff) |
Updated for new Mathutils (should be faster)
uses Mesh rather then NMesh
uses expernal box packer
uv coords are not stretched anynore.
Diffstat (limited to 'release')
-rw-r--r-- | release/scripts/archimap.py | 660 |
1 files changed, 54 insertions, 606 deletions
diff --git a/release/scripts/archimap.py b/release/scripts/archimap.py index 02444816634..a7a4a57ed58 100644 --- a/release/scripts/archimap.py +++ b/release/scripts/archimap.py @@ -1,27 +1,26 @@ #!BPY """ Registration info for Blender menus: <- these words are ignored -Name: 'ArchiMap UV Unwrapper' -Blender: 237 +Name: 'ArchiMap UV Projection Unwrapper' +Blender: 240 Group: 'UV' -Tooltip: 'ArchiMap UV Unwrap Mesh faces.' +Tooltip: 'ArchiMap UV Unwrap mesh faces for all select mesh objects' """ __author__ = "Campbell Barton" __url__ = ("blender", "elysiun") -__version__ = "1.0 6/13/05" +__version__ = "1.1 12/18/05" __bpydoc__ = """\ This script projection unwraps the selected faces of a mesh. -It operates on all selected mesh objects, and can be set to unwrap +it operates on all selected mesh objects, and can be set to unwrap selected faces, or all faces. - """ # -------------------------------------------------------------------------- -# Archimap UV Projection Unwrapper v1.0 by Campbell Barton (AKA Ideasman) +# Archimap UV Projection Unwrapper v1.1 by Campbell Barton (AKA Ideasman) # -------------------------------------------------------------------------- # ***** BEGIN GPL LICENSE BLOCK ***** # @@ -43,509 +42,23 @@ selected faces, or all faces. # -------------------------------------------------------------------------- - from Blender import * -from Blender import Mathutils -from Blender.Mathutils import * - -from math import cos, acos,pi,sqrt +from Blender.Mathutils import CrossVecs, Matrix, Vector, RotationMatrix, DotVecs, TriangleArea +from math import cos -try: - import sys as py_sys -except: - py_sys = None - - -DEG_TO_RAD = pi/180.0 +DEG_TO_RAD = 0.017453292519943295 # pi/180.0 SMALL_NUM = 0.000000001 BIG_NUM = 1e15 - - -try: - dummy = Mathutils.Matrix( Mathutils.Matrix() ) - del dummy - NEW_2_38_MATHUTILS = True -except TypeError: - NEW_2_38_MATHUTILS = False - - global USER_FILL_HOLES global USER_FILL_HOLES_QUALITY USER_FILL_HOLES = None USER_FILL_HOLES_QUALITY = None -# ================================================== USER_BOX_PACK_MOD.py -from Blender import NMesh, Window, sys - -# a box packing vert -class vt: - def __init__(self, x,y): - self.x, self.y = x, y - - self.free = 15 - - # Set flags so cant test bottom left of 0/0 - #~ BLF = 1; TRF = 2; TLF = 4; BRF = 8 - - #self.users = [] # A list of boxes. - # Rather then users, store Quadrents - self.blb = self.tlb = self.brb = self.trb = None - - - # A hack to remember the box() that last intersectec this vert - self.intersectCache = ([], [], [], []) - -class vertList: - def __init__(self, verts=[]): - self.verts = verts - - # Sorts closest first. - uses the box w/h as a bias, - # this makes it so its less likely to have lots of poking out bits - # that use too much - # Lambada based sort - def sortCorner(self,w,h): - self.verts.sort(lambda A, B: cmp(max(A.x+w, A.y+h) , max(B.x+w, B.y+h))) # Reverse area sort - - -class box: - global packedVerts - def __init__(self, width, height, id=None): - global packedVerts - - self.id= id - - self.area = width * height # real area - self.farea = width + height # fake area - #self.farea = float(min(width, height)) / float(max(width, height)) # fake area - - self.width = width - self.height = height - - # Append 4 new verts - # (BL,TR,TL,BR) / 0,1,2,3 - self.v = [vt(0,0), vt(width,height), vt(0,height), vt(width,0)] - - # Set the interior quadrents as used. - self.v[0].free &= ~TRF - self.v[1].free &= ~BLF - self.v[2].free &= ~BRF - self.v[3].free &= ~TLF - - #for v in self.v: - # v.users.append(self) - self.v[0].trb = self - self.v[1].blb = self - self.v[2].brb = self - self.v[3].tlb = self - - - - # Updates verts 3 & 4 from 1 and 2 - # since 3 and 4 are only there foill need is resizing/ rotating of patterns on the fly while I painr new box placement - # but may be merged later with other verts - def updateV34(self): - - self.v[TL].x = self.v[BL].x - self.v[TL].y = self.v[TR].y - - self.v[BR].x = self.v[TR].x - self.v[BR].y = self.v[BL].y - - - def setLeft(self, lft=None): - self.v[TR].x = lft + self.v[TR].x - self.v[BL].x - self.v[BL].x = lft - # update othere verts - self.updateV34() - - def setRight(self, rgt=None): - self.v[BL].x = rgt - (self.v[TR].x - self.v[BL].x) - self.v[TR].x = rgt - self.updateV34() - - def setBottom(self, btm=None): - self.v[TR].y = btm + self.v[TR].y - self.v[BL].y - self.v[BL].y = btm - self.updateV34() - - def setTop(self, tp=None): - self.v[BL].y = tp - (self.v[TR].y - self.v[BL].y) - self.v[TR].y = tp - self.updateV34() - - def getLeft(self): - return self.v[BL].x - - def getRight(self): - return self.v[TR].x - - def getBottom(self): - return self.v[BL].y - - def getTop(self): - return self.v[TR].y - - # Returns none, meaning it didnt overlap any new boxes - def overlapAll(self, boxLs, intersectCache): # Flag index lets us know which quadere - if self.v[BL].x < 0: - return None - elif self.v[BL].y < 0: - return None - else: - bIdx = len(intersectCache) - while bIdx: - bIdx-=1 - b = intersectCache[bIdx] - if not (self.v[TR].y <= b.v[BL].y or\ - self.v[BL].y >= b.v[TR].y or\ - self.v[BL].x >= b.v[TR].x or\ - self.v[TR].x <= b.v[BL].x ): - - return None # Intersection with existing box - #return 0 # Must keep looking - - - for b in boxLs.boxes: - if not (self.v[TR].y <= b.v[BL].y or\ - self.v[BL].y >= b.v[TR].y or\ - self.v[BL].x >= b.v[TR].x or\ - self.v[TR].x <= b.v[BL].x ): - - return b # Intersection with new box. - return 0 - - - - def place(self, vert, quad): - if quad == BLF: - self.setLeft(vert.x) - self.setBottom(vert.y) - - elif quad == TRF: - self.setRight(vert.x) - self.setBottom(vert.y) - - elif quad == TLF: - self.setLeft(vert.x) - self.setTop(vert.y) - - elif quad == BRF: - self.setRight(vert.x) - self.setTop(vert.y) - - # Trys to lock a box onto another box's verts - # cleans up double verts after - def tryVert(self, boxes, baseVert): - flagIndex = -1 - for freeQuad in quadFlagLs: - flagIndex +=1 - #print 'Testing ', self.width - if not baseVert.free & freeQuad: - continue - - self.place(baseVert, freeQuad) - overlapBox = self.overlapAll(boxes, baseVert.intersectCache[flagIndex]) - if overlapBox == 0: # There is no overlap - baseVert.free &= ~freeQuad # Removes quad - # Appends all verts but the one that matches. this removes the need for remove doubles - for vIdx in range(4): # (BL,TR,TL,BR): # (BL,TR,TL,BR) / 0,1,2,3 - self_v = self.v[vIdx] # shortcut - if not (self_v.x == baseVert.x and self_v.y == baseVert.y): - packedVerts.verts.append(self_v) - else: - baseVert.free &= self.v[vIdx].free # make sure the - - # Inherit used boxes from old verts - if self_v.blb: baseVert.blb = self_v.blb - if self_v.brb: baseVert.brb = self_v.brb #print 'inherit2' - if self_v.tlb: baseVert.tlb = self_v.tlb #print 'inherit3' - if self_v.trb: baseVert.trb = self_v.trb #print 'inherit4' - self.v[vIdx] = baseVert - - - # ========================== WHY DOSENT THIS WORK??? - #~ if baseVert.tlb and baseVert.trb: - #~ if self == baseVert.tlb or self == baseVert.trb: - - #~ if baseVert.tlb.height > baseVert.trb.height: - #~ #baseVert.trb.v[TL].free &= ~TLF & ~BLF - #~ baseVert.trb.v[TL].free &= ~TLF - #~ baseVert.trb.v[TL].free &= ~BLF - - #~ elif baseVert.tlb.height < baseVert.trb.height: - #~ #baseVert.trb.v[TL].free &= ~TLF & ~BLF - #~ baseVert.tlb.v[TR].free &= ~TRF - #~ baseVert.tlb.v[TR].free &= ~BRF - #~ else: # same - #~ baseVert.tlb.v[TR].free &= ~BLF - #~ baseVert.trb.v[TL].free &= ~BRF - - - #~ if baseVert.blb and baseVert.brb: - #~ if self == baseVert.blb or self == baseVert.brb: - - #~ if baseVert.blb.height > baseVert.brb.height: - #~ #baseVert.trb.v[TL].free &= ~TLF & ~BLF - #~ baseVert.brb.v[BL].free &= ~TLF - #~ baseVert.brb.v[BL].free &= ~BLF - - #~ elif baseVert.blb.height < baseVert.brb.height: - #~ #baseVert.trb.v[TL].free &= ~TLF & ~BLF - #~ baseVert.blb.v[BR].free &= ~TRF - #~ baseVert.blb.v[BR].free &= ~BRF - #~ else: # same - #~ baseVert.blb.v[BR].free &= ~TLF - #~ baseVert.brb.v[BL].free &= ~TRF - - #~ # print 'Hay', baseVert.tlb.height, baseVert.trb.height - - - - return 1 # Working - - # We have a box that intersects that quadrent. - elif overlapBox != None: # None is used for a box thats alredt in the freq list. - - # There was an overlap, add this box to the verts list - #quadFlagLs = (BLF,BRF,TLF,TRF) - baseVert.intersectCache[flagIndex].append(overlapBox) - - - - return 0 - - -class boxList: - global packedVerts - def __init__(self, boxes): - self.boxes = boxes - - # keep a running update of the width and height so we know the area - # initialize with first box, fixes but where we whwere only packing 1 box - self.width = 0 - self.height = 0 - if len(boxes) > 0: - for b in boxes: - self.width = max(self.width, b.width) - self.height = max(self.height, b.height) - - - - - # boxArea is the total area of all boxes in the list, - # can be used with packArea() to determine waistage. - self.boxArea = 0 # incremented with addBox() - - - # Just like MyBoxLs.boxes.append(), but sets bounds - def addBoxPack(self, box): - - - # Resize this boxlist bounds for the current box. - self.width = max(self.width, box.getRight()) - self.height = max(self.height, box.getTop()) - - self.boxArea += box.area - - - - # iterate through these - #~ quadFlagLs = (1,8,4,2) - #~ # Flags for vert idx used quads - #~ BLF = 1; TRF = 2; TLF = 4; BRF = 8 - #~ quadFlagLs = (BLF,BRF,TLF,TRF) - - # Look through all the free vert quads and see if there are some we can remove - ''' - for v in box.v: - - # Is my bottom being used. - - if v.free & BLF and v.free & BRF: # BLF and BRF - for b in self.boxes: - if b.v[TR].y == v.y: - if b.v[TR].x > v.x: - if b.v[BL].x < v.x: - v.free &= ~BLF # Removes quad - v.free &= ~BRF # Removes quad - - # Is my left being used. - if v.free & BLF and v.free & TLF: - for b in self.boxes: - if b.v[TR].x == v.x: - if b.v[TR].y > v.y: - if b.v[BL].y < v.y: - v.free &= ~BLF # Removes quad - v.free &= ~TLF # Removes quad - - if v.free & TRF and v.free & TLF: - # Is my top being used. - for b in self.boxes: - if b.v[BL].y == v.y: - if b.v[TR].x > v.x: - if b.v[BL].x < v.x: - v.free &= ~TLF # Removes quad - v.free &= ~TRF # Removes quad - - - # Is my right being used. - if v.free & TRF and v.free & BRF: - for b in self.boxes: - if b.v[BL].x == v.x: - if b.v[TR].y > v.y: - if b.v[BL].y < v.y: - v.free &= ~BRF # Removes quad - v.free &= ~TRF # Removes quad - - ''' - self.boxes.append(box) - - - - # Just like MyBoxLs.boxes.append(), but sets bounds - def addBox(self, box): - self.boxes.append(box) - self.boxArea += box.area - - # The area of the backing bounds. - def packedArea(self): - return self.width * self.height - - # Sort boxes by area - # TODO REPLACE WITH SORT(LAMBDA(CMP...)) - def sortArea(self): - self.boxes.sort(lambda A, B: cmp(B.area, A.area) ) # Reverse area sort - - # BLENDER only - def draw(self): - m = NMesh.GetRaw() - - - for b in self.boxes: - z = min(b.width, b.height ) / max(b.width, b.height ) - #z = b.farea - #z=0 - f = NMesh.Face() - m.verts.append(NMesh.Vert(b.getLeft(), b.getBottom(), z)) - f.v.append(m.verts[-1]) - m.verts.append(NMesh.Vert(b.getRight(), b.getBottom(), z)) - f.v.append(m.verts[-1]) - m.verts.append(NMesh.Vert(b.getRight(), b.getTop(), z)) - f.v.append(m.verts[-1]) - m.verts.append(NMesh.Vert(b.getLeft(), b.getTop(), z)) - f.v.append(m.verts[-1]) - m.faces.append(f) - NMesh.PutRaw(m, 's') - Window.Redraw(1) - - def pack(self): - global packedVerts - packedVerts = vertList() - - self.sortArea() - - if len(self.boxes) == 0: - return - - packedboxes = boxList([self.boxes[0]]) - - # Remove verts we KNOW cant be added to - - unpackedboxes = boxList(self.boxes[1:]) - - # STart with this box - packedVerts.verts.extend(packedboxes.boxes[0].v) - - while unpackedboxes.boxes != []: - - freeBoxIdx = 0 - while freeBoxIdx < len(unpackedboxes.boxes): - - # Sort the verts with this boxes dimensions as a bias, so less poky out bits are made. - packedVerts.sortCorner(unpackedboxes.boxes[freeBoxIdx].width, unpackedboxes.boxes[freeBoxIdx].height) - - vertIdx = 0 - - while vertIdx < len(packedVerts.verts): - baseVert = packedVerts.verts[vertIdx] - - if baseVert.free != 0: - # This will lock the box if its possibel - if unpackedboxes.boxes[freeBoxIdx].tryVert(packedboxes, baseVert): - packedboxes.addBoxPack(unpackedboxes.boxes[freeBoxIdx]) - unpackedboxes.boxes.pop(freeBoxIdx) - freeBoxIdx = -1 - break - - vertIdx +=1 - freeBoxIdx +=1 - self.width = packedboxes.width - self.height = packedboxes.height - # All boxes as a list - X/Y/WIDTH/HEIGHT - def list(self): - ls = [] - for b in self.boxes: - ls.append( (b.id, b.getLeft(), b.getBottom(), b.width, b.height ) ) - return ls - - -''' Define all globals here ''' -# vert IDX's, make references easier to understand. -BL = 0; TR = 1; TL = 2; BR = 3 - -# iterate through these -quadFlagLs = (1,8,4,2) -# Flags for vert idx used quads -BLF = 1; TRF = 2; TLF = 4; BRF = 8 -quadFlagLs = (BLF,BRF,TLF,TRF) - - -# Global vert pool, stores used lists -packedVerts = vertList() - - -# Packs a list w/h's into box types and places then #Iter times -def boxPackIter(boxLs, iter=1, draw=0): - iterIdx = 0 - bestArea = None - # Iterate over packing the boxes to get the best FIT! - while iterIdx < iter: - myBoxLs = boxList([]) - for b in boxLs: - myBoxLs.addBox( box(b[1], b[2], b[0]) ) # w/h/id - - myBoxLs.pack() - # myBoxLs.draw() # Draw as we go? - - newArea = myBoxLs.packedArea() - - #print 'pack test %s of %s, area:%.2f' % (iterIdx, iter, newArea) - - # First time? - if bestArea == None: - bestArea = newArea - bestBoxLs = myBoxLs - elif newArea < bestArea: - bestArea = newArea - bestBoxLs = myBoxLs - iterIdx+=1 - - - if draw: - bestBoxLs.draw() - - #print 'best area: %.4f, %.2f%% efficient' % (bestArea, (float(bestBoxLs.boxArea) / (bestArea+0.000001))*100) - return bestBoxLs.width, bestBoxLs.height, bestBoxLs.list() -# END USER_BOX_PACK_MOD.py - -# ============================================================== - - # Box Packer is included for distrobution. -#import box_pack_mod -#reload(box_pack_mod) +import boxpack2d +# reload(boxpack2d) @@ -622,24 +135,6 @@ def lineIntersection2D(x1,y1, x2,y2, _x1,_y1, _x2,_y2): else: return None, None -def triArea(p1, p2, p3): - return CrossVecs(p1-p2, p3-p2).length/2 - -# IS a point inside our triangle? -''' -def pointInTri2D(PT, triP1, triP2, triP3): - def triArea(p1, p2, p3): - return CrossVecs(p1-p2, p3-p2).length /2 - area1 = triArea(PT, triP2, triP3) - area2 = triArea(PT, triP1, triP3) - area3 = triArea(PT, triP1, triP2) - triArea = triArea(triP1, triP2, triP3) - if area1 + area2 + area3 > triArea+0.01: - return False - else: - return True -''' - dict_matrix = {} def pointInTri2D(v, v1, v2, v3): @@ -655,13 +150,13 @@ def pointInTri2D(v, v1, v2, v3): side1 = v2 - v1 side2 = v3 - v1 - nor = Mathutils.CrossVecs(side1, side2) + nor = CrossVecs(side1, side2) l1 = [side1[0], side1[1], side1[2]] l2 = [side2[0], side2[1], side2[2]] l3 = [nor[0], nor[1], nor[2]] - mtx = Mathutils.Matrix(l1, l2, l3) + mtx = Matrix(l1, l2, l3) # Zero area 2d tri, even tho we throw away zerop area faces # the projection UV can result in a zero area UV. @@ -673,24 +168,17 @@ def pointInTri2D(v, v1, v2, v3): dict_matrix[key] = mtx - if NEW_2_38_MATHUTILS: - uvw = (v - v1) * mtx - else: - uvw = Mathutils.VecMultMat(v - v1, mtx) - + uvw = (v - v1) * mtx return 0 <= uvw[0] and 0 <= uvw[1] and uvw[0] + uvw[1] <= 1 - def faceArea(f): - if len(f) == 3: - return triArea(f.v[0].co, f.v[1].co, f.v[2].co) - elif len(f) == 4: + if len(f.v) == 3: + return TriangleArea(f.v[0].co, f.v[1].co, f.v[2].co) + elif len(f.v) == 4: return\ - triArea(f.v[0].co, f.v[1].co, f.v[2].co) +\ - triArea(f.v[0].co, f.v[2].co, f.v[3].co) - - + TriangleArea(f.v[0].co, f.v[1].co, f.v[2].co) +\ + TriangleArea(f.v[0].co, f.v[2].co, f.v[3].co) def boundsIsland(faces): @@ -730,7 +218,7 @@ def island2Edge(island): edges = {} for f in island: - for vIdx in range(len(f)): + for vIdx in range(len(f.v)): if f.v[vIdx].index > f.v[vIdx-1].index: edges[((f.uv[vIdx-1][0], f.uv[vIdx-1][1]), (f.uv[vIdx][0], f.uv[vIdx][1]))] =\ (Vector([f.uv[vIdx-1][0], f.uv[vIdx-1][1]]) - Vector([f.uv[vIdx][0], f.uv[vIdx][1]])).length @@ -794,7 +282,7 @@ def pointInIsland(pt, island): if pointInTri2D(pt, vec1, vec2, vec3): return True - if len(f) == 4: + if len(f.v) == 4: vec1.x, vec1.y = f.uv[0] vec2.x, vec2.y = f.uv[2] vec3.x, vec3.y = f.uv[3] @@ -822,10 +310,7 @@ def islandIntersectUvIsland(source, target, xSourceOffset, ySourceOffset): # 1 test for source being totally inside target for pv in source[7]: - if NEW_2_38_MATHUTILS: - p = Vector(pv) - else: - p = CopyVec(pv) + p = Vector(pv) p.x += xSourceOffset p.y += ySourceOffset @@ -834,11 +319,7 @@ def islandIntersectUvIsland(source, target, xSourceOffset, ySourceOffset): # 2 test for a part of the target being totaly inside the source. for pv in target[7]: - - if NEW_2_38_MATHUTILS: - p = Vector(pv) - else: - p = CopyVec(pv) + p = Vector(pv) p.x -= xSourceOffset p.y -= ySourceOffset @@ -861,11 +342,7 @@ def testNewVecLs2DRotIsBetter(vecs, mat=-1, bestAreaSoFar = -1): # Do this allong the way if mat != -1: - # 2.37 depricated - if NEW_2_38_MATHUTILS: - v = vecs[i] = v*mat - else: - v = vecs[i] = VecMultMat(v, mat) + v = vecs[i] = v*mat minx = min(minx, v.x) maxx = max(maxx, v.x) @@ -971,8 +448,8 @@ def optiRotateUvIsland(faces): # Now write the vectors back to the face UV's i = 0 # count the serialized uv/vectors for f in faces: - f.uv = [uv for uv in uvVecs[i:len(f)+i] ] - i += len(f) + f.uv = tuple([uv for uv in uvVecs[i:len(f.v)+i] ]) + i += len(f.v) # Takes an island list and tries to find concave, hollow areas to pack smaller islands into. @@ -1000,7 +477,7 @@ def mergeUvIslands(islandList, islandListArea): while fIdx: fIdx-=1 f = islandList[islandIdx][fIdx] - f.uv = [(uv[0]-minx, uv[1]-miny) for uv in f.uv] + f.uv = tuple([Vector(uv[0]-minx, uv[1]-miny) for uv in f.uv]) totFaceArea += islandListArea[islandIdx][fIdx] # Use Cached area. dont recalculate. islandBoundsArea = w*h efficiency = abs(islandBoundsArea - totFaceArea) @@ -1119,26 +596,16 @@ def mergeUvIslands(islandList, islandListArea): ''' # Move the test allong its width + SMALL_NUM boxLeft += sourceIsland[4] + SMALL_NUM - #py_sys.stdout.write('>') - #pass elif Intersect == 0: # No intersection?? Place it. # Progress removedCount +=1 Window.DrawProgressBar(0.0, 'Merged: %i islands, Ctrl to finish early.' % removedCount) - ''' - if py_sys: - py_sys.stdout.write('#') - py_sys.stdout.flush() - else: - print '#' - ''' - # Move faces into new island and offset targetIsland[0].extend(sourceIsland[0]) while sourceIsland[0]: f = sourceIsland[0].pop() - f.uv = [(uv[0]+boxLeft, uv[1]+boxBottom) for uv in f.uv] + f.uv = tuple([Vector(uv[0]+boxLeft, uv[1]+boxBottom) for uv in f.uv]) # Move edge loop into new and offset. # targetIsland[6].extend(sourceIsland[6]) @@ -1179,19 +646,12 @@ def mergeUvIslands(islandList, islandListArea): areaIslandIdx+=1 # Remove empty islands - # removedCount = 0 i = len(islandList) while i: i-=1 if not islandList[i]: - islandList.pop(i) - # removedCount+=1 - - # Dont need to return anything - # if py_sys: py_sys.stdout.flush() + islandList.pop(i) # Can increment islands removed here. - # print '' - # print removedCount, 'merged' # Takes groups of faces. assumes face groups are UV groups. def packLinkedUvs(faceGroups, faceGroupsArea, me): @@ -1254,7 +714,7 @@ def packLinkedUvs(faceGroups, faceGroupsArea, me): for v in newIsland[0].v: popoffset = 0 for fIdx in xrange(len(faceUsers[v.index])): - if faceUsers[v.index][fIdx - popoffset] == newIsland[0]: + if faceUsers[v.index][fIdx - popoffset] is newIsland[0]: faceUsers[v.index].pop(fIdx - popoffset) faceUsersArea[v.index].pop(fIdx - popoffset) @@ -1276,7 +736,7 @@ def packLinkedUvs(faceGroups, faceGroupsArea, me): #faceUsers = [f for f in faceUsers[vv.index] if f != sharedFace] fIdx = 0 for fIdx in xrange(len(faceUsers[vv.index])): - if faceUsers[vv.index][fIdx] == sharedFace: + if faceUsers[vv.index][fIdx] is sharedFace: faceUsers[vv.index].pop(fIdx) faceUsersArea[vv.index].pop(fIdx) break # Can only be used once. @@ -1291,15 +751,7 @@ def packLinkedUvs(faceGroups, faceGroupsArea, me): else: print '\t(empty island found, ignoring)' - - - - - #Window.DrawProgressBar(0.1, 'Found %i UV Islands' % len(islandList)) - #print '\n\tFound %i UV Islands' % len(islandList) - - #print '\tOptimizing Island Rotation...' Window.DrawProgressBar(0.1, 'Optimizing Rotation for %i UV Islands' % len(islandList)) @@ -1309,9 +761,7 @@ def packLinkedUvs(faceGroups, faceGroupsArea, me): if USER_FILL_HOLES: - Window.DrawProgressBar(0.1, 'Merging Islands...') - #print '\tMerging islands to save space ("#" == one merge):\n', - if py_sys: py_sys.stdout.flush() + Window.DrawProgressBar(0.1, 'Merging Islands (Ctrl: skip merge)...') mergeUvIslands(islandList, islandListArea) # Modify in place @@ -1354,7 +804,7 @@ def packLinkedUvs(faceGroups, faceGroupsArea, me): Window.DrawProgressBar(0.7, 'Packing %i UV Islands...' % len(boxes2Pack) ) time1 = sys.time() - packWidth, packHeight, packedLs = boxPackIter(boxes2Pack) + packWidth, packHeight, packedLs = boxpack2d.boxPackIter(boxes2Pack) # print 'Box Packing Time:', sys.time() - time1 #if len(pa ckedLs) != len(islandList): @@ -1367,8 +817,12 @@ def packLinkedUvs(faceGroups, faceGroupsArea, me): islandIdx = len(islandList) # Having these here avoids devide by 0 if islandIdx: - xfactor = 1.0 / packWidth - yfactor = 1.0 / packHeight + # Maximize to uv area?? Will write a normalize function. + #xfactor = 1.0 / packWidth + #yfactor = 1.0 / packHeight + + # Keep proportions. + xfactor = yfactor = 1.0 / max(packWidth, packHeight) while islandIdx: islandIdx -=1 @@ -1378,14 +832,11 @@ def packLinkedUvs(faceGroups, faceGroupsArea, me): xoffset = packedLs[islandIdx][1] - islandOffsetList[islandIdx][0] yoffset = packedLs[islandIdx][2] - islandOffsetList[islandIdx][1] for f in islandList[islandIdx]: # Offsetting the UV's so they fit in there packed box - f.uv = [(((uv[0]+xoffset)*xfactor), ((uv[1]+yoffset)*yfactor)) for uv in f.uv] + f.uv = tuple([Vector(((uv[0]+xoffset)*xfactor), ((uv[1]+yoffset)*yfactor)) for uv in f.uv]) def VectoMat(vec): - if NEW_2_38_MATHUTILS: - a3 = Vector(vec) - else: - a3 = CopyVec(vec) + a3 = Vector(vec) a3.normalize() @@ -1442,11 +893,11 @@ def main(): if ob.getType() != 'Mesh': continue - me = ob.getData() + me = ob.getData(mesh=1) if USER_ONLY_SELECTED_FACES: - meshFaces = [f for f in me.getSelectedFaces() if len(f) > 2] + meshFaces = [f for f in me.faces if f.sel if len(f.v) > 2] else: - meshFaces = [f for f in me.faces if len(f) > 2] + meshFaces = [f for f in me.faces if len(f.v) > 2] if not meshFaces: continue @@ -1467,7 +918,7 @@ def main(): for f in meshFaces: area = faceArea(f) if area <= SMALL_NUM: - f.uv = [(0.0, 0.0)] * len(f) + f.uv = [(0.0, 0.0)] * len(f.v) print 'found zero area face, removing.' else: @@ -1573,9 +1024,7 @@ def main(): i = len(projectVecs) # Initialize first - bestAng = DotVecs(fvec, projectVecs[0]) - # print bestAng bestAngIdx = 0 # Cycle through the remaining, first alredy done @@ -1609,26 +1058,25 @@ def main(): # Get the faces UV's from the projected vertex. for f in faceProjectionGroupList[i]: - - if NEW_2_38_MATHUTILS: - f.uv = [MatProj * v.co for v in f.v] - else: - f.uv = [MatMultVec(MatProj, v.co) for v in f.v] + f.uv = tuple([MatProj * v.co for v in f.v]) packLinkedUvs(faceProjectionGroupList, faceProjectionGroupListArea, me) - #print "ArchiMap time: %.2f" % (sys.time() - time1) + print "ArchiMap time: %.2f" % (sys.time() - time1) Window.DrawProgressBar(0.9, "ArchiMap Done, time: %.2f sec." % (sys.time() - time1)) # Update and dont mess with edge data. - me.update(0, (me.edges != []), 0) + # OLD NMESH # me.update(0, (me.edges != []), 0) + + Window.DrawProgressBar(1.0, "") + Window.WaitCursor(0) Window.RedrawAll() - try: main() + except KeyboardInterrupt: print '\nUser Canceled.' Draw.PupMenu('user canceled execution, unwrap aborted.') - -Window.WaitCursor(0) + Window.DrawProgressBar(1.0, "") + Window.WaitCursor(0)
\ No newline at end of file |