def build(self): wire = self.request.wire topoWire = Topo(wire) #get all the vertices for the wire #these are sorted by ascending distance choices = OCCUtil.nearestVertices([wire], self.request.startPoint, MAX_DISTANCE) #print "There are %d choices" % len(choices); bestSolution = None for (wire, vertex, point, distance) in choices: #print "vertex: distance %0.3f" % distance; sol = JoinAtVertex(self.request, vertex).compute() if distance < self.tolerance: #compute a joint solution based on this vertex if bestSolution is None: bestSolution = sol elif sol.isBetterThan(bestSolution): #print "switching solution to another vertex!" bestSolution = sol else: #all of the points below this one will be even less attractive, and #entry angle doesnt matter because we'll probably rapid there. Thus, #simply choose the next one if bestSolution: break else: sol.isJoint = False bestSolution = sol #at this point we have the best solution, which is either a joint to a vertex #with the best combination of angles, or we have a move to then nearest vertex bestSolution.buildWire() return bestSolution
def build(self): topoWire = Topo(self.wire) #compute closest point on the wire brp = BRepExtrema.BRepExtrema_DistShapeShape() brp.LoadS1(OCCUtil.make_vertex(self.startPoint)) brp.LoadS2(self.wire) result = brp.Perform() p1 = brp.PointOnShape2(1) wb = OCCUtil.WireBuilder() closestParam = None if brp.SupportTypeShape2(1) == BRepExtrema.BRepExtrema_IsOnEdge: #closest point is a point along an edge interSectingEdge = OCCUtil.cast(brp.SupportOnShape2(1)) closestParam = brp.ParOnEdgeS2(1) else: #closest point is a point on a vertex, here we'll shorten one edge #in this case closest point is a vertex, so we dont have a param on an edge vertex = OCCUtil.cast(brp.SupportOnShape2(1)) edges = [] for e in topoWire.edges_from_vertex(vertex): edges.append(e) interSectingEdge = edges[0] #compute parameter along one curve #break the edge into two new edges. account for a split distance between them. ej = EdgeJoin(interSectingEdge, self.startPoint, self.trackWidth, closestParam) #add lead-in edges for e in ej.connectingEdges: wb.add(e) #now add all of the other edges in the wire except the original one that we split for e in topoWire.edges(): if not e.IsSame(interSectingEdge): wb.add(e) for e in ej.otherEdges: wb.add(e) return wb.wire()
def build(self): topoWire = Topo(self.wire); #compute closest point on the wire brp = BRepExtrema.BRepExtrema_DistShapeShape(); brp.LoadS1(OCCUtil.make_vertex(self.startPoint)); brp.LoadS2(self.wire); result = brp.Perform(); p1 = brp.PointOnShape2(1); wb = OCCUtil.WireBuilder(); closestParam = None; if brp.SupportTypeShape2(1) == BRepExtrema.BRepExtrema_IsOnEdge: #closest point is a point along an edge interSectingEdge = OCCUtil.cast(brp.SupportOnShape2(1)); closestParam = brp.ParOnEdgeS2(1); else: #closest point is a point on a vertex, here we'll shorten one edge #in this case closest point is a vertex, so we dont have a param on an edge vertex = OCCUtil.cast(brp.SupportOnShape2(1)); edges = []; for e in topoWire.edges_from_vertex(vertex): edges.append(e); interSectingEdge = edges[0]; #compute parameter along one curve #break the edge into two new edges. account for a split distance between them. ej = EdgeJoin(interSectingEdge,self.startPoint,self.trackWidth ,closestParam); #add lead-in edges for e in ej.connectingEdges: wb.add(e); #now add all of the other edges in the wire except the original one that we split for e in topoWire.edges(): if not e.IsSame(interSectingEdge): wb.add(e); for e in ej.otherEdges: wb.add(e); return wb.wire();
def buildWire(self): # simply do the work of the trimming and construction. wB = OCCUtil.WireBuilder() wire = self.jointRequest.wire tw = Topo(wire) edgeToTrim = self.pointOnEdge.edge # shorten the selected edge # TODO: maybe simplify this to return pointOnEdge? (self.trimmedEdge, self.trimmedPoint, self.trimmedVec) = OCCUtil.shortenEdge( edgeToTrim, self.pointOnEdge.point, self.trimDistance ) wB.add(self.trimmedEdge) # add the edges we didnt touch for e in tw.edges(): if not e.IsSame(edgeToTrim): wB.add(e) self.wire = wB.wire()
def buildWire(self): #simply do the work of the trimming and construction. wB = OCCUtil.WireBuilder() wire = self.jointRequest.wire tw = Topo(wire) edgeToTrim = self.pointOnEdge.edge #shorten the selected edge #TODO: maybe simplify this to return pointOnEdge? (self.trimmedEdge, self.trimmedPoint, self.trimmedVec) = OCCUtil.shortenEdge(edgeToTrim, self.pointOnEdge.point, self.trimDistance) wB.add(self.trimmedEdge) #add the edges we didnt touch for e in tw.edges(): if not e.IsSame(edgeToTrim): wB.add(e) self.wire = wB.wire()
def makeExtrusionWire( shellWire, startPoint, trackWidth): topoWire = Topo(shellWire); #compute closest point on the wire brp = BRepExtrema.BRepExtrema_DistShapeShape(); brp.LoadS1(OCCUtil.make_vertex(startPoint)); brp.LoadS2(shellWire); result = brp.Perform(); p1 = brp.PointOnShape2(1); wb = WireBuilder(); #make an edge from start point to located point. #wb.add ( OCCUtil.edgeFromTwoPoints(startPoint, p1 ) ); dist = p1.Distance(p2) if brp.SupportTypeShape2(1) == BRepExtrema.BRepExtrema_IsOnEdge: #closest point is a point along an edge interSectingEdge = OCCUtil.cast(brp.SupportOnShape2(1)); p = brp.ParOnEdgeS2(1); #compute parameter along one curve #break the edge into two new edges. account for a split distance between them. (e1,e2)= OCCUtil.splitEdge(interSectingEdge,p); wb.add(e1); #add second one shortened, on the end near the vertex wb.add ( OCCUtil.shortenEdge(e2,p1,trackWidth)); #hack, must find parameter closest to this end #now add all of the other edges in the wire except the original one that we split for e in topoWire.edges(): if not e.IsSame(interSectingEdge): wb.add(e); else: #closest point is a point on a vertex, here we'll shorten one edge # vertex = OCCUtil.cast(brp.SupportOnShape2(1)); edges = []; for e in topoWire.edges_from_vertex(vertex): edges.append(e); #shorten one, leave other intact #try to handle case where vertex is at end of a wire ( ie a non-closed wire ) e1 = edges[0]; wb.add( edges[0]); e2 = None; if len(edges) > 1: e2 = edges[1]; e3 = OCCUtil.shortenEdge(e2,p1,trackWidth); #hack-- find edges closest to this end #display.DisplayColoredShape(e3,'BLUE') wb.add ( e3); for e in topoWire.edges(): if e.IsSame(e1): continue; if e2 and e.IsSame(e2): continue; wb.add ( e ); return wb.wire();
return wb.wire(); if __name__=='__main__': from OCC.Display.SimpleGui import * display, start_display, add_menu, add_function_to_menu = init_display() heart = TestObjects.makeHeartWire(); #p1 = gp.gp_Pnt(0.0,-0.5,0.0); p1 = gp.gp_Pnt(2.1,1.5,0.0); v1 = OCCUtil.make_vertex ( gp.gp_Pnt(2.0,3.1,0.0)); #t = time.clock(); #for i in range(1000): # p2 = distToPoint(heart,v1 ); #print "dist time %0.3f" % ( time.clock() - t ); #about 1.6ms per call for a simple heart wire . not too shabby #v2 = OCCUtil.make_vertex ( p2 ); #display.DisplayShape([heart,v1,v2]); #test splitting a wire newWire= makeExtrusionWire(heart,p1,0.25); display.DisplayColoredShape(heart, 'WHITE') display.DisplayColoredShape(newWire, 'GREEN'); print "Total Edges %d" % Topo(newWire).number_of_edges() start_display();
def compute(self): tw = Topo(self.request.wire) eL = list(tw.edges_from_vertex(self.vertex)) if len(eL) > 2: raise Exception("Cannot trim wire at vertex with more than two edges") if len(eL) == 0: raise Exception("Vertex has no edges, cannot trim") allVertices = list(tw.vertices()) # only one edge accessible from this vertex if len(eL) == 1: edgeWrapper = Wrappers.Edge(eL[0]) pointObj = edgeWrapper.getPointAtVertex(self.vertex) self.solution = JointSolution(self.request, pointObj) self.solution.trimDistance = self.request.trackWidth # for a single edge, simply trim the path width return self.solution # else len(eL) == 2. this is the most common case. (edge1, edge2) = eL[:2] edgeWrapper1 = Wrappers.Edge(eL[0]) edgeWrapper2 = Wrappers.Edge(eL[1]) # compute solutions using both edges pointOnEdge1 = edgeWrapper1.getPointAtVertex(self.vertex) pointOnEdge2 = edgeWrapper2.getPointAtVertex(self.vertex) solution1 = JointSolution(self.request, pointOnEdge1) solution2 = JointSolution(self.request, pointOnEdge2) # choose the solution that is best. ideally, we want wide angles, # remember, these are direction vectors, so small angles means 'same direction' which is good, # while pi ( 180 ) angles are bad, becaues the paths switch back onto themselves. if solution1.isBetterThan(solution2): self.solution = solution1 else: self.solution = solution2 # compute the trim distance, which is based on the angles between the edges # edges with vectors pi apart overlap, and 0 degrees are aligned # TODO: this assumes all angles are between zero and 2pi angleAtVertex = pointOnEdge1.vector.Angle(pointOnEdge2.vector) angleDiff = abs(math.pi - angleAtVertex) trimWidth = self.request.trackWidth if angleDiff < 0.1: # print "Trimmed Wire: two edges are very close to each other!" # TODO: here, if one of the edges is a curve we can re-evaluate along the curve # to find a better location. If the cuves are lines, the two should be removed. # for now, though, we'll handle this in the shortening routine, which will # essentially never allow replacing an entire edge trimDistance = trimWidth * 5.0 elif angleDiff < (math.pi / 2): # print "Trimmed Wire based on sin rule" trimDistance = trimWidth / 2 * (1 + (1 / math.sin(angleAtVertex))) else: # print "No Trim was necessary" trimDistance = trimWidth / 2 solution1.trimDistance = trimDistance solution2.trimDistance = trimDistance if self.solution is None: raise Exception("No solution selected, this should not ever occur.") return self.solution
def compute(self): tw = Topo(self.request.wire) eL = list(tw.edges_from_vertex(self.vertex)) if len(eL) > 2: raise Exception( "Cannot trim wire at vertex with more than two edges") if len(eL) == 0: raise Exception("Vertex has no edges, cannot trim") allVertices = list(tw.vertices()) #only one edge accessible from this vertex if len(eL) == 1: edgeWrapper = Wrappers.Edge(eL[0]) pointObj = edgeWrapper.getPointAtVertex(self.vertex) self.solution = JointSolution(self.request, pointObj) self.solution.trimDistance = self.request.trackWidth #for a single edge, simply trim the path width return self.solution #else len(eL) == 2. this is the most common case. (edge1, edge2) = eL[:2] edgeWrapper1 = Wrappers.Edge(eL[0]) edgeWrapper2 = Wrappers.Edge(eL[1]) #compute solutions using both edges pointOnEdge1 = edgeWrapper1.getPointAtVertex(self.vertex) pointOnEdge2 = edgeWrapper2.getPointAtVertex(self.vertex) solution1 = JointSolution(self.request, pointOnEdge1) solution2 = JointSolution(self.request, pointOnEdge2) #choose the solution that is best. ideally, we want wide angles, #remember, these are direction vectors, so small angles means 'same direction' which is good, #while pi ( 180 ) angles are bad, becaues the paths switch back onto themselves. if solution1.isBetterThan(solution2): self.solution = solution1 else: self.solution = solution2 #compute the trim distance, which is based on the angles between the edges #edges with vectors pi apart overlap, and 0 degrees are aligned #TODO: this assumes all angles are between zero and 2pi angleAtVertex = pointOnEdge1.vector.Angle(pointOnEdge2.vector) angleDiff = abs(math.pi - angleAtVertex) trimWidth = self.request.trackWidth if angleDiff < 0.1: #print "Trimmed Wire: two edges are very close to each other!" #TODO: here, if one of the edges is a curve we can re-evaluate along the curve #to find a better location. If the cuves are lines, the two should be removed. #for now, though, we'll handle this in the shortening routine, which will #essentially never allow replacing an entire edge trimDistance = trimWidth * 5.0 elif angleDiff < (math.pi / 2): #print "Trimmed Wire based on sin rule" trimDistance = trimWidth / 2 * (1 + (1 / math.sin(angleAtVertex))) else: #print "No Trim was necessary" trimDistance = trimWidth / 2 solution1.trimDistance = trimDistance solution2.trimDistance = trimDistance if self.solution is None: raise Exception( "No solution selected, this should not ever occur.") return self.solution