Exemplo n.º 1
0
    def test20(self):
        '''Start and end are equal or start lower than finish '''
        clearance_height= 15
        safe_height = 12

        start_depth = 10
        step_down = 2
        z_finish_step = 0
        final_depth = 10
        user_depths =  None

        expected =[10]

        d = PathUtils.depth_params(clearance_height, safe_height, start_depth, step_down, z_finish_step, final_depth, user_depths)
        r = [i for i in d]
        self.assertListEqual (r, expected)

        start_depth = 10
        final_depth = 15

        expected =[]

        d = PathUtils.depth_params(clearance_height, safe_height, start_depth, step_down, z_finish_step, final_depth, user_depths)
        r = [i for i in d]
        self.assertListEqual (r, expected)
Exemplo n.º 2
0
    def test20(self):
        '''Start and end are equal or start lower than finish '''
        clearance_height = 15
        rapid_safety_space = 12

        start_depth = 10
        step_down = 2
        z_finish_step = 0
        final_depth = 10
        user_depths = None

        expected = []

        d = PU.depth_params(clearance_height, rapid_safety_space, start_depth,
                            step_down, z_finish_step, final_depth, user_depths)
        r = d.get_depths()
        self.assertListEqual(r, expected)

        start_depth = 10
        final_depth = 15

        expected = []

        d = PU.depth_params(clearance_height, rapid_safety_space, start_depth,
                            step_down, z_finish_step, final_depth, user_depths)
        r = d.get_depths()
        self.assertListEqual(r, expected)
Exemplo n.º 3
0
    def test20(self):
        """Start and end are equal or start lower than finish"""

        args = {
            "clearance_height": 15,
            "safe_height": 12,
            "start_depth": 10,
            "step_down": 2,
            "z_finish_step": 0,
            "final_depth": 10,
            "user_depths": None,
        }
        expected = [10]

        d = PathUtils.depth_params(**args)
        r = [i for i in d]
        self.assertListEqual(r, expected)

        args["start_depth"] = 10
        args["final_depth"] = 15

        expected = []

        d = PathUtils.depth_params(**args)
        r = [i for i in d]
        self.assertListEqual(r, expected)
Exemplo n.º 4
0
    def test20(self):
        '''Start and end are equal or start lower than finish '''
        clearance_height = 15
        rapid_safety_space = 12

        start_depth = 10
        step_down = 2
        z_finish_step = 0
        final_depth = 10
        user_depths = None

        expected = [10]

        d = PU.depth_params(clearance_height, rapid_safety_space, start_depth,
                            step_down, z_finish_step, final_depth, user_depths)
        r = d.get_depths()
        self.assertListEqual(r, expected)

        start_depth = 10
        final_depth = 15

        expected = []

        d = PU.depth_params(clearance_height, rapid_safety_space, start_depth,
                            step_down, z_finish_step, final_depth, user_depths)
        r = d.get_depths()
        self.assertListEqual(r, expected)
Exemplo n.º 5
0
    def test20(self):
        '''Start and end are equal or start lower than finish '''
        clearance_height= 15
        safe_height = 12

        start_depth = 10
        step_down = 2
        z_finish_step = 0
        final_depth = 10
        user_depths =  None

        expected =[10]

        d = PU.depth_params(clearance_height, safe_height, start_depth, step_down, z_finish_step, final_depth, user_depths)
        r = [i for i in d]
        self.assertListEqual (r, expected)

        start_depth = 10
        final_depth = 15

        expected =[]

        d = PU.depth_params(clearance_height, safe_height, start_depth, step_down, z_finish_step, final_depth, user_depths)
        r = [i for i in d]
        self.assertListEqual (r, expected)
Exemplo n.º 6
0
    def test010(self):
        """stepping down with single stepdown roughly equal to total depth"""
        args = {
            "clearance_height": 20.0,
            "safe_height": 15.0,
            "start_depth": 10.000000001,
            "step_down": 10.0,
            "z_finish_step": 0.0,
            "final_depth": 0.0,
            "user_depths": None,
        }

        expected = [0]

        d = PathUtils.depth_params(**args)
        r = [i for i in d]
        self.assertListEqual(
            r, expected, "Expected {}, but result of {}".format(expected, r))

        args = {
            "clearance_height": 20.0,
            "safe_height": 15.0,
            "start_depth": 10.0,
            "step_down": 9.9999999,
            "z_finish_step": 0.0,
            "final_depth": 0.0,
            "user_depths": None,
        }

        d = PathUtils.depth_params(**args)
        r = [i for i in d]
        self.assertListEqual(
            r, expected, "Expected {}, but result of {}".format(expected, r))
Exemplo n.º 7
0
    def test80(self):
        """Test handling of negative step-down, negative finish step, and relative size of step/finish"""

        # negative steps should be converted to positive values
        args = {
            "clearance_height": 3,
            "safe_height": 3,
            "start_depth": 2,
            "step_down": -1,
            "z_finish_step": -1,
            "final_depth": 0,
            "user_depths": None,
        }

        expected = [1.0, 0]

        d = PathUtils.depth_params(**args)
        r = [i for i in d]
        self.assertListEqual(r, expected)

        # a step_down less than the finish step is an error
        args = {
            "clearance_height": 3,
            "safe_height": 3,
            "start_depth": 2,
            "step_down": 0.1,
            "z_finish_step": 1,
            "final_depth": 0,
            "user_depths": None,
        }
        self.assertRaises(ValueError, PathUtils.depth_params, **args)
Exemplo n.º 8
0
 def _customDepthParams(self, obj, strDep, finDep):
     finish_step = obj.FinishDepth.Value if hasattr(obj, "FinishDepth") else 0.0
     cdp = PathUtils.depth_params(
         clearance_height=obj.ClearanceHeight.Value,
         safe_height=obj.SafeHeight.Value,
         start_depth=strDep,
         step_down=obj.StepDown.Value,
         z_finish_step=finish_step,
         final_depth=finDep,
         user_depths=None)
     return cdp
Exemplo n.º 9
0
    def test70(self):
        '''stepping down with stepdown greater than total depth'''
        clearance_height= 10
        rapid_safety_space = 5

        start_depth = 10
        step_down = 20
        z_finish_step = 1
        final_depth = 0
        user_depths =  None

        expected =[1.0, 0]

        d = PU.depth_params(clearance_height, rapid_safety_space, start_depth, step_down, z_finish_step, final_depth, user_depths)
        r = d.get_depths(equalstep=True)
        self.assertListEqual (r, expected)

        d = PU.depth_params(clearance_height, rapid_safety_space, start_depth, step_down, z_finish_step, final_depth, user_depths)
        r = d.get_depths()
        self.assertListEqual (r, expected)
Exemplo n.º 10
0
    def opExecute(self, obj, getsim=False):
        '''opExecute(obj, getsim=False) ... implementation of Path.Area ops.
        determines the parameters for _buildPathArea().
        Do not overwrite, implement
            areaOpAreaParams(obj, isHole) ... op specific area param dictionary
            areaOpPathParams(obj, isHole) ... op specific path param dictionary
            areaOpShapes(obj)             ... the shape for path area to process
            areaOpUseProjection(obj)      ... return true if operation can use projection
        instead.'''
        PathLog.track()
        self.endVector = None

        finish_step = obj.FinishDepth.Value if hasattr(obj, "FinishDepth") else 0.0
        self.depthparams = PathUtils.depth_params(
                clearance_height=obj.ClearanceHeight.Value,
                safe_height=obj.SafeHeight.Value,
                start_depth=obj.StartDepth.Value,
                step_down=obj.StepDown.Value,
                z_finish_step=finish_step,
                final_depth=obj.FinalDepth.Value,
                user_depths=None)

        if PathOp.FeatureStartPoint & self.opFeatures(obj) and obj.UseStartPoint:
            start = obj.StartPoint
        else:
            start = None

        shapes = self.areaOpShapes(obj)

        jobs = [{
            'x': s[0].BoundBox.XMax,
            'y': s[0].BoundBox.YMax,
            'shape': s
        } for s in shapes]

        jobs = PathUtils.sort_jobs(jobs, ['x', 'y'])

        shapes = [j['shape'] for j in jobs]

        sims = []
        for (shape, isHole) in shapes:
            try:
                (pp, sim) = self._buildPathArea(obj, shape, isHole, start, getsim)
                self.commandlist.extend(pp.Commands)
                sims.append(sim)
            except Exception as e:
                FreeCAD.Console.PrintError(e)
                FreeCAD.Console.PrintError("Something unexpected happened. Check project and tool config.")

            if self.areaOpRetractTool(obj):
                self.endVector = None

        return sims
