Path: drilling mostly working again
This commit is contained in:
committed by
Yorik van Havre
parent
bf1bdc897e
commit
d24b7730de
@@ -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 @@ class ObjectDrilling:
|
||||
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 @@ class ObjectDrilling:
|
||||
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 @@ class ObjectDrilling:
|
||||
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 @@ class TaskPanel:
|
||||
self.s = SelObserver()
|
||||
FreeCADGui.Selection.addObserver(self.s)
|
||||
|
||||
def addBase(self):
|
||||
# check that the selection contains exactly what we want
|
||||
selection = FreeCADGui.Selection.getSelectionEx()
|
||||
# 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)
|
||||
# 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()
|
||||
# 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)
|
||||
# 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 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 @@ class TaskPanel:
|
||||
|
||||
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 @@ class TaskPanel:
|
||||
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 @@ class SelObserver:
|
||||
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()
|
||||
|
||||
|
||||
|
||||
@@ -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 @@ class MESHGate:
|
||||
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 @@ class ENGRAVEGate:
|
||||
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) == "<Cylinder object>":
|
||||
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")
|
||||
|
||||
@@ -31,6 +31,8 @@ import PathScripts
|
||||
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')
|
||||
|
||||
Reference in New Issue
Block a user