Beispiel #1
0
def cutFigure(wholeFigure, hyperplane):

	facesAscending=[]
	queue=[wholeFigure]
	mark=object()
	while queue:
		figure=queue.pop(0)
		if figure.mark==mark: continue
		figure.mark=mark
		facesAscending.insert(0,figure)
		queue.extend(figure.boundary)

	for figure in facesAscending:
		figure.usedInSection=False
		figure.sectionFacets=[]
		if figure.dim == 0: # Vertex
			dist=hyperplane.orientedDistance(figure.position)
			if abs(dist)<0.0001:
				figure.cuttingCache=([], [figure], [])
			elif dist>0:
				figure.cuttingCache=([], [], [figure])
			else:
				figure.cuttingCache=([figure], [], [])
			continue;

		# Edge, face, ...

		left,middle,right = \
				zip(*map(lambda f: f.cuttingCache, figure.boundary))
		left,middle,right = (reduce(lambda a,b: a+b, l) for l in (left,middle,right))

		if not right and not left: # All in the hyperplane
			figure.cuttingCache=([], [figure], [])
			continue


		if not right or not left:
			for f in middle:
				if f.dim==figure.dim-1:
					for f2 in f.boundary:
						f2.usedInSection=True
					figure.sectionFacets.append(f)

		middle2=[]
		for f in middle:
			if not f.usedInSection or f.dim == figure.dim-2:
				middle2.append(f)
		middle=middle2


		if not right:            # Nothing right
			figure.cuttingCache=([figure], middle, [])
			continue
		if not left:             # Nothing left
			figure.cuttingCache=([], middle, [figure])
			continue

		section=[]
		middle2=set()
		for f in middle:
			if f.dim == figure.dim-2:
				middle2.add(f)
			elif f.dim != figure.dim-1:
				section.append(f)
		middle=middle2

		if figure.dim == 1:      # Cutting edge
			diff=algebra.vectDiff(right[0].position, left[0].position)
			prod=algebra.dotProduct(diff, hyperplane.normal)
			dist=hyperplane.orientedDistance(left[0].position)
			vert=Vertex(algebra.vectSum(left[0].position, algebra.vectMult(-dist/prod, diff)))
			vert.usedInSection=True
			leftEdge=Figure([left[0], vert])
			rightEdge=Figure([right[0], vert])
			leftEdge.sectionFacets=[vert]
			rightEdge.sectionFacets=[vert]
			figure.cuttingCache=([leftEdge], [vert], [rightEdge])
			continue

		# Cutting face (at least 2-dimensional)

		leftComp=check.findComponents(left, middle)
		rightComp=check.findComponents(right, middle)
		leftComp=[Figure(c) for c in leftComp]
		rightComp=[Figure(c) for c in rightComp]

		for rightFigure in rightComp:
			rightFigure.sectionFacets=[]
			rightFigure.sectionRidges=set()
			for f in rightFigure.boundary:
				rightFigure.sectionRidges.update(f.sectionFacets)
		for leftFigure in leftComp:
			leftFigure.sectionFacets=[]
			leftRidges=set()
			for f in leftFigure.boundary:
				leftRidges.update(f.sectionFacets)
			for rightFigure in rightComp:
				rightRidges=rightFigure.sectionRidges
				commonRidges=leftRidges | rightRidges
				if commonRidges:
					f=Figure(commonRidges)
					f.usedInSection=True
					leftFigure.sectionFacets.append(f)
					rightFigure.sectionFacets.append(f)
					leftFigure.boundary.add(f)
					rightFigure.boundary.add(f)
					section.append(f)


		for f in middle:
			if not f.usedInSection:
				section.append(f)


		figure.cuttingCache=(leftComp, section, rightComp)

	ret=wholeFigure.cuttingCache;
	for figure in wholeFigure:
		del figure.cuttingCache
		del figure.usedInSection

	return ret;