Exemplo n.º 11
0
    def test70(self):
        '''stepping down with stepdown greater than total depth'''
        clearance_height = 10
        rapid_safety_space = 5

        start_depth = 10
        step_down = 20
        z_finish_step = 1
        final_depth = 0
        user_depths = None

        expected = [1.0, 0]

        d = PU.depth_params(clearance_height, rapid_safety_space, start_depth,
                            step_down, z_finish_step, final_depth, user_depths)
        r = d.get_depths(equalstep=True)
        self.assertListEqual(r, expected)

        d = PU.depth_params(clearance_height, rapid_safety_space, start_depth,
                            step_down, z_finish_step, final_depth, user_depths)
        r = d.get_depths()
        self.assertListEqual(r, expected)
    def test30(self):
        '''User Parameters passed in'''
        clearance_height= 10
        rapid_safety_space = 5

        start_depth = 0
        step_down = 2
        z_finish_step = 0
        final_depth = -10
        user_depths =  [2, 4, 8, 10, 11, 12]

        expected =[2, 4, 8, 10, 11, 12]

        d = PU.depth_params(clearance_height, rapid_safety_space, start_depth, step_down, z_finish_step, final_depth, user_depths)
        r = d.get_depths()
        self.assertListEqual (r, expected)
    def test00(self):
        '''Stepping down to zero '''
        clearance_height= 15
        rapid_safety_space = 12

        start_depth = 10
        step_down = 2
        z_finish_step = 1
        final_depth = 0
        user_depths =  None

        expected =[8,6,4,2,1,0]

        d = PU.depth_params(clearance_height, rapid_safety_space, start_depth, step_down, z_finish_step, final_depth, user_depths)
        r = d.get_depths()
        self.assertListEqual (r, expected)
    def test60(self):
        '''stepping down with equalstep=True and a finish depth'''
        clearance_height= 10
        rapid_safety_space = 5

        start_depth = 10
        step_down = 3
        z_finish_step = 1
        final_depth = 0
        user_depths =  None

        expected =[7.0, 4.0, 1.0, 0]

        d = PU.depth_params(clearance_height, rapid_safety_space, start_depth, step_down, z_finish_step, final_depth, user_depths)
        r = d.get_depths(equalstep=True)
        self.assertListEqual (r, expected)
    def test40(self):
        '''Finish depth passed in.'''
        clearance_height= 10
        rapid_safety_space = 5

        start_depth = 0
        step_down = 2
        z_finish_step = 1
        final_depth = -10
        user_depths =  None

        expected =[-2, -4, -6, -8, -9, -10]

        d = PU.depth_params(clearance_height, rapid_safety_space, start_depth, step_down, z_finish_step, final_depth, user_depths)
        r = d.get_depths()
        self.assertListEqual (r, expected)
Exemplo n.º 16
0
    def test50(self):
        '''stepping down with equalstep=True'''
        clearance_height= 10
        safe_height = 5

        start_depth = 10
        step_down = 3
        z_finish_step = 0
        final_depth = 0
        user_depths =  None

        expected =[7.5, 5.0, 2.5, 0]

        d = PathUtils.depth_params(clearance_height, safe_height, start_depth, step_down, z_finish_step, final_depth, user_depths, equalstep=True)
        r = [i for i in d]
        self.assertListEqual (r, expected)
Exemplo n.º 17
0
    def test40(self):
        '''z_finish_step passed in.'''
        clearance_height= 10
        safe_height = 5

        start_depth = 0
        step_down = 2
        z_finish_step = 1
        final_depth = -10
        user_depths =  None

        expected =[-2, -4, -6, -8, -9, -10]

        d = PU.depth_params(clearance_height, safe_height, start_depth, step_down, z_finish_step, final_depth, user_depths)
        r = [i for i in d]
        self.assertListEqual (r, expected)
Exemplo n.º 18
0
    def test00(self):
        '''Stepping down to zero '''
        clearance_height= 15
        safe_height = 12

        start_depth = 10
        step_down = 2
        z_finish_step = 1
        final_depth = 0
        user_depths =  None

        expected =[8,6,4,2,1,0]

        d = PU.depth_params(clearance_height, safe_height, start_depth, step_down, z_finish_step, final_depth, user_depths)
        r = [i for i in d]
        self.assertListEqual (r, expected)
Exemplo n.º 19
0
    def test30(self):
        '''User Parameters passed in'''
        clearance_height= 10
        safe_height = 5

        start_depth = 0
        step_down = 2
        z_finish_step = 0
        final_depth = -10
        user_depths =  [2, 4, 8, 10, 11, 12]

        expected =[2, 4, 8, 10, 11, 12]

        d = PU.depth_params(clearance_height, safe_height, start_depth, step_down, z_finish_step, final_depth, user_depths)
        r = [i for i in d]
        self.assertListEqual (r, expected)
Exemplo n.º 20
0
    def test70(self):
        '''stepping down with stepdown greater than total depth'''
        clearance_height= 10
        safe_height = 5

        start_depth = 10
        step_down = 20
        z_finish_step = 1
        final_depth = 0
        user_depths =  None

        expected =[1.0, 0]

        d = PU.depth_params(clearance_height, safe_height, start_depth, step_down, z_finish_step, final_depth, user_depths)
        r = [i for i in d]
        self.assertListEqual (r, expected)
Exemplo n.º 21
0
    def test60(self):
        '''stepping down with equalstep=True and a finish depth'''
        clearance_height= 10
        safe_height = 5

        start_depth = 10
        step_down = 3
        z_finish_step = 1
        final_depth = 0
        user_depths =  None

        expected =[7.0, 4.0, 1.0, 0]

        d = PU.depth_params(clearance_height, safe_height, start_depth, step_down, z_finish_step, final_depth, user_depths, equalstep=True)
        r = [i for i in d]
        self.assertListEqual (r, expected)
Exemplo n.º 22
0
    def test60(self):
        '''stepping down with equalstep=True and a finish depth'''
        clearance_height = 10
        rapid_safety_space = 5

        start_depth = 10
        step_down = 3
        z_finish_step = 1
        final_depth = 0
        user_depths = None

        expected = [7.0, 4.0, 1.0, 0]

        d = PU.depth_params(clearance_height, rapid_safety_space, start_depth,
                            step_down, z_finish_step, final_depth, user_depths)
        r = d.get_depths(equalstep=True)
        self.assertListEqual(r, expected)
Exemplo n.º 23
0
    def test00(self):
        '''Stepping down to zero '''
        clearance_height = 15
        rapid_safety_space = 12

        start_depth = 10
        step_down = 2
        z_finish_step = 1
        final_depth = 0
        user_depths = None

        expected = [8, 6, 4, 2, 1, 0]

        d = PU.depth_params(clearance_height, rapid_safety_space, start_depth,
                            step_down, z_finish_step, final_depth, user_depths)
        r = d.get_depths()
        self.assertListEqual(r, expected)
