Expressions: Add Vector API expression functions (#10237)
This commit is contained in:
committed by
GitHub
parent
a49e104993
commit
8003606222
@@ -1757,6 +1757,7 @@ FunctionExpression::FunctionExpression(const DocumentObject *_owner, Function _f
|
||||
case TAN:
|
||||
case TANH:
|
||||
case TRUNC:
|
||||
case VNORMALIZE:
|
||||
if (args.size() != 1)
|
||||
ARGUMENT_THROW("exactly one required.");
|
||||
break;
|
||||
@@ -1774,6 +1775,12 @@ FunctionExpression::FunctionExpression(const DocumentObject *_owner, Function _f
|
||||
case MROTATEY:
|
||||
case MROTATEZ:
|
||||
case POW:
|
||||
case VANGLE:
|
||||
case VCROSS:
|
||||
case VDOT:
|
||||
case VSCALEX:
|
||||
case VSCALEY:
|
||||
case VSCALEZ:
|
||||
if (args.size() != 2)
|
||||
ARGUMENT_THROW("exactly two required.");
|
||||
break;
|
||||
@@ -1793,9 +1800,18 @@ FunctionExpression::FunctionExpression(const DocumentObject *_owner, Function _f
|
||||
ARGUMENT_THROW("exactly two, three, or four required.");
|
||||
break;
|
||||
case VECTOR:
|
||||
case VLINEDIST:
|
||||
case VLINESEGDIST:
|
||||
case VLINEPROJ:
|
||||
case VPLANEDIST:
|
||||
case VPLANEPROJ:
|
||||
if (args.size() != 3)
|
||||
ARGUMENT_THROW("exactly three required.");
|
||||
break;
|
||||
case VSCALE:
|
||||
if (args.size() != 4)
|
||||
ARGUMENT_THROW("exactly four required.");
|
||||
break;
|
||||
case MATRIX:
|
||||
if (args.size() > 16)
|
||||
ARGUMENT_THROW("exactly 16 or less required.");
|
||||
@@ -2101,6 +2117,36 @@ Py::Object FunctionExpression::translationMatrix(double x, double y, double z)
|
||||
return Py::asObject(new Base::MatrixPy(matrix));
|
||||
}
|
||||
|
||||
double FunctionExpression::extractLengthValueArgument(
|
||||
const Expression *expression,
|
||||
const std::vector<Expression*> &arguments,
|
||||
int argumentIndex
|
||||
)
|
||||
{
|
||||
Quantity argumentQuantity = pyToQuantity(arguments[argumentIndex]->getPyValue(), expression);
|
||||
|
||||
if (!(argumentQuantity.isDimensionlessOrUnit(Unit::Length))) {
|
||||
_EXPR_THROW("Unit must be either empty or a length.", expression);
|
||||
}
|
||||
|
||||
return argumentQuantity.getValue();
|
||||
}
|
||||
|
||||
Base::Vector3d FunctionExpression::extractVectorArgument(
|
||||
const Expression *expression,
|
||||
const std::vector<Expression*> &arguments,
|
||||
int argumentIndex
|
||||
)
|
||||
{
|
||||
Py::Object argument = arguments[argumentIndex]->getPyValue();
|
||||
|
||||
if (!PyObject_TypeCheck(argument.ptr(), &Base::VectorPy::Type)) {
|
||||
_EXPR_THROW("Argument must be a vector.", expression);
|
||||
}
|
||||
|
||||
return static_cast<Base::VectorPy*>(argument.ptr())->value();
|
||||
}
|
||||
|
||||
Py::Object FunctionExpression::evaluate(const Expression *expr, int f, const std::vector<Expression*> &args)
|
||||
{
|
||||
if(!expr || !expr->getOwner())
|
||||
@@ -2268,6 +2314,76 @@ Py::Object FunctionExpression::evaluate(const Expression *expr, int f, const std
|
||||
case HIDDENREF:
|
||||
case HREF:
|
||||
return args[0]->getPyValue();
|
||||
case VANGLE:
|
||||
case VCROSS:
|
||||
case VDOT:
|
||||
case VLINEDIST:
|
||||
case VLINESEGDIST:
|
||||
case VLINEPROJ:
|
||||
case VNORMALIZE:
|
||||
case VPLANEDIST:
|
||||
case VPLANEPROJ:
|
||||
case VSCALE:
|
||||
case VSCALEX:
|
||||
case VSCALEY:
|
||||
case VSCALEZ: {
|
||||
Base::Vector3d vector1 = extractVectorArgument(expr, args, 0);
|
||||
|
||||
switch (f) {
|
||||
case VNORMALIZE:
|
||||
return Py::asObject(new Base::VectorPy(vector1.Normalize()));
|
||||
case VSCALE: {
|
||||
double scaleX = extractLengthValueArgument(expr, args, 1);
|
||||
double scaleY = extractLengthValueArgument(expr, args, 2);
|
||||
double scaleZ = extractLengthValueArgument(expr, args, 3);
|
||||
vector1.Scale(scaleX, scaleY, scaleZ);
|
||||
return Py::asObject(new Base::VectorPy(vector1));
|
||||
}
|
||||
case VSCALEX: {
|
||||
double scaleX = extractLengthValueArgument(expr, args, 1);
|
||||
vector1.ScaleX(scaleX);
|
||||
return Py::asObject(new Base::VectorPy(vector1));
|
||||
}
|
||||
case VSCALEY: {
|
||||
double scaleY = extractLengthValueArgument(expr, args, 1);
|
||||
vector1.ScaleY(scaleY);
|
||||
return Py::asObject(new Base::VectorPy(vector1));
|
||||
}
|
||||
case VSCALEZ: {
|
||||
double scaleZ = extractLengthValueArgument(expr, args, 1);
|
||||
vector1.ScaleZ(scaleZ);
|
||||
return Py::asObject(new Base::VectorPy(vector1));
|
||||
}
|
||||
}
|
||||
|
||||
Base::Vector3d vector2 = extractVectorArgument(expr, args, 1);
|
||||
|
||||
switch (f) {
|
||||
case VANGLE:
|
||||
return Py::asObject(new QuantityPy(new Quantity(vector1.GetAngle(vector2) * 180 / M_PI, Unit::Angle)));
|
||||
case VCROSS:
|
||||
return Py::asObject(new Base::VectorPy(vector1.Cross(vector2)));
|
||||
case VDOT:
|
||||
return Py::Float(vector1.Dot(vector2));
|
||||
}
|
||||
|
||||
Base::Vector3d vector3 = extractVectorArgument(expr, args, 2);
|
||||
|
||||
switch (f) {
|
||||
case VLINEDIST:
|
||||
return Py::asObject(new QuantityPy(new Quantity(vector1.DistanceToLine(vector2, vector3), Unit::Length)));
|
||||
case VLINESEGDIST:
|
||||
return Py::asObject(new Base::VectorPy(vector1.DistanceToLineSegment(vector2, vector3)));
|
||||
case VLINEPROJ:
|
||||
vector1.ProjectToLine(vector2, vector3);
|
||||
return Py::asObject(new Base::VectorPy(vector1));
|
||||
case VPLANEDIST:
|
||||
return Py::asObject(new QuantityPy(new Quantity(vector1.DistanceToPlane(vector2, vector3), Unit::Length)));
|
||||
case VPLANEPROJ:
|
||||
vector1.ProjectToPlane(vector2, vector3);
|
||||
return Py::asObject(new Base::VectorPy(vector1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Py::Object e1 = args[0]->getPyValue();
|
||||
@@ -2623,6 +2739,32 @@ void FunctionExpression::_toString(std::ostream &ss, bool persistent,int) const
|
||||
ss << "tanh("; break;;
|
||||
case TRUNC:
|
||||
ss << "trunc("; break;;
|
||||
case VANGLE:
|
||||
ss << "vangle("; break;;
|
||||
case VCROSS:
|
||||
ss << "vcross("; break;;
|
||||
case VDOT:
|
||||
ss << "vdot("; break;;
|
||||
case VLINEDIST:
|
||||
ss << "vlinedist("; break;;
|
||||
case VLINESEGDIST:
|
||||
ss << "vlinesegdist("; break;;
|
||||
case VLINEPROJ:
|
||||
ss << "vlineproj("; break;;
|
||||
case VNORMALIZE:
|
||||
ss << "vnormalize("; break;;
|
||||
case VPLANEDIST:
|
||||
ss << "vplanedist("; break;;
|
||||
case VPLANEPROJ:
|
||||
ss << "vplaneproj("; break;;
|
||||
case VSCALE:
|
||||
ss << "vscale("; break;;
|
||||
case VSCALEX:
|
||||
ss << "vscalex("; break;;
|
||||
case VSCALEY:
|
||||
ss << "vscaley("; break;;
|
||||
case VSCALEZ:
|
||||
ss << "vscalez("; break;;
|
||||
case MINVERT:
|
||||
ss << "minvert("; break;;
|
||||
case MROTATE:
|
||||
@@ -3495,6 +3637,19 @@ static void initParser(const App::DocumentObject *owner)
|
||||
registered_functions["tan"] = FunctionExpression::TAN;
|
||||
registered_functions["tanh"] = FunctionExpression::TANH;
|
||||
registered_functions["trunc"] = FunctionExpression::TRUNC;
|
||||
registered_functions["vangle"] = FunctionExpression::VANGLE;
|
||||
registered_functions["vcross"] = FunctionExpression::VCROSS;
|
||||
registered_functions["vdot"] = FunctionExpression::VDOT;
|
||||
registered_functions["vlinedist"] = FunctionExpression::VLINEDIST;
|
||||
registered_functions["vlinesegdist"] = FunctionExpression::VLINESEGDIST;
|
||||
registered_functions["vlineproj"] = FunctionExpression::VLINEPROJ;
|
||||
registered_functions["vnormalize"] = FunctionExpression::VNORMALIZE;
|
||||
registered_functions["vplanedist"] = FunctionExpression::VPLANEDIST;
|
||||
registered_functions["vplaneproj"] = FunctionExpression::VPLANEPROJ;
|
||||
registered_functions["vscale"] = FunctionExpression::VSCALE;
|
||||
registered_functions["vscalex"] = FunctionExpression::VSCALEX;
|
||||
registered_functions["vscaley"] = FunctionExpression::VSCALEY;
|
||||
registered_functions["vscalez"] = FunctionExpression::VSCALEZ;
|
||||
|
||||
registered_functions["minvert"] = FunctionExpression::MINVERT;
|
||||
registered_functions["mrotate"] = FunctionExpression::MROTATE;
|
||||
|
||||
Reference in New Issue
Block a user