Пример #1
0
    def copyToZ(self, z):
        "makes a copy of this slice, transformed to the specified z height"
        theCopy = Slice()
        theCopy.zLevel = z
        theCopy.zHeight = self.zHeight
        theCopy.sliceHeight = self.sliceHeight
        theCopy.fillWidth = self.fillWidth
        theCopy.hatchDir = self.hatchDir
        theCopy.checkSum = self.checkSum

        # make transformation
        p1 = gp.gp_Pnt(0, 0, 0)
        p2 = gp.gp_Pnt(0, 0, z)
        xform = gp.gp_Trsf()
        xform.SetTranslation(p1, p2)
        bt = BRepBuilderAPI.BRepBuilderAPI_Transform(xform)

        # copy all of the faces
        for f in hSeqIterator(self.faces):
            bt.Perform(f, True)
            theCopy.addFace(Wrappers.cast(bt.Shape()))

            # copy all of the fillWires
        for w in hSeqIterator(self.fillWires):
            bt.Perform(w, True)
            # TestDisplay.display.showShape(bt.Shape() );
            theCopy.fillWires.Append(Wrappers.cast(bt.Shape()))

            # copy all of the fillEdges
        for e in hSeqIterator(self.fillEdges):
            bt.Perform(e, True)
            # TestDisplay.display.showShape(bt.Shape() );
            theCopy.fillEdges.Append(Wrappers.cast(bt.Shape()))

        return theCopy
Пример #2
0
    def copyToZ(self, z):
        "makes a copy of this slice, transformed to the specified z height"
        theCopy = Slice()
        theCopy.zLevel = z
        theCopy.zHeight = self.zHeight
        theCopy.sliceHeight = self.sliceHeight
        theCopy.fillWidth = self.fillWidth
        theCopy.hatchDir = self.hatchDir
        theCopy.checkSum = self.checkSum

        #make transformation
        p1 = gp.gp_Pnt(0, 0, 0)
        p2 = gp.gp_Pnt(0, 0, z)
        xform = gp.gp_Trsf()
        xform.SetTranslation(p1, p2)
        bt = BRepBuilderAPI.BRepBuilderAPI_Transform(xform)

        #copy all of the faces
        for f in hSeqIterator(self.faces):
            bt.Perform(f, True)
            theCopy.addFace(Wrappers.cast(bt.Shape()))

        #copy all of the fillWires
        for w in hSeqIterator(self.fillWires):
            bt.Perform(w, True)
            #TestDisplay.display.showShape(bt.Shape() );
            theCopy.fillWires.Append(Wrappers.cast(bt.Shape()))

        #copy all of the fillEdges
        for e in hSeqIterator(self.fillEdges):
            bt.Perform(e, True)
            #TestDisplay.display.showShape(bt.Shape() );
            theCopy.fillEdges.Append(Wrappers.cast(bt.Shape()))

        return theCopy
Пример #3
0
	def makeHexArray(self,bottomLeftCenter, countX, countY ):
		"""
			makes an array of hexagons
			bottomLeftCenter is the center of the top left hex, as a three-element tuple
			countX is the number of hexes in the x direction
			countY is the number of hexes in the y direction
			returns a list of wires representing a hexagon fill pattern
		"""
		pattern = self.makePeriodic(bottomLeftCenter);
		wireBuilder = BRepBuilderAPI.BRepBuilderAPI_MakeWire(pattern);

		#make horizontal array
		tsf = gp.gp_Trsf();
		pDist = 2.0 * self.cartesianSpacing()[0];
		tsf.SetTranslation(gp.gp_Pnt(0,0,0),gp.gp_Pnt(pDist ,0,0));
		tx = BRepBuilderAPI.BRepBuilderAPI_Transform(tsf);
		currentShape = pattern;
		for i in range(1,int((countX/2)+1)):
			tx.Perform(currentShape,False);
			currentShape = tx.Shape();
			#display.DisplayShape(currentShape);
			wireBuilder.Add(Wrappers.cast(currentShape));

		#create an array by alternately offsetting one cell right and 
		#moving down
		topHalf = wireBuilder.Wire();		
		#topHalf= approximatedWire(topHalf);
		
		wires=[];
		wires.append(topHalf);
		dY = self.cartesianSpacing()[1]/2.0;
		dX = self.cartesianSpacing()[0];
		
		####TODO// performance note.  This method takes about 31ms to compute 1000x1000 hex.
		# pretty good, except that nearly 50% of the time is spent in makeTransform!!!
		# a much better method would be to use the same transform object somehow
		for i in range(1,int(countY*2)):
			if i % 2 == 0:
				t = makeTransform(0,dY*i,0);
			else:
				t = makeTransform(dX,dY*i,0);
			t.Perform(topHalf,False);
			w = Wrappers.cast(t.Shape());
			
			#approximate the wire
			#wires.append ( approximatedWire(w));
			wires.append( w);
		
		#display.DisplayShape(wires);
		return wires;
