const double theTolerance,
double& theParameter) const
{
- return GeomLib_Tool::Parameter(MY_BSPLINE, thePoint->impl<gp_Pnt2d>(),
- theTolerance, theParameter) == Standard_True;
+ const gp_Pnt2d& aPoint = thePoint->impl<gp_Pnt2d>();
+ bool isOk = GeomLib_Tool::Parameter(MY_BSPLINE, aPoint,
+ theTolerance, theParameter) == Standard_True;
+ if (!isOk) {
+ // Sometimes OCCT's Extrema algorithm cannot find the parameter on B-spline curve
+ // (usually, if the point is near the curve extremity).
+ // Workaround: compute distance to each boundary point
+ isOk = true;
+ double aDistPS = aPoint.Distance(MY_BSPLINE->Poles().First());
+ double aDistPE = aPoint.Distance(MY_BSPLINE->Poles().Last());
+ if (aDistPS < aDistPE && aDistPS < theTolerance)
+ theParameter = MY_BSPLINE->Knots().First();
+ else if (aDistPE < aDistPS && aDistPE < theTolerance)
+ theParameter = MY_BSPLINE->Knots().Last();
+ else
+ isOk = false;
+ }
+ return isOk;
}
void GeomAPI_BSpline2d::D0(const double theU, std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
std::shared_ptr<GeomAPI_XY> aDeriv;
myCurve->D1(u, aValue, aDeriv);
- return DeriVector2(aValue->x(), aValue->y(), aDeriv->x() * du, aDeriv->y() * du);
+ // calculate the derivative on solver's parameter
+ std::shared_ptr<GeomAPI_Pnt2d> aValueDeriv(new GeomAPI_Pnt2d(0.0, 0.0));
+ bool hasParam = false;
+ std::list<GeomPnt2dPtr> aPolesDeriv;
+ for (GCS::VEC_P::iterator anIt = poles.begin(); anIt != poles.end(); ++anIt) {
+ double x = 0.0, y = 0.0;
+ if (anIt->x == derivparam) {
+ x = 1.0;
+ hasParam = true;
+ }
+ else if (anIt->y == derivparam) {
+ y = 1.0;
+ hasParam = true;
+ }
+ aPolesDeriv.push_back(GeomPnt2dPtr(new GeomAPI_Pnt2d(x, y)));
+ }
+ if (hasParam) {
+ // use non-periodic curve, because the most of B-spline coefficients are 0,
+ // thus, it is not necessary to keep original knots and multiplicities to get correct value
+ std::shared_ptr<GeomAPI_BSpline2d> aCurveDeriv(
+ new GeomAPI_BSpline2d(degree, aPolesDeriv, myCachedWeights));
+ aCurveDeriv->D0(u, aValueDeriv);
+ }
+
+ return DeriVector2(aValue->x(), aValue->y(),
+ aValueDeriv->x() + aDeriv->x() * du, aValueDeriv->y() + aDeriv->y() * du);
}
DeriVector2 BSplineImpl::CalculateNormal(Point &p, double* derivparam)
rebuildCache();
double u = 0.0;
- if (!myCurve->parameter(GeomPnt2dPtr(new GeomAPI_Pnt2d(*p.x, *p.y)), 1e100, u)) {
- // Sometimes OCCT's Extrema algorithm cannot find the parameter on B-spline curve
- // (usually, if the point is near the curve extremity).
- // Workaround: compute distance to each boundary point
- double aDistPS = PlaneGCSSolver_Tools::distance(p, poles.front());
- double aDistPE = PlaneGCSSolver_Tools::distance(p, poles.back());
- static const double THE_TOLERANCE = 1.e-6;
- if (aDistPS < aDistPE && aDistPS < THE_TOLERANCE)
- u = *knots.front();
- else if (aDistPE < aDistPS && aDistPE < THE_TOLERANCE)
- u = *knots.back();
- else
- return DeriVector2();
- }
+ if (!myCurve->parameter(GeomPnt2dPtr(new GeomAPI_Pnt2d(*p.x, *p.y)), 1e100, u))
+ return DeriVector2();
std::shared_ptr<GeomAPI_Pnt2d> aValue;
std::shared_ptr<GeomAPI_XY> aDeriv;
#include <SketchPlugin_MultiTranslation.h>
#include <SketchPlugin_Point.h>
+#include <GeomAPI_BSpline2d.h>
#include <GeomAPI_Circ2d.h>
#include <GeomAPI_Dir2d.h>
#include <GeomAPI_Ellipse2d.h>
new GeomAPI_Ellipse2d(aCenter, anAxis, anEllipse->getRadMaj(), *anEllipse->radmin));
}
+std::shared_ptr<GeomAPI_BSpline2d> PlaneGCSSolver_Tools::bspline(EntityWrapperPtr theEntity)
+{
+ if (theEntity->type() != ENTITY_BSPLINE)
+ return std::shared_ptr<GeomAPI_BSpline2d>();
+
+ std::shared_ptr<PlaneGCSSolver_EdgeWrapper> anEntity =
+ std::dynamic_pointer_cast<PlaneGCSSolver_EdgeWrapper>(theEntity);
+ std::shared_ptr<GCS::BSpline> aSpline =
+ std::dynamic_pointer_cast<GCS::BSpline>(anEntity->entity());
+
+ std::list<GeomPnt2dPtr> aPoles;
+ for (GCS::VEC_P::iterator anIt = aSpline->poles.begin(); anIt != aSpline->poles.end(); ++anIt)
+ aPoles.push_back(GeomPnt2dPtr(new GeomAPI_Pnt2d(*anIt->x, *anIt->y)));
+
+ std::list<double> aWeights;
+ for (GCS::VEC_pD::iterator anIt = aSpline->weights.begin();
+ anIt != aSpline->weights.end(); ++anIt)
+ aWeights.push_back(**anIt);
+
+ std::list<double> aKnots;
+ for (GCS::VEC_pD::iterator anIt = aSpline->knots.begin(); anIt != aSpline->knots.end(); ++anIt)
+ aKnots.push_back(**anIt);
+
+ std::list<int> aMultiplicities;
+ aMultiplicities.assign(aSpline->mult.begin(), aSpline->mult.end());
+
+ return std::shared_ptr<GeomAPI_BSpline2d>(
+ new GeomAPI_BSpline2d(aSpline->degree, aPoles, aWeights,
+ aKnots, aMultiplicities, aSpline->periodic));
+}
+
void PlaneGCSSolver_Tools::recalculateArcParameters(EntityWrapperPtr theArc)
{
std::shared_ptr<PlaneGCSSolver_EdgeWrapper> anEdge =
#include <SketchSolver_ConstraintMovement.h>
#include <SketchPlugin_Constraint.h>
+class GeomAPI_BSpline2d;
class GeomAPI_Circ2d;
class GeomAPI_Ellipse2d;
class GeomAPI_Lin2d;
/// \brief Convert entity to ellipse
/// \return empty pointer if the entity is not an ellipse
std::shared_ptr<GeomAPI_Ellipse2d> ellipse(EntityWrapperPtr theEntity);
+ /// \brief Convert entity to Bs-pline
+ /// \return empty pointer if the entity is not an ellipse
+ std::shared_ptr<GeomAPI_BSpline2d> bspline(EntityWrapperPtr theEntity);
/// \brief Convert entity to line
/// \return empty pointer if the entity is not a line
#include <PlaneGCSSolver_Tools.h>
#include <PlaneGCSSolver_UpdateCoincidence.h>
+#include <GeomAPI_BSpline2d.h>
+#include <GeomAPI_Pnt2d.h>
+
#include <GeomDataAPI_Point2D.h>
#include <ModelAPI_AttributeInteger.h>
std::shared_ptr<PlaneGCSSolver_Storage> aStorage =
std::dynamic_pointer_cast<PlaneGCSSolver_Storage>(myStorage);
myAuxValue.reset(new PlaneGCSSolver_ScalarWrapper(aStorage->createParameter()));
+ // calculate the parameter of the point on B-spline nearest to the constrained point.
+ GeomPnt2dPtr aPoint = PlaneGCSSolver_Tools::point(theAttributes[0]);
+ std::shared_ptr<GeomAPI_BSpline2d> aSpline = PlaneGCSSolver_Tools::bspline(theAttributes[2]);
+ if (aPoint && aSpline)
+ aSpline->parameter(aPoint, 1.e100, *myAuxValue->scalar());
}
else {
// obtain extremity points of the coincident feature for further checking of multi-coincidence