Merge pull request #21129 from jffmichi/fix_active_and_coolant

CAM: fix handling of Active state and CoolantMode with nested dressups
This commit is contained in:
sliptonic
2025-05-19 10:33:45 -05:00
committed by GitHub
23 changed files with 308 additions and 193 deletions

View File

@@ -141,14 +141,14 @@ G53 G00 G17
G21
;Begin operation
G54
;End operation: Fixture
;End operation
;Begin operation
;TC: Default Tool
;Begin toolchange
M6 T1
;End operation: TC: Default Tool
;End operation
;Begin operation
;End operation: Profile
;End operation
;Begin postamble
M5
M25

View File

@@ -0,0 +1,155 @@
# -*- coding: utf-8 -*-
# ***************************************************************************
# * Copyright (c) 2022 sliptonic <shopinthewoods@gmail.com> *
# * Copyright (c) 2022-2025 Larry Woestman <LarryWoestman2@gmail.com> *
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) *
# * as published by the Free Software Foundation; either version 2 of *
# * the License, or (at your option) any later version. *
# * for detail see the LICENCE text file. *
# * *
# * This program 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 program; if not, write to the Free Software *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * *
# ***************************************************************************
import FreeCAD
import Path
import CAMTests.PathTestUtils as PathTestUtils
from Path.Post.Processor import PostProcessorFactory
import Path.Dressup.Utils as PathDressup
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
Path.Log.trackModule(Path.Log.thisModule())
class TestRefactoredTestDressupPost(PathTestUtils.PathTestBase):
"""Test the refactored_test_post.py postprocessor command line arguments."""
@classmethod
def setUpClass(cls):
"""setUpClass()...
This method is called upon instantiation of this test class. Add code
and objects here that are needed for the duration of the test() methods
in this class. In other words, set up the 'global' test environment
here; use the `setUp()` method to set up a 'local' test environment.
This method does not have access to the class `self` reference, but it
is able to call static methods within this same class.
"""
FreeCAD.ConfigSet("SuppressRecomputeRequiredDialog", "True")
cls.doc = FreeCAD.open(FreeCAD.getHomePath() + "/Mod/CAM/CAMTests/dressuptest.FCStd")
cls.job = cls.doc.getObject("Job")
cls.post = PostProcessorFactory.get_post_processor(cls.job, "refactored_test")
# there are 4 operations in dressuptest.FCStd
# every operation uses a different ToolController
# each operation uses one more dressup to check nested dressups also work correctly
cls.ops = cls.job.Operations.Group
@classmethod
def tearDownClass(cls):
"""tearDownClass()...
This method is called prior to destruction of this test class. Add
code and objects here that cleanup the test environment after the
test() methods in this class have been executed. This method does
not have access to the class `self` reference. This method is able
to call static methods within this same class.
"""
FreeCAD.closeDocument(cls.doc.Name)
FreeCAD.ConfigSet("SuppressRecomputeRequiredDialog", "")
# Setup and tear down methods called before and after each unit test
def setUp(self):
"""setUp()...
This method is called prior to each `test()` method. Add code and
objects here that are needed for multiple `test()` methods.
"""
# allow a full length "diff" if an error occurs
self.maxDiff = None
#
# reinitialize the postprocessor data structures between tests
#
self.post.reinitialize()
def tearDown(self):
"""tearDown()...
This method is called after each test() method. Add cleanup instructions here.
Such cleanup instructions will likely undo those in the setUp() method.
"""
pass
def test001(self):
# test handling of Active state in postprocessor and nested dressups
self.post.values["OUTPUT_COMMENTS"] = True
self.post.values["SHOW_OPERATION_LABELS"] = True
# set all operations to Active = False
for op in self.ops:
PathDressup.baseOp(op).Active = False
# check that none of the operations is in the output
gcode = self.post.export()[0][1].splitlines()
for op in self.ops:
expected = "(Begin operation: " + op.Label + ")"
self.assertNotIn(expected, gcode)
# set all operations back to Active = True
for op in self.ops:
PathDressup.baseOp(op).Active = True
# check that all operations are in the output
gcode = self.post.export()[0][1].splitlines()
for op in self.ops:
expected = "(Begin operation: " + op.Label + ")"
self.assertIn(expected, gcode)
def test002(self):
# test handling of ToolController in postprocessor and nested dressups
self.post.values["OUTPUT_TOOL_CHANGE"] = True
gcode = self.post.export()[0][1].splitlines()
self.assertIn("M6 T1", gcode)
self.assertIn("M6 T2", gcode)
self.assertIn("M6 T3", gcode)
self.assertIn("M6 T4", gcode)
def test003(self):
# test handling of CoolantMode in postprocessor and nested dressups
self.post.values["ENABLE_COOLANT"] = True
for op in self.ops:
base = PathDressup.baseOp(op)
base.CoolantMode = "Mist"
gcode = self.post.export()[0][1].splitlines()
self.assertIn("M7", gcode)
self.assertIn("M9", gcode)
base.CoolantMode = "None"

