Fix the issue related to the on-the-fly projection to sketch, when projecting a periodic B-spline curve orthogonal to the sketch plane.
return newBSpline2d(thePoles, theWeights, theDegree, thePeriodic);
int anAuxPole = 0;
- if (thePeriodic && thePoles.front()->distance(thePoles.back()) < Precision::Confusion())
- anAuxPole = -1;
+ if (thePeriodic && thePoles.front()->distance(thePoles.back()) < Precision::Confusion()) {
+ // additionally check the number of poles is greater than needed for th periodic B-spline
+ int aNbPoles = 0;
+ std::list<int>::const_iterator it = theMults.begin();
+ for (++it; it != theMults.end(); ++it)
+ aNbPoles += *it;
+ if ((int)thePoles.size() > aNbPoles)
+ anAuxPole = -1;
+ }
// collect arrays of poles, weights, knots and multiplicities
TColgp_Array1OfPnt2d aPoles(1, (int)thePoles.size() + anAuxPole);
anIntoResult->setValue(SKETCH_PROJECTION_INCLUDE_INTO_RESULT);
aProjectionFeature->execute();
+ ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators();
+ bool isValid = aValidators->validate(aProjectionFeature);
+
// if projection feature has not been created, exit
AttributeRefAttrPtr aRefAttr = aProjectionFeature->data()->refattr(
SketchPlugin_Projection::PROJECTED_FEATURE_ID());
- if (!aRefAttr || !aRefAttr->isInitialized())
+ if (!isValid || !aRefAttr || !aRefAttr->isInitialized())
{
// remove external feature if the attribute is not filled
std::set<FeaturePtr> aFeatures;
#include <GeomAlgoAPI_EdgeBuilder.h>
#include <GeomAlgoAPI_ShapeTools.h>
+#include <GeomAPI_BSpline.h>
#include <GeomAPI_Circ.h>
#include <GeomAPI_Dir2d.h>
#include <GeomAPI_Ellipse.h>
theError.arg(anEdge->isClosed() ? "Error: Ellipse is orthogonal to the sketch plane."
: "Error: Elliptic Arc is orthogonal to the sketch plane.");
}
+ else if (anEdge->isBSpline()) {
+ // check B-spline is periodic and planar
+ std::shared_ptr<GeomAPI_Curve> aCurve(new GeomAPI_Curve(anEdge));
+ std::shared_ptr<GeomAPI_BSpline> aBSpline(new GeomAPI_BSpline(aCurve));
+ if (aBSpline->isPeriodic()) {
+ GeomPlanePtr aBSplinePlane = GeomAlgoAPI_ShapeTools::findPlane(ListOfShape(1, anEdge));
+ if (aBSplinePlane) {
+ std::shared_ptr<GeomAPI_Dir> aBSplineNormal = aBSplinePlane->direction();
+ double aDot = fabs(aNormal->dot(aBSplineNormal));
+ aValid = fabs(aDot - 1.0) <= tolerance * tolerance;
+ if (!aValid) {
+ // B-spline's plane is orthogonal to the sketch plane,
+ // thus, need to check whether B-spline is planar.
+ std::list<GeomPointPtr> aPoles = aBSpline->poles();
+ for (std::list<GeomPointPtr>::iterator it = aPoles.begin();
+ it != aPoles.end() && !aValid; ++it) {
+ if (aBSplinePlane->distance(*it) > tolerance)
+ aValid = true; // non-planar B-spline curve
+ }
+ if (!aValid)
+ theError = "Error: Periodic B-spline is orthogonal to the sketch plane.";
+ }
+ }
+ }
+ }
return aValid;
}
<source>Error: Elliptic Arc is orthogonal to the sketch plane.</source>
<translation>Error: Elliptic Arc is orthogonal to the sketch plane.</translation>
</message>
+ <message>
+ <source>Error: Periodic B-spline is orthogonal to the sketch plane.</source>
+ <translation>Error: Periodic B-spline is orthogonal to the sketch plane.</translation>
+ </message>
<message>
<source>Error: Selected object is not supported for projection.</source>
<translation>Error: Selected object is not supported for projection.</translation>
<source>Error: Elliptic Arc is orthogonal to the sketch plane.</source>
<translation>Erreur: L'arc d'ellipse est orthogonal au plan d'esquisse.</translation>
</message>
+ <message>
+ <source>Error: Periodic B-spline is orthogonal to the sketch plane.</source>
+ <translation>Erreur: La B-spline périodique est orthogonale au plan d'esquisse.</translation>
+ </message>
<message>
<source>Error: Selected object is not supported for projection.</source>
<translation>Erreur: L'objet sélectionné n'est pas pris en charge pour la projection.</translation>