Пример #4
0
    def makeHexArray(self, bottomLeftCenter, countX, countY):
        """
			makes an array of hexagons
			bottomLeftCenter is the center of the top left hex, as a three-element tuple
			countX is the number of hexes in the x direction
			countY is the number of hexes in the y direction
			returns a list of wires representing a hexagon fill pattern
		"""
        pattern = self.makePeriodic(bottomLeftCenter)
        wireBuilder = BRepBuilderAPI.BRepBuilderAPI_MakeWire(pattern)

        #make horizontal array
        tsf = gp.gp_Trsf()
        pDist = 2.0 * self.cartesianSpacing()[0]
        tsf.SetTranslation(gp.gp_Pnt(0, 0, 0), gp.gp_Pnt(pDist, 0, 0))
        tx = BRepBuilderAPI.BRepBuilderAPI_Transform(tsf)
        currentShape = pattern
        for i in range(1, int((countX / 2) + 1)):
            tx.Perform(currentShape, False)
            currentShape = tx.Shape()
            #display.DisplayShape(currentShape);
            wireBuilder.Add(Wrappers.cast(currentShape))

        #create an array by alternately offsetting one cell right and
        #moving down
        topHalf = wireBuilder.Wire()
        #topHalf= approximatedWire(topHalf);

        wires = []
        wires.append(topHalf)
        dY = self.cartesianSpacing()[1] / 2.0
        dX = self.cartesianSpacing()[0]

        ####TODO// performance note.  This method takes about 31ms to compute 1000x1000 hex.
        # pretty good, except that nearly 50% of the time is spent in makeTransform!!!
        # a much better method would be to use the same transform object somehow
        for i in range(1, int(countY * 2)):
            if i % 2 == 0:
                t = makeTransform(0, dY * i, 0)
            else:
                t = makeTransform(dX, dY * i, 0)
            t.Perform(topHalf, False)
            w = Wrappers.cast(t.Shape())

            #approximate the wire
            #wires.append ( approximatedWire(w));
            wires.append(w)

        #display.DisplayShape(wires);
        return wires
Пример #5
0
    def addWire(self, wire, type):
        "add all the edges of a wire. They will be connected together."
        "type is the node type for each edge"

        #for finding an edge node
        wr = Wrappers.Wire(wire)
        self.edgeSeq = wr.edgesAsSequence()
        firstNode = None
        lastNode = None
        last = None
        for i in range(1, self.edgeSeq.Length() + 1):

            edge = Wrappers.cast(self.edgeSeq.Value(i))
            te = Wrappers.Edge(edge)

            newnode = EdgeNode(edge, te.firstParameter, te.lastParameter, type)
            self.addNode(newnode)

            if last:
                newnode.addPrev(newnode)
                last.addNext(newnode)

            last = newnode

            if i == 1:
                firstNode = newnode
            if i == self.edgeSeq.Length():
                lastNode = newnode

        #link last and first edge if the wire is closed
        if wire.Closed():
            lastNode.addNext(firstNode)
            firstNode.addPrev(lastNode)
