Arch: removing unnecessary 'if' conditional check
Fix for ArchRebar.py
@@ -361,7 +361,7 @@ public:
|
||||
* transactions, meaning that there are other transactions before the given
|
||||
* ID. The Gui component shall ask user if they want to undo multiple steps.
|
||||
* And if the user agrees, call undo(id) to unroll all transaction before
|
||||
* and including the the one with the give ID. Same applies for redo.
|
||||
* and including the one with the given ID. Same applies for redo.
|
||||
*
|
||||
* The new transaction ID describe here is fully backward compatible.
|
||||
* Calling the APIs with a default id=0 gives the original behavior.
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
# FreeCAD init module
|
||||
#
|
||||
# Gathering all the information to start FreeCAD.
|
||||
# This is the second of of three init scripts.
|
||||
# This is the second of three init scripts.
|
||||
# The third one runs when the gui is up,
|
||||
|
||||
# imports the one and only
|
||||
|
||||
@@ -35,7 +35,7 @@ depending on the actual extension object underlying this python
|
||||
object.
|
||||
|
||||
If 'val' is omitted, i.e. calling configLinkProperty(key,...), then
|
||||
it is assumed the the actually property name is the same as 'key'
|
||||
it is assumed that the actual property name is the same as 'key'
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
|
||||
@@ -423,7 +423,7 @@ static void linkConvert(bool unlink) {
|
||||
replaceObj = link;
|
||||
}
|
||||
|
||||
// adjust subname for the the new object
|
||||
// adjust subname for the new object
|
||||
auto pos = info.subname.rfind('.');
|
||||
if(pos==std::string::npos && pos)
|
||||
info.subname.clear();
|
||||
|
||||
@@ -43,37 +43,39 @@ void ExpressionBindingPy::init_type()
|
||||
behaviors().set_tp_new(PyMake);
|
||||
behaviors().readyType();
|
||||
|
||||
add_varargs_method("bind",&ExpressionBindingPy::bind,"Bind with an expression");
|
||||
add_varargs_method("isBound",&ExpressionBindingPy::isBound,"Check if already bound with an expression");
|
||||
add_varargs_method("apply",&ExpressionBindingPy::apply,"apply");
|
||||
add_varargs_method("hasExpression",&ExpressionBindingPy::hasExpression,"hasExpression");
|
||||
add_varargs_method("autoApply",&ExpressionBindingPy::autoApply,"autoApply");
|
||||
add_varargs_method("setAutoApply",&ExpressionBindingPy::setAutoApply,"setAutoApply");
|
||||
add_varargs_method("bind", &ExpressionBindingPy::bind, "Bind with an expression");
|
||||
add_varargs_method("isBound", &ExpressionBindingPy::isBound, "Check if already bound with an expression");
|
||||
add_varargs_method("apply", &ExpressionBindingPy::apply, "apply");
|
||||
add_varargs_method("hasExpression", &ExpressionBindingPy::hasExpression, "hasExpression");
|
||||
add_varargs_method("autoApply", &ExpressionBindingPy::autoApply, "autoApply");
|
||||
add_varargs_method("setAutoApply", &ExpressionBindingPy::setAutoApply, "setAutoApply");
|
||||
}
|
||||
|
||||
PyObject *ExpressionBindingPy::PyMake(struct _typeobject *, PyObject * args, PyObject *)
|
||||
{
|
||||
Py::Tuple tuple(args);
|
||||
PyObject* pyObj;
|
||||
if (!PyArg_ParseTuple(args, "O", &pyObj))
|
||||
return nullptr;
|
||||
|
||||
ExpressionBinding* expr = nullptr;
|
||||
PythonWrapper wrap;
|
||||
wrap.loadWidgetsModule();
|
||||
|
||||
QWidget* obj = dynamic_cast<QWidget*>(wrap.toQObject(tuple.getItem(0)));
|
||||
QWidget* obj = dynamic_cast<QWidget*>(wrap.toQObject(Py::Object(pyObj)));
|
||||
if (obj) {
|
||||
do {
|
||||
QuantitySpinBox* sb = qobject_cast<QuantitySpinBox*>(obj);
|
||||
if (sb) {
|
||||
expr = sb;
|
||||
QuantitySpinBox* qsb = qobject_cast<QuantitySpinBox*>(obj);
|
||||
if (qsb) {
|
||||
expr = qsb;
|
||||
break;
|
||||
}
|
||||
InputField* le = qobject_cast<InputField*>(obj);
|
||||
if (le) {
|
||||
expr = le;
|
||||
InputField* inp = qobject_cast<InputField*>(obj);
|
||||
if (inp) {
|
||||
expr = inp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while(false);
|
||||
while (false);
|
||||
}
|
||||
|
||||
if (!expr) {
|
||||
|
||||
@@ -187,7 +187,7 @@ public:
|
||||
/** partial rendering setup
|
||||
*
|
||||
* @param subelements: a list of dot separated string refer to the sub element
|
||||
* @param clear: if true, remove the the subelement from partial rendering.
|
||||
* @param clear: if true, remove the subelement from partial rendering.
|
||||
* If else, add the subelement for rendering.
|
||||
*
|
||||
* @return Return the number of subelement found
|
||||
|
||||
@@ -2128,7 +2128,7 @@ class ComponentTaskPanel:
|
||||
"New Property".
|
||||
ptype: str, optional
|
||||
The name of the property type the new property will be set as. If
|
||||
not specified, the the property's type will be determined using the
|
||||
not specified, the property's type will be determined using the
|
||||
idx parameter.
|
||||
"""
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ void TaskFemConstraint::setSelection(QListWidgetItem* item) {
|
||||
ItemName.erase(0, pos + delimiter.length());
|
||||
// clear existing selection
|
||||
Gui::Selection().clearSelection();
|
||||
// highligh the selected item
|
||||
// highlight the selected item
|
||||
Gui::Selection().addSelection(docName.c_str(), objName.c_str(), ItemName.c_str(), 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,21 +27,21 @@
|
||||
// (X0i,Y0i,Z0i) = (Xc,Yc,Zc) + s(L,M,N)
|
||||
// where s is the distance from (Xc,Yc,Zc) to (X0i,Y0i,Z0i) when (L,M,N) is
|
||||
// of unit length (normalized).
|
||||
// The distance between a cylinder surface point (Xi,Yi,Zi) and its
|
||||
// The distance between a cylinder surface point (Xi,Yi,Zi) and its
|
||||
// projection onto the axis (X0i,Y0i,Z0i) is the radius:
|
||||
// (Xi - X0i)^2 + (Yi - Y0i)^2 + (Zi - Z0i)^2 = R^2
|
||||
// Also the vector to a cylinder surface point (Xi,Yi,Zi) from its
|
||||
// Also the vector to a cylinder surface point (Xi,Yi,Zi) from its
|
||||
// projection onto the axis (X0i,Y0i,Z0i) is orthogonal to the axis so we can
|
||||
// write:
|
||||
// (Xi - X0i, Yi - Y0i, Zi - Z0i).(L,M,N) = 0 or
|
||||
// L(Xi - X0i) + M(Yi - Y0i) + N(Zi - Z0i) = 0
|
||||
// If we substitute these various equations into each other and further add
|
||||
// the constraint that L^2 + M^2 + N^2 = 1 then we can arrive at a single
|
||||
// If we substitute these various equations into each other and further add
|
||||
// the constraint that L^2 + M^2 + N^2 = 1 then we can arrive at a single
|
||||
// equation for the cylinder surface points:
|
||||
// (Xi - Xc + L*L*(Xc - Xi) + L*M*(Yc - Yi) + L*N*(Zc - Zi))^2 +
|
||||
// (Yi - Yc + M*L*(Xc - Xi) + M*M*(Yc - Yi) + M*N*(Zc - Zi))^2 +
|
||||
// (Zi - Zc + N*L*(Xc - Xi) + N*M*(Yc - Yi) + N*N*(Zc - Zi))^2 - R^2 = 0
|
||||
// This equation is what is used in the least squares solution below. Because
|
||||
// This equation is what is used in the least squares solution below. Because
|
||||
// we are constraining the direction vector to a unit length and also because
|
||||
// we need to stop the axis point from moving along the axis we need to fix one
|
||||
// of the ordinates in the solution. So from our initial approximations for the
|
||||
@@ -58,7 +58,7 @@
|
||||
#ifndef _PreComp_
|
||||
# include <algorithm>
|
||||
# include <cstdlib>
|
||||
# include <iterator>
|
||||
# include <iterator>
|
||||
#endif
|
||||
|
||||
#include "CylinderFit.h"
|
||||
@@ -226,7 +226,7 @@ void CylinderFit::ProjectToCylinder()
|
||||
}
|
||||
}
|
||||
|
||||
// Compute approximations for the parameters using all points by computing a
|
||||
// Compute approximations for the parameters using all points by computing a
|
||||
// line through the points. This doesn't work well if the points are only from
|
||||
// one small surface area.
|
||||
// In that case rather use SetApproximations() with a better estimate.
|
||||
@@ -430,8 +430,8 @@ void CylinderFit::setupNormalEquationMatrices(SolutionD solDir, const std::vecto
|
||||
atpa.setZero();
|
||||
atpl.setZero();
|
||||
|
||||
// For each point, setup the observation equation coefficients and add their
|
||||
// contribution into the the normal equation matrices
|
||||
// For each point, setup the observation equation coefficients and add their
|
||||
// contribution into the normal equation matrices
|
||||
double a[5], b[3];
|
||||
double f0, qw;
|
||||
std::vector< Base::Vector3d >::const_iterator vIt = residuals.begin();
|
||||
@@ -446,7 +446,7 @@ void CylinderFit::setupNormalEquationMatrices(SolutionD solDir, const std::vecto
|
||||
setLowerPart(atpa);
|
||||
}
|
||||
|
||||
// Sets up contributions of given observation to the quasi parameteric
|
||||
// Sets up contributions of given observation to the quasi parameteric
|
||||
// normal equation matrices. Assumes uncorrelated coordinates.
|
||||
// point ... point
|
||||
// residual ... residual for this point computed from previous iteration (zero for first iteration)
|
||||
@@ -456,13 +456,13 @@ void CylinderFit::setupNormalEquationMatrices(SolutionD solDir, const std::vecto
|
||||
// b[3] ... observation partials
|
||||
void CylinderFit::setupObservation(SolutionD solDir, const Base::Vector3f &point, const Base::Vector3d &residual, double a[5], double &f0, double &qw, double b[3]) const
|
||||
{
|
||||
// This adjustment requires an update of the observation approximations
|
||||
// This adjustment requires an update of the observation approximations
|
||||
// because the residuals do not have a linear relationship.
|
||||
// New estimates for the observations:
|
||||
double xEstimate = (double)point.x + residual.x;
|
||||
double yEstimate = (double)point.y + residual.y;
|
||||
double zEstimate = (double)point.z + residual.z;
|
||||
|
||||
|
||||
// intermediate parameters
|
||||
double lambda = _vAxis.x * (xEstimate - _vBase.x) + _vAxis.y * (yEstimate - _vBase.y) + _vAxis.z * (zEstimate - _vBase.z);
|
||||
double x0 = _vBase.x + lambda * _vAxis.x;
|
||||
@@ -493,7 +493,7 @@ void CylinderFit::setupObservation(SolutionD solDir, const Base::Vector3f &point
|
||||
ddzdm = -(_vAxis.y * _vAxis.z / _vAxis.x) * dx00 + _vAxis.z * dy00;
|
||||
ddxdn = -2.0 * _vAxis.z * dx00 - (_vAxis.y * _vAxis.z / _vAxis.x) * dy00 + (_vAxis.x - _vAxis.z * _vAxis.z / _vAxis.x) * dz00;
|
||||
ddydn = -(_vAxis.y * _vAxis.z / _vAxis.x) * dx00 + _vAxis.y * dz00;
|
||||
ddzdn = (_vAxis.x - _vAxis.z * _vAxis.z / _vAxis.x) * dx00 + _vAxis.y * dy00 + 2.0 * _vAxis.z * dz00;
|
||||
ddzdn = (_vAxis.x - _vAxis.z * _vAxis.z / _vAxis.x) * dx00 + _vAxis.y * dy00 + 2.0 * _vAxis.z * dz00;
|
||||
a[0] = -b[1];
|
||||
a[1] = -b[2];
|
||||
a[2] = 2.0 * (dx * ddxdm + dy * ddydm + dz * ddzdm);
|
||||
@@ -529,10 +529,10 @@ void CylinderFit::setupObservation(SolutionD solDir, const Base::Vector3f &point
|
||||
a[4] = -2.0 * _dRadius;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// free term
|
||||
f0 = _dRadius * _dRadius - dx * dx - dy * dy - dz * dz + b[0] * residual.x + b[1] * residual.y + b[2] * residual.z;
|
||||
|
||||
|
||||
// quasi weight (using equal weights for cylinder point coordinate observations)
|
||||
//w[0] = 1.0;
|
||||
//w[1] = 1.0;
|
||||
@@ -618,7 +618,7 @@ bool CylinderFit::computeResiduals(SolutionD solDir, const Eigen::VectorXd &x, s
|
||||
|
||||
//sigma0 += v.x * w[0] * v.x + v.y * w[1] * v.y + v.z * w[2] * v.z;
|
||||
sigma0 += v.x * v.x + v.y * v.y + v.z * v.z;
|
||||
|
||||
|
||||
if ((dVx > vConvLimit) || (dVy > vConvLimit) || (dVz > vConvLimit))
|
||||
vConverged = false;
|
||||
|
||||
@@ -650,7 +650,7 @@ bool CylinderFit::computeResiduals(SolutionD solDir, const Eigen::VectorXd &x, s
|
||||
|
||||
// Update the parameters after solving the normal equations
|
||||
bool CylinderFit::updateParameters(SolutionD solDir, const Eigen::VectorXd &x)
|
||||
{
|
||||
{
|
||||
// Update the parameters used as unknowns in the solution
|
||||
switch (solDir)
|
||||
{
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#ifndef _PreComp_
|
||||
# include <algorithm>
|
||||
# include <cstdlib>
|
||||
# include <iterator>
|
||||
# include <iterator>
|
||||
#endif
|
||||
|
||||
#include "SphereFit.h"
|
||||
@@ -130,8 +130,8 @@ void SphereFit::ProjectToSphere()
|
||||
Base::Vector3f& cPnt = *it;
|
||||
|
||||
// Compute unit vector from sphere centre to point.
|
||||
// Because this vector is orthogonal to the sphere's surface at the
|
||||
// intersection point we can easily compute the projection point on the
|
||||
// Because this vector is orthogonal to the sphere's surface at the
|
||||
// intersection point we can easily compute the projection point on the
|
||||
// closest surface point using the radius of the sphere
|
||||
Base::Vector3d diff((double)cPnt.x - _vCenter.x, (double)cPnt.y - _vCenter.y, (double)cPnt.z - _vCenter.z);
|
||||
double length = diff.Length();
|
||||
@@ -210,7 +210,7 @@ float SphereFit::Fit()
|
||||
|
||||
// Set up the quasi parameteric normal equations
|
||||
setupNormalEquationMatrices(residuals, atpa, atpl);
|
||||
|
||||
|
||||
// Solve the equations for the unknown corrections
|
||||
Eigen::LLT< Matrix4x4 > llt(atpa);
|
||||
if (llt.info() != Eigen::Success)
|
||||
@@ -256,8 +256,8 @@ void SphereFit::setupNormalEquationMatrices(const std::vector< Base::Vector3d >
|
||||
atpa.setZero();
|
||||
atpl.setZero();
|
||||
|
||||
// For each point, setup the observation equation coefficients and add their
|
||||
// contribution into the the normal equation matrices
|
||||
// For each point, setup the observation equation coefficients and add their
|
||||
// contribution into the normal equation matrices
|
||||
double a[4], b[3];
|
||||
double f0, qw;
|
||||
std::vector< Base::Vector3d >::const_iterator vIt = residuals.begin();
|
||||
@@ -272,7 +272,7 @@ void SphereFit::setupNormalEquationMatrices(const std::vector< Base::Vector3d >
|
||||
setLowerPart(atpa);
|
||||
}
|
||||
|
||||
// Sets up contributions of given observation to the quasi parameteric
|
||||
// Sets up contributions of given observation to the quasi parameteric
|
||||
// normal equation matrices. Assumes uncorrelated coordinates.
|
||||
// point ... point
|
||||
// residual ... residual for this point computed from previous iteration (zero for first iteration)
|
||||
@@ -282,7 +282,7 @@ void SphereFit::setupNormalEquationMatrices(const std::vector< Base::Vector3d >
|
||||
// b[3] ... observation partials
|
||||
void SphereFit::setupObservation(const Base::Vector3f &point, const Base::Vector3d &residual, double a[4], double &f0, double &qw, double b[3]) const
|
||||
{
|
||||
// This adjustment requires an update of the observation approximations
|
||||
// This adjustment requires an update of the observation approximations
|
||||
// because the residuals do not have a linear relationship.
|
||||
// New estimates for the observations:
|
||||
double xEstimate = (double)point.x + residual.x;
|
||||
@@ -393,7 +393,7 @@ bool SphereFit::computeResiduals(const Eigen::VectorXd &x, std::vector< Base::Ve
|
||||
|
||||
//sigma0 += v.x * w[0] * v.x + v.y * w[1] * v.y + v.z * w[2] * v.z;
|
||||
sigma0 += v.x * v.x + v.y * v.y + v.z * v.z;
|
||||
|
||||
|
||||
if ((dVx > vConvLimit) || (dVy > vConvLimit) || (dVz > vConvLimit))
|
||||
vConverged = false;
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
namespace MeshCore {
|
||||
|
||||
/**
|
||||
* Trim the the facets in 3D with a plane
|
||||
* Trim the facets in 3D with a plane
|
||||
* \author Werner Mayer
|
||||
*/
|
||||
class MeshExport MeshTrimByPlane
|
||||
|
||||
@@ -612,7 +612,7 @@ public:
|
||||
);
|
||||
add_keyword_method("getShape",&Module::getShape,
|
||||
"getShape(obj,subname=None,mat=None,needSubElement=False,transform=True,retType=0):\n"
|
||||
"Obtain the the TopoShape of a given object with SubName reference\n\n"
|
||||
"Obtain the TopoShape of a given object with SubName reference\n\n"
|
||||
"* obj: the input object\n"
|
||||
"* subname: dot separated sub-object reference\n"
|
||||
"* mat: the current transformation matrix\n"
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
<PythonExport
|
||||
Father="BoundedCurvePy"
|
||||
Name="BSplineCurvePy"
|
||||
Name="BSplineCurvePy"
|
||||
PythonName="Part.BSplineCurve"
|
||||
Twin="GeomBSplineCurve"
|
||||
TwinPointer="GeomBSplineCurve"
|
||||
Include="Mod/Part/App/Geometry.h"
|
||||
Namespace="Part"
|
||||
Twin="GeomBSplineCurve"
|
||||
TwinPointer="GeomBSplineCurve"
|
||||
Include="Mod/Part/App/Geometry.h"
|
||||
Namespace="Part"
|
||||
FatherInclude="Mod/Part/App/BoundedCurvePy.h"
|
||||
FatherNamespace="Part"
|
||||
Constructor="true">
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="Werner Mayer" EMail="wmayer@users.sourceforge.net" />
|
||||
<UserDocu>Describes a B-Spline curve in 3D space</UserDocu>
|
||||
</Documentation>
|
||||
FatherNamespace="Part"
|
||||
Constructor="true">
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="Werner Mayer" EMail="wmayer@users.sourceforge.net" />
|
||||
<UserDocu>Describes a B-Spline curve in 3D space</UserDocu>
|
||||
</Documentation>
|
||||
<Methode Name="__reduce__" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>__reduce__()
|
||||
@@ -23,446 +23,456 @@ Serialization of Part.BSplineCurve objects
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Attribute Name="Degree" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns the polynomial degree of this B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Degree" Type="Long"/>
|
||||
</Attribute>
|
||||
<Attribute Name="MaxDegree" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns the value of the maximum polynomial degree of any
|
||||
<Documentation>
|
||||
<UserDocu>Returns the polynomial degree of this B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Degree" Type="Long"/>
|
||||
</Attribute>
|
||||
<Attribute Name="MaxDegree" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns the value of the maximum polynomial degree of any
|
||||
B-Spline curve curve. This value is 25.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="MaxDegree" Type="Long"/>
|
||||
</Attribute>
|
||||
<Attribute Name="NbPoles" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns the number of poles of this B-Spline curve.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="NbPoles" Type="Long"/>
|
||||
</Attribute>
|
||||
<Attribute Name="NbKnots" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Returns the number of knots of this B-Spline curve.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="NbPoles" Type="Long"/>
|
||||
</Attribute>
|
||||
<Attribute Name="StartPoint" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns the start point of this B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="StartPoint" Type="Object"/>
|
||||
</Attribute>
|
||||
<Attribute Name="EndPoint" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns the end point of this B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="EndPoint" Type="Object"/>
|
||||
</Attribute>
|
||||
<Attribute Name="FirstUKnotIndex" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns the index in the knot array of the knot
|
||||
</Documentation>
|
||||
<Parameter Name="MaxDegree" Type="Long"/>
|
||||
</Attribute>
|
||||
<Attribute Name="NbPoles" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns the number of poles of this B-Spline curve.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="NbPoles" Type="Long"/>
|
||||
</Attribute>
|
||||
<Attribute Name="NbKnots" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Returns the number of knots of this B-Spline curve.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="NbPoles" Type="Long"/>
|
||||
</Attribute>
|
||||
<Attribute Name="StartPoint" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns the start point of this B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="StartPoint" Type="Object"/>
|
||||
</Attribute>
|
||||
<Attribute Name="EndPoint" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns the end point of this B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="EndPoint" Type="Object"/>
|
||||
</Attribute>
|
||||
<Attribute Name="FirstUKnotIndex" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns the index in the knot array of the knot
|
||||
corresponding to the first or last parameter
|
||||
of this B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="FirstUKnotIndex" Type="Object"/>
|
||||
</Attribute>
|
||||
<Attribute Name="LastUKnotIndex" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns the index in the knot array of the knot
|
||||
</Documentation>
|
||||
<Parameter Name="FirstUKnotIndex" Type="Object"/>
|
||||
</Attribute>
|
||||
<Attribute Name="LastUKnotIndex" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns the index in the knot array of the knot
|
||||
corresponding to the first or last parameter
|
||||
of this B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="LastUKnotIndex" Type="Object"/>
|
||||
</Attribute>
|
||||
<Attribute Name="KnotSequence" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns the knots sequence of this B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="KnotSequence" Type="List"/>
|
||||
</Attribute>
|
||||
</Documentation>
|
||||
<Parameter Name="LastUKnotIndex" Type="Object"/>
|
||||
</Attribute>
|
||||
<Attribute Name="KnotSequence" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns the knots sequence of this B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="KnotSequence" Type="List"/>
|
||||
</Attribute>
|
||||
<Methode Name="isRational" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Returns true if this B-Spline curve is rational.
|
||||
A B-Spline curve is rational if, at the time of construction,
|
||||
the weight table has been initialized.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Returns true if this B-Spline curve is rational.
|
||||
A B-Spline curve is rational if, at the time of construction,
|
||||
the weight table has been initialized.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="isPeriodic" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns true if this BSpline curve is periodic.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Documentation>
|
||||
<UserDocu>Returns true if this BSpline curve is periodic.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="isClosed" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Returns true if the distance between the start point and end point of
|
||||
this B-Spline curve is less than or equal to gp::Resolution().
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="increaseDegree">
|
||||
<Documentation>
|
||||
<UserDocu>increase(Int=Degree)
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Returns true if the distance between the start point and end point of
|
||||
this B-Spline curve is less than or equal to gp::Resolution().
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="increaseDegree">
|
||||
<Documentation>
|
||||
<UserDocu>increase(Int=Degree)
|
||||
Increases the degree of this B-Spline curve to Degree.
|
||||
As a result, the poles, weights and multiplicities tables
|
||||
are modified; the knots table is not changed. Nothing is
|
||||
done if Degree is less than or equal to the current degree.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="increaseMultiplicity">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
increaseMultiplicity(int index, int mult)
|
||||
increaseMultiplicity(int start, int end, int mult)
|
||||
Increases multiplicity of knots up to mult.
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="increaseMultiplicity">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
increaseMultiplicity(int index, int mult)
|
||||
increaseMultiplicity(int start, int end, int mult)
|
||||
Increases multiplicity of knots up to mult.
|
||||
|
||||
index: the index of a knot to modify (1-based)
|
||||
start, end: index range of knots to modify.
|
||||
If mult is lower or equal to the current multiplicity nothing is done. If mult is higher than the degree the degree is used.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="incrementMultiplicity">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
incrementMultiplicity(int start, int end, int mult)
|
||||
Raises multiplicity of knots by mult.
|
||||
index: the index of a knot to modify (1-based)
|
||||
start, end: index range of knots to modify.
|
||||
If mult is lower or equal to the current multiplicity nothing is done. If mult is higher than the degree the degree is used.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="incrementMultiplicity">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
incrementMultiplicity(int start, int end, int mult)
|
||||
Raises multiplicity of knots by mult.
|
||||
|
||||
start, end: index range of knots to modify.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="insertKnot">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
insertKnot(u, mult = 1, tol = 0.0)
|
||||
Inserts a knot value in the sequence of knots. If u is an existing knot the
|
||||
multiplicity is increased by mult. </UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="insertKnots">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
insertKnots(list_of_floats, list_of_ints, tol = 0.0, bool_add = True)
|
||||
Inserts a set of knots values in the sequence of knots.
|
||||
start, end: index range of knots to modify.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="insertKnot">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
insertKnot(u, mult = 1, tol = 0.0)
|
||||
Inserts a knot value in the sequence of knots. If u is an existing knot the
|
||||
multiplicity is increased by mult. </UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="insertKnots">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
insertKnots(list_of_floats, list_of_ints, tol = 0.0, bool_add = True)
|
||||
Inserts a set of knots values in the sequence of knots.
|
||||
|
||||
For each u = list_of_floats[i], mult = list_of_ints[i]
|
||||
For each u = list_of_floats[i], mult = list_of_ints[i]
|
||||
|
||||
If u is an existing knot the multiplicity is increased by mult if bool_add is
|
||||
True, otherwise increased to mult.
|
||||
If u is an existing knot the multiplicity is increased by mult if bool_add is
|
||||
True, otherwise increased to mult.
|
||||
|
||||
If u is not on the parameter range nothing is done.
|
||||
If u is not on the parameter range nothing is done.
|
||||
|
||||
If the multiplicity is negative or null nothing is done. The new multiplicity
|
||||
is limited to the degree.
|
||||
If the multiplicity is negative or null nothing is done. The new multiplicity
|
||||
is limited to the degree.
|
||||
|
||||
The tolerance criterion for knots equality is the max of Epsilon(U) and ParametricTolerance.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="removeKnot">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
removeKnot(Index, M, tol)
|
||||
The tolerance criterion for knots equality is the max of Epsilon(U) and ParametricTolerance.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="removeKnot">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
removeKnot(Index, M, tol)
|
||||
|
||||
Reduces the multiplicity of the knot of index Index to M.
|
||||
If M is equal to 0, the knot is removed.
|
||||
With a modification of this type, the array of poles is also modified.
|
||||
Two different algorithms are systematically used to compute the new
|
||||
poles of the curve. If, for each pole, the distance between the pole
|
||||
calculated using the first algorithm and the same pole calculated using
|
||||
the second algorithm, is less than Tolerance, this ensures that the curve
|
||||
is not modified by more than Tolerance. Under these conditions, true is
|
||||
returned; otherwise, false is returned.
|
||||
Reduces the multiplicity of the knot of index Index to M.
|
||||
If M is equal to 0, the knot is removed.
|
||||
With a modification of this type, the array of poles is also modified.
|
||||
Two different algorithms are systematically used to compute the new
|
||||
poles of the curve. If, for each pole, the distance between the pole
|
||||
calculated using the first algorithm and the same pole calculated using
|
||||
the second algorithm, is less than Tolerance, this ensures that the curve
|
||||
is not modified by more than Tolerance. Under these conditions, true is
|
||||
returned; otherwise, false is returned.
|
||||
|
||||
A low tolerance is used to prevent modification of the curve.
|
||||
A high tolerance is used to 'smooth' the curve.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="segment">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
segment(u1,u2)
|
||||
Modifies this B-Spline curve by segmenting it.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setKnot">
|
||||
<Documentation>
|
||||
<UserDocu>Set a knot of the B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
A low tolerance is used to prevent modification of the curve.
|
||||
A high tolerance is used to 'smooth' the curve.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="segment">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
segment(u1,u2)
|
||||
Modifies this B-Spline curve by segmenting it.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setKnot">
|
||||
<Documentation>
|
||||
<UserDocu>Set a knot of the B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getKnot" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>Get a knot of the B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setKnots">
|
||||
<Documentation>
|
||||
<UserDocu>Set knots of the B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Documentation>
|
||||
<UserDocu>Get a knot of the B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setKnots">
|
||||
<Documentation>
|
||||
<UserDocu>Set knots of the B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getKnots" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>Get all knots of the B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setPole">
|
||||
<Documentation>
|
||||
<UserDocu>Modifies this B-Spline curve by assigning P
|
||||
<Documentation>
|
||||
<UserDocu>Get all knots of the B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setPole">
|
||||
<Documentation>
|
||||
<UserDocu>Modifies this B-Spline curve by assigning P
|
||||
to the pole of index Index in the poles table.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getPole" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>Get a pole of the B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Documentation>
|
||||
<UserDocu>Get a pole of the B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getPoles" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>Get all poles of the B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setWeight">
|
||||
<Documentation>
|
||||
<UserDocu>Set a weight of the B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Documentation>
|
||||
<UserDocu>Get all poles of the B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setWeight">
|
||||
<Documentation>
|
||||
<UserDocu>Set a weight of the B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getWeight" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>Get a weight of the B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Documentation>
|
||||
<UserDocu>Get a weight of the B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getWeights" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>Get all weights of the B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Documentation>
|
||||
<UserDocu>Get all weights of the B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getPolesAndWeights" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns the table of poles and weights in homogeneous coordinates.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getResolution" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>Computes for this B-Spline curve the parametric tolerance (UTolerance)
|
||||
<Documentation>
|
||||
<UserDocu>Returns the table of poles and weights in homogeneous coordinates.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getResolution" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>Computes for this B-Spline curve the parametric tolerance (UTolerance)
|
||||
for a given 3D tolerance (Tolerance3D).
|
||||
If f(t) is the equation of this B-Spline curve, the parametric tolerance
|
||||
ensures that:
|
||||
|t1-t0| < UTolerance =""==> |f(t1)-f(t0)| < Tolerance3D</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="movePoint">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
movePoint(U, P, Index1, Index2)
|
||||
Moves the point of parameter U of this B-Spline curve to P.
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="movePoint">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
movePoint(U, P, Index1, Index2)
|
||||
Moves the point of parameter U of this B-Spline curve to P.
|
||||
Index1 and Index2 are the indexes in the table of poles of this B-Spline curve
|
||||
of the first and last poles designated to be moved.
|
||||
|
||||
Returns: (FirstModifiedPole, LastModifiedPole). They are the indexes of the
|
||||
first and last poles which are effectively modified.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setNotPeriodic">
|
||||
<Documentation>
|
||||
<UserDocu>Changes this B-Spline curve into a non-periodic curve.
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setNotPeriodic">
|
||||
<Documentation>
|
||||
<UserDocu>Changes this B-Spline curve into a non-periodic curve.
|
||||
If this curve is already non-periodic, it is not modified.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setPeriodic">
|
||||
<Documentation>
|
||||
<UserDocu>Changes this B-Spline curve into a periodic curve.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setOrigin">
|
||||
<Documentation>
|
||||
<UserDocu>Assigns the knot of index Index in the knots table
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setPeriodic">
|
||||
<Documentation>
|
||||
<UserDocu>Changes this B-Spline curve into a periodic curve.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setOrigin">
|
||||
<Documentation>
|
||||
<UserDocu>Assigns the knot of index Index in the knots table
|
||||
as the origin of this periodic B-Spline curve. As a consequence,
|
||||
the knots and poles tables are modified.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getMultiplicity" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns the multiplicity of the knot of index
|
||||
<Documentation>
|
||||
<UserDocu>Returns the multiplicity of the knot of index
|
||||
from the knots table of this B-Spline curve.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getMultiplicities" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Returns the multiplicities table M of the knots of this B-Spline curve.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="approximate" Keyword="true">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Replaces this B-Spline curve by approximating a set of points.
|
||||
The function accepts keywords as arguments.
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Returns the multiplicities table M of the knots of this B-Spline curve.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="approximate" Keyword="true">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Replaces this B-Spline curve by approximating a set of points.
|
||||
The function accepts keywords as arguments.
|
||||
|
||||
approximate(Points = list_of_points)
|
||||
approximate(Points = list_of_points)
|
||||
|
||||
Optional arguments :
|
||||
Optional arguments :
|
||||
|
||||
DegMin = integer (3) : Minimum degree of the curve.
|
||||
DegMax = integer (8) : Maximum degree of the curve.
|
||||
Tolerance = float (1e-3) : approximating tolerance.
|
||||
Continuity = string ('C2') : Desired continuity of the curve.
|
||||
Possible values : 'C0','G1','C1','G2','C2','C3','CN'
|
||||
DegMin = integer (3) : Minimum degree of the curve.
|
||||
DegMax = integer (8) : Maximum degree of the curve.
|
||||
Tolerance = float (1e-3) : approximating tolerance.
|
||||
Continuity = string ('C2') : Desired continuity of the curve.
|
||||
Possible values : 'C0','G1','C1','G2','C2','C3','CN'
|
||||
|
||||
LengthWeight = float, CurvatureWeight = float, TorsionWeight = float
|
||||
If one of these arguments is not null, the functions approximates the
|
||||
points using variational smoothing algorithm, which tries to minimize
|
||||
additional criterium:
|
||||
LengthWeight*CurveLength + CurvatureWeight*Curvature + TorsionWeight*Torsion
|
||||
LengthWeight = float, CurvatureWeight = float, TorsionWeight = float
|
||||
If one of these arguments is not null, the functions approximates the
|
||||
points using variational smoothing algorithm, which tries to minimize
|
||||
additional criterium:
|
||||
LengthWeight*CurveLength + CurvatureWeight*Curvature + TorsionWeight*Torsion
|
||||
Continuity must be C0, C1(with DegMax >= 3) or C2(with DegMax >= 5).
|
||||
|
||||
Parameters = list of floats : knot sequence of the approximated points.
|
||||
This argument is only used if the weights above are all null.
|
||||
Parameters = list of floats : knot sequence of the approximated points.
|
||||
This argument is only used if the weights above are all null.
|
||||
|
||||
ParamType = string ('Uniform','Centripetal' or 'ChordLength')
|
||||
Parameterization type. Only used if weights and Parameters above aren't specified.
|
||||
ParamType = string ('Uniform','Centripetal' or 'ChordLength')
|
||||
Parameterization type. Only used if weights and Parameters above aren't specified.
|
||||
|
||||
Note : Continuity of the spline defaults to C2. However, it may not be applied if
|
||||
it conflicts with other parameters ( especially DegMax ).
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
Note : Continuity of the spline defaults to C2. However, it may not be applied if
|
||||
it conflicts with other parameters ( especially DegMax ).
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getCardinalSplineTangents" Keyword="true" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>Compute the tangents for a Cardinal spline</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="interpolate" Keyword="true">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Replaces this B-Spline curve by interpolating a set of points.
|
||||
The function accepts keywords as arguments.
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Replaces this B-Spline curve by interpolating a set of points.
|
||||
The function accepts keywords as arguments.
|
||||
|
||||
interpolate(Points = list_of_points)
|
||||
interpolate(Points = list_of_points)
|
||||
|
||||
Optional arguments :
|
||||
Optional arguments :
|
||||
|
||||
PeriodicFlag = bool (False) : Sets the curve closed or opened.
|
||||
Tolerance = float (1e-6) : interpolating tolerance
|
||||
PeriodicFlag = bool (False) : Sets the curve closed or opened.
|
||||
Tolerance = float (1e-6) : interpolating tolerance
|
||||
|
||||
Parameters : knot sequence of the interpolated points.
|
||||
If not supplied, the function defaults to chord-length parameterization.
|
||||
If PeriodicFlag == True, one extra parameter must be appended.
|
||||
Parameters : knot sequence of the interpolated points.
|
||||
If not supplied, the function defaults to chord-length parameterization.
|
||||
If PeriodicFlag == True, one extra parameter must be appended.
|
||||
|
||||
EndPoint Tangent constraints :
|
||||
EndPoint Tangent constraints :
|
||||
|
||||
InitialTangent = vector, FinalTangent = vector
|
||||
specify tangent vectors for starting and ending points
|
||||
of the BSpline. Either none, or both must be specified.
|
||||
InitialTangent = vector, FinalTangent = vector
|
||||
specify tangent vectors for starting and ending points
|
||||
of the BSpline. Either none, or both must be specified.
|
||||
|
||||
Full Tangent constraints :
|
||||
Full Tangent constraints :
|
||||
|
||||
Tangents = list_of_vectors, TangentFlags = list_of_bools
|
||||
Both lists must have the same length as Points list.
|
||||
Tangents specifies the tangent vector of each point in Points list.
|
||||
TangentFlags (bool) activates or deactivates the corresponding tangent.
|
||||
These arguments will be ignored if EndPoint Tangents (above) are also defined.
|
||||
Tangents = list_of_vectors, TangentFlags = list_of_bools
|
||||
Both lists must have the same length as Points list.
|
||||
Tangents specifies the tangent vector of each point in Points list.
|
||||
TangentFlags (bool) activates or deactivates the corresponding tangent.
|
||||
These arguments will be ignored if EndPoint Tangents (above) are also defined.
|
||||
|
||||
Note : Continuity of the spline defaults to C2. However, if periodic, or tangents
|
||||
are supplied, the continuity will drop to C1.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="buildFromPoles">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Builds a B-Spline by a list of poles.
|
||||
arguments: poles (sequence of Base.Vector), [periodic (default is False), degree (default is 3), interpolate (default is False)]
|
||||
Note : Continuity of the spline defaults to C2. However, if periodic, or tangents
|
||||
are supplied, the continuity will drop to C1.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="buildFromPoles">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Builds a B-Spline by a list of poles.
|
||||
arguments: poles (sequence of Base.Vector), [periodic (default is False), degree (default is 3), interpolate (default is False)]
|
||||
|
||||
Examples:
|
||||
from FreeCAD import Base
|
||||
import Part
|
||||
V = Base.Vector
|
||||
poles = [V(-2, 2, 0),V(0, 2, 1),V(2, 2, 0),V(2, -2, 0),V(0, -2, 1),V(-2, -2, 0)]
|
||||
Examples:
|
||||
from FreeCAD import Base
|
||||
import Part
|
||||
V = Base.Vector
|
||||
poles = [V(-2, 2, 0),V(0, 2, 1),V(2, 2, 0),V(2, -2, 0),V(0, -2, 1),V(-2, -2, 0)]
|
||||
|
||||
# non-periodic spline
|
||||
n=Part.BSplineCurve()
|
||||
n.buildFromPoles(poles)
|
||||
Part.show(n.toShape())
|
||||
# non-periodic spline
|
||||
n=Part.BSplineCurve()
|
||||
n.buildFromPoles(poles)
|
||||
Part.show(n.toShape())
|
||||
|
||||
# periodic spline
|
||||
n=Part.BSplineCurve()
|
||||
n.buildFromPoles(poles, True)
|
||||
Part.show(n.toShape())
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="buildFromPolesMultsKnots" Keyword="true">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Builds a B-Spline by a lists of Poles, Mults, Knots.
|
||||
arguments: poles (sequence of Base.Vector), [mults , knots, periodic, degree, weights (sequence of float), CheckRational]
|
||||
# periodic spline
|
||||
n=Part.BSplineCurve()
|
||||
n.buildFromPoles(poles, True)
|
||||
Part.show(n.toShape())
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="buildFromPolesMultsKnots" Keyword="true">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Builds a B-Spline by a lists of Poles, Mults, Knots.
|
||||
arguments: poles (sequence of Base.Vector), [mults , knots, periodic, degree, weights (sequence of float), CheckRational]
|
||||
|
||||
Examples:
|
||||
from FreeCAD import Base
|
||||
import Part
|
||||
V=Base.Vector
|
||||
poles=[V(-10,-10),V(10,-10),V(10,10),V(-10,10)]
|
||||
Examples:
|
||||
from FreeCAD import Base
|
||||
import Part
|
||||
V=Base.Vector
|
||||
poles=[V(-10,-10),V(10,-10),V(10,10),V(-10,10)]
|
||||
|
||||
# non-periodic spline
|
||||
n=Part.BSplineCurve()
|
||||
n.buildFromPolesMultsKnots(poles,(3,1,3),(0,0.5,1),False,2)
|
||||
Part.show(n.toShape())
|
||||
# non-periodic spline
|
||||
n=Part.BSplineCurve()
|
||||
n.buildFromPolesMultsKnots(poles,(3,1,3),(0,0.5,1),False,2)
|
||||
Part.show(n.toShape())
|
||||
|
||||
# periodic spline
|
||||
p=Part.BSplineCurve()
|
||||
p.buildFromPolesMultsKnots(poles,(1,1,1,1,1),(0,0.25,0.5,0.75,1),True,2)
|
||||
Part.show(p.toShape())
|
||||
# periodic spline
|
||||
p=Part.BSplineCurve()
|
||||
p.buildFromPolesMultsKnots(poles,(1,1,1,1,1),(0,0.25,0.5,0.75,1),True,2)
|
||||
Part.show(p.toShape())
|
||||
|
||||
# periodic and rational spline
|
||||
r=Part.BSplineCurve()
|
||||
r.buildFromPolesMultsKnots(poles,(1,1,1,1,1),(0,0.25,0.5,0.75,1),True,2,(1,0.8,0.7,0.2))
|
||||
Part.show(r.toShape())
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
# periodic and rational spline
|
||||
r=Part.BSplineCurve()
|
||||
r.buildFromPolesMultsKnots(poles,(1,1,1,1,1),(0,0.25,0.5,0.75,1),True,2,(1,0.8,0.7,0.2))
|
||||
Part.show(r.toShape())
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="toBezier" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Build a list of Bezier splines.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Build a list of Bezier splines.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="toBiArcs" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Build a list of arcs and lines to approximate the B-spline.
|
||||
toBiArcs(tolerance) -> list.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="join">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Build a new spline by joining this and a second spline.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="makeC1Continuous">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
makeC1Continuous(tol = 1e-6, ang_tol = 1e-7)
|
||||
Reduces as far as possible the multiplicities of the knots of this BSpline
|
||||
(keeping the geometry). It returns a new BSpline, which could still be C0.
|
||||
tol is a geometrical tolerance.
|
||||
The tol_ang is angular tolerance, in radians. It sets tolerable angle mismatch
|
||||
of the tangents on the left and on the right to decide if the curve is G1 or
|
||||
not at a given point.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
</PythonExport>
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Build a list of arcs and lines to approximate the B-spline.
|
||||
toBiArcs(tolerance) -> list.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="join">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Build a new spline by joining this and a second spline.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="makeC1Continuous">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
makeC1Continuous(tol = 1e-6, ang_tol = 1e-7)
|
||||
Reduces as far as possible the multiplicities of the knots of this BSpline
|
||||
(keeping the geometry). It returns a new BSpline, which could still be C0.
|
||||
tol is a geometrical tolerance.
|
||||
The tol_ang is angular tolerance, in radians. It sets tolerable angle mismatch
|
||||
of the tangents on the left and on the right to decide if the curve is G1 or
|
||||
not at a given point.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="scaleKnotsToBounds">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Scales the knots list to fit the specified bounds.
|
||||
The shape of the curve is not modified.
|
||||
bspline_curve.scaleKnotsToBounds(u0, u1)
|
||||
Default arguments are (0.0, 1.0)
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
|
||||
@@ -72,7 +72,7 @@ int BSplineCurvePy::PyInit(PyObject* args, PyObject* kwd)
|
||||
PyObject* obj;
|
||||
// poles, [ periodic, degree, interpolate ]
|
||||
// {"poles", "mults", "knots", "periodic", "degree", "weights", "CheckRational", NULL};
|
||||
obj = buildFromPolesMultsKnots(args,kwd);
|
||||
obj = buildFromPolesMultsKnots(args, kwd);
|
||||
|
||||
if (obj) {
|
||||
Py_DECREF(obj);
|
||||
@@ -154,7 +154,7 @@ PyObject* BSplineCurvePy::increaseDegree(PyObject * args)
|
||||
(getGeometryPtr()->handle());
|
||||
curve->IncreaseDegree(degree);
|
||||
Py_Return;
|
||||
} PY_CATCH_OCC ;
|
||||
} PY_CATCH_OCC;
|
||||
}
|
||||
|
||||
PyObject* BSplineCurvePy::increaseMultiplicity(PyObject * args)
|
||||
@@ -236,14 +236,14 @@ PyObject* BSplineCurvePy::insertKnots(PyObject * args)
|
||||
|
||||
try {
|
||||
Py::Sequence knots(obj1);
|
||||
TColStd_Array1OfReal k(1,knots.size());
|
||||
TColStd_Array1OfReal k(1, knots.size());
|
||||
int index=1;
|
||||
for (Py::Sequence::iterator it = knots.begin(); it != knots.end(); ++it) {
|
||||
Py::Float val(*it);
|
||||
k(index++) = (double)val;
|
||||
}
|
||||
Py::Sequence mults(obj2);
|
||||
TColStd_Array1OfInteger m(1,mults.size());
|
||||
TColStd_Array1OfInteger m(1, mults.size());
|
||||
index=1;
|
||||
for (Py::Sequence::iterator it = mults.begin(); it != mults.end(); ++it) {
|
||||
Py::Long val(*it);
|
||||
@@ -266,14 +266,14 @@ PyObject* BSplineCurvePy::insertKnots(PyObject * args)
|
||||
PyObject* BSplineCurvePy::removeKnot(PyObject * args)
|
||||
{
|
||||
double tol;
|
||||
int Index,M;
|
||||
int Index, M;
|
||||
if (!PyArg_ParseTuple(args, "iid", &Index, &M, &tol))
|
||||
return nullptr;
|
||||
|
||||
try {
|
||||
Handle(Geom_BSplineCurve) curve = Handle(Geom_BSplineCurve)::DownCast
|
||||
(getGeometryPtr()->handle());
|
||||
Standard_Boolean ok = curve->RemoveKnot(Index,M,tol);
|
||||
Standard_Boolean ok = curve->RemoveKnot(Index, M, tol);
|
||||
return PyBool_FromLong(ok ? 1 : 0);
|
||||
}
|
||||
catch (Standard_Failure& e) {
|
||||
@@ -284,22 +284,22 @@ PyObject* BSplineCurvePy::removeKnot(PyObject * args)
|
||||
|
||||
PyObject* BSplineCurvePy::segment(PyObject * args)
|
||||
{
|
||||
double u1,u2;
|
||||
if (!PyArg_ParseTuple(args, "dd", &u1,&u2))
|
||||
double u1, u2;
|
||||
if (!PyArg_ParseTuple(args, "dd", &u1, &u2))
|
||||
return nullptr;
|
||||
try {
|
||||
Handle(Geom_BSplineCurve) curve = Handle(Geom_BSplineCurve)::DownCast
|
||||
(getGeometryPtr()->handle());
|
||||
Handle(Geom_BSplineCurve) tempCurve = Handle(Geom_BSplineCurve)::DownCast
|
||||
(curve->Copy());
|
||||
tempCurve->Segment(u1,u2);
|
||||
tempCurve->Segment(u1, u2);
|
||||
if (std::abs(tempCurve->FirstParameter()-u1) > Precision::Approximation() ||
|
||||
std::abs(tempCurve->LastParameter()-u2) > Precision::Approximation()) {
|
||||
Standard_Failure::Raise("Failed to segment BSpline curve");
|
||||
return nullptr;
|
||||
}
|
||||
else {
|
||||
curve->Segment(u1,u2);
|
||||
curve->Segment(u1, u2);
|
||||
}
|
||||
Py_Return;
|
||||
}
|
||||
@@ -1392,6 +1392,29 @@ PyObject* BSplineCurvePy::makeC1Continuous(PyObject *args)
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* BSplineCurvePy::scaleKnotsToBounds(PyObject *args)
|
||||
{
|
||||
double u0=0.0;
|
||||
double u1=1.0;
|
||||
if (!PyArg_ParseTuple(args, "|dd", &u0, &u1))
|
||||
return nullptr;
|
||||
try {
|
||||
if (u0 >= u1) {
|
||||
Standard_Failure::Raise("Bad parameter range");
|
||||
return nullptr;
|
||||
}
|
||||
GeomBSplineCurve* curve = getGeomBSplineCurvePtr();
|
||||
curve->scaleKnotsToBounds(u0, u1);
|
||||
Py_Return;
|
||||
}
|
||||
catch (Standard_Failure& e) {
|
||||
std::string err = e.GetMessageString();
|
||||
if (err.empty()) err = e.DynamicType()->Name();
|
||||
PyErr_SetString(PartExceptionOCCError, err.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* BSplineCurvePy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
|
||||
@@ -1680,7 +1680,7 @@ Py::List BSplineSurfacePy::getVKnotSequence(void) const
|
||||
return list;
|
||||
}
|
||||
|
||||
PyObject* BSplineSurfacePy::setBounds(PyObject *args)
|
||||
PyObject* BSplineSurfacePy::scaleKnotsToBounds(PyObject *args)
|
||||
{
|
||||
double u0=0.0;
|
||||
double u1=1.0;
|
||||
@@ -1695,7 +1695,7 @@ PyObject* BSplineSurfacePy::setBounds(PyObject *args)
|
||||
return nullptr;;
|
||||
}
|
||||
GeomBSplineSurface* surf = getGeomBSplineSurfacePtr();
|
||||
surf->setBounds(u0, u1, v0, v1);
|
||||
surf->scaleKnotsToBounds(u0, u1, v0, v1);
|
||||
Py_Return;
|
||||
}
|
||||
catch (Standard_Failure& e) {
|
||||
@@ -1706,8 +1706,12 @@ PyObject* BSplineSurfacePy::setBounds(PyObject *args)
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *BSplineSurfacePy::getCustomAttributes(const char* /*attr*/) const
|
||||
PyObject *BSplineSurfacePy::getCustomAttributes(const char* attr) const
|
||||
{
|
||||
// for backward compatibility
|
||||
if (strcmp(attr, "setBounds") == 0) {
|
||||
return PyObject_GetAttrString(const_cast<BSplineSurfacePy*>(this), "scaleKnotsToBounds");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
</Methode>
|
||||
<Methode Name="sense" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns the orientation of the curves in the the array returned by curves2d</UserDocu>
|
||||
<UserDocu>Returns the orientation of the curves in the array returned by curves2d</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="order" Const="true">
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
# include <BRepBuilderAPI_MakeEdge.hxx>
|
||||
# include <BRepBuilderAPI_MakeFace.hxx>
|
||||
# include <BRepBuilderAPI_MakeVertex.hxx>
|
||||
# include <BSplCLib.hxx>
|
||||
# include <GC_MakeArcOfCircle.hxx>
|
||||
# include <GC_MakeArcOfEllipse.hxx>
|
||||
# include <GC_MakeArcOfHyperbola.hxx>
|
||||
@@ -37,10 +38,10 @@
|
||||
# include <GCPnts_AbscissaPoint.hxx>
|
||||
# include <gce_ErrorType.hxx>
|
||||
# include <gce_MakeParab.hxx>
|
||||
#include <Geom_BezierCurve.hxx>
|
||||
#include <Geom_BezierSurface.hxx>
|
||||
#include <Geom_BSplineCurve.hxx>
|
||||
#include <Geom_BSplineSurface.hxx>
|
||||
# include <Geom_BezierCurve.hxx>
|
||||
# include <Geom_BezierSurface.hxx>
|
||||
# include <Geom_BSplineCurve.hxx>
|
||||
# include <Geom_BSplineSurface.hxx>
|
||||
# include <Geom_CartesianPoint.hxx>
|
||||
# include <Geom_Circle.hxx>
|
||||
# include <Geom_ConicalSurface.hxx>
|
||||
@@ -1615,6 +1616,25 @@ void GeomBSplineCurve::Trim(double u, double v)
|
||||
}
|
||||
}
|
||||
|
||||
void GeomBSplineCurve::scaleKnotsToBounds(double u0, double u1)
|
||||
{
|
||||
try {
|
||||
Handle(Geom_BSplineCurve) curve = Handle(Geom_BSplineCurve)::DownCast(myCurve->Copy());
|
||||
Standard_RangeError_Raise_if (u1 <= u0, " ");
|
||||
TColStd_Array1OfReal k(1,curve->NbKnots());
|
||||
curve->Knots(k);
|
||||
if ((abs(u0-k.First()) > Precision::Confusion()) || (abs(u1-k.Last()) > Precision::Confusion())) {
|
||||
BSplCLib::Reparametrize(u0, u1, k);
|
||||
curve->SetKnots(k);
|
||||
}
|
||||
myCurve = curve;
|
||||
return;
|
||||
}
|
||||
catch (Standard_Failure& e) {
|
||||
THROWM(Base::CADKernelError,e.GetMessageString())
|
||||
}
|
||||
}
|
||||
|
||||
// Persistence implementer
|
||||
unsigned int GeomBSplineCurve::getMemSize () const
|
||||
{
|
||||
@@ -4458,7 +4478,7 @@ Geometry *GeomBSplineSurface::copy() const
|
||||
return newSurf;
|
||||
}
|
||||
|
||||
void GeomBSplineSurface::setBounds(double u0, double u1, double v0, double v1)
|
||||
void GeomBSplineSurface::scaleKnotsToBounds(double u0, double u1, double v0, double v1)
|
||||
{
|
||||
try {
|
||||
Handle(Geom_BSplineSurface) surf = Handle(Geom_BSplineSurface)::DownCast(mySurface->Copy());
|
||||
@@ -4467,23 +4487,15 @@ void GeomBSplineSurface::setBounds(double u0, double u1, double v0, double v1)
|
||||
surf->Bounds(bu0,bu1,bv0,bv1);
|
||||
if ((abs(u0-bu0) > Precision::Confusion()) || (abs(u1-bu1) > Precision::Confusion())) {
|
||||
TColStd_Array1OfReal uk(1,surf->NbUKnots());
|
||||
TColStd_Array1OfReal nuk(1,surf->NbUKnots());
|
||||
surf->UKnots(uk);
|
||||
Standard_Real ur = uk(uk.Upper()) - uk(uk.Lower());
|
||||
for (Standard_Integer i=uk.Lower(); i<=uk.Upper(); i++) {
|
||||
nuk(i) = u0 + ((u1 - u0) * (uk(i) - uk(uk.Lower())) / ur);
|
||||
}
|
||||
surf->SetUKnots(nuk);
|
||||
BSplCLib::Reparametrize(u0, u1, uk);
|
||||
surf->SetUKnots(uk);
|
||||
}
|
||||
if ((abs(v0-bv0) > Precision::Confusion()) || (abs(v1-bv1) > Precision::Confusion())) {
|
||||
TColStd_Array1OfReal vk(1,surf->NbVKnots());
|
||||
TColStd_Array1OfReal nvk(1,surf->NbVKnots());
|
||||
surf->VKnots(vk);
|
||||
Standard_Real vr = vk(vk.Upper()) - vk(vk.Lower());
|
||||
for (Standard_Integer j=vk.Lower(); j<=vk.Upper(); j++) {
|
||||
nvk(j) = v0 + ((v1 - v0) * (vk(j) - vk(vk.Lower())) / vr);
|
||||
}
|
||||
surf->SetVKnots(nvk);
|
||||
BSplCLib::Reparametrize(v0, v1, vk);
|
||||
surf->SetVKnots(vk);
|
||||
}
|
||||
mySurface = surf;
|
||||
return;
|
||||
|
||||
@@ -317,6 +317,7 @@ public:
|
||||
bool removeKnot(int index, int multiplicity, double tolerance = Precision::PConfusion());
|
||||
|
||||
void Trim(double u, double v);
|
||||
void scaleKnotsToBounds(double u0, double u1);
|
||||
|
||||
// Persistence implementer ---------------------
|
||||
unsigned int getMemSize() const override;
|
||||
@@ -844,7 +845,7 @@ public:
|
||||
~GeomBSplineSurface() override;
|
||||
Geometry *copy() const override;
|
||||
|
||||
void setBounds(double u0, double u1, double v0, double v1);
|
||||
void scaleKnotsToBounds(double u0, double u1, double v0, double v1);
|
||||
// Persistence implementer ---------------------
|
||||
unsigned int getMemSize() const override;
|
||||
void Save(Base::Writer &/*writer*/) const override;
|
||||
|
||||
@@ -59,7 +59,7 @@ using namespace Part;
|
||||
|
||||
|
||||
//===========================================================================
|
||||
// TopoShapePyOld - Warpper for the TopoDS classes
|
||||
// TopoShapePyOld - Wrapper for the TopoDS classes
|
||||
//===========================================================================
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@@ -188,7 +188,7 @@ class PartTestBSplineSurface(unittest.TestCase):
|
||||
bs = to.toBSpline()
|
||||
self.assertAlmostEqual(bs.bounds()[1], 2 * math.pi)
|
||||
self.assertAlmostEqual(bs.bounds()[3], 2 * math.pi)
|
||||
bs.setBounds(0.0, 1.0, 0.0, 1.0)
|
||||
bs.scaleKnotsToBounds(0.0, 1.0, 0.0, 1.0)
|
||||
self.assertAlmostEqual(bs.bounds()[1], 1.0)
|
||||
self.assertAlmostEqual(bs.bounds()[3], 1.0)
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
</Methode>
|
||||
<Attribute Name="VisibleFeature" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>Return the the visible feature of this body</UserDocu>
|
||||
<UserDocu>Return the visible feature of this body</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="VisibleFeature" Type="Object" />
|
||||
</Attribute>
|
||||
|
||||
@@ -258,7 +258,7 @@ void TaskDressUpParameters::setSelection(QListWidgetItem* current) {
|
||||
DressUpView->highlightReferences(true);
|
||||
// clear existing selection because only the current item is highlighted, not all selected ones to keep the overview
|
||||
Gui::Selection().clearSelection();
|
||||
// highligh the selected item
|
||||
// highlight the selected item
|
||||
Gui::Selection().addSelection(docName.c_str(), objName.c_str(), subName.c_str(), 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,7 +254,7 @@
|
||||
<item>
|
||||
<widget class="QCheckBox" name="stockInside">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>I checked the path is constrained by the solid. Otherwise the the volume of the solid describes a &quot;keep out&quot; zone.</p></body></html></string>
|
||||
<string><html><head/><body><p>I checked the path is constrained by the solid. Otherwise the volume of the solid describes a &quot;keep out&quot; zone.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Constrained to Inside</string>
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
<item row="3" column="1">
|
||||
<widget class="Gui::InputField" name="ifRadius">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Radius of the fillet on the tag's top edge.</p><p>If the radius is bigger than that which the the tag shape itself supports, the resulting shape will be that of a dome.</p></body></html></string>
|
||||
<string><html><head/><body><p>Radius of the fillet on the tag's top edge.</p><p>If the radius is bigger than that which the tag shape itself supports, the resulting shape will be that of a dome.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -51,7 +51,7 @@ class ObjectEngrave(PathEngraveBase.ObjectOp):
|
||||
self.wires = []
|
||||
|
||||
def opFeatures(self, obj):
|
||||
"""opFeatures(obj) ... return all standard features and edges based geomtries"""
|
||||
"""opFeatures(obj) ... return all standard features and edges based geometries"""
|
||||
return (
|
||||
PathOp.FeatureTool
|
||||
| PathOp.FeatureDepths
|
||||
|
||||
@@ -115,7 +115,7 @@ def processFileNameSubstitutions(
|
||||
j = job.Label
|
||||
filename = filename.replace("%j", j)
|
||||
|
||||
# Use the sequnce number if explicitly called
|
||||
# Use the sequence number if explicitly called
|
||||
if "%S" in filename:
|
||||
j = job.Label
|
||||
filename = filename.replace("%S", str(sequencenumber))
|
||||
|
||||
@@ -10,7 +10,7 @@ practically impossible for `*.fcstd` files.
|
||||
|
||||
When a tool is instantiated in a job the PDN body is created from the shape and the attributes and constraints are set
|
||||
according to the values from the JSON file. All additional parameters are created as properties on the object. This
|
||||
provides the the correct shape and dimensions which can be used to generate a point cloud or mesh for advanced
|
||||
provides the correct shape and dimensions which can be used to generate a point cloud or mesh for advanced
|
||||
algorithms (and potentially simulation).
|
||||
|
||||
# Tool Libraries
|
||||
|
||||
@@ -108,7 +108,7 @@ namespace ConstraintFilter {
|
||||
return (... | (1 << static_cast<std::underlying_type_t<Args>>(args)));
|
||||
}
|
||||
|
||||
/// Array of FilterValue bit sets of size the the number of FilterValues indicating for each FilterValue, which other
|
||||
/// Array of FilterValue bit sets of size of the number of FilterValues indicating for each FilterValue, which other
|
||||
/// FilterValues are comprised therein. It defines the dependencies between filters.
|
||||
constexpr std::array< FilterValueBitset, FilterValueLength> filterAggregates {
|
||||
buildBitset(FilterValue::All, FilterValue::Geometric, FilterValue::Datums, FilterValue::Named, FilterValue::NonDriving, FilterValue::Horizontal,
|
||||
|
||||
@@ -341,7 +341,7 @@ public:
|
||||
// we draw the lines with 36 segments, 8 for each arc and 4 lines
|
||||
// draw the arcs
|
||||
for (int i = 0; i < 8; i++) {
|
||||
// calculate the x,y positions forming the the arc
|
||||
// calculate the x,y positions forming the arc
|
||||
double angle = i * M_PI / 16.0;
|
||||
double x_i = -radius * sin(angle);
|
||||
double y_i = -radius * cos(angle);
|
||||
|
||||
@@ -24,24 +24,29 @@
|
||||
|
||||
#include <Base/Console.h>
|
||||
#include <Base/PyObjectBase.h>
|
||||
#include "FeatureFilling.h"
|
||||
#include "FeatureSewing.h"
|
||||
|
||||
#include "Blending/BlendCurvePy.h"
|
||||
#include "Blending/BlendPointPy.h"
|
||||
#include "Blending/FeatureBlendCurve.h"
|
||||
#include "FeatureCut.h"
|
||||
#include "FeatureGeomFillSurface.h"
|
||||
#include "FeatureExtend.h"
|
||||
#include "FeatureFilling.h"
|
||||
#include "FeatureGeomFillSurface.h"
|
||||
#include "FeatureSections.h"
|
||||
#include "FeatureSewing.h"
|
||||
|
||||
#include <Base/Interpreter.h>
|
||||
#include <Base/Parameter.h>
|
||||
|
||||
|
||||
namespace Surface {
|
||||
class Module : public Py::ExtensionModule<Module>
|
||||
namespace Surface
|
||||
{
|
||||
class Module: public Py::ExtensionModule<Module>
|
||||
{
|
||||
public:
|
||||
Module() : Py::ExtensionModule<Module>("Surface")
|
||||
{
|
||||
initialize("This module is the Surface module."); // register with Python
|
||||
initialize("This module is the Surface module.");// register with Python
|
||||
}
|
||||
|
||||
~Module() override {}
|
||||
@@ -49,13 +54,12 @@ public:
|
||||
private:
|
||||
};
|
||||
|
||||
PyObject* initModule()
|
||||
PyObject *initModule()
|
||||
{
|
||||
return Base::Interpreter().addModule(new Module);
|
||||
}
|
||||
|
||||
} // namespace Surface
|
||||
|
||||
}// namespace Surface
|
||||
|
||||
/* Python entry */
|
||||
PyMOD_INIT_FUNC(Surface)
|
||||
@@ -63,21 +67,24 @@ PyMOD_INIT_FUNC(Surface)
|
||||
try {
|
||||
Base::Interpreter().runString("import Part");
|
||||
}
|
||||
catch(const Base::Exception& e) {
|
||||
catch (const Base::Exception &e) {
|
||||
PyErr_SetString(PyExc_ImportError, e.what());
|
||||
PyMOD_Return(nullptr);
|
||||
}
|
||||
|
||||
PyObject* mod = Surface::initModule();
|
||||
PyObject *mod = Surface::initModule();
|
||||
Base::Console().Log("Loading Surface module... done\n");
|
||||
Base::Interpreter().addType(&Surface::BlendPointPy::Type, mod, "BlendPoint");
|
||||
Base::Interpreter().addType(&Surface::BlendCurvePy::Type, mod, "BlendCurve");
|
||||
|
||||
// Add types to module
|
||||
Surface::Filling ::init();
|
||||
Surface::Sewing ::init();
|
||||
Surface::Cut ::init();
|
||||
Surface::GeomFillSurface ::init();
|
||||
Surface::Extend ::init();
|
||||
Surface::Sections ::init();
|
||||
Surface::Filling ::init();
|
||||
Surface::Sewing ::init();
|
||||
Surface::Cut ::init();
|
||||
Surface::GeomFillSurface ::init();
|
||||
Surface::Extend ::init();
|
||||
Surface::FeatureBlendCurve ::init();
|
||||
Surface::Sections ::init();
|
||||
|
||||
PyMOD_Return(mod);
|
||||
}
|
||||
|
||||
141
src/Mod/Surface/App/Blending/BlendCurve.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2022 Matteo Grellier <matteogrellier@gmail.com> *
|
||||
* *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <BSplCLib.hxx>
|
||||
#include <Geom_BezierCurve.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <math_Gauss.hxx>
|
||||
#include <math_Matrix.hxx>
|
||||
#endif
|
||||
#include "Blending/BlendCurve.h"
|
||||
#include "Blending/BlendCurvePy.h"
|
||||
#include <Base/Vector3D.h>
|
||||
#include <Mod/Part/App/Geometry.h>
|
||||
|
||||
using namespace Surface;
|
||||
|
||||
BlendCurve::BlendCurve(const std::vector<BlendPoint>& blendPointsList)
|
||||
{
|
||||
// Retrieve number of blendPoints and push them into blendPoints.
|
||||
size_t nb_pts = blendPointsList.size();
|
||||
|
||||
if (nb_pts > 2) {
|
||||
throw Base::NotImplementedError("Not implemented");
|
||||
}
|
||||
else if (nb_pts < 2) {
|
||||
throw Base::ValueError("Need two points for working");
|
||||
}
|
||||
blendPoints = blendPointsList;
|
||||
}
|
||||
|
||||
Handle(Geom_BezierCurve) BlendCurve::compute()
|
||||
{
|
||||
size_t nb_pts = blendPoints.size();
|
||||
try {
|
||||
// Uniform Parametrization
|
||||
TColStd_Array1OfReal params(1, nb_pts);
|
||||
for (size_t i = 0; i < nb_pts; ++i) {
|
||||
params(i + 1) = (double)i / ((double)nb_pts - 1);
|
||||
}
|
||||
|
||||
int num_poles = 0;
|
||||
for (size_t i = 0; i < nb_pts; ++i) {
|
||||
num_poles += blendPoints[i].nbVectors();
|
||||
}
|
||||
|
||||
Handle(Geom_BezierCurve) curve;
|
||||
if (num_poles > (curve->MaxDegree() + 1))// use Geom_BezierCurve max degree
|
||||
Standard_Failure::Raise("number of constraints exceeds bezier curve capacity");
|
||||
|
||||
TColStd_Array1OfReal knots(1, 2 * num_poles);
|
||||
for (int i = 1; i <= num_poles; ++i) {
|
||||
knots(i) = params(1);
|
||||
knots(num_poles + i) = params(nb_pts);
|
||||
}
|
||||
|
||||
math_Matrix OCCmatrix(1, num_poles, 1, num_poles, 0.0);
|
||||
math_Vector res_x(1, num_poles, 0.0);
|
||||
math_Vector res_y(1, num_poles, 0.0);
|
||||
math_Vector res_z(1, num_poles, 0.0);
|
||||
int row_idx = 1;
|
||||
int cons_idx = 1;
|
||||
for (size_t i = 0; i < nb_pts; ++i) {
|
||||
math_Matrix bezier_eval(1, blendPoints[i].nbVectors(), 1, num_poles, 0.0);
|
||||
Standard_Integer first_non_zero;
|
||||
BSplCLib::EvalBsplineBasis(blendPoints[i].nbVectors() - 1, num_poles, knots, params(cons_idx), first_non_zero, bezier_eval, Standard_False);
|
||||
int idx2 = 1;
|
||||
for (int it2 = 0; it2 < blendPoints[i].nbVectors(); ++it2) {
|
||||
OCCmatrix.SetRow(row_idx, bezier_eval.Row(idx2));
|
||||
Base::Vector3d pnt = blendPoints[i].vectors[it2];
|
||||
res_x(row_idx) = pnt.x;
|
||||
res_y(row_idx) = pnt.y;
|
||||
res_z(row_idx) = pnt.z;
|
||||
idx2++;
|
||||
row_idx++;
|
||||
}
|
||||
cons_idx++;
|
||||
}
|
||||
math_Gauss gauss(OCCmatrix);
|
||||
gauss.Solve(res_x);
|
||||
if (!gauss.IsDone())
|
||||
Standard_Failure::Raise("Failed to solve equations");
|
||||
gauss.Solve(res_y);
|
||||
if (!gauss.IsDone())
|
||||
Standard_Failure::Raise("Failed to solve equations");
|
||||
gauss.Solve(res_z);
|
||||
if (!gauss.IsDone())
|
||||
Standard_Failure::Raise("Failed to solve equations");
|
||||
|
||||
TColgp_Array1OfPnt poles(1, num_poles);
|
||||
for (int idx = 1; idx <= num_poles; ++idx) {
|
||||
poles.SetValue(idx, gp_Pnt(res_x(idx), res_y(idx), res_z(idx)));
|
||||
}
|
||||
Handle(Geom_BezierCurve) bezier = new Geom_BezierCurve(poles);
|
||||
return bezier;
|
||||
}
|
||||
catch (Standard_Failure &) {
|
||||
PyErr_SetString(Base::PyExc_FC_CADKernelError, "Failed to compute bezier curve");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void BlendCurve::setSize(int i, double f, bool relative)
|
||||
{
|
||||
double size = f;
|
||||
try {
|
||||
if (relative) {
|
||||
double nb_poles = blendPoints.front().nbVectors() + blendPoints[1].nbVectors();
|
||||
Base::Vector3d diff = blendPoints[1].vectors[0] - blendPoints[0].vectors[0];
|
||||
size = size * diff.Length() / nb_poles;
|
||||
}
|
||||
blendPoints[i].setSize(size);
|
||||
}
|
||||
catch (Standard_Failure &e) {
|
||||
PyErr_SetString(Base::PyExc_FC_CADKernelError, e.GetMessageString());
|
||||
}
|
||||
}
|
||||
63
src/Mod/Surface/App/Blending/BlendCurve.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2022 Matteo Grellier <matteogrellier@gmail.com> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef SURFACE_BLEND_CURVE_H
|
||||
#define SURFACE_BLEND_CURVE_H
|
||||
|
||||
#include <Geom_BezierCurve.hxx>
|
||||
#include <Mod/Surface/SurfaceGlobal.h>
|
||||
#include <Mod/Surface/App/Blending/BlendPoint.h>
|
||||
|
||||
namespace Surface
|
||||
{
|
||||
/*!
|
||||
* Create a BezierCurve interpolating a list of BlendPoints
|
||||
*/
|
||||
class SurfaceExport BlendCurve
|
||||
{
|
||||
public:
|
||||
std::vector<BlendPoint> blendPoints;
|
||||
|
||||
BlendCurve() = default;
|
||||
/*!
|
||||
* Constructor
|
||||
*\param std::vector<BlendPoint>
|
||||
*/
|
||||
BlendCurve(const std::vector<BlendPoint>& blendPointsList);
|
||||
~BlendCurve() = default;
|
||||
/*!
|
||||
* Perform the interpolate algorithm
|
||||
*\return the BezierCurve
|
||||
*/
|
||||
Handle(Geom_BezierCurve) compute();
|
||||
/*!
|
||||
* Set the size of the first derivative of a BlendPoint
|
||||
*\param int index of the BlendPoint to modify
|
||||
*\param double new size
|
||||
*\param bool interpret new size relative to chordlength
|
||||
*/
|
||||
void setSize(int, double, bool);
|
||||
};
|
||||
}// namespace Surface
|
||||
|
||||
#endif
|
||||
|
||||
41
src/Mod/Surface/App/Blending/BlendCurvePy.xml
Normal file
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
Father="PyObjectBase"
|
||||
FatherInclude="Base/BaseClassPy.h"
|
||||
FatherNamespace="Base"
|
||||
Name="BlendCurvePy"
|
||||
PythonName="Surface.BlendCurve"
|
||||
Twin="BlendCurve"
|
||||
TwinPointer="BlendCurve"
|
||||
Include="Mod/Surface/App/Blending/BlendCurve.h"
|
||||
Namespace="Surface"
|
||||
Constructor="true"
|
||||
Delete="true">
|
||||
<Documentation>
|
||||
</Documentation>
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="Mattéo Grellier" EMail="matteogrellier@gmail.com" />
|
||||
<UserDocu>
|
||||
Create a BlendCurve that interpolate 2 BlendPoints.
|
||||
curve = BlendCurve(BlendPoint1, BlendPoint2)
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
<Methode Name="compute">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Return the BezierCurve that interpolate the input BlendPoints.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setSize">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Set the tangent size of the blendpoint at given index.
|
||||
If relative is true, the size is considered relative to the distance between the two blendpoints.
|
||||
myBlendCurve.setSize(idx, size, relative)
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
97
src/Mod/Surface/App/Blending/BlendCurvePyImp.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
///***************************************************************************
|
||||
// * Copyright (c) 2022 Matteo Grellier <matteogrellier@gmail.com> *
|
||||
// * *
|
||||
// * This file is part of the FreeCAD CAx development system. *
|
||||
// * *
|
||||
// * This library is free software; you can redistribute it and/or *
|
||||
// * modify it under the terms of the GNU Library General Public *
|
||||
// * License as published by the Free Software Foundation; either *
|
||||
// * version 2 of the License, or (at your option) any later version. *
|
||||
// * *
|
||||
// * This library is distributed in the hope that it will be useful, *
|
||||
// * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
// * GNU Library General Public License for more details. *
|
||||
// * *
|
||||
// * You should have received a copy of the GNU Library General Public *
|
||||
// * License along with this library; see the file COPYING.LIB. If not, *
|
||||
// * write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
// * Suite 330, Boston, MA 02111-1307, USA *
|
||||
// * *
|
||||
// ***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include "Blending/BlendCurvePy.h"
|
||||
#include "Blending/BlendCurvePy.cpp"
|
||||
#include "Blending/BlendPointPy.h"
|
||||
#include <Base/VectorPy.h>
|
||||
#include <Mod/Part/App/BezierCurvePy.h>
|
||||
|
||||
using namespace Surface;
|
||||
|
||||
std::string BlendCurvePy::representation() const
|
||||
{
|
||||
return "BlendCurve";
|
||||
}
|
||||
|
||||
PyObject *BlendCurvePy::PyMake(struct _typeobject *, PyObject *, PyObject *)// Python wrapper
|
||||
{
|
||||
// create a new instance of BlendCurvePy
|
||||
return new BlendCurvePy(new BlendCurve);
|
||||
}
|
||||
|
||||
int BlendCurvePy::PyInit(PyObject *args, PyObject * /*kwds*/)
|
||||
{
|
||||
PyObject *b1;
|
||||
PyObject *b2;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O!O!", &(Surface::BlendPointPy::Type), &b1, &(Surface::BlendPointPy::Type), &b2))
|
||||
return -1;
|
||||
|
||||
std::vector<BlendPoint> bpList;
|
||||
BlendPoint *geom1 = static_cast<BlendPointPy *>(b1)->getBlendPointPtr();
|
||||
BlendPoint *geom2 = static_cast<BlendPointPy *>(b2)->getBlendPointPtr();
|
||||
bpList.emplace_back(*geom1);
|
||||
bpList.emplace_back(*geom2);
|
||||
this->getBlendCurvePtr()->blendPoints = bpList;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyObject *BlendCurvePy::compute(PyObject * args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return nullptr;
|
||||
|
||||
BlendCurve *bc = getBlendCurvePtr();
|
||||
Handle(Geom_BezierCurve) gc = bc->compute();
|
||||
return new Part::BezierCurvePy(new Part::GeomBezierCurve(gc));
|
||||
}
|
||||
|
||||
PyObject *BlendCurvePy::setSize(PyObject *args)
|
||||
{
|
||||
int i;
|
||||
double size;
|
||||
PyObject *relative = Py_True;
|
||||
if (!PyArg_ParseTuple(args, "idO!", &i, &size, &PyBool_Type, &relative)) {
|
||||
return nullptr;
|
||||
}
|
||||
try {
|
||||
getBlendCurvePtr()->setSize(i, size, Base::asBoolean(relative));
|
||||
Py_Return;
|
||||
}
|
||||
catch (Standard_Failure &e) {
|
||||
PyErr_SetString(Base::PyExc_FC_CADKernelError, e.GetMessageString());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *BlendCurvePy::getCustomAttributes(const char * /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int BlendCurvePy::setCustomAttributes(const char * /*attr*/, PyObject * /*obj*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
70
src/Mod/Surface/App/Blending/BlendPoint.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2022 Matteo Grellier <matteogrellier@gmail.com> *
|
||||
* *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <Precision.hxx>
|
||||
#include <Standard_Real.hxx>
|
||||
#endif
|
||||
#include "Blending/BlendPoint.h"
|
||||
#include "Blending/BlendPointPy.h"
|
||||
|
||||
|
||||
using namespace Surface;
|
||||
|
||||
BlendPoint::BlendPoint(const std::vector<Base::Vector3d>& vectorList)
|
||||
: vectors{vectorList}
|
||||
{
|
||||
}
|
||||
|
||||
BlendPoint::BlendPoint()
|
||||
{
|
||||
vectors.emplace_back(Base::Vector3d(0, 0, 0));
|
||||
}
|
||||
|
||||
void BlendPoint::multiply(double f)
|
||||
{
|
||||
for (int i = 0; i < nbVectors(); i++) {
|
||||
vectors[i] *= Pow(f, i);
|
||||
}
|
||||
}
|
||||
|
||||
void BlendPoint::setSize(double f)
|
||||
{
|
||||
if (nbVectors() > 1) {
|
||||
double il = vectors[1].Length();
|
||||
if (il > Precision::Confusion()) {
|
||||
multiply(f / il);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int BlendPoint::getContinuity()
|
||||
{
|
||||
return vectors.size() - 1;
|
||||
}
|
||||
|
||||
int BlendPoint::nbVectors()
|
||||
{
|
||||
return vectors.size();
|
||||
}
|
||||
76
src/Mod/Surface/App/Blending/BlendPoint.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2014 Matteo Grellier <matteogrellier@gmail.com> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef SURFACE_BLEND_POINT_H
|
||||
#define SURFACE_BLEND_POINT_H
|
||||
|
||||
|
||||
#include <Mod/Surface/SurfaceGlobal.h>
|
||||
#include <Base/Vector3D.h>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace Surface
|
||||
{
|
||||
|
||||
/*!
|
||||
* Create a list of vectors formed by a point and some derivatives
|
||||
* obtained from a curve or surface
|
||||
*/
|
||||
class SurfaceExport BlendPoint
|
||||
{
|
||||
public:
|
||||
std::vector<Base::Vector3d> vectors;
|
||||
|
||||
BlendPoint();
|
||||
/*!
|
||||
* Constructor
|
||||
*\param std::vector<Base::Vector3d>
|
||||
*/
|
||||
BlendPoint(const std::vector<Base::Vector3d>& vectorList);
|
||||
~BlendPoint() = default;
|
||||
/*!
|
||||
* Scale the blendpoint vectors
|
||||
*\param double scaling factor
|
||||
*/
|
||||
void multiply(double f);
|
||||
/*!
|
||||
* Resize the blendpoint vectors
|
||||
* by setting the size of the first derivative
|
||||
*\param double new size
|
||||
*/
|
||||
void setSize(double f);
|
||||
/*!
|
||||
*\return continuity of this BlendPoint
|
||||
*/
|
||||
int getContinuity();
|
||||
/*!
|
||||
*\return Number of vectors of this BlendPoint
|
||||
*/
|
||||
int nbVectors();
|
||||
|
||||
private:
|
||||
};
|
||||
}// namespace Surface
|
||||
|
||||
#endif
|
||||
|
||||
57
src/Mod/Surface/App/Blending/BlendPointPy.xml
Normal file
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
Father="PyObjectBase"
|
||||
FatherInclude="Base/BaseClassPy.h"
|
||||
FatherNamespace="Base"
|
||||
Name="BlendPointPy"
|
||||
PythonName="Surface.BlendPoint"
|
||||
Twin="BlendPoint"
|
||||
TwinPointer="BlendPoint"
|
||||
Include="Mod/Surface/App/Blending/BlendPoint.h"
|
||||
Namespace="Surface"
|
||||
Constructor="true"
|
||||
Delete="true">
|
||||
<Documentation>
|
||||
</Documentation>
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="Mattéo Grellier" EMail="matteogrellier@gmail.com" />
|
||||
<UserDocu>
|
||||
Create BlendPoint from a point and some derivatives.
|
||||
myBlendPoint = BlendPoint([Point, D1, D2, ..., DN])
|
||||
BlendPoint can also be constructed from an edge
|
||||
myBlendPoint = BlendPoint(Edge, parameter = float, continuity = int)
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
<Attribute Name="Vectors" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>The list of vectors of this BlendPoint.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="vectors" Type="List"/>
|
||||
</Attribute>
|
||||
<Methode Name="getSize" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Return BlendPoint first derivative length.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setSize">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Resizes the BlendPoint vectors,
|
||||
by setting the length of the first derivative.
|
||||
theBlendPoint.setSize(new_size)
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="setvectors">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Set the vectors of BlendPoint.
|
||||
BlendPoint.setvectors([Point, D1, D2, ..., DN])
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
195
src/Mod/Surface/App/Blending/BlendPointPyImp.cpp
Normal file
@@ -0,0 +1,195 @@
|
||||
///***************************************************************************
|
||||
// * Copyright (c) 2022 Matteo Grellier <matteogrellier@gmail.com> *
|
||||
// * *
|
||||
// * This file is part of the FreeCAD CAx development system. *
|
||||
// * *
|
||||
// * This library is free software; you can redistribute it and/or *
|
||||
// * modify it under the terms of the GNU Library General Public *
|
||||
// * License as published by the Free Software Foundation; either *
|
||||
// * version 2 of the License, or (at your option) any later version. *
|
||||
// * *
|
||||
// * This library is distributed in the hope that it will be useful, *
|
||||
// * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
// * GNU Library General Public License for more details. *
|
||||
// * *
|
||||
// * You should have received a copy of the GNU Library General Public *
|
||||
// * License along with this library; see the file COPYING.LIB. If not, *
|
||||
// * write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
// * Suite 330, Boston, MA 02111-1307, USA *
|
||||
// * *
|
||||
// ***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <BRepAdaptor_Curve.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#endif
|
||||
#include "Blending/BlendPoint.h"
|
||||
#include "Blending/BlendPointPy.h"
|
||||
#include "Blending/BlendPointPy.cpp"
|
||||
#include <Base/GeometryPyCXX.h>
|
||||
#include <Base/VectorPy.h>
|
||||
#include <Mod/Part/App/TopoShapePy.h>
|
||||
|
||||
|
||||
using namespace Surface;
|
||||
|
||||
std::string BlendPointPy::representation() const
|
||||
{
|
||||
std::stringstream str;
|
||||
str << "G" << getBlendPointPtr()->getContinuity() << " BlendPoint";
|
||||
|
||||
if (getBlendPointPtr()->vectors.empty()) {
|
||||
Base::Vector3d bp = getBlendPointPtr()->vectors[0];
|
||||
str << " at (" << bp.x << ", " << bp.y << ", " << bp.z << "), ";
|
||||
}
|
||||
return str.str();
|
||||
}
|
||||
|
||||
PyObject *BlendPointPy::PyMake(struct _typeobject *, PyObject *, PyObject *)// Python wrapper
|
||||
{
|
||||
// create a new instance of BlendPointPy
|
||||
return new BlendPointPy(new BlendPoint);
|
||||
}
|
||||
|
||||
int BlendPointPy::PyInit(PyObject *args, PyObject *)
|
||||
{
|
||||
PyObject *plist;
|
||||
std::vector<Base::Vector3d> vecs;
|
||||
if (PyArg_ParseTuple(args, "O", &plist)) {
|
||||
Py::Sequence list(plist);
|
||||
if (list.size() == 0) {
|
||||
vecs.emplace_back(Base::Vector3d(0, 0, 0));
|
||||
}
|
||||
else {
|
||||
for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
|
||||
Py::Vector v(*it);
|
||||
Base::Vector3d vec = v.toVector();
|
||||
vecs.emplace_back(vec);
|
||||
}
|
||||
}
|
||||
this->getBlendPointPtr()->vectors = vecs;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args, "")) {
|
||||
vecs.emplace_back(Base::Vector3d(0, 0, 0));
|
||||
this->getBlendPointPtr()->vectors = vecs;
|
||||
return 0;
|
||||
}
|
||||
|
||||
double param;
|
||||
int cont;
|
||||
PyObject *pcObj;
|
||||
PyErr_Clear();
|
||||
// Create a curve with an edge, parameter and continiuity.
|
||||
if (PyArg_ParseTuple(args, "O!di", &(Part::TopoShapePy::Type), &pcObj, ¶m, &cont)) {
|
||||
try {
|
||||
gp_Pnt Pt;
|
||||
TopoDS_Shape shape = static_cast<Part::TopoShapePy *>(pcObj)->getTopoShapePtr()->getShape();
|
||||
const TopoDS_Edge &e = TopoDS::Edge(shape);
|
||||
BRepAdaptor_Curve adapt(e);
|
||||
if (param < adapt.FirstParameter() || param > adapt.LastParameter()) {
|
||||
PyErr_Warn(PyExc_UserWarning, "BlendPoint: edge is not a closed curve");
|
||||
Base::Console().Message("fp=%f\n", adapt.FirstParameter());
|
||||
Base::Console().Message("lp=%f\n", adapt.LastParameter());
|
||||
}
|
||||
|
||||
adapt.D0(param, Pt);
|
||||
Base::Vector3d bv(Pt.X(), Pt.Y(), Pt.Z());
|
||||
vecs.emplace_back(bv);
|
||||
|
||||
for (int i = 1; i <= cont; i++) {
|
||||
gp_Vec v1 = adapt.DN(param, i);
|
||||
Base::Vector3d bbv1(v1.X(), v1.Y(), v1.Z());
|
||||
vecs.emplace_back(bbv1);
|
||||
}
|
||||
this->getBlendPointPtr()->vectors = vecs;
|
||||
return 0;
|
||||
}
|
||||
catch (const std::exception &e) {
|
||||
PyErr_SetString(PyExc_RuntimeError, e.what());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "supported signatures:\n"
|
||||
"BlendPoint()\n"
|
||||
"BlendPoint(list of Vector)\n"
|
||||
"BlendPoint(edge, parameter and continiuity)\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
PyObject *BlendPointPy::setSize(PyObject *args)
|
||||
{
|
||||
double size = 1.0;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "d", &size))
|
||||
return nullptr;
|
||||
try {
|
||||
getBlendPointPtr()->setSize(size);
|
||||
Py_Return;
|
||||
}
|
||||
catch (Standard_Failure &e) {
|
||||
PyErr_SetString(Base::PyExc_FC_CADKernelError, "Failed to set size");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *BlendPointPy::getSize(PyObject *args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return nullptr;
|
||||
int nb = getBlendPointPtr()->nbVectors();
|
||||
if (nb >= 2) {
|
||||
double bpTangentLength = getBlendPointPtr()->vectors[1].Length();
|
||||
return Py_BuildValue("d", bpTangentLength);
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_RuntimeError, "Cannot determine size");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Py::List BlendPointPy::getVectors() const
|
||||
{
|
||||
BlendPoint *bp = getBlendPointPtr();
|
||||
Py::List vecs;
|
||||
for (const auto& p : bp->vectors) {
|
||||
Base::VectorPy *vec = new Base::VectorPy(p);
|
||||
vecs.append(Py::asObject(vec));
|
||||
}
|
||||
return vecs;
|
||||
}
|
||||
|
||||
PyObject *BlendPointPy::setvectors(PyObject *args)
|
||||
{
|
||||
PyObject *plist;
|
||||
if (!PyArg_ParseTuple(args, "O", &plist)) {
|
||||
PyErr_SetString(PyExc_TypeError, "List of vectors required.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Py::Sequence list(plist);
|
||||
std::vector<Base::Vector3d> vecs;
|
||||
for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
|
||||
Py::Vector v(*it);
|
||||
Base::Vector3d pole = v.toVector();
|
||||
vecs.emplace_back(pole);
|
||||
}
|
||||
|
||||
BlendPoint *bp = getBlendPointPtr();
|
||||
bp->vectors = vecs;
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject *BlendPointPy::getCustomAttributes(const char * /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int BlendPointPy::setCustomAttributes(const char * /*attr*/, PyObject * /*obj*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
180
src/Mod/Surface/App/Blending/FeatureBlendCurve.cpp
Normal file
@@ -0,0 +1,180 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2022 Matteo Grellier <matteogrellier@gmail.com> *
|
||||
* *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <BRepAdaptor_Curve.hxx>
|
||||
#include <BRepBuilderAPI_MakeEdge.hxx>
|
||||
#include <Base/Tools.h>
|
||||
#include <Geom_Curve.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <Standard_Version.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#endif
|
||||
#include "FeatureBlendCurve.h"
|
||||
#include "Mod/Surface/App/Blending/BlendCurve.h"
|
||||
#include "Mod/Surface/App/Blending/BlendPoint.h"
|
||||
|
||||
using namespace Surface;
|
||||
|
||||
const App::PropertyFloatConstraint::Constraints StartParameterConstraint = {0.0, 1.0, 0.05};
|
||||
const App::PropertyFloatConstraint::Constraints EndParameterConstraint = {0.0, 1.0, 0.05};
|
||||
const App::PropertyIntegerConstraint::Constraints StartContinuityConstraint = {0, 25, 1};
|
||||
const App::PropertyIntegerConstraint::Constraints EndContinuityConstraint = {0, 25, 1};
|
||||
|
||||
PROPERTY_SOURCE(Surface::FeatureBlendCurve, Part::Spline)
|
||||
|
||||
FeatureBlendCurve::FeatureBlendCurve() : lockOnChangeMutex(false)
|
||||
{
|
||||
ADD_PROPERTY_TYPE(StartEdge, (nullptr), "FirstEdge", App::Prop_None, "");
|
||||
ADD_PROPERTY_TYPE(StartContinuity, (2), "FirstEdge", App::Prop_None, "");
|
||||
StartContinuity.setConstraints(&StartContinuityConstraint);
|
||||
ADD_PROPERTY_TYPE(StartParameter, (0.0f), "FirstEdge", App::Prop_None, "");
|
||||
StartParameter.setConstraints(&StartParameterConstraint);
|
||||
ADD_PROPERTY_TYPE(StartSize, (1.0f), "FirstEdge", App::Prop_None, "");
|
||||
|
||||
ADD_PROPERTY_TYPE(EndEdge, (nullptr), "SecondEdge", App::Prop_None, "");
|
||||
ADD_PROPERTY_TYPE(EndContinuity, (2), "SecondEdge", App::Prop_None, "");
|
||||
EndContinuity.setConstraints(&EndContinuityConstraint);
|
||||
ADD_PROPERTY_TYPE(EndParameter, (0.0f), "SecondEdge", App::Prop_None, "");
|
||||
EndParameter.setConstraints(&EndParameterConstraint);
|
||||
ADD_PROPERTY_TYPE(EndSize, (1.0f), "SecondEdge", App::Prop_None, "");
|
||||
Handle(Geom_BezierCurve) maxDegreeCurve;
|
||||
maxDegree = maxDegreeCurve->MaxDegree();
|
||||
}
|
||||
|
||||
short FeatureBlendCurve::mustExecute() const
|
||||
{
|
||||
if (StartEdge.isTouched())
|
||||
return 1;
|
||||
if (StartParameter.isTouched())
|
||||
return 1;
|
||||
if (StartContinuity.isTouched())
|
||||
return 1;
|
||||
if (StartSize.isTouched())
|
||||
return 1;
|
||||
if (EndEdge.isTouched())
|
||||
return 1;
|
||||
if (EndParameter.isTouched())
|
||||
return 1;
|
||||
if (EndContinuity.isTouched())
|
||||
return 1;
|
||||
if (EndSize.isTouched())
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
BlendPoint FeatureBlendCurve::GetBlendPoint(App::PropertyLinkSub &link, App::PropertyFloatConstraint ¶m, App::PropertyIntegerConstraint &continuity)
|
||||
{
|
||||
auto linked = link.getValue();
|
||||
|
||||
TopoDS_Shape axEdge;
|
||||
if (link.getSubValues().size() > 0 && link.getSubValues()[0].length() > 0) {
|
||||
axEdge = Feature::getTopoShape(linked, link.getSubValues()[0].c_str(), true /*need element*/).getShape();
|
||||
}
|
||||
else {
|
||||
axEdge = Feature::getShape(linked);
|
||||
}
|
||||
|
||||
if (axEdge.IsNull())
|
||||
throw Base::ValueError("DirLink shape is null");
|
||||
if (axEdge.ShapeType() != TopAbs_EDGE)
|
||||
throw Base::TypeError("DirLink shape is not an edge");
|
||||
const TopoDS_Edge &e = TopoDS::Edge(axEdge);
|
||||
BRepAdaptor_Curve adapt(e);
|
||||
double fp = adapt.FirstParameter();
|
||||
double lp = adapt.LastParameter();
|
||||
|
||||
double RealPar = RelativeToRealParameters(param.getValue(), fp, lp);
|
||||
|
||||
std::vector<Base::Vector3d> constraints;
|
||||
gp_Pnt Pt;
|
||||
|
||||
adapt.D0(RealPar, Pt);
|
||||
Base::Vector3d bv(Pt.X(), Pt.Y(), Pt.Z());
|
||||
constraints.emplace_back(bv);
|
||||
|
||||
for (int i = 1; i <= continuity.getValue(); i++) {
|
||||
gp_Vec v1 = adapt.DN(RealPar, i);
|
||||
Base::Vector3d bbv1(v1.X(), v1.Y(), v1.Z());
|
||||
constraints.emplace_back(bbv1);
|
||||
}
|
||||
|
||||
BlendPoint bp(constraints);
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
App::DocumentObjectExecReturn *FeatureBlendCurve::execute(void)
|
||||
{
|
||||
BlendPoint bp1 = GetBlendPoint(StartEdge, StartParameter, StartContinuity);
|
||||
BlendPoint bp2 = GetBlendPoint(EndEdge, EndParameter, EndContinuity);
|
||||
|
||||
std::vector<BlendPoint> blendPointsList;
|
||||
|
||||
blendPointsList.emplace_back(bp1);
|
||||
blendPointsList.emplace_back(bp2);
|
||||
|
||||
BlendCurve curve(blendPointsList);
|
||||
curve.setSize(0, StartSize.getValue(), true);
|
||||
curve.setSize(1, EndSize.getValue(), true);
|
||||
|
||||
Handle(Geom_BezierCurve) bc(curve.compute());
|
||||
BRepBuilderAPI_MakeEdge mkEdge(bc);
|
||||
|
||||
Shape.setValue(mkEdge.Edge());
|
||||
|
||||
return StdReturn;
|
||||
}
|
||||
|
||||
double FeatureBlendCurve::RelativeToRealParameters(double relativeValue, double fp, double lp)
|
||||
{
|
||||
return fp + relativeValue * (lp - fp);
|
||||
}
|
||||
|
||||
|
||||
void FeatureBlendCurve::onChanged(const App::Property *prop)
|
||||
{
|
||||
// using a mutex and lock to protect a recursive calling when setting the new values
|
||||
if (lockOnChangeMutex)
|
||||
return;
|
||||
Base::StateLocker lock(lockOnChangeMutex);
|
||||
|
||||
if (prop == &StartContinuity) {
|
||||
auto changedStartProp = dynamic_cast<const App::PropertyInteger *>(prop);
|
||||
|
||||
if (changedStartProp->getValue() > (maxDegree - 2 - EndContinuity.getValue())) {
|
||||
|
||||
StartContinuity.setValue(maxDegree - 2 - EndContinuity.getValue());
|
||||
}
|
||||
}
|
||||
else if (prop == &EndContinuity) {
|
||||
auto changedEndProp = dynamic_cast<const App::PropertyInteger *>(prop);
|
||||
|
||||
if (changedEndProp->getValue() > (maxDegree - 2 - StartContinuity.getValue())) {
|
||||
EndContinuity.setValue(maxDegree - 2 - StartContinuity.getValue());
|
||||
}
|
||||
}
|
||||
Part::Spline::onChanged(prop);
|
||||
}
|
||||
74
src/Mod/Surface/App/Blending/FeatureBlendCurve.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2014 Matteo Grellier <matteogrellier@gmail.com> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef FEATURE_BLEND_CURVE_H
|
||||
#define FEATURE_BLEND_CURVE_H
|
||||
|
||||
#include <App/PropertyLinks.h>
|
||||
#include <App/PropertyStandard.h>
|
||||
#include <App/PropertyUnits.h>
|
||||
#include <Mod/Part/App/FeaturePartSpline.h>
|
||||
#include <Mod/Surface/SurfaceGlobal.h>
|
||||
#include <Mod/Surface/App/Blending/BlendPoint.h>
|
||||
|
||||
namespace Surface
|
||||
{
|
||||
|
||||
class SurfaceExport FeatureBlendCurve: public Part::Spline
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(Surface::FeatureBlendCurve);
|
||||
|
||||
public:
|
||||
|
||||
FeatureBlendCurve();
|
||||
|
||||
App::PropertyLinkSub StartEdge;
|
||||
App::PropertyFloatConstraint StartParameter;
|
||||
App::PropertyIntegerConstraint StartContinuity;
|
||||
App::PropertyFloat StartSize;
|
||||
|
||||
App::PropertyLinkSub EndEdge;
|
||||
App::PropertyFloatConstraint EndParameter;
|
||||
App::PropertyIntegerConstraint EndContinuity;
|
||||
App::PropertyFloat EndSize;
|
||||
|
||||
Standard_Integer maxDegree;
|
||||
|
||||
App::DocumentObjectExecReturn *execute() override;
|
||||
short mustExecute() const override;
|
||||
const char *getViewProviderName() const override
|
||||
{
|
||||
return "SurfaceGui::ViewProviderBlendCurve";
|
||||
}
|
||||
|
||||
private:
|
||||
BlendPoint GetBlendPoint(App::PropertyLinkSub &link, App::PropertyFloatConstraint ¶m, App::PropertyIntegerConstraint &Continuity);
|
||||
double RelativeToRealParameters(double, double, double);
|
||||
bool lockOnChangeMutex;
|
||||
|
||||
protected:
|
||||
void onChanged(const App::Property *prop) override;
|
||||
};
|
||||
|
||||
}//Namespace Surface
|
||||
|
||||
#endif
|
||||
@@ -1,37 +1,87 @@
|
||||
if(MSVC)
|
||||
add_definitions(-DHAVE_ACOSH -DHAVE_ASINH -DHAVE_ATANH)
|
||||
add_definitions(-DHAVE_ACOSH -DHAVE_ASINH -DHAVE_ATANH)
|
||||
else(MSVC)
|
||||
add_definitions(-DHAVE_LIMITS_H -DHAVE_CONFIG_H)
|
||||
add_definitions(-DHAVE_LIMITS_H -DHAVE_CONFIG_H)
|
||||
endif(MSVC)
|
||||
|
||||
include_directories(
|
||||
${Boost_INCLUDE_DIRS}
|
||||
${OCC_INCLUDE_DIR}
|
||||
${PYTHON_INCLUDE_DIRS}
|
||||
${ZLIB_INCLUDE_DIR}
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_BINARY_DIR}/src
|
||||
${CMAKE_SOURCE_DIR}/src
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${Boost_INCLUDE_DIRS}
|
||||
${OCC_INCLUDE_DIR}
|
||||
${PYTHON_INCLUDE_DIRS}
|
||||
${ZLIB_INCLUDE_DIR}
|
||||
${FREETYPE_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
link_directories(${OCC_LIBRARY_DIR})
|
||||
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Blending)
|
||||
|
||||
generate_from_xml(Blending/BlendPointPy)
|
||||
generate_from_xml(Blending/BlendCurvePy)
|
||||
|
||||
set(Surface_LIBS
|
||||
FreeCADApp
|
||||
Part
|
||||
FreeCADApp
|
||||
Part
|
||||
)
|
||||
|
||||
# BlendPoint Wrapper
|
||||
SET(BlendingPy_SRCS
|
||||
Blending/BlendPointPy.xml
|
||||
Blending/BlendPointPyImp.cpp
|
||||
Blending/BlendCurvePy.xml
|
||||
Blending/BlendCurvePyImp.cpp
|
||||
)
|
||||
SOURCE_GROUP("Blending" FILES ${BlendingPy_SRCS})
|
||||
|
||||
SET(Blending_SRCS
|
||||
Blending/FeatureBlendCurve.cpp
|
||||
Blending/FeatureBlendCurve.h
|
||||
Blending/BlendPoint.cpp
|
||||
Blending/BlendPoint.h
|
||||
Blending/BlendCurve.cpp
|
||||
Blending/BlendCurve.h
|
||||
)
|
||||
|
||||
SET(BlendingPy_SRCS
|
||||
Blending/BlendPointPy.xml
|
||||
Blending/BlendPointPyImp.cpp
|
||||
Blending/BlendCurvePy.xml
|
||||
Blending/BlendCurvePyImp.cpp
|
||||
)
|
||||
SOURCE_GROUP("Blending" FILES ${BlendingPy_SRCS})
|
||||
|
||||
SET(Blending_SRCS
|
||||
Blending/FeatureBlendCurve.cpp
|
||||
Blending/FeatureBlendCurve.h
|
||||
Blending/BlendPoint.cpp
|
||||
Blending/BlendPoint.h
|
||||
Blending/BlendCurve.cpp
|
||||
Blending/BlendCurve.h
|
||||
)
|
||||
|
||||
SET(Surface_SRCS
|
||||
AppSurface.cpp
|
||||
PreCompiled.cpp
|
||||
PreCompiled.h
|
||||
FeatureExtend.cpp
|
||||
FeatureExtend.h
|
||||
FeatureGeomFillSurface.cpp
|
||||
FeatureGeomFillSurface.h
|
||||
FeatureFilling.cpp
|
||||
FeatureFilling.h
|
||||
FeatureSections.cpp
|
||||
FeatureSections.h
|
||||
FeatureSewing.cpp
|
||||
FeatureSewing.h
|
||||
FeatureCut.cpp
|
||||
FeatureCut.h
|
||||
${Blending_SRCS}
|
||||
${BlendingPy_SRCS}
|
||||
AppSurface.cpp
|
||||
PreCompiled.cpp
|
||||
PreCompiled.h
|
||||
FeatureExtend.cpp
|
||||
FeatureExtend.h
|
||||
FeatureGeomFillSurface.cpp
|
||||
FeatureGeomFillSurface.h
|
||||
FeatureFilling.cpp
|
||||
FeatureFilling.h
|
||||
FeatureSections.cpp
|
||||
FeatureSections.h
|
||||
FeatureSewing.cpp
|
||||
FeatureSewing.h
|
||||
FeatureCut.cpp
|
||||
FeatureCut.h
|
||||
)
|
||||
|
||||
link_directories(${OCC_LIBRARY_DIR})
|
||||
|
||||
@@ -24,15 +24,16 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include <Base/Console.h>
|
||||
#include <Base/PyObjectBase.h>
|
||||
#include <Base/Interpreter.h>
|
||||
#include <Base/PyObjectBase.h>
|
||||
#include <Gui/Application.h>
|
||||
|
||||
#include "Workbench.h"
|
||||
#include "TaskGeomFillSurface.h"
|
||||
#include "Blending/ViewProviderBlendCurve.h"
|
||||
#include "TaskFilling.h"
|
||||
#include "TaskGeomFillSurface.h"
|
||||
#include "TaskSections.h"
|
||||
#include "ViewProviderExtend.h"
|
||||
#include "Workbench.h"
|
||||
|
||||
|
||||
// use a different name to CreateCommand()
|
||||
@@ -45,7 +46,7 @@ class Module : public Py::ExtensionModule<Module>
|
||||
public:
|
||||
Module() : Py::ExtensionModule<Module>("SurfaceGui")
|
||||
{
|
||||
initialize("This module is the SurfaceGui module."); // register with Python
|
||||
initialize("This module is the SurfaceGui module.");// register with Python
|
||||
}
|
||||
|
||||
~Module() override {}
|
||||
@@ -53,12 +54,11 @@ public:
|
||||
private:
|
||||
};
|
||||
|
||||
PyObject* initModule()
|
||||
{
|
||||
PyObject *initModule() {
|
||||
return Base::Interpreter().addModule(new Module);
|
||||
}
|
||||
|
||||
} // namespace SurfaceGui
|
||||
}// namespace SurfaceGui
|
||||
|
||||
/* Python entry */
|
||||
PyMOD_INIT_FUNC(SurfaceGui)
|
||||
@@ -78,10 +78,11 @@ PyMOD_INIT_FUNC(SurfaceGui)
|
||||
SurfaceGui::ViewProviderGeomFillSurface ::init();
|
||||
SurfaceGui::ViewProviderFilling ::init();
|
||||
SurfaceGui::ViewProviderSections ::init();
|
||||
SurfaceGui::ViewProviderExtend::init();
|
||||
SurfaceGui::ViewProviderExtend ::init();
|
||||
SurfaceGui::ViewProviderBlendCurve ::init();
|
||||
// SurfaceGui::ViewProviderCut::init();
|
||||
|
||||
PyObject* mod = SurfaceGui::initModule();
|
||||
PyObject *mod = SurfaceGui::initModule();
|
||||
Base::Console().Log("Loading GUI of Surface module... done\n");
|
||||
PyMOD_Return(mod);
|
||||
}
|
||||
|
||||
38
src/Mod/Surface/Gui/Blending/ViewProviderBlendCurve.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2022 Matteo Grellier <matteogrellier@gmail.com> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include <Gui/BitmapFactory.h>
|
||||
#include "ViewProviderBlendCurve.h"
|
||||
|
||||
PROPERTY_SOURCE(SurfaceGui::ViewProviderBlendCurve, PartGui::ViewProviderSpline)
|
||||
|
||||
namespace SurfaceGui
|
||||
{
|
||||
|
||||
QIcon ViewProviderBlendCurve::getIcon() const
|
||||
{
|
||||
return Gui::BitmapFactory().pixmap("BlendCurve");
|
||||
}
|
||||
|
||||
}//namespace SurfaceGui
|
||||
41
src/Mod/Surface/Gui/Blending/ViewProviderBlendCurve.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2022 Matteo Grellier <matteogrellier@gmail.com> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef SURFACEGUI_VIEWPROVIDERBLENDCURVE_H
|
||||
#define SURFACEGUI_VIEWPROVIDERBLENDCURVE_H
|
||||
|
||||
#include <Mod/Part/Gui/ViewProviderSpline.h>
|
||||
|
||||
namespace SurfaceGui
|
||||
{
|
||||
|
||||
class ViewProviderBlendCurve: public PartGui::ViewProviderSpline
|
||||
{
|
||||
PROPERTY_HEADER(SurfaceGui::ViewProviderBlendCurve);
|
||||
|
||||
public:
|
||||
QIcon getIcon() const;
|
||||
};
|
||||
|
||||
}//namespace SurfaceGui
|
||||
|
||||
#endif// SURFACEGUI_VIEWPROVIDEREXTEND_H
|
||||
@@ -9,6 +9,7 @@ include_directories(
|
||||
${CMAKE_SOURCE_DIR}/src
|
||||
${CMAKE_BINARY_DIR}/src
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${Boost_INCLUDE_DIRS}
|
||||
${COIN3D_INCLUDE_DIRS}
|
||||
${OCC_INCLUDE_DIR}
|
||||
@@ -36,6 +37,11 @@ SET(SurfaceGui_UIC_SRCS
|
||||
TaskSections.ui
|
||||
)
|
||||
|
||||
SET(BlendingGui_SRCS
|
||||
Blending/ViewProviderBlendCurve.cpp
|
||||
Blending/ViewProviderBlendCurve.h
|
||||
)
|
||||
|
||||
if (BUILD_QT5)
|
||||
qt5_wrap_ui(SurfaceGui_UIC_HDRS ${SurfaceGui_UIC_SRCS})
|
||||
else()
|
||||
@@ -45,6 +51,7 @@ endif()
|
||||
SET(SurfaceGui_SRCS
|
||||
${SurfaceGui_QRC_SRCS}
|
||||
${SurfaceGui_UIC_HDRS}
|
||||
${BlendingGui_SRCS}
|
||||
TaskFilling.cpp
|
||||
TaskFilling.h
|
||||
TaskFillingEdge.cpp
|
||||
|
||||
@@ -61,6 +61,8 @@
|
||||
#include <App/PropertyUnits.h>
|
||||
#include <App/PropertyLinks.h>
|
||||
#include "Mod/Part/App/PartFeature.h"
|
||||
#include <BRepAdaptor_Curve.hxx>
|
||||
#include <GeomAPI_ProjectPointOnCurve.hxx>
|
||||
|
||||
|
||||
//===========================================================================
|
||||
@@ -189,6 +191,8 @@ void CmdSurfaceGeomFillSurface::activated(int iMsg)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
DEF_STD_CMD_A(CmdSurfaceCurveOnMesh)
|
||||
|
||||
CmdSurfaceCurveOnMesh::CmdSurfaceCurveOnMesh()
|
||||
@@ -204,6 +208,8 @@ CmdSurfaceCurveOnMesh::CmdSurfaceCurveOnMesh()
|
||||
sPixmap = "Surface_CurveOnMesh";
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CmdSurfaceCurveOnMesh::activated(int)
|
||||
{
|
||||
doCommand(Doc,"import MeshPartGui, FreeCADGui\n"
|
||||
@@ -224,6 +230,118 @@ bool CmdSurfaceCurveOnMesh::isActive()
|
||||
return false;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// CmdBlendSurface THIS IS THE BLEND SURFACE COMMAND
|
||||
//===========================================================================
|
||||
DEF_STD_CMD_A(CmdBlendSurface)
|
||||
|
||||
CmdBlendSurface::CmdBlendSurface()
|
||||
: Command("Surface_BlendSurface")
|
||||
{
|
||||
sAppModule = "Surface";
|
||||
sGroup = QT_TR_NOOP("Surface");
|
||||
sMenuText = QT_TR_NOOP("Blend Surface");
|
||||
sToolTipText = QT_TR_NOOP("This is the blend Surface feature");
|
||||
sStatusTip = sToolTipText;
|
||||
sWhatsThis = "BlendSurface";
|
||||
sPixmap = "BlendSurface";
|
||||
}
|
||||
|
||||
void CmdBlendSurface::activated(int)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool CmdBlendSurface::isActive()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//===========================================================================
|
||||
// CmdBlendCurve THIS IS THE BLEND CURVE COMMAND
|
||||
//===========================================================================
|
||||
DEF_STD_CMD_A(CmdBlendCurve)
|
||||
|
||||
CmdBlendCurve::CmdBlendCurve()
|
||||
: Command("Surface_BlendCurve")
|
||||
{
|
||||
sAppModule = "Surface";
|
||||
sGroup = QT_TR_NOOP("Surface");
|
||||
sMenuText = QT_TR_NOOP("Blend Curve");
|
||||
sToolTipText = QT_TR_NOOP("Join two edges with high continuity");
|
||||
sStatusTip = sToolTipText;
|
||||
sWhatsThis = "BlendCurve";
|
||||
sPixmap = "BlendCurve";
|
||||
}
|
||||
|
||||
void CmdBlendCurve::activated(int)
|
||||
{
|
||||
// To do add pickpoints to parameters
|
||||
std::string docName = App::GetApplication().getActiveDocument()->getName();
|
||||
std::string objName[2];
|
||||
std::string edge[2];
|
||||
std::string featName = getUniqueObjectName("BlendCurve");
|
||||
std::vector<Gui::SelectionObject> sel = getSelection().getSelectionEx(0, Part::Feature::getClassTypeId());
|
||||
//std::vector<Base::Vector3d> pickedPoints = sel[0].getPickedPoints();
|
||||
//App::DocumentObject *obj1 = sel[0].getObject();
|
||||
//App::DocumentObject *obj2 = sel[1].getObject();
|
||||
//std::vector<std::string> edge1SubName = sel[0].getSubNames();
|
||||
//std::vector<std::string> edge2SubName = sel[1].getSubNames();
|
||||
|
||||
//TopoDS_Shape edge1 = static_cast<Part::Feature *>(obj1)
|
||||
// ->Shape.getShape()
|
||||
// .getSubShape(edge1SubName[0].c_str());
|
||||
//if (edge1.IsNull() || edge1.ShapeType() != TopAbs_EDGE)
|
||||
// return;
|
||||
//TopoDS_Shape edge2 = static_cast<Part::Feature *>(obj2)
|
||||
// ->Shape.getShape()
|
||||
// .getSubShape(edge2SubName[0].c_str());
|
||||
//if (edge2.IsNull() || edge2.ShapeType() != TopAbs_EDGE)
|
||||
// return;
|
||||
|
||||
//const TopoDS_Edge &e1 = TopoDS::Edge(edge1);
|
||||
//BRepAdaptor_Curve adapt1(e1);
|
||||
//gp_Pnt pnt1(pickedPoints[0].x, pickedPoints[0].y, pickedPoints[0].z);
|
||||
|
||||
//GeomAdaptor_Curve geomCurve = adapt1.Curve();
|
||||
//GeomAPI_ProjectPointOnCurve geomAPI(pnt1, geomCurve.Curve());
|
||||
//double par = geomAPI.LowerDistanceParameter();
|
||||
|
||||
//edge2.Curve.closestParameter(vec, par)
|
||||
|
||||
objName[0] = sel[0].getFeatName();
|
||||
edge[0] = sel[0].getSubNames()[0];
|
||||
|
||||
if (sel.size() == 1) {
|
||||
objName[1] = sel[0].getFeatName();
|
||||
edge[1] = sel[0].getSubNames()[1];
|
||||
}
|
||||
else {
|
||||
objName[1] = sel[1].getFeatName();
|
||||
edge[1] = sel[1].getSubNames()[0];
|
||||
}
|
||||
openCommand(QT_TRANSLATE_NOOP("Command", "Blend Curve"));
|
||||
doCommand(Doc, "App.ActiveDocument.addObject(\"Surface::FeatureBlendCurve\",\"%s\")", featName.c_str());
|
||||
doCommand(Doc, "App.ActiveDocument.%s.StartEdge = (App.getDocument('%s').getObject('%s'),['%s'])", featName.c_str(), docName.c_str(), objName[0].c_str(), edge[0].c_str());
|
||||
doCommand(Doc, "App.ActiveDocument.%s.EndEdge = (App.getDocument('%s').getObject('%s'),['%s'])", featName.c_str(), docName.c_str(), objName[1].c_str(), edge[1].c_str());
|
||||
updateActive();
|
||||
commitCommand();
|
||||
}
|
||||
|
||||
bool CmdBlendCurve::isActive()
|
||||
{
|
||||
Gui::SelectionFilter edgeFilter("SELECT Part::Feature SUBELEMENT Edge COUNT 2");
|
||||
return edgeFilter.match();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
DEF_STD_CMD_A(CmdSurfaceExtendFace)
|
||||
|
||||
CmdSurfaceExtendFace::CmdSurfaceExtendFace()
|
||||
@@ -306,4 +424,6 @@ void CreateSurfaceCommands()
|
||||
rcCmdMgr.addCommand(new CmdSurfaceSections());
|
||||
rcCmdMgr.addCommand(new CmdSurfaceExtendFace());
|
||||
rcCmdMgr.addCommand(new CmdSurfaceCurveOnMesh());
|
||||
rcCmdMgr.addCommand(new CmdBlendCurve());
|
||||
rcCmdMgr.addCommand(new CmdBlendSurface());
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<file>icons/Surface_BSplineSurface.svg</file>
|
||||
<file>icons/Surface_CurveOnMesh.svg</file>
|
||||
<file>icons/Surface_Cut.svg</file>
|
||||
<file>icons/BlendCurve.svg</file>
|
||||
<file>icons/Surface_ExtendFace.svg</file>
|
||||
<file>icons/Surface_Filling.svg</file>
|
||||
<file>icons/Surface_GeomFillSurface.svg</file>
|
||||
@@ -11,6 +12,7 @@
|
||||
<file>icons/Surface_Sewing.svg</file>
|
||||
<file>icons/Surface_Surface.svg</file>
|
||||
<file>icons/Surface_Workbench.svg</file>
|
||||
<file>icons/BlendSurface.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
|
||||
30
src/Mod/Surface/Gui/Resources/icons/BlendCurve.svg
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
191
src/Mod/Surface/Gui/Resources/icons/BlendSurface.svg
Normal file
@@ -0,0 +1,191 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
version="1.1"
|
||||
id="svg2985"
|
||||
height="64px"
|
||||
width="64px">
|
||||
<title
|
||||
id="title889">Surface_Sewing</title>
|
||||
<defs
|
||||
id="defs2987">
|
||||
<linearGradient
|
||||
id="linearGradient4387">
|
||||
<stop
|
||||
id="stop4389"
|
||||
offset="0"
|
||||
style="stop-color:#71b2f8;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop4391"
|
||||
offset="1"
|
||||
style="stop-color:#002795;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient6321">
|
||||
<stop
|
||||
id="stop6323"
|
||||
offset="0"
|
||||
style="stop-color:#71b2f8;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop6325"
|
||||
offset="1"
|
||||
style="stop-color:#002795;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
gradientTransform="translate(-0.23443224,0.23443198)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
r="19.467436"
|
||||
fy="28.869568"
|
||||
fx="45.883327"
|
||||
cy="28.869568"
|
||||
cx="45.883327"
|
||||
id="radialGradient3692"
|
||||
xlink:href="#linearGradient3377" />
|
||||
<linearGradient
|
||||
id="linearGradient3377">
|
||||
<stop
|
||||
style="stop-color:#faff2b;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3379" />
|
||||
<stop
|
||||
style="stop-color:#ffaa00;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3381" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3377-3">
|
||||
<stop
|
||||
style="stop-color:#faff2b;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3379-8" />
|
||||
<stop
|
||||
style="stop-color:#ffaa00;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3381-3" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
r="19.467436"
|
||||
fy="28.869568"
|
||||
fx="45.883327"
|
||||
cy="28.869568"
|
||||
cx="45.883327"
|
||||
gradientTransform="matrix(0.67067175,0,0,0.64145918,-63.380792,0.83845403)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient6412"
|
||||
xlink:href="#linearGradient3377-3" />
|
||||
<linearGradient
|
||||
id="linearGradient3036">
|
||||
<stop
|
||||
style="stop-color:#ef2929;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3038" />
|
||||
<stop
|
||||
style="stop-color:#a40000;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3040" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientTransform="matrix(0.96812402,0,0,0.96755864,-0.72057496,-2.6783592)"
|
||||
xlink:href="#linearGradient1189"
|
||||
id="linearGradient2095"
|
||||
x1="47"
|
||||
y1="9"
|
||||
x2="7"
|
||||
y2="28"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient1189">
|
||||
<stop
|
||||
style="stop-color:#204a87;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop1185" />
|
||||
<stop
|
||||
style="stop-color:#729fcf;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop1187" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<metadata
|
||||
id="metadata2990">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>Surface_Sewing</dc:title>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>[bitacovir]</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:title>Part_Shape_from_Mesh</dc:title>
|
||||
<dc:date>2020/10/03</dc:date>
|
||||
<dc:relation>http://www.freecadweb.org/wiki/index.php?title=Artwork</dc:relation>
|
||||
<dc:publisher>
|
||||
<cc:Agent>
|
||||
<dc:title>FreeCAD</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:publisher>
|
||||
<dc:identifier />
|
||||
<dc:rights>
|
||||
<cc:Agent>
|
||||
<dc:title>FreeCAD LGPL2+</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:rights>
|
||||
<cc:license>https://www.gnu.org/copyleft/lesser.html</cc:license>
|
||||
<dc:contributor>
|
||||
<cc:Agent>
|
||||
<dc:title />
|
||||
</cc:Agent>
|
||||
</dc:contributor>
|
||||
<dc:subject>
|
||||
<rdf:Bag>
|
||||
<rdf:li>surface</rdf:li>
|
||||
</rdf:Bag>
|
||||
</dc:subject>
|
||||
<dc:description />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1">
|
||||
<path
|
||||
style="display:inline;fill:url(#linearGradient2095);fill-opacity:1;stroke:#0b1521;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 3.1519208,24.413282 17.899691,60.320494 c 14.52186,-34.832109 31.154371,7.93994 42.771854,-25.924611 L 38.972508,3.1269928 C 30.809307,30.407148 17.749067,-0.16084869 3.1519208,24.413282 Z"
|
||||
id="path3820-1-9" />
|
||||
<path
|
||||
id="path3820-1-9-6"
|
||||
d="M 5.3492197,24.626663 18.113409,55.643482 C 32.677175,26.678261 49.470489,63.641047 58.406281,34.501823 L 39.63819,7.4361573 C 30.967406,29.589343 16.774125,4.5857267 5.3492197,24.626663 Z"
|
||||
style="display:inline;fill:none;fill-opacity:1;stroke:#729fcf;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;stroke:#0b1521;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 10.982526,42.149889 C 22.049849,14.305576 38.645757,44.184548 50.089385,20.093327"
|
||||
id="path1219-0" />
|
||||
<path
|
||||
id="path882"
|
||||
d="m 27.670296,26.630997 c 10.9647,1.930433 15.10812,2.91774 20.11825,-7.524843"
|
||||
style="fill:none;stroke:#729fcf;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="path859"
|
||||
d="m 38.193663,21.887236 9.330416,13.952023"
|
||||
style="fill:none;stroke:#0b1521;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;stroke:#729fcf;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 31.751036,32.387618 C 22.26124,30.47478 16.502839,32.473328 13.131071,43.29124"
|
||||
id="path882-9" />
|
||||
<path
|
||||
style="fill:none;stroke:#0b1521;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 13.709416,25.210411 21.313357,40.45729"
|
||||
id="path859-1" />
|
||||
<path
|
||||
style="fill:none;stroke:#0b1521;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 25.62034,22.195278 7.9739,14.506961"
|
||||
id="path859-0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.7 KiB |
@@ -44,40 +44,42 @@ Workbench::~Workbench()
|
||||
{
|
||||
}
|
||||
|
||||
Gui::MenuItem* Workbench::setupMenuBar() const
|
||||
Gui::MenuItem *Workbench::setupMenuBar() const
|
||||
{
|
||||
Gui::MenuItem* root = StdWorkbench::setupMenuBar();
|
||||
Gui::MenuItem* item = root->findItem( "&Windows" );
|
||||
Gui::MenuItem *root = StdWorkbench::setupMenuBar();
|
||||
Gui::MenuItem *item = root->findItem("&Windows");
|
||||
|
||||
Gui::MenuItem* surface = new Gui::MenuItem;
|
||||
root->insertItem( item, surface );
|
||||
Gui::MenuItem *surface = new Gui::MenuItem;
|
||||
root->insertItem(item, surface);
|
||||
surface->setCommand("Surface");
|
||||
*surface << "Surface_Filling"
|
||||
<< "Surface_GeomFillSurface"
|
||||
<< "Surface_Sections"
|
||||
<< "Surface_ExtendFace"
|
||||
<< "Surface_CurveOnMesh";
|
||||
/*
|
||||
<< "Surface_CurveOnMesh"
|
||||
<< "Surface_BlendCurve";
|
||||
/*
|
||||
*surface << "Surface_Cut";
|
||||
*/
|
||||
*/
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
Gui::ToolBarItem* Workbench::setupToolBars() const
|
||||
Gui::ToolBarItem *Workbench::setupToolBars() const
|
||||
{
|
||||
Gui::ToolBarItem* root = StdWorkbench::setupToolBars();
|
||||
Gui::ToolBarItem *root = StdWorkbench::setupToolBars();
|
||||
|
||||
Gui::ToolBarItem* surface = new Gui::ToolBarItem(root);
|
||||
Gui::ToolBarItem *surface = new Gui::ToolBarItem(root);
|
||||
surface->setCommand("Surface");
|
||||
*surface << "Surface_Filling"
|
||||
<< "Surface_GeomFillSurface"
|
||||
<< "Surface_Sections"
|
||||
<< "Surface_ExtendFace"
|
||||
<< "Surface_CurveOnMesh";
|
||||
/*
|
||||
<< "Surface_CurveOnMesh"
|
||||
<< "Surface_BlendCurve";
|
||||
/*
|
||||
*surface << "Surface_Cut";
|
||||
*/
|
||||
*/
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ DrawProjGroup::DrawProjGroup()
|
||||
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter().GetGroup("BaseApp")->
|
||||
GetGroup("Preferences")->GetGroup("Mod/TechDraw/General");
|
||||
bool autoDist = hGrp->GetBool("AutoDist",true);
|
||||
|
||||
|
||||
ADD_PROPERTY_TYPE(Source, (nullptr), group, App::Prop_None, "Shape to view");
|
||||
Source.setScope(App::LinkScope::Global);
|
||||
Source.setAllowExternal(true);
|
||||
@@ -268,7 +268,7 @@ bool DrawProjGroup::checkFit() const
|
||||
{
|
||||
// Base::Console().Message("DPG::checkFit() - %s\n", getNameInDocument());
|
||||
if (waitingForChildren()) {
|
||||
//assume everything fits since we don't know what size the chilren are
|
||||
//assume everything fits since we don't know what size the children are
|
||||
return true;
|
||||
}
|
||||
auto page = findParentPage();
|
||||
@@ -348,7 +348,7 @@ void DrawProjGroup::getViewArea(DrawProjGroupItem *viewPtrs[10],
|
||||
// Get the child view bounding boxes
|
||||
Base::BoundBox3d bboxes[10];
|
||||
makeViewBbs(viewPtrs, bboxes, scaled);
|
||||
|
||||
|
||||
//TODO: note that TLF/TRF/BLF,BRF extend a bit farther than a strict row/col arrangement would suggest.
|
||||
//get widest view in each row/column
|
||||
double col0w = std::max(std::max(bboxes[0].LengthX(), bboxes[3].LengthX()), bboxes[7].LengthX()),
|
||||
@@ -514,7 +514,7 @@ int DrawProjGroup::removeProjection(const char *viewProjType)
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//removes all DPGI - used when deleting DPG
|
||||
int DrawProjGroup::purgeProjections()
|
||||
@@ -576,7 +576,7 @@ std::pair<Base::Vector3d,Base::Vector3d> DrawProjGroup::getDirsFromFront(std::st
|
||||
gp_Ax2 newCS;
|
||||
gp_Dir gNewDir;
|
||||
gp_Dir gNewXDir;
|
||||
|
||||
|
||||
double angle = M_PI / 2.0; //90*
|
||||
|
||||
if (viewType == "Right") {
|
||||
|
||||
@@ -587,7 +587,7 @@ void BaseGeom::intersectionLL(TechDraw::BaseGeomPtr geom1,
|
||||
// Taken from: <http://de.wikipedia.org/wiki/Schnittpunkt>
|
||||
TechDraw::GenericPtr gen1 = std::static_pointer_cast<TechDraw::Generic>(geom1);
|
||||
TechDraw::GenericPtr gen2 = std::static_pointer_cast<TechDraw::Generic>(geom2);
|
||||
// we calculate vectors to start points and direction verctors
|
||||
// we calculate vectors to start points and direction vectors
|
||||
Base::Vector3d startPnt1 = gen1->points.at(0);
|
||||
Base::Vector3d endPnt1 = gen1->points.at(1);
|
||||
Base::Vector3d startPnt2 = gen2->points.at(0);
|
||||
|
||||
@@ -48,7 +48,7 @@ DlgPrefsTechDrawAnnotationImp::DlgPrefsTechDrawAnnotationImp( QWidget* parent )
|
||||
ui->setupUi(this);
|
||||
ui->pdsbBalloonKink->setUnit(Base::Unit::Length);
|
||||
ui->pdsbBalloonKink->setMinimum(0);
|
||||
|
||||
|
||||
// connect the LineGroup the update the tooltip if index changed
|
||||
connect(ui->pcbLineGroup, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(onLineGroupChanged(int)));
|
||||
@@ -98,7 +98,7 @@ void DlgPrefsTechDrawAnnotationImp::loadSettings()
|
||||
for (auto it = lgNames.begin(); it < lgNames.end(); ++it) {
|
||||
ui->pcbLineGroup->addItem(tr((*it).c_str()));
|
||||
}
|
||||
|
||||
|
||||
ui->cbAutoHoriz->onRestore();
|
||||
ui->cbPrintCenterMarks->onRestore();
|
||||
ui->cbPyramidOrtho->onRestore();
|
||||
@@ -147,7 +147,7 @@ void DlgPrefsTechDrawAnnotationImp::onLineGroupChanged(int index)
|
||||
ui->pcbLineGroup->setToolTip(QObject::tr("Please select a Line Group"));
|
||||
return;
|
||||
}
|
||||
// get the definition the the selected LineGroup (includes the name)
|
||||
// get the definition of the selected LineGroup (includes the name)
|
||||
std::string lgRecord = LineGroup::getRecordFromFile(Preferences::lineGroupFile(), index);
|
||||
std::stringstream ss(lgRecord);
|
||||
std::vector<std::string> lgNames;
|
||||
|
||||
@@ -275,7 +275,7 @@ e">
|
||||
<polygon points="598,828 606,828 602,834" />
|
||||
</g>
|
||||
|
||||
<g id="bunding hole">
|
||||
<g id="binding hole">
|
||||
<g stroke="black" stroke-width="0.5" fill="#BBBBBB" stroke="#666666" >
|
||||
<circle cx="10" cy="571.5" r="3" />
|
||||
<circle cx="10" cy="609.5" r="3" />
|
||||
|
||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
@@ -253,7 +253,7 @@ e">
|
||||
<polygon points="423.99998,581 432.49998,581 427.99998,587" />
|
||||
</g>
|
||||
|
||||
<g id="bunding hole">
|
||||
<g id="binding hole">
|
||||
<g stroke="black" stroke-width="0.5" fill="#BBBBBB" stroke="#666666" >
|
||||
<circle cx="10" cy="324.5" r="3" />
|
||||
<circle cx="10" cy="362.5" r="3" />
|
||||
|
||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
@@ -233,7 +233,7 @@ nter;fill:#000000;"><tspan></tspan></text>
|
||||
<path d="m 354.5,410 v 5" />
|
||||
</g>
|
||||
|
||||
<g id="bunding hole">
|
||||
<g id="binding hole">
|
||||
<g stroke="black" stroke-width="0.5" fill="#BBBBBB" stroke="#666666" >
|
||||
<circle cx="10" cy="150.5" r="3" />
|
||||
<circle cx="10" cy="188.5" r="3" />
|
||||
|
||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
@@ -183,7 +183,7 @@
|
||||
<!-- project mark end -->
|
||||
</g>
|
||||
|
||||
<g id="bunding hole">
|
||||
<g id="binding hole">
|
||||
<g stroke="black" stroke-width="0.5" fill="#BBBBBB" stroke="#666666" >
|
||||
<circle cx="10" cy="27.5" r="3" />
|
||||
<circle cx="10" cy="65.5" r="3" />
|
||||
|
||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
@@ -166,7 +166,7 @@
|
||||
</g>
|
||||
|
||||
<!--
|
||||
<g id="bunding hole">
|
||||
<g id="binding hole">
|
||||
<g stroke="black" stroke-width="0.5" fill="#BBBBBB" stroke="#888888" >
|
||||
<circle cx="12.5" cy="25" r="3" />
|
||||
<circle cx="12.5" cy="105" r="3" />
|
||||
|
||||
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
@@ -188,7 +188,7 @@
|
||||
<!-- project mark end -->
|
||||
</g>
|
||||
|
||||
<g id="bunding hole">
|
||||
<g id="binding hole">
|
||||
<g stroke="black" stroke-width="0.5" fill="#BBBBBB" stroke="#666666" >
|
||||
<circle cx="10" cy="150.5" r="3" />
|
||||
<circle cx="10" cy="188.5" r="3" />
|
||||
|
||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
@@ -167,7 +167,7 @@
|
||||
<!-- project mark end -->
|
||||
</g>
|
||||
|
||||
<g id="bunding hole">
|
||||
<g id="binding hole">
|
||||
<g stroke="black" stroke-width="0.5" fill="#BBBBBB" stroke="#666666" >
|
||||
<circle cx="10" cy="27.5" r="3" />
|
||||
<circle cx="10" cy="65.5" r="3" />
|
||||
|
||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
@@ -547,7 +547,7 @@ class ViewProviderMolecule:
|
||||
sep2.addChild(coin.SoSphere())
|
||||
obj.RootNode.addChild(sep1)
|
||||
obj.RootNode.addChild(sep2)
|
||||
# triggers an updateData call so the the assignment at the end
|
||||
# triggers an updateData call so the assignment at the end
|
||||
obj.Proxy = self
|
||||
|
||||
def updateData(self, fp, prop):
|
||||
|
||||
@@ -7,7 +7,7 @@ DistInst = DistName + "_installer.msi"
|
||||
DistDir = "../../DistTemp/"
|
||||
|
||||
#====================================================================
|
||||
# copy intaller file
|
||||
# copy installer file
|
||||
|
||||
FileTools.cpfile("../../Install/FreeCAD.msi",DistDir+DistInst)
|
||||
|
||||
|
||||