Пример #1
0
    def backSmaller(self, i):
        import DraftGeomUtils

        profilCurrent = self.findProfil(i)
        profilBack1 = self.findProfil(i - 1)
        dec = profilBack1["height"] / math.tan(math.radians(profilCurrent["angle"]))
        edgeRidgeOnPane = DraftGeomUtils.offset(
            profilCurrent["edge"], self.getPerpendicular(profilCurrent["vec"], profilCurrent["rot"], dec)
        )
        ptInter1 = DraftGeomUtils.findIntersection(
            edgeRidgeOnPane, profilBack1["ridge"], infinite1=True, infinite2=True
        )
        edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInter1[0]), profilCurrent["edge"].Vertexes[0].Point)
        ptInter2 = edgeHip.Vertexes[0].Point
        vecInterRidges = DraftGeomUtils.findPerpendicular(ptInter2, [profilCurrent["ridge"].Edges[0]], force=0)
        ptInterRidges = ptInter2.add(vecInterRidges[0])
        self.ptsPaneProject.append(FreeCAD.Vector(ptInterRidges))
        self.ptsPaneProject.append(FreeCAD.Vector(ptInter1[0]))
        ptInterHipEave = DraftGeomUtils.findIntersection(
            edgeHip, profilCurrent["eave"], infinite1=True, infinite2=False
        )
        if ptInterHipEave:
            self.ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave[0]))
        else:
            ptInterHipEave = DraftGeomUtils.findIntersection(
                edgeHip, profilBack1["eaveD"], infinite1=True, infinite2=True
            )
            self.ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave[0]))
            self.ptsPaneProject.append(FreeCAD.Vector(profilCurrent["eave"].Vertexes[0].Point[0]))
Пример #2
0
 def nextSmaller(self, i):
     print("Next : ht2 < ht1")
     profilCurrent = self.findProfil(i)
     profilNext1 = self.findProfil(i+1)
     dec = profilNext1["height"]/math.tan(math.radians(profilCurrent["angle"]))
     edgeRidgeOnPane = DraftGeomUtils.offset(profilCurrent["edge"],self.getPerpendicular(profilCurrent["vec"],profilCurrent["rot"],dec))
     ptInter = DraftGeomUtils.findIntersection(profilNext1["ridge"],edgeRidgeOnPane,infinite1=True,infinite2=True,)
     edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInter[0]),profilCurrent["edge"].Vertexes[-1].Point)
     ptInterHipEave = DraftGeomUtils.findIntersection(edgeHip,profilCurrent["eave"],infinite1=True,infinite2=False,)
     if ptInterHipEave:
         print "a ",FreeCAD.Vector(ptInterHipEave[0])
         self.ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave[0]))
     else:
         ptInterHipEave = DraftGeomUtils.findIntersection(edgeHip,profilNext1["eaveD"],infinite1=True,infinite2=True,)
         print "b ",FreeCAD.Vector(profilCurrent["eave"].Vertexes[-1].Point[0])
         print "c ",FreeCAD.Vector(ptInterHipEave[0])
         self.ptsPaneProject.append(FreeCAD.Vector(profilCurrent["eave"].Vertexes[-1].Point[0]))
         self.ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave[0]))
     print "d ",FreeCAD.Vector(ptInter[0])
     self.ptsPaneProject.append(FreeCAD.Vector(ptInter[0]))
     ptInter = edgeHip.Vertexes[0].Point
     vecInterRidges = DraftGeomUtils.findPerpendicular(ptInter, [profilCurrent["ridge"].Edges[0],], force=0)
     ptInterRidges = ptInter.add(vecInterRidges[0])
     print "e ",FreeCAD.Vector(ptInterRidges)
     self.ptsPaneProject.append(FreeCAD.Vector(ptInterRidges))
Пример #3
0
 def backSmaller(self, i):
     import DraftGeomUtils
     print("Back : ht0 < ht1")
     profilCurrent = self.findProfil(i)
     profilBack1 = self.findProfil(i - 1)
     dec = profilBack1["height"] / math.tan(
         math.radians(profilCurrent["angle"]))
     edgeRidgeOnPane = DraftGeomUtils.offset(
         profilCurrent["edge"],
         self.getPerpendicular(profilCurrent["vec"], profilCurrent["rot"],
                               dec))
     ptInter1 = DraftGeomUtils.findIntersection(
         edgeRidgeOnPane,
         profilBack1["ridge"],
         infinite1=True,
         infinite2=True,
     )
     edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInter1[0]),
                                  profilCurrent["edge"].Vertexes[0].Point)
     ptInter2 = edgeHip.Vertexes[0].Point
     vecInterRidges = DraftGeomUtils.findPerpendicular(ptInter2, [
         profilCurrent["ridge"].Edges[0],
     ],
                                                       force=0)
     ptInterRidges = ptInter2.add(vecInterRidges[0])
     print "a ", FreeCAD.Vector(ptInterRidges)
     print "b ", FreeCAD.Vector(ptInter1[0])
     self.ptsPaneProject.append(FreeCAD.Vector(ptInterRidges))
     self.ptsPaneProject.append(FreeCAD.Vector(ptInter1[0]))
     ptInterHipEave = DraftGeomUtils.findIntersection(
         edgeHip,
         profilCurrent["eave"],
         infinite1=True,
         infinite2=False,
     )
     if ptInterHipEave:
         print "c ", FreeCAD.Vector(ptInterHipEave[0])
         self.ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave[0]))
     else:
         ptInterHipEave = DraftGeomUtils.findIntersection(
             edgeHip,
             profilBack1["eaveD"],
             infinite1=True,
             infinite2=True,
         )
         print "d ", FreeCAD.Vector(ptInterHipEave[0])
         print "e ", FreeCAD.Vector(
             profilCurrent["eave"].Vertexes[0].Point[0])
         self.ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave[0]))
         self.ptsPaneProject.append(
             FreeCAD.Vector(profilCurrent["eave"].Vertexes[0].Point[0]))
Пример #4
0
    def nextSmaller(self, i):

        import DraftGeomUtils
        profilCurrent = self.findProfil(i)
        profilNext1 = self.findProfil(i + 1)
        dec = profilNext1["height"] / math.tan(
            math.radians(profilCurrent["angle"]))
        edgeRidgeOnPane = DraftGeomUtils.offset(
            profilCurrent["edge"],
            self.getPerpendicular(profilCurrent["vec"], profilCurrent["rot"],
                                  dec))
        ptInter = DraftGeomUtils.findIntersection(
            profilNext1["ridge"],
            edgeRidgeOnPane,
            infinite1=True,
            infinite2=True,
        )
        edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInter[0]),
                                     profilCurrent["edge"].Vertexes[-1].Point)
        ptInterHipEave = DraftGeomUtils.findIntersection(
            edgeHip,
            profilCurrent["eave"],
            infinite1=True,
            infinite2=False,
        )
        if ptInterHipEave:
            self.ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave[0]))
        else:
            ptInterHipEave = DraftGeomUtils.findIntersection(
                edgeHip,
                profilNext1["eaveD"],
                infinite1=True,
                infinite2=True,
            )
            self.ptsPaneProject.append(
                FreeCAD.Vector(profilCurrent["eave"].Vertexes[-1].Point[0]))
            self.ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave[0]))
        self.ptsPaneProject.append(FreeCAD.Vector(ptInter[0]))
        ptInter = edgeHip.Vertexes[0].Point
        vecInterRidges = DraftGeomUtils.findPerpendicular(ptInter, [
            profilCurrent["ridge"].Edges[0],
        ],
                                                          force=0)
        ptInterRidges = ptInter.add(vecInterRidges[0])
        self.ptsPaneProject.append(FreeCAD.Vector(ptInterRidges))