View File

@@ -306,15 +306,15 @@ G90
G21
(Begin operation)
G54
(Finish operation: Fixture)
(Finish operation)
(Begin operation)
(TC: Default Tool)
(Begin toolchange)
(M6 T1)
(Finish operation: TC: Default Tool)
(Finish operation)
(Begin operation)
(comment with spaces)
(Finish operation: Profile)
(Finish operation)
(Begin postamble)
""",
"--command_space=' ' --comments",
@@ -326,15 +326,15 @@ G90
G21
(Begin operation)
G54
(Finish operation: Fixture)
(Finish operation)
(Begin operation)
(TC: Default Tool)
(Begin toolchange)
(M6T1)
(Finish operation: TC: Default Tool)
(Finish operation)
(Begin operation)
(comment with spaces)
(Finish operation: Profile)
(Finish operation)
(Begin postamble)
""",
"--command_space='' --comments",
@@ -352,15 +352,15 @@ G90
G21
(Begin operation)
G54
(Finish operation: Fixture)
(Finish operation)
(Begin operation)
(TC: Default Tool)
(Begin toolchange)
(M6 T1)
(Finish operation: TC: Default Tool)
(Finish operation)
(Begin operation)
(comment with spaces)
(Finish operation: Profile)
(Finish operation)
(Begin postamble)
""",
"--comments",
@@ -372,15 +372,15 @@ G90
G21
;Begin operation
G54
;Finish operation: Fixture
;Finish operation
;Begin operation
;TC: Default Tool
;Begin toolchange
;M6 T1
;Finish operation: TC: Default Tool
;Finish operation
;Begin operation
;comment with spaces
;Finish operation: Profile
;Finish operation
;Begin postamble
""",
"--comment_symbol=';' --comments",
@@ -392,15 +392,15 @@ G90
G21
!Begin operation
G54
!Finish operation: Fixture
!Finish operation
!Begin operation
!TC: Default Tool
!Begin toolchange
!M6 T1
!Finish operation: TC: Default Tool
!Finish operation
!Begin operation
!comment with spaces
!Finish operation: Profile
!Finish operation
!Begin postamble
""",
"--comment_symbol='!' --comments",
@@ -471,14 +471,14 @@ G54
self.assertEqual(split_gcode[6], "G21")
self.assertEqual(split_gcode[7], "(Begin operation)")
self.assertEqual(split_gcode[8], "G54")
self.assertEqual(split_gcode[9], "(Finish operation: Fixture)")
self.assertEqual(split_gcode[9], "(Finish operation)")
self.assertEqual(split_gcode[10], "(Begin operation)")
self.assertEqual(split_gcode[11], "(TC: Default Tool)")
self.assertEqual(split_gcode[12], "(Begin toolchange)")
self.assertEqual(split_gcode[13], "(M6 T1)")
self.assertEqual(split_gcode[14], "(Finish operation: TC: Default Tool)")
self.assertEqual(split_gcode[14], "(Finish operation)")
self.assertEqual(split_gcode[15], "(Begin operation)")
self.assertEqual(split_gcode[16], "(Finish operation: Profile)")
self.assertEqual(split_gcode[16], "(Finish operation)")
self.assertEqual(split_gcode[17], "(Begin postamble)")
# Test with comments without header.
@@ -487,14 +487,14 @@ G90
G21
(Begin operation)
G54
(Finish operation: Fixture)
(Finish operation)
(Begin operation)
(TC: Default Tool)
(Begin toolchange)
(M6 T1)
(Finish operation: TC: Default Tool)
(Finish operation)
(Begin operation)
(Finish operation: Profile)
(Finish operation)
(Begin postamble)
"""
self.job.PostProcessorArgs = "--comments --no-header"

View File

