mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-08-18 01:25:58 +08:00
Fixed the part splitter
This commit is contained in:
parent
44c38bf924
commit
c0ff43a221
@ -84,7 +84,6 @@ class mesh(object):
|
|||||||
removeDict = {}
|
removeDict = {}
|
||||||
tree = util3d.AABBTree()
|
tree = util3d.AABBTree()
|
||||||
off = numpy.array([0.0001,0.0001,0.0001])
|
off = numpy.array([0.0001,0.0001,0.0001])
|
||||||
newVertexList = []
|
|
||||||
for idx in xrange(0, self.vertexCount):
|
for idx in xrange(0, self.vertexCount):
|
||||||
v = self.vertexes[idx]
|
v = self.vertexes[idx]
|
||||||
e = util3d.AABB(v-off, v+off)
|
e = util3d.AABB(v-off, v+off)
|
||||||
@ -92,67 +91,71 @@ class mesh(object):
|
|||||||
if len(q) < 1:
|
if len(q) < 1:
|
||||||
e.idx = idx
|
e.idx = idx
|
||||||
tree.insert(e)
|
tree.insert(e)
|
||||||
newVertexList.append(v)
|
|
||||||
else:
|
else:
|
||||||
removeDict[idx] = q[0].idx
|
removeDict[idx] = q[0].idx
|
||||||
print "%f: " % (time.time() - t0), "Marked %d duplicate vertexes for removal." % (len(removeDict))
|
print "%f: " % (time.time() - t0), "Marked %d duplicate vertexes for removal." % (len(removeDict))
|
||||||
|
|
||||||
|
faceList = []
|
||||||
|
for idx in xrange(0, self.vertexCount, 3):
|
||||||
|
f = [idx, idx + 1, idx + 2]
|
||||||
|
if removeDict.has_key(f[0]):
|
||||||
|
f[0] = removeDict[f[0]]
|
||||||
|
if removeDict.has_key(f[1]):
|
||||||
|
f[1] = removeDict[f[1]]
|
||||||
|
if removeDict.has_key(f[2]):
|
||||||
|
f[2] = removeDict[f[2]]
|
||||||
|
faceList.append(f)
|
||||||
|
|
||||||
#Make facelists so we can quickly remove all the vertexes.
|
print "%f: " % (time.time() - t0), "Building face lists after vertex removal."
|
||||||
vertexFaceList = []
|
vertexFaceList = []
|
||||||
for idx in xrange(0, self.vertexCount):
|
for idx in xrange(0, self.vertexCount):
|
||||||
vertexFaceList.append([])
|
vertexFaceList.append([])
|
||||||
for f in self.faces:
|
for idx in xrange(0, len(faceList)):
|
||||||
f.v[0].faceList.append(f)
|
f = faceList[idx]
|
||||||
f.v[1].faceList.append(f)
|
vertexFaceList[f[0]].append(idx)
|
||||||
f.v[2].faceList.append(f)
|
vertexFaceList[f[1]].append(idx)
|
||||||
|
vertexFaceList[f[2]].append(idx)
|
||||||
self.vertexes = newVertexList
|
|
||||||
for v1 in removeDict.iterkeys():
|
|
||||||
v0 = removeDict[v1]
|
|
||||||
for f in v1.faceList:
|
|
||||||
if f.v[0] == v1:
|
|
||||||
f.v[0] = v0
|
|
||||||
if f.v[1] == v1:
|
|
||||||
f.v[1] = v0
|
|
||||||
if f.v[2] == v1:
|
|
||||||
f.v[2] = v0
|
|
||||||
print "%f: " % (time.time() - t0), "Building face lists after vertex removal."
|
|
||||||
for v in self.vertexes:
|
|
||||||
v.faceList = []
|
|
||||||
for f in self.faces:
|
|
||||||
f.v[0].faceList.append(f)
|
|
||||||
f.v[1].faceList.append(f)
|
|
||||||
f.v[2].faceList.append(f)
|
|
||||||
|
|
||||||
print "%f: " % (time.time() - t0), "Building parts."
|
print "%f: " % (time.time() - t0), "Building parts."
|
||||||
|
self._vertexFaceList = vertexFaceList
|
||||||
|
self._faceList = faceList
|
||||||
partList = []
|
partList = []
|
||||||
doneSet = set()
|
doneSet = set()
|
||||||
for f in self.faces:
|
for idx in xrange(0, len(faceList)):
|
||||||
if not f in doneSet:
|
if not idx in doneSet:
|
||||||
partList.append(self._createPartFromFacewalk(f, doneSet))
|
partList.append(self._createPartFromFacewalk(idx, doneSet))
|
||||||
print "%f: " % (time.time() - t0), "Split into %d parts" % (len(partList))
|
print "%f: " % (time.time() - t0), "Split into %d parts" % (len(partList))
|
||||||
|
self._vertexFaceList = None
|
||||||
|
self._faceList = None
|
||||||
return partList
|
return partList
|
||||||
|
|
||||||
def _createPartFromFacewalk(self, startFace, doneSet):
|
def _createPartFromFacewalk(self, startFaceIdx, doneSet):
|
||||||
m = mesh()
|
m = mesh()
|
||||||
todoList = [startFace]
|
m._prepareVertexCount(self.vertexCount)
|
||||||
doneSet.add(startFace)
|
todoList = [startFaceIdx]
|
||||||
|
doneSet.add(startFaceIdx)
|
||||||
while len(todoList) > 0:
|
while len(todoList) > 0:
|
||||||
f = todoList.pop()
|
faceIdx = todoList.pop()
|
||||||
m._partAddFacewalk(f, doneSet, todoList)
|
self._partAddFacewalk(m, faceIdx, doneSet, todoList)
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def _partAddFacewalk(self, f, doneSet, todoList):
|
def _partAddFacewalk(self, part, faceIdx, doneSet, todoList):
|
||||||
self.addFace(f.v[0], f.v[1], f.v[2])
|
f = self._faceList[faceIdx]
|
||||||
for f1 in f.v[0].faceList:
|
v0 = self.vertexes[f[0]]
|
||||||
|
v1 = self.vertexes[f[0]]
|
||||||
|
v2 = self.vertexes[f[0]]
|
||||||
|
part.addVertex(v0[0], v0[1], v0[2])
|
||||||
|
part.addVertex(v1[0], v1[1], v1[2])
|
||||||
|
part.addVertex(v2[0], v2[1], v2[2])
|
||||||
|
for f1 in self._vertexFaceList[f[0]]:
|
||||||
if f1 not in doneSet:
|
if f1 not in doneSet:
|
||||||
todoList.append(f1)
|
todoList.append(f1)
|
||||||
doneSet.add(f1)
|
doneSet.add(f1)
|
||||||
for f1 in f.v[1].faceList:
|
for f1 in self._vertexFaceList[f[1]]:
|
||||||
if f1 not in doneSet:
|
if f1 not in doneSet:
|
||||||
todoList.append(f1)
|
todoList.append(f1)
|
||||||
doneSet.add(f1)
|
doneSet.add(f1)
|
||||||
for f1 in f.v[2].faceList:
|
for f1 in self._vertexFaceList[f[2]]:
|
||||||
if f1 not in doneSet:
|
if f1 not in doneSet:
|
||||||
todoList.append(f1)
|
todoList.append(f1)
|
||||||
doneSet.add(f1)
|
doneSet.add(f1)
|
||||||
|
@ -66,6 +66,6 @@ if __name__ == '__main__':
|
|||||||
m = stlModel().load(filename)
|
m = stlModel().load(filename)
|
||||||
print("Loaded %d faces" % (m.vertexCount / 3))
|
print("Loaded %d faces" % (m.vertexCount / 3))
|
||||||
parts = m.splitToParts()
|
parts = m.splitToParts()
|
||||||
# for p in parts:
|
for p in parts:
|
||||||
# saveAsSTL(p, "export_%i.stl" % parts.index(p))
|
saveAsSTL(p, "export_%i.stl" % parts.index(p))
|
||||||
|
|
||||||
|
@ -82,9 +82,7 @@ class AABB(object):
|
|||||||
def __init__(self, vMin, vMax):
|
def __init__(self, vMin, vMax):
|
||||||
self.vMin = vMin
|
self.vMin = vMin
|
||||||
self.vMax = vMax
|
self.vMax = vMax
|
||||||
|
self.perimeter = numpy.sum(self.vMax - self.vMin)
|
||||||
def getPerimeter(self):
|
|
||||||
return (self.vMax[0] - self.vMax[0]) + (self.vMax[1] - self.vMax[1]) + (self.vMax[2] - self.vMax[2])
|
|
||||||
|
|
||||||
def combine(self, aabb):
|
def combine(self, aabb):
|
||||||
return AABB(numpy.minimum(self.vMin, aabb.vMin), numpy.maximum(self.vMax, aabb.vMax))
|
return AABB(numpy.minimum(self.vMin, aabb.vMin), numpy.maximum(self.vMax, aabb.vMax))
|
||||||
@ -125,25 +123,25 @@ class AABBTree(object):
|
|||||||
child1 = node.child1
|
child1 = node.child1
|
||||||
child2 = node.child2
|
child2 = node.child2
|
||||||
|
|
||||||
area = node.aabb.getPerimeter()
|
area = node.aabb.perimeter
|
||||||
combinedAABB = node.aabb.combine(aabb)
|
combinedAABB = node.aabb.combine(aabb)
|
||||||
combinedArea = combinedAABB.getPerimeter()
|
combinedArea = combinedAABB.perimeter
|
||||||
|
|
||||||
cost = 2.0 * combinedArea
|
cost = 2.0 * combinedArea
|
||||||
inheritanceCost = 2.0 * (combinedArea - area)
|
inheritanceCost = 2.0 * (combinedArea - area)
|
||||||
|
|
||||||
if child1.isLeaf():
|
if child1.isLeaf():
|
||||||
cost1 = aabb.combine(child1.aabb).getPerimeter() + inheritanceCost
|
cost1 = aabb.combine(child1.aabb).perimeter + inheritanceCost
|
||||||
else:
|
else:
|
||||||
oldArea = child1.aabb.getPerimeter()
|
oldArea = child1.aabb.perimeter
|
||||||
newArea = aabb.combine(child1.aabb).getPerimeter()
|
newArea = aabb.combine(child1.aabb).perimeter
|
||||||
cost1 = (newArea - oldArea) + inheritanceCost
|
cost1 = (newArea - oldArea) + inheritanceCost
|
||||||
|
|
||||||
if child2.isLeaf():
|
if child2.isLeaf():
|
||||||
cost2 = aabb.combine(child1.aabb).getPerimeter() + inheritanceCost
|
cost2 = aabb.combine(child1.aabb).perimeter + inheritanceCost
|
||||||
else:
|
else:
|
||||||
oldArea = child2.aabb.getPerimeter()
|
oldArea = child2.aabb.perimeter
|
||||||
newArea = aabb.combine(child2.aabb).getPerimeter()
|
newArea = aabb.combine(child2.aabb).perimeter
|
||||||
cost2 = (newArea - oldArea) + inheritanceCost
|
cost2 = (newArea - oldArea) + inheritanceCost
|
||||||
|
|
||||||
if cost < cost1 and cost < cost2:
|
if cost < cost1 and cost < cost2:
|
||||||
@ -230,8 +228,8 @@ class AABBTree(object):
|
|||||||
A.aabb = B.aabb.combine(G.aabb)
|
A.aabb = B.aabb.combine(G.aabb)
|
||||||
C.aabb = A.aabb.combine(F.aabb)
|
C.aabb = A.aabb.combine(F.aabb)
|
||||||
|
|
||||||
A.height = 1 + Math.max(B.height, G.height)
|
A.height = 1 + max(B.height, G.height)
|
||||||
C.height = 1 + Math.max(A.height, F.height)
|
C.height = 1 + max(A.height, F.height)
|
||||||
else:
|
else:
|
||||||
C.child2 = G
|
C.child2 = G
|
||||||
A.child2 = F
|
A.child2 = F
|
||||||
@ -309,9 +307,9 @@ class AABBTree(object):
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
tree = AABBTree()
|
tree = AABBTree()
|
||||||
tree.insert(AABB(numpy.array([0,0,0]), numpy.array([0,0,0])))
|
tree.insert(AABB(Vector3(0,0,0), Vector3(0,0,0)))
|
||||||
tree.insert(AABB(numpy.array([1,1,1]), numpy.array([1,1,1])))
|
tree.insert(AABB(Vector3(1,1,1), Vector3(1,1,1)))
|
||||||
tree.insert(AABB(numpy.array([0.5,0.5,0.5]), numpy.array([0.5,0.5,0.5])))
|
tree.insert(AABB(Vector3(0.5,0.5,0.5), Vector3(0.5,0.5,0.5)))
|
||||||
print(tree)
|
print(tree)
|
||||||
print(tree.query(AABB(numpy.array([0,0,0]), numpy.array([0,0,0]))))
|
print(tree.query(AABB(Vector3(0,0,0), Vector3(0,0,0))))
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user