diff --git a/src/Mod/Path/PathScripts/PathContour.py b/src/Mod/Path/PathScripts/PathContour.py index 1acc1399e1..5e6820e1f6 100644 --- a/src/Mod/Path/PathScripts/PathContour.py +++ b/src/Mod/Path/PathScripts/PathContour.py @@ -34,7 +34,7 @@ from PathScripts.PathUtils import waiting_effects from PathScripts.PathUtils import makeWorkplane LOG_MODULE = 'PathContour' -PathLog.setLevel(PathLog.Level.DEBUG, LOG_MODULE) +PathLog.setLevel(PathLog.Level.INFO, LOG_MODULE) PathLog.trackModule('PathContour') FreeCAD.setLogLevel('Path.Area', 0) @@ -42,6 +42,7 @@ if FreeCAD.GuiUp: import FreeCADGui from PySide import QtGui + # Qt tanslation handling def translate(context, text, disambig=None): return QtCore.QCoreApplication.translate(context, text, disambig) @@ -77,9 +78,6 @@ class ObjectContour: obj.addProperty("App::PropertyEnumeration", "Direction", "Contour", QtCore.QT_TRANSLATE_NOOP("App::Property", "The direction that the toolpath should go around the part ClockWise CW or CounterClockWise CCW")) obj.Direction = ['CW', 'CCW'] # this is the direction that the Contour runs obj.addProperty("App::PropertyBool", "UseComp", "Contour", QtCore.QT_TRANSLATE_NOOP("App::Property", "make True, if using Cutter Radius Compensation")) - # obj.addProperty("App::PropertyEnumeration", "Side", "Contour", QtCore.QT_TRANSLATE_NOOP("App::Property", "Side of edge that tool should cut")) - # obj.Side = ['Left', 'Right'] # side of profile that cutter is on in relation to direction of profile - # obj.setEditorMode('Side', 2) # hide obj.addProperty("App::PropertyDistance", "OffsetExtra", "Contour", QtCore.QT_TRANSLATE_NOOP("App::Property", "Extra value to stay away from final Contour- good for roughing toolpath")) @@ -98,11 +96,6 @@ class ObjectContour: def onChanged(self, obj, prop): pass - # if prop == "UseComp": - # if not obj.UseComp: - # obj.setEditorMode('Side', 2) - # else: - # obj.setEditorMode('Side', 0) def setDepths(proxy, obj): PathLog.track() @@ -133,7 +126,7 @@ class ObjectContour: profile.add(baseobject) profileparams = {'Fill': 0, - 'Coplanar': 0} + 'Coplanar': 2} if obj.UseComp is False: profileparams['Offset'] = 0.0 @@ -244,8 +237,10 @@ class ObjectContour: # Let's always start by rapid to clearance...just for safety commandlist.append(Path.Command("G0", {"Z": obj.ClearanceHeight.Value})) + isPanel = False if hasattr(baseobject, "Proxy"): if isinstance(baseobject.Proxy, ArchPanel.PanelSheet): # process the sheet + isPanel = True baseobject.Proxy.execute(baseobject) shapes = baseobject.Proxy.getOutlines(baseobject, transform=True) for shape in shapes: @@ -255,15 +250,16 @@ class ObjectContour: try: commandlist.extend(self._buildPathArea(obj, contourshape, start=obj.StartPoint).Commands) except Exception as e: - print(e) + FreeCAD.Console.PrintError(e) FreeCAD.Console.PrintError("Something unexpected happened. Unable to generate a contour path. Check project and tool config.") - else: + + if hasattr(baseobject, "Shape") and not isPanel: bb = baseobject.Shape.BoundBox env = PathUtils.getEnvelope(partshape=baseobject.Shape, subshape=None, stockheight=bb.ZLength + (obj.StartDepth.Value-bb.ZMax)) try: commandlist.extend(self._buildPathArea(obj, env, start=obj.StartPoint).Commands) except Exception as e: - print(e) + FreeCAD.Console.PrintError(e) FreeCAD.Console.PrintError("Something unexpected happened. Unable to generate a contour path. Check project and tool config.") path = Path.Path(commandlist) diff --git a/src/Mod/Path/PathScripts/PathMillFace.py b/src/Mod/Path/PathScripts/PathMillFace.py index cc232db931..963e807c4b 100644 --- a/src/Mod/Path/PathScripts/PathMillFace.py +++ b/src/Mod/Path/PathScripts/PathMillFace.py @@ -178,7 +178,7 @@ class ObjectFace: 'Angle': obj.ZigZagAngle, 'FromCenter': (obj.StartAt == "Center"), 'PocketStepover': stepover, - 'PocketExtraOffset': obj.PassExtension.Value} + 'PocketExtraOffset': 0 - obj.PassExtension.Value} Pattern = ['ZigZag', 'Offset', 'Spiral', 'ZigZagOffset', 'Line', 'Grid', 'Triangle'] pocketparams['PocketMode'] = Pattern.index(obj.OffsetPattern) + 1 diff --git a/src/Mod/Path/PathScripts/PathUtils.py b/src/Mod/Path/PathScripts/PathUtils.py index 7325da3573..c430d0286a 100644 --- a/src/Mod/Path/PathScripts/PathUtils.py +++ b/src/Mod/Path/PathScripts/PathUtils.py @@ -38,9 +38,10 @@ from PySide import QtGui LOG_MODULE = 'PathUtils' PathLog.setLevel(PathLog.Level.INFO, LOG_MODULE) -#PathLog.trackModule('PathUtils') +# PathLog.trackModule('PathUtils') FreeCAD.setLogLevel('Path.Area', 0) + def waiting_effects(function): def new_function(*args, **kwargs): if not FreeCAD.GuiUp: @@ -147,6 +148,11 @@ def isDrillable(obj, candidate, tooldiameter=None): PathLog.debug("Has Radius, Circle") if tooldiameter is not None: drillable = edge.Curve.Radius >= tooldiameter/2 + if not drillable: + FreeCAD.Console.PrintMessage( + "Found a drillable hole with diameter: {}: " + "too small for the current tool with " + "diameter: {}".format(edge.Curve.Radius*2, tooldiameter)) else: drillable = True PathLog.debug("candidate is drillable: {}".format(drillable)) @@ -277,10 +283,11 @@ def getEnvelope(partshape, subshape=None, stockheight=None): else: envelopeshape = sec.extrude(FreeCAD.Vector(0, 0, partshape.BoundBox.ZLength)) if PathLog.getLevel(PathLog.thisModule()) == PathLog.Level.DEBUG: - removalshape=FreeCAD.ActiveDocument.addObject("Part::Feature","Envelope") + removalshape = FreeCAD.ActiveDocument.addObject("Part::Feature", "Envelope") removalshape.Shape = envelopeshape return envelopeshape + def reverseEdge(e): if geomType(e) == "Circle": arcstpt = e.valueAt(e.FirstParameter) @@ -610,6 +617,7 @@ def rampPlunge(edge, rampangle, destZ, startZ): return rampCmds + def sort_jobs(locations, keys, attractors=[]): """ sort holes by the nearest neighbor method keys: two-element list of keys for X and Y coordinates. for example ['x','y'] @@ -624,7 +632,7 @@ def sort_jobs(locations, keys, attractors=[]): """ square Euclidean distance """ d = 0 for k in keys: - d += (a[k] - b[k]) ** 2 + d += (a[k] - b[k]) ** 2 return d @@ -646,7 +654,6 @@ def sort_jobs(locations, keys, attractors=[]): return result - out = [] zero = defaultdict(lambda: 0) @@ -744,15 +751,16 @@ class depth_params: else: return [stop] + depths.tolist() + class CollisionTester: def compareBBSpace(self, bb1, bb2): - if ( bb1.XMin == bb2.XMin and - bb1.XMax == bb2.XMax and - bb1.YMin == bb2.YMin and - bb1.YMax == bb2.YMax and - bb1.ZMin == bb2.ZMin and - bb1.ZMax == bb2.ZMax ) : + if (bb1.XMin == bb2.XMin and + bb1.XMax == bb2.XMax and + bb1.YMin == bb2.YMin and + bb1.YMax == bb2.YMax and + bb1.ZMin == bb2.ZMin and + bb1.ZMax == bb2.ZMax): return True return False @@ -774,13 +782,13 @@ class CollisionTester: if self.compareBBSpace(i.BoundBox, j.BoundBox): match = True if match is True: - #print ("Need to highlight Face{}".format(idx+1)) + # print ("Need to highlight Face{}".format(idx+1)) colorassignment.append(intersecColor) else: colorassignment.append(baseColor) - collisionSim = FreeCAD.ActiveDocument.addObject("Part::Feature","Collision") + collisionSim = FreeCAD.ActiveDocument.addObject("Part::Feature", "Collision") collisionSim.Shape = gougedShape - collisionSim.ViewObject.DiffuseColor=colorassignment + collisionSim.ViewObject.DiffuseColor = colorassignment return collisionSim else: return None diff --git a/src/Mod/Path/PathTests/TestPathCore.py b/src/Mod/Path/PathTests/TestPathCore.py index b8aae11e0e..efa31840a7 100644 --- a/src/Mod/Path/PathTests/TestPathCore.py +++ b/src/Mod/Path/PathTests/TestPathCore.py @@ -47,7 +47,7 @@ class TestPathCore(PathTestBase): self.assertEqual(c.Parameters, {'Y': 0.5, 'X': 1}) #output gcode - self.assertEqual(c.toGCode(), 'G1 X1.00000 Y0.50000') + self.assertEqual(c.toGCode(), 'G1 X1.000000 Y0.500000') #create and assign name in one c2=Path.Command("G2") @@ -61,7 +61,7 @@ class TestPathCore(PathTestBase): #use placement self.assertEqual( str(c3.Placement), 'Placement [Pos=(34,1.2,0), Yaw-Pitch-Roll=(0,0,0)]') - self.assertEqual( c3.toGCode(), 'G1 X34.00000 Y1.20000') + self.assertEqual( c3.toGCode(), 'G1 X34.000000 Y1.200000') p1 = FreeCAD.Placement() p1.Base = FreeCAD.Vector(3,2,1) self.assertEqual(str(p1), 'Placement [Pos=(3,2,1), Yaw-Pitch-Roll=(0,0,0)]') @@ -96,7 +96,7 @@ class TestPathCore(PathTestBase): self.assertEqual(str(p.Commands), '[Command G1 [ X:1 Y:0 ], Command G1 [ X:0 Y:2 ]]') self.assertAlmostEqual( p.Length, 3.2361, places=4) p.addCommands(c1) - self.assertEqual(p.toGCode(), 'G1 X1.00000 Y0.00000\nG1 X0.00000 Y2.00000\nG1 X1.00000 Y0.00000\n') + self.assertEqual(p.toGCode(), 'G1 X1.000000 Y0.000000\nG1 X0.000000 Y2.000000\nG1 X1.000000 Y0.000000\n') lines = ''' G0X-0.5905Y-0.3937S3000M03 @@ -109,20 +109,15 @@ G1X-0.5905Y-0.3937 G0Z0.5 ''' - -<<<<<<< d3838802b1665892c464bce8a340531cafcb66f2 output = '''G0 S3000.000000 X-0.590500 Y-0.393700 -======= - output = '''G0 S3000.00000 X0.-59050 Y0.-39370 ->>>>>>> Path: add output precision option to linuxcnc post. M03 -G0 Z0.12500 -G1 F3.00000 Z0.0-400 -G1 F14.17000 X0.98420 Y0.-39370 -G1 X0.98420 Y0.43300 -G1 X0.-59050 Y0.43300 -G1 X0.-59050 Y0.-39370 -G0 Z0.50000 +G0 Z0.125000 +G1 F3.000000 Z-0.004000 +G1 F14.170000 X0.984200 Y-0.393700 +G1 X0.984200 Y0.433000 +G1 X-0.590500 Y0.433000 +G1 X-0.590500 Y-0.393700 +G0 Z0.500000 '''