@@ -768,12 +768,12 @@ G90
G21
(Begin operation)
G54
(Finish operation: Fixture)
(Finish operation)
(Begin operation)
(TC: Default Tool)
(Begin toolchange)
(M6 T1)
(Finish operation: TC: Default Tool)
(Finish operation)
(Begin operation)
G0 X1.000 Y2.000
G0 Z8.000
@@ -795,7 +795,7 @@ G1 Z0.000 F7380.000
G0 Z5.000
(G80)
G90
(Finish operation: Profile)
(Finish operation)
(Begin postamble)
""",
"--comments --translate_drill",
@@ -865,12 +865,12 @@ G90
G21
(Begin operation)
G54
(Finish operation: Fixture)
(Finish operation)
(Begin operation)
(TC: Default Tool)
(Begin toolchange)
(M6 T1)
(Finish operation: TC: Default Tool)
(Finish operation)
(Begin operation)
G0 X1.000 Y2.000
G0 Z8.000
@@ -894,7 +894,7 @@ G0 Z13.000
G91
(G80)
G90
(Finish operation: Profile)
(Finish operation)
(Begin postamble)
""",
"--comments --translate_drill",
@@ -951,12 +951,12 @@ G90
G21
(Begin operation)
G54
(Finish operation: Fixture)
(Finish operation)
(Begin operation)
(TC: Default Tool)
(Begin toolchange)
(M6 T1)
(Finish operation: TC: Default Tool)
(Finish operation)
(Begin operation)
G0 X1.000 Y2.000
G0 Z8.000
@@ -969,7 +969,7 @@ G1 Z0.000 F7380.000
G0 Z5.000
(G80)
G90
(Finish operation: Profile)
(Finish operation)
(Begin postamble)
""",
"--comments --translate_drill",
@@ -1030,12 +1030,12 @@ G90
G21
(Begin operation)
G54
(Finish operation: Fixture)
(Finish operation)
(Begin operation)
(TC: Default Tool)
(Begin toolchange)
(M6 T1)
(Finish operation: TC: Default Tool)
(Finish operation)
(Begin operation)
G0 X1.000 Y2.000
G0 Z8.000
@@ -1050,7 +1050,7 @@ G0 Z13.000
G91
(G80)
G90
(Finish operation: Profile)
(Finish operation)
(Begin postamble)
""",
"--comments --translate_drill",
@@ -1108,12 +1108,12 @@ G90
G21
(Begin operation)
G54
(Finish operation: Fixture)
(Finish operation)
(Begin operation)
(TC: Default Tool)
(Begin toolchange)
(M6 T1)
(Finish operation: TC: Default Tool)
(Finish operation)
(Begin operation)
G0 X1.000 Y2.000
G0 Z8.000
@@ -1127,7 +1127,7 @@ G4 P1.23456
G0 Z5.000
(G80)
G90
(Finish operation: Profile)
(Finish operation)
(Begin postamble)
""",
"--comments --translate_drill",
@@ -1189,12 +1189,12 @@ G90
G21
(Begin operation)
G54
(Finish operation: Fixture)
(Finish operation)
(Begin operation)
(TC: Default Tool)
(Begin toolchange)
(M6 T1)
(Finish operation: TC: Default Tool)
(Finish operation)
(Begin operation)
G0 X1.000 Y2.000
G0 Z8.000
@@ -1210,7 +1210,7 @@ G0 Z13.000
G91
(G80)
G90
(Finish operation: Profile)
(Finish operation)
(Begin postamble)
""",
"--comments --translate_drill",
@@ -1276,12 +1276,12 @@ G90
G21
(Begin operation)
G54
(Finish operation: Fixture)
(Finish operation)
(Begin operation)
(TC: Default Tool)
(Begin toolchange)
(M6 T1)
(Finish operation: TC: Default Tool)
(Finish operation)
(Begin operation)
G0 X1.000 Y2.000
G0 Z8.000
@@ -1303,7 +1303,7 @@ G1 Z0.000 F7380.000
G0 Z5.000
(G80)
G90
(Finish operation: Profile)
(Finish operation)
(Begin postamble)
""",
"--comments --translate_drill",
@@ -1373,12 +1373,12 @@ G90
G21
(Begin operation)
G54
(Finish operation: Fixture)
(Finish operation)
(Begin operation)
(TC: Default Tool)
(Begin toolchange)
(M6 T1)
(Finish operation: TC: Default Tool)
(Finish operation)
(Begin operation)
G0 X1.000 Y2.000
G0 Z8.000
@@ -1402,7 +1402,7 @@ G0 Z13.000
G91
(G80)
G90
(Finish operation: Profile)
(Finish operation)
(Begin postamble)
""",
"--comments --translate_drill",

