Esempio n. 1
0
def Execute(op,obj):
    # pylint: disable=global-statement
    global sceneGraph
    global topZ

    sceneGraph = FreeCADGui.ActiveDocument.ActiveView.getSceneGraph()

    Console.PrintMessage("*** Adaptive toolpath processing started...\n")

    #hide old toolpaths during recalculation
    obj.Path = Path.Path("(Calculating...)")

    #store old visibility state
    job = op.getJob(obj)
    oldObjVisibility = obj.ViewObject.Visibility
    oldJobVisibility = job.ViewObject.Visibility

    obj.ViewObject.Visibility = False
    job.ViewObject.Visibility = False

    FreeCADGui.updateGui()
    try:
        helixDiameter = obj.HelixDiameterLimit.Value
        topZ = op.stock.Shape.BoundBox.ZMax
        obj.Stopped = False
        obj.StopProcessing = False
        if obj.Tolerance < 0.001:
            obj.Tolerance = 0.001

        pathArray = []
        for base, subs in obj.Base:
            for sub in subs:
                shape = base.Shape.getElement(sub)
                for edge in shape.Edges:
                    pathArray.append([discretize(edge)])

        #pathArray=connectEdges(edges)
        path2d = convertTo2d(pathArray)

        stockPaths = []
        if op.stock.StockType == "CreateCylinder":
            stockPaths.append([discretize(op.stock.Shape.Edges[0])])

        else:
            stockBB = op.stock.Shape.BoundBox
            v=[]
            v.append(FreeCAD.Vector(stockBB.XMin,stockBB.YMin,0))
            v.append(FreeCAD.Vector(stockBB.XMax,stockBB.YMin,0))
            v.append(FreeCAD.Vector(stockBB.XMax,stockBB.YMax,0))
            v.append(FreeCAD.Vector(stockBB.XMin,stockBB.YMax,0))
            v.append(FreeCAD.Vector(stockBB.XMin,stockBB.YMin,0))
            stockPaths.append([v])

        stockPath2d = convertTo2d(stockPaths)

        opType = area.AdaptiveOperationType.ClearingInside
        if obj.OperationType == "Clearing":
            if obj.Side == "Outside":
                opType = area.AdaptiveOperationType.ClearingOutside

            else:
                opType = area.AdaptiveOperationType.ClearingInside

        else: # profiling
            if obj.Side == "Outside":
                opType = area.AdaptiveOperationType.ProfilingOutside

            else:
                opType = area.AdaptiveOperationType.ProfilingInside


        keepToolDownRatio = 3.0
        if hasattr(obj, 'KeepToolDownRatio'):
            keepToolDownRatio = float(obj.KeepToolDownRatio)

        # put here all properties that influence calculation of adaptive base paths,

        inputStateObject = {
            "tool": float(op.tool.Diameter),
            "tolerance": float(obj.Tolerance),
            "geometry" : path2d,
            "stockGeometry": stockPath2d,
            "stepover" : float(obj.StepOver),
            "effectiveHelixDiameter": float(helixDiameter),
            "operationType": obj.OperationType,
            "side": obj.Side,
            "forceInsideOut" : obj.ForceInsideOut,
            "keepToolDownRatio": keepToolDownRatio,
            "stockToLeave": float(obj.StockToLeave)
        }

        inputStateChanged = False
        adaptiveResults = None

        if obj.AdaptiveOutputState != None and obj.AdaptiveOutputState != "":
            adaptiveResults = obj.AdaptiveOutputState

        if json.dumps(obj.AdaptiveInputState) != json.dumps(inputStateObject):
            inputStateChanged = True
            adaptiveResults = None

        # progress callback fn, if return true it will stop processing
        def progressFn(tpaths):
            for path in tpaths: #path[0] contains the MotionType, #path[1] contains list of points
                if path[0] == area.AdaptiveMotionType.Cutting:
                    sceneDrawPath(path[1],(0,0,1))

                else:
                    sceneDrawPath(path[1],(1,0,1))

            FreeCADGui.updateGui()

            return  obj.StopProcessing

        start = time.time()

        if inputStateChanged or adaptiveResults is None:
            a2d = area.Adaptive2d()
            a2d.stepOverFactor = 0.01*obj.StepOver
            a2d.toolDiameter = float(op.tool.Diameter)
            a2d.helixRampDiameter =  helixDiameter
            a2d.keepToolDownDistRatio = keepToolDownRatio
            a2d.stockToLeave =float(obj.StockToLeave)
            a2d.tolerance = float(obj.Tolerance)
            a2d.forceInsideOut = obj.ForceInsideOut
            a2d.opType = opType

            # EXECUTE
            results = a2d.Execute(stockPath2d,path2d,progressFn)

            # need to convert results to python object to be JSON serializable
            adaptiveResults = []
            for result in results:
                adaptiveResults.append({
                    "HelixCenterPoint": result.HelixCenterPoint,
                    "StartPoint": result.StartPoint,
                    "AdaptivePaths": result.AdaptivePaths,
                    "ReturnMotionType": result.ReturnMotionType })


        # GENERATE
        GenerateGCode(op,obj,adaptiveResults,helixDiameter)

        if not obj.StopProcessing:
            Console.PrintMessage("*** Done. Elapsed time: %f sec\n\n" %(time.time()-start))
            obj.AdaptiveOutputState = adaptiveResults
            obj.AdaptiveInputState=inputStateObject

        else:
            Console.PrintMessage("*** Processing cancelled (after: %f sec).\n\n" %(time.time()-start))

    finally:
        obj.ViewObject.Visibility = oldObjVisibility
        job.ViewObject.Visibility = oldJobVisibility
        sceneClean()
