Draft: Update the Plane class (step 2)
Related issue: #5603. Previous PRs: #10766 #10838 The remaining Plane class functions have been processed (some are unchanged): `setup` * Updated to use new functions. * The `direction` etc. arguments are never used AFAICT. * Added `from draftutils import gui_utils`. `reset` * Unchanged. `setTop` * Calls `super().set_to_top()`. That function does not use `align_to_point_and_axis` but specifies exact vectors for improved accuracy. * `import FreeCADGui` already happens at the top of the file. * The code block after `if FreeCAD.GuiUp:` was kept for now. `setFront` * Idem. `setSide` * This function sets the WP to the left side position, and not to the right side postion as in the Draft_SelectPlane command. * Idem. `getRotation` * Revised. * The function has an akward name as it returns a Placement. * The special code for Arch active container is obsolete (was already commented out in other functions). `getPlacement` * The `rotated argument` is ignored now. It was only used in the context of the old `placement_from_face` algorithm. See `DraftGeomUtils.placement_from_face` for the new implementation. * Calls `super().get_placement()`. `getNormal` * Basically unchanged. `setFromPlacement` * Revised to call `super()` functions. `inverse` * Unchanged. `save` * Unchanged. `restore` * More compact code, but basically unchanged. `getLocalCoords` * Calls `super().get_local_coords()` which does not rely on Draft code, but creates a matrix and returns `mtx.inverse().multVec(point)`. `getGlobalCoords` * Calls `super().get_global_coords()` which creates a matrix and returns `mtx.multVec(point)`. `getLocalRot` * Calls `super().get_local_coords()`. `getGlobalRot` * Calls `super().get_global_coords()`. `getClosestAxis` * Calls `super().get_closest_axis(vec)` which translates the vector to the WP coordinate system and then finds the closest axis by comparing the absolute coordinates of the vector. `isGlobal` * Not used anywhere AFAICT. * Calls `super().is_global()` which also checks the `position` attribute. * As before the function works without any tolerance. `isOrtho` * Not used anywhere AFAICT. * The original algorithm did not work properly (there was a comment). All angles were measured relative to the global Y axis. If the WP was randomly rotated around that axis the function would still return `True`. The new algorithm, `super().is_ortho()`, uses rounded Yaw, Pitch and Roll angles to check for orthogonality. `getDeviation` * Not used anywhere AFAICT. * Unchanged. `getParameters` * Calls `super().get_parameters()` which uses the local `_get_prop_list` function. `setFromParameters` * Calls `super().set_parameters()` which uses the local `_get_prop_list` function. `_get_prop_list` * Function used internally. Returns a list of attribute.
This commit is contained in:
@@ -40,6 +40,7 @@ import lazy_loader.lazy_loader as lz
|
||||
import FreeCAD
|
||||
import DraftVecUtils
|
||||
from FreeCAD import Vector
|
||||
from draftutils import gui_utils
|
||||
from draftutils import utils
|
||||
from draftutils.messages import _wrn
|
||||
from draftutils.translate import translate
|
||||
@@ -881,7 +882,7 @@ class Plane(PlaneBase):
|
||||
"""Set up the working plane if it exists but is undefined.
|
||||
|
||||
If `direction` and `point` are present,
|
||||
it calls `alignToPointAndAxis(point, direction, 0, upvec)`.
|
||||
it calls `align_to_point_and_axis(point, direction, 0, upvec)`.
|
||||
|
||||
Otherwise, it gets the camera orientation to define
|
||||
a working plane that is perpendicular to the current view,
|
||||
@@ -896,40 +897,26 @@ class Plane(PlaneBase):
|
||||
|
||||
Parameters
|
||||
----------
|
||||
direction : Base::Vector3, optional
|
||||
direction: Base.Vector, optional
|
||||
It defaults to `None`. It is the new `axis` of the plane.
|
||||
point : Base::Vector3, optional
|
||||
point: Base.Vector, optional
|
||||
It defaults to `None`. It is the new `position` of the plane.
|
||||
upvec : Base::Vector3, optional
|
||||
upvec: Base.Vector, optional
|
||||
It defaults to `None`. It is the new `v` orientation of the plane.
|
||||
force : Bool
|
||||
force: bool
|
||||
If True, it sets the plane even if the plane is not in weak mode
|
||||
|
||||
To do
|
||||
-----
|
||||
When the interface is not loaded it should fail and print
|
||||
a message, `_wrn()`.
|
||||
"""
|
||||
if self.weak or force:
|
||||
if direction and point:
|
||||
self.alignToPointAndAxis(point, direction, 0, upvec)
|
||||
if direction is not None and point is not None:
|
||||
super().align_to_point_and_axis(point, direction, 0, upvec)
|
||||
elif FreeCAD.GuiUp:
|
||||
try:
|
||||
import FreeCADGui
|
||||
from pivy import coin
|
||||
view = FreeCADGui.ActiveDocument.ActiveView
|
||||
camera = view.getCameraNode()
|
||||
rot = camera.getField("orientation").getValue()
|
||||
coin_up = coin.SbVec3f(0, 1, 0)
|
||||
upvec = Vector(rot.multVec(coin_up).getValue())
|
||||
vdir = view.getViewDirection()
|
||||
# don't change the plane if the axis and v vector
|
||||
# are already correct:
|
||||
tol = Part.Precision.angular()
|
||||
if abs(math.pi - vdir.getAngle(self.axis)) > tol \
|
||||
or abs(math.pi - upvec.getAngle(self.v)) > tol:
|
||||
self.alignToPointAndAxis(Vector(0, 0, 0),
|
||||
vdir.negative(), 0, upvec)
|
||||
view = gui_utils.get_3d_view()
|
||||
if view is not None:
|
||||
cam = view.getCameraNode()
|
||||
rot = FreeCAD.Rotation(*cam.getField("orientation").getValue().getValue())
|
||||
self.u, self.v, self.axis = self._axes_from_view_rotation(rot)
|
||||
self.position = Vector()
|
||||
except Exception:
|
||||
pass
|
||||
if force:
|
||||
@@ -938,17 +925,17 @@ class Plane(PlaneBase):
|
||||
self.weak = True
|
||||
|
||||
def reset(self):
|
||||
"""Reset the plane.
|
||||
"""Reset the WP.
|
||||
|
||||
Set `weak` to `True`.
|
||||
Sets the `weak` attribute to `True`.
|
||||
"""
|
||||
self.weak = True
|
||||
|
||||
def setTop(self):
|
||||
"""sets the WP to top position and updates the GUI"""
|
||||
self.alignToPointAndAxis(FreeCAD.Vector(0.0, 0.0, 0.0), FreeCAD.Vector(0, 0, 1), 0.0)
|
||||
"""Sets the WP to the top position and updates the GUI."""
|
||||
super().set_to_top()
|
||||
self.weak = False
|
||||
if FreeCAD.GuiUp:
|
||||
import FreeCADGui
|
||||
from draftutils.translate import translate
|
||||
if hasattr(FreeCADGui,"Snapper"):
|
||||
FreeCADGui.Snapper.setGrid()
|
||||
@@ -956,10 +943,10 @@ class Plane(PlaneBase):
|
||||
FreeCADGui.draftToolBar.wplabel.setText(translate("draft", "Top"))
|
||||
|
||||
def setFront(self):
|
||||
"""sets the WP to front position and updates the GUI"""
|
||||
self.alignToPointAndAxis(FreeCAD.Vector(0.0, 0.0, 0.0), FreeCAD.Vector(0, 1, 0), 0.0)
|
||||
"""Sets the WP to the front position and updates the GUI."""
|
||||
super().set_to_front()
|
||||
self.weak = False
|
||||
if FreeCAD.GuiUp:
|
||||
import FreeCADGui
|
||||
from draftutils.translate import translate
|
||||
if hasattr(FreeCADGui,"Snapper"):
|
||||
FreeCADGui.Snapper.setGrid()
|
||||
@@ -967,10 +954,17 @@ class Plane(PlaneBase):
|
||||
FreeCADGui.draftToolBar.wplabel.setText(translate("draft", "Front"))
|
||||
|
||||
def setSide(self):
|
||||
"""sets the WP to top position and updates the GUI"""
|
||||
self.alignToPointAndAxis(FreeCAD.Vector(0.0, 0.0, 0.0), FreeCAD.Vector(-1, 0, 0), 0.0)
|
||||
"""Sets the WP to the left side position and updates the GUI.
|
||||
|
||||
Note that set_to_side from the parent class sets the WP to the right side position.
|
||||
Which matches the Side option from Draft_SelectPlane.
|
||||
"""
|
||||
self.u = Vector(0, -1, 0)
|
||||
self.v = Vector(0, 0, 1)
|
||||
self.axis = Vector(-1, 0, 0)
|
||||
self.position = Vector()
|
||||
self.weak = False
|
||||
if FreeCAD.GuiUp:
|
||||
import FreeCADGui
|
||||
from draftutils.translate import translate
|
||||
if hasattr(FreeCADGui,"Snapper"):
|
||||
FreeCADGui.Snapper.setGrid()
|
||||
@@ -978,106 +972,32 @@ class Plane(PlaneBase):
|
||||
FreeCADGui.draftToolBar.wplabel.setText(translate("draft", "Side"))
|
||||
|
||||
def getRotation(self):
|
||||
"""Return a placement describing the plane orientation only.
|
||||
|
||||
If `FreeCAD.GuiUp` is `True`, that is, if the graphical interface
|
||||
is loaded, it will test if the active object is an `Arch` container
|
||||
and will calculate the placement accordingly.
|
||||
|
||||
Returns
|
||||
-------
|
||||
Base::Placement
|
||||
A placement, comprised of a `Base` (`Base::Vector3`),
|
||||
and a `Rotation` (`Base::Rotation`).
|
||||
"""
|
||||
m = DraftVecUtils.getPlaneRotation(self.u, self.v)
|
||||
p = FreeCAD.Placement(m)
|
||||
# Arch active container
|
||||
if FreeCAD.GuiUp:
|
||||
import FreeCADGui
|
||||
if FreeCADGui.ActiveDocument:
|
||||
view = FreeCADGui.ActiveDocument.ActiveView
|
||||
if view and hasattr(view,"getActiveOject"):
|
||||
a = view.getActiveObject("Arch")
|
||||
if a:
|
||||
p = a.Placement.inverse().multiply(p)
|
||||
return p
|
||||
"""Return a placement describing the WP orientation only."""
|
||||
return FreeCAD.Placement(Vector(), FreeCAD.Rotation(self.u, self.v, self.axis, "ZYX"))
|
||||
|
||||
def getPlacement(self, rotated=False):
|
||||
"""Return the placement of the plane.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
rotated : bool, optional
|
||||
It defaults to `False`. If it is `True`, it switches `axis`
|
||||
with `-v` to produce a rotated placement.
|
||||
|
||||
Returns
|
||||
-------
|
||||
Base::Placement
|
||||
A placement, comprised of a `Base` (`Base::Vector3`),
|
||||
and a `Rotation` (`Base::Rotation`).
|
||||
"""
|
||||
if rotated:
|
||||
m = DraftVecUtils.getPlaneRotation(self.u, self.axis)
|
||||
else:
|
||||
m = DraftVecUtils.getPlaneRotation(self.u, self.v)
|
||||
m.move(self.position)
|
||||
p = FreeCAD.Placement(m)
|
||||
# Arch active container if based on App Part
|
||||
# if FreeCAD.GuiUp:
|
||||
# import FreeCADGui
|
||||
# view = FreeCADGui.ActiveDocument.ActiveView
|
||||
# a = view.getActiveObject("Arch")
|
||||
# if a:
|
||||
# p = a.Placement.inverse().multiply(p)
|
||||
return p
|
||||
"""Return a placement calculated from the WP. The rotated argument is ignored."""
|
||||
return super().get_placement()
|
||||
|
||||
def getNormal(self):
|
||||
"""Return the normal vector of the plane (axis).
|
||||
"""Return the normal vector (axis) of the WP."""
|
||||
return self.axis
|
||||
|
||||
Returns
|
||||
-------
|
||||
Base::Vector3
|
||||
The `axis` attribute of the plane.
|
||||
"""
|
||||
n = self.axis
|
||||
# Arch active container if based on App Part
|
||||
# if FreeCAD.GuiUp:
|
||||
# import FreeCADGui
|
||||
# view = FreeCADGui.ActiveDocument.ActiveView
|
||||
# a = view.getActiveObject("Arch")
|
||||
# if a:
|
||||
# n = a.Placement.inverse().Rotation.multVec(n)
|
||||
return n
|
||||
|
||||
def setFromPlacement(self, pl, rebase=False):
|
||||
"""Set the plane from a placement.
|
||||
|
||||
It normally uses only the rotation, unless `rebase` is `True`.
|
||||
def setFromPlacement(self, place, rebase=False):
|
||||
"""Align the WP to a placement.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
pl : Base::Placement or Base::Matrix4D
|
||||
A placement, comprised of a `Base` (`Base::Vector3`),
|
||||
and a `Rotation` (`Base::Rotation`),
|
||||
or a `Base::Matrix4D` that defines a placement.
|
||||
rebase : bool, optional
|
||||
It defaults to `False`.
|
||||
If `True`, it will use `pl.Base` as the new `position`
|
||||
of the plane. Otherwise it will only consider `pl.Rotation`.
|
||||
|
||||
To do
|
||||
-----
|
||||
If `pl` is a `Base::Matrix4D`, it shouldn't try to use `pl.Base`
|
||||
because a matrix has no `Base`.
|
||||
place: Base.Placement
|
||||
Placement.
|
||||
rebase: bool, optional
|
||||
Defaults to `False`.
|
||||
If `False` the `position` of the WP is not changed.
|
||||
"""
|
||||
rot = FreeCAD.Placement(pl).Rotation
|
||||
self.u = rot.multVec(FreeCAD.Vector(1, 0, 0))
|
||||
self.v = rot.multVec(FreeCAD.Vector(0, 1, 0))
|
||||
self.axis = rot.multVec(FreeCAD.Vector(0, 0, 1))
|
||||
if rebase:
|
||||
self.position = pl.Base
|
||||
super().align_to_placement(place)
|
||||
else:
|
||||
super()._axes_from_rotation(place.Rotation)
|
||||
|
||||
def inverse(self):
|
||||
"""Invert the direction of the plane.
|
||||
@@ -1101,284 +1021,56 @@ class Plane(PlaneBase):
|
||||
Restores the attributes `u`, `v`, `axis`, `position` and `weak`
|
||||
from `stored`, and set `stored` to `None`.
|
||||
"""
|
||||
if self.stored:
|
||||
self.u = self.stored[0]
|
||||
self.v = self.stored[1]
|
||||
self.axis = self.stored[2]
|
||||
self.position = self.stored[3]
|
||||
self.weak = self.stored[4]
|
||||
if self.stored is not None:
|
||||
self.u, self.v, self.axis, self.position, self.weak = self.stored
|
||||
self.stored = None
|
||||
|
||||
def getLocalCoords(self, point):
|
||||
"""Return the coordinates of the given point, from the plane.
|
||||
|
||||
If the `point` was constructed using the plane as origin,
|
||||
return the relative coordinates from the `point` to the plane.
|
||||
|
||||
A vector is calculated from the plane's `position`
|
||||
to the external `point`, and this vector is projected onto
|
||||
each of the `u`, `v` and `axis` of the plane to determine
|
||||
the local, relative vector.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
point : Base::Vector3
|
||||
The point external to the plane.
|
||||
|
||||
Returns
|
||||
-------
|
||||
Base::Vector3
|
||||
The relative coordinates of the point from the plane.
|
||||
|
||||
See Also
|
||||
--------
|
||||
getGlobalCoords, getLocalRot, getGlobalRot
|
||||
|
||||
Notes
|
||||
-----
|
||||
The following graphic explains the coordinates.
|
||||
::
|
||||
g GlobalCoords (1, 11)
|
||||
|
|
||||
|
|
||||
|
|
||||
(n) p point (1, 6)
|
||||
| LocalCoords (1, 1)
|
||||
|
|
||||
----plane--------c-------- position (0, 5)
|
||||
|
||||
In the graphic
|
||||
|
||||
* `p` is an arbitrary point, external to the plane
|
||||
* `c` is the plane's `position`
|
||||
* `g` is the global coordinates of `p` when added to the plane
|
||||
* `n` is the relative coordinates of `p` when referred to the plane
|
||||
|
||||
To do
|
||||
-----
|
||||
Maybe a better name would be getRelativeCoords?
|
||||
"""Translate a point from the global coordinate system to
|
||||
the local (WP) coordinate system.
|
||||
"""
|
||||
pt = point.sub(self.position)
|
||||
xv = DraftVecUtils.project(pt, self.u)
|
||||
x = xv.Length
|
||||
# If the angle between the projection xv and u
|
||||
# is larger than 1 radian (57.29 degrees), use the negative
|
||||
# of the magnitude. Why exactly 1 radian?
|
||||
if xv.getAngle(self.u) > 1:
|
||||
x = -x
|
||||
yv = DraftVecUtils.project(pt, self.v)
|
||||
y = yv.Length
|
||||
if yv.getAngle(self.v) > 1:
|
||||
y = -y
|
||||
zv = DraftVecUtils.project(pt, self.axis)
|
||||
z = zv.Length
|
||||
if zv.getAngle(self.axis) > 1:
|
||||
z = -z
|
||||
return Vector(x, y, z)
|
||||
return super().get_local_coords(point)
|
||||
|
||||
def getGlobalCoords(self, point):
|
||||
"""Return the coordinates of the given point, added to the plane.
|
||||
|
||||
If the `point` was constructed using the plane as origin,
|
||||
return the absolute coordinates from the `point`
|
||||
to the global origin.
|
||||
|
||||
The `u`, `v`, and `axis` vectors scale the components of `point`,
|
||||
and the result is added to the planes `position`.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
point : Base::Vector3
|
||||
The external point.
|
||||
|
||||
Returns
|
||||
-------
|
||||
Base::Vector3
|
||||
The coordinates of the point from the absolute origin.
|
||||
|
||||
See Also
|
||||
--------
|
||||
getLocalCoords, getLocalRot, getGlobalRot
|
||||
|
||||
Notes
|
||||
-----
|
||||
The following graphic explains the coordinates.
|
||||
::
|
||||
g GlobalCoords (1, 11)
|
||||
|
|
||||
|
|
||||
|
|
||||
(n) p point (1, 6)
|
||||
| LocalCoords (1, 1)
|
||||
|
|
||||
----plane--------c-------- position (0, 5)
|
||||
|
||||
In the graphic
|
||||
|
||||
* `p` is an arbitrary point, external to the plane
|
||||
* `c` is the plane's `position`
|
||||
* `g` is the global coordinates of `p` when added to the plane
|
||||
* `n` is the relative coordinates of `p` when referred to the plane
|
||||
|
||||
"""Translate a point from the local (WP) coordinate system to
|
||||
the global coordinate system.
|
||||
"""
|
||||
vx = Vector(self.u).multiply(point.x)
|
||||
vy = Vector(self.v).multiply(point.y)
|
||||
vz = Vector(self.axis).multiply(point.z)
|
||||
pt = (vx.add(vy)).add(vz)
|
||||
return pt.add(self.position)
|
||||
return super().get_global_coords(point)
|
||||
|
||||
def getLocalRot(self, point):
|
||||
"""Like getLocalCoords, but doesn't use the plane's position.
|
||||
|
||||
If the `point` was constructed using the plane as origin,
|
||||
return the relative coordinates from the `point` to the plane.
|
||||
However, in this case, the plane is assumed to have its `position`
|
||||
at the global origin, therefore, the returned coordinates
|
||||
will only consider the orientation of the plane.
|
||||
|
||||
The external `point` is a vector, which is projected onto
|
||||
each of the `u`, `v` and `axis` of the plane to determine
|
||||
the local, relative vector.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
point : Base::Vector3
|
||||
The point external to the plane.
|
||||
|
||||
Returns
|
||||
-------
|
||||
Base::Vector3
|
||||
The relative coordinates of the point from the plane,
|
||||
if the plane had its `position` at the global origin.
|
||||
|
||||
See Also
|
||||
--------
|
||||
getLocalCoords, getGlobalCoords, getGlobalRot
|
||||
def getLocalRot(self, vec):
|
||||
"""Translate a vector from the global coordinate system to
|
||||
the local (WP) coordinate system.
|
||||
"""
|
||||
xv = DraftVecUtils.project(point, self.u)
|
||||
x = xv.Length
|
||||
if xv.getAngle(self.u) > 1:
|
||||
x = -x
|
||||
yv = DraftVecUtils.project(point, self.v)
|
||||
y = yv.Length
|
||||
if yv.getAngle(self.v) > 1:
|
||||
y = -y
|
||||
zv = DraftVecUtils.project(point, self.axis)
|
||||
z = zv.Length
|
||||
if zv.getAngle(self.axis) > 1:
|
||||
z = -z
|
||||
return Vector(x, y, z)
|
||||
return super().get_local_coords(vec, as_vector=True)
|
||||
|
||||
def getGlobalRot(self, point):
|
||||
"""Like getGlobalCoords, but doesn't use the plane's position.
|
||||
|
||||
If the `point` was constructed using the plane as origin,
|
||||
return the absolute coordinates from the `point`
|
||||
to the global origin.
|
||||
However, in this case, the plane is assumed to have its `position`
|
||||
at the global origin, therefore, the returned coordinates
|
||||
will only consider the orientation of the plane.
|
||||
|
||||
The `u`, `v`, and `axis` vectors scale the components of `point`.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
point : Base::Vector3
|
||||
The external point.
|
||||
|
||||
Returns
|
||||
-------
|
||||
Base::Vector3
|
||||
The coordinates of the point from the absolute origin.
|
||||
|
||||
See Also
|
||||
--------
|
||||
getGlobalCoords, getLocalCoords, getLocalRot
|
||||
def getGlobalRot(self, vec):
|
||||
"""Translate a vector from the local (WP) coordinate system to
|
||||
the global coordinate system.
|
||||
"""
|
||||
vx = Vector(self.u).multiply(point.x)
|
||||
vy = Vector(self.v).multiply(point.y)
|
||||
vz = Vector(self.axis).multiply(point.z)
|
||||
pt = (vx.add(vy)).add(vz)
|
||||
return pt
|
||||
return super().get_global_coords(vec, as_vector=True)
|
||||
|
||||
def getClosestAxis(self, point):
|
||||
"""Return the closest axis of the plane to the given point (vector).
|
||||
|
||||
It tests the angle that the `point` vector makes with the unit vectors
|
||||
`u`, `v`, and `axis`, as well their negatives.
|
||||
The smallest angle indicates the closest axis.
|
||||
def getClosestAxis(self, vec):
|
||||
"""Return the closest WP axis to a vector.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
point : Base::Vector3
|
||||
The external point to test.
|
||||
vec: Base.Vector
|
||||
Vector.
|
||||
|
||||
Returns
|
||||
-------
|
||||
str
|
||||
* It is `'x'` if the closest axis is `u` or `-u`.
|
||||
* It is `'y'` if the closest axis is `v` or `-v`.
|
||||
* It is `'z'` if the closest axis is `axis` or `-axis`.
|
||||
`'x'`, `'y'` or `'z'`.
|
||||
"""
|
||||
ax = point.getAngle(self.u)
|
||||
ay = point.getAngle(self.v)
|
||||
az = point.getAngle(self.axis)
|
||||
bx = point.getAngle(self.u.negative())
|
||||
by = point.getAngle(self.v.negative())
|
||||
bz = point.getAngle(self.axis.negative())
|
||||
b = min(ax, ay, az, bx, by, bz)
|
||||
if b in [ax, bx]:
|
||||
return "x"
|
||||
elif b in [ay, by]:
|
||||
return "y"
|
||||
elif b in [az, bz]:
|
||||
return "z"
|
||||
else:
|
||||
return None
|
||||
return super().get_closest_axis(vec)
|
||||
|
||||
def isGlobal(self):
|
||||
"""Return True if the plane axes are equal to the global axes.
|
||||
|
||||
Return `False` if any of `u`, `v`, or `axis` does not correspond
|
||||
to `+X`, `+Y`, or `+Z`, respectively.
|
||||
"""
|
||||
if self.u != Vector(1, 0, 0):
|
||||
return False
|
||||
if self.v != Vector(0, 1, 0):
|
||||
return False
|
||||
if self.axis != Vector(0, 0, 1):
|
||||
return False
|
||||
return True
|
||||
"""Return `True` if the WP matches the global coordinate system."""
|
||||
return super().is_global()
|
||||
|
||||
def isOrtho(self):
|
||||
"""Return True if the plane axes are orthogonal with the global axes.
|
||||
|
||||
Orthogonal means that the angle between `u` and the global axis `+Y`
|
||||
is a multiple of 90 degrees, meaning 0, -90, 90, -180, 180,
|
||||
-270, 270, or 360 degrees.
|
||||
And similarly for `v` and `axis`.
|
||||
All three axes should be orthogonal to the `+Y` axis.
|
||||
|
||||
Due to rounding errors, the angle difference is rounded
|
||||
to 6 decimal digits to do the test.
|
||||
|
||||
Returns
|
||||
-------
|
||||
bool
|
||||
Returns `True` if all three `u`, `v`, and `axis`
|
||||
are orthogonal with the global axis `+Y`.
|
||||
Otherwise it returns `False`.
|
||||
"""
|
||||
ortho = [0, -1.570796, 1.570796,
|
||||
-3.141593, 3.141593,
|
||||
-4.712389, 4.712389, 6.283185]
|
||||
# Shouldn't the angle difference be calculated with
|
||||
# the other global axes `+X` and `+Z` as well?
|
||||
if round(self.u.getAngle(Vector(0, 1, 0)), 6) in ortho:
|
||||
if round(self.v.getAngle(Vector(0, 1, 0)), 6) in ortho:
|
||||
if round(self.axis.getAngle(Vector(0, 1, 0)), 6) in ortho:
|
||||
return True
|
||||
return False
|
||||
"""Return `True` if the WP axes are orthogonal to the global axes."""
|
||||
return super().is_ortho()
|
||||
|
||||
def getDeviation(self):
|
||||
"""Return the angle between the u axis and the horizontal plane.
|
||||
@@ -1409,15 +1101,15 @@ class Plane(PlaneBase):
|
||||
|
||||
def getParameters(self):
|
||||
"""Return a dictionary with the data which define the plane:
|
||||
`u`, `v`, `axis`, `weak`.
|
||||
`u`, `v`, `axis`, `position`, `weak`.
|
||||
|
||||
Returns
|
||||
-------
|
||||
dict
|
||||
dictionary of the form:
|
||||
{"position":position, "u":x, "v":v, "axis":axis, "weak":weak}
|
||||
{"u":x, "v":v, "axis":axis, "position":position, "weak":weak}
|
||||
"""
|
||||
return {"position":self.position, "u":self.u, "v":self.v, "axis":self.axis, "weak":self.weak}
|
||||
return super().get_parameters()
|
||||
|
||||
def setFromParameters(self, data):
|
||||
"""Set the plane according to data.
|
||||
@@ -1426,15 +1118,16 @@ class Plane(PlaneBase):
|
||||
----------
|
||||
data: dict
|
||||
dictionary of the form:
|
||||
{"position":position, "u":x, "v":v, "axis":axis, "weak":weak}
|
||||
{"u":x, "v":v, "axis":axis, "position":position, "weak":weak}
|
||||
"""
|
||||
self.position = data["position"]
|
||||
self.u = data["u"]
|
||||
self.v = data["v"]
|
||||
self.axis = data["axis"]
|
||||
self.weak = data["weak"]
|
||||
super().set_parameters(data)
|
||||
|
||||
return None
|
||||
def _get_prop_list(self):
|
||||
return ["u",
|
||||
"v",
|
||||
"axis",
|
||||
"position",
|
||||
"weak"]
|
||||
|
||||
plane = Plane
|
||||
|
||||
|
||||
Reference in New Issue
Block a user