Draft: move working plane to vertex when pre-selected (#27979)

This commit is contained in:
Bojan Pejic
2026-03-08 11:53:13 +00:00
committed by GitHub
parent 35b77bc069
commit d68b0c087e
+117 -2
View File
@@ -243,6 +243,87 @@ class PlaneBase:
self.position = pos + (self.axis * offset)
return True
def align_to_straight_edge(self, edge, offset=0):
"""Align the WP to a straight edge.
Used when a single straight edge is selected and does not define a
plane. The edge direction becomes the WP `u` axis. All three axes are
recomputed using XZY priority so the result is always a valid
orthonormal frame.
Parameters
----------
edge: Part.Edge
A straight edge.
offset: float, optional
Defaults to zero.
Offset along the WP `axis`.
Returns
-------
`True`/`False`
`True` if successful.
"""
tol = 1e-7
if edge.Length <= tol:
return False
u = edge.derivative1At(edge.FirstParameter).normalize()
rot = FreeCAD.Rotation(u, self.v, self.axis, "XZY")
self.u, self.v, self.axis = self._axes_from_rotation(rot)
self.position = edge.Vertexes[0].Point + (self.axis * offset)
return True
def align_to_vertex(self, vertex, offset=0):
"""Move the WP origin to a vertex, keeping the current orientation.
Parameters
----------
vertex: Part.Vertex
A vertex.
offset: float, optional
Defaults to zero.
Offset along the WP `axis`.
Returns
-------
`True`
Always successful.
"""
self.position = vertex.Point + (self.axis * offset)
return True
def align_to_two_vertices(self, v1, v2, offset=0):
"""Align the WP to two vertices.
The direction from `v1` to `v2` defines the WP `u` axis. The `v` and
`axis` vectors are recomputed using XZY priority. The WP origin is set
to `v1`.
Parameters
----------
v1: Part.Vertex
First vertex (WP origin).
v2: Part.Vertex
Second vertex (defines u axis direction).
offset: float, optional
Defaults to zero.
Offset along the WP `axis`.
Returns
-------
`True`/`False`
`True` if successful.
"""
tol = 1e-7
u = v2.Point - v1.Point
if u.Length <= tol:
return False
u.normalize()
rot = FreeCAD.Rotation(u, self.v, self.axis, "XZY")
self.u, self.v, self.axis = self._axes_from_rotation(rot)
self.position = v1.Point + (self.axis * offset)
return True
def align_to_face(self, face, offset=0):
"""Align the WP to a face with an optional offset.
@@ -1286,7 +1367,13 @@ class PlaneGui(PlaneBase):
def align_to_selection(self, offset=0, _hist_add=True):
"""Align the WP to a selection with an optional offset.
The selection must define a plane.
For a single face the WP is aligned to that face. For a single curved
edge or wire the WP is aligned to the plane of that shape. For a
single straight edge the WP u-axis is aligned along the edge while the
WP axis (normal) is preserved. For a single vertex the WP origin is
moved to that point while the orientation is preserved. For two
vertices the direction from the first to the second defines the WP
u-axis; selection order matters.
Parameter
---------
@@ -1313,7 +1400,11 @@ class PlaneGui(PlaneBase):
if len(objs) != 1:
ret = False
if all(
if len(objs) == 2 and all(
obj[0].isNull() is False and obj[0].ShapeType == "Vertex" for obj in objs
):
ret = self.align_to_two_vertices(objs[0][0], objs[1][0], offset, _hist_add)
elif all(
[
obj[0].isNull() is False and obj[0].ShapeType in ["Edge", "Vertex"]
for obj in objs
@@ -1351,8 +1442,12 @@ class PlaneGui(PlaneBase):
ret = self.align_to_face(shape, offset, _hist_add)
elif shape.ShapeType == "Edge":
ret = self.align_to_edge_or_wire(shape, offset, _hist_add)
if ret is False:
ret = self.align_to_straight_edge(shape, offset, _hist_add)
elif shape.Solids:
ret = self.align_to_obj_placement(obj, offset, place, _hist_add)
elif shape.ShapeType == "Vertex":
ret = self.align_to_vertex(shape, offset, _hist_add)
else:
ret = self.align_to_edges_vertexes(shape.Vertexes, offset, _hist_add)
@@ -1388,6 +1483,26 @@ class PlaneGui(PlaneBase):
self._handle_custom(_hist_add)
return True
def align_to_straight_edge(self, edge, offset=0, _hist_add=True):
"""See PlaneBase.align_to_straight_edge."""
if super().align_to_straight_edge(edge, offset) is False:
return False
self._handle_custom(_hist_add)
return True
def align_to_vertex(self, vertex, offset=0, _hist_add=True):
"""See PlaneBase.align_to_vertex."""
super().align_to_vertex(vertex, offset)
self._handle_custom(_hist_add)
return True
def align_to_two_vertices(self, v1, v2, offset=0, _hist_add=True):
"""See PlaneBase.align_to_two_vertices."""
if super().align_to_two_vertices(v1, v2, offset) is False:
return False
self._handle_custom(_hist_add)
return True
def align_to_face(self, face, offset=0, _hist_add=True):
"""See PlaneBase.align_to_face."""
if super().align_to_face(face, offset) is False: