Merge pull request #2343 from mlampert/bugfix/robust-circular-hole-processing
Path:: Bugfix/robust circular hole processing
This commit is contained in:
@@ -134,15 +134,20 @@ class ObjectOp(PathOp.ObjectOp):
|
||||
edge = self.getArchPanelEdge(obj, base, sub)
|
||||
return edge.BoundBox.XLength
|
||||
|
||||
shape = base.Shape.getElement(sub)
|
||||
if shape.ShapeType == 'Vertex':
|
||||
return 0
|
||||
try:
|
||||
shape = base.Shape.getElement(sub)
|
||||
if shape.ShapeType == 'Vertex':
|
||||
return 0
|
||||
|
||||
if shape.ShapeType == 'Edge' and type(shape.Curve) == Part.Circle:
|
||||
return shape.Curve.Radius * 2
|
||||
if shape.ShapeType == 'Edge' and type(shape.Curve) == Part.Circle:
|
||||
return shape.Curve.Radius * 2
|
||||
|
||||
# for all other shapes the diameter is just the dimension in X
|
||||
return shape.BoundBox.XLength
|
||||
# for all other shapes the diameter is just the dimension in X
|
||||
return shape.BoundBox.XLength
|
||||
except Part.OCCError as e:
|
||||
PathLog.error(e)
|
||||
|
||||
return 0
|
||||
|
||||
def holePosition(self, obj, base, sub):
|
||||
'''holePosition(obj, base, sub) ... returns a Vector for the position defined by the given features.
|
||||
@@ -152,18 +157,21 @@ class ObjectOp(PathOp.ObjectOp):
|
||||
center = edge.Curve.Center
|
||||
return FreeCAD.Vector(center.x, center.y, 0)
|
||||
|
||||
shape = base.Shape.getElement(sub)
|
||||
if shape.ShapeType == 'Vertex':
|
||||
return FreeCAD.Vector(shape.X, shape.Y, 0)
|
||||
try:
|
||||
shape = base.Shape.getElement(sub)
|
||||
if shape.ShapeType == 'Vertex':
|
||||
return FreeCAD.Vector(shape.X, shape.Y, 0)
|
||||
|
||||
if shape.ShapeType == 'Edge' and hasattr(shape.Curve, 'Center'):
|
||||
return FreeCAD.Vector(shape.Curve.Center.x, shape.Curve.Center.y, 0)
|
||||
if shape.ShapeType == 'Edge' and hasattr(shape.Curve, 'Center'):
|
||||
return FreeCAD.Vector(shape.Curve.Center.x, shape.Curve.Center.y, 0)
|
||||
|
||||
if shape.ShapeType == 'Face':
|
||||
if hasattr(shape.Surface, 'Center'):
|
||||
return FreeCAD.Vector(shape.Surface.Center.x, shape.Surface.Center.y, 0)
|
||||
if len(shape.Edges) == 1 and type(shape.Edges[0].Curve) == Part.Circle:
|
||||
return shape.Edges[0].Curve.Center
|
||||
if shape.ShapeType == 'Face':
|
||||
if hasattr(shape.Surface, 'Center'):
|
||||
return FreeCAD.Vector(shape.Surface.Center.x, shape.Surface.Center.y, 0)
|
||||
if len(shape.Edges) == 1 and type(shape.Edges[0].Curve) == Part.Circle:
|
||||
return shape.Edges[0].Curve.Center
|
||||
except Part.OCCError as e:
|
||||
PathLog.error(e)
|
||||
|
||||
PathLog.error(translate("Path", "Feature %s.%s cannot be processed as a circular hole - please remove from Base geometry list.") % (base.Label, sub))
|
||||
return None
|
||||
@@ -181,7 +189,6 @@ class ObjectOp(PathOp.ObjectOp):
|
||||
calculated and assigned.
|
||||
Do not overwrite, implement circularHoleExecute(obj, holes) instead.'''
|
||||
PathLog.track()
|
||||
PathLog.debug("\nopExecute() in PathCircularHoleBase.py")
|
||||
|
||||
holes = []
|
||||
baseSubsTuples = []
|
||||
@@ -239,7 +246,7 @@ class ObjectOp(PathOp.ObjectOp):
|
||||
|
||||
# Complete rotational analysis and temp clone creation as needed
|
||||
if obj.EnableRotation == 'Off':
|
||||
PathLog.info("Enable Rotation setting is 'Off' for {}.".format(obj.Name))
|
||||
PathLog.debug("Enable Rotation setting is 'Off' for {}.".format(obj.Name))
|
||||
stock = PathUtils.findParentJob(obj).Stock
|
||||
for (base, subList) in obj.Base:
|
||||
baseSubsTuples.append((base, subList, 0.0, 'A', stock))
|
||||
@@ -361,6 +368,8 @@ class ObjectOp(PathOp.ObjectOp):
|
||||
pass # pylint: disable=unnecessary-pass
|
||||
|
||||
def findAllHoles(self, obj):
|
||||
'''findAllHoles(obj) ... find all holes of all base models and assign as features.'''
|
||||
PathLog.track()
|
||||
if not self.getJob(obj):
|
||||
return
|
||||
features = []
|
||||
|
||||
@@ -81,7 +81,8 @@ class TaskPanelHoleGeometryPage(PathOpGui.TaskPanelBaseGeometryPage):
|
||||
item.setData(self.DataObjectSub, sub)
|
||||
self.form.baseList.setItem(self.form.baseList.rowCount()-1, 0, item)
|
||||
|
||||
item = QtGui.QTableWidgetItem("{:.3f}".format(obj.Proxy.holeDiameter(obj, base, sub)))
|
||||
dia = obj.Proxy.holeDiameter(obj, base, sub)
|
||||
item = QtGui.QTableWidgetItem("{:.3f}".format(dia))
|
||||
item.setData(self.DataFeatureName, name)
|
||||
item.setData(self.DataObject, base)
|
||||
item.setData(self.DataObjectSub, sub)
|
||||
|
||||
@@ -71,6 +71,10 @@ class ObjectHelix(PathCircularHoleBase.ObjectOp):
|
||||
obj.addProperty("App::PropertyEnumeration", "EnableRotation", "Rotation", QtCore.QT_TRANSLATE_NOOP("App::Property", "Enable rotation to gain access to pockets/areas not normal to Z axis."))
|
||||
obj.EnableRotation = ['Off', 'A(x)', 'B(y)', 'A & B']
|
||||
|
||||
def opOnDocumentRestored(self, obj):
|
||||
if not hasattr(obj, 'StartRadius'):
|
||||
obj.addProperty("App::PropertyLength", "StartRadius", "Helix Drill", translate("PathHelix", "Starting Radius"))
|
||||
|
||||
def circularHoleExecute(self, obj, holes):
|
||||
'''circularHoleExecute(obj, holes) ... generate helix commands for each hole in holes'''
|
||||
PathLog.track()
|
||||
|
||||
@@ -114,13 +114,17 @@ class ViewProvider:
|
||||
self.switch = None
|
||||
self.taskPanel = None
|
||||
self.vobj = None
|
||||
self.baseVisibility = None
|
||||
self.stockVisibility = None
|
||||
self.baseVisibility = {}
|
||||
self.stockVisibility = False
|
||||
|
||||
def attach(self, vobj):
|
||||
self.vobj = vobj
|
||||
self.obj = vobj.Object
|
||||
self.taskPanel = None
|
||||
if not hasattr(self, 'baseVisibility'):
|
||||
self.baseVisibility = {}
|
||||
if not hasattr(self, 'stockVisibility'):
|
||||
self.stockVisibility = False
|
||||
|
||||
# setup the axis display at the origin
|
||||
self.switch = coin.SoSwitch()
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
# ***************************************************************************
|
||||
|
||||
import FreeCAD
|
||||
import Part
|
||||
import Path
|
||||
import PathScripts.PathGeom as PathGeom
|
||||
import PathScripts.PathLog as PathLog
|
||||
@@ -215,6 +216,10 @@ class ObjectOp(object):
|
||||
if not hasattr(obj, 'OpStockZMax'):
|
||||
self.addOpValues(obj, ['stockz'])
|
||||
|
||||
if not hasattr(obj, 'EnableRotation'):
|
||||
obj.addProperty("App::PropertyEnumeration", "EnableRotation", "Rotation", QtCore.QT_TRANSLATE_NOOP("App::Property", "Enable rotation to gain access to pockets/areas not normal to Z axis."))
|
||||
obj.EnableRotation = ['Off', 'A(x)', 'B(y)', 'A & B']
|
||||
|
||||
self.setEditorModes(obj, features)
|
||||
self.opOnDocumentRestored(obj)
|
||||
|
||||
@@ -393,9 +398,13 @@ class ObjectOp(object):
|
||||
bb = base.Shape.BoundBox
|
||||
zmax = max(zmax, bb.ZMax)
|
||||
for sub in sublist:
|
||||
fbb = base.Shape.getElement(sub).BoundBox
|
||||
zmin = max(zmin, faceZmin(bb, fbb))
|
||||
zmax = max(zmax, fbb.ZMax)
|
||||
try:
|
||||
fbb = base.Shape.getElement(sub).BoundBox
|
||||
zmin = max(zmin, faceZmin(bb, fbb))
|
||||
zmax = max(zmax, fbb.ZMax)
|
||||
except Part.OCCError as e:
|
||||
PathLog.error(e)
|
||||
|
||||
else:
|
||||
# clearing with stock boundaries
|
||||
job = PathUtils.findParentJob(obj)
|
||||
|
||||
Reference in New Issue
Block a user