Draft: parametrize Draft vector utils precision (#20199)
* parametrize draft vector utils precision * fix: a single function didn't get the complete latest update. * compatibility: reintroduce DraftVecUtils.precision() as deprecated.
This commit is contained in:
@@ -35,11 +35,13 @@ but which can also be used in other workbenches and in macros.
|
||||
# flake8 --ignore=E226,E266,E401,W503
|
||||
|
||||
import math
|
||||
import warnings
|
||||
|
||||
import FreeCAD
|
||||
from FreeCAD import Vector
|
||||
from draftutils import params
|
||||
from draftutils import messages
|
||||
from draftutils.utils import precision as draft_precision
|
||||
|
||||
__title__ = "FreeCAD Draft Workbench - Vector library"
|
||||
__author__ = "Yorik van Havre, Werner Mayer, Martin Burbaum, Ken Cline"
|
||||
@@ -48,17 +50,28 @@ __url__ = "https://www.freecad.org"
|
||||
## \addtogroup DRAFTVECUTILS
|
||||
# @{
|
||||
|
||||
|
||||
# @deprecated("use Draft.precision() instead.")
|
||||
def precision():
|
||||
"""Get the number of decimal numbers used for precision.
|
||||
"""
|
||||
Get the number of fractional decimal digits as configured
|
||||
in Draft preferences.
|
||||
|
||||
This function is deprecated since it is a doublette of
|
||||
Draft.precision()
|
||||
|
||||
Returns
|
||||
-------
|
||||
int
|
||||
Return the number of decimal places set up in the preferences,
|
||||
or a standard value (6), if the parameter is missing.
|
||||
Return the number of fractional decimal digits as configured
|
||||
in Draft preferences.
|
||||
"""
|
||||
return params.get_param("precision")
|
||||
warnings.warn("Call to deprecated function 'DraftVecUtils.precision()'."
|
||||
+ " Please consider using Draft.precision().",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
messages._wrn("DraftVecUtils.precision() called, which is deprecated."
|
||||
+ " Please consider using Draft.precision(). ")
|
||||
|
||||
return draft_precision()
|
||||
|
||||
|
||||
def typecheck(args_and_types, name="?"):
|
||||
@@ -177,7 +190,7 @@ def neg(u):
|
||||
return Vector(-u.x, -u.y, -u.z)
|
||||
|
||||
|
||||
def equals(u, v):
|
||||
def equals(u, v, precision=None):
|
||||
"""Check for equality between two vectors.
|
||||
|
||||
Due to rounding errors, two vectors will rarely be `equal`.
|
||||
@@ -191,10 +204,13 @@ def equals(u, v):
|
||||
|
||||
Parameters
|
||||
----------
|
||||
u : Base::Vector3
|
||||
The first vector.
|
||||
v : Base::Vector3
|
||||
The second vector.
|
||||
u : Base::Vector3
|
||||
The first vector.
|
||||
v : Base::Vector3
|
||||
The second vector.
|
||||
precision : int | None
|
||||
mathematical precision - if None use configured draft
|
||||
precision
|
||||
|
||||
Returns
|
||||
-------
|
||||
@@ -202,7 +218,7 @@ def equals(u, v):
|
||||
`True` if the vectors are within the precision, `False` otherwise.
|
||||
"""
|
||||
typecheck([(u, Vector), (v, Vector)], "equals")
|
||||
return isNull(u.sub(v))
|
||||
return isNull(u.sub(v), precision)
|
||||
|
||||
|
||||
def scale(u, scalar):
|
||||
@@ -525,19 +541,22 @@ def getRotation(vector, reference=Vector(1, 0, 0)):
|
||||
return (c.x, c.y, c.z, Q)
|
||||
|
||||
|
||||
def isNull(vector):
|
||||
def isNull(vector, precision=None):
|
||||
"""Return False if each of the components of the vector is zero.
|
||||
|
||||
Due to rounding errors, an element is probably never going to be
|
||||
exactly zero. Therefore, it rounds the element by the number
|
||||
of decimals specified in the `precision` parameter
|
||||
in the parameter database, accessed through `FreeCAD.ParamGet()`.
|
||||
It then compares the rounded numbers against zero.
|
||||
of decimals specified in the `precision` parameter - if `precision`
|
||||
is not set or set to None configured Draft precision is used.
|
||||
It then compares the rounded coordinates against zero.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
vector : Base::Vector3
|
||||
The tested vector.
|
||||
precision : int | None
|
||||
mathematical precision - if None use configured draft
|
||||
precision
|
||||
|
||||
Returns
|
||||
-------
|
||||
@@ -545,14 +564,15 @@ def isNull(vector):
|
||||
`True` if each of the elements is zero within the precision.
|
||||
`False` otherwise.
|
||||
"""
|
||||
p = precision()
|
||||
x = round(vector.x, p)
|
||||
y = round(vector.y, p)
|
||||
z = round(vector.z, p)
|
||||
if precision is None:
|
||||
precision = params.get_param("precision")
|
||||
x = round(vector.x, precision)
|
||||
y = round(vector.y, precision)
|
||||
z = round(vector.z, precision)
|
||||
return (x == 0 and y == 0 and z == 0)
|
||||
|
||||
|
||||
def find(vector, vlist):
|
||||
def find(vector, vlist, precision=None):
|
||||
"""Find a vector in a list of vectors, and return the index.
|
||||
|
||||
Finding a vector tests for `equality` which depends on the `precision`
|
||||
@@ -564,10 +584,13 @@ def find(vector, vlist):
|
||||
The tested vector.
|
||||
vlist : list
|
||||
A list of Base::Vector3 vectors.
|
||||
precision : int | None
|
||||
mathematical precision - if None use configured draft
|
||||
precision
|
||||
|
||||
Returns
|
||||
-------
|
||||
int
|
||||
int | None
|
||||
The index of the list where the vector is found,
|
||||
or `None` if the vector is not found.
|
||||
|
||||
@@ -577,7 +600,7 @@ def find(vector, vlist):
|
||||
"""
|
||||
typecheck([(vector, Vector), (vlist, list)], "find")
|
||||
for i, v in enumerate(vlist):
|
||||
if equals(vector, v):
|
||||
if equals(vector, v, precision):
|
||||
return i
|
||||
return None
|
||||
|
||||
@@ -628,7 +651,7 @@ def closest(vector, vlist, return_length=False):
|
||||
return index
|
||||
|
||||
|
||||
def isColinear(vlist):
|
||||
def isColinear(vlist, precision=None):
|
||||
"""Check if the vectors in the list are colinear.
|
||||
|
||||
Colinear vectors are those whose angle between them is zero.
|
||||
@@ -655,6 +678,9 @@ def isColinear(vlist):
|
||||
vlist : list
|
||||
List of Base::Vector3 vectors.
|
||||
At least three elements must be present.
|
||||
precision : int | None
|
||||
mathematical precision - if None use configured draft
|
||||
precision
|
||||
|
||||
Returns
|
||||
-------
|
||||
@@ -676,8 +702,8 @@ def isColinear(vlist):
|
||||
# This doesn't test for colinearity between the first two vectors.
|
||||
if len(vlist) < 3:
|
||||
return True
|
||||
|
||||
p = precision()
|
||||
if precision is None:
|
||||
precision = params.get_param("precision")
|
||||
|
||||
# Difference between the second vector and the first one
|
||||
first = vlist[1].sub(vlist[0])
|
||||
@@ -691,12 +717,12 @@ def isColinear(vlist):
|
||||
# The angle between the difference and the first difference.
|
||||
_angle = angle(diff, first)
|
||||
|
||||
if round(_angle, p) != 0:
|
||||
if round(_angle, precision) != 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def rounded(v,d=None):
|
||||
def rounded(v,precision=None):
|
||||
"""Return a vector rounded to the `precision` in the parameter database
|
||||
or to the given decimals value
|
||||
|
||||
@@ -705,9 +731,12 @@ def rounded(v,d=None):
|
||||
|
||||
Parameters
|
||||
----------
|
||||
v : Base::Vector3
|
||||
The input vector.
|
||||
d : (Optional) the number of decimals to round to
|
||||
v : Base::Vector3
|
||||
The input vector.
|
||||
precision : int | None
|
||||
mathematical precision - if None use configured draft
|
||||
precision
|
||||
|
||||
|
||||
Returns
|
||||
-------
|
||||
@@ -716,10 +745,9 @@ def rounded(v,d=None):
|
||||
to the number of decimals specified in the `precision` parameter
|
||||
in the parameter database.
|
||||
"""
|
||||
p = precision()
|
||||
if d:
|
||||
p = d
|
||||
return Vector(round(v.x, p), round(v.y, p), round(v.z, p))
|
||||
if precision is None:
|
||||
precision = params.get_param("precision")
|
||||
return Vector(round(v.x, precision), round(v.y, precision), round(v.z, precision))
|
||||
|
||||
|
||||
def getPlaneRotation(u, v, _ = None):
|
||||
@@ -766,7 +794,7 @@ def getPlaneRotation(u, v, _ = None):
|
||||
return m
|
||||
|
||||
|
||||
def removeDoubles(vlist):
|
||||
def removeDoubles(vlist, precision=None):
|
||||
"""Remove duplicated vectors from a list of vectors.
|
||||
|
||||
It removes only the duplicates that are next to each other in the list.
|
||||
@@ -784,9 +812,12 @@ def removeDoubles(vlist):
|
||||
|
||||
Parameters
|
||||
----------
|
||||
vlist : list of Base::Vector3
|
||||
List with vectors.
|
||||
|
||||
vlist : list of Base::Vector3
|
||||
List with vectors.
|
||||
precision : int | None
|
||||
mathematical precision - if None use configured draft
|
||||
precision
|
||||
|
||||
Returns
|
||||
-------
|
||||
list of Base::Vector3
|
||||
@@ -805,20 +836,23 @@ def removeDoubles(vlist):
|
||||
# Iterate until the penultimate element, and test for equality
|
||||
# with the element in front
|
||||
for i in range(len(vlist) - 1):
|
||||
if not equals(vlist[i], vlist[i+1]):
|
||||
if not equals(vlist[i], vlist[i+1], precision):
|
||||
nlist.append(vlist[i])
|
||||
# Add the last element
|
||||
nlist.append(vlist[-1])
|
||||
return nlist
|
||||
|
||||
def get_spherical_coords(x, y, z):
|
||||
def get_spherical_coords(x, y, z, precision=None):
|
||||
"""Get the Spherical coordinates of the vector represented
|
||||
by Cartesian coordinates (x, y, z).
|
||||
|
||||
Parameters
|
||||
----------
|
||||
vector : Base::Vector3
|
||||
The input vector.
|
||||
vector : Base::Vector3
|
||||
The input vector.
|
||||
precision : int | None
|
||||
mathematical precision - if None use configured draft
|
||||
precision
|
||||
|
||||
Returns
|
||||
-------
|
||||
@@ -836,13 +870,16 @@ def get_spherical_coords(x, y, z):
|
||||
(0, 0, z) -> (radius, theta, 0)
|
||||
"""
|
||||
|
||||
if precision is None:
|
||||
precision = params.get_param("precision")
|
||||
|
||||
v = Vector(x,y,z)
|
||||
x_axis = Vector(1,0,0)
|
||||
z_axis = Vector(0,0,1)
|
||||
y_axis = Vector(0,1,0)
|
||||
rad = v.Length
|
||||
|
||||
if not bool(round(rad, precision())):
|
||||
if not bool(round(rad, precision)):
|
||||
return (0, math.pi/2, 0)
|
||||
|
||||
theta = v.getAngle(z_axis)
|
||||
|
||||
Reference in New Issue
Block a user