diff --git a/src/Mod/Path/PathScripts/PathDeburr.py b/src/Mod/Path/PathScripts/PathDeburr.py index ba530dc366..c540811765 100644 --- a/src/Mod/Path/PathScripts/PathDeburr.py +++ b/src/Mod/Path/PathScripts/PathDeburr.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # *************************************************************************** # * Copyright (c) 2018 sliptonic * -# * Copyright (c) 2020 Schildkroet * +# * Copyright (c) 2020-2021 Schildkroet * # * * # * This program is free software; you can redistribute it and/or modify * # * it under the terms of the GNU Lesser General Public License (LGPL) * @@ -93,7 +93,7 @@ class ObjectDeburr(PathEngraveBase.ObjectOp): '''Proxy class for Deburr operation.''' def opFeatures(self, obj): - return PathOp.FeatureTool | PathOp.FeatureHeights | PathOp.FeatureStepDown | PathOp.FeatureBaseEdges | PathOp.FeatureBaseFaces | PathOp.FeatureCoolant + return PathOp.FeatureTool | PathOp.FeatureHeights | PathOp.FeatureStepDown | PathOp.FeatureBaseEdges | PathOp.FeatureBaseFaces | PathOp.FeatureCoolant | PathOp.FeatureBaseGeometry def initOperation(self, obj): PathLog.track(obj.Label) @@ -139,14 +139,59 @@ class ObjectDeburr(PathEngraveBase.ObjectOp): for base, subs in obj.Base: edges = [] basewires = [] + max_h = -99999 + for f in subs: sub = base.Shape.getElement(f) - if type(sub) == Part.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 + # Find z value of upper edge + for edge in sub.Edges: + for p0 in edge.Vertexes: + if p0.Point.z > max_h: + max_h = p0.Point.z + + # 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 edge.Vertexes[0].Point.z < max_h: + + if edge.Closed: # Circle + v = FreeCAD.Vector(edge.Curve.Center.x, edge.Curve.Center.y, max_h) + new_edge = Part.makeCircle(edge.Curve.Radius, v, FreeCAD.Vector(0, 0, 1)) + edges.append(new_edge) + break + else: # Arc + if edge.Vertexes[0].Point.z == edge.Vertexes[1].Point.z: + 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) + + 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) + + if edge.Vertexes[0].Point.y < edge.Curve.Center.y: + start_angle *= -1 + if edge.Vertexes[1].Point.y < edge.Curve.Center.y: + end_angle *= -1 + + edge = Part.ArcOfCircle(Part.Circle(edge.Curve.Center, FreeCAD.Vector(0,0,1), edge.Curve.Radius), start_angle, end_angle).toShape() + 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))) + edges.append(new_edge) + + elif sub.Wires: basewires.extend(sub.Wires) - else: + + else: # Flat face basewires.append(Part.Wire(sub.Edges)) + self.edges = edges # pylint: disable=attribute-defined-outside-init for edgelist in Part.sortEdges(edges): basewires.append(Part.Wire(edgelist)) @@ -160,9 +205,6 @@ class ObjectDeburr(PathEngraveBase.ObjectOp): if wire: wires.append(wire) - # # Save Outside or Inside - # obj.Side = side[0] - # Set direction of op forward = (obj.Direction == 'CW') diff --git a/src/Mod/Path/PathScripts/PathDeburrGui.py b/src/Mod/Path/PathScripts/PathDeburrGui.py index d98642f4dd..1d4e0d8bf3 100644 --- a/src/Mod/Path/PathScripts/PathDeburrGui.py +++ b/src/Mod/Path/PathScripts/PathDeburrGui.py @@ -55,14 +55,14 @@ class TaskPanelBaseGeometryPage(PathOpGui.TaskPanelBaseGeometryPage): return super(TaskPanelBaseGeometryPage, self) def addBaseGeometry(self, selection): - for sel in selection: - if sel.HasSubObjects: + #for sel in selection: + #if sel.HasSubObjects: # selectively add some elements of the drawing to the Base - for sub in sel.SubObjects: - if isinstance(sub, Part.Face): - if sub.normalAt(0, 0) != FreeCAD.Vector(0, 0, 1): - PathLog.info(translate("Path", "Ignoring non-horizontal Face")) - return + #for sub in sel.SubObjects: + # if isinstance(sub, Part.Face): + # if sub.normalAt(0, 0) != FreeCAD.Vector(0, 0, 1): + # PathLog.info(translate("Path", "Ignoring non-horizontal Face")) + # return self.super().addBaseGeometry(selection) diff --git a/src/Mod/Path/PathScripts/PathOpTools.py b/src/Mod/Path/PathScripts/PathOpTools.py index 5bdb3a9ba4..862710bca5 100644 --- a/src/Mod/Path/PathScripts/PathOpTools.py +++ b/src/Mod/Path/PathScripts/PathOpTools.py @@ -166,6 +166,28 @@ def offsetWire(wire, base, offset, forward):#, Side = None): edge = Part.makeCircle(curve.Radius - offset, curve.Center, FreeCAD.Vector(0, 0, -z)) w = Part.Wire([edge]) return w + + if Part.Circle == type(curve) and not wire.isClosed(): + # Process arc segment + z = -1 if forward else 1 + l1 = math.sqrt((edge.Vertexes[0].Point.x - curve.Center.x)**2 + (edge.Vertexes[0].Point.y - curve.Center.y)**2) + l2 = math.sqrt((edge.Vertexes[1].Point.x - curve.Center.x)**2 + (edge.Vertexes[1].Point.y - curve.Center.y)**2) + + start_angle = math.acos((edge.Vertexes[0].Point.x - curve.Center.x) / l1) + end_angle = math.acos((edge.Vertexes[1].Point.x - curve.Center.x) / l2) + + if edge.Vertexes[0].Point.y < curve.Center.y: + start_angle *= -1 + if edge.Vertexes[1].Point.y < curve.Center.y: + end_angle *= -1 + + if base.isInside(edge.Vertexes[0].Point, offset/2, True): + offset *= -1 + + edge = Part.ArcOfCircle(Part.Circle(curve.Center, FreeCAD.Vector(0,0,1), curve.Radius+offset), start_angle, end_angle).toShape() + + return Part.Wire([edge]) + if Part.Line == type(curve) or Part.LineSegment == type(curve): # offsetting a single edge doesn't work because there is an infinite # possible planes into which the edge could be offset diff --git a/src/Mod/Path/PathScripts/PathSelection.py b/src/Mod/Path/PathScripts/PathSelection.py index 055bfb1757..8f0725407b 100644 --- a/src/Mod/Path/PathScripts/PathSelection.py +++ b/src/Mod/Path/PathScripts/PathSelection.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # *************************************************************************** # * Copyright (c) 2015 Dan Falck * +# * Copyright (c) 2021 Schildkroet * # * * # * This program is free software; you can redistribute it and/or modify * # * it under the terms of the GNU Lesser General Public License (LGPL) * @@ -115,7 +116,7 @@ class CHAMFERGate(PathBaseGate): subShape = shape.getElement(sub) if subShape.ShapeType == 'Edge': return True - elif (subShape.ShapeType == 'Face' and subShape.normalAt(0, 0) == FreeCAD.Vector(0, 0, 1)): + elif (subShape.ShapeType == 'Face'): return True return False