Merge pull request #3568 from Russ4262/3D_Surface_fixes_2

[Path] 3D Surface and Waterline: FinalDepth guess and `InternalFeaturesCut` fixes
This commit is contained in:
sliptonic
2020-06-19 11:10:14 -05:00
committed by GitHub
5 changed files with 101 additions and 36 deletions

View File

@@ -436,6 +436,17 @@ class ObjectSurface(PathOp.ObjectOp):
except Part.OCCError as e:
PathLog.error(e)
obj.OpFinalDepth = zmin
elif self.job:
if hasattr(obj, 'BoundBox'):
if obj.BoundBox == 'BaseBoundBox':
models = self.job.Model.Group
zmin = models[0].Shape.BoundBox.ZMin
for M in models:
zmin = min(zmin, M.Shape.BoundBox.ZMin)
obj.OpFinalDepth = zmin
if obj.BoundBox == 'Stock':
models = self.job.Stock
obj.OpFinalDepth = self.job.Stock.Shape.BoundBox.ZMin
def opExecute(self, obj):
'''opExecute(obj) ... process surface operation'''

View File

@@ -40,7 +40,7 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage):
'''Page controller class for the Surface operation.'''
def initPage(self, obj):
self.setTitle("3D Surface")
self.setTitle("3D Surface - " + obj.Label)
# self.updateVisibility()
# retrieve property enumerations
self.propEnums = PathSurface.ObjectSurface.opPropertyEnumerations(False)

View File

@@ -664,7 +664,9 @@ class ProcessSelectedFaces:
FUR.setTempGroup(self.tempGroup)
outFCS = FUR.getUnifiedRegions()
if not self.obj.InternalFeaturesCut:
ifL.extend(FUR.getInternalFeatures())
gIF = FUR.getInternalFeatures()
if gIF:
ifL.extend(gIF)
PathLog.debug('Attempting to get cross-section of collective faces.')
if len(outFCS) == 0:
@@ -740,7 +742,9 @@ class ProcessSelectedFaces:
if len(gUR) > 0:
outerFace = gUR[0]
if not self.obj.InternalFeaturesCut:
ifL = FUR.getInternalFeatures()
gIF = FUR.getInternalFeatures()
if gIF:
ifL = gIF
if outerFace:
PathLog.debug('Attempting to create offset face of Face{}'.format(fNum))
@@ -804,9 +808,13 @@ class ProcessSelectedFaces:
FUR = FindUnifiedRegions([(fcshp, fcIdx)], self.JOB.GeometryTolerance.Value)
if self.showDebugObjects:
FUR.setTempGroup(self.tempGroup)
outFCS.extend(FUR.getUnifiedRegions())
gUR = FUR.getUnifiedRegions()
if len(gUR) > 0:
outFCS.extend(gUR)
if not self.obj.InternalFeaturesCut:
intFEAT.extend(FUR.getInternalFeatures())
gIF = FUR.getInternalFeatures()
if gIF:
intFEAT.extend(gIF)
lenOtFcs = len(outFCS)
if lenOtFcs == 0:
@@ -1773,10 +1781,11 @@ class FindUnifiedRegions:
self.noSharedEdges = True
self.topWires = list()
self.REGIONS = list()
self.INTERNALS = False
self.INTERNALS = list()
self.idGroups = list()
self.sharedEdgeIdxs = list()
self.fusedFaces = None
self.internalsReady = False
if self.geomToler == 0.0:
self.geomToler = 0.00001
@@ -1807,37 +1816,43 @@ class FindUnifiedRegions:
cutBox.translate(FreeCAD.Vector(efBB.XMin - 1.0, efBB.YMin - 1.0, zHght))
base = ef.cut(cutBox)
# Identify top face of base
fIdx = 0
zMin = base.Faces[fIdx].BoundBox.ZMin
for bfi in range(0, len(base.Faces)):
fzmin = base.Faces[bfi].BoundBox.ZMin
if fzmin > zMin:
fIdx = bfi
zMin = fzmin
if base.Volume == 0:
PathLog.debug('Ignoring Face{}. It is likely vertical with no horizontal exposure.'.format(fcIdx))
cont = False
# Translate top face to Z=0.0 and save to topFaces list
topFace = base.Faces[fIdx]
# self._showShape(topFace, 'topFace_{}'.format(fNum))
tfBB = topFace.BoundBox
tfBB_Area = tfBB.XLength * tfBB.YLength
fBB_Area = fBB.XLength * fBB.YLength
if tfBB_Area < (fBB_Area * 0.9):
# attempt alternate methods
topFace = self._getCompleteCrossSection(ef)
if cont:
# Identify top face of base
fIdx = 0
zMin = base.Faces[fIdx].BoundBox.ZMin
for bfi in range(0, len(base.Faces)):
fzmin = base.Faces[bfi].BoundBox.ZMin
if fzmin > zMin:
fIdx = bfi
zMin = fzmin
# Translate top face to Z=0.0 and save to topFaces list
topFace = base.Faces[fIdx]
# self._showShape(topFace, 'topFace_{}'.format(fNum))
tfBB = topFace.BoundBox
tfBB_Area = tfBB.XLength * tfBB.YLength
# self._showShape(topFace, 'topFaceAlt_1_{}'.format(fNum))
fBB_Area = fBB.XLength * fBB.YLength
if tfBB_Area < (fBB_Area * 0.9):
topFace = getShapeSlice(ef)
# attempt alternate methods
topFace = self._getCompleteCrossSection(ef)
tfBB = topFace.BoundBox
tfBB_Area = tfBB.XLength * tfBB.YLength
# self._showShape(topFace, 'topFaceAlt_2_{}'.format(fNum))
# self._showShape(topFace, 'topFaceAlt_1_{}'.format(fNum))
if tfBB_Area < (fBB_Area * 0.9):
msg = translate('PathSurfaceSupport',
'Faild to extract processing region for Face')
FreeCAD.Console.PrintError(msg + '{}.\n'.format(fNum))
cont = False
topFace = getShapeSlice(ef)
tfBB = topFace.BoundBox
tfBB_Area = tfBB.XLength * tfBB.YLength
# self._showShape(topFace, 'topFaceAlt_2_{}'.format(fNum))
if tfBB_Area < (fBB_Area * 0.9):
msg = translate('PathSurfaceSupport',
'Faild to extract processing region for Face')
FreeCAD.Console.PrintError(msg + '{}.\n'.format(fNum))
cont = False
# Eif
if cont:
topFace.translate(FreeCAD.Vector(0.0, 0.0, 0.0 - zMin))
@@ -2157,7 +2172,6 @@ class FindUnifiedRegions:
# if True action here
if isTrue:
self.REGIONS[hi] = high.cut(low)
# self.INTERNALS.append(low)
remList.append(li)
else:
hold.append(hi)
@@ -2233,7 +2247,6 @@ class FindUnifiedRegions:
'''getUnifiedRegions()... Returns a list of unified regions from list
of tuples (faceShape, faceIndex) received at instantiation of the class object.'''
PathLog.debug('getUnifiedRegions()')
self.INTERNALS = list()
if len(self.FACES) == 0:
msg = translate('PathSurfaceSupport',
'No FACE data tuples received at instantiation of class.')
@@ -2255,6 +2268,7 @@ class FindUnifiedRegions:
for w in range(1, lenWrs):
wr = topFace.Wires[w]
self.INTERNALS.append(Part.Face(wr))
self.internalsReady = True
# Flatten face and extract outer wire, then convert to face
extWire = getExtrudedShape(topFace)
wCS = getCrossSection(extWire)
@@ -2281,7 +2295,17 @@ class FindUnifiedRegions:
if self.noSharedEdges:
PathLog.debug('No shared edges by length detected.')
return [topFace for (topFace, fcIdx) in self.topFaces]
allTopFaces = list()
for (topFace, fcIdx) in self.topFaces:
allTopFaces.append(topFace)
# Identify internal features
lenWrs = len(topFace.Wires)
if lenWrs > 1:
for w in range(1, lenWrs):
wr = topFace.Wires[w]
self.INTERNALS.append(Part.Face(wr))
self.internalsReady = True
return allTopFaces
else:
# Delete shared edges from edgeData list
self.sharedEdgeIdxs.sort(reverse=True)
@@ -2294,13 +2318,18 @@ class FindUnifiedRegions:
# for ri in range(0, len(self.REGIONS)):
# self._showShape(self.REGIONS[ri], 'UnifiedRegion_{}'.format(ri))
self.internalsReady = True
return self.REGIONS
def getInternalFeatures(self):
'''getInternalFeatures()... Returns internal features identified
after calling getUnifiedRegions().'''
if self.INTERNALS:
return self.INTERNALS
if self.internalsReady:
if len(self.INTERNALS) > 0:
return self.INTERNALS
else:
return False
msg = translate('PathSurfaceSupport',
'getUnifiedRegions() must be called before getInternalFeatures().')
FreeCAD.Console.PrintError(msg + '\n')