Exemplo n.º 24
0
    def test00(self):
        """Stepping down to zero"""
        args = {
            "clearance_height": 15,
            "safe_height": 12,
            "start_depth": 10,
            "step_down": 2,
            "z_finish_step": 1,
            "final_depth": 0,
            "user_depths": None,
        }

        expected = [8, 6, 4, 2, 1, 0]

        d = PathUtils.depth_params(**args)
        r = [i for i in d]
        self.assertListEqual(r, expected)
Exemplo n.º 25
0
    def test30(self):
        '''User Parameters passed in'''
        clearance_height = 10
        rapid_safety_space = 5

        start_depth = 0
        step_down = 2
        z_finish_step = 0
        final_depth = -10
        user_depths = [2, 4, 8, 10, 11, 12]

        expected = [2, 4, 8, 10, 11, 12]

        d = PU.depth_params(clearance_height, rapid_safety_space, start_depth,
                            step_down, z_finish_step, final_depth, user_depths)
        r = d.get_depths()
        self.assertListEqual(r, expected)
Exemplo n.º 26
0
    def test40(self):
        """z_finish_step passed in."""
        args = {
            "clearance_height": 10,
            "safe_height": 5,
            "start_depth": 0,
            "step_down": 2,
            "z_finish_step": 1,
            "final_depth": -10,
            "user_depths": None,
        }

        expected = [-2, -4, -6, -8, -9, -10]

        d = PathUtils.depth_params(**args)
        r = [i for i in d]
        self.assertListEqual(r, expected)
Exemplo n.º 27
0
    def test60(self):
        """stepping down with equalstep=True and a finish depth"""
        args = {
            "clearance_height": 10,
            "safe_height": 5,
            "start_depth": 10,
            "step_down": 3,
            "z_finish_step": 1,
            "final_depth": 0,
            "user_depths": None,
        }

        expected = [7.0, 4.0, 1.0, 0]

        d = PathUtils.depth_params(**args)
        r = [i for i in d]
        self.assertListEqual(r, expected)
Exemplo n.º 28
0
    def test10(self):
        '''Stepping from zero to a negative depth '''

        clearance_height= 10
        safe_height = 5

        start_depth = 0
        step_down = 2
        z_finish_step = 0
        final_depth = -10
        user_depths =  None

        expected =[-2, -4, -6, -8, -10]

        d = PU.depth_params(clearance_height, safe_height, start_depth, step_down, z_finish_step, final_depth, user_depths)
        r = [i for i in d]
        self.assertListEqual (r, expected)
Exemplo n.º 29
0
    def test70(self):
        """stepping down with stepdown greater than total depth"""
        args = {
            "clearance_height": 10,
            "safe_height": 5,
            "start_depth": 10,
            "step_down": 20,
            "z_finish_step": 1,
            "final_depth": 0,
            "user_depths": None,
        }

        expected = [1.0, 0]

        d = PathUtils.depth_params(**args)
        r = [i for i in d]
        self.assertListEqual(r, expected)
Exemplo n.º 30
0
    def test40(self):
        '''z_finish_step passed in.'''
        clearance_height = 10
        rapid_safety_space = 5

        start_depth = 0
        step_down = 2
        z_finish_step = 1
        final_depth = -10
        user_depths = None

        expected = [-2, -4, -6, -8, -9, -10]

        d = PU.depth_params(clearance_height, rapid_safety_space, start_depth,
                            step_down, z_finish_step, final_depth, user_depths)
        r = d.get_depths()
        self.assertListEqual(r, expected)
Exemplo n.º 31
0
    def test30(self):
        """User Parameters passed in"""
        args = {
            "clearance_height": 10,
            "safe_height": 5,
            "start_depth": 0,
            "step_down": 2,
            "z_finish_step": 0,
            "final_depth": -10,
            "user_depths": [2, 4, 8, 10, 11, 12],
        }

        expected = [2, 4, 8, 10, 11, 12]

        d = PathUtils.depth_params(**args)
        r = [i for i in d]
        self.assertListEqual(r, expected)
Exemplo n.º 32
0
    def test001(self):
        """Stepping from zero to a negative depth"""

        args = {
            "clearance_height": 10,
            "safe_height": 5,
            "start_depth": 0,
            "step_down": 2,
            "z_finish_step": 0,
            "final_depth": -10,
            "user_depths": None,
        }

        expected = [-2, -4, -6, -8, -10]

        d = PathUtils.depth_params(**args)
        r = [i for i in d]
        self.assertListEqual(r, expected)
