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

@@ -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: