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)
def splitPerfTest(): "make a long wire of lots of edges" """ performance of the wire split routine is surprisingly bad! """ WIDTH=0.1 edges = []; #trick here. after building a wire, the edges change identity. #evidently, BRepBuilder_MakeWire makes copies of the underliying edges. h = hexagonlib.Hexagon(2.0,0 ); wirelist = h.makeHexForBoundingBox((0,0,0), (100,100,0)); w = wirelist[0]; ee = Wrappers.Wire(w).edgesAsList(); #compute two intersections e1 = Wrappers.Edge(ee[5]); e2 = Wrappers.Edge(ee[55]); e1p = (e1.lastParameter - e1.firstParameter )/ 2; e2p = (e2.lastParameter - e2.firstParameter )/ 2; p1 = PointOnAnEdge(e1.edge,e1p ,e1.pointAtParameter(e1p)); p2 = PointOnAnEdge(e2.edge,e2p ,e2.pointAtParameter(e2p)); t = Util.Timer(); ee = []; for i in range(1,1000): ee = splitWire(w,[p2,p1]); assert len(ee) == 1; print "Elapsed for 1000splits:",t.finishedString();
def findIntersectionsUsingCurvesWithBoundingBoxes(wire, lines): """ find all of the intersections points between the wire and the lines, no fancy sorting """ points = [] count = 0 rejected = 0 w = Wrappers.Wire(wire) for boundaryEdge in w.edges2(): #get the curve from the 2d edge curve = get2dCurveFrom3dEdge(boundaryEdge) #make bounding box for the test curve box = boundingBoxForCurve(curve) for l in lines: #the line is already a geom-curve-- count += 1 box2 = boundingBoxForCurve(l) if box2.IsOut(box): rejected += 1 continue isector = Geom2dAPI.Geom2dAPI_InterCurveCurve(curve, l) if isector.NbPoints() > 0: for k in range(1, isector.NbPoints() + 1): points.append(isector.Point(k)) print "Rejected %d intersections." % rejected return (count, points)
def testSplitWire2(): "intersections on different edges. one edge completely inside" e1 = Wrappers.edgeFromTwoPoints(gp.gp_Pnt(0,0,0),gp.gp_Pnt(2,0,0)); e2 = Wrappers.edgeFromTwoPoints(gp.gp_Pnt(2,0,0),gp.gp_Pnt(5,0,0)); e3 = Wrappers.edgeFromTwoPoints(gp.gp_Pnt(5,0,0),gp.gp_Pnt(6,0,0)); #trick here. after building a wire, the edges change identity. #evidently, BRepBuilder_MakeWire makes copies of the underliying edges. w = Wrappers.wireFromEdges([e1,e2,e3]); ee = Wrappers.Wire(w).edgesAsList(); #print "Original Edges: %d %d %d " % ( ee[0].__hash__(),ee[1].__hash__(),ee[2].__hash__()); p1 = PointOnAnEdge(ee[0],1.0,gp.gp_Pnt(1.0,0,0)); p2 = PointOnAnEdge(ee[2],0.5,gp.gp_Pnt(5.0,0,0)); ee = splitWire(w,[p2,p1]); assert len(ee) == 1; length = 0; for e in ee[0]: ew = Wrappers.Edge(e); length += ew.distanceBetweenEnds(); TestDisplay.display.showShape(e); #print "length=%0.3f" % length; assert length == 4.5;
def intersectWiresUsingDistShapeShape(wire, edges): "intersect a wire with a series of edges. naive algorithm without bounding box sorting " ipoints = [] w = Wrappers.Wire(wire) circle = gp.gp_Circ2d(gp.gp_Ax2d(tP(2, 4), gp.gp().DX2d()), 2) e2 = BRepBuilderAPI.BRepBuilderAPI_MakeEdge2d(circle, tP(4, 4), tP(0, 4)).Edge() TestDisplay.display.showShape(e2) e4 = edgeFromTwoPoints((-4, 4), (0, 0)) TestDisplay.display.showShape(e4) brp = BRepExtrema.BRepExtrema_DistShapeShape(e2, e4) print "runing" brp.Perform() print "done" if brp.Value() < 0.001: 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): p1 = brp.PointOnShape1(k) ipoints.append(p1.X(), p1.Y()) return (count, ipoints)
def testProjectingPointInaccurately(): """ test projecting a point onto a curve """ h = makeHeartWire() #convert to twod curves curves = [] for e in Wrappers.Wire(h).edges2(): curves.append(get2dCurveFrom3dEdge(e)) #project a point onto the wire. we want to see if slight inaccurcies will project. #this simulates trying to find points on a curve that were put there via pixels display.DisplayShape(h) DISTANCE = 0.004 p = gp.gp_Pnt2d(2.0 + DISTANCE, 2.0 - DISTANCE) display.DisplayShape(Wrappers.make_vertex(gp.gp_Pnt(p.X(), p.Y(), 0))) for c in curves: r = projectPointOnCurve2d(c, p, 0.005) if r is not None: (param, pnt) = r print "found point: parmater-%0.3f, point-(%0.3f,%0.3f)" % ( param, pnt.X(), pnt.Y()) display.DisplayShape( Wrappers.make_vertex(gp.gp_Pnt(pnt.X(), pnt.Y(), 0)))
def findIntersectionsUsingCurvesNoSorting(wire, lines): """ find all of the intersections points between the wire and the lines, no fancy sorting """ points = [] count = 0 w = Wrappers.Wire(wire) for boundaryEdge in w.edges2(): #use this code if the supplied wire is a 3d wire #get the curve from the 2d edge #hCurve = get2dCurveFrom3dEdge(boundaryEdge) #curve=hCurve.GetObject(); #lp = curve.FirstParameter(); #up = curve.LastParameter(); #use this code if the supplied wire is a wire of 2d edges r = brt.Curve(boundaryEdge) hCurve = r[0] lp = r[1] up = r[2] print hCurve for l in lines: #the line is already a geom-curve count += 1 isector = Geom2dAPI.Geom2dAPI_InterCurveCurve(hCurve, l) if isector.NbPoints() > 0: for k in range(1, isector.NbPoints() + 1): #make sure the point is actually within the parameter boundaries on the curve. (a, b) = projectPointOnCurve2d(hCurve, isector.Point(k), 0.001) if a >= lp and a <= up: points.append(isector.Point(k)) return (count, points)
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);
def tuplesFromWire(wire, deflection): "return a list of tuples from a wire" list = [] ww = Wrappers.Wire(wire) for e in ww.edges2(): #for each edge, set vertices, and compute points on the edge ew = Wrappers.Edge(e) for pnt in ew.discretePoints(deflection): list.append(tP(pnt)) return list
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);
def followWire(self, wire, finish=False): """ Follow the edges in a wire in order """ ww = Wrappers.Wire(wire) for e in ww.edges2(): for m in self.followEdge(e, False): yield m #flush any last remaining move if finish: t = self._fetchPendingMove() if t: yield t
def makeHexEdges(xMin, yMin, xMax, yMax, zLevel): #this can be faster by avoiding 3d wires in the first place, for for now it is ok hex = hexagonlib.Hexagon(0.35, 0.01) wires = hex.makeHexForBoundingBox((xMin, yMin, zLevel), (xMax, yMax, zLevel)) tt = [] for w in wires: ww = Wrappers.Wire(w) for e in ww.edges2(): ew = Wrappers.Edge(e) tt.append((tP(ew.firstPoint), tP(ew.lastPoint))) print "Made %d hex edges" % len(tt) return tt
def findIntersectionsUsingCurves(wire, lines): points = [] count = 0 w = Wrappers.Wire(wire) for boundaryEdge in w.edges2(): #get the curve from the 2d edge hCurve = get2dCurveFrom3dEdge(boundaryEdge) curve = hCurve.GetObject() a = gp.gp_Pnt2d() b = gp.gp_Pnt2d() for l in lines: #the line is already a geom-curve lc = l.GetObject() count += 1 isector = Geom2dAPI.Geom2dAPI_ExtremaCurveCurve( hCurve, l, curve.FirstParameter(), curve.LastParameter(), lc.FirstParameter(), lc.LastParameter()) if isector.NbExtrema() > 0: isector.NearestPoints(a, b) points.append(a) return (count, points)
def splitPerfTest(): "make a long wire of lots of edges" """ performance of the wire split routine is surprisingly bad! """ WIDTH=0.1 edges = []; #trick here. after building a wire, the edges change identity. #evidently, BRepBuilder_MakeWire makes copies of the underliying edges. h = hexagonlib.Hexagon(2.0,0 ); wirelist = h.makeHexForBoundingBox((0,0,0), (100,100,0)); w = wirelist[0]; ee = Wrappers.Wire(w).edgesAsList(); TestDisplay.display.showShape(w); #compute two intersections e1 = Wrappers.Edge(ee[5]); e2 = Wrappers.Edge(ee[55]); e1p = (e1.lastParameter - e1.firstParameter )/ 2; e2p = (e2.lastParameter - e2.firstParameter )/ 2; p1 = PointOnAnEdge(e1.edge,e1p ,e1.pointAtParameter(e1p)); p2 = PointOnAnEdge(e2.edge,e2p ,e2.pointAtParameter(e2p)); TestDisplay.display.showShape( Wrappers.make_vertex(p1.point)); TestDisplay.display.showShape( Wrappers.make_vertex(p2.point)); #cProfile.runctx('for i in range(1,20): ee=splitWire(w,[p2,p1])', globals(), locals(), filename="slicer.prof") #p = pstats.Stats('slicer.prof') #p.sort_stats('cum') #p.print_stats(.98); t = Wrappers.Timer(); ee = []; for i in range(1,1000): ee = splitWire(w,[p2,p1]); assert len(ee) == 1; print "Elapsed for 1000splits:",t.finishedString();
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
def splitPerfTest(): "make a long wire of lots of edges" """ performance of the wire split routine is surprisingly bad! """ WIDTH=0.1 edges = []; for i in range(1,50): e = Wrappers.edgeFromTwoPoints(gp.gp_Pnt(i*WIDTH,0,0),gp.gp_Pnt((i+1)*WIDTH,0,0)) TestDisplay.display.showShape(e); edges.append(e); #trick here. after building a wire, the edges change identity. #evidently, BRepBuilder_MakeWire makes copies of the underliying edges. w = Wrappers.wireFromEdges(edges); ee = Wrappers.Wire(w).edgesAsList(); #compute two intersections e1 = Wrappers.Edge(ee[5]); e2 = Wrappers.Edge(ee[30]); e1p = (e1.lastParameter - e1.firstParameter )/ 2; e2p = (e2.lastParameter - e2.firstParameter )/ 2; p1 = PointOnAnEdge(e1.edge,e1p ,e1.pointAtParameter(e1p)); p2 = PointOnAnEdge(e2.edge,e2p ,e2.pointAtParameter(e2p)); #cProfile.runctx('for i in range(1,100): ee=splitWire(w,[p2,p1])', globals(), locals(), filename="slicer.prof") #p = pstats.Stats('slicer.prof') #p.sort_stats('time') #p.print_stats(.98); t = Wrappers.Timer(); for i in range(1,100): ee = splitWire(w,[p2,p1]); print "Elapsed for 100 splits:",t.finishedString();
def testDivideWire(): w = TestDisplay.makeCircleWire(); #w = TestDisplay.makeSquareWire(); #w = TestDisplay.makeReversedWire(); wr = Wrappers.Wire(w); eg = EdgeGraph(); eg.addWire(w,'BOUND'); print eg.edges #the big test-- split one of the edges e = eg.firstNode().edge; [newEdge1,newEdge2] = eg.divideEdge(e,2.5); print eg.edges e2 = newEdge2.edge; [newEdge3,newEdge4] = eg.divideEdge(e2,0.2333 ); for en in eg.allEdgesRandomOrder(): time.sleep(.1); e = en.newEdge(); TestDisplay.display.showShape( TestDisplay.makeEdgeIndicator(e) ); TestDisplay.display.showShape(e );
def TestWireJoiner(): heartWire = TestObjects.makeHeartWire() #man this is hard to test without resorting to graphical test. #this is sort of a semi-automatic method testPoints = [] testPoints.append([gp.gp_Pnt(-1.0, 0, 0), 5]) testPoints.append([gp.gp_Pnt(0, -1.0, 0), 5]) testPoints.append([gp.gp_Pnt(-1.0, -1.0, 0), 5]) testPoints.append([gp.gp_Pnt(1.0, 0, 0), 5]) testPoints.append([gp.gp_Pnt(1.6, 1.8, 0), 6]) testPoints.append([gp.gp_Pnt(4.15, 4.4, 0), 5]) testPoints.append([gp.gp_Pnt(0.5, 3.5, 0), 5]) testPoints.append([gp.gp_Pnt(4.0, 4.7, 0), 6]) for tp in testPoints: display.EraseAll() display.DisplayColoredShape(heartWire, 'GREEN') wj = WireJoiner(heartWire, tp[0], 0.08) result = wj.build() assert len(Wrappers.Wire(result).edgesAsList()) == tp[1] display.DisplayColoredShape(result, 'RED') time.sleep(1)
print "%d Intervals(C3)" % curve.NbIntervals(3) nB = curve.NbIntervals(2) #TestDisplay.display.showShape(testWire); resultEdge = TopoDS.TopoDS_Edge() #try to get edge from paramter p = 0.5 eP = curve.Edge(p, resultEdge) print "CompCurve Parameter %0.2f = edge parameter %0.2f" % (p, eP) TestDisplay.display.showShape(resultEdge) #show the selected point also point = curve.Value(p) #get all of the intervals for the wire print "Getting %d Intervals" % nB array = TColStd.TColStd_Array1OfReal(1, nB + 2) curve.Intervals(array, 2) print "Bounding Parameters: ", listFromArray(array) TestDisplay.display.showShape(Wrappers.make_vertex(point)) wr = Wrappers.Wire(testWire) edgeList = [] for e in wr.edges2(): edgeList.append(e) print "Edges:", edgeList TestDisplay.display.run()
def splitWire(wire, ipoints): """ ipoints is a list of intersection points. """ #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 eS = wr.edgesAsList(); #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 = eS[iEdge]; #currentEdgeWrapper = Wrappers.Edge(currentEdge); currentEdgeBounds = brepTool.Range(currentEdge); startParam = currentEdgeBounds[0]; while iIntersection < len(ix) and ( iEdge < len(eS) ) : currentIntersection = ix[iIntersection]; if hashE(currentEdge) == hashE(currentIntersection.edge): #current edge matches intersection point if inside: #transition to outside: add this part edge #currentEdgeWrapper = Wrappers.Edge(currentEdge); currentEdgeBounds = brepTool.Range(currentEdge); #startParam = currentEdgeWrapper.firstParameter; newEdge = Wrappers.trimmedEdge(currentEdge,startParam,currentIntersection.param); #newEdge = currentEdgeWrapper.trimmedEdge(startParam, currentIntersection.param); 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); #currentEdgeWrapper = Wrappers.Edge(currentEdge); if startParam == currentEdgeBounds[0]: edges.append(currentEdge); else: newEdge = Wrappers.trimmedEdge(currentEdge,startParam, currentEdgeBounds[1] ); #newEdge = currentEdgeWrapper.trimmedEdge(startParam, currentEdgeWrapper.lastParameter); edges.append(newEdge); #move to next edge iEdge += 1; currentEdge = eS[iEdge]; #currentEdgeWrapper = Wrappers.Edge(currentEdge); startParam = currentEdgeBounds[0]; #done. return the edges return edges;
return def tP(point): "return a tuple for a point" return (point.X(), point.Y(), point.Z()) if __name__ == '__main__': print "Basic Wrappers and Utilities Module" w = TestDisplay.makeCircleWire() w = TestDisplay.makeSquareWire() #w = TestDisplay.makeReversedWire(); wr = Wrappers.Wire(w) g = networkx.Graph() for e in wr.edges(): ew = Wrappers.Edge(e) g.add_edge(tP(ew.firstPoint), tP(ew.lastPoint), {'ew': ew}) TestDisplay.display.showShape(e) #print g.nodes(); #print g.edges(); print g.get_edge_data((5.0, 0.0, 0.0), (5.0, 5.0, 0.0)) #eg = EdgeGraph(); #eg.addWire(w,'BOUND');