Draft: Add edge-face intersection snap

This commit is contained in:
Roy-043
2025-08-25 13:56:17 +02:00
committed by Yorik van Havre
parent f3c675ed5b
commit e4d6b9a31d
3 changed files with 41 additions and 26 deletions

View File

@@ -150,8 +150,11 @@ def findIntersection(edge1, edge2,
return [] # bound boxes don't intersect
# First, try to use Shape.section if possible
if (dts and isinstance(edge1, Part.Edge) and isinstance(edge2, Part.Edge)
and (not infinite1) and (not infinite2)):
if dts \
and ((isinstance(edge1, Part.Edge) and isinstance(edge2, (Part.Edge, Part.Face)))
or (isinstance(edge1, (Part.Edge, Part.Face)) and isinstance(edge2, Part.Edge))) \
and (not infinite1) \
and (not infinite2):
return [v.Point for v in edge1.section((edge2), tol).Vertexes]
pt1 = None

View File

@@ -96,6 +96,7 @@ class Snapper:
self.cursorMode = None
self.cursorQt = None
self.maxEdges = params.get_param("maxSnapEdges")
self.maxFaces = params.get_param("maxSnapFaces")
# we still have no 3D view when the draft module initializes
self.tracker = None
@@ -407,6 +408,7 @@ class Snapper:
face = shape
snaps.extend(self.snapToNearFace(face, point))
snaps.extend(self.snapToPerpendicularFace(face, lastpoint))
snaps.extend(self.snapToIntersection(face))
snaps.extend(self.snapToCenterFace(face))
elif "Vertex" in comp:
# we are snapping to a vertex
@@ -1021,30 +1023,39 @@ class Snapper:
snaps = []
if self.isEnabled("Intersection"):
# get the stored objects to calculate intersections
for o in self.lastObj:
obj = App.ActiveDocument.getObject(o)
if obj:
if obj.isDerivedFrom("Part::Feature") or (Draft.getType(obj) == "Axis"):
if (not self.maxEdges) or (len(obj.Shape.Edges) <= self.maxEdges):
for e in obj.Shape.Edges:
# get the intersection points
try:
if self.isEnabled("WorkingPlane") and hasattr(e,"Curve") and isinstance(e.Curve,(Part.Line,Part.LineSegment)) and hasattr(shape,"Curve") and isinstance(shape.Curve,(Part.Line,Part.LineSegment)):
# get apparent intersection (lines projected on WP)
p1 = self.toWP(e.Vertexes[0].Point)
p2 = self.toWP(e.Vertexes[-1].Point)
p3 = self.toWP(shape.Vertexes[0].Point)
p4 = self.toWP(shape.Vertexes[-1].Point)
pt = DraftGeomUtils.findIntersection(p1, p2, p3, p4, True, True)
else:
pt = DraftGeomUtils.findIntersection(e, shape)
if pt:
for p in pt:
snaps.append([p, 'intersection', self.toWP(p)])
except Exception:
pass
# some curve types yield an error
# when trying to read their types
for obj_name in self.lastObj:
obj = App.ActiveDocument.getObject(obj_name)
if obj and (obj.isDerivedFrom("Part::Feature") or (Draft.getType(obj) == "Axis")):
if (not self.maxFaces) or (len(obj.Shape.Faces) <= self.maxFaces):
for face in obj.Shape.Faces:
try:
pts = DraftGeomUtils.findIntersection(face, shape)
for pt in pts:
snaps.append([pt, "intersection", self.toWP(pt)])
except Exception:
pass
if (not self.maxEdges) or (len(obj.Shape.Edges) <= self.maxEdges):
for edge in obj.Shape.Edges:
try:
if self.isEnabled("WorkingPlane") \
and hasattr(edge, "Curve") \
and isinstance(edge.Curve,(Part.Line,Part.LineSegment)) \
and hasattr(shape, "Curve") \
and isinstance(shape.Curve,(Part.Line,Part.LineSegment)):
# get apparent intersection (lines projected on WP)
p1 = self.toWP(edge.Vertexes[0].Point)
p2 = self.toWP(edge.Vertexes[-1].Point)
p3 = self.toWP(shape.Vertexes[0].Point)
p4 = self.toWP(shape.Vertexes[-1].Point)
pts = DraftGeomUtils.findIntersection(p1, p2, p3, p4, True, True)
else:
pts = DraftGeomUtils.findIntersection(edge, shape)
for pt in pts:
snaps.append([pt, "intersection", self.toWP(pt)])
except Exception:
pass
# some curve types yield an error
# when trying to read their types
return snaps

View File

@@ -465,6 +465,7 @@ def _get_param_dictionary():
"LayersManagerWidth": ("int", 640),
"MakeFaceMode": ("bool", True),
"maxSnapEdges": ("int", 0),
"maxSnapFaces": ("int", 0),
"OffsetCopyMode": ("bool", False),
"Offset_OCC": ("bool", False),
"RelativeMode": ("bool", True),