예제 #1
0
    def followShape(self, shape, finish=False):
        "follows  this shape"
        if shape.ShapeType() == TopAbs.TopAbs_WIRE:
            for m in self.followWire(topoDS.Wire(shape)):
                yield m
        elif shape.ShapeType() == TopAbs.TopAbs_EDGE:
            for m in self.followEdge(topoDS.Edge(shape)):
                yield m
        elif shape.ShapeType() == TopAbs.TopAbs_COMPOUND:
            bb = TopExp.TopExp_Explorer()
            bb.Init(shape, TopAbs.TopAbs_WIRE)
            while bb.More():
                w = topoDS.Wire(bb.Current())
                for m in self.followWire(wire):
                    yield m
                bb.Next()
            bb.ReInit()
        else:
            "unknown shape"
            pass

        #flush any last remaining move
        if finish:
            t = self._fetchPendingMove()
            if t:
                yield t
예제 #2
0
    def preview(self, input, direction):
        if self.step == 0:
            from OCC import TopExp, TopAbs, BRep
            exp = TopExp.TopExp_Explorer(input, TopAbs.TopAbs_VERTEX)
            v1 = TopoDS.topods_Vertex(exp.Current())
            v1_ = BRep.BRep_Tool.Pnt(TopoDS.TopoDS_Vertex(v1))
            # TODO: 0.3: finish: automatically determine orthogonal direction
            # from
            #   input
            self.previous_data = [input, direction]
            try:
                wire = TopoDS.TopoDS_Wire(input)
                print(dir(wire))
            except:
                pass
            return ()
        elif self.step == 1:
            object, dir_ = self.previous_data[:]

            dirvec = [0, 0, 0]
            dirvec[dir_] = input[dir_]
            if dirvec == [0, 0, 0]:
                raise InvalidInputException
            self.remove = [self.previous_data[0]]
            self._final = [BRepPrimAPI.BRepPrimAPI_MakePrism(
                                object, gp.gp_Vec(*dirvec)).Shape()]
            return self._final
예제 #3
0
def offsetWireList(wireList, offsetAmount):

    if len(wireList) == 0:
        print "Warning: zero wires in the shape-- skipping"
        return []

    bo = BRepOffsetAPI.BRepOffsetAPI_MakeOffset()

    for w in wireList:
        bo.AddWire(w)

    bo.Perform(offsetAmount, 0.0)
    #if this crashes, try using a small non zero number for the last argument
    if not bo.IsDone():
        print "Warning: offset not computed!"
        return None
    else:
        #make sure to return a list of wires also, since we got one in
        returnWires = []
        shape = bo.Shape()
        if shape.ShapeType() == TopAbs.TopAbs_WIRE:
            returnWires.append(cast(shape))
        elif shape.ShapeType() == TopAbs.TopAbs_COMPOUND:

            bb = TopExp.TopExp_Explorer()
            bb.Init(shape, TopAbs.TopAbs_WIRE)
            while bb.More():
                w = topoDS.wire(bb.Current())
                returnWires.append(cast(w))
                bb.Next()
            bb.ReInit()
    return returnWires
예제 #4
0
def makeWiresFromOffsetShape(shape):
    "get all the wires from the offset shape"
    resultWires = TopTools.TopTools_HSequenceOfShape()
    if shape.ShapeType() == TopAbs.TopAbs_WIRE:
        #log.info( "offset result is a wire" );
        wire = topoDS.Wire(shape)
        #resultWires.append(wire);
        resultWires.Append(wire)
    elif shape.ShapeType() == TopAbs.TopAbs_COMPOUND:
        #log.info( "offset result is a compound");

        bb = TopExp.TopExp_Explorer()
        bb.Init(shape, TopAbs.TopAbs_WIRE)
        while bb.More():
            w = topoDS.Wire(bb.Current())

            #resultWires.append(w);
            resultWires.Append(w)
            #
            #debugShape(w);
            bb.Next()

        bb.ReInit()

    return resultWires
예제 #5
0
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
예제 #6
0
 def edges(self):
     "a generator for edges"
     bb = TopExp.TopExp_Explorer()
     bb.Init(self.wire, TopAbs.TopAbs_EDGE)
     while bb.More():
         e = topoDS.edge(bb.Current())
         yield e
         bb.Next()
     bb.ReInit()
