From f8a57157246a5f2d98f0cf7176aa4c011e5b1b90 Mon Sep 17 00:00:00 2001 From: Markus Lampert Date: Sun, 17 Sep 2017 20:49:41 -0700 Subject: [PATCH] Extended edge-loop-selection command become active if there is a single edge selected and that edge is only part of one wire in the horizontal plane. --- src/Mod/Path/PathCommands.py | 10 ++++++++-- src/Mod/Path/PathScripts/PathGeom.py | 11 +++++++++++ src/Mod/Path/PathScripts/PathPocketShape.py | 14 +++----------- src/Mod/Path/PathScripts/PathUtils.py | 9 +++++++++ 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/Mod/Path/PathCommands.py b/src/Mod/Path/PathCommands.py index 394535fab1..b0d41d5f2a 100644 --- a/src/Mod/Path/PathCommands.py +++ b/src/Mod/Path/PathCommands.py @@ -25,6 +25,7 @@ import FreeCAD import PathScripts from PathScripts.PathUtils import loopdetect +from PathScripts.PathUtils import horizontalLoop from PathScripts.PathUtils import addToJob from PathScripts.PathUtils import findParentJob @@ -57,6 +58,8 @@ class _CommandSelectLoop: sub1 = sel.SubElementNames[0] if sub1[0:4] != 'Edge': return False + if len(sel.SubElementNames) == 1 and horizontalLoop(sel.Object, sel.SubObjects[0]): + return True sub2 = sel.SubElementNames[1] if sub2[0:4] != 'Edge': return False @@ -68,8 +71,11 @@ class _CommandSelectLoop: sel = FreeCADGui.Selection.getSelectionEx()[0] obj = sel.Object edge1 = sel.SubObjects[0] - edge2 = sel.SubObjects[1] - loopwire = loopdetect(obj, edge1, edge2) + if len(sel.SubObjects) == 1: + loopwire = horizontalLoop(obj, edge1) + else: + edge2 = sel.SubObjects[1] + loopwire = loopdetect(obj, edge1, edge2) if loopwire is not None: FreeCADGui.Selection.clearSelection() elist = obj.Shape.Edges diff --git a/src/Mod/Path/PathScripts/PathGeom.py b/src/Mod/Path/PathScripts/PathGeom.py index 8f594e5bf2..d6671c4f49 100644 --- a/src/Mod/Path/PathScripts/PathGeom.py +++ b/src/Mod/Path/PathScripts/PathGeom.py @@ -132,6 +132,17 @@ class PathGeom: a = a2 - a1 return a + @classmethod + def isVertical(cls, vector): + '''isVertical(vector) ... answer True if vector points into Z''' + return PathGeom.pointsCoincide(vector, FreeCAD.Vector(0, 0, 1)) or PathGeom.pointsCoincide(vector, FreeCAD.Vector(0, 0, -1)) + + @classmethod + def isHorizontal(cls, vector): + '''isHorizontal(vector) ... answer True if vector points into X or Y''' + return PathGeom.pointsCoincide(vector, FreeCAD.Vector(1, 0, 0)) or PathGeom.pointsCoincide(vector, FreeCAD.Vector(-1, 0, 0)) or PathGeom.pointsCoincide(vector, FreeCAD.Vector(0, 1, 0)) or PathGeom.pointsCoincide(vector, FreeCAD.Vector(0, -1, 0)) + + @classmethod def commandEndPoint(cls, cmd, defaultPoint = Vector(), X='X', Y='Y', Z='Z'): """(cmd, [defaultPoint=Vector()], [X='X'], [Y='Y'], [Z='Z']) diff --git a/src/Mod/Path/PathScripts/PathPocketShape.py b/src/Mod/Path/PathScripts/PathPocketShape.py index 06f30f5c4f..aead19c6f4 100644 --- a/src/Mod/Path/PathScripts/PathPocketShape.py +++ b/src/Mod/Path/PathScripts/PathPocketShape.py @@ -50,14 +50,6 @@ def translate(context, text, disambig=None): return QtCore.QCoreApplication.translate(context, text, disambig) -def isVertical(vector): - '''isVertical(vector) ... answer True if vector points into Z''' - return PathGeom.pointsCoincide(vector, FreeCAD.Vector(0, 0, 1)) or PathGeom.pointsCoincide(vector, FreeCAD.Vector(0, 0, -1)) - -def isHorizontal(vector): - '''isHorizontal(vector) ... answer True if vector points into X or Y''' - return PathGeom.pointsCoincide(vector, FreeCAD.Vector(1, 0, 0)) or PathGeom.pointsCoincide(vector, FreeCAD.Vector(-1, 0, 0)) or PathGeom.pointsCoincide(vector, FreeCAD.Vector(0, 1, 0)) or PathGeom.pointsCoincide(vector, FreeCAD.Vector(0, -1, 0)) - class ObjectPocket(PathPocketBase.ObjectPocket): '''Proxy object for Pocket operation.''' @@ -100,10 +92,10 @@ class ObjectPocket(PathPocketBase.ObjectPocket): for sub in o[1]: if "Face" in sub: face = base.Shape.getElement(sub) - if type(face.Surface) == Part.Plane and isVertical(face.Surface.Axis): + if type(face.Surface) == Part.Plane and PathGeom.isVertical(face.Surface.Axis): # it's a flat horizontal face horizontal.append(face) - elif type(face.Surface) == Part.Cylinder and isVertical(face.Surface.Axis): + elif type(face.Surface) == Part.Cylinder and PathGeom.isVertical(face.Surface.Axis): # vertical cylinder wall if any(e.isClosed() for e in face.Edges): # complete cylinder @@ -113,7 +105,7 @@ class ObjectPocket(PathPocketBase.ObjectPocket): else: # partial cylinder wall vertical.append(face) - elif type(face.Surface) == Part.Plane and isHorizontal(face.Surface.Axis): + elif type(face.Surface) == Part.Plane and PathGeom.isHorizontal(face.Surface.Axis): vertical.append(face) else: PathLog.error(translate('PathPocket', "Pocket does not support shape %s.%s") % (base.Label, sub)) diff --git a/src/Mod/Path/PathScripts/PathUtils.py b/src/Mod/Path/PathScripts/PathUtils.py index 8506778b99..56d5a2fc3b 100644 --- a/src/Mod/Path/PathScripts/PathUtils.py +++ b/src/Mod/Path/PathScripts/PathUtils.py @@ -35,6 +35,7 @@ from FreeCAD import Vector from PathScripts import PathJob from PathScripts import PathJobCmd from PathScripts import PathLog +from PathScripts.PathGeom import PathGeom from PySide import QtCore from PySide import QtGui @@ -215,6 +216,14 @@ def loopdetect(obj, edge1, edge2): loopwire = next(x for x in loop)[1] return loopwire +def horizontalLoop(obj, edge): + '''horizontalLoopWire(obj, edge) ... returns a wire in the horizontal plane, if that is the only horizontal wire the given edge is a part of.''' + h = edge.hashCode() + wires = [w for w in obj.Shape.Wires if any(e.hashCode() == h for e in w.Edges)] + loops = [w for w in wires if PathGeom.isVertical(Part.Face(w).Surface.Axis)] + if len(loops) == 1: + return loops[0] + return None def filterArcs(arcEdge): '''filterArcs(Edge) -used to split arcs that over 180 degrees. Returns list '''