Пример #6
0
	def addWire(self,wire,type):
		"add all the edges of a wire. They will be connected together."
		"type is the node type for each edge"
		
		#for finding an edge node
		wr = Wrappers.Wire(wire);
		self.edgeSeq = wr.edgesAsSequence();
		firstNode = None;
		lastNode = None;
		last = None;
		for i in range(1,self.edgeSeq.Length()+1):

			edge = Wrappers.cast(self.edgeSeq.Value(i));
			te = Wrappers.Edge(edge);			
			newnode = EdgeNode(te,type);
			self.addNode(newnode);
			
			if last:
				self.linkPrev( newnode,last);
				self.linkNext(last,newnode );
				
			last = newnode;

			if i == 1:
				firstNode = newnode;
			if i == self.edgeSeq.Length():
				lastNode = newnode;

		#link last and first edge if the wire is closed
		if wire.Closed():
			self.linkPrev( firstNode,lastNode);
			self.linkNext( lastNode,firstNode);			
Пример #7
0
	def addBoundaryWire(self,wire):
		#for finding an edge node
		wr = Wrappers.Wire(wire);
		eS = wr.edgesAsSequence();

		for i in range(1,eS.Length()+1):
			e = Wrappers.cast(eS.Value(i));
			self.addSingleBoundaryEdge(e);	
Пример #8
0
def loopWire(w):
    topexp = TopExp.TopExp_Explorer()
    topexp.Init(w, TopAbs.TopAbs_EDGE)
    edges = []
    while topexp.More():
        currentEdge = Wrappers.cast(topexp.Current())
        edges.append(currentEdge)
        topexp.Next()
    return edges
Пример #9
0
def loopWire(w):
	topexp = TopExp.TopExp_Explorer();
	topexp.Init(w,TopAbs.TopAbs_EDGE);
	edges = [];
	while topexp.More():
		currentEdge = Wrappers.cast(topexp.Current());
		edges.append(currentEdge);
		topexp.Next();
	return edges;
Пример #10
0
	def addWire(self,wire,type):
		"add all the edges of a wire. They will be connected together."
		"each edge is added at its full length"
		
		#for finding an edge node
		wr = Wrappers.Wire(wire);
		eS = wr.edgesAsSequence();

		for i in range(1,eS.Length()+1):
			e = Wrappers.cast(eS.Value(i));
			self.addEdge(e,type);
Пример #11
0
	def addWire(self,wire,type):
		"add all the edges of a wire. They will be connected together."
		"each edge is added at its full length"
		
		#for finding an edge node
		wr = Wrappers.Wire(wire);
		eS = wr.edgesAsSequence();

		for i in range(1,eS.Length()+1):
			e = Wrappers.cast(eS.Value(i));
			self.addEdge(e,type);
Пример #12
0
def boundarypixmapFromFace(face):
	"""	
		creates a pixel map containing only the boundaries of the object.
		the shape is approximated with straight lines, and vertices are marked
		with different values to help re-construct the lines later on.	
		
		Some c++ optimizaion woudl really speed this up.
	"""
	PIXEL = 0.02;
	DEFLECTION = PIXEL / 4.0;

	#get bounding box
	(xMin,yMin,zMin,xMax,yMax,zMax) = boundingBox([face]);
		
	#make pixmap
	pixmap = pixmaptest.pixmap((xMin,yMin),(xMax,yMax),PIXEL);

	#approximate each wire with a set of segments
	bb = TopExp.TopExp_Explorer();
	bb.Init(face,TopAbs.TopAbs_WIRE);
	while bb.More():
		#print "plotting wire"
		w = Wrappers.Wire(Wrappers.cast(bb.Current()));
		
		#divide the edge into discrete segments
		lastPnt = None;
		for e in w.edges2():
			#for each edge, set vertices, and compute points on the edge
			ew = Wrappers.Edge(e);
			lastPnt = None;
			for pnt in ew.discretePoints(DEFLECTION):				
				pixmap.set(tP(pnt),2);
						
				#plot the line
				if lastPnt != None: pixmap.drawLine(tP(lastPnt),tP(pnt) );				
				lastPnt = pnt;
		bb.Next();
	
	return pixmap;
