4 class _objectOrder(object):
5 def __init__(self, order, todo):
9 class _objectOrderFinder(object):
10 def __init__(self, scene, offset, leftToRight, frontToBack, gantryHeight):
12 self._offset = offset - numpy.array([0.1,0.1])
13 self._objs = scene.objects()
14 self._leftToRight = leftToRight
15 self._frontToBack = frontToBack
17 for n in xrange(0, len(self._objs)):
18 if scene.checkPlatform(self._objs[n]):
21 if self._objs[n].getSize()[2] > gantryHeight and len(initialList) > 1:
24 if len(initialList) == 0:
29 self._hitMap = [None] * (max(initialList)+1)
31 self._hitMap[a] = [False] * (max(initialList)+1)
33 self._hitMap[a][b] = self._checkHit(a, b)
35 initialList.sort(self._objIdxCmp)
38 self._todo = [_objectOrder([], initialList)]
39 while len(self._todo) > 0:
41 current = self._todo.pop()
42 #print len(self._todo), len(current.order), len(initialList), current.order
43 for addIdx in current.todo:
44 if not self._checkHitFor(addIdx, current.order) and not self._checkBlocks(addIdx, current.todo):
45 todoList = current.todo[:]
46 todoList.remove(addIdx)
47 order = current.order[:] + [addIdx]
48 if len(todoList) == 0:
52 self._todo.append(_objectOrder(order, todoList))
55 def _objIdxCmp(self, a, b):
56 scoreA = sum(self._hitMap[a])
57 scoreB = sum(self._hitMap[b])
58 return scoreA - scoreB
60 def _checkHitFor(self, addIdx, others):
62 if self._hitMap[addIdx][idx]:
66 def _checkBlocks(self, addIdx, others):
68 if addIdx != idx and self._hitMap[idx][addIdx]:
72 def _checkHit(self, addIdx, idx):
73 addPos = self._scene._objectList[addIdx].getPosition()
74 addSize = self._scene._objectList[addIdx].getSize()
75 pos = self._scene._objectList[idx].getPosition()
76 size = self._scene._objectList[idx].getSize()
79 if addPos[0] - addSize[0] / 2 - self._offset[0] <= pos[0] + size[0] / 2:
82 if addPos[0] + addSize[0] / 2 + self._offset[0] <= pos[0] - size[0] / 2:
86 if addPos[1] - addSize[1] / 2 - self._offset[1] >= pos[1] + size[1] / 2:
89 if addPos[1] + addSize[1] / 2 + self._offset[1] >= pos[1] - size[1] / 2:
97 self._sizeOffsets = numpy.array([0.0,0.0], numpy.float32)
98 self._machineSize = numpy.array([100,100,100], numpy.float32)
99 self._headOffsets = numpy.array([18.0,18.0], numpy.float32)
100 self._leftToRight = False
101 self._frontToBack = True
102 self._gantryHeight = 60
104 def setMachineSize(self, machineSize):
105 self._machineSize = machineSize
107 def setSizeOffsets(self, sizeOffsets):
108 self._sizeOffsets = sizeOffsets
110 def setHeadSize(self, xMin, xMax, yMin, yMax, gantryHeight):
111 self._leftToRight = xMin < xMax
112 self._frontToBack = yMin < yMax
113 self._headOffsets[0] = min(xMin, xMax)
114 self._headOffsets[1] = min(yMin, yMax)
115 self._gantryHeight = gantryHeight
117 def getObjectExtend(self):
118 return self._sizeOffsets + self._headOffsets
121 return self._objectList
124 self._findFreePositionFor(obj)
125 self._objectList.append(obj)
128 def remove(self, obj):
129 self._objectList.remove(obj)
131 def merge(self, obj1, obj2):
133 obj1._meshList += obj2._meshList
135 obj1.setPosition((obj1.getPosition() + obj2.getPosition()) / 2)
140 while self._pushFree():
145 def arrangeAll(self):
146 oldList = self._objectList
147 self._objectList = []
149 obj.setPosition(numpy.array([0,0], numpy.float32))
153 minPos = numpy.array([9999999,9999999], numpy.float32)
154 maxPos = numpy.array([-9999999,-9999999], numpy.float32)
155 for obj in self._objectList:
156 pos = obj.getPosition()
158 minPos[0] = min(minPos[0], pos[0] - size[0] / 2)
159 minPos[1] = min(minPos[1], pos[1] - size[1] / 2)
160 maxPos[0] = max(maxPos[0], pos[0] + size[0] / 2)
161 maxPos[1] = max(maxPos[1], pos[1] + size[1] / 2)
162 offset = -(maxPos + minPos) / 2
163 for obj in self._objectList:
164 obj.setPosition(obj.getPosition() + offset)
166 def printOrder(self):
167 order = _objectOrderFinder(self, self._headOffsets + self._sizeOffsets, self._leftToRight, self._frontToBack, self._gantryHeight).order
169 print "ODD! Cannot find out proper printing order!!!"
170 for obj in self._objectList:
171 print obj.getPosition(), obj.getSize()
175 for a in self._objectList:
176 for b in self._objectList:
177 if not self._checkHit(a, b):
179 posDiff = a.getPosition() - b.getPosition()
180 if posDiff[0] == 0.0 and posDiff[1] == 0.0:
182 if abs(posDiff[0]) > abs(posDiff[1]):
186 aPos = a.getPosition()
187 bPos = b.getPosition()
188 center = (aPos[axis] + bPos[axis]) / 2
189 distance = (a.getSize()[axis] + b.getSize()[axis]) / 2 + 0.1 + self._sizeOffsets[axis] + self._headOffsets[axis]
190 if posDiff[axis] < 0:
192 aPos[axis] = center + distance / 2
193 bPos[axis] = center - distance / 2
199 def _checkHit(self, a, b):
202 posDiff = a.getPosition() - b.getPosition()
203 if abs(posDiff[0]) < (a.getSize()[0] + b.getSize()[0]) / 2 + self._sizeOffsets[0] + self._headOffsets[0]:
204 if abs(posDiff[1]) < (a.getSize()[1] + b.getSize()[1]) / 2 + self._sizeOffsets[1] + self._headOffsets[1]:
208 def checkPlatform(self, obj):
209 p = obj.getPosition()
210 s = obj.getSize()[0:2] / 2 + self._sizeOffsets
211 if p[0] - s[0] < -self._machineSize[0] / 2:
213 if p[0] + s[0] > self._machineSize[0] / 2:
215 if p[1] - s[1] < -self._machineSize[1] / 2:
217 if p[1] + s[1] > self._machineSize[1] / 2:
221 def _findFreePositionFor(self, obj):
223 for a in self._objectList:
225 s = (a.getSize()[0:2] + obj.getSize()[0:2]) / 2 + self._sizeOffsets + self._headOffsets
226 posList.append(p + s * ( 1.0, 1.0))
227 posList.append(p + s * ( 0.0, 1.0))
228 posList.append(p + s * (-1.0, 1.0))
229 posList.append(p + s * ( 1.0, 0.0))
230 posList.append(p + s * (-1.0, 0.0))
231 posList.append(p + s * ( 1.0,-1.0))
232 posList.append(p + s * ( 0.0,-1.0))
233 posList.append(p + s * (-1.0,-1.0))
240 for a in self._objectList:
241 if self._checkHit(a, obj):
246 dist = numpy.linalg.norm(p)
247 if not self.checkPlatform(obj):
249 if best is None or dist < bestDist:
253 obj.setPosition(best)