View File

@@ -406,6 +406,31 @@ class ObjectWaterline(PathOp.ObjectOp):
obj.AvoidLastX_Faces = 100
PathLog.error(translate('PathWaterline', 'AvoidLastX_Faces: Avoid last X faces count limited to 100.'))
def opUpdateDepths(self, obj):
if hasattr(obj, 'Base') and obj.Base:
base, sublist = obj.Base[0]
fbb = base.Shape.getElement(sublist[0]).BoundBox
zmin = fbb.ZMax
for base, sublist in obj.Base:
for sub in sublist:
try:
fbb = base.Shape.getElement(sub).BoundBox
zmin = min(zmin, fbb.ZMin)
except Part.OCCError as e:
PathLog.error(e)
obj.OpFinalDepth = zmin
elif self.job:
if hasattr(obj, 'BoundBox'):
if obj.BoundBox == 'BaseBoundBox':
models = self.job.Model.Group
zmin = models[0].Shape.BoundBox.ZMin
for M in models:
zmin = min(zmin, M.Shape.BoundBox.ZMin)
obj.OpFinalDepth = zmin
if obj.BoundBox == 'Stock':
models = self.job.Stock
obj.OpFinalDepth = self.job.Stock.Shape.BoundBox.ZMin
def opExecute(self, obj):
'''opExecute(obj) ... process surface operation'''
PathLog.track()

View File

@@ -41,7 +41,7 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage):
'''Page controller class for the Waterline operation.'''
def initPage(self, obj):
# self.setTitle("Waterline")
self.setTitle("Waterline - " + obj.Label)
self.updateVisibility()
def getForm(self):