Merge pull request #23747 from tarman3/selectside

CAM: Path.Op.Area - Fix offer side
This commit is contained in:
Connor9220
2026-03-06 17:50:15 -05:00
committed by GitHub
+59 -23
View File
@@ -27,6 +27,7 @@ import Path
import Path.Op.Base as PathOp
import PathScripts.PathUtils as PathUtils
from Path.Geom import isRoughly
# lazily loaded modules
from lazy_loader.lazy_loader import LazyLoader
@@ -129,31 +130,18 @@ class ObjectOp(PathOp.ObjectOp):
changes.
Do not overwrite, overwrite areaOpOnChanged(obj, prop) instead."""
# Path.Log.track(obj.Label, prop)
if prop in ["AreaParams", "PathParams", "removalshape"]:
if prop in ("AreaParams", "PathParams", "removalshape"):
obj.setEditorMode(prop, 2)
if hasattr(obj, "Side") and prop == "Base" and len(obj.Base) == 1:
(base, subNames) = obj.Base[0]
bb = base.Shape.BoundBox # parent boundbox
if "Face" in subNames[0]:
face = base.Shape.getElement(subNames[0])
fbb = face.BoundBox # face boundbox
if bb.XLength == fbb.XLength and bb.YLength == fbb.YLength:
obj.Side = "Outside"
else:
obj.Side = "Inside"
elif "Edge" in subNames[0]:
edges = [
base.Shape.getElement(sub).copy() for sub in subNames if sub.startswith("Edge")
]
wire = Part.Wire(Part.__sortEdges__(edges))
wbb = wire.BoundBox # wire boundbox
if not wire.isClosed() or (bb.XLength == wbb.XLength and bb.YLength == wbb.YLength):
obj.Side = "Outside"
else:
obj.Side = "Inside"
if (
getattr(self, "init", False)
and hasattr(obj, "Side")
and prop == "FinalDepth"
and obj.Base
):
# Offer side only while creating new operation
self.init = False
self.opSetDefaultSide(obj)
self.areaOpOnChanged(obj, prop)
@@ -213,12 +201,60 @@ class ObjectOp(PathOp.ObjectOp):
)
self.areaOpSetDefaultValues(obj, job)
self.init = True # using for offer 'Side' while creating new operation
def areaOpSetDefaultValues(self, obj, job):
"""areaOpSetDefaultValues(obj, job) ... overwrite to set initial values of operation specific properties.
Can safely be overwritten by subclasses."""
pass
def opSetDefaultSide(self, obj):
"""setDefaltSide(obj) ... offer side while creating new operation"""
(base, subNames) = obj.Base[0]
# find parent boundbox
if isinstance(base.Shape, Part.Compound):
bbs = [shape.BoundBox for shape in base.Shape.SubShapes]
else:
bbs = [base.Shape.BoundBox]
subBb = None
if "Face" in subNames[0]:
faces = [base.Shape.getElement(sub) for sub in subNames if sub.startswith("Face")]
vFaces = [f for f in faces if not Path.Geom.isHorizontal(f)]
if vFaces:
# check if vertical faces creates a closed area
fzMin = min(e.BoundBox.ZMin for f in vFaces for e in f.Edges)
bottomEdges = [
e for f in vFaces for e in f.Edges if isRoughly(e.BoundBox.ZMax, fzMin)
]
wire = Part.Wire(Part.__sortEdges__(bottomEdges))
if not wire.isClosed():
# for open area always offer 'Outside'
obj.Side = "Outside"
return
shape = Part.Compound(faces)
subBb = shape.BoundBox
elif "Edge" in subNames[0]:
edges = [base.Shape.getElement(sub) for sub in subNames if sub.startswith("Edge")]
wire = Part.Wire(Part.__sortEdges__(edges))
if not wire.isClosed():
# for open wire always offer 'Outside'
obj.Side = "Outside"
return
else:
subBb = wire.BoundBox
if subBb:
for bb in bbs:
if not bb.isInside(subBb):
continue
if isRoughly(bb.XLength, subBb.XLength) and isRoughly(bb.YLength, subBb.YLength):
obj.Side = "Outside"
else:
obj.Side = "Inside"
return
def getMiddlePointLongestEdge(self, shape):
"""getMiddlePointLongestEdge(shape) ... return middle point of longest edge from shape."""
candidate = shape.Edges[0]