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:
@@ -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'''
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user