Пример #5
0
    def buildpathocc(self, obj, shape):
        """Build pocket Path using Native OCC algorithm."""
        import Part
        import DraftGeomUtils
        from PathScripts.PathUtils import fmt, helicalPlunge, rampPlunge

        FreeCAD.Console.PrintMessage(
            translate("PathPocket",
                      "Generating toolpath with OCC native offsets.\n"))

        # Build up the offset loops
        output = ""
        offsets = []
        nextradius = (self.radius * 2) * (float(obj.StepOver) / 100)
        result = DraftGeomUtils.pocket2d(shape, nextradius)
        print "did we get something: " + str(result)
        while result:
            print "Adding " + str(len(result)) + " wires"
            offsets.extend(result)
            nextradius += (self.radius * 2) * (float(obj.StepOver) / 100)
            result = DraftGeomUtils.pocket2d(shape, nextradius)

        # revert the list so we start with the outer wires
        if obj.StartAt != 'Edge':
            offsets.reverse()

        plungePos = None
        rampEdge = None
        if obj.UseEntry:
            # Try to find an entry location
            toold = self.radius * 2
            helixBounds = DraftGeomUtils.pocket2d(
                shape, self.radius * (1 + obj.HelixSize))

            if helixBounds:
                rampD = obj.RampSize

                if obj.StartAt == 'Edge':
                    plungePos = helixBounds[0].Edges[0].Vertexes[0].Point
                else:
                    plungePos = offsets[0].Edges[0].Vertexes[0].Point

                    # If it turns out this is invalid for some reason, nuke plungePos
                    [perp, idx] = DraftGeomUtils.findPerpendicular(
                        plungePos, shape.Edges)
                    if not perp or perp.Length < self.radius * (1 +
                                                                obj.HelixSize):
                        plungePos = None
                        FreeCAD.Console.PrintError(
                            translate("PathPocket",
                                      "Helical Entry location not found.\n"))
                    # FIXME: Really need to do a point-in-polygon operation to make sure this is within helixBounds
                    # Or some math to prove that it has to be (doubt that's true)
                    # Maybe reverse helixBounds and pick off that?

            if plungePos is None:  # If we didn't find a place to helix, how about a ramp?
                FreeCAD.Console.PrintMessage(
                    translate("PathPocket", "Attempting ramp entry.\n"))
                if (offsets[0].Edges[0].Length >= toold * rampD) and not (
                        isinstance(offsets[0].Edges[0].Curve, Part.Circle)):
                    rampEdge = offsets[0].Edges[0]
                # The last edge also connects with the starting location- try that
                elif (offsets[0].Edges[-1].Length >= toold * rampD) and not (
                        isinstance(offsets[0].Edges[-1].Curve, Part.Circle)):
                    rampEdge = offsets[0].Edges[-1]
                else:
                    FreeCAD.Console.PrintError(
                        translate("PathPocket",
                                  "Ramp Entry location not found.\n"))
                    # print "Neither edge works: " + str(offsets[0].Edges[0]) + ", " + str(offsets[0].Edges[-1])
                    # FIXME: There's got to be a smarter way to find a place to ramp

        fastZPos = obj.ClearanceHeight.Value

        # For helix-ing/ramping, know where we were last time
        # FIXME: Can probably get this from the "machine"?
        lastZ = fastZPos

        startPoint = None

        for vpos in PathUtils.frange(obj.StartDepth.Value,
                                     obj.FinalDepth.Value, obj.StepDown,
                                     obj.FinishDepth.Value):
            first = True
            # loop over successive wires
            for currentWire in offsets:
                #output += PathUtils.convert(currentWire.Edges, "on", 1)
                last = None
                for edge in currentWire.Edges:
                    if not last:
                        # we set the base GO to our fast move to our starting pos
                        if first:
                            # If we can helix, do so
                            if plungePos:
                                output += helicalPlunge(
                                    plungePos, obj.RampAngle, vpos, lastZ,
                                    self.radius * 2, obj.HelixSize,
                                    self.horizFeed)
                                # print output
                                lastZ = vpos
                            # Otherwise, see if we can ramp
                            # FIXME: This could be a LOT smarter (eg, searching for a longer leg of the edge to ramp along)
                            elif rampEdge:
                                output += rampPlunge(rampEdge, obj.RampAngle,
                                                     vpos, lastZ)
                                lastZ = vpos
                            # Otherwise, straight plunge... Don't want to, but sometimes you might not have a choice.
                            # FIXME: At least not with the lazy ramp programming above...
                            else:
                                print "WARNING: Straight-plunging... probably not good, but we didn't find a place to helix or ramp"
                                startPoint = edge.Vertexes[0].Point
                                output += "G0 X" + fmt(startPoint.x) + " Y" + fmt(startPoint.y) +\
                                          " Z" + fmt(fastZPos) + "\n"
                            first = False
                        # then move slow down to our starting point for our profile
                        last = edge.Vertexes[0].Point
                        output += "G1 X" + fmt(last.x) + " Y" + fmt(
                            last.y) + " Z" + fmt(vpos) + "\n"
                    # if isinstance(edge.Curve,Part.Circle):
                    if DraftGeomUtils.geomType(edge) == "Circle":
                        point = edge.Vertexes[-1].Point
                        if point == last:  # edges can come flipped
                            point = edge.Vertexes[0].Point
                        center = edge.Curve.Center
                        relcenter = center.sub(last)
                        v1 = last.sub(center)
                        v2 = point.sub(center)
                        if v1.cross(v2).z < 0:
                            output += "G2"
                        else:
                            output += "G3"
                        output += " X" + fmt(point.x) + " Y" + fmt(
                            point.y) + " Z" + fmt(vpos)
                        output += " I" + fmt(relcenter.x) + " J" + fmt(
                            relcenter.y) + " K" + fmt(relcenter.z)
                        output += "\n"
                        last = point
                    else:
                        point = edge.Vertexes[-1].Point
                        if point == last:  # edges can come flipped
                            point = edge.Vertexes[0].Point
                        output += "G1 X" + fmt(point.x) + " Y" + fmt(
                            point.y) + " Z" + fmt(vpos) + "\n"
                        last = point

        # move back up
        output += "G1 Z" + fmt(fastZPos) + "\n"
        return output
Пример #6
0
    def execute(self,obj):
        if obj.Base:
            tool = PathUtils.getLastTool(obj)

            if tool:
                radius = tool.Diameter/2
                if radius < 0:# safe guard
                    radius -= radius
            else:
                # temporary value, to be taken from the properties later on
                radius = 1

            import Part, DraftGeomUtils
            if "Face" in obj.Base[1][0]:
                shape = getattr(obj.Base[0].Shape,obj.Base[1][0])
            else:
                edges = [getattr(obj.Base[0].Shape,sub) for sub in obj.Base[1]]
                shape = Part.Wire(edges)
                print len(edges)

            # absolute coords, millimeters, cancel offsets
            output = "G90\nG21\nG40\n"
            # save tool
            if obj.ToolNumber > 0 and tool.ToolNumber != obj.ToolNumber:
                output += "M06 T" + str(tool.ToolNumber) + "\n"
            
            # build offsets
            offsets = []
            nextradius = radius
            result = DraftGeomUtils.pocket2d(shape,nextradius)
            while result:
                #print "Adding " + str(len(result)) + " wires"
                offsets.extend(result)
                nextradius += radius
                result = DraftGeomUtils.pocket2d(shape,nextradius)
            
            # first move will be rapid, subsequent will be at feed rate
            first = True
            startPoint = None
            fastZPos = max(obj.StartDepth + 2, obj.RetractHeight)
            
            # revert the list so we start with the outer wires
            if obj.StartAt != 'Edge':
                offsets.reverse()

