diff --git a/src/Mod/Path/PathScripts/PathDrilling.py b/src/Mod/Path/PathScripts/PathDrilling.py index ce2e44a316c8..ce15d395e367 100644 --- a/src/Mod/Path/PathScripts/PathDrilling.py +++ b/src/Mod/Path/PathScripts/PathDrilling.py @@ -24,14 +24,14 @@ from __future__ import print_function import FreeCAD -from FreeCAD import Vector +#from FreeCAD import Vector import Path import PathScripts.PathLog as PathLog -import Part +#import Part from PySide import QtCore, QtGui from PathScripts import PathUtils from PathScripts.PathUtils import fmt -from math import pi +#from math import pi LOG_MODULE = 'PathDrilling' @@ -193,40 +193,6 @@ def execute(self, obj): obj.Path = path obj.ViewObject.Visibility = False - def _isDrillable(self, obj, candidate): - PathLog.track() - drillable = False - if candidate.BoundBox.ZLength > 0: - face = candidate - # eliminate flat faces - if (round(face.ParameterRange[0], 8) == 0.0) and (round(face.ParameterRange[1], 8) == round(pi * 2, 8)): - for edge in face.Edges: # Find seam edge and check if aligned to Z axis. - if (isinstance(edge.Curve, Part.Line)): - v0 = edge.Vertexes[0].Point - v1 = edge.Vertexes[1].Point - if (v1.sub(v0).x == 0) and (v1.sub(v0).y == 0): - # vector of top center - lsp = Vector(face.BoundBox.Center.x, - face.BoundBox.Center.y, face.BoundBox.ZMax) - # vector of bottom center - lep = Vector(face.BoundBox.Center.x, - face.BoundBox.Center.y, face.BoundBox.ZMin) - if obj.isInside(lsp, 0, False) or obj.isInside(lep, 0, False): - drillable = False - # eliminate elliptical holes - elif abs(face.BoundBox.XLength - face.BoundBox.YLength) > 0.05: - drillable = False - else: - drillable = True - else: - for edge in candidate.Edges: - if (isinstance(edge.Curve, Part.Circle)): - if abs(edge.BoundBox.XLength - edge.BoundBox.YLength) > 0.05: - drillable = False - else: - drillable = True - return drillable - def findHoles(self, obj): PathLog.track() holelist = [] @@ -234,7 +200,7 @@ def findHoles(self, obj): for i in range(len(obj.Edges)): candidateEdgeName = "Edge" + str(i +1) e = obj.getElement(candidateEdgeName) - if self._isDrillable(obj, e): + if PathUtils.isDrillable(obj, e): x = e.BoundBox.Center.x y = e.BoundBox.Center.y diameter = e.BoundBox.XLength @@ -243,7 +209,7 @@ def findHoles(self, obj): for i in range(len(obj.Faces)): candidateFaceName = "Face" + str(i + 1) f = obj.getElement(candidateFaceName) - if self._isDrillable(obj, f): + if PathUtils.isDrillable(obj, f): x = f.BoundBox.Center.x y = f.BoundBox.Center.y diameter = f.BoundBox.XLength @@ -415,38 +381,38 @@ def open(self): self.s = SelObserver() FreeCADGui.Selection.addObserver(self.s) - def addBase(self): - # check that the selection contains exactly what we want - selection = FreeCADGui.Selection.getSelectionEx() - - if not len(selection) >= 1: - FreeCAD.Console.PrintError(translate("PathProject", "Please select at least one Drillable Location\n")) - return - for s in selection: - if s.HasSubObjects: - for i in s.SubElementNames: - self.obj.Proxy.addDrillableLocation(self.obj, s.Object, i) - else: - self.obj.Proxy.addDrillableLocation(self.obj, s.Object) - - self.setFields() # defaults may have changed. Reload. - self.form.baseList.clear() - - for i in self.obj.Base: - for sub in i[1]: - self.form.baseList.addItem(i[0].Name + "." + sub) - - def deleteBase(self): - dlist = self.form.baseList.selectedItems() - for d in dlist: - newlist = [] - for i in self.obj.Base: - if not i[0].Name == d.text().partition(".")[0]: - newlist.append(i) - self.obj.Base = newlist - self.form.baseList.takeItem(self.form.baseList.row(d)) - # self.obj.Proxy.execute(self.obj) - # FreeCAD.ActiveDocument.recompute() + # def addBase(self): + # # check that the selection contains exactly what we want + # selection = FreeCADGui.Selection.getSelectionEx() + + # if not len(selection) >= 1: + # FreeCAD.Console.PrintError(translate("PathProject", "Please select at least one Drillable Location\n")) + # return + # for s in selection: + # if s.HasSubObjects: + # for i in s.SubElementNames: + # self.obj.Proxy.addDrillableLocation(self.obj, s.Object, i) + # else: + # self.obj.Proxy.addDrillableLocation(self.obj, s.Object) + + # self.setFields() # defaults may have changed. Reload. + # self.form.baseList.clear() + + # for i in self.obj.Base: + # for sub in i[1]: + # self.form.baseList.addItem(i[0].Name + "." + sub) + + # def deleteBase(self): + # dlist = self.form.baseList.selectedItems() + # for d in dlist: + # newlist = [] + # for i in self.obj.Base: + # if not i[0].Name == d.text().partition(".")[0]: + # newlist.append(i) + # self.obj.Base = newlist + # self.form.baseList.takeItem(self.form.baseList.row(d)) + # # self.obj.Proxy.execute(self.obj) + # # FreeCAD.ActiveDocument.recompute() def itemActivated(self): FreeCADGui.Selection.clearSelection() @@ -462,19 +428,19 @@ def itemActivated(self): FreeCADGui.updateGui() - def reorderBase(self): - newlist = [] - for i in range(self.form.baseList.count()): - s = self.form.baseList.item(i).text() - objstring = s.partition(".") + # def reorderBase(self): + # newlist = [] + # for i in range(self.form.baseList.count()): + # s = self.form.baseList.item(i).text() + # objstring = s.partition(".") - obj = FreeCAD.ActiveDocument.getObject(objstring[0]) - item = (obj, str(objstring[2])) - newlist.append(item) - self.obj.Base = newlist + # obj = FreeCAD.ActiveDocument.getObject(objstring[0]) + # item = (obj, str(objstring[2])) + # newlist.append(item) + # self.obj.Base = newlist - self.obj.Proxy.execute(self.obj) - FreeCAD.ActiveDocument.recompute() + # self.obj.Proxy.execute(self.obj) + # FreeCAD.ActiveDocument.recompute() def getStandardButtons(self): return int(QtGui.QDialogButtonBox.Ok) @@ -487,16 +453,16 @@ def setupUi(self): self.form.safeHeight.editingFinished.connect(self.getFields) self.form.clearanceHeight.editingFinished.connect(self.getFields) - self.form.addBase.clicked.connect(self.addBase) - self.form.deleteBase.clicked.connect(self.deleteBase) - self.form.reorderBase.clicked.connect(self.reorderBase) + #self.form.addBase.clicked.connect(self.addBase) + #self.form.deleteBase.clicked.connect(self.deleteBase) + #self.form.reorderBase.clicked.connect(self.reorderBase) self.form.baseList.itemSelectionChanged.connect(self.itemActivated) self.form.uiToolController.currentIndexChanged.connect(self.getFields) - sel = FreeCADGui.Selection.getSelectionEx() - if len(sel) != 0 and sel[0].HasSubObjects: - self.addBase() + # sel = FreeCADGui.Selection.getSelectionEx() + # if len(sel) != 0 and sel[0].HasSubObjects: + # self.addBase() self.setFields() @@ -510,7 +476,7 @@ def __del__(self): PST.clear() def addSelection(self, doc, obj, sub, pnt): - FreeCADGui.doCommand('Gui.Selection.addSelection(FreeCAD.ActiveDocument.' + obj + ')') + FreeCADGui.doCommand('Gui.Selection.addSelection(FreeCAD.ActiveDocument.' + obj + ',"' + sub + '")') FreeCADGui.updateGui() diff --git a/src/Mod/Path/PathScripts/PathSelection.py b/src/Mod/Path/PathScripts/PathSelection.py index 78bd7af7d149..f5c5d34d4faa 100644 --- a/src/Mod/Path/PathScripts/PathSelection.py +++ b/src/Mod/Path/PathScripts/PathSelection.py @@ -25,44 +25,12 @@ import FreeCAD import FreeCADGui -#from FreeCAD import Vector +import PathUtils +import PathScripts.PathLog as PathLog - -# def equals(p1, p2): -# '''returns True if vertexes have same coordinates within precision amount of digits ''' -# precision = 12 -# p = precision -# u = Vector(p1.X, p1.Y, p1.Z) -# v = Vector(p2.X, p2.Y, p2.Z) -# vector = (u.sub(v)) -# isNull = (round(vector.x, p) == 0 and round(vector.y, p) == 0 and round(vector.z, p) == 0) -# return isNull - - -# def segments(poly): -# ''' A sequence of (x,y) numeric coordinates pairs ''' -# return zip(poly, poly[1:] + [poly[0]]) - - -# def check_clockwise(poly): -# ''' -# check_clockwise(poly) a function for returning a boolean if the selected wire is clockwise or counter clockwise -# based on point order. poly = [(x1,y1),(x2,y2),(x3,y3)] -# ''' -# clockwise = False -# if (sum(x0*y1 - x1*y0 for ((x0, y0), (x1, y1)) in segments(poly))) < 0: -# clockwise = not clockwise -# return clockwise - - -# class FGate: -# def allow(self, doc, obj, sub): -# return (sub[0:4] == 'Face') - - -# class VGate: -# def allow(self, doc, obj, sub): -# return (sub[0:6] == 'Vertex') +LOG_MODULE = 'PathSelection' +PathLog.setLevel(PathLog.Level.INFO, LOG_MODULE) +PathLog.trackModule('PathSelection') class EGate: @@ -78,7 +46,6 @@ def allow(self, doc, obj, sub): class ENGRAVEGate: def allow(self, doc, obj, sub): engraveable = False - if hasattr(obj, "Shape"): if obj.Shape.BoundBox.ZLength == 0.0: try: @@ -87,31 +54,18 @@ def allow(self, doc, obj, sub): return False if len(obj.Wires) > 0: engraveable = True - return engraveable + class DRILLGate: def allow(self, doc, obj, sub): - import Part - drillable = False - try: + PathLog.debug('obj: {} sub: {}'.format(obj, sub)) + if hasattr(obj, "Shape"): obj = obj.Shape - except: + subobj = obj.getElement(sub) + return PathUtils.isDrillable(obj, subobj) + else: return False - if obj.ShapeType == 'Vertex': - drillable = True - elif obj.ShapeType in['Solid', 'Compound']: - if sub[0:4] == 'Face': - subobj = obj.getElement(sub) - drillable = isinstance(subobj.Edges[0].Curve, Part.Circle) - if str(subobj.Surface) == "": - drillable = subobj.isClosed() - - if sub[0:4] == 'Edge': - o = obj.getElement(sub) - drillable = isinstance(o.Curve, Part.Circle) - - return drillable class PROFILEGate: @@ -182,46 +136,30 @@ def contourselect(): FreeCADGui.Selection.addSelectionGate(CONTOURGate()) FreeCAD.Console.PrintWarning("Contour Select Mode\n") -# def fselect(): -# FreeCADGui.Selection.addSelectionGate(FGate()) -# FreeCAD.Console.PrintWarning("Face Select Mode\n") - - -# def vselect(): -# FreeCADGui.Selection.addSelectionGate(VGate()) -# FreeCAD.Console.PrintWarning("Vertex Select Mode\n") - - def eselect(): FreeCADGui.Selection.addSelectionGate(EGate()) FreeCAD.Console.PrintWarning("Edge Select Mode\n") - def drillselect(): FreeCADGui.Selection.addSelectionGate(DRILLGate()) FreeCAD.Console.PrintWarning("Drilling Select Mode\n") - def engraveselect(): FreeCADGui.Selection.addSelectionGate(ENGRAVEGate()) FreeCAD.Console.PrintWarning("Engraving Select Mode\n") - def profileselect(): FreeCADGui.Selection.addSelectionGate(PROFILEGate()) FreeCAD.Console.PrintWarning("Profiling Select Mode\n") - def pocketselect(): FreeCADGui.Selection.addSelectionGate(POCKETGate()) FreeCAD.Console.PrintWarning("Pocketing Select Mode\n") - def surfaceselect(): FreeCADGui.Selection.addSelectionGate(MESHGate()) FreeCAD.Console.PrintWarning("Surfacing Select Mode\n") - def clear(): FreeCADGui.Selection.removeSelectionGate() FreeCAD.Console.PrintWarning("Free Select\n") diff --git a/src/Mod/Path/PathScripts/PathUtils.py b/src/Mod/Path/PathScripts/PathUtils.py index 7760b42971ff..a145c908b49f 100644 --- a/src/Mod/Path/PathScripts/PathUtils.py +++ b/src/Mod/Path/PathScripts/PathUtils.py @@ -31,6 +31,8 @@ from PathScripts import PathJob import numpy import PathLog +#from math import pi +from FreeCAD import Vector LOG_MODULE = 'PathUtils' PathLog.setLevel(PathLog.Level.INFO, LOG_MODULE) @@ -84,6 +86,44 @@ def curvetowire(obj, steps): p0 = p return edgelist +def isDrillable(obj, candidate): + PathLog.track() + PathLog.debug('obj: {} candidate {}') + drillable = False + if candidate.ShapeType == 'Face': + face = candidate + # eliminate flat faces + if (round(face.ParameterRange[0], 8) == 0.0) and (round(face.ParameterRange[1], 8) == round(math.pi * 2, 8)): + for edge in face.Edges: # Find seam edge and check if aligned to Z axis. + if (isinstance(edge.Curve, Part.Line)): + v0 = edge.Vertexes[0].Point + v1 = edge.Vertexes[1].Point + if (v1.sub(v0).x == 0) and (v1.sub(v0).y == 0): + # vector of top center + lsp = Vector(face.BoundBox.Center.x, + face.BoundBox.Center.y, face.BoundBox.ZMax) + # vector of bottom center + lep = Vector(face.BoundBox.Center.x, + face.BoundBox.Center.y, face.BoundBox.ZMin) + if obj.isInside(lsp, 0, False) or obj.isInside(lep, 0, False): + drillable = False + # eliminate elliptical holes + elif abs(face.BoundBox.XLength - face.BoundBox.YLength) > 0.05: + drillable = False + else: + drillable = True + else: + print('here') + drillable = False + else: + print ('looking at edges') + for edge in candidate.Edges: + if (isinstance(edge.Curve, Part.Circle)): + if abs(edge.BoundBox.XLength - edge.BoundBox.YLength) > 0.05: + drillable = False + else: + drillable = True + return drillable # fixme set at 4 decimal places for testing def fmt(val): return format(val, '.4f')