diff --git a/src/Mod/CAM/Path/Op/Area.py b/src/Mod/CAM/Path/Op/Area.py index ac10389ec4..d326635957 100644 --- a/src/Mod/CAM/Path/Op/Area.py +++ b/src/Mod/CAM/Path/Op/Area.py @@ -219,6 +219,15 @@ class ObjectOp(PathOp.ObjectOp): Can safely be overwritten by subclasses.""" pass + def getMiddlePointLongestEdge(self, shape): + """getMiddlePointLongestEdge(shape) ... return middle point of longest edge from shape.""" + candidate = shape.Edges[0] + for edge in shape.Edges: + if edge.Length > candidate.Length: + candidate = edge + + return candidate.discretize(3)[1] + def _buildPathArea(self, obj, baseobject, isHole, start, getsim): """_buildPathArea(obj, baseobject, isHole, start, getsim) ... internal function.""" Path.Log.track() @@ -301,7 +310,13 @@ class ObjectOp(PathOp.ObjectOp): if not self.areaOpRetractTool(obj): pathParams["threshold"] = 2.001 * self.radius - if self.endVector is not None: + if ( + not obj.UseStartPoint + and getattr(obj, "HandleMultipleFeatures", None) == "Individually" + and getattr(obj, "UseLongestEdge", False) + ): + pathParams["start"] = self.getMiddlePointLongestEdge(shapelist[0]) + elif self.endVector is not None: if self.endVector[:2] != (0, 0): pathParams["start"] = self.endVector elif PathOp.FeatureStartPoint & self.opFeatures(obj) and obj.UseStartPoint: diff --git a/src/Mod/CAM/Path/Op/Profile.py b/src/Mod/CAM/Path/Op/Profile.py index ba2d59c47c..13769035d0 100644 --- a/src/Mod/CAM/Path/Op/Profile.py +++ b/src/Mod/CAM/Path/Op/Profile.py @@ -191,6 +191,17 @@ class ObjectProfile(PathAreaOp.ObjectOp): "If doing multiple passes, the extra offset of each additional pass", ), ), + ( + "App::PropertyBool", + "UseLongestEdge", + "Start Point", + QT_TRANSLATE_NOOP( + "App::Property", + "Override start point" + "\nShoud be used only with Individually HandleMultipleFeatures" + "and disabled UseStartPoint", + ), + ), ] @classmethod @@ -294,6 +305,10 @@ class ObjectProfile(PathAreaOp.ObjectOp): elif opType == "Edge": pass + useLongestEdgeMode = ( + 0 if obj.HandleMultipleFeatures == "Individually" and not obj.UseStartPoint else 2 + ) + obj.setEditorMode("JoinType", 2) obj.setEditorMode("MiterLimit", 2) # ml obj.setEditorMode("Side", side) @@ -301,6 +316,7 @@ class ObjectProfile(PathAreaOp.ObjectOp): obj.setEditorMode("processCircles", fc) obj.setEditorMode("processHoles", fc) obj.setEditorMode("processPerimeter", fc) + obj.setEditorMode("UseLongestEdge", useLongestEdgeMode) def _getOperationType(self, obj): if len(obj.Base) == 0: @@ -318,9 +334,8 @@ class ObjectProfile(PathAreaOp.ObjectOp): def areaOpOnChanged(self, obj, prop): """areaOpOnChanged(obj, prop) ... updates certain property visibilities depending on changed properties.""" - if prop in ["UseComp", "JoinType", "Base"]: - if hasattr(self, "propertiesReady") and self.propertiesReady: - self.setOpEditorProperties(obj) + if hasattr(self, "propertiesReady") and self.propertiesReady: + self.setOpEditorProperties(obj) def areaOpAreaParams(self, obj, isHole): """areaOpAreaParams(obj, isHole) ... returns dictionary with area parameters. @@ -560,9 +575,6 @@ class ObjectProfile(PathAreaOp.ObjectOp): FreeCADGui.ActiveDocument.getObject(tmpGrpNm).Visibility = False self.tmpGrp.purgeTouched() - # for shape in shapes: - # Part.show(shape[0]) - # print(shape) return shapes # Method to handle each model as a whole, when no faces are selected