Draft: Add placement_from_points to geometry.py

Changed getPlacementFromPoints function in WorkingPlane.py to a compatibility function that calls placement_from_points.
This commit is contained in:
Roy-043
2023-08-23 11:17:17 +02:00
committed by GitHub
parent 5da3143f02
commit 649dde9808
4 changed files with 70 additions and 52 deletions

View File

@@ -77,7 +77,8 @@ from draftgeoutils.geometry import (findPerpendicular,
calculatePlacement,
mirror,
are_coplanar,
is_straight_line)
is_straight_line,
placement_from_points)
from draftgeoutils.edges import (findEdge,
orientEdge,

View File

@@ -40,6 +40,7 @@ import lazy_loader.lazy_loader as lz
import FreeCAD
import DraftVecUtils
from FreeCAD import Vector
from draftutils import utils
from draftutils.translate import translate
DraftGeomUtils = lz.LazyLoader("DraftGeomUtils", globals(), "DraftGeomUtils")
@@ -1312,53 +1313,14 @@ class Plane:
plane = Plane
# Compatibility function:
def getPlacementFromPoints(points):
"""Return a placement from a list of 3 or 4 points.
"""Return a placement from a list of 3 or 4 points. The 4th point is no longer used.
With these points a temporary `plane` is defined.
Then it returns the `Base::Placement` returned from `plane.getPlacement()`.
Parameters
----------
points : list of Base::Vector3
A list with 3 or 4 points to create a temporary plane
from which to extract the placement.
The first point is the plane's `position`.
The other two points are used to define the `u` and `v` axes,
as originating from the first point.
If the fourth point exists, it is used to define the plane's `axis`
as originating from the first point.
If no fourth point is provided, the cross product bewtween
the previously defined `u` and `v` is used as `axis`.
Return
------
Base::Placement
A placement obtained from the temporary plane
defined by `points`,
or `None` is it fails to use the points.
See Also
--------
getPlacement
Calls DraftGeomUtils.placement_from_points(). See there.
"""
pl = plane()
try:
pl.position = points[0]
pl.u = (points[1].sub(points[0]).normalize())
pl.v = (points[2].sub(points[0]).normalize())
if len(points) == 4:
pl.axis = (points[3].sub(points[0]).normalize())
else:
pl.axis = ((pl.u).cross(pl.v)).normalize()
except Exception:
return None
p = pl.getPlacement()
del pl
return p
utils.use_instead("DraftGeomUtils.placement_from_points")
return DraftGeomUtils.placement_from_points(*points[:3])
def getPlacementFromFace(face, rotated=False):

View File

@@ -517,6 +517,60 @@ def mirror(point, edge):
return None
def placement_from_points(pt_pos, pt_x, pt_y, as_vectors=False, tol=-1):
"""Return a placement from 3 points defining an origin, an X axis and a Y axis.
If the vectors calculated from the arguments are too short or parallel,
the returned placement will have a default rotation.
Parameters
----------
pt_pos : Base::Vector3
Origin (Base of Placement).
pt_x : Base::Vector3
Point on positive X axis. Or X axis vector if as_vectors is `True`.
pt_y : Base::Vector3
Point on positive Y axis. Or Y axis vector if as_vectors is `True`.
as_vectors : bool
If `True` treat pt_x and pt_y as axis vectors.
tol : float
Internal tolerance. 1e-7 is used if tol <=0.
See also:
---------
DraftVecUtils.getRotation
DraftGeomUtils.getRotation
Return
------
Base::Placement
"""
err = 1e-7 if tol <= 0 else tol
if as_vectors is False:
vec_u = pt_x - pt_pos
vec_v = pt_y - pt_pos
else:
vec_u = App.Vector(pt_x)
vec_v = App.Vector(pt_y)
if vec_u.Length < err or vec_v.Length < err:
rot = App.Rotation()
else:
vec_u.normalize()
vec_v.normalize()
if vec_u.isEqual(vec_v, err) \
or vec_u.isEqual(vec_v.negative(), err):
rot = App.Rotation()
else:
rot = App.Rotation(vec_u, vec_v, App.Vector(), "XYZ")
return App.Placement(pt_pos, rot)
#compatibility layer
getSplineNormal = get_spline_normal

View File

@@ -1267,7 +1267,6 @@ class boxTracker(Tracker):
def update(self, line=None, normal=None):
"""Update the tracker."""
import WorkingPlane
import DraftGeomUtils
if not normal:
normal = FreeCAD.DraftWorkingPlane.axis
@@ -1283,16 +1282,18 @@ class boxTracker(Tracker):
bp = self.baseline.Shape.Edges[0].Vertexes[0].Point
else:
return
right = lvec.cross(normal)
self.cube.width.setValue(lvec.Length)
p = WorkingPlane.getPlacementFromPoints([bp,
bp.add(lvec),
bp.add(right)])
if p:
self.trans.rotation.setValue(p.Rotation.Q)
bp = bp.add(lvec.multiply(0.5))
bp = bp.add(DraftVecUtils.scaleTo(normal, self.cube.depth.getValue()/2.0))
self.pos(bp)
tol = 1e-6
if lvec.Length > tol and normal.Length > tol:
lvec.normalize()
normal.normalize()
if not lvec.isEqual(normal, tol) \
and not lvec.isEqual(normal.negative(), tol):
rot = FreeCAD.Rotation(lvec, FreeCAD.Vector(), normal, "XZY")
self.trans.rotation.setValue(rot.Q)
def setRotation(self, rot):
"""Set the rotation."""