예제 #7
0
def loopWire2(w):
    edges = TopTools.TopTools_HSequenceOfShape()
    topexp = TopExp.TopExp_Explorer()
    topexp.Init(w, TopAbs.TopAbs_EDGE)

    while topexp.More():
        #currentEdge = Wrappers.cast();
        edges.Append(topexp.Current())
        topexp.Next()
    return edges
예제 #8
0
    def _makeSlice(self, shapeToSlice, zLevel):
        s = Slice()

        #change if layers are variable thickness
        s.sliceHeight = self.sliceHeight
        s.zLevel = zLevel

        #make a cutting plane
        p = gp.gp_Pnt(0, 0, zLevel)

        origin = gp.gp_Pnt(0, 0, zLevel - 1)
        csys = gp.gp_Ax3(p, gp.gp().DZ())
        cuttingPlane = gp.gp_Pln(csys)
        bff = BRepBuilderAPI.BRepBuilderAPI_MakeFace(cuttingPlane)
        face = bff.Face()

        #odd, a halfspace is faster than a box?
        hs = BRepPrimAPI.BRepPrimAPI_MakeHalfSpace(face, origin)
        hs.Build()
        halfspace = hs.Solid()

        #make the cut
        bc = BRepAlgoAPI.BRepAlgoAPI_Cut(shapeToSlice, halfspace)
        cutShape = bc.Shape()

        #search the shape for faces at the specified zlevel
        texp = TopExp.TopExp_Explorer()
        texp.Init(cutShape, TopAbs.TopAbs_FACE)
        foundFace = False
        while (texp.More()):
            face = ts.Face(texp.Current())
            if self._isAtZLevel(zLevel, face):
                foundFace = True
                logging.debug("Face is at zlevel" + str(zLevel))
                s.addFace(face, self.saveSliceFaces)
            texp.Next()

        #free memory
        face.Nullify()
        bc.Destroy()
        texp.Clear()
        texp.Destroy()

        if not foundFace:
            logging.warn("No faces found after slicing at zLevel " +
                         str(zLevel) + " !. Skipping This layer completely")
            return None
        else:
            return s
예제 #9
0
def subshapes(shape, shapetype):
    """Return a list of subshapes of the specified type"""
    # TODO: Return a generator instead of a list
    convertor = _convertors[shapetype]
    shapelist = []
    exp = TopExp.TopExp_Explorer(shape, shapetype)
    while exp.More():
        v = exp.Current()
        t = type(v)
        i = id(v)
        # v2 = convertor(exp.Current())
        k = get_key(_convertors, t)
        shapelist.append(v)
        exp.Next()
    return shapelist
예제 #10
0
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
예제 #11
0
    def addFace(self, face, saveFaceCopy=True):

        if saveFaceCopy:
            copier = BRepBuilderAPI.BRepBuilderAPI_Copy(face)
            self.faces.append(copier.Shape())
            copier.Delete()

        ow = brt.OuterWire(face)
        logging.debug("Adding OuterWire...")
        self.addWire(ow)

        logging.debug("Adding Other Wires...")
        #now get the other wires
        te = TopExp.TopExp_Explorer()

        te.Init(face, TopAbs.TopAbs_WIRE)
        while te.More():
            w = ts.Wire(te.Current())
            if not w.IsSame(ow):
                self.addWire(w)
            te.Next()
        te.Clear()
        te.Destroy()
예제 #12
0
def checkMinimumDistanceForOffset(offset, resolution):
    "PERFORMANCE INTENSIVE!!!!"
    "check an offset shape to make sure that it does not overlap too closely"
    "this consists of making sure that none of the wires are too close to each other"
    "and that no individual wires have edges too close together"
    log.info("Checking this offset for minimum distances")

    te = TopExp.TopExp_Explorer()
    resultWires = TopTools.TopTools_HSequenceOfShape()
    te.Init(offset, TopAbs.TopAbs_WIRE)

    allPoints = []
    while te.More():
        w = ts.Wire(te.Current())
        wr = Wire(w)
        resultWires.Append(w)
        allPoints.extend(pointsFromWire(w, resolution * 3))
        #for p in wr.discretePoints(resolution/2):
        #	debugShape(make_vertex(p));
        #	allPoints.append(p);
        te.Next()
    te.ReInit()

    log.info("There are %d wires, and %d points" %
             (resultWires.Length(), len(allPoints)))

    #cool trick here: list all permutations of these points
    "this is where we could probably really improve this algorithm"
    for (p1, p2) in list(itertools.combinations(allPoints, 2)):
        d = p1.Distance(p2)
        if d < resolution:
            log.warn("Distance %0.5f is less than expected value" % d)
            return False
        #else:
        #log.info("Computed distance = %0.5f" % d );

    return True