#            print "startDepth: " + str(obj.StartDepth)
#            print "finalDepth: " + str(obj.FinalDepth)
#            print "stepDown: " + str(obj.StepDown)
#            print "finishDepth" + str(obj.FinishDepth)
#            print "offsets:", len(offsets)

            def prnt(vlu): return str("%.4f" % round(vlu, 4))
            
            #Fraction of tool radius our plunge helix is to be
            #FIXME: This should be configurable
            plungeR = 0.75
            
            #(minimum) Fraction of tool DIAMETER to go back and forth while ramp-plunging
            #FIXME: This should be configurable
            #FIXME: The ramp plunging should maybe even be limited to this distance; I don't know what's best
            rampD = 0.75
            
            
            #Total offset from the desired pocket edge is tool radius plus the plunge helix radius
            #Any point on these curves could be the center of a plunge
            helixBounds = DraftGeomUtils.pocket2d(shape, tool.Diameter / 2. * (1 + plungeR))
            
            
            #Try to find a location to nicely plunge, starting with a helix, then ramp
            #Can't do it without knowledge of a tool
            plungePos = None
            rampEdge = None
            if not tool:
                    raise Error("Ramp plunge location-finding requires a tool")
                    return
            else:
                #Since we're going to start machining either the inner-most
                #edge or the outer (depending on StartAt setting), try to
                #plunge near that location
                
                if helixBounds:
                    #Edge is easy- pick a point on helixBounds and go with it
                    if obj.StartAt == 'Edge':
                        plungePos = helixBounds[0].Edges[0].Vertexes[0].Point
                    #Center is harder- use a point from the first offset, check if it works
                    else:
                        plungePos = offsets[0].Edges[0].Vertexes[0].Point
                        
                        #If it turns out this is invalid for some reason, nuke plungePos
                        [perp,idx] = DraftGeomUtils.findPerpendicular(plungePos, shape.Edges)
                        if not perp or perp.Length < tool.Diameter / 2. * (1 + plungeR):
                            plungePos = None
                        #FIXME: Really need to do a point-in-polygon operation to make sure this is within helixBounds
                        #Or some math to prove that it has to be (doubt that's true)
                        #Maybe reverse helixBounds and pick off that?
                
                
                #If we didn't find a place to helix, how about a ramp?
                if not plungePos:
                    #Check first edge of our offsets
                    if (offsets[0].Edges[0].Length >= tool.Diameter * rampD) and not (isinstance(offsets[0].Edges[0].Curve, Part.Circle)):
                        rampEdge = offsets[0].Edges[0]
                    #The last edge also connects with the starting location- try that
                    elif (offsets[0].Edges[-1].Length >= tool.Diameter * rampD) and not (isinstance(offsets[0].Edges[-1].Curve, Part.Circle)):
                        rampEdge = offsets[0].Edges[-1]
                    else:
                        print "Neither edge works: " + str(offsets[0].Edges[0]) + ", " + str(offsets[0].Edges[-1])
                    #FIXME: There's got to be a smarter way to find a place to ramp
                
            
            #Returns gcode to perform a rapid move
            def rapid(x=None, y=None, z=None):
                retstr = "G00"
                if (x != None) or (y != None) or (z != None):
                    if (x != None):
                        retstr += " X" + str("%.4f" % x)
                    if (y != None):
                        retstr += " Y" + str("%.4f" % y)
                    if (z != None):
                        retstr += " Z" + str("%.4f" % z)
                else:
                    return ""
                return retstr + "\n"
                
            #Returns gcode to perform a linear feed
            def feed(x=None, y=None, z=None):
                global feedxy
                retstr = "G01 F"
                if(x == None) and (y == None):
                    retstr += str("%.4f" % obj.HorizFeed)
                else:
                    retstr += str("%.4f" % obj.VertFeed)
                
                if (x != None) or (y != None) or (z != None):
                    if (x != None):
                        retstr += " X" + str("%.4f" % x)
                    if (y != None):
                        retstr += " Y" + str("%.4f" % y)
                    if (z != None):
                        retstr += " Z" + str("%.4f" % z)
                else:
                    return ""
                return retstr + "\n"
            
            #Returns gcode to perform an arc
            #Assumes XY plane or helix around Z
            #Don't worry about starting Z- assume that's dealt with elsewhere
            def arc(cx, cy, sx, sy, ex, ey, ez=None, ccw=False):
                #If start/end radii aren't within eps, abort
                eps = 0.01
                if (math.sqrt((cx - sx)**2 + (cy - sy)**2) - math.sqrt((cx - ex)**2 + (cy - ey)**2)) >= eps:
                    print "ERROR: Illegal arc: Stand and end radii not equal"
                    return ""
                
                #Set [C]CW and feed
                retstr = ""
                if ccw:
                    retstr += "G03 F"
                else:
                    retstr += "G02 F"
                retstr += str(obj.HorizFeed)
                
                #End location
                retstr += " X" + str("%.4f" % ex) + " Y" + str("%.4f" % ey)
                
                #Helix if requested
                if ez != None:
                    retstr += " Z" + str("%.4f" % ez)
                
                #Append center offsets
                retstr += " I" + str("%.4f" % (cx - sx)) + " J" + str("%.4f" % (cy - sy))
                
                return retstr + "\n"

            #Returns gcode to helically plunge
            #destZ is the milling level
            #startZ is the height we can safely feed down to before helix-ing
            def helicalPlunge(plungePos, rampangle, destZ, startZ):
                helixCmds = "(START HELICAL PLUNGE)\n"
                if(plungePos == None):
                    raise Error("Helical plunging requires a position!")
                    return None
                if(not tool):
                    raise Error("Helical plunging requires a tool!")
                    return None

                helixX = plungePos.x + tool.Diameter/2. * plungeR
                helixY = plungePos.y;
                
                helixCirc = math.pi * tool.Diameter * plungeR
                dzPerRev = math.sin(rampangle/180. * math.pi) * helixCirc

                #Go to the start of the helix position
                helixCmds += rapid(helixX, helixY)
                helixCmds += rapid(z=startZ)
                
                #Helix as required to get to the requested depth
                lastZ = startZ
                curZ = max(startZ-dzPerRev, destZ)
                done = False
                while not done:
                    done = (curZ == destZ)
                    #NOTE: FreeCAD doesn't render this, but at least LinuxCNC considers it valid
                    #helixCmds += arc(plungePos.x, plungePos.y, helixX, helixY, helixX, helixY, ez = curZ, ccw=True)
                    
                    #Use two half-helixes; FreeCAD renders that correctly,
                    #and it fits with the other code breaking up 360-degree arcs
                    helixCmds += arc(plungePos.x, plungePos.y, helixX, helixY, helixX - tool.Diameter * plungeR, helixY, ez = (curZ + lastZ)/2., ccw=True)
                    helixCmds += arc(plungePos.x, plungePos.y, helixX - tool.Diameter * plungeR, helixY, helixX, helixY, ez = curZ, ccw=True)
                    lastZ = curZ
                    curZ = max(curZ - dzPerRev, destZ)
                
                return helixCmds
                
                
            #Returns commands to linearly ramp into a cut
            #FIXME: This ramps along the first edge, assuming it's long
            #enough, NOT just wiggling back and forth by ~0.75 * toolD.
            #Not sure if that's any worse, but it's simpler
            #FIXME: This code is untested
            def rampPlunge(edge, rampangle, destZ, startZ):
                rampCmds = "(START RAMP PLUNGE)\n"
                if(edge == None):
                    raise Error("Ramp plunging requires an edge!")
                    return None
                if(not tool):
                    raise Error("Ramp plunging requires a tool!")
                
                
                sPoint = edge.Vertexes[0].Point
                ePoint = edge.Vertexes[1].Point
                #Evidently edges can get flipped- pick the right one in this case
                #FIXME: This is iffy code, based on what already existed in the "for vpos ..." loop below
                if ePoint == sPoint:
                    #print "FLIP"
                    ePoint = edge.Vertexes[-1].Point
                #print "Start: " + str(sPoint) + " End: " + str(ePoint) + " Zhigh: " + prnt(startZ) + " ZLow: " + prnt(destZ)
                
                rampDist = edge.Length
                rampDZ = math.sin(rampangle/180. * math.pi) * rampDist
                
                rampCmds += rapid(sPoint.x, sPoint.y)
                rampCmds += rapid(z=startZ)
                
                #Ramp down to the requested depth
                #FIXME: This might be an arc, so handle that as well
                lastZ = startZ
                curZ = max(startZ-rampDZ, destZ)
                done = False
                while not done:
                    done = (curZ == destZ)
                    
                    #If it's an arc, handle it!
                    if isinstance(edge.Curve,Part.Circle):
                        raise Error("rampPlunge: Screw it, not handling an arc.")
                    #Straight feed! Easy!
                    else:
                        rampCmds += feed(ePoint.x, ePoint.y, curZ)
                        rampCmds += feed(sPoint.x, sPoint.y)

                    lastZ = curZ
                    curZ = max(curZ - rampDZ, destZ)
                
                return rampCmds
                    
            
            
            
            #For helix-ing/ramping, know where we were last time
            #FIXME: Can probably get this from the "machine"?
            lastZ = fastZPos

            for vpos in frange(obj.StartDepth, obj.FinalDepth, obj.StepDown, obj.FinishDepth):
#                print "vpos: " + str(vpos)
                #Every for every depth we should helix down
                first = True
                # loop over successive wires
                for currentWire in offsets:
#                    print "new line (offset)"
                    last = None
                    for edge in currentWire.Edges:
#                        print "new edge"
                        if not last:
                            # we set the base GO to our fast move to our starting pos
                            if first:
                                #If we can helix, do so
                                if plungePos:
                                    output += helicalPlunge(plungePos, 3, vpos, lastZ)
                                    #print output
                                    lastZ = vpos
                                #Otherwise, see if we can ramp
                                #FIXME: This could be a LOT smarter (eg, searching for a longer leg of the edge to ramp along)
                                elif rampEdge:
                                    output += rampPlunge(rampEdge, 3, vpos, lastZ)
                                    lastZ = vpos
                                #Otherwise, straight plunge... Don't want to, but sometimes you might not have a choice.
                                #FIXME: At least not with the lazy ramp programming above...
                                else:
                                    print "WARNING: Straight-plunging... probably not good, but we didn't find a place to helix or ramp"
                                    startPoint = edge.Vertexes[0].Point
                                    output += "G0 X" + prnt(startPoint.x) + " Y" + prnt(startPoint.y) +\
                                              " Z" + prnt(fastZPos) + "\n"
                                first = False
                            #then move slow down to our starting point for our profile
                            last = edge.Vertexes[0].Point
                            output += "G1 X" + prnt(last.x) + " Y" + prnt(last.y) + " Z" + prnt(vpos) + "\n"
                        #if isinstance(edge.Curve,Part.Circle):
                        if DraftGeomUtils.geomType(edge) == "Circle":
                            point = edge.Vertexes[-1].Point
                            if point == last: # edges can come flipped
                                point = edge.Vertexes[0].Point
