From 69e7a2e9fde7ee4b035f6f20f8eb9636bc5e8fa6 Mon Sep 17 00:00:00 2001 From: sliptonic Date: Tue, 25 Jan 2022 15:24:49 -0600 Subject: [PATCH] surface and waterline translation --- .../Resources/panels/PageOpWaterlineEdit.ui | 140 ++++++------ src/Mod/Path/PathScripts/PathGui.py | 19 ++ src/Mod/Path/PathScripts/PathLog.py | 2 + src/Mod/Path/PathScripts/PathSurface.py | 183 +++++++-------- src/Mod/Path/PathScripts/PathSurfaceGui.py | 51 ++--- .../Path/PathScripts/PathSurfaceSupport.py | 4 +- src/Mod/Path/PathScripts/PathWaterline.py | 210 +++++++++++------- src/Mod/Path/PathScripts/PathWaterlineGui.py | 53 +++-- 8 files changed, 346 insertions(+), 316 deletions(-) diff --git a/src/Mod/Path/Gui/Resources/panels/PageOpWaterlineEdit.ui b/src/Mod/Path/Gui/Resources/panels/PageOpWaterlineEdit.ui index 1193b14478..72de5243b4 100644 --- a/src/Mod/Path/Gui/Resources/panels/PageOpWaterlineEdit.ui +++ b/src/Mod/Path/Gui/Resources/panels/PageOpWaterlineEdit.ui @@ -53,7 +53,34 @@ - + + + + Algorithm + + + + + + + <html><head/><body><p>Select the algorithm to use: OCL Dropcutter*, or Experimental (Not OCL based).</p></body></html> + + + + + + + + 0 + 0 + + + + BoundBox + + + + @@ -65,20 +92,14 @@ - - - - - 0 - 0 - - - - <html><head/><body><p>Positive values push the cutter toward, or beyond, the boundary. Negative values retract the cutter away from the boundary.</p></body></html> + + + + Layer Mode - + @@ -90,20 +111,22 @@ - - - - <html><head/><body><p>Select the algorithm to use: OCL Dropcutter*, or Experimental (Not OCL based).</p></body></html> + + + + Cut Pattern - - - - <html><head/><body><p>Enable optimization of linear paths (co-linear points). Removes unnecessary co-linear points from G-Code output.</p></body></html> + + + + + 12 + - - Optimize Linear Paths + + <html><head/><body><p>Set the geometric clearing pattern to use for the operation.</p></body></html> @@ -120,19 +143,24 @@ - - - - - 12 - - + + - <html><head/><body><p>Set the geometric clearing pattern to use for the operation.</p></body></html> + <html><head/><body><p>Set the Z-axis depth offset from the target surface.</p></body></html> + + + mm - + + + + Step over + + + + @@ -151,34 +179,14 @@ - - + + - Layer Mode + Sample interval - - - - - 0 - 0 - - - - BoundBox - - - - - - - Step over - - - - + <html><head/><body><p>Set the sampling resolution. Smaller values quickly increase processing time.</p></body></html> @@ -188,24 +196,13 @@ - - - - Cut Pattern + + + + <html><head/><body><p>Enable optimization of linear paths (co-linear points). Removes unnecessary co-linear points from G-Code output.</p></body></html> - - - - - Sample interval - - - - - - - Algorithm + Optimize Linear Paths @@ -241,7 +238,6 @@ boundBoxSelect layerMode cutPattern - boundaryAdjustment stepOver sampleInterval optimizeEnabled diff --git a/src/Mod/Path/PathScripts/PathGui.py b/src/Mod/Path/PathScripts/PathGui.py index 3cdb2fbf64..8f4d5a7c2b 100644 --- a/src/Mod/Path/PathScripts/PathGui.py +++ b/src/Mod/Path/PathScripts/PathGui.py @@ -39,6 +39,24 @@ else: PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) +def populateCombobox(form, enumTups, comboBoxesPropertyMap): + """fillComboboxes(form, comboBoxesPropertyMap) ... populate comboboxes with translated enumerations + ** comboBoxesPropertyMap will be unnecessary if UI files use strict combobox naming protocol. + Args: + form = UI form + enumTups = list of (translated_text, data_string) tuples + comboBoxesPropertyMap = list of (translated_text, data_string) tuples + """ + PathLog.track(enumTups) + + # Load appropriate enumerations in each combobox + for cb, prop in comboBoxesPropertyMap: + box = getattr(form, cb) # Get the combobox + box.clear() # clear the combobox + for text, data in enumTups[prop]: # load enumerations + box.addItem(text, data) + + def updateInputField(obj, prop, widget, onBeforeChange=None): """updateInputField(obj, prop, widget) ... update obj's property prop with the value of widget. The property's value is only assigned if the new value differs from the current value. @@ -50,6 +68,7 @@ def updateInputField(obj, prop, widget, onBeforeChange=None): """ PathLog.track() value = widget.property("rawValue") + PathLog.track("value: {}".format(value)) attr = PathUtil.getProperty(obj, prop) attrValue = attr.Value if hasattr(attr, "Value") else attr diff --git a/src/Mod/Path/PathScripts/PathLog.py b/src/Mod/Path/PathScripts/PathLog.py index 80128d3c51..43509bad90 100644 --- a/src/Mod/Path/PathScripts/PathLog.py +++ b/src/Mod/Path/PathScripts/PathLog.py @@ -107,6 +107,8 @@ def _log(level, module_line_func, msg): def debug(msg): """(message)""" + module, line, func = _caller() + msg = "({}) - {}".format(line, msg) return _log(Level.DEBUG, _caller(), msg) def info(msg): """(message)""" diff --git a/src/Mod/Path/PathScripts/PathSurface.py b/src/Mod/Path/PathScripts/PathSurface.py index 73040076d0..6a16a8c0fa 100644 --- a/src/Mod/Path/PathScripts/PathSurface.py +++ b/src/Mod/Path/PathScripts/PathSurface.py @@ -101,7 +101,7 @@ class ObjectSurface(PathOp.ObjectOp): def initOpProperties(self, obj, warn=False): """initOpProperties(obj) ... create operation specific properties""" - self.addNewProps = list() + self.addNewProps = [] for (prtyp, nm, grp, tt) in self.opPropertyDefinitions(): if not hasattr(obj, nm): @@ -453,19 +453,19 @@ class ObjectSurface(PathOp.ObjectOp): # Enumeration lists for App::PropertyEnumeration properties enums = { "BoundBox": [ - (translate("Path_Surface", "Outside"), "Outside"), - (translate("Path_Surface", "Inside"), "Inside"), - ], # this is the direction that the profile runs + (translate("Path_Surface", "BaseBoundBox"), "BaseBoundBox"), + (translate("Path_Surface", "Stock"), "Stock"), + ], "PatternCenterAt": [ (translate("Path_Surface", "CenterOfMass"), "CenterOfMass"), (translate("Path_Surface", "CenterOfBoundBox"), "CenterOfBoundBox"), (translate("Path_Surface", "XminYmin"), "XminYmin"), (translate("Path_Surface", "Custom"), "Custom"), - ], # side of profile that cutter is on in relation to direction of profile + ], "CutMode": [ (translate("Path_Surface", "Conventional"), "Conventional"), (translate("Path_Surface", "Climb"), "Climb"), - ], # side of profile that cutter is on in relation to direction of profile + ], "CutPattern": [ (translate("Path_Surface", "Circular"), "Circular"), (translate("Path_Surface", "CircularZigZag"), "CircularZigZag"), @@ -473,76 +473,46 @@ class ObjectSurface(PathOp.ObjectOp): (translate("Path_Surface", "Offset"), "Offset"), (translate("Path_Surface", "Spiral"), "Spiral"), (translate("Path_Surface", "ZigZag"), "ZigZag"), - ], # side of profile that cutter is on in relation to direction of profile + ], "DropCutterDir": [ (translate("Path_Surface", "X"), "X"), (translate("Path_Surface", "Y"), "Y"), - ], # side of profile that cutter is on in relation to direction of profile + ], "HandleMultipleFeatures": [ (translate("Path_Surface", "Collectively"), "Collectively"), (translate("Path_Surface", "Individually"), "Individually"), - ], # side of profile that cutter is on in relation to direction of profile + ], "LayerMode": [ (translate("Path_Surface", "Single-pass"), "Single-pass"), (translate("Path_Surface", "Multi-pass"), "Multi-pass"), - ], # side of profile that cutter is on in relation to direction of profile + ], "ProfileEdges": [ (translate("Path_Surface", "None"), "None"), (translate("Path_Surface", "Only"), "Only"), (translate("Path_Surface", "First"), "First"), (translate("Path_Surface", "Last"), "Last"), - ], # side of profile that cutter is on in relation to direction of profile + ], "RotationAxis": [ (translate("Path_Surface", "X"), "X"), (translate("Path_Surface", "Y"), "Y"), - ], # side of profile that cutter is on in relation to direction of profile + ], "ScanType": [ (translate("Path_Surface", "Planar"), "Planar"), (translate("Path_Surface", "Rotational"), "Rotational"), - ], # side of profile that cutter is on in relation to direction of profile + ], } if dataType == "raw": return enums - data = list() + data = [] idx = 0 if dataType == "translated" else 1 - PathLog.debug(enums) - for k, v in enumerate(enums): data.append((v, [tup[idx] for tup in enums[v]])) - PathLog.debug(data) return data - # def opPropertyEnumerations(self): - # # Enumeration lists for App::PropertyEnumeration properties - # return { - # "BoundBox": ["BaseBoundBox", "Stock"], - # "PatternCenterAt": [ - # "CenterOfMass", - # "CenterOfBoundBox", - # "XminYmin", - # "Custom", - # ], - # "CutMode": ["Conventional", "Climb"], - # "CutPattern": [ - # "Circular", - # "CircularZigZag", - # "Line", - # "Offset", - # "Spiral", - # "ZigZag", - # ], # Additional goals ['Offset', 'ZigZagOffset', 'Grid', 'Triangle'] - # "DropCutterDir": ["X", "Y"], - # "HandleMultipleFeatures": ["Collectively", "Individually"], - # "LayerMode": ["Single-pass", "Multi-pass"], - # "ProfileEdges": ["None", "Only", "First", "Last"], - # "RotationAxis": ["X", "Y"], - # "ScanType": ["Planar", "Rotational"], - # } - def opPropertyDefaults(self, obj, job): """opPropertyDefaults(obj, job) ... returns a dictionary of default values for the operation's properties.""" @@ -781,22 +751,22 @@ class ObjectSurface(PathOp.ObjectOp): """opExecute(obj) ... process surface operation""" PathLog.track() - self.modelSTLs = list() - self.safeSTLs = list() - self.modelTypes = list() - self.boundBoxes = list() - self.profileShapes = list() - self.collectiveShapes = list() - self.individualShapes = list() - self.avoidShapes = list() + self.modelSTLs = [] + self.safeSTLs = [] + self.modelTypes = [] + self.boundBoxes = [] + self.profileShapes = [] + self.collectiveShapes = [] + self.individualShapes = [] + self.avoidShapes = [] self.tempGroup = None self.CutClimb = False self.closedGap = False self.tmpCOM = None self.gaps = [0.1, 0.2, 0.3] self.cancelOperation = False - CMDS = list() - modelVisibility = list() + CMDS = [] + modelVisibility = [] FCAD = FreeCAD.ActiveDocument try: @@ -931,26 +901,25 @@ class ObjectSurface(PathOp.ObjectOp): # Save model visibilities for restoration if FreeCAD.GuiUp: - for m in range(0, len(JOB.Model.Group)): - mNm = JOB.Model.Group[m].Name + for model in JOB.Model.Group: + mNm = model.Name modelVisibility.append( FreeCADGui.ActiveDocument.getObject(mNm).Visibility ) # Setup STL, model type, and bound box containers for each model in Job - for m in range(0, len(JOB.Model.Group)): - M = JOB.Model.Group[m] + for model in JOB.Model.Group: self.modelSTLs.append(False) self.safeSTLs.append(False) self.profileShapes.append(False) # Set bound box if obj.BoundBox == "BaseBoundBox": - if M.TypeId.startswith("Mesh"): + if model.TypeId.startswith("Mesh"): self.modelTypes.append("M") # Mesh - self.boundBoxes.append(M.Mesh.BoundBox) + self.boundBoxes.append(model.Mesh.BoundBox) else: self.modelTypes.append("S") # Solid - self.boundBoxes.append(M.Shape.BoundBox) + self.boundBoxes.append(model.Shape.BoundBox) elif obj.BoundBox == "Stock": self.modelTypes.append("S") # Solid self.boundBoxes.append(JOB.Stock.Shape.BoundBox) @@ -971,18 +940,20 @@ class ObjectSurface(PathOp.ObjectOp): self.modelSTLs = PSF.modelSTLs self.profileShapes = PSF.profileShapes - for m in range(0, len(JOB.Model.Group)): + for idx, model in enumerate(JOB.Model.Group): + PathLog.debug(idx) # Create OCL.stl model objects - PathSurfaceSupport._prepareModelSTLs(self, JOB, obj, m, ocl) + PathSurfaceSupport._prepareModelSTLs(self, JOB, obj, idx, ocl) - Mdl = JOB.Model.Group[m] - if FACES[m]: - PathLog.debug("Working on Model.Group[{}]: {}".format(m, Mdl.Label)) - if m > 0: + if FACES[idx]: + PathLog.debug( + "Working on Model.Group[{}]: {}".format(idx, model.Label) + ) + if idx > 0: # Raise to clearance between models CMDS.append( Path.Command( - "N (Transition to base: {}.)".format(Mdl.Label) + "N (Transition to base: {}.)".format(model.Label) ) ) CMDS.append( @@ -993,14 +964,14 @@ class ObjectSurface(PathOp.ObjectOp): ) # make stock-model-voidShapes STL model for avoidance detection on transitions PathSurfaceSupport._makeSafeSTL( - self, JOB, obj, m, FACES[m], VOIDS[m], ocl + self, JOB, obj, idx, FACES[idx], VOIDS[idx], ocl ) # Process model/faces - OCL objects must be ready - CMDS.extend(self._processCutAreas(JOB, obj, m, FACES[m], VOIDS[m])) - else: - PathLog.debug( - "No data for model base: {}".format(JOB.Model.Group[m].Label) + CMDS.extend( + self._processCutAreas(JOB, obj, idx, FACES[idx], VOIDS[idx]) ) + else: + PathLog.debug("No data for model base: {}".format(model.Label)) # Save gcode produced self.commandlist.extend(CMDS) @@ -1031,7 +1002,7 @@ class ObjectSurface(PathOp.ObjectOp): tempGroup.purgeTouched() # Provide user feedback for gap sizes - gaps = list() + gaps = [] for g in self.gaps: if g != self.toolDiam: gaps.append(g) @@ -1094,7 +1065,7 @@ class ObjectSurface(PathOp.ObjectOp): It then calls the correct scan method depending on the ScanType property.""" PathLog.debug("_processCutAreas()") - final = list() + final = [] # Process faces Collectively or Individually if obj.HandleMultipleFeatures == "Collectively": @@ -1146,8 +1117,8 @@ class ObjectSurface(PathOp.ObjectOp): It calls the correct Single or Multi-pass method as needed. It returns the gcode for the operation.""" PathLog.debug("_processPlanarOp()") - final = list() - SCANDATA = list() + final = [] + SCANDATA = [] def getTransition(two): first = two[0][0][0] # [step][item][point] @@ -1176,23 +1147,23 @@ class ObjectSurface(PathOp.ObjectOp): self.cutter, ) - profScan = list() + profScan = [] if obj.ProfileEdges != "None": prflShp = self.profileShapes[mdlIdx][fsi] if prflShp is False: msg = translate("PathSurface", "No profile geometry shape returned.") PathLog.error(msg) - return list() + return [] self.showDebugObject(prflShp, "NewProfileShape") # get offset path geometry and perform OCL scan with that geometry pathOffsetGeom = self._offsetFacesToPointData(obj, prflShp) if pathOffsetGeom is False: msg = translate("PathSurface", "No profile path geometry returned.") PathLog.error(msg) - return list() + return [] profScan = [self._planarPerformOclScan(obj, pdc, pathOffsetGeom, True)] - geoScan = list() + geoScan = [] if obj.ProfileEdges != "Only": self.showDebugObject(cmpdShp, "CutArea") # get internal path geometry and perform OCL scan with that geometry @@ -1204,7 +1175,7 @@ class ObjectSurface(PathOp.ObjectOp): if pathGeom is False: msg = translate("PathSurface", "No clearing shape returned.") PathLog.error(msg) - return list() + return [] if obj.CutPattern == "Offset": useGeom = self._offsetFacesToPointData(obj, pathGeom, profile=False) if useGeom is False: @@ -1212,7 +1183,7 @@ class ObjectSurface(PathOp.ObjectOp): "PathSurface", "No clearing path geometry returned." ) PathLog.error(msg) - return list() + return [] geoScan = [self._planarPerformOclScan(obj, pdc, useGeom, True)] else: geoScan = self._planarPerformOclScan(obj, pdc, pathGeom, False) @@ -1232,7 +1203,7 @@ class ObjectSurface(PathOp.ObjectOp): if len(SCANDATA) == 0: msg = translate("PathSurface", "No scan data to convert to Gcode.") PathLog.error(msg) - return list() + return [] # Apply depth offset if obj.DepthOffset.Value != 0.0: @@ -1269,7 +1240,7 @@ class ObjectSurface(PathOp.ObjectOp): def _offsetFacesToPointData(self, obj, subShp, profile=True): PathLog.debug("_offsetFacesToPointData()") - offsetLists = list() + offsetLists = [] dist = obj.SampleInterval.Value / 5.0 # defl = obj.SampleInterval.Value / 5.0 @@ -1301,18 +1272,18 @@ class ObjectSurface(PathOp.ObjectOp): Switching function for calling the appropriate path-geometry to OCL points conversion function for the various cut patterns.""" PathLog.debug("_planarPerformOclScan()") - SCANS = list() + SCANS = [] if offsetPoints or obj.CutPattern == "Offset": PNTSET = PathSurfaceSupport.pathGeomToOffsetPointSet(obj, pathGeom) for D in PNTSET: - stpOvr = list() - ofst = list() + stpOvr = [] + ofst = [] for I in D: if I == "BRK": stpOvr.append(ofst) stpOvr.append(I) - ofst = list() + ofst = [] else: # D format is ((p1, p2), (p3, p4)) (A, B) = I @@ -1321,7 +1292,7 @@ class ObjectSurface(PathOp.ObjectOp): stpOvr.append(ofst) SCANS.extend(stpOvr) elif obj.CutPattern in ["Line", "Spiral", "ZigZag"]: - stpOvr = list() + stpOvr = [] if obj.CutPattern == "Line": # PNTSET = PathSurfaceSupport.pathGeomToLinesPointSet(obj, pathGeom, self.CutClimb, self.toolDiam, self.closedGap, self.gaps) PNTSET = PathSurfaceSupport.pathGeomToLinesPointSet(self, obj, pathGeom) @@ -1342,7 +1313,7 @@ class ObjectSurface(PathOp.ObjectOp): (A, B) = LN stpOvr.append(self._planarDropCutScan(pdc, A, B)) SCANS.append(stpOvr) - stpOvr = list() + stpOvr = [] elif obj.CutPattern in ["Circular", "CircularZigZag"]: # PNTSET is list, by stepover. # Each stepover is a list containing arc/loop descriptions, (sp, ep, cp) @@ -1350,7 +1321,7 @@ class ObjectSurface(PathOp.ObjectOp): PNTSET = PathSurfaceSupport.pathGeomToCircularPointSet(self, obj, pathGeom) for so in range(0, len(PNTSET)): - stpOvr = list() + stpOvr = [] erFlg = False (aTyp, dirFlg, ARCS) = PNTSET[so] @@ -1441,7 +1412,7 @@ class ObjectSurface(PathOp.ObjectOp): odd = True lstStpEnd = None for so in range(0, lenSCANDATA): - cmds = list() + cmds = [] PRTS = SCANDATA[so] lenPRTS = len(PRTS) first = PRTS[0][0] # first point of arc/line stepover group @@ -1544,7 +1515,7 @@ class ObjectSurface(PathOp.ObjectOp): odd = True # ZigZag directional switch lyrHasCmds = False actvSteps = 0 - LYR = list() + LYR = [] # if lyr > 0: # if prvStpLast is not None: # lastPrvStpLast = prvStpLast @@ -1558,8 +1529,8 @@ class ObjectSurface(PathOp.ObjectOp): lenSO = len(SO) # Pre-process step-over parts for layer depth and holds - ADJPRTS = list() - LMAX = list() + ADJPRTS = [] + LMAX = [] soHasPnts = False brkFlg = False for i in range(0, lenSO): @@ -1585,9 +1556,9 @@ class ObjectSurface(PathOp.ObjectOp): # Process existing parts within current step over prtsHasCmds = False stepHasCmds = False - prtsCmds = list() - stpOvrCmds = list() - transCmds = list() + prtsCmds = [] + stpOvrCmds = [] + transCmds = [] if soHasPnts is True: first = ADJPRTS[0][0] # first point of arc/line stepover group last = None @@ -1712,8 +1683,8 @@ class ObjectSurface(PathOp.ObjectOp): return GCODE def _planarMultipassPreProcess(self, obj, LN, prvDep, layDep): - ALL = list() - PTS = list() + ALL = [] + PTS = [] optLinTrans = obj.OptimizeStepOverTransitions safe = math.ceil(obj.SafeHeight.Value) @@ -1740,7 +1711,7 @@ class ObjectSurface(PathOp.ObjectOp): if optLinTrans is True: # Remove leading and trailing Hold Points - popList = list() + popList = [] for i in range(0, len(PTS)): # identify leading string if PTS[i].z == safe: popList.append(i) @@ -1750,7 +1721,7 @@ class ObjectSurface(PathOp.ObjectOp): for p in popList: # Remove hold points PTS.pop(p) ALL.pop(p) - popList = list() + popList = [] for i in range(len(PTS) - 1, -1, -1): # identify trailing string if PTS[i].z == safe: popList.append(i) @@ -1772,7 +1743,7 @@ class ObjectSurface(PathOp.ObjectOp): return (PTS, lMax) def _planarMultipassProcess(self, obj, PNTS, lMax): - output = list() + output = [] optimize = obj.OptimizeLinearPaths safe = math.ceil(obj.SafeHeight.Value) lenPNTS = len(PNTS) @@ -1855,7 +1826,7 @@ class ObjectSurface(PathOp.ObjectOp): passes, as well as other kinds of breaks. When OptimizeStepOverTransitions is enabled, uses safePDC to safely optimize short (~order of cutter diameter) transitions.""" - cmds = list() + cmds = [] rtpd = False height = obj.SafeHeight.Value # Allow cutter-down transitions with a distance up to 2x cutter @@ -1924,7 +1895,7 @@ class ObjectSurface(PathOp.ObjectOp): return cmds def _arcsToG2G3(self, LN, numPts, odd, gDIR, tolrnc): - cmds = list() + cmds = [] strtPnt = LN[0] endPnt = LN[numPts - 1] strtHght = strtPnt.z diff --git a/src/Mod/Path/PathScripts/PathSurfaceGui.py b/src/Mod/Path/PathScripts/PathSurfaceGui.py index 81747fb26a..83e98323cd 100644 --- a/src/Mod/Path/PathScripts/PathSurfaceGui.py +++ b/src/Mod/Path/PathScripts/PathSurfaceGui.py @@ -51,7 +51,8 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage): self.setTitle("3D Surface - " + obj.Label) # self.updateVisibility() # retrieve property enumerations - self.propEnums = PathSurface.ObjectSurface.opPropertyEnumerations(False) + # self.propEnums = PathSurface.ObjectSurface.opPropertyEnumerations(False) + self.propEnums = PathSurface.ObjectSurface.propertyEnumerations(False) def getForm(self): """getForm() ... returns UI""" @@ -59,29 +60,16 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage): comboToPropertyMap = [ ("boundBoxSelect", "BoundBox"), ("scanType", "ScanType"), + ("cutPattern", "CutPattern"), + ("profileEdges", "ProfileEdges"), ("layerMode", "LayerMode"), ("dropCutterDirSelect", "DropCutterDir"), ] enumTups = PathSurface.ObjectSurface.propertyEnumerations(dataType="raw") - self.populateCombobox(form, enumTups, comboToPropertyMap) + PathGui.populateCombobox(form, enumTups, comboToPropertyMap) return form - def populateCombobox(self, form, enumTups, comboBoxesPropertyMap): - """fillComboboxes(form, comboBoxesPropertyMap) ... populate comboboxes with translated enumerations - ** comboBoxesPropertyMap will be unnecessary if UI files use strict combobox naming protocol. - Args: - form = UI form - enumTups = list of (translated_text, data_string) tuples - comboBoxesPropertyMap = list of (translated_text, data_string) tuples - """ - # Load appropriate enumerations in each combobox - for cb, prop in comboBoxesPropertyMap: - box = getattr(form, cb) # Get the combobox - box.clear() # clear the combobox - for text, data in enumTups[prop]: # load enumerations - box.addItem(text, data) - def getFields(self, obj): """getFields(obj) ... transfers values from UI to obj's proprties""" self.updateToolController(obj, self.form.toolController) @@ -108,13 +96,16 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage): This type of dynamic combobox population is done for the Tool Controller selection. """ - val = self.propEnums["CutPattern"][self.form.cutPattern.currentIndex()] - if obj.CutPattern != val: - obj.CutPattern = val + # val = self.propEnums["CutPattern"][self.form.cutPattern.currentIndex()] + # if obj.CutPattern != val: + # obj.CutPattern = val - val = self.propEnums["ProfileEdges"][self.form.profileEdges.currentIndex()] - if obj.ProfileEdges != val: - obj.ProfileEdges = val + # val = self.propEnums["ProfileEdges"][self.form.profileEdges.currentIndex()] + # if obj.ProfileEdges != val: + # obj.ProfileEdges = val + + obj.CutPattern = self.form.cutPattern.currentData() + obj.ProfileEdges = self.form.profileEdges.currentData() if obj.AvoidLastX_Faces != self.form.avoidLastX_Faces.value(): obj.AvoidLastX_Faces = self.form.avoidLastX_Faces.value() @@ -169,12 +160,12 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage): and the UI panel QComboBox list. The original method is commented out below. """ - idx = self.propEnums["CutPattern"].index(obj.CutPattern) - self.form.cutPattern.setCurrentIndex(idx) - idx = self.propEnums["ProfileEdges"].index(obj.ProfileEdges) - self.form.profileEdges.setCurrentIndex(idx) - # self.selectInComboBox(obj.CutPattern, self.form.cutPattern) - # self.selectInComboBox(obj.ProfileEdges, self.form.profileEdges) + # idx = self.propEnums["CutPattern"].index(obj.CutPattern) + # self.form.cutPattern.setCurrentIndex(idx) + # idx = self.propEnums["ProfileEdges"].index(obj.ProfileEdges) + # self.form.profileEdges.setCurrentIndex(idx) + self.selectInComboBox(obj.CutPattern, self.form.cutPattern) + self.selectInComboBox(obj.ProfileEdges, self.form.profileEdges) self.form.avoidLastX_Faces.setValue(obj.AvoidLastX_Faces) self.form.boundBoxExtraOffsetX.setText( @@ -287,7 +278,7 @@ Command = PathOpGui.SetupOperation( "Surface", PathSurface.Create, TaskPanelOpPage, - "Path_Surface", + "Path_3DSurface", QtCore.QT_TRANSLATE_NOOP("Path_Surface", "3D Surface"), QtCore.QT_TRANSLATE_NOOP( "Path_Surface", "Create a 3D Surface Operation from a model" diff --git a/src/Mod/Path/PathScripts/PathSurfaceSupport.py b/src/Mod/Path/PathScripts/PathSurfaceSupport.py index e064a5022e..8ba42c20b4 100644 --- a/src/Mod/Path/PathScripts/PathSurfaceSupport.py +++ b/src/Mod/Path/PathScripts/PathSurfaceSupport.py @@ -1207,11 +1207,9 @@ def getSliceFromEnvelope(env): def _prepareModelSTLs(self, JOB, obj, m, ocl): """Tessellate model shapes or copy existing meshes into ocl.STLSurf objects""" - PathLog.debug("_prepareModelSTLs()") if self.modelSTLs[m] is True: model = JOB.Model.Group[m] - if self.modelSTLs[m] is True: - self.modelSTLs[m] = _makeSTL(model, obj, ocl, self.modelTypes[m]) + self.modelSTLs[m] = _makeSTL(model, obj, ocl, self.modelTypes[m]) def _makeSafeSTL(self, JOB, obj, mdlIdx, faceShapes, voidShapes, ocl): diff --git a/src/Mod/Path/PathScripts/PathWaterline.py b/src/Mod/Path/PathScripts/PathWaterline.py index aa0704042d..2f2ec32da7 100644 --- a/src/Mod/Path/PathScripts/PathWaterline.py +++ b/src/Mod/Path/PathScripts/PathWaterline.py @@ -22,6 +22,8 @@ # *************************************************************************** from __future__ import print_function +from PySide import QtCore +import FreeCAD __title__ = "Path Waterline Operation" __author__ = "russ4262 (Russell Johnson), sliptonic (Brad Collette)" @@ -29,28 +31,24 @@ __url__ = "http://www.freecadweb.org" __doc__ = "Class and implementation of Waterline operation." __contributors__ = "" -import FreeCAD -from PySide import QtCore - # OCL must be installed try: import ocl except ImportError: msg = QtCore.QCoreApplication.translate( - "PathWaterline", "This operation requires OpenCamLib to be installed." + "path_waterline", "This operation requires OpenCamLib to be installed." ) FreeCAD.Console.PrintError(msg + "\n") raise ImportError - # import sys - # sys.exit(msg) import Path import PathScripts.PathLog as PathLog -import PathScripts.PathUtils as PathUtils import PathScripts.PathOp as PathOp import PathScripts.PathSurfaceSupport as PathSurfaceSupport -import time +import PathScripts.PathUtils as PathUtils import math +import time +from PySide.QtCore import QT_TRANSLATE_NOOP # lazily loaded modules from lazy_loader.lazy_loader import LazyLoader @@ -60,13 +58,13 @@ Part = LazyLoader("Part", globals(), "Part") if FreeCAD.GuiUp: import FreeCADGui -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 class ObjectWaterline(PathOp.ObjectOp): @@ -83,6 +81,79 @@ class ObjectWaterline(PathOp.ObjectOp): | PathOp.FeatureBaseFaces ) + @classmethod + def propertyEnumerations(self, dataType="data"): + """propertyEnumerations(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 = { + "Algorithm": [ + (translate("path_waterline", "OCL Dropcutter"), "OCL Dropcutter"), + (translate("path_waterline", "Experimental"), "Experimental"), + ], + "BoundBox": [ + (translate("path_waterline", "BaseBoundBox"), "BaseBoundBox"), + (translate("path_waterline", "Stock"), "Stock"), + ], + "PatternCenterAt": [ + (translate("path_waterline", "CenterOfMass"), "CenterOfMass"), + (translate("path_waterline", "CenterOfBoundBox"), "CenterOfBoundBox"), + (translate("path_waterline", "XminYmin"), "XminYmin"), + (translate("path_waterline", "Custom"), "Custom"), + ], + "ClearLastLayer": [ + (translate("path_waterline", "Off"), "Off"), + (translate("path_waterline", "Circular"), "Circular"), + (translate("path_waterline", "CircularZigZag"), "CircularZigZag"), + (translate("path_waterline", "Line"), "Line"), + (translate("path_waterline", "Offset"), "Offset"), + (translate("path_waterline", "Spiral"), "Spiral"), + (translate("path_waterline", "ZigZag"), "ZigZag"), + ], + "CutMode": [ + (translate("path_waterline", "Conventional"), "Conventional"), + (translate("path_waterline", "Climb"), "Climb"), + ], + "CutPattern": [ + (translate("path_waterline", "None"), "None"), + (translate("path_waterline", "Circular"), "Circular"), + (translate("path_waterline", "CircularZigZag"), "CircularZigZag"), + (translate("path_waterline", "Line"), "Line"), + (translate("path_waterline", "Offset"), "Offset"), + (translate("path_waterline", "Spiral"), "Spiral"), + (translate("path_waterline", "ZigZag"), "ZigZag"), + ], + "HandleMultipleFeatures": [ + (translate("path_waterline", "Collectively"), "Collectively"), + (translate("path_waterline", "Individually"), "Individually"), + ], + "LayerMode": [ + (translate("path_waterline", "Single-pass"), "Single-pass"), + (translate("path_waterline", "Multi-pass"), "Multi-pass"), + ], + } + + if dataType == "raw": + return enums + + data = list() + idx = 0 if dataType == "translated" else 1 + + PathLog.debug(enums) + + for k, v in enumerate(enums): + data.append((v, [tup[idx] for tup in enums[v]])) + PathLog.debug(data) + + return data + def initOperation(self, obj): """initOperation(obj) ... Initialize the operation by managing property creation and property editor status.""" @@ -108,10 +179,10 @@ class ObjectWaterline(PathOp.ObjectOp): # Set enumeration lists for enumeration properties if len(self.addNewProps) > 0: - ENUMS = self.opPropertyEnumerations() + ENUMS = self.propertyEnumerations() for n in ENUMS: - if n in self.addNewProps: - setattr(obj, n, ENUMS[n]) + if n[0] in self.addNewProps: + setattr(obj, n[0], n[1]) if warn: newPropMsg = translate("PathWaterline", "New property added to") @@ -128,7 +199,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyBool", "ShowTempObjects", "Debug", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Show the temporary path construction objects when module is in DEBUG mode.", ), @@ -137,7 +208,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyDistance", "AngularDeflection", "Mesh Conversion", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Smaller values yield a finer, more accurate the mesh. Smaller values increase processing time a lot.", ), @@ -146,7 +217,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyDistance", "LinearDeflection", "Mesh Conversion", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Smaller values yield a finer, more accurate the mesh. Smaller values do not increase processing time much.", ), @@ -155,7 +226,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyInteger", "AvoidLastX_Faces", "Selected Geometry Settings", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Avoid cutting the last 'N' faces in the Base Geometry list of selected faces.", ), @@ -164,7 +235,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyBool", "AvoidLastX_InternalFeatures", "Selected Geometry Settings", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Do not cut internal features on avoided faces." ), ), @@ -172,7 +243,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyDistance", "BoundaryAdjustment", "Selected Geometry Settings", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Positive values push the cutter toward, or beyond, the boundary. Negative values retract the cutter away from the boundary.", ), @@ -181,7 +252,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyBool", "BoundaryEnforcement", "Selected Geometry Settings", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "If true, the cutter will remain inside the boundaries of the model or selected face(s).", ), @@ -190,7 +261,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyEnumeration", "HandleMultipleFeatures", "Selected Geometry Settings", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Choose how to process multiple Base Geometry features.", ), @@ -199,7 +270,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyDistance", "InternalFeaturesAdjustment", "Selected Geometry Settings", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Positive values push the cutter toward, or into, the feature. Negative values retract the cutter away from the feature.", ), @@ -208,7 +279,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyBool", "InternalFeaturesCut", "Selected Geometry Settings", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Cut internal feature areas within a larger selected face.", ), @@ -217,7 +288,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyEnumeration", "Algorithm", "Clearing Options", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Select the algorithm to use: OCL Dropcutter*, or Experimental (Not OCL based).", ), @@ -226,7 +297,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyEnumeration", "BoundBox", "Clearing Options", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Select the overall boundary for the operation." ), ), @@ -234,7 +305,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyEnumeration", "ClearLastLayer", "Clearing Options", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Set to clear last layer in a `Multi-pass` operation.", ), @@ -243,7 +314,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyEnumeration", "CutMode", "Clearing Options", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Set the direction for the cutting tool to engage the material: Climb (ClockWise) or Conventional (CounterClockWise)", ), @@ -252,7 +323,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyEnumeration", "CutPattern", "Clearing Options", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Set the geometric clearing pattern to use for the operation.", ), @@ -261,7 +332,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyFloat", "CutPatternAngle", "Clearing Options", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "The yaw angle used for certain clearing patterns" ), ), @@ -269,7 +340,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyBool", "CutPatternReversed", "Clearing Options", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Reverse the cut order of the stepover paths. For circular cut patterns, begin at the outside and work toward the center.", ), @@ -278,7 +349,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyDistance", "DepthOffset", "Clearing Options", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Set the Z-axis depth offset from the target surface.", ), @@ -287,7 +358,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyDistance", "IgnoreOuterAbove", "Clearing Options", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Ignore outer waterlines above this height." ), ), @@ -295,7 +366,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyEnumeration", "LayerMode", "Clearing Options", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Complete the operation in a single pass at depth, or mulitiple passes to final depth.", ), @@ -304,7 +375,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyVectorDistance", "PatternCenterCustom", "Clearing Options", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Set the start point for the cut pattern." ), ), @@ -312,7 +383,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyEnumeration", "PatternCenterAt", "Clearing Options", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Choose location of the center point for starting the cut pattern.", ), @@ -321,7 +392,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyDistance", "SampleInterval", "Clearing Options", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Set the sampling resolution. Smaller values quickly increase processing time.", ), @@ -330,7 +401,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyFloat", "StepOver", "Clearing Options", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Set the stepover percentage, based on the tool's diameter.", ), @@ -339,7 +410,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyBool", "OptimizeLinearPaths", "Optimization", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Enable optimization of linear paths (co-linear points). Removes unnecessary co-linear points from G-Code output.", ), @@ -348,7 +419,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyBool", "OptimizeStepOverTransitions", "Optimization", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Enable separate optimization of transitions between, and breaks within, each step over path.", ), @@ -357,7 +428,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyDistance", "GapThreshold", "Optimization", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Collinear and co-radial artifact gaps that are smaller than this threshold are closed in the path.", ), @@ -366,7 +437,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyString", "GapSizes", "Optimization", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Feedback: three smallest gaps identified in the path geometry.", ), @@ -375,7 +446,7 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyVectorDistance", "StartPoint", "Start Point", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "The custom start point for the path of this operation", ), @@ -384,46 +455,12 @@ class ObjectWaterline(PathOp.ObjectOp): "App::PropertyBool", "UseStartPoint", "Start Point", - QtCore.QT_TRANSLATE_NOOP( + QT_TRANSLATE_NOOP( "App::Property", "Make True, if specifying a Start Point" ), ), ] - def opPropertyEnumerations(self): - # Enumeration lists for App::PropertyEnumeration properties - return { - "Algorithm": ["OCL Dropcutter", "Experimental"], - "BoundBox": ["BaseBoundBox", "Stock"], - "PatternCenterAt": [ - "CenterOfMass", - "CenterOfBoundBox", - "XminYmin", - "Custom", - ], - "ClearLastLayer": [ - "Off", - "Circular", - "CircularZigZag", - "Line", - "Offset", - "Spiral", - "ZigZag", - ], - "CutMode": ["Conventional", "Climb"], - "CutPattern": [ - "None", - "Circular", - "CircularZigZag", - "Line", - "Offset", - "Spiral", - "ZigZag", - ], # Additional goals ['Offset', 'Spiral', 'ZigZagOffset', 'Grid', 'Triangle'] - "HandleMultipleFeatures": ["Collectively", "Individually"], - "LayerMode": ["Single-pass", "Multi-pass"], - } - def opPropertyDefaults(self, obj, job): """opPropertyDefaults(obj, job) ... returns a dictionary of default values for the operation's properties.""" @@ -543,15 +580,16 @@ class ObjectWaterline(PathOp.ObjectOp): obj.setEditorMode("ShowTempObjects", mode) # Repopulate enumerations in case of changes - ENUMS = self.opPropertyEnumerations() + + ENUMS = self.propertyEnumerations() for n in ENUMS: restore = False - if hasattr(obj, n): - val = obj.getPropertyByName(n) + if hasattr(obj, n[0]): + val = obj.getPropertyByName(n[0]) restore = True - setattr(obj, n, ENUMS[n]) + setattr(obj, n[0], n[1]) if restore: - setattr(obj, n, val) + setattr(obj, n[0], val) self.setEditorProperties(obj) diff --git a/src/Mod/Path/PathScripts/PathWaterlineGui.py b/src/Mod/Path/PathScripts/PathWaterlineGui.py index 73124f5d02..ed8548051b 100644 --- a/src/Mod/Path/PathScripts/PathWaterlineGui.py +++ b/src/Mod/Path/PathScripts/PathWaterlineGui.py @@ -21,20 +21,28 @@ # * * # *************************************************************************** +from PySide import QtCore +from PySide.QtCore import QT_TRANSLATE_NOOP import FreeCAD import FreeCADGui -import PathGui as PGui # ensure Path/Gui/Resources are loaded -import PathScripts.PathWaterline as PathWaterline +import PathScripts.PathLog as PathLog import PathScripts.PathGui as PathGui import PathScripts.PathOpGui as PathOpGui - -from PySide import QtCore +import PathScripts.PathWaterline as PathWaterline __title__ = "Path Waterline Operation UI" __author__ = "sliptonic (Brad Collette), russ4262 (Russell Johnson)" __url__ = "http://www.freecadweb.org" __doc__ = "Waterline operation page controller and command implementation." +translate = FreeCAD.Qt.translate + +if False: + PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule()) + PathLog.trackModule(PathLog.thisModule()) +else: + PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) + class TaskPanelOpPage(PathOpGui.TaskPanelPage): """Page controller class for the Waterline operation.""" @@ -45,24 +53,33 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage): def getForm(self): """getForm() ... returns UI""" - return FreeCADGui.PySideUic.loadUi(":/panels/PageOpWaterlineEdit.ui") + form = FreeCADGui.PySideUic.loadUi(":/panels/PageOpWaterlineEdit.ui") + comboToPropertyMap = [ + ("algorithmSelect", "Algorithm"), + ("boundBoxSelect", "BoundBox"), + ("layerMode", "LayerMode"), + ("cutPattern", "CutPattern"), + ] + enumTups = PathWaterline.ObjectWaterline.propertyEnumerations(dataType="raw") + PathGui.populateCombobox(form, enumTups, comboToPropertyMap) + return form def getFields(self, obj): """getFields(obj) ... transfers values from UI to obj's proprties""" self.updateToolController(obj, self.form.toolController) self.updateCoolant(obj, self.form.coolantController) - if obj.Algorithm != str(self.form.algorithmSelect.currentText()): - obj.Algorithm = str(self.form.algorithmSelect.currentText()) + if obj.Algorithm != str(self.form.algorithmSelect.currentData()): + obj.Algorithm = str(self.form.algorithmSelect.currentData()) - if obj.BoundBox != str(self.form.boundBoxSelect.currentText()): - obj.BoundBox = str(self.form.boundBoxSelect.currentText()) + if obj.BoundBox != str(self.form.boundBoxSelect.currentData()): + obj.BoundBox = str(self.form.boundBoxSelect.currentData()) - if obj.LayerMode != str(self.form.layerMode.currentText()): - obj.LayerMode = str(self.form.layerMode.currentText()) + if obj.LayerMode != str(self.form.layerMode.currentData()): + obj.LayerMode = str(self.form.layerMode.currentData()) - if obj.CutPattern != str(self.form.cutPattern.currentText()): - obj.CutPattern = str(self.form.cutPattern.currentText()) + if obj.CutPattern != str(self.form.cutPattern.currentData()): + obj.CutPattern = str(self.form.cutPattern.currentData()) PathGui.updateInputField( obj, "BoundaryAdjustment", self.form.boundaryAdjustment @@ -121,7 +138,7 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage): def updateVisibility(self, sentObj=None): """updateVisibility(sentObj=None)... Updates visibility of Tasks panel objects.""" - Algorithm = self.form.algorithmSelect.currentText() + Algorithm = self.form.algorithmSelect.currentData() self.form.optimizeEnabled.hide() # Has no independent QLabel object if Algorithm == "OCL Dropcutter": @@ -138,7 +155,7 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage): self.form.boundaryAdjustment.show() self.form.cutPattern_label.show() self.form.boundaryAdjustment_label.show() - if self.form.cutPattern.currentText() == "None": + if self.form.cutPattern.currentData() == "None": self.form.stepOver.hide() self.form.stepOver_label.hide() else: @@ -157,10 +174,8 @@ Command = PathOpGui.SetupOperation( PathWaterline.Create, TaskPanelOpPage, "Path_Waterline", - QtCore.QT_TRANSLATE_NOOP("Path_Waterline", "Waterline"), - QtCore.QT_TRANSLATE_NOOP( - "Path_Waterline", "Create a Waterline Operation from a model" - ), + QT_TRANSLATE_NOOP("Path_Waterline", "Waterline"), + QT_TRANSLATE_NOOP("Path_Waterline", "Create a Waterline Operation from a model"), PathWaterline.SetupProperties, )