Пример #13
0
def boundarypixmapFromFace(face):
    """	
		creates a pixel map containing only the boundaries of the object.
		the shape is approximated with straight lines, and vertices are marked
		with different values to help re-construct the lines later on.	
		
		Some c++ optimizaion woudl really speed this up.
	"""
    PIXEL = 0.02
    DEFLECTION = PIXEL / 4.0

    #get bounding box
    (xMin, yMin, zMin, xMax, yMax, zMax) = boundingBox([face])

    #make pixmap
    pixmap = pixmaptest.pixmap((xMin, yMin), (xMax, yMax), PIXEL)

    #approximate each wire with a set of segments
    bb = TopExp.TopExp_Explorer()
    bb.Init(face, TopAbs.TopAbs_WIRE)
    while bb.More():
        #print "plotting wire"
        w = Wrappers.Wire(Wrappers.cast(bb.Current()))

        #divide the edge into discrete segments
        lastPnt = None
        for e in w.edges2():
            #for each edge, set vertices, and compute points on the edge
            ew = Wrappers.Edge(e)
            lastPnt = None
            for pnt in ew.discretePoints(DEFLECTION):
                pixmap.set(tP(pnt), 2)

                #plot the line
                if lastPnt != None: pixmap.drawLine(tP(lastPnt), tP(pnt))
                lastPnt = pnt
        bb.Next()

    return pixmap
Пример #14
0
def splitWire(wire,ipoints):
	"""
		ipoints is a list of intersection points.
		returns a list of wires inside the intersection point
		
		this method must also work for a 'wire' consisting of a single
		edge. more than one intersection point can be on each edge, 
		but all of the ipoints are expected to be on edges in the provided wire.
		BASELINE PERFORMANCE: 11 ms per call for splitwiretest
		
		returns a list of lists.
		each element in the top list is a chain of connected edges.
			each element in that list is an edge ( or part of an edge )
			
		so, for example, suppose you compute a wire that has 100 edges, and there are 4 intersection points.
		in this case, there will be two elements returned, and each element would contain a list of edges
		between the two segments.
		---E1---+---E2---+-X-E3---+---E4--X--+---E5---
		will return [  [E1,E2], [ E3,E4 ] ]
		
	"""
	topexp = TopExp.TopExp_Explorer();
	topexp.Init(wire,TopAbs.TopAbs_EDGE);

	#sort intersection points by ascending X location
	ix = sorted(ipoints,key = lambda p: p.point.X() );	

	edgeList = [];
	
	assert (len(ipoints) % 2) == 0;
	
	for i in range(0,len(ipoints),2):
		#process intersection points in pairs
		#TODO: this could be done more cleanly with a pairwise iterator
		currentIntersection = ix[i];
		nextIntersection = ix[i+1];
		
		#if they are on the same edge, simply add a trimmed edge.
		#in this case, 
		if currentIntersection.hash == nextIntersection.hash:
			edgeList.append ( [ Wrappers.trimmedEdge(currentIntersection.edge, currentIntersection.param, nextIntersection.param ) ] ); 
		else:
			#intersections are not on the same edge.
			#add the fraction of the first edge
			(bp,ep) = brepTool.Range(currentIntersection.edge);
			edges = [];
			#print "adding piece of start edge."
			edges.append( Wrappers.trimmedEdge(currentIntersection.edge,currentIntersection.param, ep));
	
			#pick up whole edges between the first intersection and the next one
			#loop till current edge is same as current intersection
			while topexp.Current().__hash__() != currentIntersection.hash:
				topexp.Next();
			
			#advance to next edge
			topexp.Next();
			
			#add edges till current edge is same as next intersection
			#most of the performance suckage is happening here, with gc associated with these
			#edge objects.  If that gets fixed, we'll get a huge speed boost. about 33% of total time is saved.
			while topexp.Current().__hash__() != nextIntersection.hash:
				edge = Wrappers.cast(topexp.Current() );
				edges.append(edge);
				#print "adding middle edge"
				topexp.Next();
	
			#add the last edge
			(bp,ep) = brepTool.Range(nextIntersection.edge);
			edges.append( Wrappers.trimmedEdge(nextIntersection.edge,bp,nextIntersection.param));
			#print "adding last piece of edge"
			edgeList.append(edges);
	return edgeList;
