From a32b8e5b427c1d2ebb4b90eeda4c9ca97c70f1a9 Mon Sep 17 00:00:00 2001 From: mpv Date: Tue, 24 Oct 2017 12:19:17 +0300 Subject: [PATCH] Update of the intersection-points calculation due to the note #9 of the issue #2209. --- .../ConstructionPlugin_Point.cpp | 24 ++++++-- .../ConstructionPlugin_Point.h | 2 +- src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp | 60 ++++++++++--------- src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h | 5 +- 4 files changed, 55 insertions(+), 36 deletions(-) diff --git a/src/ConstructionPlugin/ConstructionPlugin_Point.cpp b/src/ConstructionPlugin/ConstructionPlugin_Point.cpp index f08cd5fa4..08ff70a3a 100644 --- a/src/ConstructionPlugin/ConstructionPlugin_Point.cpp +++ b/src/ConstructionPlugin/ConstructionPlugin_Point.cpp @@ -79,7 +79,7 @@ void ConstructionPlugin_Point::execute() { GeomShapePtr aShape; - // to support compatibility with old documents where aCreationMethod did not exist + // to support compatibility with old documents where aCreationMethod did not exist std::string aCreationMethod = string(CREATION_METHOD()).get() && !string(CREATION_METHOD())->value().empty() ? string(CREATION_METHOD())->value() : CREATION_METHOD_BY_XYZ(); @@ -92,7 +92,20 @@ void ConstructionPlugin_Point::execute() } else if(aCreationMethod == CREATION_METHOD_BY_LINES_INTERSECTION()) { aShape = createByLinesIntersection(); }*/ else if(aCreationMethod == CREATION_METHOD_BY_LINE_AND_PLANE_INTERSECTION()) { - aShape = createByLineAndPlaneIntersection(); + // this may produce several points + std::list > aPoints = createByLineAndPlaneIntersection(); + if (!aPoints.empty()) { // if no points found produce the standard error later + int anIndex = 0; + std::list >::iterator aPIter = aPoints.begin(); + for(; aPIter != aPoints.end(); aPIter++, anIndex++) { + std::shared_ptr aConstr = + document()->createConstruction(data(), anIndex); + aConstr->setShape(*aPIter); + setResult(aConstr, anIndex); + } + removeResults(anIndex); + return; + } } if(!aShape.get()) { @@ -100,6 +113,7 @@ void ConstructionPlugin_Point::execute() return; } + removeResults(1); // for case the point type was switched from multi-results type std::shared_ptr aConstr = document()->createConstruction(data()); aConstr->setShape(aShape); setResult(aConstr); @@ -191,7 +205,8 @@ std::shared_ptr ConstructionPlugin_Point::createByLinesIntersect */ //================================================================================================== -std::shared_ptr ConstructionPlugin_Point::createByLineAndPlaneIntersection() +std::list > + ConstructionPlugin_Point::createByLineAndPlaneIntersection() { // Get line. AttributeSelectionPtr aLineSelection = selection(INTERSECTION_LINE()); @@ -218,5 +233,6 @@ std::shared_ptr ConstructionPlugin_Point::createByLineAndPlaneIn } } - return GeomAlgoAPI_ShapeTools::intersect(anEdge, aFace); + return GeomAlgoAPI_ShapeTools::intersect(anEdge, aFace, + aPlaneSelection->context()->groupName() == ModelAPI_ResultConstruction::group()); } diff --git a/src/ConstructionPlugin/ConstructionPlugin_Point.h b/src/ConstructionPlugin/ConstructionPlugin_Point.h index a9f59d31d..f983ec327 100644 --- a/src/ConstructionPlugin/ConstructionPlugin_Point.h +++ b/src/ConstructionPlugin/ConstructionPlugin_Point.h @@ -223,7 +223,7 @@ private: /*std::shared_ptr createByDistanceOnEdge(); std::shared_ptr createByProjection(); std::shared_ptr createByLinesIntersection();*/ - std::shared_ptr createByLineAndPlaneIntersection(); + std::list > createByLineAndPlaneIntersection(); }; diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp index 04ae892e3..503046f78 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp @@ -54,7 +54,7 @@ #include #include #include -#include +#include #include #include #include @@ -750,11 +750,13 @@ bool GeomAlgoAPI_ShapeTools::isParallel(const std::shared_ptr theE } //================================================================================================== -std::shared_ptr GeomAlgoAPI_ShapeTools::intersect( - const std::shared_ptr theEdge, const std::shared_ptr theFace) +std::list > GeomAlgoAPI_ShapeTools::intersect( + const std::shared_ptr theEdge, const std::shared_ptr theFace, + const bool thePointsOutsideFace) { + std::list > aResult; if(!theEdge.get() || !theFace.get()) { - return std::shared_ptr(); + return aResult; } TopoDS_Edge anEdge = TopoDS::Edge(theEdge->impl()); @@ -764,33 +766,33 @@ std::shared_ptr GeomAlgoAPI_ShapeTools::intersect( TopoDS_Face aFace = TopoDS::Face(theFace->impl()); Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); - GeomAPI_ExtremaCurveSurface anExt(aCurve, aSurf); - // searching for the best point-intersection - int aMaxLevel = 0; - gp_Pnt aResult; - for(int anIntNum = 1; anIntNum <= anExt.NbExtrema(); anIntNum++) { - if (anExt.Distance(anIntNum) > Precision::Confusion()) - continue; - Standard_Real aW, aU, aV; - anExt.Parameters(anIntNum, aW, aU, aV); - gp_Pnt2d aPointOfSurf(aU, aV); - // level of the intersection: if it is inside of edge and/or face the level is higher - int aIntLevel = aW > aFirstOnCurve && aW < aLastOnCurve ? 2 : 1; - BRepClass_FaceClassifier aFClass(aFace, aPointOfSurf, Precision::Confusion()); - if (aFClass.State() == TopAbs_IN) // "in" is better than "on" - aIntLevel += 2; - else if (aFClass.State() == TopAbs_ON) - aIntLevel += 1; - if (aMaxLevel < aIntLevel) { - aMaxLevel = anIntNum; - anExt.Points(anIntNum, aResult, aResult); + GeomAPI_IntCS anIntAlgo(aCurve, aSurf); + if (!anIntAlgo.IsDone()) + return aResult; + // searching for points-intersection + for(int anIntNum = 1; anIntNum <= anIntAlgo.NbPoints() + anIntAlgo.NbSegments(); anIntNum++) { + gp_Pnt anInt; + if (anIntNum <= anIntAlgo.NbPoints()) { + anInt = anIntAlgo.Point(anIntNum); + } else { // take the middle point on the segment of the intersection + Handle(Geom_Curve) anIntCurve = anIntAlgo.Segment(anIntNum - anIntAlgo.NbPoints()); + anIntCurve->D0((anIntCurve->FirstParameter() + anIntCurve->LastParameter()) / 2., anInt); } + if (!thePointsOutsideFace) { + Standard_Real aW, aU, aV; + anExt.Parameters(anIntNum, aW, aU, aV); + gp_Pnt2d aPointOfSurf(aU, aV); + BRepClass_FaceClassifier aFClass(aFace, aPointOfSurf, Precision::Confusion()); + if (aFClass.State() == TopAbs_OUT) + continue; // outside points are filtered out if not needed + } + gp_Pnt anIntPnt; + anExt.Points(anIntNum, anIntPnt, anIntPnt); + + aResult.push_back(std::shared_ptr( + new GeomAPI_Vertex(anInt.X(), anInt.Y(), anInt.Z()))); } - if (aMaxLevel > 0) { // intersection found - return std::shared_ptr( - new GeomAPI_Vertex(aResult.X(), aResult.Y(), aResult.Z())); - } - return std::shared_ptr(); // no intersection found + return aResult; } //================================================================================================== diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h index 168e07609..a7f051a8d 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h @@ -137,8 +137,9 @@ public: // Computes intersection point between the edge curve and a face surface (only one point, with // preferences to point that belongs to edge and face boundaries. /// \returns null if there is no intersection - GEOMALGOAPI_EXPORT static std::shared_ptr intersect( - const std::shared_ptr theEdge, const std::shared_ptr theFace); + GEOMALGOAPI_EXPORT static std::list > intersect( + const std::shared_ptr theEdge, const std::shared_ptr theFace, + const bool thePointsOutsideFace); typedef std::map, std::pair >, -- 2.39.2