Esempio n. 2
0
    def compute(self):
        self.motions = []
        trsf = trsf_from_Ax2(self.ax)
        trsf_inv = trsf.Inverted()
        mt = BRepBuilderAPI_Transform(self.face, trsf)
        face_transformed = mt.Shape()
        tess = OCC.Core.Tesselator.ShapeTesselator(face_transformed)
        tess.Compute(compute_edges=True,
                     mesh_quality=self.tesselation_mesh_quality)
        vertices = []
        initialized = False
        for i_edge in range(tess.ObjGetEdgeCount()):
            for i_vertex in range(tess.ObjEdgeGetVertexCount(i_edge)):
                x, y, z = tess.GetEdgeVertex(i_edge, i_vertex)
                if not initialized:
                    initialized = True
                    v_new = gp_Vec(x, y, z)
                    v_old = v_new
                    need_vertex = True
                else:
                    v_old = v_new
                    v_new = gp_Vec(x, y, z)
                    need_vertex = True
                if need_vertex:
                    vertices.append(tess.GetEdgeVertex(i_edge, i_vertex))

        a2d = area.Adaptive2d()
        a2d.tolerance = self.tolerance
        a2d.opType = area.AdaptiveOperationType.ClearingInside
        a2d.stockToLeave = self.stockToLeave
        a2d.toolDiameter = self.tool_diameter
        a2d.helixRampDiameter = self.helix_diameter
        a2d.stepOverFactor = self.step_over_factor

        def callback(something):
            return False  # True stops processing

        stock_path = [[[-1000, -1000], [1000, -1000], [1000, 1000],
                       [-1000, 1000]]]

        path = [vertices]
        a2d_output = a2d.Execute(stock_path, path, callback)

        self.comp = TopoDS_Compound()
        builder = BRep_Builder()
        builder.MakeCompound(self.comp)
        edges = []
        mw = BRepBuilderAPI_MakeWire()

        x = 0
        y = 0
        print("len(a2d_output):", len(a2d_output))
        regions = []
        for region in a2d_output:
            need_depth_to_depth_link = False
            for i_depth, current_z_cut in enumerate(self.cut_depths):
                motions_region_i = []
                print("helix center point")
                x, y = region.HelixCenterPoint
                # peek at first point
                motion_type, path_i = region.AdaptivePaths[0]
                x_peek, y_peek = path_i[0]

                ax = gp_Ax2(gp_Pnt(x, y, current_z_cut), gp_Dir(0, 0, 1),
                            gp_Dir(x_peek - x, y_peek - y, 0))
                cyl = gp_Cylinder(gp_Ax3(ax), self.helix_diameter / 2.0)

                if i_depth == 0:
                    dv = self.z_clearance - self.cut_depths[i_depth]
                else:
                    dv = self.cut_depths[i_depth -
                                         1] - self.cut_depths[i_depth]
                dv_du = tan(radians(self.helix_angle))
                du = dv / dv_du
                dt = du / cos(radians(self.helix_angle))
                aLine2d = gp_Lin2d(gp_Pnt2d(-du, dv), gp_Dir2d(du, -dv))
                segment = GCE2d_MakeSegment(aLine2d, 0, dt)
                helixEdge = BRepBuilderAPI_MakeEdge(
                    segment.Value(), Geom_CylindricalSurface(cyl)).Edge()

                curve = BRepAdaptor_Curve(helixEdge)
                v0 = gp_Vec(curve.Value(curve.FirstParameter()).XYZ())
                v1 = gp_Vec(curve.Value(curve.LastParameter()).XYZ())

                if need_depth_to_depth_link:
                    # go up to clearance plane
                    v_next = gp_Vec(v_now.X(), v_now.Y(), self.z_clearance)
                    me = BRepBuilderAPI_MakeEdge(gp_Pnt(v_now.XYZ()),
                                                 gp_Pnt(v_next.XYZ()))
                    mt = BRepBuilderAPI_Transform(me.Edge(), trsf_inv)
                    motions_region_i.append(
                        Adaptive2dMotion(self, mt.Shape(),
                                         self.rapid_feedrate))
                    mw.Add(me.Edge())
                    builder.Add(self.comp, me.Edge())
                    v_now = v_next
                    # go to helix start xy
                    v_next = gp_Vec(v0.X(), v0.Y(), v_now.Z())
                    me = BRepBuilderAPI_MakeEdge(gp_Pnt(v_now.XYZ()),
                                                 gp_Pnt(v_next.XYZ()))
                    mt = BRepBuilderAPI_Transform(me.Edge(), trsf_inv)
                    motions_region_i.append(
                        Adaptive2dMotion(self, mt.Shape(),
                                         self.rapid_feedrate))
                    mw.Add(me.Edge())
                    builder.Add(self.comp, me.Edge())
                    v_now = v_next
                    # go to helix start xyz
                    v_next = v0
                    me = BRepBuilderAPI_MakeEdge(gp_Pnt(v_now.XYZ()),
                                                 gp_Pnt(v_next.XYZ()))
                    mt = BRepBuilderAPI_Transform(me.Edge(), trsf_inv)
                    motions_region_i.append(
                        Adaptive2dMotion(self, mt.Shape(),
                                         self.rapid_feedrate))
                    mw.Add(me.Edge())
                    builder.Add(self.comp, me.Edge())
                    v_now = v_next

                need_depth_to_depth_link = True

                mw.Add(helixEdge)
                builder.Add(self.comp, helixEdge)
                mt = BRepBuilderAPI_Transform(helixEdge, trsf_inv)
                motions_region_i.append(
                    Adaptive2dMotion(self, mt.Shape(), self.plunge_feedrate))
                v_now = v1

                # add circle at bottom
                aLin2d = gp_Lin2d(gp_Pnt2d(0, 0), gp_Dir2d(du, 0))
                dt = 2 * pi
                segment = GCE2d_MakeSegment(aLin2d, 0, dt)
                circleEdge = BRepBuilderAPI_MakeEdge(
                    segment.Value(), Geom_CylindricalSurface(cyl)).Edge()
                mw.Add(circleEdge)
                builder.Add(self.comp, circleEdge)
                mt = BRepBuilderAPI_Transform(circleEdge, trsf_inv)
                motions_region_i.append(
                    Adaptive2dMotion(self, mt.Shape(), self.plunge_feedrate))

                curve = BRepAdaptor_Curve(circleEdge)
                v1 = gp_Vec(curve.Value(curve.LastParameter()).XYZ())

                v_now = v1

                PATH_TYPE = {
                    0: "Cutting",
                    1: "LinkClear",
                    2: "LinkNotClear",
                    3: "LinkClearAtPrevPass"
                }

                for path_type, points in region.AdaptivePaths:
                    if PATH_TYPE[path_type] == "Cutting":
                        # handle the first point
                        x, y = points[0]
                        # choose feedrate
                        if (v_now.Z() - current_z_cut) > 1e-3:
                            feedrate = self.rapid_feedrate
                        else:
                            feedrate = self.milling_feedrate

                        v_next = gp_Vec(x, y, v_now.Z())
                        if (v_now - v_next).Magnitude() > 1e-6:
                            me = BRepBuilderAPI_MakeEdge(
                                gp_Pnt(v_now.XYZ()), gp_Pnt(v_next.XYZ()))
                            mt = BRepBuilderAPI_Transform(me.Edge(), trsf_inv)
                            motions_region_i.append(
                                Adaptive2dMotion(self, mt.Shape(), feedrate))
                            mw.Add(me.Edge())
                            builder.Add(self.comp, me.Edge())
                            v_now = v_next

                        if v_now.Z() != current_z_cut:
                            v_next = gp_Vec(x, y, current_z_cut)
                            me = BRepBuilderAPI_MakeEdge(
                                gp_Pnt(v_now.XYZ()), gp_Pnt(v_next.XYZ()))
                            mt = BRepBuilderAPI_Transform(me.Edge(), trsf_inv)
                            motions_region_i.append(
                                Adaptive2dMotion(self, mt.Shape(),
                                                 self.plunge_feedrate))
                            v_now = v_next
                            mw.Add(me.Edge())
                            builder.Add(self.comp, me.Edge())

                        # handle the rest of the points
                        for x, y in points[1:]:
                            v_next = gp_Vec(x, y, current_z_cut)
                            if (v_now - v_next).Magnitude() > 1e-6:
                                me = BRepBuilderAPI_MakeEdge(
                                    gp_Pnt(v_now.XYZ()), gp_Pnt(v_next.XYZ()))
                                mt = BRepBuilderAPI_Transform(
                                    me.Edge(), trsf_inv)
                                motions_region_i.append(
                                    Adaptive2dMotion(self, mt.Shape(),
                                                     self.milling_feedrate))
                                v_now = v_next
                                mw.Add(me.Edge())
                                builder.Add(self.comp, me.Edge())

                    elif (PATH_TYPE[path_type]
                          == "LinkClear") or (PATH_TYPE[path_type]
                                              == "LinkNotClear"):
                        if (PATH_TYPE[path_type] == "LinkClear"):
                            z = current_z_cut + self.z_link_clear
                        else:
                            z = self.z_clearance

                        if v_now.Z() != z:
                            if v_now.Z() >= z:
                                feedrate = self.plunge_feedrate
                            else:
                                feedrate = self.rapid_feedrate
                            v_next = gp_Vec(v_now.X(), v_now.Y(), z)
                            me = BRepBuilderAPI_MakeEdge(
                                gp_Pnt(v_now.XYZ()), gp_Pnt(v_next.XYZ()))
                            mt = BRepBuilderAPI_Transform(me.Edge(), trsf_inv)
                            motions_region_i.append(
                                Adaptive2dMotion(self, mt.Shape(),
                                                 self.plunge_feedrate))
                            v_now = v_next
                            mw.Add(me.Edge())
                            builder.Add(self.comp, me.Edge())

                        if len(points) > 0:
                            # go to each point
                            for x, y in points[1:]:
                                v_next = gp_Vec(x, y, z)
                                me = BRepBuilderAPI_MakeEdge(
                                    gp_Pnt(v_now.XYZ()), gp_Pnt(v_next.XYZ()))
                                mt = BRepBuilderAPI_Transform(
                                    me.Edge(), trsf_inv)
                                motions_region_i.append(
                                    Adaptive2dMotion(self, mt.Shape(),
                                                     self.rapid_feedrate))
                                v_now = v_next
                                mw.Add(me.Edge())
                                builder.Add(self.comp, me.Edge())
                    else:
                        raise Warning("path type not implemented")

                self.motions.append(motions_region_i)
        mt = BRepBuilderAPI_Transform(mw.Wire(), trsf_inv)
        self.wire = mt.Shape()
        return self.wire