Exemplo n.º 33
0
    def calculateAdaptivePocket(self, obj, base, subObjTups):
        '''calculateAdaptivePocket(obj, base, subObjTups)
        Orient multiple faces around common facial center of mass.
        Identify edges that are connections for adjacent faces.
        Attempt to separate unconnected edges into top and bottom loops of the pocket.
        Trim the top and bottom of the pocket if available and requested.
        return: tuple with pocket shape information'''
        low = []
        high = []
        removeList = []
        Faces = []
        allEdges = []
        makeHighFace = 0
        tryNonPlanar = False
        isHighFacePlanar = True
        isLowFacePlanar = True
        faceType = 0

        for (sub, face) in subObjTups:
            Faces.append(face)

        # identify max and min face heights for top loop
        (zmin, zmax) = self.getMinMaxOfFaces(Faces)

        # Order faces around common center of mass
        subObjTups = self.orderFacesAroundCenterOfMass(subObjTups)
        # find connected edges and map to edge names of base
        (connectedEdges, touching) = self.findSharedEdges(subObjTups)
        (low, high) = self.identifyUnconnectedEdges(subObjTups, touching)

        if len(high) > 0 and obj.AdaptivePocketStart is True:
            # attempt planar face with top edges of pocket
            allEdges = []
            makeHighFace = 0
            tryNonPlanar = False
            for (sub, face, ei) in high:
                allEdges.append(face.Edges[ei])

            (hzmin, hzmax) = self.getMinMaxOfFaces(allEdges)

            try:
                highFaceShape = Part.Face(
                    Part.Wire(Part.__sortEdges__(allEdges)))
            except Exception as ee:
                PathLog.warning(ee)
                PathLog.error(
                    translate(
                        "Path",
                        "A planar adaptive start is unavailable. The non-planar will be attempted."
                    ))
                tryNonPlanar = True
            else:
                makeHighFace = 1

            if tryNonPlanar is True:
                try:
                    highFaceShape = Part.makeFilledFace(
                        Part.__sortEdges__(allEdges))  # NON-planar face method
                except Exception as eee:
                    PathLog.warning(eee)
                    PathLog.error(
                        translate(
                            "Path",
                            "The non-planar adaptive start is also unavailable."
                        ) + "(1)")
                    isHighFacePlanar = False
                else:
                    makeHighFace = 2

            if makeHighFace > 0:
                FreeCAD.ActiveDocument.addObject('Part::Feature',
                                                 'topEdgeFace')
                highFace = FreeCAD.ActiveDocument.ActiveObject
                highFace.Shape = highFaceShape
                removeList.append(highFace.Name)

            # verify non-planar face is within high edge loop Z-boundaries
            if makeHighFace == 2:
                mx = hzmax + obj.StepDown.Value
                mn = hzmin - obj.StepDown.Value
                if highFace.Shape.BoundBox.ZMax > mx or highFace.Shape.BoundBox.ZMin < mn:
                    PathLog.warning("ZMaxDiff: {};  ZMinDiff: {}".format(
                        highFace.Shape.BoundBox.ZMax - mx,
                        highFace.Shape.BoundBox.ZMin - mn))
                    PathLog.error(
                        translate(
                            "Path",
                            "The non-planar adaptive start is also unavailable."
                        ) + "(2)")
                    isHighFacePlanar = False
                    makeHighFace = 0
        else:
            isHighFacePlanar = False

        if len(low) > 0 and obj.AdaptivePocketFinish is True:
            # attempt planar face with bottom edges of pocket
            allEdges = []
            for (sub, face, ei) in low:
                allEdges.append(face.Edges[ei])

            # (lzmin, lzmax) = self.getMinMaxOfFaces(allEdges)

            try:
                lowFaceShape = Part.Face(
                    Part.Wire(Part.__sortEdges__(allEdges)))
                # lowFaceShape = Part.makeFilledFace(Part.__sortEdges__(allEdges))  # NON-planar face method
            except Exception as ee:
                PathLog.error(ee)
                PathLog.error("An adaptive finish is unavailable.")
                isLowFacePlanar = False
            else:
                FreeCAD.ActiveDocument.addObject('Part::Feature',
                                                 'bottomEdgeFace')
                lowFace = FreeCAD.ActiveDocument.ActiveObject
                lowFace.Shape = lowFaceShape
                removeList.append(lowFace.Name)
        else:
            isLowFacePlanar = False

        # Start with a regular pocket envelope
        strDep = obj.StartDepth.Value
        finDep = obj.FinalDepth.Value
        cuts = []
        starts = []
        finals = []
        starts.append(obj.StartDepth.Value)
        finals.append(zmin)
        if obj.AdaptivePocketStart is True or len(subObjTups) == 1:
            strDep = zmax + obj.StepDown.Value
            starts.append(zmax + obj.StepDown.Value)

        finish_step = obj.FinishDepth.Value if hasattr(obj,
                                                       "FinishDepth") else 0.0
        depthparams = PathUtils.depth_params(
            clearance_height=obj.ClearanceHeight.Value,
            safe_height=obj.SafeHeight.Value,
            start_depth=strDep,
            step_down=obj.StepDown.Value,
            z_finish_step=finish_step,
            final_depth=finDep,
            user_depths=None)
        shape = Part.makeCompound(Faces)
        env = PathUtils.getEnvelope(base[0].Shape,
                                    subshape=shape,
                                    depthparams=depthparams)
        cuts.append(env.cut(base[0].Shape))

        # Might need to change to .cut(job.Stock.Shape) if pocket has no bottom
        # job = PathUtils.findParentJob(obj)
        # envBody = env.cut(job.Stock.Shape)

        if isHighFacePlanar is True and len(subObjTups) > 1:
            starts.append(hzmax + obj.StepDown.Value)
            # make shape to trim top of reg pocket
            strDep1 = obj.StartDepth.Value + (hzmax - hzmin)
            if makeHighFace == 1:
                # Planar face
                finDep1 = highFace.Shape.BoundBox.ZMin + obj.StepDown.Value
            else:
                # Non-Planar face
                finDep1 = hzmin + obj.StepDown.Value
            depthparams1 = PathUtils.depth_params(
                clearance_height=obj.ClearanceHeight.Value,
                safe_height=obj.SafeHeight.Value,
                start_depth=strDep1,
                step_down=obj.StepDown.Value,
                z_finish_step=finish_step,
                final_depth=finDep1,
                user_depths=None)
            envTop = PathUtils.getEnvelope(base[0].Shape,
                                           subshape=highFace.Shape,
                                           depthparams=depthparams1)
            cbi = len(cuts) - 1
            cuts.append(cuts[cbi].cut(envTop))

        if isLowFacePlanar is True and len(subObjTups) > 1:
            # make shape to trim top of pocket
            if makeHighFace == 1:
                # Planar face
                strDep2 = lowFace.Shape.BoundBox.ZMax
            else:
                # Non-Planar face
                strDep2 = hzmax
            finDep2 = obj.FinalDepth.Value
            depthparams2 = PathUtils.depth_params(
                clearance_height=obj.ClearanceHeight.Value,
                safe_height=obj.SafeHeight.Value,
                start_depth=strDep2,
                step_down=obj.StepDown.Value,
                z_finish_step=finish_step,
                final_depth=finDep2,
                user_depths=None)
            envBottom = PathUtils.getEnvelope(base[0].Shape,
                                              subshape=lowFace.Shape,
                                              depthparams=depthparams2)
            cbi = len(cuts) - 1
            cuts.append(cuts[cbi].cut(envBottom))

        # package pocket details into tuple
        sdi = len(starts) - 1
        fdi = len(finals) - 1
        cbi = len(cuts) - 1
        pocket = (cuts[cbi], False, '3DPocket', 0.0, 'X', starts[sdi],
                  finals[fdi])
        if FreeCAD.GuiUp:
            import FreeCADGui
            for rn in removeList:
                FreeCADGui.ActiveDocument.getObject(rn).Visibility = False

        for rn in removeList:
            FreeCAD.ActiveDocument.getObject(rn).purgeTouched()
            self.tempObjectNames.append(rn)
        return pocket