예제 #13
0
def isLocalMinimum(wire, vertex):
    """
		The vertex is assumed to exist on the wire.
		
		The method determines if the vertex is situated such that the 
		location is a local minimum or maxiumum on the boundary.
		
		The method is needed for teh scanline algorithm: in the case
		that a filling line intersects a boundary at a vertex, the
		vertex counts as boundary if it does, and does not count otherwise.
	
		This method is slow, hopefully it is very rarely used.
		
		TODO: right now, this assumes that scanlines are always oriented parallel
		with the x axis ( horizontal ). this algorithm needs a direction vector
		in order to be generalized for the situation where the fill lines can be
		oriented in any direction
	"""
    #print "Determining if the specified point is a local minimum or not..."
    topexp = TopExp.TopExp_Explorer()
    topexp.Init(wire, TopAbs.TopAbs_EDGE)
    te = TopExp.TopExp()

    #find two edges that contain the vertex
    edges = []
    while topexp.More():
        e = cast(topexp.Current())
        if te.LastVertex(e).__hash__() == vertex.__hash__():
            #print "found a last vertex"
            edges.append(e)
        if te.FirstVertex(e).__hash__() == vertex.__hash__():
            edges.append(e)
            #print "found a first vertex"
        topexp.Next()

    assert len(edges) == 2

    #move a little away from the vertex in each direction

    ALITTLEBIT = d1 = d2 = 0.01
    e1 = edges[0]
    e2 = edges[1]
    p1 = brepTool.Parameter(vertex, e1)
    p2 = brepTool.Parameter(vertex, e2)

    (bp1, ep1) = brepTool.Range(e1)
    (bp2, ep2) = brepTool.Range(e2)

    if p1 == ep1: d1 = d1 * (-1)
    if p2 == ep2: d2 = d2 * (-1)

    pnt1 = pointAtParameter(e1, p1 + d1)
    pnt2 = pointAtParameter(e2, p2 + d2)

    #TestDisplay.display.showShape(vertex);
    #TestDisplay.display.showShape(wire);
    #TestDisplay.display.showShape(make_vertex(pnt1));
    #TestDisplay.display.showShape(make_vertex(pnt2));
    #TestDisplay.display.run();
    #finally! compare y values. this is the part that needs to change later
    #to account for rotated filling lines
    y = brepTool.Pnt(vertex).Y()

    dy1 = pnt1.Y() - y
    dy2 = pnt2.Y() - y

    if dy1 * dy2 > 0:
        #print "local min/max detected."
        return True
    else:
        #print "vertex is not a local min/max"
        return False