#                                print "flipped"
                            center = edge.Curve.Center
                            relcenter = center.sub(last)
                            v1 = last.sub(center)
                            v2 = point.sub(center)
                            if v1.cross(v2).z < 0:
                                output += "G2"
                            else:
                                output += "G3"
                            output += " X" + prnt(point.x) + " Y" + prnt(point.y) + " Z" + prnt(vpos)
                            output += " I" + prnt(relcenter.x) + " J" +prnt(relcenter.y) + " K" + prnt(relcenter.z)
                            output += "\n"
                            last = point
                        else:
                            point = edge.Vertexes[-1].Point
                            if point == last: # edges can come flipped
                                point = edge.Vertexes[0].Point
                            output += "G1 X" + prnt(point.x) + " Y" + prnt(point.y) + " Z" + prnt(vpos) + "\n"
                            last = point

            #move back up
            output += "G0 Z" + prnt(fastZPos) + "\n"
#            print output
#            path = Path.Path(output)
#            obj.Path = path
            if obj.Active:
                path = Path.Path(output)
                obj.Path = path
                obj.ViewObject.Visibility = True
            else:
                path = Path.Path("(inactive operation)")
                obj.Path = path
                obj.ViewObject.Visibility = False
Пример #7
0
    def action(self, arg):
        """Handle the 3D scene events.

        This is installed as an EventCallback in the Inventor view.

        Parameters
        ----------
        arg: dict
            Dictionary with strings that indicates the type of event received
            from the 3D view.
        """
        import DraftGeomUtils
        plane = App.DraftWorkingPlane

        if arg["Type"] == "SoKeyboardEvent":
            if arg["Key"] == "ESCAPE":
                self.finish()
        elif arg["Type"] == "SoLocation2Event":
            self.point, ctrlPoint, info = gui_tool_utils.getPoint(self, arg)
            if (gui_tool_utils.hasMod(arg, gui_tool_utils.MODCONSTRAIN)
                    and self.constrainSeg):
                dist = DraftGeomUtils.findPerpendicular(self.point,
                                                        self.shape,
                                                        self.constrainSeg[1])
            else:
                dist = DraftGeomUtils.findPerpendicular(self.point,
                                                        self.shape.Edges)
            if dist:
                self.ghost.on()
                if self.mode == "Wire":
                    d = dist[0].negative()
                    v1 = DraftGeomUtils.getTangent(self.shape.Edges[0],
                                                   self.point)
                    v2 = DraftGeomUtils.getTangent(self.shape.Edges[dist[1]],
                                                   self.point)
                    a = -DraftVecUtils.angle(v1, v2, plane.axis)
                    self.dvec = DraftVecUtils.rotate(d, a, plane.axis)
                    occmode = self.ui.occOffset.isChecked()
                    utils.param.SetBool("Offset_OCC", occmode)
                    _wire = DraftGeomUtils.offsetWire(self.shape,
                                                      self.dvec,
                                                      occ=occmode)
                    self.ghost.update(_wire, forceclosed=occmode)
                elif self.mode == "BSpline":
                    d = dist[0].negative()
                    e = self.shape.Edges[0]
                    basetan = DraftGeomUtils.getTangent(e, self.point)
                    self.npts = []
                    for p in self.sel.Points:
                        currtan = DraftGeomUtils.getTangent(e, p)
                        a = -DraftVecUtils.angle(currtan, basetan, plane.axis)
                        self.dvec = DraftVecUtils.rotate(d, a, plane.axis)
                        self.npts.append(p.add(self.dvec))
                    self.ghost.update(self.npts)
                elif self.mode == "Circle":
                    self.dvec = self.point.sub(self.center).Length
                    self.ghost.setRadius(self.dvec)
                self.constrainSeg = dist
                self.linetrack.on()
                self.linetrack.p1(self.point)
                self.linetrack.p2(self.point.add(dist[0]))
                self.ui.setRadiusValue(dist[0].Length, unit="Length")
            else:
                self.dvec = None
                self.ghost.off()
                self.constrainSeg = None
                self.linetrack.off()
                self.ui.radiusValue.setText("off")
            self.ui.radiusValue.setFocus()
            self.ui.radiusValue.selectAll()
            if self.extendedCopy:
                if not gui_tool_utils.hasMod(arg, gui_tool_utils.MODALT):
                    self.finish()
            gui_tool_utils.redraw3DView()

        elif arg["Type"] == "SoMouseButtonEvent":
            if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
                copymode = False
                occmode = self.ui.occOffset.isChecked()
                utils.param.SetBool("Offset_OCC", occmode)
                if (gui_tool_utils.hasMod(arg, gui_tool_utils.MODALT)
                        or self.ui.isCopy.isChecked()):
                    copymode = True
                Gui.addModule("Draft")
                if self.npts:
                    # _msg("offset:npts= " + str(self.npts))
                    _cmd = 'Draft.offset'
                    _cmd += '('
                    _cmd += 'FreeCAD.ActiveDocument.'
                    _cmd += self.sel.Name + ', '
                    _cmd += DraftVecUtils.toString(self.npts) + ', '
                    _cmd += 'copy=' + str(copymode)
                    _cmd += ')'
                    _cmd_list = ['offst = ' + _cmd,
                                 'FreeCAD.ActiveDocument.recompute()']
                    self.commit(translate("draft", "Offset"),
                                _cmd_list)
                elif self.dvec:
                    if isinstance(self.dvec, float):
                        delta = str(self.dvec)
                    else:
                        delta = DraftVecUtils.toString(self.dvec)
                    _cmd = 'Draft.offset'
                    _cmd += '('
                    _cmd += 'FreeCAD.ActiveDocument.'
                    _cmd += self.sel.Name + ', '
                    _cmd += delta + ', '
                    _cmd += 'copy=' + str(copymode) + ', '
                    _cmd += 'occ=' + str(occmode)
                    _cmd += ')'
                    _cmd_list = ['offst = ' + _cmd,
                                 'FreeCAD.ActiveDocument.recompute()']
                    self.commit(translate("draft", "Offset"),
                                _cmd_list)
                if gui_tool_utils.hasMod(arg, gui_tool_utils.MODALT):
                    self.extendedCopy = True
                else:
                    self.finish()