Exemplo n.º 34
0
def GenerateGCode(op,obj,adaptiveResults, helixDiameter):
    # pylint: disable=unused-argument
    if len(adaptiveResults) == 0 or len(adaptiveResults[0]["AdaptivePaths"]) == 0:
        return

    # minLiftDistance = op.tool.Diameter
    helixRadius = 0
    for region in adaptiveResults:
        p1 =  region["HelixCenterPoint"]
        p2 =  region["StartPoint"]
        r =math.sqrt((p1[0]-p2[0]) * (p1[0]-p2[0]) +  (p1[1]-p2[1]) * (p1[1]-p2[1]))
        if r > helixRadius:
            helixRadius = r

    stepDown = obj.StepDown.Value
    passStartDepth=obj.StartDepth.Value

    if stepDown < 0.1 :
        stepDown = 0.1

    length = 2*math.pi * helixRadius

    if float(obj.HelixAngle) < 1:
        obj.HelixAngle = 1

    helixAngleRad = math.pi * float(obj.HelixAngle) / 180.0
    depthPerOneCircle = length * math.tan(helixAngleRad)
    #print("Helix circle depth: {}".format(depthPerOneCircle))

    stepUp = obj.LiftDistance.Value
    if stepUp < 0:
        stepUp = 0


    finish_step = obj.FinishDepth.Value if hasattr(obj, "FinishDepth") else 0.0
    if finish_step > stepDown:
        finish_step = stepDown

    depth_params = PathUtils.depth_params(
            clearance_height=obj.ClearanceHeight.Value,
            safe_height=obj.SafeHeight.Value,
            start_depth=obj.StartDepth.Value,
            step_down=stepDown,
            z_finish_step=finish_step,
            final_depth=obj.FinalDepth.Value,
            user_depths=None)



    # ml: this is dangerous because it'll hide all unused variables hence forward
    #     however, I don't know what lx and ly signify so I'll leave them for now
    # pylint: disable=unused-variable
    lx = adaptiveResults[0]["HelixCenterPoint"][0]
    ly = adaptiveResults[0]["HelixCenterPoint"][1]
    lz = passStartDepth
    step = 0

    for passEndDepth in depth_params.data:
        step = step + 1

        for region in adaptiveResults:
            startAngle = math.atan2(region["StartPoint"][1] - region["HelixCenterPoint"][1], region["StartPoint"][0] - region["HelixCenterPoint"][0])

            lx = region["HelixCenterPoint"][0]
            ly = region["HelixCenterPoint"][1]

            passDepth = (passStartDepth - passEndDepth)

            p1 = region["HelixCenterPoint"]
            p2 = region["StartPoint"]
            helixRadius = math.sqrt((p1[0]-p2[0]) * (p1[0]-p2[0]) +  (p1[1]-p2[1]) * (p1[1]-p2[1]))

            # helix ramp
            if helixRadius > 0.001:
                r = helixRadius - 0.01

                maxfi =  passDepth / depthPerOneCircle * 2 * math.pi
                fi = 0
                offsetFi = -maxfi + startAngle-math.pi/16

                helixStart = [region["HelixCenterPoint"][0] + r * math.cos(offsetFi), region["HelixCenterPoint"][1] + r * math.sin(offsetFi)]

                op.commandlist.append(Path.Command("(Helix to depth: %f)"%passEndDepth))

                if obj.UseHelixArcs == False:
                    # rapid move to start point
                    op.commandlist.append(Path.Command("G0", {"X": helixStart[0], "Y": helixStart[1], "Z": obj.ClearanceHeight.Value}))

                    # rapid move to safe height
                    op.commandlist.append(Path.Command("G0", {"X": helixStart[0], "Y": helixStart[1], "Z": obj.SafeHeight.Value}))

                    # move to start depth
                    op.commandlist.append(Path.Command("G1", {"X": helixStart[0], "Y": helixStart[1], "Z": passStartDepth, "F": op.vertFeed}))

                    while fi < maxfi:
                        x = region["HelixCenterPoint"][0] + r * math.cos(fi+offsetFi)
                        y = region["HelixCenterPoint"][1] + r * math.sin(fi+offsetFi)
                        z = passStartDepth - fi / maxfi * (passStartDepth - passEndDepth)
                        op.commandlist.append(Path.Command("G1", { "X": x, "Y":y, "Z":z, "F": op.vertFeed}))
                        lx = x
                        ly = y
                        fi=fi+math.pi/16

                    # one more circle at target depth to make sure center is cleared
                    maxfi = maxfi + 2*math.pi
                    while fi < maxfi:
                        x = region["HelixCenterPoint"][0] + r * math.cos(fi+offsetFi)
                        y = region["HelixCenterPoint"][1] + r * math.sin(fi+offsetFi)
                        z = passEndDepth
                        op.commandlist.append(Path.Command("G1", { "X": x, "Y":y, "Z":z, "F": op.horizFeed}))
                        lx = x
                        ly = y
                        fi = fi + math.pi/16
                else:
                    helixStart = [region["HelixCenterPoint"][0] + r, region["HelixCenterPoint"][1]]

                    # rapid move to start point
                    op.commandlist.append(Path.Command("G0", {"X": helixStart[0], "Y": helixStart[1], "Z": obj.ClearanceHeight.Value}))

                    # rapid move to safe height
                    op.commandlist.append(Path.Command("G0", {"X": helixStart[0], "Y": helixStart[1], "Z": obj.SafeHeight.Value}))

                    # move to start depth
                    op.commandlist.append(Path.Command("G1", {"X": helixStart[0], "Y": helixStart[1], "Z": passStartDepth, "F": op.vertFeed}))

                    x = region["HelixCenterPoint"][0] + r
                    y = region["HelixCenterPoint"][1]

                    curDep = passStartDepth
                    while curDep > (passEndDepth + depthPerOneCircle):
                        op.commandlist.append(Path.Command("G2", { "X": x - (2*r), "Y": y, "Z": curDep - (depthPerOneCircle/2), "I": -r, "F": op.horizFeed}))
                        op.commandlist.append(Path.Command("G2", { "X": x, "Y": y, "Z": curDep - depthPerOneCircle, "I": r, "F": op.horizFeed}))
                        curDep = curDep - depthPerOneCircle

                    lastStep = curDep - passEndDepth
                    if lastStep > (depthPerOneCircle/2):
                        op.commandlist.append(Path.Command("G2", { "X": x - (2*r), "Y": y, "Z": curDep - (lastStep/2), "I": -r, "F": op.horizFeed}))
                        op.commandlist.append(Path.Command("G2", { "X": x, "Y": y, "Z": passEndDepth, "I": r, "F": op.horizFeed}))
                    else:
                        op.commandlist.append(Path.Command("G2", { "X": x - (2*r), "Y": y, "Z": passEndDepth, "I": -r, "F": op.horizFeed}))
                        op.commandlist.append(Path.Command("G1", {"X": x, "Y": y, "Z": passEndDepth, "F": op.vertFeed}))

                    # one more circle at target depth to make sure center is cleared
                    op.commandlist.append(Path.Command("G2", { "X": x - (2*r), "Y": y, "Z": passEndDepth, "I": -r, "F": op.horizFeed}))
                    op.commandlist.append(Path.Command("G2", { "X": x, "Y": y, "Z": passEndDepth, "I": r, "F": op.horizFeed}))
                    lx = x
                    ly = y

            else: # no helix entry
                # rapid move to clearance height
                op.commandlist.append(Path.Command("G0", {"X": region["StartPoint"][0], "Y": region["StartPoint"][1], "Z": obj.ClearanceHeight.Value}))
                # straight plunge to target depth
                op.commandlist.append(Path.Command("G1", {"X":region["StartPoint"][0], "Y": region["StartPoint"][1], "Z": passEndDepth,"F": op.vertFeed}))

            lz = passEndDepth
            z = obj.ClearanceHeight.Value
            op.commandlist.append(Path.Command("(Adaptive - depth: %f)"%passEndDepth))

            # add adaptive paths
            for pth in region["AdaptivePaths"]:
                motionType = pth[0]  #[0] contains motion type

                for pt in pth[1]:    #[1] contains list of points
                    x = pt[0]
                    y = pt[1]

                    # dist = math.sqrt((x-lx)*(x-lx) + (y-ly)*(y-ly))

                    if motionType == area.AdaptiveMotionType.Cutting:
                        z = passEndDepth
                        if z != lz:
                            op.commandlist.append(Path.Command("G1", { "Z":z,"F": op.vertFeed}))

                        op.commandlist.append(Path.Command("G1", { "X": x, "Y":y, "F": op.horizFeed}))

                    elif motionType == area.AdaptiveMotionType.LinkClear:
                        z = passEndDepth + stepUp
                        if z != lz:
                            op.commandlist.append(Path.Command("G0", { "Z":z}))

                        op.commandlist.append(Path.Command("G0", { "X": x, "Y":y}))

                    elif motionType == area.AdaptiveMotionType.LinkNotClear:
                        z = obj.ClearanceHeight.Value
                        if z != lz:
                            op.commandlist.append(Path.Command("G0", { "Z":z}))

                        op.commandlist.append(Path.Command("G0", { "X": x, "Y":y}))

                    # elif motionType == area.AdaptiveMotionType.LinkClearAtPrevPass:
                    #     if lx!=x or ly!=y:
                    #         op.commandlist.append(Path.Command("G0", { "X": lx, "Y":ly, "Z":passStartDepth+stepUp}))
                    #     op.commandlist.append(Path.Command("G0", { "X": x, "Y":y, "Z":passStartDepth+stepUp}))

                    lx = x
                    ly = y
                    lz = z

            # return to safe height in this Z pass
            z = obj.ClearanceHeight.Value
            if z != lz:
                op.commandlist.append(Path.Command("G0", { "Z":z}))

            lz = z

        passStartDepth = passEndDepth

        # return to safe height in this Z pass
        z = obj.ClearanceHeight.Value
        if z != lz:
            op.commandlist.append(Path.Command("G0", { "Z":z}))

        lz = z

    z = obj.ClearanceHeight.Value
    if z != lz:
        op.commandlist.append(Path.Command("G0", { "Z":z}))

    lz = z