Пример #15
0
def splitWire(wire, ipoints):
	"""
		ipoints is a list of intersection points.
		returns a list of wires inside the intersection point
		
		BASELINE PERFORMANCE: 11 ms per call for splitwiretest
	"""
	
	#load original wire
	#we make an important assumption that the wire is organized from
	#left to right or from right to left, and starts outside the boundaries.
	#this allows the scanline algorithm to define which segments are 'inside'
	#wr = Wrappers.Wire(wire);
	
	
	
	#assume edges are in ascending x order also
	#very interesting OCC weird thing: topexp is much faster than wireexplorer
	topexp = TopExp.TopExp_Explorer();
	topexp.Init(wire,TopAbs.TopAbs_EDGE);


	#sort intersection points by ascending X location
	ix = sorted(ipoints,key = lambda p: p.point.X() );
	
	inside = False;		
	edges = []; #a list of edges for the current wire.	

	iEdge = 0;
	iIntersection=0;
	
	#TODO: handle odd number of intersections
	
	#the last parameter on the current edge.
	#it is either the first parameter on the current edge,
	#or the last intersection point on the edge.
	currentEdge = Wrappers.cast(topexp.Current());
	currentEdgeBounds = brepTool.Range(currentEdge);
	startParam = currentEdgeBounds[0];
	#print "handling %d intersections" % len(ix)
	while iIntersection < len(ix) and ( topexp.More()  ) :
		currentIntersection = ix[iIntersection];

		if hashE(currentEdge) == currentIntersection.hash:
						
			#current edge matches intersection point
			if inside:
				#transition to outside: add this part edge
				currentEdgeBounds = brepTool.Range(currentEdge);
				newEdge = Wrappers.trimmedEdge(currentEdge,startParam,currentIntersection.param);
				#TestDisplay.display.showShape(newEdge);
				edges.append(newEdge);
							
			#move to next point, store last intersection
			iIntersection += 1;
			startParam = currentIntersection.param;			
			inside = not inside;
			
		else:
			#edges do not match		
			if inside:
				currentEdgeBounds = brepTool.Range(currentEdge);
				if startParam == currentEdgeBounds[0]:
					edges.append(currentEdge);
				else:
					newEdge = Wrappers.trimmedEdge(currentEdge,startParam, currentEdgeBounds[1] );
					
					edges.append(newEdge);
			
			#move to next edge
			topexp.Next();
			currentEdge = Wrappers.cast(topexp.Current());
			startParam = currentEdgeBounds[0];			
	#print "returning %d edges" % len(edges)
	return edges;	