Пример #8
0
    def buildpathocc(self, obj, shape):
        """Build pocket Path using Native OCC algorithm."""
        import Part
        import DraftGeomUtils
        from PathScripts.PathUtils import fmt, helicalPlunge, rampPlunge, depth_params

        FreeCAD.Console.PrintMessage(translate("PathPocket", "Generating toolpath with OCC native offsets.\n"))
        extraoffset = obj.MaterialAllowance.Value

        # Build up the offset loops
        output = ""
        if obj.Comment != "":
            output += '(' + str(obj.Comment)+')\n'
        output += 'G0 Z' + fmt(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"

        offsets = []
        nextradius = self.radius + extraoffset
        result = DraftGeomUtils.pocket2d(shape, nextradius)
        while result:
            offsets.extend(result)
            nextradius += (self.radius * 2) * (float(obj.StepOver)/100)
            result = DraftGeomUtils.pocket2d(shape, nextradius)

        # revert the list so we start with the outer wires
        if obj.StartAt != 'Edge':
            offsets.reverse()

        plungePos = None
        rampEdge = None
        if obj.UseEntry:
            # Try to find an entry location
            toold = self.radius*2
            helixBounds = DraftGeomUtils.pocket2d(shape, self.radius * (1 + obj.HelixSize))

            if helixBounds:
                rampD = obj.RampSize

                if obj.StartAt == 'Edge':
                    plungePos = helixBounds[0].Edges[0].Vertexes[0].Point
                else:
                    plungePos = offsets[0].Edges[0].Vertexes[0].Point

                    # If it turns out this is invalid for some reason, nuke plungePos
                    [perp, idx] = DraftGeomUtils.findPerpendicular(plungePos, shape.Edges)
                    if not perp or perp.Length < self.radius * (1 + obj.HelixSize):
                        plungePos = None
                        FreeCAD.Console.PrintError(translate("PathPocket", "Helical Entry location not found.\n"))
                    # FIXME: Really need to do a point-in-polygon operation to make sure this is within helixBounds
                    # Or some math to prove that it has to be (doubt that's true)
                    # Maybe reverse helixBounds and pick off that?

            if plungePos is None:  # If we didn't find a place to helix, how about a ramp?
                FreeCAD.Console.PrintMessage(translate("PathPocket", "Attempting ramp entry.\n"))
                if (offsets[0].Edges[0].Length >= toold * rampD) and not (isinstance(offsets[0].Edges[0].Curve, Part.Circle)):
                    rampEdge = offsets[0].Edges[0]
                # The last edge also connects with the starting location- try that
                elif (offsets[0].Edges[-1].Length >= toold * rampD) and not (isinstance(offsets[0].Edges[-1].Curve, Part.Circle)):
                    rampEdge = offsets[0].Edges[-1]
                else:
                    FreeCAD.Console.PrintError(translate("PathPocket", "Ramp Entry location not found.\n"))
                    # print "Neither edge works: " + str(offsets[0].Edges[0]) + ", " + str(offsets[0].Edges[-1])
                    # FIXME: There's got to be a smarter way to find a place to ramp

        # For helix-ing/ramping, know where we were last time
        # FIXME: Can probably get this from the "machine"?
        lastZ = obj.ClearanceHeight.Value

        startPoint = None

        depthparams = depth_params(
                obj.ClearanceHeight.Value,
                obj.SafeHeight.Value,
                obj.StartDepth.Value,
                obj.StepDown,
                obj.FinishDepth.Value,
                obj.FinalDepth.Value)

        for vpos in depthparams.get_depths():

            first = True
            # loop over successive wires
            for currentWire in offsets:
                last = None
                for edge in currentWire.Edges:
                    if not last:
                        # we set the base GO to our fast move to our starting pos
                        if first:
                            # If we can helix, do so
                            if plungePos:
                                output += helicalPlunge(plungePos, obj.RampAngle, vpos, lastZ, self.radius*2, obj.HelixSize, self.horizFeed)
                                lastZ = vpos
                            # Otherwise, see if we can ramp
                            # FIXME: This could be a LOT smarter (eg, searching for a longer leg of the edge to ramp along)
                            elif rampEdge:
                                output += rampPlunge(rampEdge, obj.RampAngle, vpos, lastZ)
                                lastZ = vpos
                            # Otherwise, straight plunge... Don't want to, but sometimes you might not have a choice.
                            # FIXME: At least not with the lazy ramp programming above...
                            else:
                                print "WARNING: Straight-plunging... probably not good, but we didn't find a place to helix or ramp"
                                startPoint = edge.Vertexes[0].Point
                                output += "G0 Z" + fmt(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
                                output += "G0 X" + fmt(startPoint.x) + " Y" + fmt(startPoint.y) +\
                                          " Z" + fmt(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.horizRapid) + "\n"
                            first = False
                        # then move slow down to our starting point for our profile
                        last = edge.Vertexes[0].Point
                        output += "G1 X" + fmt(last.x) + " Y" + fmt(last.y) + " Z" + fmt(vpos) + " F" + fmt(self.vertFeed) + "\n"
                    if DraftGeomUtils.geomType(edge) == "Circle":
                        point = edge.Vertexes[-1].Point
                        if point == last:  # edges can come flipped
                            point = edge.Vertexes[0].Point
                        center = edge.Curve.Center
                        relcenter = center.sub(last)
                        v1 = last.sub(center)
                        v2 = point.sub(center)
                        if v1.cross(v2).z < 0:
                            output += "G2"
                        else:
                            output += "G3"
                        output += " X" + fmt(point.x) + " Y" + fmt(point.y) + " Z" + fmt(vpos)
                        output += " I" + fmt(relcenter.x) + " J" + fmt(relcenter.y) + " K" + fmt(relcenter.z)  + " F" + fmt(self.horizFeed) 
                        output += "\n"
                        last = point
                    else:
                        point = edge.Vertexes[-1].Point
                        if point == last:  # edges can come flipped
                            point = edge.Vertexes[0].Point
                        output += "G1 X" + fmt(point.x) + " Y" + fmt(point.y) + " Z" + fmt(vpos) + " F" + fmt(self.horizFeed)  + "\n"
                        last = point

        # move back up
        output += "G0 Z" + fmt(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
        return output
Пример #9
0
    def execute(self, obj):
        import Part, math, DraftGeomUtils
        pl = obj.Placement
        self.baseface = None

        base = None
        if obj.Base and obj.Angles:
            w = None
            if obj.Base.isDerivedFrom("Part::Feature"):
                if (obj.Base.Shape.Faces and obj.Face):
                    w = obj.Base.Shape.Faces[obj.Face - 1].Wires[0]
                elif obj.Base.Shape.Wires:
                    w = obj.Base.Shape.Wires[0]
            if w:
                if w.isClosed():
                    self.profilsDico = []
                    self.shps = []
                    self.subVolshps = []
                    heights = []
                    edges = DraftGeomUtils.sortEdges(w.Edges)
                    l = len(edges)
                    print("le contour contient " + str(l) + " aretes")
                    for i in range(l):
                        self.makeRoofProfilsDic(i, obj.Angles[i], obj.Runs[i],
                                                obj.IdRel[i], obj.Overhang[i],
                                                obj.Thickness[i])
                    for i in range(l):
                        self.calcMissingData(i)
                    for p in self.profilsDico:
                        heights.append(p["height"])
                    obj.Heights = heights
                    for i in range(l):
                        edgesForward = edges[:]
                        edgesForward.append(edges[0])
                        ptsPaneProject = []
                        profil0 = self.profilsDico[i - 1]
                        profil1 = self.profilsDico[i]
                        if i == l - 1:
                            profil2 = self.profilsDico[0]
                        else:
                            profil2 = self.profilsDico[i + 1]
                        vec0 = edges[i - 1].Vertexes[-1].Point.sub(
                            edges[i - 1].Vertexes[0].Point)
                        vec1 = edges[i].Vertexes[-1].Point.sub(
                            edges[i].Vertexes[0].Point)
                        vec2 = edgesForward[i + 1].Vertexes[-1].Point.sub(
                            edgesForward[i + 1].Vertexes[0].Point)
                        rotEdge0 = math.degrees(DraftVecUtils.angle(vec0))
                        rotEdge1 = math.degrees(DraftVecUtils.angle(vec1))
                        rotEdge2 = math.degrees(DraftVecUtils.angle(vec2))
                        edgeEave0 = DraftGeomUtils.offset(
                            edges[i - 1],
                            self.getPerpendicular(
                                vec0, rotEdge0,
                                profil0["overhang"]).negative())
                        edgeEave1 = DraftGeomUtils.offset(
                            edges[i],
                            self.getPerpendicular(
                                vec1, rotEdge1,
                                profil1["overhang"]).negative())
                        edgeEave2 = DraftGeomUtils.offset(
                            edgesForward[i + 1],
                            self.getPerpendicular(
                                vec2, rotEdge2,
                                profil2["overhang"]).negative())
                        pt0Eave1 = DraftGeomUtils.findIntersection(
                            edgeEave0,
                            edgeEave1,
                            infinite1=True,
                            infinite2=True,
                        )
                        pt1Eave1 = DraftGeomUtils.findIntersection(
                            edgeEave1,
                            edgeEave2,
                            infinite1=True,
                            infinite2=True,
                        )
                        edgeEave1 = DraftGeomUtils.edg(
                            FreeCAD.Vector(pt0Eave1[0]),
                            FreeCAD.Vector(pt1Eave1[0]))
                        edgeRidge0 = DraftGeomUtils.offset(
                            edges[i - 1],
                            self.getPerpendicular(vec0, rotEdge0,
                                                  profil0["run"]))
                        edgeRidge1 = DraftGeomUtils.offset(
                            edges[i],
                            self.getPerpendicular(vec1, rotEdge1,
                                                  profil1["run"]))
                        edgeRidge2 = DraftGeomUtils.offset(
                            edgesForward[i + 1],
                            self.getPerpendicular(vec2, rotEdge2,
                                                  profil2["run"]))
                        midpoint = DraftGeomUtils.findMidpoint(edges[i])
                        pt0Edge1 = edges[i].Vertexes[0].Point
                        pt1Edge1 = edges[i].Vertexes[-1].Point
                        print("Analyse profil " + str(i))
                        if profil1["angle"] != 90.:
                            if profil2["angle"] == 90.:
                                print("situation a droite : pignon")
                                ptsPaneProject.append(
                                    FreeCAD.Vector(pt1Eave1[0]))
                                point = DraftGeomUtils.findIntersection(
                                    edgeRidge1,
                                    edgeEave2,
                                    infinite1=True,
                                    infinite2=True,
                                )
                                ptsPaneProject.append(FreeCAD.Vector(point[0]))
                            elif profil1["height"] == profil2["height"]:
                                print("situation a droite : ht1 = ht2")
                                ptInterRidges = DraftGeomUtils.findIntersection(
                                    edgeRidge1,
                                    edgeRidge2,
                                    infinite1=True,
                                    infinite2=True,
                                )
                                edgeHip = DraftGeomUtils.edg(
                                    FreeCAD.Vector(ptInterRidges[0]), pt1Edge1)
                                ptInterHipEave1 = DraftGeomUtils.findIntersection(
                                    edgeHip,
                                    edgeEave1,
                                    infinite1=True,
                                    infinite2=False,
                                )
                                if ptInterHipEave1:
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(ptInterHipEave1[0]))
                                else:
                                    ptInterHipEave2 = DraftGeomUtils.findIntersection(
                                        edgeHip,
                                        edgeEave2,
                                        infinite1=True,
                                        infinite2=True,
                                    )
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(pt1Eave1[0]))
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(ptInterHipEave2[0]))
                                ptsPaneProject.append(
                                    FreeCAD.Vector(ptInterRidges[0]))
                            elif profil1["height"] > profil2["height"]:
                                print("situation a droite : ht1 > ht2")
                                dec = profil2["height"] / math.tan(
                                    math.radians(profil1["angle"]))
                                edgeRidge2OnPane = DraftGeomUtils.offset(
                                    edges[i],
                                    self.getPerpendicular(vec1, rotEdge1, dec))
                                ptInter1 = DraftGeomUtils.findIntersection(
                                    edgeRidge2,
                                    edgeRidge2OnPane,
                                    infinite1=True,
                                    infinite2=True,
                                )
                                edgeHip = DraftGeomUtils.edg(
                                    FreeCAD.Vector(ptInter1[0]), pt1Edge1)
                                ptInterHipEave1 = DraftGeomUtils.findIntersection(
                                    edgeHip,
                                    edgeEave1,
                                    infinite1=True,
                                    infinite2=False,
                                )
                                if ptInterHipEave1:
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(ptInterHipEave1[0]))
                                else:
                                    ptInterHipEave2 = DraftGeomUtils.findIntersection(
                                        edgeHip,
                                        edgeEave2,
                                        infinite1=True,
                                        infinite2=True,
                                    )
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(pt1Eave1[0]))
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(ptInterHipEave2[0]))
                                ptsPaneProject.append(
                                    FreeCAD.Vector(ptInter1[0]))
                                ptInter2 = edgeHip.Vertexes[0].Point
                                vecInterRidges = DraftGeomUtils.findPerpendicular(
                                    ptInter2, [
                                        edgeRidge1.Edges[0],
                                    ], force=0)
                                ptInterRidges = ptInter2.add(vecInterRidges[0])
                                ptsPaneProject.append(
                                    FreeCAD.Vector(ptInterRidges))
                            elif profil1["height"] < profil2["height"]:
                                print("situation a droite : ht1 < ht2")
                                dec = profil1["height"] / math.tan(
                                    math.radians(profil2["angle"]))
                                edgeRidge2OnPane = DraftGeomUtils.offset(
                                    edgesForward[i + 1],
                                    self.getPerpendicular(vec2, rotEdge2, dec))
                                ptInter1 = DraftGeomUtils.findIntersection(
                                    edgeRidge1,
                                    edgeRidge2OnPane,
                                    infinite1=True,
                                    infinite2=True,
                                )
                                edgeHip = DraftGeomUtils.edg(
                                    FreeCAD.Vector(ptInter1[0]), pt1Edge1)
                                ptInterHipEave1 = DraftGeomUtils.findIntersection(
                                    edgeHip,
                                    edgeEave1,
                                    infinite1=True,
                                    infinite2=False,
                                )
                                if ptInterHipEave1:
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(ptInterHipEave1[0]))
                                else:
                                    ptInterHipEave2 = DraftGeomUtils.findIntersection(
                                        edgeHip,
                                        edgeEave2,
                                        infinite1=True,
                                        infinite2=True,
                                    )
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(pt1Eave1[0]))
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(ptInterHipEave2[0]))
                                ptsPaneProject.append(
                                    FreeCAD.Vector(ptInter1[0]))
                                ptInterRidges = DraftGeomUtils.findIntersection(
                                    edgeRidge1,
                                    edgeRidge2,
                                    infinite1=True,
                                    infinite2=True,
                                )
                                ptsPaneProject.append(
                                    FreeCAD.Vector(ptInterRidges[0]))
                            else:
                                print("Cas de figure non pris en charge")
                            if profil0["angle"] == 90.:
                                print("situation a gauche : pignon")
                                point = DraftGeomUtils.findIntersection(
                                    edgeRidge1,
                                    edgeEave0,
                                    infinite1=True,
                                    infinite2=True,
                                )
                                ptsPaneProject.append(FreeCAD.Vector(point[0]))
                                ptsPaneProject.append(
                                    FreeCAD.Vector(pt0Eave1[0]))
                            elif profil0["height"] == profil1["height"]:
                                print("situation a gauche : ht1 = ht0")
                                edgeRidge0 = DraftGeomUtils.offset(
                                    edges[i - 1],
                                    self.getPerpendicular(
                                        vec0, rotEdge0, profil0["run"]))
                                ptInterRidges = DraftGeomUtils.findIntersection(
                                    edgeRidge1,
                                    edgeRidge0,
                                    infinite1=True,
                                    infinite2=True,
                                )
                                ptsPaneProject.append(
                                    FreeCAD.Vector(ptInterRidges[0]))
                                edgeHip = DraftGeomUtils.edg(
                                    FreeCAD.Vector(ptInterRidges[0]), pt0Edge1)
                                ptInterHipEave3 = DraftGeomUtils.findIntersection(
                                    edgeHip,
                                    edgeEave1,
                                    infinite1=True,
                                    infinite2=False,
                                )
                                if ptInterHipEave3:
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(ptInterHipEave3[0]))
                                else:
                                    ptInterHipEave4 = DraftGeomUtils.findIntersection(
                                        edgeHip,
                                        edgeEave0,
                                        infinite1=True,
                                        infinite2=True,
                                    )
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(ptInterHipEave4[0]))
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(pt0Eave1[0]))
                            elif profil1["height"] > profil0["height"]:
                                print("situation a gauche : ht1 > ht0")
                                dec = profil0["height"] / math.tan(
                                    math.radians(profil1["angle"]))
                                edgeRidge0OnPane = DraftGeomUtils.offset(
                                    edges[i],
                                    self.getPerpendicular(vec1, rotEdge1, dec))
                                ptInter1 = DraftGeomUtils.findIntersection(
                                    edgeRidge0OnPane,
                                    edgeRidge0,
                                    infinite1=True,
                                    infinite2=True,
                                )
                                edgeHip = DraftGeomUtils.edg(
                                    FreeCAD.Vector(ptInter1[0]), pt0Edge1)
                                ptInter2 = edgeHip.Vertexes[0].Point
                                vecInterRidges = DraftGeomUtils.findPerpendicular(
                                    ptInter2, [
                                        edgeRidge1.Edges[0],
                                    ], force=0)
                                ptInterRidges = ptInter2.add(vecInterRidges[0])
                                ptsPaneProject.append(
                                    FreeCAD.Vector(ptInterRidges))
                                ptsPaneProject.append(
                                    FreeCAD.Vector(ptInter1[0]))
                                ptInterHipEave3 = DraftGeomUtils.findIntersection(
                                    edgeHip,
                                    edgeEave1,
                                    infinite1=True,
                                    infinite2=False,
                                )
                                if ptInterHipEave3:
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(ptInterHipEave3[0]))
                                else:
                                    ptInterHipEave4 = DraftGeomUtils.findIntersection(
                                        edgeHip,
                                        edgeEave0,
                                        infinite1=True,
                                        infinite2=True,
                                    )
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(ptInterHipEave4[0]))
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(pt0Eave1[0]))
                            elif profil1["height"] < profil0["height"]:
                                print("situation a gauche : ht1 < ht0")
                                dec = profil1["height"] / math.tan(
                                    math.radians(profil0["angle"]))
                                edgeRidge0OnPane = DraftGeomUtils.offset(
                                    edges[i - 1],
                                    self.getPerpendicular(vec0, rotEdge0, dec))
                                ptInterRidges = DraftGeomUtils.findIntersection(
                                    edgeRidge0OnPane,
                                    edgeRidge1,
                                    infinite1=True,
                                    infinite2=True,
                                )
                                ptsPaneProject.append(
                                    FreeCAD.Vector(ptInterRidges[0]))
                                edgeHip = DraftGeomUtils.edg(
                                    FreeCAD.Vector(ptInterRidges[0]), pt0Edge1)
                                ptInterHipEave3 = DraftGeomUtils.findIntersection(
                                    edgeHip,
                                    edgeEave1,
                                    infinite1=True,
                                    infinite2=False,
                                )
                                if ptInterHipEave3:
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(ptInterHipEave3[0]))
                                else:
                                    ptInterHipEave4 = DraftGeomUtils.findIntersection(
                                        edgeHip,
                                        edgeEave0,
                                        infinite1=True,
                                        infinite2=True,
                                    )
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(ptInterHipEave4[0]))
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(pt0Eave1[0]))
                            else:
                                print("Cas de figure non pris en charge")
                            ptsPaneProject = DraftVecUtils.removeDoubles(
                                ptsPaneProject)
                            print("ptsPaneProject", ptsPaneProject)
                            print("Fin Analyse profil " + str(i))
                            self.profilsDico[i]["points"] = ptsPaneProject
                            lp = len(ptsPaneProject)
                            ptsPaneProject.append(ptsPaneProject[0])
                            edgesWire = []
                            for i in range(lp):
                                edge = Part.makeLine(ptsPaneProject[i],
                                                     ptsPaneProject[i + 1])
                                edgesWire.append(edge)
                            wire = Part.Wire(edgesWire)
                            d = wire.BoundBox.DiagonalLength
                            thicknessV = profil1["thickness"] / (math.cos(
                                math.radians(profil1["angle"])))
                            overhangV = profil1["overhang"] * math.tan(
                                math.radians(profil1["angle"]))
                            if wire.isClosed():
                                f = Part.Face(wire)
                                f = f.extrude(
                                    FreeCAD.Vector(
                                        0, 0, profil1["height"] +
                                        2 * thicknessV + 2 * overhangV))
                                f.translate(
                                    FreeCAD.Vector(0.0, 0.0, -2 * overhangV))
                            ptsPaneProfil = [
                                FreeCAD.Vector(-profil1["overhang"],
                                               -overhangV, 0.0),
                                FreeCAD.Vector(profil1["run"],
                                               profil1["height"], 0.0),
                                FreeCAD.Vector(profil1["run"],
                                               profil1["height"] + thicknessV,
                                               0.0),
                                FreeCAD.Vector(-profil1["overhang"],
                                               -overhangV + thicknessV, 0.0)
                            ]
                            self.createProfilShape(ptsPaneProfil, midpoint,
                                                   rotEdge1, vec1,
                                                   profil1["run"], d,
                                                   self.shps, f)
                            ## subVolume shape
                            ptsSubVolumeProfil = [
                                FreeCAD.Vector(-profil1["overhang"],
                                               -overhangV, 0.0),
                                FreeCAD.Vector(profil1["run"],
                                               profil1["height"], 0.0),
                                FreeCAD.Vector(profil1["run"],
                                               profil1["height"] + 10000, 0.0),
                                FreeCAD.Vector(0.0, profil1["height"] + 10000,
                                               0.0)
                            ]
                            self.createProfilShape(ptsSubVolumeProfil,
                                                   midpoint, rotEdge1, vec1,
                                                   profil1["run"], d,
                                                   self.subVolshps, f)
                        else:
                            #TODO PIGNON
                            pass

                    ## SubVolume
                    self.sub = self.subVolshps.pop()
                    for s in self.subVolshps:
                        self.sub = self.sub.fuse(s)
                    self.sub = self.sub.removeSplitter()
                    if not self.sub.isNull():
                        if not DraftGeomUtils.isNull(pl):
                            self.sub.Placement = pl
                    ## BaseVolume
                    base = Part.makeCompound(self.shps)
                    if not base.isNull():
                        if not DraftGeomUtils.isNull(pl):
                            base.Placement = pl
        base = self.processSubShapes(obj, base)
        if base:
            if not base.isNull():
                obj.Shape = base