Exemplo n.º 35
0
    def _waterline(self, obj, s, bb):
        import time
        import ocl

        def drawLoops(loops):
            nloop = 0
            pp = []
            pp.append(Path.Command("(waterline begin)" ))

            for loop in loops:
                p = loop[0]
                pp.append(Path.Command("(loop begin)" ))
                pp.append(Path.Command('G0', {"Z": obj.SafeHeight.Value, 'F': self.vertRapid}))
                pp.append(Path.Command('G0', {'X': p.x, "Y": p.y, 'F': self.horizRapid}))
                pp.append(Path.Command('G1', {"Z": p.z, 'F': self.vertFeed}))

                for p in loop[1:]:
                    pp.append(Path.Command('G1', {'X': p.x, "Y": p.y, "Z": p.z, 'F': self.horizFeed}))
                   # zheight = p.z
                p = loop[0]
                pp.append(Path.Command('G1', {'X': p.x, "Y": p.y, "Z": p.z, 'F': self.horizFeed}))
                pp.append(Path.Command("(loop end)" ))

                print("    loop ", nloop, " with ", len(loop), " points")
                nloop = nloop + 1
            pp.append(Path.Command("(waterline end)" ))

            return pp

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

        t_before = time.time()
        zheights = [i for i in depthparams]

        wl = ocl.Waterline()
        wl.setSTL(s)
        cutter = ocl.CylCutter(obj.ToolController.Tool.Diameter, 5)
        wl.setCutter(cutter)
        # this should be smaller than the smallest details in the STL file
        wl.setSampling(obj.SampleInterval)
        # AdaptiveWaterline() also has settings for minimum sampling interval
        # (see c++ code)
        all_loops = []
        print ("zheights: {}".format(zheights))
        for zh in zheights:
            print("calculating Waterline at z= ", zh)
            wl.reset()
            wl.setZ(zh)  # height for this waterline
            wl.run()
            all_loops.append(wl.getLoops())
        t_after = time.time()
        calctime = t_after - t_before
        n = 0
        output = []
        for loops in all_loops:  # at each z-height, we may get many loops
            print("  %d/%d:" % (n, len(all_loops)))
            output.extend(drawLoops(loops))
            n = n + 1
        print("(" + str(calctime) + ")")
        return output
Exemplo n.º 36
0
    def _waterline(self, obj, s, bb):
        import time
        import ocl

        def drawLoops(loops):
            nloop = 0
            pp = []
            pp.append(Path.Command("(waterline begin)"))

            for loop in loops:
                p = loop[0]
                pp.append(Path.Command("(loop begin)"))
                pp.append(Path.Command('G0', {"Z": obj.SafeHeight.Value, 'F': self.vertRapid}))
                pp.append(Path.Command('G0', {'X': p.x, "Y": p.y, 'F': self.horizRapid}))
                pp.append(Path.Command('G1', {"Z": p.z, 'F': self.vertFeed}))
                prev = ocl.Point(float("inf"), float("inf"), float("inf"))
                next = ocl.Point(float("inf"), float("inf"), float("inf"))
                optimize = obj.Optimize
                for i in range(1, len(loop)):
                    p = loop[i]
                    if i < len(loop) - 1:
                        next.x = loop[i + 1].x
                        next.y = loop[i + 1].y
                        next.z = loop[i + 1].z
                    else:
                        optimize = False
                    if not optimize or not self.isPointOnLine(FreeCAD.Vector(prev.x, prev.y, prev.z), FreeCAD.Vector(next.x, next.y, next.z), FreeCAD.Vector(p.x, p.y, p.z)):
                        pp.append(Path.Command('G1', {'X': p.x, "Y": p.y, "Z": p.z, 'F': self.horizFeed}))
                    prev.x = p.x
                    prev.y = p.y
                    prev.z = p.z
                    # zheight = p.z
                p = loop[0]
                pp.append(Path.Command('G1', {'X': p.x, "Y": p.y, "Z": p.z, 'F': self.horizFeed}))
                pp.append(Path.Command("(loop end)"))

                print("    loop ", nloop, " with ", len(loop), " points")
                nloop = nloop + 1
            pp.append(Path.Command("(waterline end)"))

            return pp

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

        t_before = time.time()
        zheights = [i for i in depthparams]

        wl = ocl.Waterline()
        wl.setSTL(s)

        if obj.ToolController.Tool.ToolType == 'BallEndMill':
            cutter = ocl.BallCutter(obj.ToolController.Tool.Diameter, 5)  # TODO: 5 represents cutting edge height. Should be replaced with the data from toolcontroller?
        else:
            cutter = ocl.CylCutter(obj.ToolController.Tool.Diameter, 5)

        wl.setCutter(cutter)
        # this should be smaller than the smallest details in the STL file
        wl.setSampling(obj.SampleInterval)
        # AdaptiveWaterline() also has settings for minimum sampling interval
        # (see c++ code)
        all_loops = []
        print ("zheights: {}".format(zheights))
        for zh in zheights:
            print("calculating Waterline at z= ", zh)
            wl.reset()
            wl.setZ(zh)  # height for this waterline
            wl.run()
            all_loops.append(wl.getLoops())
        t_after = time.time()
        calctime = t_after - t_before
        n = 0
        output = []
        for loops in all_loops:  # at each z-height, we may get many loops
            print("  %d/%d:" % (n, len(all_loops)))
            output.extend(drawLoops(loops))
            n = n + 1
        print("(" + str(calctime) + ")")
        return output
Exemplo n.º 37
0
    def _waterline(self, obj, s, bb):
        import time
        import ocl

        def drawLoops(loops):
            nloop = 0
            pp = []
            pp.append(Path.Command("(waterline begin)" ))

            for loop in loops:
                p = loop[0]
                pp.append(Path.Command("(loop begin)" ))
                pp.append(Path.Command('G0', {"Z": obj.SafeHeight.Value, 'F': self.vertRapid}))
                pp.append(Path.Command('G0', {'X': p.x, "Y": p.y, 'F': self.horizRapid}))
                pp.append(Path.Command('G1', {"Z": p.z, 'F': self.vertFeed}))

                for p in loop[1:]:
                    pp.append(Path.Command('G1', {'X': p.x, "Y": p.y, "Z": p.z, 'F': self.horizFeed}))
                   # zheight = p.z
                p = loop[0]
                pp.append(Path.Command('G1', {'X': p.x, "Y": p.y, "Z": p.z, 'F': self.horizFeed}))
                pp.append(Path.Command("(loop end)" ))

                print("    loop ", nloop, " with ", len(loop), " points")
                nloop = nloop + 1
            pp.append(Path.Command("(waterline end)" ))

            return pp

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

        t_before = time.time()
        zheights = [i for i in depthparams]

        wl = ocl.Waterline()
        wl.setSTL(s)
        cutter = ocl.CylCutter(obj.ToolController.Tool.Diameter, 5)
        wl.setCutter(cutter)
        # this should be smaller than the smallest details in the STL file
        wl.setSampling(obj.SampleInterval)
        # AdaptiveWaterline() also has settings for minimum sampling interval
        # (see c++ code)
        all_loops = []
        print ("zheights: {}".format(zheights))
        for zh in zheights:
            print("calculating Waterline at z= ", zh)
            wl.reset()
            wl.setZ(zh)  # height for this waterline
            wl.run()
            all_loops.append(wl.getLoops())
        t_after = time.time()
        calctime = t_after - t_before
        n = 0
        output = []
        for loops in all_loops:  # at each z-height, we may get many loops
            print("  %d/%d:" % (n, len(all_loops)))
            output.extend(drawLoops(loops))
            n = n + 1
        print("(" + str(calctime) + ")")
        return output