Пример #16
0
    def hatch(self):
        """take the a slice and compute hatches
		
			computing the intersections of wires is very expensive, 
			so it is important to do this as efficently as possible.
			
			Inputs: a set of boundary wires that define a face,
			        a set of filling wires that cover a bounding box around the face.
			
			Outputs: 
				trim covering wires/edges by the boundaries, 
				trim boundaries by intersections with wires
				
			optimizations so far:
				* use active wire table to detect when to stop computing intersections with wires.
				 each boundary must be activated before computation stops, and a boundary is finished
				 after intersections have been found, and then stop occurring.
				 
			More optimization can be used by Bnd_BoundSortBox-- which would compare all of the bounding
			boxes at once in c++, but with more glue code.
			
		"""
        log.info("Hatching...")
        q = time.clock()
        hatchWires = self._makeHatchLines22()
        numCompares = 0

        print "Time to Make hatch Lines: %0.3f" % (time.clock() - q)
        activeBoundaries = {}

        for b in self.boundaryWires:
            activeBoundaries[b] = 0
            self.graphBuilder.addBoundaryWire(b)

        print "There are %d boundary wires, %d hatch wires" % (len(
            self.boundaryWires), len(hatchWires))
        #intersect each line with each boundary
        for hatchLine in hatchWires:

            if len(activeBoundaries) == 0:
                break
                #finished hatching, no more active boundaries.

            interSections = []
            #list of intersections for just this single hatch line
            closePoints = []
            #extrema that are not intersectionsf or this single hatch line

            for boundary in activeBoundaries.keys():
                brp = BRepExtrema.BRepExtrema_DistShapeShape()
                brp.LoadS1(boundary)
                brp.LoadS2(hatchLine)
                numCompares += 1
                result = brp.Perform()
                """
					tricky thing: for a given hatch line ( whether a line or a string of hexes ),
					we want to check for both intersections and close points that would result in overdrawing.
					if the line has zero intersections, then it is not in play, and should not be considered.
					if the line has at least one intersection, then it is in play, and extrema that are not intersections should
					also be included for later processing.
				"""
                if result and brp.Value(
                ) < 0.050:  #if < tolerance we have an intersection. if < filament width we have a close sitation
                    #print "intersection found!"
                    #TODO need to handle the somewhat unusual cases that the intersection is
                    #on a vertex
                    for k in range(1, brp.NbSolution() + 1):
                        activeBoundaries[boundary] = 1
                        if brp.Value(
                        ) < 0.001:  #there is at least one intersection on this wire. there may also be extrema
                            #try:
                            #make the node
                            #quite complex depending on where exactly the intersection is.
                            if brp.SupportTypeShape1(
                                    k) == BRepExtrema.BRepExtrema_IsOnEdge:
                                #well this sux-- have to check to ensure that the edge is not a local
                                #minimum or maximum also.
                                if Wrappers.isEdgeLocalMinimum(
                                        Wrappers.cast(brp.SupportOnShape1(k)),
                                        brp.ParOnEdgeS1(k),
                                        brp.PointOnShape1(k)):
                                    #print "Warning: edge appears to be a local min/max.  Is it a tangent?"
                                    continue
                                else:
                                    #self.boundaryIntersectionsByEdge = {} #boundary intersections, hashed by edges
                                    self.graphBuilder.addPointOnBoundaryEdge(
                                        Wrappers.cast(brp.SupportOnShape1(k)),
                                        brp.ParOnEdgeS1(k),
                                        brp.PointOnShape1(k))

                            if brp.SupportTypeShape2(
                                    k) == BRepExtrema.BRepExtrema_IsOnEdge:
                                if brp.SupportTypeShape1(
                                        k) == BRepExtrema.BRepExtrema_IsVertex:
                                    #the intersection is on a vertex of the boundary.
                                    vertex = Wrappers.cast(
                                        brp.SupportOnShape1(k))
                                    if Wrappers.isLocalMinimum(
                                            boundary, vertex):
                                        print "vertex encountered that is a local minimum, skipping it"
                                        continue

                                #otherwise, vertex was not a local minimum, or was on an edge
                                poe = eg.PointOnAnEdge(
                                    Wrappers.cast(brp.SupportOnShape2(k)),
                                    brp.ParOnEdgeS2(k), brp.PointOnShape2(k))
                                interSections.append(poe)

                            elif brp.SupportTypeShape2(
                                    k) == BRepExtrema.BRepExtrema_IsVertex:
                                #how on earth to handle this one?
                                #this actually means that a vertex can also have an infill node attached to it!
                                #for right now let's just ignore it.
                                print "WARNING: intersection on vertex of hatch line!"
                                pass
                            else:
                                raise ValueError(
                                    "I dont know how to handle this kind of intersection"
                                )
                        else:  #brp.Value is between 0.001 and 0.05
                            #we know this is a place where the boundary is close to a fill contour.
                            #our goal is to eventually remove it from the list. Support1 is the boundary.
                            #print "found extremum close but not intersecting, distance = %0.3f" %  ( brp.Value() )
                            if brp.SupportTypeShape1(
                                    k) == BRepExtrema.BRepExtrema_IsOnEdge:
                                poeBound = eg.PointOnAnEdge(
                                    brp.SupportOnShape1(k), brp.ParOnEdgeS1(k),
                                    brp.PointOnShape1(k))
                                closePoints.append(
                                    (poeBound, 'EDGE', brp.SupportOnShape2(k)))
                            elif brp.SupportTypeShape2(
                                    k) == BRepExtrema.BRepExtrema_IsVertex:
                                #here a vertex is closest to a fill line.
                                poeBound = eg.PointOnAnEdge(
                                    brp.SupportOnShape1(k), 0,
                                    brp.PointOnShape1(k))
                                closePoints.append((poeBound, 'VERTEX',
                                                    brp.SupportOnShape2(k)))

                else:
                    if activeBoundaries[boundary] == 1:
                        #finished with this wire.
                        #print "Finished with wire %d" % boundary.__hash__();
                        del activeBoundaries[boundary]

            if len(interSections) % 2 == 1:
                log.warn(
                    "Detected Odd Number of intersection points. This is ignored for now."
                )
                continue

            if len(interSections) == 0:
                #log.warn("Hatch has no intersections-- discarding");
                continue

            #at this point we have all the intersections for this hatch line.
            #we also know we have at least one intersection.

            if len(closePoints) > 0:
                #there were extrema ( points where this hatch is close to a boundary but doesnt intersect.
                #we do this here instead of inline because we have to avoid hatch lines that are close, but do not actually
                #intersect a wire. ( ie, they are 'just outside' of the boundary )
                for cp in closePoints:
                    self.graphBuilder.addPointsTooClose(cp[0], cp[1])
                    display.DisplayShape(Wrappers.make_vertex(cp[0].point))
                    #display.DisplayShape(cp[2] );

            #add the edges 'inside' the shape to the graph
            #print "Splitting wire by %d intersection points" % len(interSections )
            edgesInside = []
            edgesInside = eg.splitWire(hatchLine, interSections)

            #returned value is a list of lists. each entry is a chain of edges
            for e in edgesInside:
                self.graphBuilder.addFillEdges(e)

            #test to see if we can break out of the loop.
            #we can stop if we've hit each boundary at least once
            #if len(interSections) == 0 and (len(boundariesFound) ==  len(self.boundaryWires)):
            #	continueHatching = False;

            log.debug("found %d intersection Nodes." % len(interSections))

        log.info("Finished Hatching.")
        print "%d Total Intersections computed." % (numCompares)
        self.graphBuilder.buildGraph()
