diff --git a/src/Mod/Path/PathScripts/PathDeburr.py b/src/Mod/Path/PathScripts/PathDeburr.py
index fbfdf7cf02..45c92b9676 100644
--- a/src/Mod/Path/PathScripts/PathDeburr.py
+++ b/src/Mod/Path/PathScripts/PathDeburr.py
@@ -29,54 +29,68 @@ import PathScripts.PathOp as PathOp
import PathScripts.PathOpTools as PathOpTools
import math
-from PySide import QtCore
+from PySide.QtCore import QT_TRANSLATE_NOOP
# lazily loaded modules
from lazy_loader.lazy_loader import LazyLoader
-Part = LazyLoader('Part', globals(), 'Part')
+
+Part = LazyLoader("Part", globals(), "Part")
__title__ = "Path Deburr Operation"
__author__ = "sliptonic (Brad Collette), Schildkroet"
__url__ = "http://www.freecadweb.org"
__doc__ = "Deburr operation."
-PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
-# PathLog.trackModule(PathLog.thisModule())
+if False:
+ PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
+ PathLog.trackModule(PathLog.thisModule())
+else:
+ PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
-# Qt translation handling
-def translate(context, text, disambig=None):
- return QtCore.QCoreApplication.translate(context, text, disambig)
+translate = FreeCAD.Qt.translate
def toolDepthAndOffset(width, extraDepth, tool, printInfo):
- '''toolDepthAndOffset(width, extraDepth, tool) ... return tuple for given\n
- parameters.'''
+ """toolDepthAndOffset(width, extraDepth, tool) ... return tuple for given\n
+ parameters."""
- if not hasattr(tool, 'Diameter'):
- raise ValueError('Deburr requires tool with diameter\n')
+ if not hasattr(tool, "Diameter"):
+ raise ValueError("Deburr requires tool with diameter\n")
suppressInfo = False
- if hasattr(tool, 'CuttingEdgeAngle'):
+ if hasattr(tool, "CuttingEdgeAngle"):
angle = float(tool.CuttingEdgeAngle)
if PathGeom.isRoughly(angle, 180) or PathGeom.isRoughly(angle, 0):
angle = 180
toolOffset = float(tool.Diameter) / 2
else:
- if hasattr(tool, 'TipDiameter'):
+ if hasattr(tool, "TipDiameter"):
toolOffset = float(tool.TipDiameter) / 2
- elif hasattr(tool, 'FlatRadius'):
+ elif hasattr(tool, "FlatRadius"):
toolOffset = float(tool.FlatRadius)
else:
toolOffset = 0.0
if printInfo and not suppressInfo:
- FreeCAD.Console.PrintMessage(translate('PathDeburr', "The selected tool has no FlatRadius and no TipDiameter property. Assuming {}\n".format("Endmill" if angle == 180 else "V-Bit")))
+ FreeCAD.Console.PrintMessage(
+ translate(
+ "PathDeburr",
+ "The selected tool has no FlatRadius and no TipDiameter property. Assuming {}\n".format(
+ "Endmill" if angle == 180 else "V-Bit"
+ ),
+ )
+ )
suppressInfo = True
else:
angle = 180
toolOffset = float(tool.Diameter) / 2
if printInfo:
- FreeCAD.Console.PrintMessage(translate('PathDeburr', 'The selected tool has no CuttingEdgeAngle property. Assuming Endmill\n'))
+ FreeCAD.Console.PrintMessage(
+ translate(
+ "PathDeburr",
+ "The selected tool has no CuttingEdgeAngle property. Assuming Endmill\n",
+ )
+ )
suppressInfo = True
tan = math.tan(math.radians(angle / 2))
@@ -90,40 +104,119 @@ def toolDepthAndOffset(width, extraDepth, tool, printInfo):
class ObjectDeburr(PathEngraveBase.ObjectOp):
- '''Proxy class for Deburr operation.'''
+ """Proxy class for Deburr operation."""
def opFeatures(self, obj):
- return PathOp.FeatureTool | PathOp.FeatureHeights | PathOp.FeatureStepDown | PathOp.FeatureBaseEdges | PathOp.FeatureBaseFaces | PathOp.FeatureCoolant | PathOp.FeatureBaseGeometry
+ return (
+ PathOp.FeatureTool
+ | PathOp.FeatureHeights
+ | PathOp.FeatureStepDown
+ | PathOp.FeatureBaseEdges
+ | PathOp.FeatureBaseFaces
+ | PathOp.FeatureCoolant
+ | PathOp.FeatureBaseGeometry
+ )
def initOperation(self, obj):
PathLog.track(obj.Label)
- obj.addProperty('App::PropertyDistance', 'Width', 'Deburr',
- QtCore.QT_TRANSLATE_NOOP('PathDeburr', 'The desired width of the chamfer'))
- obj.addProperty('App::PropertyDistance', 'ExtraDepth', 'Deburr',
- QtCore.QT_TRANSLATE_NOOP('PathDeburr', 'The additional depth of the tool path'))
- obj.addProperty('App::PropertyEnumeration', 'Join', 'Deburr',
- QtCore.QT_TRANSLATE_NOOP('PathDeburr', 'How to join chamfer segments'))
- obj.Join = ['Round', 'Miter']
- obj.setEditorMode('Join', 2) # hide for now
- obj.addProperty('App::PropertyEnumeration', 'Direction', 'Deburr',
- QtCore.QT_TRANSLATE_NOOP('PathDeburr', 'Direction of Operation'))
- obj.Direction = ['CW', 'CCW']
- obj.addProperty('App::PropertyEnumeration', 'Side', 'Deburr',
- QtCore.QT_TRANSLATE_NOOP('PathDeburr', 'Side of Operation'))
- obj.Side = ['Outside', 'Inside']
- obj.setEditorMode('Side', 2) # Hide property, it's calculated by op
- obj.addProperty('App::PropertyInteger', 'EntryPoint', 'Deburr',
- QtCore.QT_TRANSLATE_NOOP('PathDeburr', 'Select the segment, there the operations starts'))
+ obj.addProperty(
+ "App::PropertyDistance",
+ "Width",
+ "Deburr",
+ QT_TRANSLATE_NOOP("App::Property", "The desired width of the chamfer"),
+ )
+ obj.addProperty(
+ "App::PropertyDistance",
+ "ExtraDepth",
+ "Deburr",
+ QT_TRANSLATE_NOOP("App::Property", "The additional depth of the tool path"),
+ )
+ obj.addProperty(
+ "App::PropertyEnumeration",
+ "Join",
+ "Deburr",
+ QT_TRANSLATE_NOOP("App::Property", "How to join chamfer segments"),
+ )
+ # obj.Join = ["Round", "Miter"]
+ obj.setEditorMode("Join", 2) # hide for now
+ obj.addProperty(
+ "App::PropertyEnumeration",
+ "Direction",
+ "Deburr",
+ QT_TRANSLATE_NOOP("App::Property", "Direction of Operation"),
+ )
+ # obj.Direction = ["CW", "CCW"]
+ obj.addProperty(
+ "App::PropertyEnumeration",
+ "Side",
+ "Deburr",
+ QT_TRANSLATE_NOOP("App::Property", "Side of Operation"),
+ )
+ obj.Side = ["Outside", "Inside"]
+ obj.setEditorMode("Side", 2) # Hide property, it's calculated by op
+ obj.addProperty(
+ "App::PropertyInteger",
+ "EntryPoint",
+ "Deburr",
+ QT_TRANSLATE_NOOP(
+ "App::Property", "Select the segment, there the operations starts"
+ ),
+ )
+
+ ENUMS = self.propertyEnumerations()
+ for n in ENUMS:
+ setattr(obj, n[0], n[1])
+
+ @classmethod
+ def propertyEnumerations(self, dataType="data"):
+
+ """opPropertyEnumerations(dataType="data")... return property enumeration lists of specified dataType.
+ Args:
+ dataType = 'data', 'raw', 'translated'
+ Notes:
+ 'data' is list of internal string literals used in code
+ 'raw' is list of (translated_text, data_string) tuples
+ 'translated' is list of translated string literals
+ """
+
+ # Enumeration lists for App::PropertyEnumeration properties
+ enums = {
+ "Direction": [
+ (translate("Path", "CW"), "CW"),
+ (translate("Path", "CCW"), "CCW"),
+ ], # this is the direction that the profile runs
+ "Join": [
+ (translate("PathDeburr", "Round"), "Round"),
+ (translate("PathDeburr", "Miter"), "Miter"),
+ ], # this is the direction that the profile runs
+ }
+
+ if dataType == "raw":
+ return enums
+
+ data = list()
+ idx = 0 if dataType == "translated" else 1
+
+ PathLog.debug(enums)
+
+ for k, v in enumerate(enums):
+ # data[k] = [tup[idx] for tup in v]
+ data.append((v, [tup[idx] for tup in enums[v]]))
+ PathLog.debug(data)
+
+ return data
def opOnDocumentRestored(self, obj):
- obj.setEditorMode('Join', 2) # hide for now
+ obj.setEditorMode("Join", 2) # hide for now
def opExecute(self, obj):
PathLog.track(obj.Label)
- if not hasattr(self, 'printInfo'):
+ if not hasattr(self, "printInfo"):
self.printInfo = True
try:
- (depth, offset, extraOffset, suppressInfo) = toolDepthAndOffset(obj.Width.Value, obj.ExtraDepth.Value, self.tool, self.printInfo)
+ (depth, offset, extraOffset, suppressInfo) = toolDepthAndOffset(
+ obj.Width.Value, obj.ExtraDepth.Value, self.tool, self.printInfo
+ )
self.printInfo = not suppressInfo
except ValueError as e:
msg = "{} \n No path will be generated".format(e)
@@ -147,13 +240,15 @@ class ObjectDeburr(PathEngraveBase.ObjectOp):
for f in subs:
sub = base.Shape.getElement(f)
- if type(sub) == Part.Edge: # Edge
+ if type(sub) == Part.Edge: # Edge
edges.append(sub)
-
- elif type(sub) == Part.Face and sub.normalAt(0, 0) != FreeCAD.Vector(0, 0, 1): # Angled face
+
+ elif type(sub) == Part.Face and sub.normalAt(0, 0) != FreeCAD.Vector(
+ 0, 0, 1
+ ): # Angled face
# If an angled face is selected, the lower edge is projected to the height of the upper edge,
# to simulate an edge
-
+
# Find z value of upper edge
for edge in sub.Edges:
for p0 in edge.Vertexes:
@@ -161,7 +256,7 @@ class ObjectDeburr(PathEngraveBase.ObjectOp):
max_h = p0.Point.z
# Find biggest radius for top/bottom
- for edge in sub.Edges:
+ for edge in sub.Edges:
if Part.Circle == type(edge.Curve):
if edge.Vertexes[0].Point.z == max_h:
if edge.Curve.Radius > radius_top:
@@ -169,63 +264,139 @@ class ObjectDeburr(PathEngraveBase.ObjectOp):
else:
if edge.Curve.Radius > radius_bottom:
radius_bottom = edge.Curve.Radius
-
+
# Search for lower edge and raise it to height of upper edge
for edge in sub.Edges:
- if Part.Circle == type(edge.Curve): # Edge is a circle
+ if Part.Circle == type(edge.Curve): # Edge is a circle
if edge.Vertexes[0].Point.z < max_h:
-
- if edge.Closed: # Circle
+
+ if edge.Closed: # Circle
# New center
- center = FreeCAD.Vector(edge.Curve.Center.x, edge.Curve.Center.y, max_h)
- new_edge = Part.makeCircle(edge.Curve.Radius, center, FreeCAD.Vector(0, 0, 1))
+ center = FreeCAD.Vector(
+ edge.Curve.Center.x, edge.Curve.Center.y, max_h
+ )
+ new_edge = Part.makeCircle(
+ edge.Curve.Radius,
+ center,
+ FreeCAD.Vector(0, 0, 1),
+ )
edges.append(new_edge)
-
+
# Modify offset for inner angled faces
if radius_bottom < radius_top:
offset -= 2 * extraOffset
-
+
break
- else: # Arc
- if edge.Vertexes[0].Point.z == edge.Vertexes[1].Point.z:
+ else: # Arc
+ if (
+ edge.Vertexes[0].Point.z
+ == edge.Vertexes[1].Point.z
+ ):
# Arc vertexes are on same layer
- l1 = math.sqrt((edge.Vertexes[0].Point.x - edge.Curve.Center.x)**2 + (edge.Vertexes[0].Point.y - edge.Curve.Center.y)**2)
- l2 = math.sqrt((edge.Vertexes[1].Point.x - edge.Curve.Center.x)**2 + (edge.Vertexes[1].Point.y - edge.Curve.Center.y)**2)
-
+ l1 = math.sqrt(
+ (
+ edge.Vertexes[0].Point.x
+ - edge.Curve.Center.x
+ )
+ ** 2
+ + (
+ edge.Vertexes[0].Point.y
+ - edge.Curve.Center.y
+ )
+ ** 2
+ )
+ l2 = math.sqrt(
+ (
+ edge.Vertexes[1].Point.x
+ - edge.Curve.Center.x
+ )
+ ** 2
+ + (
+ edge.Vertexes[1].Point.y
+ - edge.Curve.Center.y
+ )
+ ** 2
+ )
+
# New center
- center = FreeCAD.Vector(edge.Curve.Center.x, edge.Curve.Center.y, max_h)
+ center = FreeCAD.Vector(
+ edge.Curve.Center.x,
+ edge.Curve.Center.y,
+ max_h,
+ )
# Calculate angles based on x-axis (0 - PI/2)
- start_angle = math.acos((edge.Vertexes[0].Point.x - edge.Curve.Center.x) / l1)
- end_angle = math.acos((edge.Vertexes[1].Point.x - edge.Curve.Center.x) / l2)
+ start_angle = math.acos(
+ (
+ edge.Vertexes[0].Point.x
+ - edge.Curve.Center.x
+ )
+ / l1
+ )
+ end_angle = math.acos(
+ (
+ edge.Vertexes[1].Point.x
+ - edge.Curve.Center.x
+ )
+ / l2
+ )
# Angles are based on x-axis (Mirrored on x-axis) -> negative y value means negative angle
- if edge.Vertexes[0].Point.y < edge.Curve.Center.y:
+ if (
+ edge.Vertexes[0].Point.y
+ < edge.Curve.Center.y
+ ):
start_angle *= -1
- if edge.Vertexes[1].Point.y < edge.Curve.Center.y:
+ if (
+ edge.Vertexes[1].Point.y
+ < edge.Curve.Center.y
+ ):
end_angle *= -1
# Create new arc
- new_edge = Part.ArcOfCircle(Part.Circle(center, FreeCAD.Vector(0,0,1), edge.Curve.Radius), start_angle, end_angle).toShape()
+ new_edge = Part.ArcOfCircle(
+ Part.Circle(
+ center,
+ FreeCAD.Vector(0, 0, 1),
+ edge.Curve.Radius,
+ ),
+ start_angle,
+ end_angle,
+ ).toShape()
edges.append(new_edge)
-
+
# Modify offset for inner angled faces
if radius_bottom < radius_top:
offset -= 2 * extraOffset
break
- else: # Line
- if edge.Vertexes[0].Point.z == edge.Vertexes[1].Point.z and edge.Vertexes[0].Point.z < max_h:
- new_edge = Part.Edge(Part.LineSegment(FreeCAD.Vector(edge.Vertexes[0].Point.x, edge.Vertexes[0].Point.y, max_h), FreeCAD.Vector(edge.Vertexes[1].Point.x, edge.Vertexes[1].Point.y, max_h)))
+ else: # Line
+ if (
+ edge.Vertexes[0].Point.z == edge.Vertexes[1].Point.z
+ and edge.Vertexes[0].Point.z < max_h
+ ):
+ new_edge = Part.Edge(
+ Part.LineSegment(
+ FreeCAD.Vector(
+ edge.Vertexes[0].Point.x,
+ edge.Vertexes[0].Point.y,
+ max_h,
+ ),
+ FreeCAD.Vector(
+ edge.Vertexes[1].Point.x,
+ edge.Vertexes[1].Point.y,
+ max_h,
+ ),
+ )
+ )
edges.append(new_edge)
-
elif sub.Wires:
basewires.extend(sub.Wires)
-
- else: # Flat face
+
+ else: # Flat face
basewires.append(Part.Wire(sub.Edges))
self.edges = edges # pylint: disable=attribute-defined-outside-init
@@ -244,7 +415,7 @@ class ObjectDeburr(PathEngraveBase.ObjectOp):
wires.append(wire)
# Set direction of op
- forward = (obj.Direction == 'CW')
+ forward = obj.Direction == "CW"
# Set value of side
obj.Side = side[0]
@@ -258,7 +429,7 @@ class ObjectDeburr(PathEngraveBase.ObjectOp):
while z + obj.StepDown.Value < depth:
z = z + obj.StepDown.Value
zValues.append(z)
-
+
zValues.append(depth)
PathLog.track(obj.Label, depth, zValues)
@@ -269,30 +440,30 @@ class ObjectDeburr(PathEngraveBase.ObjectOp):
self.buildpathocc(obj, wires, zValues, True, forward, obj.EntryPoint)
def opRejectAddBase(self, obj, base, sub):
- '''The chamfer op can only deal with features of the base model, all others are rejected.'''
+ """The chamfer op can only deal with features of the base model, all others are rejected."""
return base not in self.model
def opSetDefaultValues(self, obj, job):
PathLog.track(obj.Label, job.Label)
- obj.Width = '1 mm'
- obj.ExtraDepth = '0.5 mm'
- obj.Join = 'Round'
- obj.setExpression('StepDown', '0 mm')
- obj.StepDown = '0 mm'
- obj.Direction = 'CW'
+ obj.Width = "1 mm"
+ obj.ExtraDepth = "0.5 mm"
+ obj.Join = "Round"
+ obj.setExpression("StepDown", "0 mm")
+ obj.StepDown = "0 mm"
+ obj.Direction = "CW"
obj.Side = "Outside"
obj.EntryPoint = 0
def SetupProperties():
setup = []
- setup.append('Width')
- setup.append('ExtraDepth')
+ setup.append("Width")
+ setup.append("ExtraDepth")
return setup
def Create(name, obj=None, parentJob=None):
- '''Create(name) ... Creates and returns a Deburr operation.'''
+ """Create(name) ... Creates and returns a Deburr operation."""
if obj is None:
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name)
obj.Proxy = ObjectDeburr(obj, name, parentJob)
diff --git a/src/Mod/Path/PathScripts/PathDeburrGui.py b/src/Mod/Path/PathScripts/PathDeburrGui.py
index 537d12dca5..ddcce623ee 100644
--- a/src/Mod/Path/PathScripts/PathDeburrGui.py
+++ b/src/Mod/Path/PathScripts/PathDeburrGui.py
@@ -27,6 +27,7 @@ import PathScripts.PathGui as PathGui
import PathScripts.PathLog as PathLog
import PathScripts.PathOpGui as PathOpGui
from PySide import QtCore, QtGui
+from PySide.QtCore import QT_TRANSLATE_NOOP
__title__ = "Path Deburr Operation UI"
__author__ = "sliptonic (Brad Collette), Schildkroet"
@@ -34,16 +35,18 @@ __url__ = "https://www.freecadweb.org"
__doc__ = "Deburr operation page controller and command implementation."
-PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
-# PathLog.trackModule(PathLog.thisModule())
+if False:
+ PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
+ PathLog.trackModule(PathLog.thisModule())
+else:
+ PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
-def translate(context, text, disambig=None):
- return QtCore.QCoreApplication.translate(context, text, disambig)
+translate = FreeCAD.Qt.translate
class TaskPanelBaseGeometryPage(PathOpGui.TaskPanelBaseGeometryPage):
- '''Enhanced base geometry page to also allow special base objects.'''
+ """Enhanced base geometry page to also allow special base objects."""
def super(self):
return super(TaskPanelBaseGeometryPage, self)
@@ -53,51 +56,69 @@ class TaskPanelBaseGeometryPage(PathOpGui.TaskPanelBaseGeometryPage):
class TaskPanelOpPage(PathOpGui.TaskPanelPage):
- '''Page controller class for the Deburr operation.'''
+ """Page controller class for the Deburr operation."""
+
+ _ui_form = ":/panels/PageOpDeburrEdit.ui"
def getForm(self):
- return FreeCADGui.PySideUic.loadUi(":/panels/PageOpDeburrEdit.ui")
+ form = FreeCADGui.PySideUic.loadUi(self._ui_form)
+ comboToPropertyMap = [("direction", "Direction")]
+ enumTups = PathDeburr.ObjectDeburr.propertyEnumerations(dataType="raw")
+
+ self.populateCombobox(form, enumTups, comboToPropertyMap)
+
+ return form
def initPage(self, obj):
- self.opImagePath = "{}Mod/Path/Images/Ops/{}".format(FreeCAD.getHomePath(), 'chamfer.svg') # pylint: disable=attribute-defined-outside-init
- self.opImage = QtGui.QPixmap(self.opImagePath) # pylint: disable=attribute-defined-outside-init
+ self.opImagePath = "{}Mod/Path/Images/Ops/{}".format(
+ FreeCAD.getHomePath(), "chamfer.svg"
+ ) # pylint: disable=attribute-defined-outside-init
+ self.opImage = QtGui.QPixmap(
+ self.opImagePath
+ ) # pylint: disable=attribute-defined-outside-init
self.form.opImage.setPixmap(self.opImage)
- iconMiter = QtGui.QIcon(':/icons/edge-join-miter-not.svg')
- iconMiter.addFile(':/icons/edge-join-miter.svg', state=QtGui.QIcon.On)
- iconRound = QtGui.QIcon(':/icons/edge-join-round-not.svg')
- iconRound.addFile(':/icons/edge-join-round.svg', state=QtGui.QIcon.On)
+ iconMiter = QtGui.QIcon(":/icons/edge-join-miter-not.svg")
+ iconMiter.addFile(":/icons/edge-join-miter.svg", state=QtGui.QIcon.On)
+ iconRound = QtGui.QIcon(":/icons/edge-join-round-not.svg")
+ iconRound.addFile(":/icons/edge-join-round.svg", state=QtGui.QIcon.On)
self.form.joinMiter.setIcon(iconMiter)
self.form.joinRound.setIcon(iconRound)
def getFields(self, obj):
- PathGui.updateInputField(obj, 'Width', self.form.value_W)
- PathGui.updateInputField(obj, 'ExtraDepth', self.form.value_h)
+ PathGui.updateInputField(obj, "Width", self.form.value_W)
+ PathGui.updateInputField(obj, "ExtraDepth", self.form.value_h)
if self.form.joinRound.isChecked():
- obj.Join = 'Round'
+ obj.Join = "Round"
elif self.form.joinMiter.isChecked():
- obj.Join = 'Miter'
+ obj.Join = "Miter"
- if obj.Direction != str(self.form.direction.currentText()):
- obj.Direction = str(self.form.direction.currentText())
+ if obj.Direction != str(self.form.direction.currentData()):
+ obj.Direction = str(self.form.direction.currentData())
self.updateToolController(obj, self.form.toolController)
self.updateCoolant(obj, self.form.coolantController)
def setFields(self, obj):
- self.form.value_W.setText(FreeCAD.Units.Quantity(obj.Width.Value, FreeCAD.Units.Length).UserString)
- self.form.value_h.setText(FreeCAD.Units.Quantity(obj.ExtraDepth.Value, FreeCAD.Units.Length).UserString)
+ self.form.value_W.setText(
+ FreeCAD.Units.Quantity(obj.Width.Value, FreeCAD.Units.Length).UserString
+ )
+ self.form.value_h.setText(
+ FreeCAD.Units.Quantity(
+ obj.ExtraDepth.Value, FreeCAD.Units.Length
+ ).UserString
+ )
self.setupToolController(obj, self.form.toolController)
self.setupCoolant(obj, self.form.coolantController)
- self.form.joinRound.setChecked('Round' == obj.Join)
- self.form.joinMiter.setChecked('Miter' == obj.Join)
+ self.form.joinRound.setChecked("Round" == obj.Join)
+ self.form.joinMiter.setChecked("Miter" == obj.Join)
self.form.joinFrame.hide()
self.selectInComboBox(obj.Direction, self.form.direction)
def updateWidth(self):
- PathGui.updateInputField(self.obj, 'Width', self.form.value_W)
+ PathGui.updateInputField(self.obj, "Width", self.form.value_W)
def updateExtraDepth(self):
- PathGui.updateInputField(self.obj, 'ExtraDepth', self.form.value_h)
+ PathGui.updateInputField(self.obj, "ExtraDepth", self.form.value_h)
def getSignalsForUpdate(self, obj):
signals = []
@@ -114,16 +135,20 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage):
self.form.value_h.editingFinished.connect(self.updateExtraDepth)
def taskPanelBaseGeometryPage(self, obj, features):
- '''taskPanelBaseGeometryPage(obj, features) ... return page for adding base geometries.'''
+ """taskPanelBaseGeometryPage(obj, features) ... return page for adding base geometries."""
return TaskPanelBaseGeometryPage(obj, features)
-Command = PathOpGui.SetupOperation('Deburr',
- PathDeburr.Create,
- TaskPanelOpPage,
- 'Path_Deburr',
- QtCore.QT_TRANSLATE_NOOP("PathDeburr", "Deburr"),
- QtCore.QT_TRANSLATE_NOOP("PathDeburr", "Creates a Deburr Path along Edges or around Faces"),
- PathDeburr.SetupProperties)
+Command = PathOpGui.SetupOperation(
+ "Deburr",
+ PathDeburr.Create,
+ TaskPanelOpPage,
+ "Path_Deburr",
+ QT_TRANSLATE_NOOP("Path_Deburr", "Deburr"),
+ QT_TRANSLATE_NOOP(
+ "Path_Deburr", "Creates a Deburr Path along Edges or around Faces"
+ ),
+ PathDeburr.SetupProperties,
+)
FreeCAD.Console.PrintLog("Loading PathDeburrGui... done\n")
diff --git a/src/Mod/Path/PathScripts/PathFixture.py b/src/Mod/Path/PathScripts/PathFixture.py
index 0571e13467..9c871bbdd6 100644
--- a/src/Mod/Path/PathScripts/PathFixture.py
+++ b/src/Mod/Path/PathScripts/PathFixture.py
@@ -189,7 +189,7 @@ PathUtils.addToJob(obj)
if FreeCAD.GuiUp:
# register the FreeCAD command
- FreeCADGui.addCommand("PathFixture", CommandPathFixture())
+ FreeCADGui.addCommand("Path_Fixture", CommandPathFixture())
FreeCAD.Console.PrintLog("Loading PathFixture... done\n")
diff --git a/src/Mod/Path/PathScripts/PathInspect.py b/src/Mod/Path/PathScripts/PathInspect.py
index f22fbe8f0d..786bcd2c4c 100644
--- a/src/Mod/Path/PathScripts/PathInspect.py
+++ b/src/Mod/Path/PathScripts/PathInspect.py
@@ -27,19 +27,17 @@ from PySide import QtCore, QtGui
import FreeCAD
import FreeCADGui
import Path
+from PySide.QtCore import QT_TRANSLATE_NOOP
-
-# Qt translation handling
-def translate(context, text, disambig=None):
- return QtCore.QCoreApplication.translate(context, text, disambig)
+translate = FreeCAD.Qt.translate
class GCodeHighlighter(QtGui.QSyntaxHighlighter):
-
def __init__(self, parent=None):
-
def convertcolor(c):
- return QtGui.QColor(int((c >> 24) & 0xFF), int((c >> 16) & 0xFF), int((c >> 8) & 0xFF))
+ return QtGui.QColor(
+ int((c >> 24) & 0xFF), int((c >> 16) & 0xFF), int((c >> 8) & 0xFF)
+ )
super(GCodeHighlighter, self).__init__(parent)
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Editor")
@@ -63,19 +61,18 @@ class GCodeHighlighter(QtGui.QSyntaxHighlighter):
self.highlightingRules = []
numberFormat = QtGui.QTextCharFormat()
numberFormat.setForeground(colors[0])
- self.highlightingRules.append(
- (QtCore.QRegExp("[\\-0-9\\.]"), numberFormat))
+ self.highlightingRules.append((QtCore.QRegExp("[\\-0-9\\.]"), numberFormat))
keywordFormat = QtGui.QTextCharFormat()
keywordFormat.setForeground(colors[1])
keywordFormat.setFontWeight(QtGui.QFont.Bold)
keywordPatterns = ["\\bG[0-9]+\\b", "\\bM[0-9]+\\b"]
self.highlightingRules.extend(
- [(QtCore.QRegExp(pattern), keywordFormat) for pattern in keywordPatterns])
+ [(QtCore.QRegExp(pattern), keywordFormat) for pattern in keywordPatterns]
+ )
speedFormat = QtGui.QTextCharFormat()
speedFormat.setFontWeight(QtGui.QFont.Bold)
speedFormat.setForeground(colors[2])
- self.highlightingRules.append(
- (QtCore.QRegExp("\\bF[0-9\\.]+\\b"), speedFormat))
+ self.highlightingRules.append((QtCore.QRegExp("\\bF[0-9\\.]+\\b"), speedFormat))
def highlightBlock(self, text):
@@ -93,7 +90,7 @@ class GCodeEditorDialog(QtGui.QDialog):
def __init__(self, PathObj, parent=FreeCADGui.getMainWindow()):
self.PathObj = PathObj.Path
- if hasattr(PathObj, 'ToolController'):
+ if hasattr(PathObj, "ToolController"):
self.tool = PathObj.ToolController.Tool
else:
self.tool = None
@@ -103,10 +100,19 @@ class GCodeEditorDialog(QtGui.QDialog):
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Path")
c = p.GetUnsigned("DefaultHighlightPathColor", 4286382335)
- Q = QtGui.QColor(int((c >> 24) & 0xFF), int((c >> 16) & 0xFF), int((c >> 8) & 0xFF))
- highlightcolor = (Q.red() / 255., Q.green() / 255., Q.blue() / 255., Q.alpha() / 255.)
+ Q = QtGui.QColor(
+ int((c >> 24) & 0xFF), int((c >> 16) & 0xFF), int((c >> 8) & 0xFF)
+ )
+ highlightcolor = (
+ Q.red() / 255.0,
+ Q.green() / 255.0,
+ Q.blue() / 255.0,
+ Q.alpha() / 255.0,
+ )
- self.selectionobj = FreeCAD.ActiveDocument.addObject("Path::Feature", "selection")
+ self.selectionobj = FreeCAD.ActiveDocument.addObject(
+ "Path::Feature", "selection"
+ )
self.selectionobj.ViewObject.LineWidth = 4
self.selectionobj.ViewObject.NormalColor = highlightcolor
@@ -123,14 +129,21 @@ class GCodeEditorDialog(QtGui.QDialog):
# Note
lab = QtGui.QLabel()
- lab.setText(translate("Path_Inspect", "Note: Pressing OK will commit any change you make above to the object, but if the object is parametric, these changes will be overridden on recompute."))
+ lab.setText(
+ translate(
+ "Path_Inspect",
+ "Note: Pressing OK will commit any change you make above to the object, but if the object is parametric, these changes will be overridden on recompute.",
+ )
+ )
lab.setWordWrap(True)
layout.addWidget(lab)
# OK and Cancel buttons
self.buttons = QtGui.QDialogButtonBox(
QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel,
- QtCore.Qt.Horizontal, self)
+ QtCore.Qt.Horizontal,
+ self,
+ )
layout.addWidget(self.buttons)
self.buttons.accepted.connect(self.accept)
self.buttons.rejected.connect(self.reject)
@@ -138,19 +151,19 @@ class GCodeEditorDialog(QtGui.QDialog):
self.finished.connect(self.cleanup)
prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Path")
- Xpos = int(prefs.GetString('inspecteditorX', "0"))
- Ypos = int(prefs.GetString('inspecteditorY', "0"))
- height = int(prefs.GetString('inspecteditorH', "500"))
- width = int(prefs.GetString('inspecteditorW', "600"))
+ Xpos = int(prefs.GetString("inspecteditorX", "0"))
+ Ypos = int(prefs.GetString("inspecteditorY", "0"))
+ height = int(prefs.GetString("inspecteditorH", "500"))
+ width = int(prefs.GetString("inspecteditorW", "600"))
self.move(Xpos, Ypos)
self.resize(width, height)
def cleanup(self):
prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Path")
- prefs.SetString('inspecteditorX', str(self.x()))
- prefs.SetString('inspecteditorY', str(self.y()))
- prefs.SetString('inspecteditorW', str(self.width()))
- prefs.SetString('inspecteditorH', str(self.height()))
+ prefs.SetString("inspecteditorX", str(self.x()))
+ prefs.SetString("inspecteditorY", str(self.y()))
+ prefs.SetString("inspecteditorW", str(self.width()))
+ prefs.SetString("inspecteditorH", str(self.height()))
FreeCAD.ActiveDocument.removeObject(self.selectionobj.Name)
def highlightpath(self):
@@ -191,7 +204,7 @@ class GCodeEditorDialog(QtGui.QDialog):
p = Path.Path()
firstrapid = Path.Command("G0", {"X": prevX, "Y": prevY, "Z": prevZ})
- selectionpath = [firstrapid] + commands[startrow:endrow + 1]
+ selectionpath = [firstrapid] + commands[startrow : endrow + 1]
p.Commands = selectionpath
self.selectionobj.Path = p
@@ -207,21 +220,28 @@ def show(obj):
prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Path")
# default Max Highlighter Size = 512 Ko
defaultMHS = 512 * 1024
- mhs = prefs.GetUnsigned('inspecteditorMaxHighlighterSize', defaultMHS)
+ mhs = prefs.GetUnsigned("inspecteditorMaxHighlighterSize", defaultMHS)
if hasattr(obj, "Path"):
if obj.Path:
dia = GCodeEditorDialog(obj)
dia.editor.setText(obj.Path.toGCode())
gcodeSize = len(dia.editor.toPlainText())
- if (gcodeSize <= mhs):
+ if gcodeSize <= mhs:
# because of poor performance, syntax highlighting is
# limited to mhs octets (default 512 KB).
# It seems than the response time curve has an inflexion near 500 KB
# beyond 500 KB, the response time increases exponentially.
dia.highlighter = GCodeHighlighter(dia.editor.document())
else:
- FreeCAD.Console.PrintMessage(translate("Path", "GCode size too big ({} o), disabling syntax highlighter.".format(gcodeSize)))
+ FreeCAD.Console.PrintMessage(
+ translate(
+ "Path",
+ "GCode size too big ({} o), disabling syntax highlighter.".format(
+ gcodeSize
+ ),
+ )
+ )
result = dia.exec_()
# exec_() returns 0 or 1 depending on the button pressed (Ok or
# Cancel)
@@ -234,12 +254,15 @@ def show(obj):
class CommandPathInspect:
-
def GetResources(self):
- return {'Pixmap': 'Path_Inspect',
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Inspect", "Inspect G-code"),
- 'Accel': "P, I",
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Inspect", "Inspects the G-code contents of a path")}
+ return {
+ "Pixmap": "Path_Inspect",
+ "MenuText": QT_TRANSLATE_NOOP("Path_Inspect", "Inspect G-code"),
+ "Accel": "P, I",
+ "ToolTip": QT_TRANSLATE_NOOP(
+ "Path_Inspect", "Inspects the G-code contents of a path"
+ ),
+ }
def IsActive(self):
if FreeCAD.ActiveDocument is not None:
@@ -253,19 +276,26 @@ class CommandPathInspect:
selection = FreeCADGui.Selection.getSelection()
if len(selection) != 1:
FreeCAD.Console.PrintError(
- translate("Path_Inspect", "Please select exactly one path object") + "\n")
+ translate("Path_Inspect", "Please select exactly one path object")
+ + "\n"
+ )
return
- if not(selection[0].isDerivedFrom("Path::Feature")):
+ if not (selection[0].isDerivedFrom("Path::Feature")):
FreeCAD.Console.PrintError(
- translate("Path_Inspect", "Please select exactly one path object") + "\n")
+ translate("Path_Inspect", "Please select exactly one path object")
+ + "\n"
+ )
return
# if everything is ok, execute
FreeCADGui.addModule("PathScripts.PathInspect")
FreeCADGui.doCommand(
- 'PathScripts.PathInspect.show(FreeCAD.ActiveDocument.' + selection[0].Name + ')')
+ "PathScripts.PathInspect.show(FreeCAD.ActiveDocument."
+ + selection[0].Name
+ + ")"
+ )
if FreeCAD.GuiUp:
# register the FreeCAD command
- FreeCADGui.addCommand('Path_Inspect', CommandPathInspect())
+ FreeCADGui.addCommand("Path_Inspect", CommandPathInspect())
diff --git a/src/Mod/Path/PathScripts/PathProbe.py b/src/Mod/Path/PathScripts/PathProbe.py
index e2fc33e8f0..dbb2b2c0e9 100644
--- a/src/Mod/Path/PathScripts/PathProbe.py
+++ b/src/Mod/Path/PathScripts/PathProbe.py
@@ -27,8 +27,8 @@ import Path
import PathScripts.PathLog as PathLog
import PathScripts.PathOp as PathOp
import PathScripts.PathUtils as PathUtils
+from PySide.QtCore import QT_TRANSLATE_NOOP
-from PySide import QtCore
__title__ = "Path Probing Operation"
__author__ = "sliptonic (Brad Collette)"
@@ -42,63 +42,106 @@ else:
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
-# Qt translation handling
-def translate(context, text, disambig=None):
- return QtCore.QCoreApplication.translate(context, text, disambig)
-
-
class ObjectProbing(PathOp.ObjectOp):
- '''Proxy object for Probing operation.'''
+ """Proxy object for Probing operation."""
def opFeatures(self, obj):
- '''opFeatures(obj) ... Probing works on the stock object.'''
+ """opFeatures(obj) ... Probing works on the stock object."""
return PathOp.FeatureDepths | PathOp.FeatureHeights | PathOp.FeatureTool
def initOperation(self, obj):
- obj.addProperty("App::PropertyLength", "Xoffset", "Probe", QtCore.QT_TRANSLATE_NOOP("App::Property", "X offset between tool and probe"))
- obj.addProperty("App::PropertyLength", "Yoffset", "Probe", QtCore.QT_TRANSLATE_NOOP("App::Property", "Y offset between tool and probe"))
- obj.addProperty("App::PropertyInteger", "PointCountX", "Probe", QtCore.QT_TRANSLATE_NOOP("App::Property", "Number of points to probe in X direction"))
- obj.addProperty("App::PropertyInteger", "PointCountY", "Probe", QtCore.QT_TRANSLATE_NOOP("App::Property", "Number of points to probe in Y direction"))
- obj.addProperty("App::PropertyFile", "OutputFileName", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "The output location for the probe data to be written"))
+ obj.addProperty(
+ "App::PropertyLength",
+ "Xoffset",
+ "Probe",
+ QT_TRANSLATE_NOOP("App::Property", "X offset between tool and probe"),
+ )
+ obj.addProperty(
+ "App::PropertyLength",
+ "Yoffset",
+ "Probe",
+ QT_TRANSLATE_NOOP("App::Property", "Y offset between tool and probe"),
+ )
+ obj.addProperty(
+ "App::PropertyInteger",
+ "PointCountX",
+ "Probe",
+ QT_TRANSLATE_NOOP(
+ "App::Property", "Number of points to probe in X direction"
+ ),
+ )
+ obj.addProperty(
+ "App::PropertyInteger",
+ "PointCountY",
+ "Probe",
+ QT_TRANSLATE_NOOP(
+ "App::Property", "Number of points to probe in Y direction"
+ ),
+ )
+ obj.addProperty(
+ "App::PropertyFile",
+ "OutputFileName",
+ "Path",
+ QT_TRANSLATE_NOOP(
+ "App::Property", "The output location for the probe data to be written"
+ ),
+ )
def nextpoint(self, startpoint=0.0, endpoint=0.0, count=3):
curstep = 0
dist = (endpoint - startpoint) / (count - 1)
- while curstep <= count-1:
+ while curstep <= count - 1:
yield startpoint + (curstep * dist)
curstep += 1
def opExecute(self, obj):
- '''opExecute(obj) ... generate probe locations.'''
+ """opExecute(obj) ... generate probe locations."""
PathLog.track()
self.commandlist.append(Path.Command("(Begin Probing)"))
stock = PathUtils.findParentJob(obj).Stock
bb = stock.Shape.BoundBox
- openstring = '(PROBEOPEN {})'.format(obj.OutputFileName)
+ openstring = "(PROBEOPEN {})".format(obj.OutputFileName)
self.commandlist.append(Path.Command(openstring))
self.commandlist.append(Path.Command("G0", {"Z": obj.ClearanceHeight.Value}))
for y in self.nextpoint(bb.YMin, bb.YMax, obj.PointCountY):
for x in self.nextpoint(bb.XMin, bb.XMax, obj.PointCountX):
- self.commandlist.append(Path.Command("G0", {"X": x + obj.Xoffset.Value, "Y": y + obj.Yoffset.Value, "Z": obj.SafeHeight.Value}))
- self.commandlist.append(Path.Command("G38.2", {"Z": obj.FinalDepth.Value, "F": obj.ToolController.VertFeed.Value}))
+ self.commandlist.append(
+ Path.Command(
+ "G0",
+ {
+ "X": x + obj.Xoffset.Value,
+ "Y": y + obj.Yoffset.Value,
+ "Z": obj.SafeHeight.Value,
+ },
+ )
+ )
+ self.commandlist.append(
+ Path.Command(
+ "G38.2",
+ {
+ "Z": obj.FinalDepth.Value,
+ "F": obj.ToolController.VertFeed.Value,
+ },
+ )
+ )
self.commandlist.append(Path.Command("G0", {"Z": obj.SafeHeight.Value}))
self.commandlist.append(Path.Command("(PROBECLOSE)"))
def opSetDefaultValues(self, obj, job):
- '''opSetDefaultValues(obj, job) ... set default value for RetractHeight'''
+ """opSetDefaultValues(obj, job) ... set default value for RetractHeight"""
def SetupProperties():
- setup = ['Xoffset', 'Yoffset', 'PointCountX', 'PointCountY', 'OutputFileName']
+ setup = ["Xoffset", "Yoffset", "PointCountX", "PointCountY", "OutputFileName"]
return setup
def Create(name, obj=None, parentJob=None):
- '''Create(name) ... Creates and returns a Probing operation.'''
+ """Create(name) ... Creates and returns a Probing operation."""
if obj is None:
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name)
proxy = ObjectProbing(obj, name, parentJob)
diff --git a/src/Mod/Path/PathScripts/PathProbeGui.py b/src/Mod/Path/PathScripts/PathProbeGui.py
index 29c97d7adc..96c80b50ae 100644
--- a/src/Mod/Path/PathScripts/PathProbeGui.py
+++ b/src/Mod/Path/PathScripts/PathProbeGui.py
@@ -22,11 +22,13 @@
import FreeCAD
import FreeCADGui
-import PathGui as PGui # ensure Path/Gui/Resources are loaded
+import PathGui as PGui # ensure Path/Gui/Resources are loaded
import PathScripts.PathProbe as PathProbe
import PathScripts.PathOpGui as PathOpGui
import PathScripts.PathGui as PathGui
+import PathScripts.PathLog as PathLog
+from PySide.QtCore import QT_TRANSLATE_NOOP
from PySide import QtCore, QtGui
__title__ = "Path Probing Operation UI"
@@ -35,38 +37,46 @@ __url__ = "http://www.freecadweb.org"
__doc__ = "Probing operation page controller and command implementation."
-# Qt translation handling
-def translate(context, text, disambig=None):
- return QtCore.QCoreApplication.translate(context, text, disambig)
+if False:
+ PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
+ PathLog.trackModule(PathLog.thisModule())
+else:
+ PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
+
+translate = FreeCAD.Qt.translate
class TaskPanelOpPage(PathOpGui.TaskPanelPage):
- '''Page controller class for the Probing operation.'''
+ """Page controller class for the Probing operation."""
def getForm(self):
- '''getForm() ... returns UI'''
+ """getForm() ... returns UI"""
return FreeCADGui.PySideUic.loadUi(":/panels/PageOpProbeEdit.ui")
def getFields(self, obj):
- '''getFields(obj) ... transfers values from UI to obj's proprties'''
+ """getFields(obj) ... transfers values from UI to obj's proprties"""
self.updateToolController(obj, self.form.toolController)
- PathGui.updateInputField(obj, 'Xoffset', self.form.Xoffset)
- PathGui.updateInputField(obj, 'Yoffset', self.form.Yoffset)
+ PathGui.updateInputField(obj, "Xoffset", self.form.Xoffset)
+ PathGui.updateInputField(obj, "Yoffset", self.form.Yoffset)
obj.PointCountX = self.form.PointCountX.value()
obj.PointCountY = self.form.PointCountY.value()
obj.OutputFileName = str(self.form.OutputFileName.text())
def setFields(self, obj):
- '''setFields(obj) ... transfers obj's property values to UI'''
+ """setFields(obj) ... transfers obj's property values to UI"""
self.setupToolController(obj, self.form.toolController)
- self.form.Xoffset.setText(FreeCAD.Units.Quantity(obj.Xoffset.Value, FreeCAD.Units.Length).UserString)
- self.form.Yoffset.setText(FreeCAD.Units.Quantity(obj.Yoffset.Value, FreeCAD.Units.Length).UserString)
+ self.form.Xoffset.setText(
+ FreeCAD.Units.Quantity(obj.Xoffset.Value, FreeCAD.Units.Length).UserString
+ )
+ self.form.Yoffset.setText(
+ FreeCAD.Units.Quantity(obj.Yoffset.Value, FreeCAD.Units.Length).UserString
+ )
self.form.OutputFileName.setText(obj.OutputFileName)
self.form.PointCountX.setValue(obj.PointCountX)
self.form.PointCountY.setValue(obj.PointCountY)
def getSignalsForUpdate(self, obj):
- '''getSignalsForUpdate(obj) ... return list of signals for updating obj'''
+ """getSignalsForUpdate(obj) ... return list of signals for updating obj"""
signals = []
signals.append(self.form.toolController.currentIndexChanged)
signals.append(self.form.PointCountX.valueChanged)
@@ -78,16 +88,25 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage):
return signals
def SetOutputFileName(self):
- filename = QtGui.QFileDialog.getSaveFileName(self.form, translate("Path_Probe", "Select Output File"), None, translate("Path_Probe", "All Files (*.*)"))
+ filename = QtGui.QFileDialog.getSaveFileName(
+ self.form,
+ translate("Path_Probe", "Select Output File"),
+ None,
+ translate("Path_Probe", "All Files (*.*)"),
+ )
if filename and filename[0]:
self.obj.OutputFileName = str(filename[0])
self.setFields(self.obj)
-Command = PathOpGui.SetupOperation('Probe', PathProbe.Create, TaskPanelOpPage,
- 'Path_Probe',
- QtCore.QT_TRANSLATE_NOOP("Probe", "Probe"),
- QtCore.QT_TRANSLATE_NOOP("Probe", "Create a Probing Grid from a job stock"),
- PathProbe.SetupProperties)
+Command = PathOpGui.SetupOperation(
+ "Probe",
+ PathProbe.Create,
+ TaskPanelOpPage,
+ "Path_Probe",
+ QtCore.QT_TRANSLATE_NOOP("Path_Probe", "Probe"),
+ QtCore.QT_TRANSLATE_NOOP("Path_Probe", "Create a Probing Grid from a job stock"),
+ PathProbe.SetupProperties,
+)
FreeCAD.Console.PrintLog("Loading PathProbeGui... done\n")