def drillWithHolesFaster(shape): "returns a shape with a bunch of spheres removed from it" box = Bnd.Bnd_Box() b = BRepBndLib.BRepBndLib() b.Add(shape, box) (xMin, yMin, zMin, xMax, yMax, zMax) = box.Get() d = 0.05 * ((xMax - xMin)) di = 3.0 * d vec = gp.gp_Vec(gp.gp_Pnt(0, 0, 0), gp.gp_Pnt(0, 0, d)) cp = None compound = TopoDS.TopoDS_Compound() builder = BRep.BRep_Builder() builder.MakeCompound(compound) #drill holes in a rectangular grid for x in frange6(xMin, xMax, di): for y in frange6(yMin, yMax, di): for z in frange6(zMin, zMax, di): #make a sphere center = gp.gp_Pnt(x, y, z) hole = BRepPrimAPI.BRepPrimAPI_MakeSphere(center, d).Shape() #lets see if a square hole is faster! #w = squareWire(center,d ); #hb = BRepPrimAPI.BRepPrimAPI_MakePrism(w,vec,False,True); #hb.Build(); #hole = hb.Shape(); builder.Add(compound, hole) display.DisplayShape(compound) q = time.clock() cut = BRepAlgoAPI.BRepAlgoAPI_Cut(shape, compound) if cut.ErrorStatus() == 0: print "Cut Took %0.3f sec." % (time.clock() - q) return cut.Shape() else: print "Error Cutting: %d" % cut.ErrorStatus() return shape
def compound(self): """ Create and returns a compound from the _shapes list Returns ------- TopoDS.TopoDS_Compound Notes ----- Importing an iges box results in: 0 solid 0 shell 6 faces 24 edges """ # Create a compound compound = TopoDS.TopoDS_Compound() brep_builder = BRep.BRep_Builder() brep_builder.MakeCompound(compound) # Populate the compound for shape in self._shapes: brep_builder.Add(compound, shape) return compound
def execute(self): input_shape = self.input.shape topo = Topo(input_shape) self._n_edges = topo.number_of_edges() builder = BRepFilletAPI.BRepFilletAPI_MakeChamfer(input_shape) Map = TDF.TDF_LabelMap() itr = TDF.TDF_ChildIterator(self.parent_label, True) while itr.More(): sub_label = itr.Value() Map.Add(sub_label) itr.Next() selector = self.selector ret = selector.Solve(Map) if not ret: raise Exception("Failed to solve for edge") #print "Failed to solve for edge" nt = TNaming.TNaming_Tool() selected_shape = nt.CurrentShape(selector.NamedShape()) selected_edge = TopoDS.TopoDS().Edge(selected_shape) try: face = Topo(input_shape).faces_from_edge(selected_edge).next() except RuntimeError: raise #not sure how to handle this size = self.size builder.Add(size, size, selected_edge, face) self.update_naming(builder) return builder.Shape()
DEFAULT_FEEDRATE = 1.0; DEFAULT_DEFLECTION=0.001; OMIT_UNCHANGED_AXES=False; TOLERANCE=0.00001; ##### #utility class instances #available to all methods ##### #Brep_Tools = BRepTools.BRepTools(); Brep_Tool = BRep.BRep_Tool(); BRepLProp_CurveTool = BRepLProp.BRepLProp_CurveTool(); #TopoDS = TopoDS.TopoDS(); #TopExp = TopExp.TopExp() #TopExp_Explorer = TopExp.TopExp_Explorer(); ts = TopoDS.TopoDS(); def close(x,y): if x == None or y == None: return False; return abs(x - y ) < TOLERANCE; def printPoint(point): return "x=%0.4f,y=%0.4f,z=%0.4f" % (point.X(), point.Y(), point.Z()); """ State machine for creating gcode. This class will track the current position, which makes it easier to move along a particular path.
def extrusion(event=None): # # Make a box # Box = BRepPrimAPI_MakeBox(400.,250.,300.) S = Box.Shape() # # Choose the first Face of the box # Ex = TopExp_Explorer() Ex.Init(S,TopAbs_FACE) Ex.Next() F = TopoDS.TopoDS_face(Ex.Current()) surf = BRep_Tool_Surface(F) # # Make a plane from this face # Pl = Handle_Geom_Plane_DownCast(surf) Pln = Pl.GetObject() # # Get the normal of this plane. This will be the direction of extrusion. # D = Pln.Axis().Direction() # # Inverse normal # D.Reverse() # # Create the 2D planar sketch # MW = BRepBuilderAPI_MakeWire() p1 = gp_Pnt2d(200.,-100.) p2 = gp_Pnt2d(100.,-100.) aline = GCE2d_MakeLine(p1,p2).Value() Edge1 = BRepBuilderAPI_MakeEdge(aline,surf,0.,p1.Distance(p2)) MW.Add(Edge1.Edge()) p1 = p2 p2 = gp_Pnt2d(100.,-200.) aline = GCE2d_MakeLine(p1,p2).Value() Edge2 = BRepBuilderAPI_MakeEdge(aline,surf,0.,p1.Distance(p2)) MW.Add(Edge2.Edge()) p1 = p2 p2 = gp_Pnt2d(200.,-200.) aline = GCE2d_MakeLine(p1,p2).Value() Edge3 = BRepBuilderAPI_MakeEdge(aline,surf,0.,p1.Distance(p2)) MW.Add(Edge3.Edge()) p1 = p2 p2 = gp_Pnt2d(200.,-100.) aline = GCE2d_MakeLine(p1,p2).Value() Edge4 = BRepBuilderAPI_MakeEdge(aline,surf,0.,p1.Distance(p2)) MW.Add(Edge4.Edge()) # # Build Face from Wire. NB: a face is required to generate a solid. # MKF = BRepBuilderAPI_MakeFace() MKF.Init(surf,False, 1e-6) MKF.Add(MW.Wire()) FP = MKF.Face() BRepLib_BuildCurves3d(FP) MKP = BRepFeat_MakePrism(S,FP,F,D,0,True) MKP.Perform(200.) res1 = MKP.Shape() display.EraseAll() display.DisplayColoredShape(res1,'BLUE')
def read_file(self): r"""Read the STL file and stores the result in a TopoDS_Shape""" stl_reader = StlAPI.StlAPI_Reader() shape = TopoDS.TopoDS_Shape() stl_reader.Read(shape, self._filename) self._shape = shape
""" EdgeGraphs Utilties for representing wires and lists of edges in a graph. """ from OCC import BRep, gp, GeomAbs, GeomAPI, GCPnts, TopoDS, BRepTools, GeomAdaptor, TopAbs, TopTools, TopExp from OCC import BRepGProp, BRepLProp, BRepBuilderAPI, BRepPrimAPI, GeomAdaptor, GeomAbs, BRepClass, GCPnts, BRepBuilderAPI, BRepOffsetAPI, BRepAdaptor import time, os, sys, string, logging from OCC.Geom import * brepTool = BRep.BRep_Tool() topoDS = TopoDS.TopoDS() import TestDisplay import itertools import Wrappers import time def hashE(edge): return edge.HashCode(1000000) "an edge in a connected set of edges." class EdgeNode: "an edge node from an edge wrapper" def __init__(self, edgeWrapper, type):
from OCC import TopExp, BRepPrimAPI, TopAbs, TopoDS box = BRepPrimAPI.BRepPrimAPI_MakeBox(10., 20., 30.) ex = TopExp.TopExp_Explorer(box.Shape(), TopAbs.TopAbs_EDGE) results = [] while ex.More(): shape = TopoDS.TopoDS().Edge(ex.Current()) print "is null?", bool(shape.IsNull()) results.append(shape) ex.Next() ex.ReInit() for edge in results: print "null now?", bool(edge.IsNull())
def copy(shape): """Return a copy of the shape that does not reference the original shape""" new = BRepAlgoAPI.BRepAlgoAPI_Common(shape, cube).Shape() comp = TopoDS.TopoDS_Compound(new) return subshapes(comp, shape.ShapeType())[0]
from OCC.Display.SimpleGui import * from OCC import BRep from OCC.BRepTools import * from OCC import TopoDS from OCC.Message import Message_PrinterOStream import sys fileName = 'input.brp' if (len(sys.argv) > 1): fileName = sys.argv[1] brep_instance = BRepTools() shape = TopoDS.TopoDS_Shape() builder = BRep.BRep_Builder() printrerStream = Message_PrinterOStream() s = printrerStream.GetStream() brep_instance.Read(shape, str(fileName), builder)
def read_file(self): r"""Read the BREP file and stores the result in a TopoDS_Shape""" shape = TopoDS.TopoDS_Shape() builder = BRep.BRep_Builder() BRepTools.breptools_Read(shape, self._filename, builder) self._shape = shape
print "testWire2 is not closed." TOLERANCE = 0.00001 curve = BRepAdaptor.BRepAdaptor_CompCurve(testWire) print "CompCurve is parameterized between %0.5f and %0.5f " % ( curve.FirstParameter(), curve.LastParameter()) print "%d Continuity" % curve.Continuity() print "%d Intervals(C0)" % curve.NbIntervals(0) print "%d Intervals(C1)" % curve.NbIntervals(1) print "%d Intervals(C2)" % curve.NbIntervals(2) 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)
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. """ q = time.clock() hatchWires = self._makeHatchLines() numCompares = 0 bbuilder = BRep.BRep_Builder() comp = TopoDS.TopoDS_Compound() bbuilder.MakeCompound(comp) #print "Time to Make hatch Lines: %0.3f" % ( time.clock() - q ) for b in self.boundaryWires: bbuilder.Add(comp, b) self.graphBuilder.addBoundaryWire(b) #print "There are %d boundary wires, %d hatch wires" % ( len(self.boundaryWires),len(hatchWires) ) #intersect each line with each boundary brp = BRepExtrema.BRepExtrema_DistShapeShape() brp.LoadS1(comp) for hatchLine in hatchWires: interSections = [] #list of intersections for just this single hatch line closePoints = [] #extrema that are not intersectionsf or this single hatch line 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, distance = %0.6f" % brp.Value() #TODO need to handle the somewhat unusual cases that the intersection is #on a vertex for k in range(1, brp.NbSolution() + 1): if brp.Value( ) < 0.001: #there is at least one intersection on this wire. there may also be extrema #print "spot on match" #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 OCCUtil.isEdgeLocalMinimum( OCCUtil.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( OCCUtil.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 = OCCUtil.cast(brp.SupportOnShape1(k)) #otherwise, vertex was not a local minimum, or was on an edge poe = eg.PointOnAnEdge( OCCUtil.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 #print "intersection is close"; #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))) if len(interSections) % 2 == 1: print "Detected Odd Number of intersection points. This is ignored for now." continue if len(interSections) == 0: #print "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(cp[0].edge ); #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; print "%d Total Intersections computed." % (numCompares) self.graphBuilder.buildGraph()
def _readSTL(self, inputFileName): ts = TopoDS.TopoDS() shape = TopoDS.TopoDS_Shape() stl_reader = StlAPI.StlAPI_Reader() stl_reader.Read(shape, inputFileName) return shape