Пример #17
0
def splitWire(wire, ipoints):
    """
		ipoints is a list of intersection points.
		returns a list of wires inside the intersection point
		
		this method must also work for a 'wire' consisting of a single
		edge. more than one intersection point can be on each edge, 
		but all of the ipoints are expected to be on edges in the provided wire.
		BASELINE PERFORMANCE: 11 ms per call for splitwiretest
		
		returns a list of lists.
		each element in the top list is a chain of connected edges.
			each element in that list is an edge ( or part of an edge )
			
		so, for example, suppose you compute a wire that has 100 edges, and there are 4 intersection points.
		in this case, there will be two elements returned, and each element would contain a list of edges
		between the two segments.
		---E1---+---E2---+-X-E3---+---E4--X--+---E5---
		will return [  [E1,E2], [ E3,E4 ] ]
		
	"""
    topexp = TopExp.TopExp_Explorer()
    topexp.Init(wire, TopAbs.TopAbs_EDGE)

    # sort intersection points by ascending X location
    ix = sorted(ipoints, key=lambda p: p.point.X())

    edgeList = []

    assert (len(ipoints) % 2) == 0

    for i in range(0, len(ipoints), 2):
        # process intersection points in pairs
        # TODO: this could be done more cleanly with a pairwise iterator
        currentIntersection = ix[i]
        nextIntersection = ix[i + 1]

        # if they are on the same edge, simply add a trimmed edge.
        # in this case,
        if currentIntersection.hash == nextIntersection.hash:
            edgeList.append(
                [Wrappers.trimmedEdge(currentIntersection.edge, currentIntersection.param, nextIntersection.param)]
            )
        else:
            # intersections are not on the same edge.
            # add the fraction of the first edge
            (bp, ep) = brepTool.Range(currentIntersection.edge)
            edges = []
            # print "adding piece of start edge."
            edges.append(Wrappers.trimmedEdge(currentIntersection.edge, currentIntersection.param, ep))

            # pick up whole edges between the first intersection and the next one
            # loop till current edge is same as current intersection
            while topexp.Current().__hash__() != currentIntersection.hash:
                topexp.Next()

                # advance to next edge
            topexp.Next()

            # add edges till current edge is same as next intersection
            # most of the performance suckage is happening here, with gc associated with these
            # edge objects.  If that gets fixed, we'll get a huge speed boost. about 33% of total time is saved.
            while topexp.Current().__hash__() != nextIntersection.hash:
                edge = Wrappers.cast(topexp.Current())
                edges.append(edge)
                # print "adding middle edge"
                topexp.Next()

                # add the last edge
            (bp, ep) = brepTool.Range(nextIntersection.edge)
            edges.append(Wrappers.trimmedEdge(nextIntersection.edge, bp, nextIntersection.param))
            # print "adding last piece of edge"
            edgeList.append(edges)
    return edgeList