BSplineSurface approximate, add parametrization type and smoothing algo
This commit is contained in:
@@ -683,14 +683,25 @@
|
||||
<UserDocu>Returns a reparametrized copy of this surface</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="approximate">
|
||||
<Methode Name="approximate" Keyword="true">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
approximate(points, degMin, degMax, continuity, tol)
|
||||
approximate(zPoints, degMin, degMax, continuity, tol, X0, dX, Y0, dY)
|
||||
|
||||
Replaces this B-Spline surface by approximating a set of points.
|
||||
continuity is an integer between 0 and 3
|
||||
This method uses keywords :
|
||||
- Points = 2Darray of points (or floats, in combination with X0, dX, Y0, dY)
|
||||
- DegMin (int), DegMax (int)
|
||||
- Continuity = 0,1 or 2 (for C0, C1, C2)
|
||||
- Tolerance (float)
|
||||
- X0, dX, Y0, dY (floats) with Points = 2Darray of floats
|
||||
- ParamType = 'Uniform','Centripetal' or 'ChordLength'
|
||||
- LengthWeight, CurvatureWeight, TorsionWeight (floats)
|
||||
|
||||
Possible combinations :
|
||||
- approximate(Points, DegMin, DegMax, Continuity, Tolerance)
|
||||
- approximate(Points, DegMin, DegMax, Continuity, Tolerance, X0, dX, Y0, dY)
|
||||
With explicit keywords :
|
||||
- approximate(Points, DegMin, DegMax, Continuity, Tolerance, ParamType)
|
||||
- approximate(Points, DegMax, Continuity, Tolerance, LengthWeight, CurvatureWeight, TorsionWeight)
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
|
||||
@@ -1235,21 +1235,25 @@ PyObject* BSplineSurfacePy::reparametrize(PyObject * args)
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* BSplineSurfacePy::approximate(PyObject *args)
|
||||
PyObject* BSplineSurfacePy::approximate(PyObject *args, PyObject *kwds)
|
||||
{
|
||||
PyObject* obj;
|
||||
Standard_Integer degMin=0;
|
||||
Standard_Integer degMax=0;
|
||||
Standard_Integer continuity=0;
|
||||
Standard_Integer degMin=3;
|
||||
Standard_Integer degMax=8;
|
||||
Standard_Integer continuity=2;
|
||||
Standard_Real tol3d = Precision::Approximation();
|
||||
char* parType = "None";
|
||||
Standard_Real weight1 = 1.0;
|
||||
Standard_Real weight2 = 1.0;
|
||||
Standard_Real weight3 = 1.0;
|
||||
Standard_Real X0=0;
|
||||
Standard_Real dX=0;
|
||||
Standard_Real Y0=0;
|
||||
Standard_Real dY=0;
|
||||
|
||||
int len = PyTuple_GET_SIZE(args);
|
||||
|
||||
if (!PyArg_ParseTuple(args, "Oiiid|dddd", &obj, °Min, °Max, &continuity, &tol3d, &X0, &dX, &Y0, &dY))
|
||||
static char* kwds_interp[] = {"Points", "DegMin", "DegMax", "Continuity", "Tolerance", "X0", "dX", "Y0", "dY", "ParamType", "LengthWeight", "CurvatureWeight", "TorsionWeight", NULL};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|iiidddddsddd", kwds_interp, &obj, °Min, °Max, &continuity, &tol3d, &X0, &dX, &Y0, &dY, &parType, &weight1, &weight2, &weight3))
|
||||
return 0;
|
||||
try {
|
||||
Py::Sequence list(obj);
|
||||
@@ -1268,7 +1272,7 @@ PyObject* BSplineSurfacePy::approximate(PyObject *args)
|
||||
Py::Sequence row(*it1);
|
||||
for (Py::Sequence::iterator it2 = row.begin(); it2 != row.end(); ++it2) {
|
||||
index2++;
|
||||
if(len == 5){
|
||||
if ((dX == 0) || (dY == 0)){
|
||||
Py::Vector v(*it2);
|
||||
Base::Vector3d pnt = v.toVector();
|
||||
gp_Pnt newPoint(pnt.x,pnt.y,pnt.z);
|
||||
@@ -1281,15 +1285,15 @@ PyObject* BSplineSurfacePy::approximate(PyObject *args)
|
||||
}
|
||||
}
|
||||
|
||||
if (continuity<0 || continuity>3) {
|
||||
Standard_Failure::Raise("continuity must be between 0 and 3");
|
||||
if (continuity<0 || continuity>2) {
|
||||
Standard_Failure::Raise("continuity must be between 0 and 2");
|
||||
}
|
||||
|
||||
if (interpolationPoints.RowLength() < 2 || interpolationPoints.ColLength() < 2) {
|
||||
Standard_Failure::Raise("not enough points given");
|
||||
}
|
||||
|
||||
GeomAbs_Shape c = GeomAbs_CN;
|
||||
GeomAbs_Shape c = GeomAbs_C2;
|
||||
switch(continuity){
|
||||
case 0:
|
||||
c = GeomAbs_C0;
|
||||
@@ -1300,17 +1304,43 @@ PyObject* BSplineSurfacePy::approximate(PyObject *args)
|
||||
case 2:
|
||||
c = GeomAbs_C2;
|
||||
break;
|
||||
case 3:
|
||||
c = GeomAbs_C3;
|
||||
break;
|
||||
}
|
||||
|
||||
Approx_ParametrizationType pt;
|
||||
std::string pstr = parType;
|
||||
Standard_Boolean useParam = Standard_True;
|
||||
if (pstr == "Uniform" )
|
||||
pt = Approx_IsoParametric;
|
||||
else if (pstr == "Centripetal" )
|
||||
pt = Approx_Centripetal;
|
||||
else if (pstr == "ChordLength" )
|
||||
pt = Approx_ChordLength;
|
||||
else
|
||||
useParam = Standard_False;
|
||||
|
||||
GeomAPI_PointsToBSplineSurface surInterpolation;
|
||||
if (len == 5) {
|
||||
surInterpolation.Init(interpolationPoints, degMin, degMax, c, tol3d);
|
||||
if (!(dX == 0) && !(dY == 0)) {
|
||||
// dX and dY are not null : we use the zPoints method
|
||||
surInterpolation.Init(zPoints, X0, dX, Y0, dY, degMin, degMax, c, tol3d);
|
||||
}
|
||||
else if (useParam) {
|
||||
// a parametrization type has been supplied
|
||||
surInterpolation.Init(interpolationPoints, pt, degMin, degMax, c, tol3d);
|
||||
}
|
||||
else if (!(weight1 == 0) || !(weight2 == 0) || !(weight3 == 0)) {
|
||||
// one of the weights is not null, we use the smoothing algorithm
|
||||
// adjust continuity for low values of degMax, instead of failing
|
||||
if (degMax < 3) {
|
||||
c = GeomAbs_C0;
|
||||
}
|
||||
else if ((degMax < 5) && (c == GeomAbs_C2)) {
|
||||
c = GeomAbs_C1;
|
||||
}
|
||||
surInterpolation.Init(interpolationPoints, weight1, weight2, weight3, degMax, c, tol3d);
|
||||
}
|
||||
else {
|
||||
surInterpolation.Init(zPoints, X0, dX, Y0, dY, degMin, degMax, c, tol3d);
|
||||
// fallback to strandard method
|
||||
surInterpolation.Init(interpolationPoints, degMin, degMax, c, tol3d);
|
||||
}
|
||||
Handle_Geom_BSplineSurface sur(surInterpolation.Surface());
|
||||
this->getGeomBSplineSurfacePtr()->setHandle(sur);
|
||||
@@ -1325,6 +1355,9 @@ PyObject* BSplineSurfacePy::approximate(PyObject *args)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PyObject* BSplineSurfacePy::interpolate(PyObject *args)
|
||||
{
|
||||
PyObject* obj;
|
||||
|
||||
Reference in New Issue
Block a user