forked from bartvdbraak/blender
10-20% speedup with better logic and limit the cache size for box intersections.
This commit is contained in:
parent
0740e4ab1c
commit
6a087fcb8b
@ -26,7 +26,13 @@ boxes2Pack.append([anyUniqueID, w,h])
|
||||
packWidth, packHeight, packedLs = boxpack2d.boxPackIter(boxes2Pack)
|
||||
'''
|
||||
|
||||
from Blender import NMesh, Window
|
||||
from Blender import NMesh, Window, Object, Scene
|
||||
|
||||
def debug_(x,y,z):
|
||||
ob = Object.New("Empty")
|
||||
ob.loc= x,y,z
|
||||
Scene.GetCurrent().link(ob)
|
||||
|
||||
|
||||
# a box packing vert
|
||||
class vt:
|
||||
@ -140,23 +146,22 @@ class box:
|
||||
''' Returns none, meaning it didnt overlap any new boxes '''
|
||||
v= self.v
|
||||
if v[BL].x < 0:
|
||||
return None
|
||||
return True
|
||||
elif v[BL].y < 0:
|
||||
return None
|
||||
return True
|
||||
else:
|
||||
bIdx = len(intersectCache)
|
||||
while bIdx:
|
||||
bIdx-=1
|
||||
b = intersectCache[bIdx]
|
||||
if not (self.v[TR].y <= b.v[BL].y or\
|
||||
if not ( v[TR].y <= b.v[BL].y or\
|
||||
v[BL].y >= b.v[TR].y or\
|
||||
v[BL].x >= b.v[TR].x or\
|
||||
v[TR].x <= b.v[BL].x ):
|
||||
|
||||
return None # Intersection with existing box
|
||||
return True # Intersection with existing box
|
||||
#return 0 # Must keep looking
|
||||
|
||||
|
||||
for b in boxLs.boxes:
|
||||
if not (v[TR].y <= b.v[BL].y or\
|
||||
v[BL].y >= b.v[TR].y or\
|
||||
@ -164,47 +169,48 @@ class box:
|
||||
v[TR].x <= b.v[BL].x ):
|
||||
|
||||
return b # Intersection with new box.
|
||||
return 0
|
||||
return False
|
||||
|
||||
|
||||
|
||||
def place(self, vert, quad):
|
||||
'''
|
||||
Place the box on the free quadrent of the vert
|
||||
'''
|
||||
if quad == BLF:
|
||||
self.setLeft(vert.x)
|
||||
self.setBottom(vert.y)
|
||||
self.setRight(vert.x)
|
||||
self.setTop(vert.y)
|
||||
|
||||
elif quad == TRF:
|
||||
self.setRight(vert.x)
|
||||
self.setLeft(vert.x)
|
||||
self.setBottom(vert.y)
|
||||
|
||||
elif quad == TLF:
|
||||
self.setLeft(vert.x)
|
||||
self.setTop(vert.y)
|
||||
self.setRight(vert.x)
|
||||
self.setBottom(vert.y)
|
||||
|
||||
elif quad == BRF:
|
||||
self.setRight(vert.x)
|
||||
self.setLeft(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
|
||||
for flagIndex, freeQuad in enumerate(quadFlagLs):
|
||||
#print 'Testing ', self.width
|
||||
if baseVert.free & freeQuad:
|
||||
|
||||
self.place(baseVert, freeQuad)
|
||||
overlapBox = self.overlapAll(boxes, baseVert.intersectCache[flagIndex])
|
||||
if overlapBox is 0: # There is no overlap
|
||||
if overlapBox is False: # 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 (0,1,2,3): # (BL,TR,TL,BR): # (BL,TR,TL,BR) / 0,1,2,3
|
||||
for vIdx in (0,1,2,3): # (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):
|
||||
boxList.packedVerts.verts.append(self_v)
|
||||
else:
|
||||
baseVert.free &= self_v.free # make sure the
|
||||
baseVert.free &= self_v.free # make sure the that any unfree areas are wiped.
|
||||
|
||||
# Inherit used boxes from old verts
|
||||
if self_v.blb: baseVert.blb = self_v.blb
|
||||
@ -214,52 +220,69 @@ class box:
|
||||
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
|
||||
# Logical checking for used verts by compares box sized and works out verts that may be free.
|
||||
# Verticle
|
||||
|
||||
#~ 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.tlb and baseVert.trb and\
|
||||
(self == baseVert.tlb or self == baseVert.trb):
|
||||
if baseVert.tlb.height > baseVert.trb.height:
|
||||
baseVert.trb.v[TL].free &= ~(TLF|BLF)
|
||||
elif baseVert.tlb.height < baseVert.trb.height:
|
||||
baseVert.tlb.v[TR].free &= ~(TRF|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:
|
||||
elif baseVert.blb and baseVert.brb and\
|
||||
(self == baseVert.blb or self == baseVert.brb):
|
||||
if baseVert.blb.height > baseVert.brb.height:
|
||||
baseVert.brb.v[BL].free &= ~(TLF|BLF)
|
||||
elif baseVert.blb.height < baseVert.brb.height:
|
||||
baseVert.blb.v[BR].free &= ~(TRF|BRF)
|
||||
else: # same
|
||||
baseVert.blb.v[BR].free &= ~TRF
|
||||
baseVert.brb.v[BL].free &= ~TLF
|
||||
|
||||
#~ 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
|
||||
# Horizontal
|
||||
if baseVert.tlb and baseVert.blb and\
|
||||
(self == baseVert.tlb or self == baseVert.blb):
|
||||
if baseVert.tlb.width > baseVert.blb.width:
|
||||
baseVert.blb.v[TL].free &= ~(TLF|TRF)
|
||||
elif baseVert.tlb.width < baseVert.blb.width:
|
||||
baseVert.tlb.v[BL].free &= ~(BLF|BRF)
|
||||
else: # same
|
||||
baseVert.blb.v[TL].free &= ~TRF
|
||||
baseVert.tlb.v[BL].free &= ~BRF
|
||||
|
||||
#~ 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
|
||||
elif baseVert.trb and baseVert.brb and\
|
||||
(self == baseVert.trb or self == baseVert.brb):
|
||||
if baseVert.trb.width > baseVert.brb.width:
|
||||
baseVert.brb.v[TR].free &= ~(TRF|TRF)
|
||||
elif baseVert.trb.width < baseVert.brb.width:
|
||||
baseVert.trb.v[BR].free &= ~(BLF|BRF)
|
||||
else: # same
|
||||
baseVert.brb.v[TR].free &= ~TLF
|
||||
baseVert.trb.v[BR].free &= ~BLF
|
||||
# END LOGICAL VREE SIZE REMOVAL
|
||||
|
||||
|
||||
|
||||
|
||||
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.
|
||||
|
||||
elif overlapBox is not False and overlapBox is not True: # True is used for a box thats alredt in the freq list or out of bounds error.
|
||||
# There was an overlap, add this box to the verts list
|
||||
#quadFlagLs = (BLF,BRF,TLF,TRF)
|
||||
baseVert.intersectCache[flagIndex].append(overlapBox)
|
||||
|
||||
# Limit the cache size
|
||||
if len(baseVert.intersectCache[flagIndex]) > 8:
|
||||
del baseVert.intersectCache[flagIndex][0]
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
@ -302,8 +325,7 @@ class boxList:
|
||||
#~ quadFlagLs = (BLF,BRF,TLF,TRF)
|
||||
|
||||
# Look through all the free vert quads and see if there are some we can remove
|
||||
# buggy but dont know why???, dont use it unless you want to debug it..
|
||||
'''
|
||||
#
|
||||
for v in box.v:
|
||||
|
||||
# Is my bottom being used.
|
||||
@ -313,8 +335,7 @@ class boxList:
|
||||
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
|
||||
v.free &= ~(BLF|BRF) # Removes quad
|
||||
|
||||
# Is my left being used.
|
||||
if v.free & BLF and v.free & TLF:
|
||||
@ -322,8 +343,7 @@ class boxList:
|
||||
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
|
||||
v.free &= ~(BLF|TLF) # Removes quad
|
||||
|
||||
if v.free & TRF and v.free & TLF:
|
||||
# Is my top being used.
|
||||
@ -331,8 +351,7 @@ class boxList:
|
||||
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
|
||||
v.free &= ~(TLF|TRF) # Removes quad
|
||||
|
||||
|
||||
# Is my right being used.
|
||||
@ -341,10 +360,9 @@ class boxList:
|
||||
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
|
||||
v.free &= ~(BRF|TRF) # Removes quad
|
||||
|
||||
|
||||
'''
|
||||
self.boxes.append(box)
|
||||
|
||||
|
||||
@ -359,7 +377,6 @@ class boxList:
|
||||
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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user