Exemplo n.º 38
0
    def areaOpShapes(self, obj):
        '''areaOpShapes(obj) ... returns envelope for all base shapes or wires for Arch.Panels.'''
        PathLog.track()
        PathLog.debug("----- areaOpShapes() in PathProfileFaces.py")

        if obj.UseComp:
            self.commandlist.append(
                Path.Command("(Compensated Tool Path. Diameter: " +
                             str(self.radius * 2) + ")"))
        else:
            self.commandlist.append(Path.Command("(Uncompensated Tool Path)"))

        shapes = []
        self.profileshape = []
        finalDepths = []

        baseSubsTuples = []
        subCount = 0
        allTuples = []

        if obj.Base:  # The user has selected subobjects from the base.  Process each.
            if obj.EnableRotation != 'Off':
                for p in range(0, len(obj.Base)):
                    (base, subsList) = obj.Base[p]
                    for sub in subsList:
                        subCount += 1
                        shape = getattr(base.Shape, sub)
                        if isinstance(shape, Part.Face):
                            rtn = False
                            (norm, surf) = self.getFaceNormAndSurf(shape)
                            (rtn, angle, axis,
                             praInfo) = self.faceRotationAnalysis(
                                 obj, norm, surf)
                            if rtn is True:
                                (clnBase, angle, clnStock,
                                 tag) = self.applyRotationalAnalysis(
                                     obj, base, angle, axis, subCount)
                                # Verify faces are correctly oriented - InverseAngle might be necessary
                                faceIA = getattr(clnBase.Shape, sub)
                                (norm, surf) = self.getFaceNormAndSurf(faceIA)
                                (rtn, praAngle, praAxis,
                                 praInfo) = self.faceRotationAnalysis(
                                     obj, norm, surf)
                                if rtn is True:
                                    PathLog.error(
                                        translate(
                                            "Path",
                                            "Face appears misaligned after initial rotation."
                                        ))
                                    if obj.AttemptInverseAngle is True and obj.InverseAngle is False:
                                        (clnBase, clnStock,
                                         angle) = self.applyInverseAngle(
                                             obj, clnBase, clnStock, axis,
                                             angle)
                                    else:
                                        msg = translate(
                                            "Path",
                                            "Consider toggling the 'InverseAngle' property and recomputing."
                                        )
                                        PathLog.error(msg)
                                        # title = translate("Path", 'Rotation Warning')
                                        # self.guiMessage(title, msg, False)
                                else:
                                    PathLog.debug(
                                        "Face appears to be oriented correctly."
                                    )

                                tup = clnBase, sub, tag, angle, axis, clnStock
                            else:
                                if self.warnDisabledAxis(obj, axis) is False:
                                    PathLog.debug(
                                        str(sub) + ": No rotation used")
                                axis = 'X'
                                angle = 0.0
                                tag = base.Name + '_' + axis + str(
                                    angle).replace('.', '_')
                                stock = PathUtils.findParentJob(obj).Stock
                                tup = base, sub, tag, angle, axis, stock
                            # Eif
                            allTuples.append(tup)
                        # Eif
                    # Efor
                # Efor
                if subCount > 1:
                    msg = translate('Path',
                                    "Multiple faces in Base Geometry.") + "  "
                    msg += translate(
                        'Path', "Depth settings will be applied to all faces.")
                    PathLog.warning(msg)
                    # title = translate("Path", "Depth Warning")
                    # self.guiMessage(title, msg)
                (Tags, Grps) = self.sortTuplesByIndex(
                    allTuples, 2)  # return (TagList, GroupList)
                subList = []
                for o in range(0, len(Tags)):
                    subList = []
                    for (base, sub, tag, angle, axis, stock) in Grps[o]:
                        subList.append(sub)
                    pair = base, subList, angle, axis, stock
                    baseSubsTuples.append(pair)
                # Efor
            else:
                PathLog.info(
                    translate("Path", "EnableRotation property is 'Off'."))
                stock = PathUtils.findParentJob(obj).Stock
                for (base, subList) in obj.Base:
                    baseSubsTuples.append((base, subList, 0.0, 'X', stock))

            # for base in obj.Base:
            for (base, subsList, angle, axis, stock) in baseSubsTuples:
                holes = []
                faces = []

                for sub in subsList:
                    shape = getattr(base.Shape, sub)
                    if isinstance(shape, Part.Face):
                        faces.append(shape)
                        if numpy.isclose(abs(shape.normalAt(0, 0).z),
                                         1):  # horizontal face
                            for wire in shape.Wires[1:]:
                                holes.append((base.Shape, wire))
                    else:
                        ignoreSub = base.Name + '.' + sub
                        msg = translate(
                            'Path',
                            "Found a selected object which is not a face. Ignoring: {}"
                            .format(ignoreSub))
                        PathLog.error(msg)
                        FreeCAD.Console.PrintWarning(msg)
                        # return

                for shape, wire in holes:
                    f = Part.makeFace(wire, 'Part::FaceMakerSimple')
                    drillable = PathUtils.isDrillable(shape, wire)
                    if (drillable
                            and obj.processCircles) or (not drillable
                                                        and obj.processHoles):
                        PathLog.track()
                        # Recalculate depthparams
                        (strDep, finDep) = self.calculateStartFinalDepths(
                            obj, shape, stock)
                        finalDepths.append(finDep)
                        PathLog.debug(
                            "Adjusted face depths strDep: {}, and finDep: {}".
                            format(self.strDep, self.finDep))
                        finish_step = obj.FinishDepth.Value if hasattr(
                            obj, "FinishDepth") else 0.0
                        self.depthparams = PathUtils.depth_params(
                            clearance_height=obj.ClearanceHeight.Value,
                            safe_height=obj.SafeHeight.Value,
                            start_depth=strDep,  # obj.StartDepth.Value,
                            step_down=obj.StepDown.Value,
                            z_finish_step=finish_step,
                            final_depth=finDep,  # obj.FinalDepth.Value,
                            user_depths=None)
                        env = PathUtils.getEnvelope(
                            shape, subshape=f, depthparams=self.depthparams)
                        # shapes.append((env, True))
                        tup = env, True, 'pathProfileFaces', angle, axis, strDep, finDep
                        shapes.append(tup)

                if len(faces) > 0:
                    profileshape = Part.makeCompound(faces)
                    self.profileshape.append(profileshape)

                if obj.processPerimeter:
                    PathLog.track()
                    if profileshape:
                        # Recalculate depthparams
                        (strDep, finDep) = self.calculateStartFinalDepths(
                            obj, profileshape, stock)
                        finalDepths.append(finDep)
                        PathLog.debug(
                            "Adjusted face depths strDep: {}, and finDep: {}".
                            format(self.strDep, self.finDep))
                        finish_step = obj.FinishDepth.Value if hasattr(
                            obj, "FinishDepth") else 0.0
                        self.depthparams = PathUtils.depth_params(
                            clearance_height=obj.ClearanceHeight.Value,
                            safe_height=obj.SafeHeight.Value,
                            start_depth=strDep,  # obj.StartDepth.Value,
                            step_down=obj.StepDown.Value,
                            z_finish_step=finish_step,
                            final_depth=finDep,  # obj.FinalDepth.Value,
                            user_depths=None)
                    else:
                        strDep = obj.StartDepth.Value
                        finDep = obj.FinalDepth.Value
                    try:
                        env = PathUtils.getEnvelope(
                            base.Shape,
                            subshape=profileshape,
                            depthparams=self.depthparams)
                    except Exception:
                        # PathUtils.getEnvelope() failed to return an object.
                        PathLog.error(
                            translate('Path',
                                      'Unable to create path for face(s).'))
                    else:
                        # shapes.append((env, False))
                        tup = env, False, 'pathProfileFaces', angle, axis, strDep, finDep
                        shapes.append(tup)
                else:
                    for shape in faces:
                        # Recalculate depthparams
                        (strDep, finDep) = self.calculateStartFinalDepths(
                            obj, shape, stock)
                        finalDepths.append(finDep)
                        finish_step = obj.FinishDepth.Value if hasattr(
                            obj, "FinishDepth") else 0.0
                        self.depthparams = PathUtils.depth_params(
                            clearance_height=obj.ClearanceHeight.Value,
                            safe_height=obj.SafeHeight.Value,
                            start_depth=strDep,  # obj.StartDepth.Value,
                            step_down=obj.StepDown.Value,
                            z_finish_step=finish_step,
                            final_depth=finDep,  # obj.FinalDepth.Value,
                            user_depths=None)
                        env = PathUtils.getEnvelope(
                            base.Shape,
                            subshape=shape,
                            depthparams=self.depthparams)
                        tup = env, False, 'pathProfileFaces', angle, axis, strDep, finDep
                        shapes.append(tup)
                # Eif

            # adjust FinalDepth as needed
            finalDepth = min(finalDepths)
            if obj.FinalDepth.Value < finalDepth:
                obj.FinalDepth.Value = finalDepth
        else:  # Try to build targets from the job base
            if 1 == len(self.model) and hasattr(self.model[0], "Proxy"):
                if isinstance(self.model[0].Proxy,
                              ArchPanel.PanelSheet):  # process the sheet
                    if obj.processCircles or obj.processHoles:
                        for shape in self.model[0].Proxy.getHoles(
                                self.model[0], transform=True):
                            for wire in shape.Wires:
                                drillable = PathUtils.isDrillable(
                                    self.model[0].Proxy, wire)
                                if (drillable and obj.processCircles) or (
                                        not drillable and obj.processHoles):
                                    f = Part.makeFace(wire,
                                                      'Part::FaceMakerSimple')
                                    env = PathUtils.getEnvelope(
                                        self.model[0].Shape,
                                        subshape=f,
                                        depthparams=self.depthparams)
                                    # shapes.append((env, True))
                                    tup = env, True, 'pathProfileFaces', 0.0, 'X', obj.StartDepth.Value, obj.FinalDepth.Value
                                    shapes.append(tup)

                    if obj.processPerimeter:
                        for shape in self.model[0].Proxy.getOutlines(
                                self.model[0], transform=True):
                            for wire in shape.Wires:
                                f = Part.makeFace(wire,
                                                  'Part::FaceMakerSimple')
                                env = PathUtils.getEnvelope(
                                    self.model[0].Shape,
                                    subshape=f,
                                    depthparams=self.depthparams)
                                # shapes.append((env, False))
                                tup = env, False, 'pathProfileFaces', 0.0, 'X', obj.StartDepth.Value, obj.FinalDepth.Value
                                shapes.append(tup)

        self.removalshapes = shapes
        PathLog.debug("%d shapes" % len(shapes))

        return shapes