예제 #14
0
def splitWire(wire,ipoints):
	"""
		ipoints is a list of intersection points.
		returns a list of wires inside the intersection point
		
		this method must also work for a 'wire' consisting of a single
		edge. more than one intersection point can be on each edge, 
		but all of the ipoints are expected to be on edges in the provided wire.
		BASELINE PERFORMANCE: 11 ms per call for splitwiretest
		
		returns a list of lists.
		each element in the top list is a chain of connected edges.
			each element in that list is an edge ( or part of an edge )
			
		so, for example, suppose you compute a wire that has 100 edges, and there are 4 intersection points.
		in this case, there will be two elements returned, and each element would contain a list of edges
		between the two segments.
		---E1---+---E2---+-X-E3---+---E4--X--+---E5---
		will return [  [E1,E2], [ E3,E4 ] ]
		
	"""
	topexp = TopExp.TopExp_Explorer();
	topexp.Init(wire,TopAbs.TopAbs_EDGE);

	#sort intersection points by ascending X location
	ix = sorted(ipoints,key = lambda p: p.point.X() );	

	edgeList = [];
	
	assert (len(ipoints) % 2) == 0;
	
	for i in range(0,len(ipoints),2):
		#process intersection points in pairs
		#TODO: this could be done more cleanly with a pairwise iterator
		currentIntersection = ix[i];
		nextIntersection = ix[i+1];
		
		#if they are on the same edge, simply add a trimmed edge.
		#in this case, 
		if currentIntersection.hash == nextIntersection.hash:
			edgeList.append ( [ Wrappers.trimmedEdge(currentIntersection.edge, currentIntersection.param, nextIntersection.param ) ] ); 
		else:
			#intersections are not on the same edge.
			#add the fraction of the first edge
			(bp,ep) = brepTool.Range(currentIntersection.edge);
			edges = [];
			#print "adding piece of start edge."
			edges.append( Wrappers.trimmedEdge(currentIntersection.edge,currentIntersection.param, ep));
	
			#pick up whole edges between the first intersection and the next one
			#loop till current edge is same as current intersection
			while topexp.Current().__hash__() != currentIntersection.hash:
				topexp.Next();
			
			#advance to next edge
			topexp.Next();
			
			#add edges till current edge is same as next intersection
			#most of the performance suckage is happening here, with gc associated with these
			#edge objects.  If that gets fixed, we'll get a huge speed boost. about 33% of total time is saved.
			while topexp.Current().__hash__() != nextIntersection.hash:
				edge = Wrappers.cast(topexp.Current() );
				edges.append(edge);
				#print "adding middle edge"
				topexp.Next();
	
			#add the last edge
			(bp,ep) = brepTool.Range(nextIntersection.edge);
			edges.append( Wrappers.trimmedEdge(nextIntersection.edge,bp,nextIntersection.param));
			#print "adding last piece of edge"
			edgeList.append(edges);
	return edgeList;
예제 #15
0
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())
예제 #16
0
def splitWire(wire, ipoints):
	"""
		ipoints is a list of intersection points.
		returns a list of wires inside the intersection point
		
		BASELINE PERFORMANCE: 11 ms per call for splitwiretest
	"""
	
	#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
	#very interesting OCC weird thing: topexp is much faster than wireexplorer
	topexp = TopExp.TopExp_Explorer();
	topexp.Init(wire,TopAbs.TopAbs_EDGE);


	#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 = Wrappers.cast(topexp.Current());
	currentEdgeBounds = brepTool.Range(currentEdge);
	startParam = currentEdgeBounds[0];
	#print "handling %d intersections" % len(ix)
	while iIntersection < len(ix) and ( topexp.More()  ) :
		currentIntersection = ix[iIntersection];

		if hashE(currentEdge) == currentIntersection.hash:
						
			#current edge matches intersection point
			if inside:
				#transition to outside: add this part edge
				currentEdgeBounds = brepTool.Range(currentEdge);
				newEdge = Wrappers.trimmedEdge(currentEdge,startParam,currentIntersection.param);
				#TestDisplay.display.showShape(newEdge);
				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);
				if startParam == currentEdgeBounds[0]:
					edges.append(currentEdge);
				else:
					newEdge = Wrappers.trimmedEdge(currentEdge,startParam, currentEdgeBounds[1] );
					
					edges.append(newEdge);
			
			#move to next edge
			topexp.Next();
			currentEdge = Wrappers.cast(topexp.Current());
			startParam = currentEdgeBounds[0];			
	#print "returning %d edges" % len(edges)
	return edges;	
예제 #17
0
##Copyright 2008 Jelle Feringa ([email protected])
예제 #18
0
# -*- coding: iso-8859-1 -*-
예제 #19
0
##   X install guide
##   X remove unneed dumpTopology and shapeDescription
##     add 2d per-slice view on select of slice
##   X add ability to easily select slice thickness
##     add separate display for original object and slices
##   X sew faces from crappy stl files into single faces somehow
##   X remove reference to profile import

#####
#utility class instances
#available to all methods
#####
brt = BRepTools.BRepTools()
btool = BRep.BRep_Tool()
ts = TopoDS.TopoDS()
topexp = TopExp.TopExp()
texp = TopExp.TopExp_Explorer()
"""
	Utility class to provide timing information
"""


class Timer:
    def __init__(self):
        self.startTime = time.time()
        self.startAscTime = time.asctime()

    def start(self):
        return self.startTime

    def elapsed(self):