From a0e5a98df2fa882a3a199f41f289e5e1c772c217 Mon Sep 17 00:00:00 2001 From: Artem Zhidkov Date: Thu, 25 Jun 2020 10:06:15 +0300 Subject: [PATCH] Issue #19725: Error when loading python dump Fix the issue related to the on-the-fly projection to sketch, when projecting a periodic B-spline curve orthogonal to the sketch plane. --- src/GeomAPI/GeomAPI_BSpline2d.cpp | 11 +++++++-- src/PartSet/PartSet_Tools.cpp | 5 +++- src/SketchPlugin/SketchPlugin_Validators.cpp | 26 ++++++++++++++++++++ src/SketchPlugin/SketchPlugin_msg_en.ts | 4 +++ src/SketchPlugin/SketchPlugin_msg_fr.ts | 4 +++ 5 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/GeomAPI/GeomAPI_BSpline2d.cpp b/src/GeomAPI/GeomAPI_BSpline2d.cpp index 5835d9707..a5bd94a16 100644 --- a/src/GeomAPI/GeomAPI_BSpline2d.cpp +++ b/src/GeomAPI/GeomAPI_BSpline2d.cpp @@ -48,8 +48,15 @@ static Handle_Geom2d_BSplineCurve* newBSpline2d( 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::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); diff --git a/src/PartSet/PartSet_Tools.cpp b/src/PartSet/PartSet_Tools.cpp index fc615f4d1..169ea993d 100644 --- a/src/PartSet/PartSet_Tools.cpp +++ b/src/PartSet/PartSet_Tools.cpp @@ -384,10 +384,13 @@ ResultPtr PartSet_Tools::createFixedObjectByExternal( 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 aFeatures; diff --git a/src/SketchPlugin/SketchPlugin_Validators.cpp b/src/SketchPlugin/SketchPlugin_Validators.cpp index 9feba7df8..b09094fd5 100644 --- a/src/SketchPlugin/SketchPlugin_Validators.cpp +++ b/src/SketchPlugin/SketchPlugin_Validators.cpp @@ -62,6 +62,7 @@ #include #include +#include #include #include #include @@ -1246,6 +1247,31 @@ bool SketchPlugin_ProjectionValidator::isValid(const AttributePtr& theAttribute, 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 aCurve(new GeomAPI_Curve(anEdge)); + std::shared_ptr aBSpline(new GeomAPI_BSpline(aCurve)); + if (aBSpline->isPeriodic()) { + GeomPlanePtr aBSplinePlane = GeomAlgoAPI_ShapeTools::findPlane(ListOfShape(1, anEdge)); + if (aBSplinePlane) { + std::shared_ptr 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 aPoles = aBSpline->poles(); + for (std::list::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; } diff --git a/src/SketchPlugin/SketchPlugin_msg_en.ts b/src/SketchPlugin/SketchPlugin_msg_en.ts index 5dd2eaa01..b2271f3ea 100644 --- a/src/SketchPlugin/SketchPlugin_msg_en.ts +++ b/src/SketchPlugin/SketchPlugin_msg_en.ts @@ -2250,6 +2250,10 @@ Error: Elliptic Arc is orthogonal to the sketch plane. Error: Elliptic Arc is orthogonal to the sketch plane. + + Error: Periodic B-spline is orthogonal to the sketch plane. + Error: Periodic B-spline is orthogonal to the sketch plane. + Error: Selected object is not supported for projection. Error: Selected object is not supported for projection. diff --git a/src/SketchPlugin/SketchPlugin_msg_fr.ts b/src/SketchPlugin/SketchPlugin_msg_fr.ts index 86f682282..369a4050f 100644 --- a/src/SketchPlugin/SketchPlugin_msg_fr.ts +++ b/src/SketchPlugin/SketchPlugin_msg_fr.ts @@ -2156,6 +2156,10 @@ Error: Elliptic Arc is orthogonal to the sketch plane. Erreur: L'arc d'ellipse est orthogonal au plan d'esquisse. + + Error: Periodic B-spline is orthogonal to the sketch plane. + Erreur: La B-spline périodique est orthogonale au plan d'esquisse. + Error: Selected object is not supported for projection. Erreur: L'objet sélectionné n'est pas pris en charge pour la projection. -- 2.39.2