Exemplo n.º 39
0
    def areaOpShapes(self, obj):
        '''areaOpShapes(obj) ... return shapes representing the solids to be removed.'''
        PathLog.track()

        subObjTups = []
        removalshapes = []

        if obj.Base:
            PathLog.debug("base items exist.  Processing... ")
            for base in obj.Base:
                PathLog.debug("obj.Base item: {}".format(base))

                # Check if all subs are faces
                allSubsFaceType = True
                Faces = []
                for sub in base[1]:
                    if "Face" in sub:
                        face = getattr(base[0].Shape, sub)
                        Faces.append(face)
                        subObjTups.append((sub, face))
                    else:
                        allSubsFaceType = False
                        break

                if len(Faces) == 0:
                    allSubsFaceType = False

                if allSubsFaceType is True and obj.HandleMultipleFeatures == 'Collectively':
                    if obj.OpFinalDepth == obj.FinalDepth:
                        (fzmin, fzmax) = self.getMinMaxOfFaces(Faces)
                        obj.FinalDepth.Value = fzmin
                        finish_step = obj.FinishDepth.Value if hasattr(
                            obj, "FinishDepth") else 0.0
                        self.depthparams = PathUtils.depth_params(
                            clearance_height=obj.ClearanceHeight.Value,
                            safe_height=obj.SafeHeight.Value,
                            start_depth=obj.StartDepth.Value,
                            step_down=obj.StepDown.Value,
                            z_finish_step=finish_step,
                            final_depth=fzmin,
                            user_depths=None)
                        PathLog.info(
                            "Updated obj.FinalDepth.Value and self.depthparams to zmin: {}"
                            .format(fzmin))

                    if obj.AdaptivePocketStart is True or obj.AdaptivePocketFinish is True:
                        pocketTup = self.calculateAdaptivePocket(
                            obj, base, subObjTups)
                        if pocketTup is not False:
                            removalshapes.append(
                                pocketTup
                            )  # (shape, isHole, sub, angle, axis, strDep, finDep)
                    else:
                        strDep = obj.StartDepth.Value
                        finDep = obj.FinalDepth.Value

                        shape = Part.makeCompound(Faces)
                        env = PathUtils.getEnvelope(
                            base[0].Shape,
                            subshape=shape,
                            depthparams=self.depthparams)
                        obj.removalshape = env.cut(base[0].Shape)
                        obj.removalshape.tessellate(0.1)
                        # (shape, isHole, sub, angle, axis, strDep, finDep)
                        removalshapes.append(
                            (obj.removalshape, False, '3DPocket', 0.0, 'X',
                             strDep, finDep))
                else:
                    for sub in base[1]:
                        if "Face" in sub:
                            shape = Part.makeCompound(
                                [getattr(base[0].Shape, sub)])
                        else:
                            edges = [
                                getattr(base[0].Shape, sub) for sub in base[1]
                            ]
                            shape = Part.makeFace(edges,
                                                  'Part::FaceMakerSimple')

                        env = PathUtils.getEnvelope(
                            base[0].Shape,
                            subshape=shape,
                            depthparams=self.depthparams)
                        obj.removalshape = env.cut(base[0].Shape)
                        obj.removalshape.tessellate(0.1)

                        removalshapes.append((obj.removalshape, False))

        else:  # process the job base object as a whole
            PathLog.debug("processing the whole job base object")
            strDep = obj.StartDepth.Value
            finDep = obj.FinalDepth.Value
            recomputeDepthparams = False
            for base in self.model:
                if obj.OpFinalDepth == obj.FinalDepth:
                    if base.Shape.BoundBox.ZMin < obj.FinalDepth.Value:
                        obj.FinalDepth.Value = base.Shape.BoundBox.ZMin
                        finDep = base.Shape.BoundBox.ZMin
                        recomputeDepthparams = True
                        PathLog.info(
                            "Updated obj.FinalDepth.Value to {}".format(
                                finDep))
                if obj.OpStartDepth == obj.StartDepth:
                    if base.Shape.BoundBox.ZMax > obj.StartDepth.Value:
                        obj.StartDepth.Value = base.Shape.BoundBox.ZMax
                        finDep = base.Shape.BoundBox.ZMax
                        recomputeDepthparams = True
                        PathLog.info(
                            "Updated obj.StartDepth.Value to {}".format(
                                strDep))
                if recomputeDepthparams is True:
                    finish_step = obj.FinishDepth.Value if hasattr(
                        obj, "FinishDepth") else 0.0
                    self.depthparams = PathUtils.depth_params(
                        clearance_height=obj.ClearanceHeight.Value,
                        safe_height=obj.SafeHeight.Value,
                        start_depth=obj.StartDepth.Value,
                        step_down=obj.StepDown.Value,
                        z_finish_step=finish_step,
                        final_depth=obj.FinalDepth.Value,
                        user_depths=None)
                    recomputeDepthparams = False

                if obj.ProcessStockArea is True:
                    job = PathUtils.findParentJob(obj)
                    finish_step = obj.FinishDepth.Value if hasattr(
                        obj, "FinishDepth") else 0.0

                    depthparams = PathUtils.depth_params(
                        clearance_height=obj.ClearanceHeight.Value,
                        safe_height=obj.SafeHeight.Value,
                        start_depth=obj.StartDepth.Value,
                        step_down=obj.StepDown.Value,
                        z_finish_step=finish_step,
                        final_depth=base.Shape.BoundBox.ZMin,
                        user_depths=None)
                    stockEnvShape = PathUtils.getEnvelope(
                        job.Stock.Shape,
                        subshape=None,
                        depthparams=depthparams)

                    obj.removalshape = stockEnvShape.cut(base.Shape)
                    obj.removalshape.tessellate(0.1)
                else:
                    env = PathUtils.getEnvelope(base.Shape,
                                                subshape=None,
                                                depthparams=self.depthparams)
                    obj.removalshape = env.cut(base.Shape)
                    obj.removalshape.tessellate(0.1)

                removalshapes.append((obj.removalshape, False, '3DPocket', 0.0,
                                      'X', strDep, finDep))

        return removalshapes