Пример #10
0
    def execute(self,obj):
        import Part, math, DraftGeomUtils
        pl = obj.Placement
        self.baseface = None

        base = None
        if obj.Base and obj.Angles:
            w = None
            if obj.Base.isDerivedFrom("Part::Feature"):
                if (obj.Base.Shape.Faces and obj.Face):
                    w = obj.Base.Shape.Faces[obj.Face-1].Wires[0]
                elif obj.Base.Shape.Wires:
                    w = obj.Base.Shape.Wires[0]
            if w:
                if w.isClosed():
                    self.profilsDico = []
                    self.shps = []
                    self.subVolshps = []
                    heights = []
                    edges = DraftGeomUtils.sortEdges(w.Edges)
                    l = len(edges)
                    print("le contour contient "+str(l)+" aretes")
                    for i in range(l):
                        self.makeRoofProfilsDic(i, obj.Angles[i], obj.Runs[i], obj.IdRel[i], obj.Overhang[i], obj.Thickness[i])
                    for i in range(l):
                        self.calcMissingData(i)
                    for p in self.profilsDico:
                        heights.append(p["height"])
                    obj.Heights = heights
                    for i in range(l):
                        edgesForward = edges[:]
                        edgesForward.append(edges[0])
                        ptsPaneProject=[]
                        profil0 =self.profilsDico[i-1]
                        profil1 =self.profilsDico[i]
                        if i == l-1:
                            profil2 =self.profilsDico[0]
                        else:
                            profil2 =self.profilsDico[i+1]
                        vec0 = edges[i-1].Vertexes[-1].Point.sub(edges[i-1].Vertexes[0].Point)
                        vec1 = edges[i].Vertexes[-1].Point.sub(edges[i].Vertexes[0].Point)
                        vec2 = edgesForward[i+1].Vertexes[-1].Point.sub(edgesForward[i+1].Vertexes[0].Point)
                        rotEdge0 = math.degrees(DraftVecUtils.angle(vec0))
                        rotEdge1 = math.degrees(DraftVecUtils.angle(vec1))
                        rotEdge2 = math.degrees(DraftVecUtils.angle(vec2))
                        edgeEave0 = DraftGeomUtils.offset(edges[i-1],self.getPerpendicular(vec0,rotEdge0,profil0["overhang"]).negative())
                        edgeEave1 = DraftGeomUtils.offset(edges[i],self.getPerpendicular(vec1,rotEdge1,profil1["overhang"]).negative())
                        edgeEave2 = DraftGeomUtils.offset(edgesForward[i+1],self.getPerpendicular(vec2,rotEdge2,profil2["overhang"]).negative())
                        pt0Eave1 = DraftGeomUtils.findIntersection(edgeEave0,edgeEave1,infinite1=True,infinite2=True,)
                        pt1Eave1 = DraftGeomUtils.findIntersection(edgeEave1,edgeEave2,infinite1=True,infinite2=True,)
                        edgeEave1 = DraftGeomUtils.edg(FreeCAD.Vector(pt0Eave1[0]),FreeCAD.Vector(pt1Eave1[0]))
                        edgeRidge0 = DraftGeomUtils.offset(edges[i-1],self.getPerpendicular(vec0,rotEdge0,profil0["run"]))
                        edgeRidge1 = DraftGeomUtils.offset(edges[i],self.getPerpendicular(vec1,rotEdge1,profil1["run"]))
                        edgeRidge2 = DraftGeomUtils.offset(edgesForward[i+1],self.getPerpendicular(vec2,rotEdge2,profil2["run"]))
                        midpoint = DraftGeomUtils.findMidpoint(edges[i])
                        pt0Edge1 = edges[i].Vertexes[0].Point
                        pt1Edge1 = edges[i].Vertexes[-1].Point
                        print("Analyse profil " + str(i))
                        if profil1["angle"] != 90.:
                            if profil2["angle"] == 90. :
                                print("situation a droite : pignon")
                                ptsPaneProject.append(FreeCAD.Vector(pt1Eave1[0]))
                                point = DraftGeomUtils.findIntersection(edgeRidge1,edgeEave2,infinite1=True,infinite2=True,)
                                ptsPaneProject.append(FreeCAD.Vector(point[0]))
                            elif profil1["height"] == profil2["height"] :
                                print("situation a droite : ht1 = ht2")
                                ptInterRidges = DraftGeomUtils.findIntersection(edgeRidge1,edgeRidge2,infinite1=True,infinite2=True,)
                                edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInterRidges[0]),pt1Edge1)
                                ptInterHipEave1 = DraftGeomUtils.findIntersection(edgeHip,edgeEave1,infinite1=True,infinite2=False,)
                                if ptInterHipEave1:
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave1[0]))
                                else:
                                    ptInterHipEave2 = DraftGeomUtils.findIntersection(edgeHip,edgeEave2,infinite1=True,infinite2=True,)
                                    ptsPaneProject.append(FreeCAD.Vector(pt1Eave1[0]))
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave2[0]))
                                ptsPaneProject.append(FreeCAD.Vector(ptInterRidges[0]))
                            elif profil1["height"] > profil2["height"]:
                                print("situation a droite : ht1 > ht2")
                                dec = profil2["height"]/math.tan(math.radians(profil1["angle"]))
                                edgeRidge2OnPane = DraftGeomUtils.offset(edges[i],self.getPerpendicular(vec1,rotEdge1,dec))
                                ptInter1 = DraftGeomUtils.findIntersection(edgeRidge2,edgeRidge2OnPane,infinite1=True,infinite2=True,)
                                edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInter1[0]),pt1Edge1)
                                ptInterHipEave1 = DraftGeomUtils.findIntersection(edgeHip,edgeEave1,infinite1=True,infinite2=False,)
                                if ptInterHipEave1:
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave1[0]))
                                else:
                                    ptInterHipEave2 = DraftGeomUtils.findIntersection(edgeHip,edgeEave2,infinite1=True,infinite2=True,)
                                    ptsPaneProject.append(FreeCAD.Vector(pt1Eave1[0]))
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave2[0]))
                                ptsPaneProject.append(FreeCAD.Vector(ptInter1[0]))
                                ptInter2 = edgeHip.Vertexes[0].Point
                                vecInterRidges = DraftGeomUtils.findPerpendicular(ptInter2, [edgeRidge1.Edges[0],], force=0)
                                ptInterRidges = ptInter2.add(vecInterRidges[0])
                                ptsPaneProject.append(FreeCAD.Vector(ptInterRidges))
                            elif profil1["height"] < profil2["height"]:
                                print("situation a droite : ht1 < ht2")
                                dec = profil1["height"]/math.tan(math.radians(profil2["angle"]))
                                edgeRidge2OnPane = DraftGeomUtils.offset(edgesForward[i+1],self.getPerpendicular(vec2,rotEdge2,dec))
                                ptInter1 = DraftGeomUtils.findIntersection(edgeRidge1,edgeRidge2OnPane,infinite1=True,infinite2=True,)
                                edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInter1[0]),pt1Edge1)
                                ptInterHipEave1 = DraftGeomUtils.findIntersection(edgeHip,edgeEave1,infinite1=True,infinite2=False,)
                                if ptInterHipEave1:
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave1[0]))
                                else:
                                    ptInterHipEave2 = DraftGeomUtils.findIntersection(edgeHip,edgeEave2,infinite1=True,infinite2=True,)
                                    ptsPaneProject.append(FreeCAD.Vector(pt1Eave1[0]))
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave2[0]))
                                ptsPaneProject.append(FreeCAD.Vector(ptInter1[0]))
                                ptInterRidges = DraftGeomUtils.findIntersection(edgeRidge1,edgeRidge2,infinite1=True,infinite2=True,)
                                ptsPaneProject.append(FreeCAD.Vector(ptInterRidges[0]))
                            else:
                                print("Cas de figure non pris en charge")
                            if profil0["angle"] == 90. :
                                print("situation a gauche : pignon")
                                point = DraftGeomUtils.findIntersection(edgeRidge1,edgeEave0,infinite1=True,infinite2=True,)
                                ptsPaneProject.append(FreeCAD.Vector(point[0]))
                                ptsPaneProject.append(FreeCAD.Vector(pt0Eave1[0]))
                            elif profil0["height"] == profil1["height"]:
                                print("situation a gauche : ht1 = ht0")
                                edgeRidge0 = DraftGeomUtils.offset(edges[i-1],self.getPerpendicular(vec0,rotEdge0,profil0["run"]))
                                ptInterRidges = DraftGeomUtils.findIntersection(edgeRidge1,edgeRidge0,infinite1=True,infinite2=True,)
                                ptsPaneProject.append(FreeCAD.Vector(ptInterRidges[0]))
                                edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInterRidges[0]),pt0Edge1)
                                ptInterHipEave3 = DraftGeomUtils.findIntersection(edgeHip,edgeEave1,infinite1=True,infinite2=False,)
                                if ptInterHipEave3:
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave3[0]))
                                else:
                                    ptInterHipEave4 = DraftGeomUtils.findIntersection(edgeHip,edgeEave0,infinite1=True,infinite2=True,)
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave4[0]))
                                    ptsPaneProject.append(FreeCAD.Vector(pt0Eave1[0]))
                            elif profil1["height"] > profil0["height"]:
                                print("situation a gauche : ht1 > ht0")
                                dec = profil0["height"]/math.tan(math.radians(profil1["angle"]))
                                edgeRidge0OnPane = DraftGeomUtils.offset(edges[i],self.getPerpendicular(vec1,rotEdge1,dec))
                                ptInter1 = DraftGeomUtils.findIntersection(edgeRidge0OnPane,edgeRidge0,infinite1=True,infinite2=True,)
                                edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInter1[0]),pt0Edge1)
                                ptInter2 = edgeHip.Vertexes[0].Point
                                vecInterRidges = DraftGeomUtils.findPerpendicular(ptInter2, [edgeRidge1.Edges[0],], force=0)
                                ptInterRidges = ptInter2.add(vecInterRidges[0])
                                ptsPaneProject.append(FreeCAD.Vector(ptInterRidges))
                                ptsPaneProject.append(FreeCAD.Vector(ptInter1[0]))
                                ptInterHipEave3 = DraftGeomUtils.findIntersection(edgeHip,edgeEave1,infinite1=True,infinite2=False,)
                                if ptInterHipEave3:
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave3[0]))
                                else:
                                    ptInterHipEave4 = DraftGeomUtils.findIntersection(edgeHip,edgeEave0,infinite1=True,infinite2=True,)
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave4[0]))
                                    ptsPaneProject.append(FreeCAD.Vector(pt0Eave1[0]))
                            elif profil1["height"] < profil0["height"]:
                                print("situation a gauche : ht1 < ht0")
                                dec = profil1["height"]/math.tan(math.radians(profil0["angle"]))
                                edgeRidge0OnPane = DraftGeomUtils.offset(edges[i-1],self.getPerpendicular(vec0,rotEdge0,dec))
                                ptInterRidges = DraftGeomUtils.findIntersection(edgeRidge0OnPane,edgeRidge1,infinite1=True,infinite2=True,)
                                ptsPaneProject.append(FreeCAD.Vector(ptInterRidges[0]))
                                edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInterRidges[0]),pt0Edge1)
                                ptInterHipEave3 = DraftGeomUtils.findIntersection(edgeHip,edgeEave1,infinite1=True,infinite2=False,)
                                if ptInterHipEave3:
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave3[0]))
                                else:
                                    ptInterHipEave4 = DraftGeomUtils.findIntersection(edgeHip,edgeEave0,infinite1=True,infinite2=True,)
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave4[0]))
                                    ptsPaneProject.append(FreeCAD.Vector(pt0Eave1[0]))
                            else:
                                print("Cas de figure non pris en charge")
                            ptsPaneProject = DraftVecUtils.removeDoubles(ptsPaneProject)
                            print("ptsPaneProject",ptsPaneProject)
                            print("Fin Analyse profil " + str(i))
                            self.profilsDico[i]["points"] = ptsPaneProject
                            lp = len(ptsPaneProject)
                            ptsPaneProject.append(ptsPaneProject[0])
                            edgesWire = []
                            for i in range(lp):
                                edge = Part.makeLine(ptsPaneProject[i],ptsPaneProject[i+1])
                                edgesWire.append(edge)
                            wire = Part.Wire(edgesWire)
                            d = wire.BoundBox.DiagonalLength
                            thicknessV = profil1["thickness"]/(math.cos(math.radians(profil1["angle"])))
                            overhangV = profil1["overhang"]*math.tan(math.radians(profil1["angle"]))
                            if wire.isClosed():
                                f = Part.Face(wire)
                                f = f.extrude(FreeCAD.Vector(0,0,profil1["height"]+2*thicknessV+2*overhangV))
                                f.translate(FreeCAD.Vector(0.0,0.0,-2*overhangV))
                            ptsPaneProfil=[FreeCAD.Vector(-profil1["overhang"],-overhangV,0.0),FreeCAD.Vector(profil1["run"],profil1["height"],0.0),FreeCAD.Vector(profil1["run"],profil1["height"]+thicknessV,0.0),FreeCAD.Vector(-profil1["overhang"],-overhangV+thicknessV,0.0)]
                            self.createProfilShape (ptsPaneProfil, midpoint, rotEdge1, vec1, profil1["run"], d, self.shps, f)
                            ## subVolume shape
                            ptsSubVolumeProfil=[FreeCAD.Vector(-profil1["overhang"],-overhangV,0.0),FreeCAD.Vector(profil1["run"],profil1["height"],0.0),FreeCAD.Vector(profil1["run"],profil1["height"]+10000,0.0),FreeCAD.Vector(0.0,profil1["height"]+10000,0.0)]
                            self.createProfilShape (ptsSubVolumeProfil, midpoint, rotEdge1, vec1, profil1["run"], d, self.subVolshps, f)
                        else:
                            #TODO PIGNON
                            pass

                    ## SubVolume
                    self.sub = self.subVolshps.pop()
                    for s in self.subVolshps:
                        self.sub = self.sub.fuse(s)
                    self.sub = self.sub.removeSplitter()
                    if not self.sub.isNull():
                        if not DraftGeomUtils.isNull(pl):
                            self.sub.Placement = pl
                    ## BaseVolume
                    base = Part.makeCompound(self.shps)
                    if not base.isNull():
                        if not DraftGeomUtils.isNull(pl):
                            base.Placement = pl
        base = self.processSubShapes(obj,base)
        if base:
            if not base.isNull():
                obj.Shape = base