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
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 " % ( hashE(ee[0]),hashE(ee[1]),hashE(ee[2])); 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) == 3; length = 0; for e in ee: ew = Wrappers.Edge(e); length += ew.distanceBetweenEnds(); TestDisplay.display.showShape(e); print "length=%0.3f" % length; assert length == 4.5;
def testSplitWire1(): """ Test split wire function. there are two main cases: wires with intersection on different edges, and a wire with a single edge split in many places """ #case 1: a single edge with lots of intersections along its length e = Wrappers.edgeFromTwoPoints( gp.gp_Pnt(0,0,0),gp.gp_Pnt(5,0,0)); w = Wrappers.wireFromEdges([e]); #out of order on purpose p1 = PointOnAnEdge(e,1.0,gp.gp_Pnt(1.0,0,0)); p3 = PointOnAnEdge(e,3.0,gp.gp_Pnt(3.0,0,0)); p2 = PointOnAnEdge(e,2.0,gp.gp_Pnt(2.0,0,0)); p4 = PointOnAnEdge(e,4.0,gp.gp_Pnt(4.0,0,0)); ee = splitWire(w,[p1,p3,p2,p4] ); assert len(ee) == 2; length = 0; for e in ee: ew = Wrappers.Edge(e); length += ew.distanceBetweenEnds(); TestDisplay.display.showShape(e); assert length == 2.0;
def makeHeartWire(): "make a heart wire" e1 = Wrappers.edgeFromTwoPoints(gp.gp_Pnt(0,0,0), gp.gp_Pnt(4.0,4.0,0)); circle = gp.gp_Circ(gp.gp_Ax2(gp.gp_Pnt(2,4,0),gp.gp().DZ()),2); e2 = BRepBuilderAPI.BRepBuilderAPI_MakeEdge(circle, gp.gp_Pnt(4,4,0),gp.gp_Pnt(0,4,0)).Edge(); circle = gp.gp_Circ(gp.gp_Ax2(gp.gp_Pnt(-2,4,0),gp.gp().DZ()),2); e3 = BRepBuilderAPI.BRepBuilderAPI_MakeEdge(circle, gp.gp_Pnt(0,4,0),gp.gp_Pnt(-4,4,0)).Edge(); e4 = Wrappers.edgeFromTwoPoints(gp.gp_Pnt(-4,4,0), gp.gp_Pnt(0,0,0)); return Wrappers.wireFromEdges([e1,e2,e3,e4]);
def scanlinesFromBoundingBox(boundingBox,interval): (xMin,yMin,zMin,xMax,yMax,zMax) = boundingBox; print boundingBox; edges = []; for y in Wrappers.frange6(yMin,yMax,interval): e = Wrappers.edgeFromTwoPoints(gp.gp_Pnt(xMin,y,0),gp.gp_Pnt(xMax,y,0)); #TestDisplay.display.showShape(e); edges.append((y,Wrappers.wireFromEdges([e]))); return edges;
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 squareWire(centerPt, w): "makes a square wire with center at the desired point" w2 = w / 2.0 p1 = gp.gp_Pnt(centerPt.X() - w2, centerPt.Y() - w2, centerPt.Z()) p2 = gp.gp_Pnt(centerPt.X() - w2, centerPt.Y() + w2, centerPt.Z()) p3 = gp.gp_Pnt(centerPt.X() + w2, centerPt.Y() + w2, centerPt.Z()) p4 = gp.gp_Pnt(centerPt.X() + w2, centerPt.Y() - w2, centerPt.Z()) e1 = Wrappers.edgeFromTwoPoints(p1, p4) e2 = Wrappers.edgeFromTwoPoints(p4, p3) e3 = Wrappers.edgeFromTwoPoints(p3, p2) e4 = Wrappers.edgeFromTwoPoints(p2, p1) return Wrappers.wireFromEdges([e1, e2, e3, e4])
def makeEdgeIndicator(edge): "makes an indicator showing which way the edge goes" ew = Wrappers.Edge(edge) fp = ew.firstParameter lp = ew.lastParameter if ew.reversed: p = fp + ((lp - fp) * 1 / 5) else: p = fp + ((lp - fp) * 4 / 5) midPnt = ew.curve.Value(p) return Wrappers.make_vertex(midPnt)
def squareWire(centerPt,w ): "makes a square wire with center at the desired point" w2 = w/2.0; p1 = gp.gp_Pnt(centerPt.X() - w2,centerPt.Y() -w2 , centerPt.Z() ) p2 = gp.gp_Pnt(centerPt.X() - w2,centerPt.Y() +w2, centerPt.Z() ) p3 = gp.gp_Pnt(centerPt.X() + w2,centerPt.Y() +w2, centerPt.Z() ) p4 = gp.gp_Pnt(centerPt.X() + w2,centerPt.Y() -w2, centerPt.Z() ) e1 = Wrappers.edgeFromTwoPoints(p1,p4); e2 = Wrappers.edgeFromTwoPoints(p4,p3); e3 = Wrappers.edgeFromTwoPoints(p3,p2); e4 = Wrappers.edgeFromTwoPoints(p2,p1); return Wrappers.wireFromEdges([e1,e2,e3,e4] );
def makeHeartWire(): "make a heart wire" e1 = Wrappers.edgeFromTwoPoints(gp.gp_Pnt(0, 0, 0), gp.gp_Pnt(4.0, 4.0, 0)) circle = gp.gp_Circ(gp.gp_Ax2(gp.gp_Pnt(2, 4, 0), gp.gp().DZ()), 2) e2 = BRepBuilderAPI.BRepBuilderAPI_MakeEdge(circle, gp.gp_Pnt(4, 4, 0), gp.gp_Pnt(0, 4, 0)).Edge() circle = gp.gp_Circ(gp.gp_Ax2(gp.gp_Pnt(-2, 4, 0), gp.gp().DZ()), 2) e3 = BRepBuilderAPI.BRepBuilderAPI_MakeEdge(circle, gp.gp_Pnt(0, 4, 0), gp.gp_Pnt(-4, 4, 0)).Edge() e4 = Wrappers.edgeFromTwoPoints(gp.gp_Pnt(-4, 4, 0), gp.gp_Pnt(0, 0, 0)) return Wrappers.wireFromEdges([e1, e2, e3, e4])
def _makeHatchLines(self): "make straight hatch lines." xMin = self.bounds[0] - (self.HATCH_PADDING) yMin = self.bounds[1] - (self.HATCH_PADDING) xMax = self.bounds[2] + (self.HATCH_PADDING) yMax = self.bounds[3] + (self.HATCH_PADDING) wires = [] for y in Wrappers.frange6(yMin, yMax, 0.02): e = Wrappers.edgeFromTwoPoints(gp.gp_Pnt(xMin, y, self.zLevel), gp.gp_Pnt(xMax, y, self.zLevel)) #display.DisplayShape(e); wires.append(Wrappers.wireFromEdges([e])) return wires
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
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;
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 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 testWirePixmap2(face): """ tests drawing a wire while adjusting sharp borders """ PIXEL = 0.01 ; DEFLECTION = PIXEL / 4.0; #get bounding box (xMin,yMin,zMin,xMax,yMax,zMax) = boundingBox([face]); g = nx.Graph(); #adjust boundaries a bit BUFFER=PIXEL*5; #make pixmap pixmap = pixmaptest.pixmap((xMin-BUFFER,yMin-BUFFER),(xMax+BUFFER,yMax+BUFFER),PIXEL); ow = brt.OuterWire(face); boundary = tuplesFromWire(ow,DEFLECTION); for et in Wrappers.pairwise(boundary): p1 = et[0]; p2 = et[1]; g.add_edge(p1,p2); i1 = pixmap.index(p1); i2 = pixmap.index(p2); #print i1,i2,p1,p2 pixmap.drawLine(p1,p2,1,2); pixmap.saveImage("c:\\temp\\thickboundary.jpg");
def testSplitWire1(): """ Test split wire function. there are two main cases: wires with intersection on different edges, and a wire with a single edge split in many places """ #case 1: a single edge with lots of intersections along its length e = OCCUtil.edgeFromTwoPoints( gp.gp_Pnt(0,0,0),gp.gp_Pnt(5,0,0)); w = OCCUtil.wireFromEdges([e]); #out of order on purpose p1 = PointOnAnEdge(e,1.0,gp.gp_Pnt(1.0,0,0)); p3 = PointOnAnEdge(e,3.0,gp.gp_Pnt(3.0,0,0)); p2 = PointOnAnEdge(e,2.0,gp.gp_Pnt(2.0,0,0)); p4 = PointOnAnEdge(e,4.0,gp.gp_Pnt(4.0,0,0)); ee = splitWire(w,[p1,p3,p2,p4] ); assert len(ee) == 2; length = 0; for e in ee: ew = Wrappers.Edge(e[0]); length += ew.distanceBetweenEnds(); assert length == 2.0;
def displayPixelGrid(pixelGrid): "show all the points in a pixel grid" l = []; for k in pixelGrid.keys(): l.append(Wrappers.make_vertex(gp.gp_Pnt(k[0],k[1],0.00))); display.DisplayShape(l);
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 divideEdge(self,edge,param): """ split the edge at the provided parameter, creating two new edge nodes. update internal structures accordingly. """ original = self.findEdge(edge,param); if original == None: raise ValueError,"Could not find edge having parameter %0.3f" % (param); #param must be between the bounds on the original edge assert param >= original.p1 and param <= original.p2; #compute nodes on either end. n1 = tP(original.firstPoint); n2 = tP(original.lastPoint); #add new node and edges n3 = tP( Wrappers.pointAtParameter(edge,param)); newNode1 = EdgeSegment(edge,original.p1,param,original.type); newNode2 = EdgeSegment(edge,param,original.p2, original.type ); self.addEdgeSegment(newNode1); self.addEdgeSegment(newNode2); #delete the original self.removeEdge(original); return [newNode1,newNode2];
def addEdge(self,edge,type): "adds an edgeto the structure, using the endpoints of the edge as the nodes" "this is equivalent to adding an edgesegment that spans the full edge" ew = Wrappers.Edge(edge); newEdge = EdgeSegment(ew,ew.firstParameter,ew.lastParameter,type); self.addEdgeSegment(newEdge);
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 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);
def __init__(self, shape, options): self.solid = Wrappers.Solid(shape) self.slices = [] #a list of slices self.sliceMap = {} #distinct slices. different because some slices are re-used instead of calculated again self.options = options self.__setDefaultOptions() self.extruder = Extruder(options) #note: make sure to fix the shape before translating! if options.fixShape: self.solid.fixDefects() if options.translateToPositiveCenter: self.solid = self.solid.translateToPositiveCenter( options.tableCenterX, options.tableCenterY) #now apply slicing limits, if the user specified them #warning, it is confusing if the user specifies these, and specifies translate=true, how do they know where zMin and zMax will be? if options.zMin == None: options.zMin = self.solid.zMin if options.zMax == None: options.zMax = self.solid.zMax
def displayPixelGrid(pixelGrid): "show all the points in a pixel grid" l = [] for k in pixelGrid.keys(): l.append(Wrappers.make_vertex(gp.gp_Pnt(k[0], k[1], 0.00))) display.DisplayShape(l)
def testWirePixmap2(face): """ tests drawing a wire while adjusting sharp borders """ PIXEL = 0.01 DEFLECTION = PIXEL / 4.0 #get bounding box (xMin, yMin, zMin, xMax, yMax, zMax) = boundingBox([face]) g = nx.Graph() #adjust boundaries a bit BUFFER = PIXEL * 5 #make pixmap pixmap = pixmaptest.pixmap((xMin - BUFFER, yMin - BUFFER), (xMax + BUFFER, yMax + BUFFER), PIXEL) ow = brt.OuterWire(face) boundary = tuplesFromWire(ow, DEFLECTION) for et in Wrappers.pairwise(boundary): p1 = et[0] p2 = et[1] g.add_edge(p1, p2) i1 = pixmap.index(p1) i2 = pixmap.index(p2) #print i1,i2,p1,p2 pixmap.drawLine(p1, p2, 1, 2) pixmap.saveImage("c:\\temp\\thickboundary.jpg")
def __init__(self, edge, p1, p2, type): "edge is a ref to an edge, with the beginning and ending parameters" "for the underlying curve" self.edge = edge self.ew = Wrappers.Edge(edge) self.p1 = p1 self.p2 = p2 self.type = type
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 = OCCUtil.cast(eS.Value(i)); self.addSingleBoundaryEdge(e);
def buildGraph(self): g = self.graph; #add fill edge nodes first for e in self.fillEdges: g.add_edge(e[0], e[1], {"type":'FILL', "edgeList":e[2]}); #add boundary nodes. for (edge, pointList ) in self.boundaryEdges.iteritems(): #sort the points by parameter sortedPoints = sorted(pointList,key = lambda p: p.param ); for (poe1,poe2) in Wrappers.pairwise(sortedPoints): #dont add if there is already an edge if not g.has_edge(poe1.node,poe2.node): #here we need to trim each edge to limit it to the desired parameters g.add_edge(poe1.node,poe2.node,{"type":"BOUND", "edge": Wrappers.trimmedEdge(edge,poe1.param,poe2.param)});
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 makeFillEdges2d(xMin, yMin, xMax, yMax, spacing): "make straight hatch lines." edges = [] for y in Wrappers.frange6(yMin, yMax, spacing): e = edgeFromTwoPoints((xMin, y), (xMax, y)) # TestDisplay.display.showShape(e); edges.append(e) return edges
def makeFillEdges2d(xMin, yMin, xMax, yMax, spacing): "make straight hatch lines." edges = [] for y in Wrappers.frange6(yMin, yMax, spacing): e = edgeFromTwoPoints((xMin, y), (xMax, y)) #TestDisplay.display.showShape(e); edges.append(e) return edges
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;
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
def displayGraph(graph): "display an networkx graph" "this is just a hack-- the tuples are in integer coordinates, and this will be terribly slow" for e in graph.edges_iter(): try: TestDisplay.display.showShape(Wrappers.edgeFromTwoPoints(pnt(e[0]),pnt(e[1]))); except: pass;
def makeFillCurves2d(xMin, yMin, xMax, yMax, spacing): """ makes a set of lines that are curves not edges probably the minimal possible construction """ lines = [] for y in Wrappers.frange6(yMin, yMax, spacing): l = GCE2d.GCE2d_MakeSegment(tP(xMin, y), tP(xMax, y)).Value() lines.append(l) return lines
def displayGraph(graph): "display an networkx graph" "this is just a hack-- the tuples are in integer coordinates, and this will be terribly slow" for e in graph.edges_iter(): try: TestDisplay.display.showShape( Wrappers.edgeFromTwoPoints(pnt(e[0]), pnt(e[1]))) except: pass
def computeLayerPath(self, slice): "computes paths for a single layer" pe = PathExport.ShapeDraw(True, 0.001) path = [] allShapes = TopTools.TopTools_HSequenceOfShape() Wrappers.extendhSeq(allShapes, slice.fillWires) Wrappers.extendhSeq(allShapes, slice.fillEdges) for move in pe.follow(allShapes): moveType = move.__class__.__name__ if moveType == "LinearMove": path.append(self.linearMove(move)) elif moveType == "ArcMove": path.append(self.arcMove(move)) else: raise ValueError, "Unknown Move Type!" return "\n".join(path)
def __init__(self,edge,p1,p2,type): "edge is a ref to an edge, with the beginning and ending parameters" "for the underlying curve" self.edge = edge; self.p1 = p1; self.p2 = p2; self.type =type; #todo, this can be optimized, the underlying curve is computed twice here. [self.firstPoint, self.lastPoint] = Wrappers.pointAtParameterList(edge, [self.p1,self.p2] );
def __init__(self, edge, p1, p2, type): "edge is a ref to an edge, with the beginning and ending parameters" "for the underlying curve" self.edge = edge self.p1 = p1 self.p2 = p2 self.type = type #todo, this can be optimized, the underlying curve is computed twice here. [self.firstPoint, self.lastPoint ] = Wrappers.pointAtParameterList(edge, [self.p1, self.p2])
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 displayAllEdgesAndVertices(g): i = 0 for en in g.edges_iter(data=True): i += 1 displayEdgeFromGraph(en[2]) print "%d edges total" % i i = 0 for n in g.nodes_iter(): i += 1 p = gp.gp_Pnt(n[0], n[1], 0) display.DisplayShape(Wrappers.make_vertex(p), update=False) print "%d nodes total" % i
def makeEdgeIndicator(edge): "makes an indicator showing which way the edge goes" ew = Wrappers.Edge(edge); fp = ew.firstParameter; lp = ew.lastParameter; if ew.reversed: p = fp + (( lp - fp ) * 1 / 5 ); else: p = fp + ((lp - fp) * 4 /5 ); midPnt = ew.curve.Value(p); return Wrappers.make_vertex(midPnt);
def makeHeartWire2d(): "make a heart wire in 2d" e1 = edgeFromTwoPoints((0, 0), (4.0, 4.0)) 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() circle = gp.gp_Circ2d(gp.gp_Ax2d(tP(-2, 4), gp.gp().DX2d()), 2) e3 = BRepBuilderAPI.BRepBuilderAPI_MakeEdge2d(circle, tP(0, 4), tP(-4, 4)).Edge() e4 = edgeFromTwoPoints((-4, 4), (0, 0)) return Wrappers.wireFromEdges([e1, e2, e3, e4])
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 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[60]); 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,2): 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 = None; for i in range(1,2): ee = splitWire(w,[p2,p1]); print "Elapsed for 100splits:",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 follow(self,shapeList, finish=True): "a generator that returns a list of moves that navigates the list of shapes" "if finish is true, any pending move will be finished. If false," "pending linear moves are left in case next moves duplicate them" log.debug("Following Shape"); for s in Wrappers.hSeqIterator(shapeList): for m in self.followShape(s): yield m; #flush any last remaining move if finish: t= self._fetchPendingMove(); if t: yield t;
def __init__(self,edge,p1,p2,type): "edge is a ref to an edge, with the beginning and ending parameters" "for the underlying curve" self.edge = edge; self.p1 = p1; self.p2 = p2; self.type =type; self.hash = self.edge.__hash__(); #precompute to save time self.myKey = ( self.hash,self.p1, self.p2); #todo, this can be optimized, the underlying curve is computed twice here. [self.firstPoint, self.lastPoint] = Wrappers.pointAtParameterList(edge, [self.p1,self.p2] );
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 __init__(self, edge, p1, p2, type): "edge is a ref to an edge, with the beginning and ending parameters" "for the underlying curve" self.edge = edge self.p1 = p1 self.p2 = p2 self.type = type self.hash = self.edge.__hash__() # precompute to save time self.myKey = (self.hash, self.p1, self.p2) # todo, this can be optimized, the underlying curve is computed twice here. [self.firstPoint, self.lastPoint] = Wrappers.pointAtParameterList(edge, [self.p1, self.p2])
def __init__(self, edge, p1, p2, type): "edge is a ref to an edge, with the beginning and ending parameters" "for the underlying curve" self.edge = edge self.ew = Wrappers.Edge(edge) self.p1 = p1 self.p2 = p2 self.type = type #next is edges reachable from the end of the edge self.next = {} #prev is the edges reachable from the beginning of the edge self.prev = {}
def addEdgeListAsSingleEdge(self, edgeList, etype): """ adds a list of edges in the graph as a single edge. The list of edges becomes a 'pseudo-edge' with a single start and endpoint. The edge cannot be divided, and its vertices are not stored in the edge graph """ # TODO: adding this method has broken the EdgeSegment intervace. # what is needed is an object that exposes first and last point, and a container for the underlying object # an edgesegment ( a portion of an edge between two parameters ), a full edge ( requring no trimming ), # and a gropu of edges combined are all special subcases. firstEdge = edgeList[0] lastEdge = edgeList[-1] (f, l) = brepTool.Range(firstEdge) (n, m) = brepTool.Range(lastEdge) # todo, this can be optimized, the underlying curve is computed twice here. # something very odd is happening here. whey does using the last parameter and first paraterm # work ? initially i had them backewards, which should have worked, but opposites worked. # wierd. do i need to account for the sense? # maybe i should just use wrappers.edge here if firstEdge.Orientation() == TopAbs.TopAbs_FORWARD: p1 = tP(Wrappers.pointAtParameter(firstEdge, f)) else: p1 = tP(Wrappers.pointAtParameter(firstEdge, l)) if lastEdge.Orientation() == TopAbs.TopAbs_FORWARD: p2 = tP(Wrappers.pointAtParameter(lastEdge, m)) else: p2 = tP(Wrappers.pointAtParameter(lastEdge, n)) # todo, i dont think we care about this key do we, as long as it is unique? self.g.add_edge(p1, p2, {"edgeList": edgeList, "type": etype}) if etype == "FILL": self.fillEdges.append((p1, p2))
def approximatedWire(wire): "returns a bezier approximation of the specified wire as an edge" #make a parameterized approximation of the wire adaptor = BRepAdaptor.BRepAdaptor_CompCurve (wire); curve = BRepAdaptor.BRepAdaptor_HCompCurve(adaptor); curveHandle = curve.GetHandle(); #approximate the curve using a tolerance approx = Approx.Approx_Curve3d(curveHandle,0.01,GeomAbs.GeomAbs_C2,1000,8); if approx.IsDone() and approx.HasResult(): # have the result anApproximatedCurve=approx.Curve(); builder = BRepLib.BRepLib_MakeEdge(anApproximatedCurve); e = builder.Edge(); return Wrappers.wireFromEdges([e]);
def testHugePixmap(face): """ tests drawing a wire while adjusting sharp borders """ PIXEL = 0.005 ; DEFLECTION = PIXEL / 2.0; #get bounding box (xMin,yMin,zMin,xMax,yMax,zMax) = boundingBox([face]); g = nx.Graph(); #adjust boundaries a bit BUFFER=PIXEL*5; #make pixmap pixmap = pixmaptest.pixmap((xMin-BUFFER,yMin-BUFFER),(xMax+BUFFER,yMax+BUFFER),PIXEL); ow = brt.OuterWire(face); boundary = tuplesFromWire(ow,DEFLECTION); for et in Wrappers.pairwise(boundary): p1 = et[0]; p2 = et[1]; g.add_edge(p1,p2); i1 = pixmap.index(p1); i2 = pixmap.index(p2); #print i1,i2,p1,p2 pixmap.drawLine(p1,p2,1,2); #now, lets see how long it takes to find the intersection of a line by painting on the pixmap q = time.clock(); p1 = ( -4.0,2.0 ) p2 = ( 4.0, 2.0 ) results = pixmap.drawLine2(p1,p2 ) print results print "Found Intersections in %0.3f seconds" % ( time.clock() - q ); #how fast is it to determine if a point is on the face? q = time.clock() p1 = ( -0.5,2.0) for i in range(1,1000): pixmap.get(p1) print "Tested 1000 points in %0.3f seconds" % ( time.clock() - q ); pixmap.saveImage( "c:\\temp\scanline.jpg" );
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;