Merge pull request #6662 from Russ4262/fix/import_gcode

Path:  Fixes #6629 - Add missing Job for import G-code [Bug]
This commit is contained in:
sliptonic
2022-03-30 11:16:00 -05:00
committed by GitHub
4 changed files with 281 additions and 50 deletions

View File

@@ -1631,7 +1631,7 @@ class TaskPanel:
self.updateSelection()
def Create(base, template=None):
def Create(base, template=None, openTaskPanel=True):
"""Create(base, template) ... creates a job instance for the given base object
using template to configure it."""
FreeCADGui.addModule("PathScripts.PathJob")
@@ -1642,7 +1642,10 @@ def Create(base, template=None):
obj.ViewObject.addExtension("Gui::ViewProviderGroupExtensionPython")
FreeCAD.ActiveDocument.commitTransaction()
obj.Document.recompute()
obj.ViewObject.Proxy.editObject(obj.Stock)
if openTaskPanel:
obj.ViewObject.Proxy.editObject(obj.Stock)
else:
obj.ViewObject.Proxy.deleteOnReject = False
return obj
except Exception as exc:
PathLog.error(exc)

View File

@@ -47,11 +47,17 @@ import FreeCAD
import PathScripts.PathUtils as PathUtils
import PathScripts.PathLog as PathLog
import re
import PathScripts.PathCustom as PathCustom
import PathScripts.PathCustomGui as PathCustomGui
import PathScripts.PathOpGui as PathOpGui
from PySide.QtCore import QT_TRANSLATE_NOOP
if FreeCAD.GuiUp:
import PathScripts.PathCustomGui as PathCustomGui
PathCustom = PathCustomGui.PathCustom
else:
import PathScripts.PathCustom as PathCustom
translate = FreeCAD.Qt.translate
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
@@ -60,6 +66,20 @@ else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
class PathNoActiveDocumentException(Exception):
"""PathNoActiveDocumentException is raised when no active document is found."""
def __init__(self):
super().__init__("No active document")
class PathNoJobException(Exception):
"""PathNoJobException is raised when no target Job object is available."""
def __init__(self):
super().__init__("No job object")
# to distinguish python built-in open function from the one declared below
if open.__module__ in ["__builtin__", "io"]:
pythonopen = open
@@ -82,54 +102,20 @@ def matchToolController(op, toolnumber):
return toolcontrollers[0]
def insert(filename, docname):
"""called when freecad imports a file"""
PathLog.track(filename)
gfile = pythonopen(filename)
gcode = gfile.read()
gfile.close()
def _isImportEnvironmentReady():
"""_isImportEnvironmentReady(docname)...
Helper function to verify an active document exists, and that a Job object is available
as a receiver for the Custom operation(s) that will be created as a result of the import process."""
# Regular expression to match tool changes in the format 'M6 Tn'
p = re.compile("[mM]+?\s?0?6\s?T\d*\s")
# Verify active document exists
if FreeCAD.ActiveDocument is None:
raise PathNoActiveDocumentException()
# split the gcode on tool changes
paths = re.split("([mM]+?\s?0?6\s?T\d*\s)", gcode)
# Verify a Job object is available, and add one if not
if not PathUtils.GetJobs():
raise PathNoJobException()
# iterate the gcode sections and add customs for each
toolnumber = 0
for path in paths:
# if the section is a tool change, extract the tool number
m = p.match(path)
if m:
toolnumber = int(m.group().split("T")[-1])
continue
# Parse the gcode and throw away any empty lists
gcode = parse(path)
if len(gcode) == 0:
continue
# Create a custom and viewobject
obj = PathCustom.Create("Custom")
res = PathOpGui.CommandResources(
"Custom",
PathCustom.Create,
PathCustomGui.TaskPanelOpPage,
"Path_Custom",
QT_TRANSLATE_NOOP("Path_Custom", "Custom"),
"",
"",
)
obj.ViewObject.Proxy = PathOpGui.ViewProvider(obj.ViewObject, res)
obj.ViewObject.Proxy.setDeleteObjectsOnReject(False)
# Set the gcode and try to match a tool controller
obj.Gcode = gcode
obj.ToolController = matchToolController(obj, toolnumber)
FreeCAD.ActiveDocument.recompute()
return True
def parse(inputstring):
@@ -195,4 +181,72 @@ def parse(inputstring):
return output
def _identifygcodeByToolNumberList(filename):
"""called when freecad imports a file"""
PathLog.track(filename)
gcodeByToolNumberList = []
gfile = pythonopen(filename)
gcode = gfile.read()
gfile.close()
# Regular expression to match tool changes in the format 'M6 Tn'
p = re.compile("[mM]+?\s?0?6\s?T\d*\s")
# split the gcode on tool changes
paths = re.split("([mM]+?\s?0?6\s?T\d*\s)", gcode)
# iterate the gcode sections and add customs for each
toolnumber = 0
for path in paths:
# if the section is a tool change, extract the tool number
m = p.match(path)
if m:
toolnumber = int(m.group().split("T")[-1])
continue
# Parse the gcode and throw away any empty lists
gcode = parse(path)
if len(gcode) > 0:
gcodeByToolNumberList.append((gcode, toolnumber))
return gcodeByToolNumberList
def insert(filename, docname=None):
"""called when freecad imports a file"""
PathLog.track(filename)
try:
if not _isImportEnvironmentReady():
return
except PathNoActiveDocumentException:
PathLog.error(translate("Path_Gcode_pre", "No active document"))
return
except PathNoJobException:
PathLog.error(translate("Path_Gcode_pre", "No job object"))
return
# Create a Custom operation for each gcode-toolNumber pair
for gcode, toolNumber in _identifygcodeByToolNumberList(filename):
obj = PathCustom.Create("Custom")
# Set the gcode and try to match a tool controller
obj.Gcode = gcode
obj.ToolController = matchToolController(obj, toolNumber)
if docname:
obj.Label = obj.Label + "_" + docname
if FreeCAD.GuiUp:
# Add a view provider to a Custom operation object
obj.ViewObject.Proxy = PathCustomGui.PathOpGui.ViewProvider(
obj.ViewObject, PathCustomGui.Command.res
)
obj.ViewObject.Proxy.setDeleteObjectsOnReject(False)
FreeCAD.ActiveDocument.recompute()
print(__name__ + " gcode preprocessor loaded.")

File diff suppressed because one or more lines are too long

View File

@@ -40,6 +40,7 @@ from PathTests.TestPathOpTools import TestPathOpTools
# from PathTests.TestPathPost import PathPostTestCases
from PathTests.TestPathPost import TestPathPostUtils
from PathTests.TestPathPost import TestPathPostImport
from PathTests.TestPathPreferences import TestPathPreferences
from PathTests.TestPathPropertyBag import TestPathPropertyBag
from PathTests.TestPathRotationGenerator import TestPathRotationGenerator
@@ -70,6 +71,7 @@ False if TestPathHelpers.__name__ else True
# False if TestPathHelix.__name__ else True
False if TestPathLog.__name__ else True
False if TestPathOpTools.__name__ else True
False if TestPathPostImport.__name__ else True
# False if TestPathPost.__name__ else True
False if TestPathPostUtils.__name__ else True
False if TestPathPreferences.__name__ else True