コード例 #1
0
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)
コード例 #2
0
ファイル: WireJoin.py プロジェクト: k-automation/emcfab
    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()
コード例 #3
0
ファイル: Filling.py プロジェクト: k-automation/emcfab
def distToPoint( wire, vertex):
    brp = BRepExtrema.BRepExtrema_DistShapeShape();
    brp.LoadS1(vertex);
    brp.LoadS2(wire);
    
    result = brp.Perform();
    if result:
        if brp.NbSolution() > 1:
            print "weird, more than one solution"
        
        point = brp.PointOnShape2(1);
        #otherwise, figure out what kind of location we have.
        if brp.SupportTypeShape2(1) == BRepExtrema.BRepExtrema_IsOnEdge:
            #closest point is a point along an edge
            edge = OCCUtil.cast(brp.SupportOnShape2(1));
            parameter = brp.ParOnEdgeS2(1);
            #print "Closest point is on an edge"
        else:
            #closest point is a point on a vertex
            vertex = OCCUtil.cast(brp.SupportOnShape2(1));
            #print "closest point is on vertex"
        
        return point;
コード例 #4
0
ファイル: Filling.py プロジェクト: k-automation/emcfab
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();
コード例 #5
0
ファイル: hatchLib.py プロジェクト: k-automation/emcfab
    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()
コード例 #6
0
ファイル: OccSliceLib2.py プロジェクト: k-automation/emcfab
def computePixelGrid(face, resolution=0.1):
    """
	   makes a pixel grid of a face at the requested resolution."
		A dictionary is used to store the values.
	"""
    box = Bnd.Bnd_Box()
    b = BRepBndLib.BRepBndLib()
    b.Add(face, box)
    TOLERANCE = 5
    bounds = box.Get()
    xMin = bounds[0]
    xMax = bounds[3]
    xDim = abs(xMax - xMin)
    yMin = bounds[1]
    yMax = bounds[4]
    yDim = abs(yMax - yMin)
    zMin = bounds[2]
    pixelTable = {}

    for y in Wrappers.frange6(yMin, yMax, resolution):
        #create a horizontal scan line
        edge = Wrappers.edgeFromTwoPoints(gp.gp_Pnt(xMin - TOLERANCE, y, zMin),
                                          gp.gp_Pnt(xMax + TOLERANCE, y, zMin))

        #get list of wires from the face
        #TODO:// this should be encapsulated by a face abstraction
        wires = []
        ow = brt.OuterWire(face)
        wires.append(ow)
        for w in Topo(face).wires():
            if not w.IsSame(ow):
                wires.append(w)

        #compute intersection points with each wire
        #this is a hack because i know how to make edges from lines
        #but really, it would be better to do 2d here and use
        #Geom2dAPI_InterCurveCurve
        xIntersections = []
        for w in wires:
            #display.DisplayShape(w);
            brp = BRepExtrema.BRepExtrema_DistShapeShape()
            #display.DisplayShape(edge);
            brp.LoadS1(w)
            brp.LoadS2(edge)

            if brp.Perform() and brp.Value() < 0.01:
                for k in range(1, brp.NbSolution() + 1):
                    if brp.SupportTypeShape1(
                            k) == BRepExtrema.BRepExtrema_IsOnEdge:
                        xIntersections.append(brp.PointOnShape1(k).X())

        if len(xIntersections) == 0:
            print "No intersection found."
            continue
        #else:
        #print "there are %d intersections " % len(xIntersections);
        #sort intersection points by x value
        xIntersections.sort()

        #fill pixel table with values on surface based on scanlines
        #TODO: for now ignore horizontals and edge vertices, this is just a test
        #better to use a generator here too
        #also need to implement edge table of scanline fill
        if (len(xIntersections) % 2 == 0):
            i = 0
            inside = False
            cx = xMin

            #print xIntersections;
            while i < len(xIntersections):
                cint = xIntersections[i]
                if inside:
                    while cx < cint:
                        key = (cx, y)
                        pixelTable[key] = 1
                        #print cx;
                        cx += resolution
                else:
                    while cx < cint:
                        cx += resolution
                        #print cx;
                        continue

                i += 1
                inside = not inside
        else:
            print "Odd number of intersections encountred."

    #displayPixelGrid(pixelTable);
    return pixelTable