diff --git a/src/Mod/Path/PathScripts/PathSurface.py b/src/Mod/Path/PathScripts/PathSurface.py index cfd552ca7b..277ccf4cad 100644 --- a/src/Mod/Path/PathScripts/PathSurface.py +++ b/src/Mod/Path/PathScripts/PathSurface.py @@ -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''' diff --git a/src/Mod/Path/PathScripts/PathSurfaceGui.py b/src/Mod/Path/PathScripts/PathSurfaceGui.py index d3bff733b7..ff72582b30 100644 --- a/src/Mod/Path/PathScripts/PathSurfaceGui.py +++ b/src/Mod/Path/PathScripts/PathSurfaceGui.py @@ -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) diff --git a/src/Mod/Path/PathScripts/PathSurfaceSupport.py b/src/Mod/Path/PathScripts/PathSurfaceSupport.py index b10b95d664..d7905ca7f5 100644 --- a/src/Mod/Path/PathScripts/PathSurfaceSupport.py +++ b/src/Mod/Path/PathScripts/PathSurfaceSupport.py @@ -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') diff --git a/src/Mod/Path/PathScripts/PathWaterline.py b/src/Mod/Path/PathScripts/PathWaterline.py index 2b48eb8887..3bb0960ab0 100644 --- a/src/Mod/Path/PathScripts/PathWaterline.py +++ b/src/Mod/Path/PathScripts/PathWaterline.py @@ -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() diff --git a/src/Mod/Path/PathScripts/PathWaterlineGui.py b/src/Mod/Path/PathScripts/PathWaterlineGui.py index 8ab8ea5698..a360ac6a77 100644 --- a/src/Mod/Path/PathScripts/PathWaterlineGui.py +++ b/src/Mod/Path/PathScripts/PathWaterlineGui.py @@ -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):