# /************************************************************************** # * Copyright (c) Kresimir Tusek (kresimir.tusek@gmail.com) 2018 * # * This file is part of the FreeCAD CAx development system. * # * * # * This library is free software; you can redistribute it and/or * # * modify it under the terms of the GNU Library General Public * # * License as published by the Free Software Foundation; either * # * version 2 of the License, or (at your option) any later version. * # * * # * This library is distributed in the hope that it will be useful, * # * but WITHOUT ANY WARRANTY; without even the implied warranty of * # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * # * GNU Library General Public License for more details. * # * * # * You should have received a copy of the GNU Library General Public * # * License along with this library; see the file COPYING.LIB. If not, * # * write to the Free Software Foundation, Inc., 59 Temple Place, * # * Suite 330, Boston, MA 02111-1307, USA * # * * # ***************************************************************************/ import PathScripts.PathOp as PathOp import PathScripts.PathUtils as PathUtils import Path import FreeCAD import FreeCADGui from FreeCAD import Console import time import json import math import area from pivy import coin __doc__ = "Class and implementation of the Adaptive path operation." def discretize(edge, flipDirection=False): pts=edge.discretize(Deflection=0.01) if flipDirection: pts.reverse() return pts def convertTo2d(pathArray): output = [] for path in pathArray: pth2 = [] for edge in path: for pt in edge: pth2.append([pt[0],pt[1]]) output.append(pth2) return output sceneGraph = None scenePathNodes = [] #for scene cleanup aftewards topZ = 10 def sceneDrawPath(path, color=(0, 0, 1)): global sceneGraph global scenePathNodes coPoint = coin.SoCoordinate3() pts = [] for pt in path: pts.append([pt[0], pt[1], topZ]) coPoint.point.setValues(0, len(pts), pts) ma = coin.SoBaseColor() ma.rgb = color li = coin.SoLineSet() li.numVertices.setValue(len(pts)) pathNode = coin.SoSeparator() pathNode.addChild(coPoint) pathNode.addChild(ma) pathNode.addChild(li) sceneGraph.addChild(pathNode) scenePathNodes.append(pathNode) #for scene cleanup afterwards def sceneClean(): global scenePathNodes for n in scenePathNodes: sceneGraph.removeChild(n) del scenePathNodes[:] def GenerateGCode(op,obj,adaptiveResults, helixDiameter): 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) 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) 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.0001: 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)) #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})) op.commandlist.append(Path.Command("G1", { "X": helixStart[0], "Y": helixStart[1], "Z": passStartDepth, "F": op.vertFeed})) while fi