Binary file not shown.

View File

@@ -301,6 +301,7 @@ SET(Tests_SRCS
CAMTests/__init__.py
CAMTests/boxtest.fcstd
CAMTests/boxtest1.fcstd
CAMTests/dressuptest.FCStd
CAMTests/Drilling_1.FCStd
CAMTests/drill_test1.FCStd
CAMTests/FilePathTestUtils.py
@@ -355,6 +356,7 @@ SET(Tests_SRCS
CAMTests/TestRefactoredLinuxCNCPost.py
CAMTests/TestRefactoredMach3Mach4Post.py
CAMTests/TestRefactoredMassoG3Post.py
CAMTests/TestRefactoredTestDressupPost.py
CAMTests/TestRefactoredTestPost.py
CAMTests/TestRefactoredTestPostGCodes.py
CAMTests/TestRefactoredTestPostMCodes.py

View File

@@ -118,13 +118,13 @@ def isSolid(obj):
return not shape.isNull() and shape.Volume and shape.isClosed()
def opProperty(op, prop):
def opProperty(op, prop, default=None):
"""opProperty(op, prop) ... return the value of property prop of the underlying operation (or None if prop does not exist)"""
if hasattr(op, prop):
return getattr(op, prop)
if hasattr(op, "Base"):
return opProperty(op.Base, prop)
return None
return opProperty(op.Base, prop, default)
return default
def toolControllerForOp(op):
@@ -134,6 +134,20 @@ def toolControllerForOp(op):
return opProperty(op, "ToolController")
def coolantModeForOp(op):
"""coolantModeForOp(op) ... return the coolant mode used by the op.
If the op doesn't have its own coolant mode but has a Base object, return its coolant mode.
Otherwise return "None"."""
return opProperty(op, "CoolantMode", "None")
def activeForOp(op):
"""activeForOp(op) ... return the active property used by the op.
If the op doesn't have its own active property but has a Base object, return its active property.
Otherwise return True."""
return opProperty(op, "Active", True)
def getPublicObject(obj):
"""getPublicObject(obj) ... returns the object which should be used to reference a feature of the given object."""
if hasattr(obj, "getParentGeoFeatureGroup"):

View File

@@ -195,7 +195,7 @@ class PostProcessor:
# Now generate the gcode
for obj in self._job.Operations.Group:
tc = PathUtil.toolControllerForOp(obj)
if tc is not None and PathUtil.opProperty(obj, "Active"):
if tc is not None and PathUtil.activeForOp(obj):
if tc.ToolNumber != currTool:
sublist.append(tc)
Path.Log.debug(f"Appending TC: {tc.Name}")
@@ -227,7 +227,7 @@ class PostProcessor:
Path.Log.track(obj.Label)
# check if the operation is active
if not getattr(obj, "Active", True):
if not PathUtil.activeForOp(obj):
Path.Log.track()
continue
@@ -276,7 +276,7 @@ class PostProcessor:
for obj in self._job.Operations.Group:
# check if the operation is active
if not getattr(obj, "Active", True):
if not PathUtil.activeForOp(obj):
continue
sublist = []

View File

@@ -587,7 +587,8 @@ def init_shared_values(values: Values) -> None:
#
values["SHOW_MACHINE_UNITS"] = True
#
# If True then the current operation label is output just before the PRE_OPERATION.
# If True then the current operation label is output just before the PRE_OPERATION
# and just before the POST_OPERATION.
#
values["SHOW_OPERATION_LABELS"] = True
#

View File

@@ -32,6 +32,7 @@ import os
from typing import Any, Dict, List
import FreeCAD
import Path.Base.Util as PathUtil
import Path.Post.Utils as PostUtils
import Path.Post.UtilsParse as PostUtilsParse
import Path.Tool.Controller as PathToolController
@@ -50,15 +51,6 @@ def check_canned_cycles(values: Values) -> None:
values["SUPPRESS_COMMANDS"] += ["G99", "G98", "G80"]
def determine_coolant_mode(obj) -> str:
"""Determine the coolant mode."""
if hasattr(obj, "CoolantMode") or hasattr(obj, "Base") and hasattr(obj.Base, "CoolantMode"):
if hasattr(obj, "CoolantMode"):
return obj.CoolantMode
return obj.Base.CoolantMode
return "None"
def output_coolant_off(values: Values, gcode: Gcode, coolant_mode: str) -> None:
"""Output the commands to turn coolant off if necessary."""
comment: str
@@ -162,9 +154,12 @@ def output_postop(values: Values, gcode: Gcode, obj) -> None:
nl: str = "\n"
if values["OUTPUT_COMMENTS"]:
comment = PostUtilsParse.create_comment(
values, f'{values["FINISH_LABEL"]} operation: {obj.Label}'
)
if values["SHOW_OPERATION_LABELS"]:
comment = PostUtilsParse.create_comment(
values, f'{values["FINISH_LABEL"]} operation: {obj.Label}'
)
else:
comment = PostUtilsParse.create_comment(values, f'{values["FINISH_LABEL"]} operation')
gcode.append(f"{PostUtilsParse.linenumber(values)}{comment}{nl}")
for line in values["POST_OPERATION"].splitlines(False):
gcode.append(f"{PostUtilsParse.linenumber(values)}{line}{nl}")
@@ -314,11 +309,9 @@ def export_common(values: Values, objectslist, filename: str) -> str:
for obj in objectslist:
# Skip inactive operations
if hasattr(obj, "Active") and not obj.Active:
if not PathUtil.activeForOp(obj):
continue
if hasattr(obj, "Base") and hasattr(obj.Base, "Active") and not obj.Base.Active:
continue
coolant_mode = determine_coolant_mode(obj)
coolant_mode = PathUtil.coolantModeForOp(obj)
output_start_bcnc(values, gcode, obj)
output_preop(values, gcode, obj)
output_coolant_on(values, gcode, coolant_mode)

View File

@@ -31,6 +31,7 @@ import Path
import argparse
import datetime
import shlex
import Path.Base.Util as PathUtil
import Path.Post.Utils as PostUtils
import PathScripts.PathUtils as PathUtils
from builtins import open as pyopen
@@ -171,7 +172,7 @@ def processArguments(argstring):
SHOW_EDITOR = False
print("Show editor = %r" % (SHOW_EDITOR))
if args.precision is not None:
PRECISION = args.precision
PRECISION = int(args.precision)
if args.preamble is not None:
PREAMBLE = args.preamble.replace("\\n", "\n")
if args.postamble is not None:
@@ -232,12 +233,9 @@ def export(objectslist, filename, argstring):
for obj in objectslist:
# Skip inactive operations
if hasattr(obj, "Active"):
if not obj.Active:
continue
if hasattr(obj, "Base") and hasattr(obj.Base, "Active"):
if not obj.Base.Active:
continue
if not PathUtil.activeForOp(obj):
continue
if hasattr(obj, "ClearanceHeight"):
clearanceHeight = obj.ClearanceHeight.Value
@@ -257,12 +255,7 @@ def export(objectslist, filename, argstring):
)
# get coolant mode
coolantMode = "None"
if hasattr(obj, "CoolantMode") or hasattr(obj, "Base") and hasattr(obj.Base, "CoolantMode"):
if hasattr(obj, "CoolantMode"):
coolantMode = obj.CoolantMode
else:
coolantMode = obj.Base.CoolantMode
coolantMode = PathUtil.coolantModeForOp(obj)
# turn coolant on if required
if OUTPUT_COMMENTS:

View File

@@ -263,7 +263,7 @@ def export(objectslist, filename, argstring):
continue
# Skip inactive operations
if PathUtil.opProperty(obj, "Active") is False:
if not PathUtil.activeForOp(obj):
continue
# do the pre_op
@@ -273,12 +273,7 @@ def export(objectslist, filename, argstring):
gcode += linenumber() + line
# get coolant mode
coolantMode = "None"
if hasattr(obj, "CoolantMode") or hasattr(obj, "Base") and hasattr(obj.Base, "CoolantMode"):
if hasattr(obj, "CoolantMode"):
coolantMode = obj.CoolantMode
else:
coolantMode = obj.Base.CoolantMode
coolantMode = PathUtil.coolantModeForOp(obj)
# turn coolant on if required
if OUTPUT_COMMENTS:

View File

@@ -38,6 +38,7 @@ import datetime
import shlex
# from PathScripts import PostUtils
import Path.Base.Util as PathUtil
import Path.Post.Utils as PostUtils
from PathScripts import PathUtils
from builtins import open as pyopen
@@ -216,12 +217,8 @@ def export(objectslist, filename, argstring):
for obj in objectslist:
# Skip inactive operations
if hasattr(obj, "Active"):
if not obj.Active:
continue
if hasattr(obj, "Base") and hasattr(obj.Base, "Active"):
if not obj.Base.Active:
continue
if not PathUtil.activeForOp(obj):
continue
# fetch machine details
job = PathUtils.findParentJob(obj)

View File

@@ -29,6 +29,7 @@ import argparse
import datetime
import shlex
import os.path
import Path.Base.Util as PathUtil
import Path.Post.Utils as PostUtils
import PathScripts.PathUtils as PathUtils
from builtins import open as pyopen
@@ -227,12 +228,8 @@ def export(objectslist, filename, argstring):
for obj in objectslist:
# Skip inactive operations
if hasattr(obj, "Active"):
if not obj.Active:
continue
if hasattr(obj, "Base") and hasattr(obj.Base, "Active"):
if not obj.Base.Active:
continue
if not PathUtil.activeForOp(obj):
continue
# do the pre_op
if OUTPUT_COMMENTS:
@@ -242,12 +239,7 @@ def export(objectslist, filename, argstring):
gcode += linenumber() + line
# get coolant mode
coolantMode = "None"
if hasattr(obj, "CoolantMode") or hasattr(obj, "Base") and hasattr(obj.Base, "CoolantMode"):
if hasattr(obj, "CoolantMode"):
coolantMode = obj.CoolantMode
else:
coolantMode = obj.Base.CoolantMode
coolantMode = PathUtil.coolantModeForOp(obj)
# turn coolant on if required
if OUTPUT_COMMENTS:

View File

@@ -315,7 +315,7 @@ def export(objectslist, filename, argstring):
return
# Skip inactive operations
if PathUtil.opProperty(obj, "Active") is False:
if not PathUtil.activeForOp(obj):
continue
# do the pre_op
@@ -329,12 +329,7 @@ def export(objectslist, filename, argstring):
gcode += linenumber() + line
# get coolant mode
coolantMode = "None"
if hasattr(obj, "CoolantMode") or hasattr(obj, "Base") and hasattr(obj.Base, "CoolantMode"):
if hasattr(obj, "CoolantMode"):
coolantMode = obj.CoolantMode
else:
coolantMode = obj.Base.CoolantMode
coolantMode = PathUtil.coolantModeForOp(obj)
# turn coolant on if required
if OUTPUT_COMMENTS:

View File

@@ -27,6 +27,7 @@ import Path
import argparse
import datetime
import shlex
import Path.Base.Util as PathUtil
import Path.Post.Utils as PostUtils
import PathScripts.PathUtils as PathUtils
from builtins import open as pyopen
@@ -203,12 +204,8 @@ def export(objectslist, filename, argstring):
for obj in objectslist:
# Skip inactive operations
if hasattr(obj, "Active"):
if not obj.Active:
continue
if hasattr(obj, "Base") and hasattr(obj.Base, "Active"):
if not obj.Base.Active:
continue
if not PathUtil.activeForOp(obj):
continue
# do the pre_op
if OUTPUT_COMMENTS:
@@ -218,12 +215,7 @@ def export(objectslist, filename, argstring):
gcode += linenumber() + line
# get coolant mode
coolantMode = "None"
if hasattr(obj, "CoolantMode") or hasattr(obj, "Base") and hasattr(obj.Base, "CoolantMode"):
if hasattr(obj, "CoolantMode"):
coolantMode = obj.CoolantMode
else:
coolantMode = obj.Base.CoolantMode
coolantMode = PathUtil.coolantModeForOp(obj)
# turn coolant on if required
if OUTPUT_COMMENTS:

View File

@@ -27,6 +27,7 @@ import Path
import argparse
import datetime
import shlex
import Path.Base.Util as PathUtil
import Path.Post.Utils as PostUtils
import PathScripts.PathUtils as PathUtils
from builtins import open as pyopen
@@ -203,12 +204,8 @@ def export(objectslist, filename, argstring):
for obj in objectslist:
# Skip inactive operations
if hasattr(obj, "Active"):
if not obj.Active:
continue
if hasattr(obj, "Base") and hasattr(obj.Base, "Active"):
if not obj.Base.Active:
continue
if not PathUtil.activeForOp(obj):
continue
# do the pre_op
if OUTPUT_COMMENTS:
@@ -221,12 +218,7 @@ def export(objectslist, filename, argstring):
gcode += linenumber() + line
# get coolant mode
coolantMode = "None"
if hasattr(obj, "CoolantMode") or hasattr(obj, "Base") and hasattr(obj.Base, "CoolantMode"):
if hasattr(obj, "CoolantMode"):
coolantMode = obj.CoolantMode
else:
coolantMode = obj.Base.CoolantMode
coolantMode = PathUtil.coolantModeForOp(obj)
# turn coolant on if required
if OUTPUT_COMMENTS:

View File

@@ -36,6 +36,7 @@ import Path
import Path.Base.Util as PathUtil
import Path.Post.Utils as PostUtils
import PathScripts.PathUtils as PathUtils
from builtins import open as pyopen
Revised = "2020-11-03" # Revision date for this file.
@@ -357,7 +358,7 @@ def export(objectslist, filename, argstring):
return
# Skip inactive operations:
if PathUtil.opProperty(obj, "Active") is False:
if not PathUtil.activeForOp(obj):
continue
# Do the pre_op:
@@ -371,12 +372,7 @@ def export(objectslist, filename, argstring):
gcode += linenumber() + line
# Get coolant mode:
coolantMode = "None" # None is the word returned from the operation
if hasattr(obj, "CoolantMode") or hasattr(obj, "Base") and hasattr(obj.Base, "CoolantMode"):
if hasattr(obj, "CoolantMode"):
coolantMode = obj.CoolantMode
else:
coolantMode = obj.Base.CoolantMode
coolantMode = PathUtil.coolantModeForOp(obj)
# Turn coolant on if required:
if OUTPUT_COMMENTS:
@@ -455,8 +451,10 @@ def export(objectslist, filename, argstring):
print("Done postprocessing.")
# Write the file:
with open(filename, "w") as fp:
fp.write(final)
if not filename == "-":
gfile = pyopen(filename, "w")
gfile.write(final)
gfile.close()
return final

View File

@@ -35,6 +35,7 @@ import Path
import Path.Base.Util as PathUtil
import Path.Post.Utils as PostUtils
import PathScripts.PathUtils as PathUtils
from builtins import open as pyopen
Revised = "2021-10-21" # Revision date for this file.
@@ -355,7 +356,7 @@ def export(objectslist, filename, argstring):
return
# Skip inactive operations:
if PathUtil.opProperty(obj, "Active") is False:
if not PathUtil.activeForOp(obj):
continue
# Do the pre_op:
@@ -369,12 +370,7 @@ def export(objectslist, filename, argstring):
gcode += linenumber() + line
# Get coolant mode:
coolantMode = "None" # None is the word returned from the operation
if hasattr(obj, "CoolantMode") or hasattr(obj, "Base") and hasattr(obj.Base, "CoolantMode"):
if hasattr(obj, "CoolantMode"):
coolantMode = obj.CoolantMode
else:
coolantMode = obj.Base.CoolantMode
coolantMode = PathUtil.coolantModeForOp(obj)
# Turn coolant on if required:
if OUTPUT_COMMENTS:
@@ -448,8 +444,12 @@ def export(objectslist, filename, argstring):
print("Done postprocessing.")
# Write the file:
with open(filename, "w") as fp:
fp.write(final)
if not filename == "-":
gfile = pyopen(filename, "w")
gfile.write(final)
gfile.close()
return final
def linenumber():

View File

@@ -31,6 +31,7 @@ from typing import Any, List, Tuple
import FreeCAD
import Path
import Path.Base.Util as PathUtil
import Path.Post.Processor
import Path.Post.UtilsArguments
import Path.Post.UtilsExport
@@ -773,11 +774,9 @@ class Snapmaker(Path.Post.Processor.PostProcessor):
for obj in objects:
# Skip inactive operations
if hasattr(obj, "Active") and not obj.Active:
if not PathUtil.activeForOp(obj):
continue
if hasattr(obj, "Base") and hasattr(obj.Base, "Active") and not obj.Base.Active:
continue
coolant_mode = Path.Post.UtilsExport.determine_coolant_mode(obj)
coolant_mode = PathUtil.coolantModeForOp(obj)
Path.Post.UtilsExport.output_start_bcnc(self.values, gcode, obj)
Path.Post.UtilsExport.output_preop(self.values, gcode, obj)
Path.Post.UtilsExport.output_coolant_on(self.values, gcode, coolant_mode)

View File

@@ -33,6 +33,7 @@
import FreeCAD
from FreeCAD import Units
import Path
import Path.Base.Util as PathUtil
import PathScripts.PathUtils as PathUtils
import argparse
import datetime
@@ -451,6 +452,10 @@ def export(objectslist, filename, argstring):
# write the code body
for obj in objectslist:
# Skip inactive operations
if not PathUtil.activeForOp(obj):
continue
# pre_op
if OUTPUT_COMMENTS:
gcode += append("(operation initialise: %s)\n" % obj.Label)
@@ -458,18 +463,17 @@ def export(objectslist, filename, argstring):
gcode += append(line)
# turn coolant on if required
if hasattr(obj, "CoolantMode"):
coolantMode = obj.CoolantMode
if coolantMode == "Mist":
if OUTPUT_COMMENTS:
gcode += append("M7 (coolant: mist on)\n")
else:
gcode += append("M7\n")
if coolantMode == "Flood":
if OUTPUT_COMMENTS:
gcode += append("M8 (coolant: flood on)\n")
else:
gcode += append("M8\n")
coolantMode = PathUtil.coolantModeForOp(obj)
if coolantMode == "Mist":
if OUTPUT_COMMENTS:
gcode += append("M7 (coolant: mist on)\n")
else:
gcode += append("M7\n")
if coolantMode == "Flood":
if OUTPUT_COMMENTS:
gcode += append("M8 (coolant: flood on)\n")
else:
gcode += append("M8\n")
# process the operation gcode
if OUTPUT_COMMENTS:
@@ -483,13 +487,12 @@ def export(objectslist, filename, argstring):
gcode += append(line)
# turn coolant off if required
if hasattr(obj, "CoolantMode"):
coolantMode = obj.CoolantMode
if not coolantMode == "None":
if OUTPUT_COMMENTS:
gcode += append("M9 (coolant: off)\n")
else:
gcode += append("M9\n")
if not coolantMode == "None":
if OUTPUT_COMMENTS:
gcode += append("M9 (coolant: off)\n")
else:
gcode += append("M9\n")
if OUTPUT_COMMENTS:
gcode += append("(operation finalised: %s)\n" % obj.Label)

View File

@@ -30,6 +30,7 @@ import Path
import argparse
import datetime
import shlex
import Path.Base.Util as PathUtil
import Path.Post.Utils as PostUtils
import PathScripts.PathUtils as PathUtils
from builtins import open as pyopen
@@ -279,12 +280,8 @@ def export(objectslist, filename, argstring):
for obj in objectslist:
# Skip inactive operations
if hasattr(obj, "Active"):
if not obj.Active:
continue
if hasattr(obj, "Base") and hasattr(obj.Base, "Active"):
if not obj.Base.Active:
continue
if not PathUtil.activeForOp(obj):
continue
# fetch machine details
job = PathUtils.findParentJob(obj)
@@ -319,12 +316,7 @@ def export(objectslist, filename, argstring):
gcode += linenumber() + line
# get coolant mode
coolantMode = "None"
if hasattr(obj, "CoolantMode") or hasattr(obj, "Base") and hasattr(obj.Base, "CoolantMode"):
if hasattr(obj, "CoolantMode"):
coolantMode = obj.CoolantMode
else:
coolantMode = obj.Base.CoolantMode
coolantMode = PathUtil.coolantModeForOp(obj)
# turn coolant on if required
if OUTPUT_COMMENTS:

View File

@@ -77,6 +77,7 @@ from CAMTests.TestRefactoredGrblPost import TestRefactoredGrblPost
from CAMTests.TestRefactoredLinuxCNCPost import TestRefactoredLinuxCNCPost
from CAMTests.TestRefactoredMassoG3Post import TestRefactoredMassoG3Post
from CAMTests.TestRefactoredMach3Mach4Post import TestRefactoredMach3Mach4Post
from CAMTests.TestRefactoredTestDressupPost import TestRefactoredTestDressupPost
from CAMTests.TestRefactoredTestPost import TestRefactoredTestPost
from CAMTests.TestRefactoredTestPostGCodes import TestRefactoredTestPostGCodes
from CAMTests.TestRefactoredTestPostMCodes import TestRefactoredTestPostMCodes
@@ -134,6 +135,7 @@ False if TestRefactoredGrblPost.__name__ else True
False if TestRefactoredLinuxCNCPost.__name__ else True
False if TestRefactoredMassoG3Post.__name__ else True
False if TestRefactoredMach3Mach4Post.__name__ else True
False if TestRefactoredTestDressupPost.__name__ else True
False if TestRefactoredTestPost.__name__ else True
False if TestRefactoredTestPostGCodes.__name__ else True
False if TestRefactoredTestPostMCodes.__name__ else True