diff --git a/dox/dev_guides/upgrade/upgrade.md b/dox/dev_guides/upgrade/upgrade.md index 6742c1e57a..d1c5e44e0f 100644 --- a/dox/dev_guides/upgrade/upgrade.md +++ b/dox/dev_guides/upgrade/upgrade.md @@ -1503,6 +1503,7 @@ The following obsolete features have been removed: * The container *BiTgte_DataMapOfShapeBox* is replaced with *TopTools_DataMapOfShapeBox*; * The class *BOPTools* has been removed as duplicate of the class *TopExp*; * The method *BOPAlgo_Builder::Splits()* has been removed as excessive. The method *BOPAlgo_Builder::Images()* can be used instead. +* The method *BOPTools_AlgoTools::CheckSameGeom()* has been removed as excessive. The method *BOPTools_AlgoTools::AreFacesSameDomain()* can be used instead. @section upgrade_occt730 Upgrade to OCCT 7.3.0 diff --git a/src/BOPAlgo/BOPAlgo.msg b/src/BOPAlgo/BOPAlgo.msg index 72c842f7df..84cf724566 100644 --- a/src/BOPAlgo/BOPAlgo.msg +++ b/src/BOPAlgo/BOPAlgo.msg @@ -91,3 +91,6 @@ Error: The Feature Removal algorithm has failed .BOPAlgo_AlertSolidBuilderUnusedFaces Warning: Some of the faces passed to the Solid Builder algorithm have not been classified and not used for solids creation + +.BOPAlgo_AlertUnableToOrientTheShape +Warning: Unable to orient the shape correctly diff --git a/src/BOPAlgo/BOPAlgo_Alerts.hxx b/src/BOPAlgo/BOPAlgo_Alerts.hxx index 7a4f927f76..8874825d11 100644 --- a/src/BOPAlgo/BOPAlgo_Alerts.hxx +++ b/src/BOPAlgo/BOPAlgo_Alerts.hxx @@ -104,4 +104,7 @@ DEFINE_SIMPLE_ALERT(BOPAlgo_AlertRemoveFeaturesFailed) //! and not used for solids creation DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertSolidBuilderUnusedFaces) +//! Unable to orient the shape correctly +DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertUnableToOrientTheShape) + #endif // _BOPAlgo_Alerts_HeaderFile diff --git a/src/BOPAlgo/BOPAlgo_BOPAlgo_msg.pxx b/src/BOPAlgo/BOPAlgo_BOPAlgo_msg.pxx index 6cd2187474..4eeb549ebb 100644 --- a/src/BOPAlgo/BOPAlgo_BOPAlgo_msg.pxx +++ b/src/BOPAlgo/BOPAlgo_BOPAlgo_msg.pxx @@ -93,4 +93,7 @@ static const char BOPAlgo_BOPAlgo_msg[] = "Error: The Feature Removal algorithm has failed\n" "\n" ".BOPAlgo_AlertSolidBuilderUnusedFaces\n" - "Warning: Some of the faces passed to the Solid Builder algorithm have not been classified and not used for solids creation\n"; + "Warning: Some of the faces passed to the Solid Builder algorithm have not been classified and not used for solids creation\n" + "\n" + ".BOPAlgo_AlertUnableToOrientTheShape\n" + "Warning: Unable to orient the shape correctly\n"; diff --git a/src/BOPAlgo/BOPAlgo_Builder.hxx b/src/BOPAlgo/BOPAlgo_Builder.hxx index 6f46abbcf6..6b8cadc6a3 100644 --- a/src/BOPAlgo/BOPAlgo_Builder.hxx +++ b/src/BOPAlgo/BOPAlgo_Builder.hxx @@ -58,6 +58,10 @@ class BOPAlgo_PaveFiller; //! i.e. the check is performed. Setting this flag to FALSE for inverted solids, //! most likely will lead to incorrect results. //! +//! The algorithm returns the following warnings: +//! - *BOPAlgo_AlertUnableToOrientTheShape* - in case the check on the orientation of the split shape +//! to match the orientation of the original shape has failed. +//! //! The algorithm returns the following Error statuses: //! - *BOPAlgo_AlertTooFewArguments* - in case there are no enough arguments to perform the operation; //! - *BOPAlgo_AlertNoFiller* - in case the intersection tool has not been created; diff --git a/src/BOPAlgo/BOPAlgo_Builder_1.cxx b/src/BOPAlgo/BOPAlgo_Builder_1.cxx index 69fc0f84cb..97ec6c7846 100644 --- a/src/BOPAlgo/BOPAlgo_Builder_1.cxx +++ b/src/BOPAlgo/BOPAlgo_Builder_1.cxx @@ -226,7 +226,7 @@ void BOPAlgo_Builder::FillImagesVertices() { TopoDS_Shape aSSIm = aItIm.Value(); if (!aSSIm.IsEqual(aSS) && - BOPTools_AlgoTools::IsSplitToReverse(aSSIm, aSS, myContext)) + BOPTools_AlgoTools::IsSplitToReverseWithWarn(aSSIm, aSS, myContext, myReport)) { aSSIm.Reverse(); } diff --git a/src/BOPAlgo/BOPAlgo_Builder_2.cxx b/src/BOPAlgo/BOPAlgo_Builder_2.cxx index 15b1b3cf38..fcc64ed2a7 100644 --- a/src/BOPAlgo/BOPAlgo_Builder_2.cxx +++ b/src/BOPAlgo/BOPAlgo_Builder_2.cxx @@ -61,7 +61,8 @@ static TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace, const TopTools_DataMapOfShapeListOfShape& theImages, - Handle(IntTools_Context)& theCtx); + Handle(IntTools_Context)& theCtx, + const Handle(Message_Report)& theReport); //======================================================================= //class : BOPAlgo_PairOfShapeBoolean @@ -311,7 +312,7 @@ void BOPAlgo_Builder::BuildSplitFaces() // the draft face will be null, as such sub-shapes may split the face on parts // (as in the case "bugs modalg_5 bug25245_1"). // The BuilderFace algorithm will be called in this case. - TopoDS_Face aFD = BuildDraftFace(aF, myImages, myContext); + TopoDS_Face aFD = BuildDraftFace(aF, myImages, myContext, myReport); if (!aFD.IsNull()) { aFacesIm(aFacesIm.Add(i, TopTools_ListOfShape())).Append(aFD); @@ -404,7 +405,7 @@ void BOPAlgo_Builder::BuildSplitFaces() }// if (bIsClosed){ // aSp.Orientation(anOriE); - bToReverse=BOPTools_AlgoTools::IsSplitToReverse(aSp, aE, myContext); + bToReverse=BOPTools_AlgoTools::IsSplitToReverseWithWarn(aSp, aE, myContext, myReport); if (bToReverse) { aSp.Reverse(); } @@ -813,21 +814,27 @@ void BOPAlgo_Builder::FillInternalVertices() //purpose : Checks if the edge has multi-connected vertices. //======================================================================= static Standard_Boolean HasMultiConnected(const TopoDS_Edge& theEdge, - TopTools_DataMapOfShapeInteger& theMap) + TopTools_DataMapOfShapeListOfShape& theMap) { TopoDS_Iterator itV(theEdge); for (; itV.More(); itV.Next()) { const TopoDS_Shape& aV = itV.Value(); - Standard_Integer *pCounter = theMap.ChangeSeek(aV); - if (!pCounter) - pCounter = theMap.Bound(aV, 1); + TopTools_ListOfShape *pList = theMap.ChangeSeek(aV); + if (!pList) + { + pList = theMap.Bound(aV, TopTools_ListOfShape()); + pList->Append(theEdge); + } else { - if (*pCounter == 2) - return Standard_True; + // The list is expected to be 1-2 elements long, + // thus using "Contains" is safe. + if (!pList->Contains(theEdge)) + pList->Append(theEdge); - ++(*pCounter); + if (pList->Extent() > 2) + return Standard_True; } } return Standard_False; @@ -839,7 +846,8 @@ static Standard_Boolean HasMultiConnected(const TopoDS_Edge& theEdge, //======================================================================= TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace, const TopTools_DataMapOfShapeListOfShape& theImages, - Handle(IntTools_Context)& theCtx) + Handle(IntTools_Context)& theCtx, + const Handle(Message_Report)& theReport) { BRep_Builder aBB; // Take the information from the original face @@ -855,7 +863,7 @@ TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace, // the vertices appearance, and if the multi-connexity is met return // the null face to use the BuilderFace algorithm for checking the // possibility of split. - TopTools_DataMapOfShapeInteger aVerticesCounter; + TopTools_DataMapOfShapeListOfShape aVerticesCounter; // Update wires of the original face and add them to draft face TopoDS_Iterator aItW(theFace.Oriented(TopAbs_FORWARD)); @@ -885,20 +893,21 @@ TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace, return TopoDS_Face(); } + // Check if the original edge is degenerated + Standard_Boolean bIsDegenerated = BRep_Tool::Degenerated(aE); + // Check for the splits of the edge const TopTools_ListOfShape* pLEIm = theImages.Seek(aE); if (!pLEIm) { // Check if the edge has multi-connected vertices - if (HasMultiConnected(aE, aVerticesCounter)) + if (!bIsDegenerated && HasMultiConnected(aE, aVerticesCounter)) return TopoDS_Face(); aBB.Add(aNewWire, aE); continue; } - // Check if the original edge is degenerated - Standard_Boolean bIsDegenerated = BRep_Tool::Degenerated(aE); // Check if the original edge is closed on the face Standard_Boolean bIsClosed = BRep_Tool::IsClosed(aE, theFace); @@ -908,7 +917,7 @@ TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace, TopoDS_Edge& aSp = TopoDS::Edge(aItLEIm.Value()); // Check if the split has multi-connected vertices - if (HasMultiConnected(aSp, aVerticesCounter)) + if (!bIsDegenerated && HasMultiConnected(aSp, aVerticesCounter)) return TopoDS_Face(); aSp.Orientation(anOriE); @@ -918,13 +927,13 @@ TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace, continue; } - // Check closeness of the split edge and if it is not - // make the second PCurve + // If the original edge is closed on the face check closeness + // of the split edge and if it is not closed make the second PCurve if (bIsClosed && !BRep_Tool::IsClosed(aSp, theFace)) BOPTools_AlgoTools3D::DoSplitSEAMOnFace(aSp, theFace); // Check if the split should be reversed - if (BOPTools_AlgoTools::IsSplitToReverse(aSp, aE, theCtx)) + if (BOPTools_AlgoTools::IsSplitToReverseWithWarn(aSp, aE, theCtx, theReport)) aSp.Reverse(); aBB.Add(aNewWire, aSp); diff --git a/src/BOPAlgo/BOPAlgo_Builder_3.cxx b/src/BOPAlgo/BOPAlgo_Builder_3.cxx index f7763d37cb..1f7d00024a 100644 --- a/src/BOPAlgo/BOPAlgo_Builder_3.cxx +++ b/src/BOPAlgo/BOPAlgo_Builder_3.cxx @@ -287,8 +287,8 @@ void BOPAlgo_Builder::BuildDraftSolid(const TopoDS_Shape& theSolid, theLIF.Append(aFx); } else { - bToReverse=BOPTools_AlgoTools::IsSplitToReverse - (aFx, aF, myContext); + bToReverse=BOPTools_AlgoTools::IsSplitToReverseWithWarn + (aFx, aF, myContext, myReport); if (bToReverse) { aFx.Reverse(); } diff --git a/src/BOPTools/BOPTools_AlgoTools.cxx b/src/BOPTools/BOPTools_AlgoTools.cxx index b4f474ba38..b5c07f02e3 100644 --- a/src/BOPTools/BOPTools_AlgoTools.cxx +++ b/src/BOPTools/BOPTools_AlgoTools.cxx @@ -17,6 +17,7 @@ #include <BOPTools_AlgoTools.hxx> +#include <BOPAlgo_Alerts.hxx> #include <BOPTools_AlgoTools2D.hxx> #include <BOPTools_AlgoTools3D.hxx> #include <BOPTools_CoupleOfShape.hxx> @@ -64,6 +65,7 @@ #include <TopTools_IndexedMapOfShape.hxx> #include <TopTools_MapOfShape.hxx> #include <TopTools_MapOfOrientedShape.hxx> +#include <Message_Report.hxx> #include <NCollection_Array1.hxx> #include <algorithm> @@ -77,7 +79,7 @@ static Standard_Boolean FindFacePairs (const TopoDS_Edge& theE, const TopTools_ListOfShape& thLF, BOPTools_ListOfCoupleOfShape& theLCFF, - Handle(IntTools_Context)& theContext); + const Handle(IntTools_Context)& theContext); static TopAbs_Orientation Orientation(const TopoDS_Edge& anE, const TopoDS_Face& aF); @@ -91,7 +93,7 @@ static const Standard_Boolean theSmallFaces, gp_Dir& aDN, gp_Dir& aDB, - Handle(IntTools_Context)& theContext, + const Handle(IntTools_Context)& theContext, GeomAPI_ProjectPointOnSurf& aProjPL, const Standard_Real aDt); static @@ -99,7 +101,7 @@ static const gp_Pnt& aP, gp_Dir& aDB, gp_Pnt& aPOut, - Handle(IntTools_Context)& theContext, + const Handle(IntTools_Context)& theContext, GeomAPI_ProjectPointOnSurf& aProjPL, const Standard_Real aDt, const Standard_Real aTolE); @@ -108,7 +110,7 @@ static const TopoDS_Face& theF1, const BOPTools_ListOfCoupleOfShape& theLCS, const gp_Pnt& aP, - Handle(IntTools_Context)& theContext, + const Handle(IntTools_Context)& theContext, Standard_Boolean& theSmallFaces); @@ -589,7 +591,7 @@ TopAbs_State BOPTools_AlgoTools::ComputeStateByOnePoint (const TopoDS_Shape& theS, const TopoDS_Solid& theRef, const Standard_Real theTol, - Handle(IntTools_Context)& theContext) + const Handle(IntTools_Context)& theContext) { TopAbs_State aState; TopAbs_ShapeEnum aType; @@ -616,7 +618,7 @@ TopAbs_State BOPTools_AlgoTools::ComputeState const TopoDS_Solid& theRef, const Standard_Real theTol, TopTools_IndexedMapOfShape& theBounds, - Handle(IntTools_Context)& theContext) + const Handle(IntTools_Context)& theContext) { TopAbs_State aState; TopExp_Explorer aExp; @@ -665,7 +667,7 @@ TopAbs_State BOPTools_AlgoTools::ComputeState (const TopoDS_Vertex& theV, const TopoDS_Solid& theRef, const Standard_Real theTol, - Handle(IntTools_Context)& theContext) + const Handle(IntTools_Context)& theContext) { TopAbs_State aState; gp_Pnt aP3D; @@ -683,7 +685,7 @@ TopAbs_State BOPTools_AlgoTools::ComputeState (const TopoDS_Edge& theE, const TopoDS_Solid& theRef, const Standard_Real theTol, - Handle(IntTools_Context)& theContext) + const Handle(IntTools_Context)& theContext) { Standard_Real aT1, aT2, aT = 0.; TopAbs_State aState; @@ -735,7 +737,7 @@ TopAbs_State BOPTools_AlgoTools::ComputeState (const gp_Pnt& theP, const TopoDS_Solid& theRef, const Standard_Real theTol, - Handle(IntTools_Context)& theContext) + const Handle(IntTools_Context)& theContext) { TopAbs_State aState; // @@ -755,7 +757,7 @@ Standard_Boolean BOPTools_AlgoTools::IsInternalFace const TopoDS_Solid& theSolid, TopTools_IndexedDataMapOfShapeListOfShape& theMEF, const Standard_Real theTol, - Handle(IntTools_Context)& theContext) + const Handle(IntTools_Context)& theContext) { Standard_Boolean bDegenerated; Standard_Integer aNbF, iRet, iFound; @@ -866,7 +868,7 @@ Standard_Integer BOPTools_AlgoTools::IsInternalFace (const TopoDS_Face& theFace, const TopoDS_Edge& theEdge, TopTools_ListOfShape& theLF, - Handle(IntTools_Context)& theContext) + const Handle(IntTools_Context)& theContext) { Standard_Integer aNbF, iRet; // @@ -911,7 +913,7 @@ Standard_Integer BOPTools_AlgoTools::IsInternalFace const TopoDS_Edge& theEdge, const TopoDS_Face& theFace1, const TopoDS_Face& theFace2, - Handle(IntTools_Context)& theContext) + const Handle(IntTools_Context)& theContext) { Standard_Boolean bRet; Standard_Integer iRet; @@ -965,7 +967,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff const TopoDS_Face& theF1, BOPTools_ListOfCoupleOfShape& theLCSOff, TopoDS_Face& theFOff, - Handle(IntTools_Context)& theContext) + const Handle(IntTools_Context)& theContext) { Standard_Boolean bRet, bIsComputed; Standard_Real aT, aT1, aT2, aAngle, aTwoPI, aAngleMin, aDt3D; @@ -1091,7 +1093,7 @@ Standard_Boolean BOPTools_AlgoTools::GetEdgeOff(const TopoDS_Edge& theE1, Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain (const TopoDS_Face& theF1, const TopoDS_Face& theF2, - Handle(IntTools_Context)& theContext, + const Handle(IntTools_Context)& theContext, const Standard_Real theFuzz) { Standard_Boolean bFacesSD = Standard_False; @@ -1151,43 +1153,13 @@ Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain return bFacesSD; } -//======================================================================= -//function : CheckSameGeom -//purpose : -//======================================================================= -Standard_Boolean BOPTools_AlgoTools::CheckSameGeom - (const TopoDS_Face& theF1, - const TopoDS_Face& theF2, - Handle(IntTools_Context)& theContext) -{ - Standard_Boolean bRet; - Standard_Real aTolF1, aTolF2, aTol; - gp_Pnt2d aP2D; - gp_Pnt aP; - TopExp_Explorer aExp; - // - bRet=Standard_False; - aExp.Init(theF1, TopAbs_EDGE); - for (; aExp.More(); aExp.Next()) { - const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current())); - if (!BRep_Tool::Degenerated(aE)) { - aTolF1=BRep_Tool::Tolerance(theF1); - aTolF2=BRep_Tool::Tolerance(theF2); - aTol=aTolF1+aTolF2; - BOPTools_AlgoTools3D::PointNearEdge(aE, theF1, aP2D, aP, theContext); - bRet=theContext->IsValidPointForFace(aP, theF2, aTol); - break; - } - } - return bRet; -} //======================================================================= // function: Sense // purpose: //======================================================================= -Standard_Integer BOPTools_AlgoTools::Sense (const TopoDS_Face& theF1, - const TopoDS_Face& theF2, - const Handle(IntTools_Context)& theContext) +Standard_Integer BOPTools_AlgoTools::Sense(const TopoDS_Face& theF1, + const TopoDS_Face& theF2, + const Handle(IntTools_Context)& theContext) { Standard_Integer iSense=0; gp_Dir aDNF1, aDNF2; @@ -1235,7 +1207,8 @@ Standard_Integer BOPTools_AlgoTools::Sense (const TopoDS_Face& theF1, Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse (const TopoDS_Shape& theSp, const TopoDS_Shape& theSr, - Handle(IntTools_Context)& theContext) + const Handle(IntTools_Context)& theContext, + Standard_Integer *theError) { Standard_Boolean bRet; TopAbs_ShapeEnum aType; @@ -1247,22 +1220,49 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse case TopAbs_EDGE: { const TopoDS_Edge& aESp=(*(TopoDS_Edge*)(&theSp)); const TopoDS_Edge& aESr=(*(TopoDS_Edge*)(&theSr)); - bRet=BOPTools_AlgoTools::IsSplitToReverse(aESp, aESr, theContext); + bRet=BOPTools_AlgoTools::IsSplitToReverse(aESp, aESr, theContext, theError); } break; // case TopAbs_FACE: { const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&theSp)); const TopoDS_Face& aFSr=(*(TopoDS_Face*)(&theSr)); - bRet=BOPTools_AlgoTools::IsSplitToReverse(aFSp, aFSr, theContext); + bRet=BOPTools_AlgoTools::IsSplitToReverse(aFSp, aFSr, theContext, theError); } break; // default: + if (theError) + *theError = 100; break; } return bRet; } + +//======================================================================= +//function : IsSplitToReverseWithWarn +//purpose : +//======================================================================= +Standard_Boolean BOPTools_AlgoTools::IsSplitToReverseWithWarn(const TopoDS_Shape& theSplit, + const TopoDS_Shape& theShape, + const Handle(IntTools_Context)& theContext, + const Handle(Message_Report)& theReport) +{ + Standard_Integer anErr; + Standard_Boolean isToReverse = BOPTools_AlgoTools::IsSplitToReverse(theSplit, theShape, theContext, &anErr); + if (anErr != 0 && !theReport.IsNull()) + { + // The error occurred during the check. + // Add warning to the report, storing the shapes into the warning. + TopoDS_Compound aWC; + BRep_Builder().MakeCompound(aWC); + BRep_Builder().Add(aWC, theSplit); + BRep_Builder().Add(aWC, theShape); + theReport->AddAlert(Message_Warning, new BOPAlgo_AlertUnableToOrientTheShape(aWC)); + } + return isToReverse; +} + //======================================================================= //function :IsSplitToReverse //purpose : @@ -1270,8 +1270,13 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse (const TopoDS_Face& theFSp, const TopoDS_Face& theFSr, - Handle(IntTools_Context)& theContext) + const Handle(IntTools_Context)& theContext, + Standard_Integer *theError) { + // Set OK error status + if (theError) + *theError = 0; + // Compare surfaces Handle(Geom_Surface) aSFSp = BRep_Tool::Surface(theFSp); Handle(Geom_Surface) aSFOr = BRep_Tool::Surface(theFSr); @@ -1305,6 +1310,8 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse } // if (!anExp.More()) { + if (theError) + *theError = 1; // The point has not been found. return bDone; } @@ -1315,6 +1322,8 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse bDone = BOPTools_AlgoTools3D::GetNormalToSurface (aSFSp, aP2DFSp.X(), aP2DFSp.Y(), aDNFSp); if (!bDone) { + if (theError) + *theError = 2; return bDone; } // @@ -1328,6 +1337,8 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse aProjector.Perform(aPFSp); bDone = (aProjector.NbPoints() > 0); if (!bDone) { + if (theError) + *theError = 3; return bDone; } // UV coordinates of the point on the original face @@ -1338,6 +1349,8 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse gp_Dir aDNFOr; bDone = BOPTools_AlgoTools3D::GetNormalToSurface(aSFOr, aU, aV, aDNFOr); if (!bDone) { + if (theError) + *theError = 4; return bDone; } // @@ -1354,51 +1367,88 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse //purpose : //======================================================================= Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse - (const TopoDS_Edge& aEF1, - const TopoDS_Edge& aEF2, - Handle(IntTools_Context)& theContext) + (const TopoDS_Edge& theESp, + const TopoDS_Edge& theEOr, + const Handle(IntTools_Context)& theContext, + Standard_Integer *theError) { - Standard_Boolean bRet, bIsDegenerated; - // - bRet=Standard_False; - bIsDegenerated=(BRep_Tool::Degenerated(aEF1) || - BRep_Tool::Degenerated(aEF2)); - if (bIsDegenerated) { - return bRet; + // The idea is to compare the tangent vectors of two edges computed in + // the same point. Thus, we need to take the point on split edge (since it is + // shorter) and project it onto original edge to find corresponding parameter. + + if (BRep_Tool::Degenerated(theESp) || + BRep_Tool::Degenerated(theEOr)) + { + if (theError) + *theError = 1; + return Standard_False; } - // - Standard_Real a, b; - TopAbs_Orientation aOrE, aOrSp; - Handle(Geom_Curve)aC1, aC2; - // - aC2=BRep_Tool::Curve(aEF2, a, b); - aC1=BRep_Tool::Curve(aEF1, a, b); - // - if (aC1==aC2) { - aOrE=aEF2.Orientation(); - aOrSp=aEF1.Orientation(); - bRet=(aOrE!=aOrSp); - return bRet; + + // Set OK error status + if (theError) + *theError = 0; + + // Get the curves from the edges + Standard_Real f, l; + Handle(Geom_Curve) aCSp = BRep_Tool::Curve(theESp, f, l); + Handle(Geom_Curve) aCOr = BRep_Tool::Curve(theEOr, f, l); + + // If the curves are the same, compare orientations only + if (aCSp == aCOr) + return theESp.Orientation() != theEOr.Orientation(); + + // Find valid range of the split edge, to ensure that the point for computing + // tangent vectors will be inside both edges. + if (!BRepLib::FindValidRange(theESp, f, l)) + BRep_Tool::Range(theESp, f, l); + + // Error code + Standard_Integer anErr = 0; + // Try a few sample points on the split edge until first valid found + const Standard_Integer aNbP = 11; + const Standard_Real aDT = (l - f) / aNbP; + for (Standard_Integer i = 1; i < aNbP; ++i) + { + const Standard_Real aTm = f + i*aDT; + // Compute tangent vector on split edge + gp_Vec aVSpTgt; + if (!BOPTools_AlgoTools2D::EdgeTangent(theESp, aTm, aVSpTgt)) + { + // Unable to compute the tangent vector on the split edge + // in this point -> take the next point + anErr = 2; + continue; + } + + // Find corresponding parameter on the original edge + Standard_Real aTmOr; + if (!theContext->ProjectPointOnEdge(aCSp->Value(aTm), theEOr, aTmOr)) + { + // Unable to project the point inside the split edge + // onto the original edge -> take the next point + anErr = 3; + continue; + } + + // Compute tangent vector on original edge + gp_Vec aVOrTgt; + if (!BOPTools_AlgoTools2D::EdgeTangent(theEOr, aTmOr, aVOrTgt)) + { + // Unable to compute the tangent vector on the original edge + // in this point -> take the next point + anErr = 4; + continue; + } + + // Compute the Dot product + Standard_Real aCos = aVSpTgt.Dot(aVOrTgt); + return (aCos < 0.); } - // - Standard_Real aT1, aT2, aScPr; - gp_Vec aV1, aV2; - gp_Pnt aP; - // - aT1=BOPTools_AlgoTools2D::IntermediatePoint(a, b); - aC1->D0(aT1, aP); - BOPTools_AlgoTools2D::EdgeTangent(aEF1, aT1, aV1); - gp_Dir aDT1(aV1); - // - theContext->ProjectPointOnEdge(aP, aEF2, aT2); - // - BOPTools_AlgoTools2D::EdgeTangent(aEF2, aT2, aV2); - gp_Dir aDT2(aV2); - // - aScPr=aDT1*aDT2; - bRet=(aScPr<0.); - // - return bRet; + + if (theError) + *theError = anErr; + + return Standard_False; } //======================================================================= @@ -1715,7 +1765,7 @@ Standard_Boolean BOPTools_AlgoTools::GetEdgeOnFace Standard_Boolean FindFacePairs (const TopoDS_Edge& theE, const TopTools_ListOfShape& thLF, BOPTools_ListOfCoupleOfShape& theLCFF, - Handle(IntTools_Context)& theContext) + const Handle(IntTools_Context)& theContext) { Standard_Boolean bFound; Standard_Integer i, aNbCEF; @@ -1841,7 +1891,7 @@ Standard_Boolean BOPTools_AlgoTools::IsBlockInOnFace (const IntTools_Range& aShrR, const TopoDS_Face& aF, const TopoDS_Edge& aE1, - Handle(IntTools_Context)& aContext) + const Handle(IntTools_Context)& aContext) { Standard_Boolean bFlag; Standard_Real f1, l1, ULD, VLD; @@ -1978,7 +2028,7 @@ Standard_Boolean GetFaceDir(const TopoDS_Edge& aE, const Standard_Boolean theSmallFaces, gp_Dir& aDN, gp_Dir& aDB, - Handle(IntTools_Context)& theContext, + const Handle(IntTools_Context)& theContext, GeomAPI_ProjectPointOnSurf& aProjPL, const Standard_Real aDt) { @@ -2022,7 +2072,7 @@ Standard_Boolean FindPointInFace(const TopoDS_Face& aF, const gp_Pnt& aP, gp_Dir& aDB, gp_Pnt& aPOut, - Handle(IntTools_Context)& theContext, + const Handle(IntTools_Context)& theContext, GeomAPI_ProjectPointOnSurf& aProjPL, const Standard_Real aDt, const Standard_Real aTolE) @@ -2092,7 +2142,7 @@ Standard_Real MinStep3D(const TopoDS_Edge& theE1, const TopoDS_Face& theF1, const BOPTools_ListOfCoupleOfShape& theLCS, const gp_Pnt& aP, - Handle(IntTools_Context)& theContext, + const Handle(IntTools_Context)& theContext, Standard_Boolean& theSmallFaces) { Standard_Real aDt, aTolE, aTolF, aDtMax, aDtMin; diff --git a/src/BOPTools/BOPTools_AlgoTools.hxx b/src/BOPTools/BOPTools_AlgoTools.hxx index 96102b3b5e..bb12821fe7 100644 --- a/src/BOPTools/BOPTools_AlgoTools.hxx +++ b/src/BOPTools/BOPTools_AlgoTools.hxx @@ -45,25 +45,235 @@ class IntTools_Context; class TopoDS_Solid; class IntTools_Range; class TopoDS_Shell; +class Message_Report; - -class BOPTools_AlgoTools +//! Provides tools used in Boolean Operations algorithm: +//! - Vertices intersection; +//! - Vertex construction; +//! - Edge construction; +//! - Classification algorithms; +//! - Making connexity blocks; +//! - Shape validation. +class BOPTools_AlgoTools { public: DEFINE_STANDARD_ALLOC +public: //! @name Intersection of the vertices + + //! Intersects the vertex <theV1> with the point <theP> with tolerance <theTolP>. + //! Returns the error status: + //! - 0 - no error, meaning that the vertex intersects the point; + //! - 1 - the distance between vertex and point is grater than the sum of tolerances. + Standard_EXPORT static Standard_Integer ComputeVV(const TopoDS_Vertex& theV, + const gp_Pnt& theP, + const Standard_Real theTolP); + + //! Intersects the given vertices with given fuzzy value. + //! Returns the error status: + //! - 0 - no error, meaning that the vertices interferes with given tolerance; + //! - 1 - the distance between vertices is grater than the sum of their tolerances. + Standard_EXPORT static Standard_Integer ComputeVV(const TopoDS_Vertex& theV1, + const TopoDS_Vertex& theV2, + const Standard_Real theFuzz = Precision::Confusion()); + +public: //! @name Vertices construction + + //! Makes the vertex in the middle of given vertices with + //! the tolerance covering all tolerance spheres of vertices. + Standard_EXPORT static void MakeVertex(const TopTools_ListOfShape& theLV, + TopoDS_Vertex& theV); + + //! Make a vertex using 3D-point <aP1> and 3D-tolerance value <aTol> + Standard_EXPORT static void MakeNewVertex(const gp_Pnt& aP1, + const Standard_Real aTol, + TopoDS_Vertex& aNewVertex); + + //! Make a vertex using couple of vertices <aV1, aV2> + Standard_EXPORT static void MakeNewVertex(const TopoDS_Vertex& aV1, + const TopoDS_Vertex& aV2, + TopoDS_Vertex& aNewVertex); + + //! Make a vertex in place of intersection between two edges + //! <aE1, aE2> with parameters <aP1, aP2> + Standard_EXPORT static void MakeNewVertex(const TopoDS_Edge& aE1, + const Standard_Real aP1, + const TopoDS_Edge& aE2, + const Standard_Real aP2, + TopoDS_Vertex& aNewVertex); + + //! Make a vertex in place of intersection between the edge <aE1> + //! with parameter <aP1> and the face <aF2> + Standard_EXPORT static void MakeNewVertex(const TopoDS_Edge& aE1, + const Standard_Real aP1, + const TopoDS_Face& aF2, + TopoDS_Vertex& aNewVertex); + + +public: //! @name Updating the vertex + + //! Update the tolerance value for vertex <aV> + //! taking into account the fact that <aV> lays on + //! the curve <aIC> + Standard_EXPORT static void UpdateVertex(const IntTools_Curve& aIC, + const Standard_Real aT, + const TopoDS_Vertex& aV); + + //! Update the tolerance value for vertex <aV> + //! taking into account the fact that <aV> lays on + //! the edge <aE> + Standard_EXPORT static void UpdateVertex(const TopoDS_Edge& aE, + const Standard_Real aT, + const TopoDS_Vertex& aV); + + //! Update the tolerance value for vertex <aVN> + //! taking into account the fact that <aVN> should + //! cover tolerance zone of <aVF> + Standard_EXPORT static void UpdateVertex(const TopoDS_Vertex& aVF, + const TopoDS_Vertex& aVN); + + +public: //! @name Edge construction + + //! Makes the edge based on the given curve with given bounding vertices. + Standard_EXPORT static void MakeEdge(const IntTools_Curve& theCurve, + const TopoDS_Vertex& theV1, + const Standard_Real theT1, + const TopoDS_Vertex& theV2, + const Standard_Real theT2, + const Standard_Real theTolR3D, + TopoDS_Edge& theE); + + //! Makes a copy of <theEdge> with vertices. + Standard_EXPORT static TopoDS_Edge CopyEdge(const TopoDS_Edge& theEdge); + + //! Make the edge from base edge <aE1> and two vertices <aV1,aV2> + //! at parameters <aP1,aP2> + Standard_EXPORT static void MakeSplitEdge(const TopoDS_Edge& aE1, + const TopoDS_Vertex& aV1, + const Standard_Real aP1, + const TopoDS_Vertex& aV2, + const Standard_Real aP2, + TopoDS_Edge& aNewEdge); + + //! Make the edge from 3D-Curve <aIC> and two vertices <aV1,aV2> + //! at parameters <aP1,aP2> + Standard_EXPORT static void MakeSectEdge(const IntTools_Curve& aIC, + const TopoDS_Vertex& aV1, + const Standard_Real aP1, + const TopoDS_Vertex& aV2, + const Standard_Real aP2, + TopoDS_Edge& aNewEdge); + + +public: //! @name Point/Edge/Face classification relatively solid + + //! Computes the 3-D state of the point thePoint + //! toward solid theSolid. + //! theTol - value of precision of computation + //! theContext- cahed geometrical tools + //! Returns 3-D state. + Standard_EXPORT static TopAbs_State ComputeState(const gp_Pnt& thePoint, + const TopoDS_Solid& theSolid, + const Standard_Real theTol, + const Handle(IntTools_Context)& theContext); - Standard_EXPORT static Standard_Integer ComputeVV (const TopoDS_Vertex& aV1, const gp_Pnt& aP2, const Standard_Real aTolP2); + //! Computes the 3-D state of the vertex theVertex + //! toward solid theSolid. + //! theTol - value of precision of computation + //! theContext- cahed geometrical tools + //! Returns 3-D state. + Standard_EXPORT static TopAbs_State ComputeState(const TopoDS_Vertex& theVertex, + const TopoDS_Solid& theSolid, + const Standard_Real theTol, + const Handle(IntTools_Context)& theContext); - Standard_EXPORT static Standard_Integer ComputeVV (const TopoDS_Vertex& aV1, - const TopoDS_Vertex& aV2, - const Standard_Real theFuzz = Precision::Confusion()); + //! Computes the 3-D state of the edge theEdge + //! toward solid theSolid. + //! theTol - value of precision of computation + //! theContext- cahed geometrical tools + //! Returns 3-D state. + Standard_EXPORT static TopAbs_State ComputeState(const TopoDS_Edge& theEdge, + const TopoDS_Solid& theSolid, + const Standard_Real theTol, + const Handle(IntTools_Context)& theContext); - Standard_EXPORT static void MakeVertex (const TopTools_ListOfShape& aLV, TopoDS_Vertex& aV); - - Standard_EXPORT static void MakeEdge (const IntTools_Curve& theCurve, const TopoDS_Vertex& theV1, const Standard_Real theT1, const TopoDS_Vertex& theV2, const Standard_Real theT2, const Standard_Real theTolR3D, TopoDS_Edge& theE); + //! Computes the 3-D state of the face theFace + //! toward solid theSolid. + //! theTol - value of precision of computation + //! theBounds - set of edges of theFace to avoid + //! theContext- cahed geometrical tools + //! Returns 3-D state. + Standard_EXPORT static TopAbs_State ComputeState(const TopoDS_Face& theFace, + const TopoDS_Solid& theSolid, + const Standard_Real theTol, + TopTools_IndexedMapOfShape& theBounds, + const Handle(IntTools_Context)& theContext); + //! Computes the 3-D state of the shape theShape + //! toward solid theSolid. + //! theTol - value of precision of computation + //! theContext- cahed geometrical tools + //! Returns 3-D state. + Standard_EXPORT static TopAbs_State ComputeStateByOnePoint(const TopoDS_Shape& theShape, + const TopoDS_Solid& theSolid, + const Standard_Real theTol, + const Handle(IntTools_Context)& theContext); + + +public: //! @name Face classification relatively solid + + //! For the face theFace and its edge theEdge + //! finds the face suitable to produce shell. + //! theLCEF - set of faces to search. All faces + //! from theLCEF must share edge theEdge + Standard_EXPORT static Standard_Boolean GetFaceOff(const TopoDS_Edge& theEdge, + const TopoDS_Face& theFace, + BOPTools_ListOfCoupleOfShape& theLCEF, + TopoDS_Face& theFaceOff, + const Handle(IntTools_Context)& theContext); + + //! Returns True if the face theFace is inside of the + //! couple of faces theFace1, theFace2. + //! The faces theFace, theFace1, theFace2 must + //! share the edge theEdge + //! Return values: + //! * 0 state is not IN + //! * 1 state is IN + //! * 2 state can not be found by the method of angles + Standard_EXPORT static Standard_Integer IsInternalFace(const TopoDS_Face& theFace, + const TopoDS_Edge& theEdge, + const TopoDS_Face& theFace1, + const TopoDS_Face& theFace2, + const Handle(IntTools_Context)& theContext); + + //! Returns True if the face theFace is inside of the + //! appropriate couple of faces (from the set theLF) . + //! The faces of the set theLF and theFace must + //! share the edge theEdge + //! * 0 state is not IN + //! * 1 state is IN + //! * 2 state can not be found by the method of angles + Standard_EXPORT static Standard_Integer IsInternalFace(const TopoDS_Face& theFace, + const TopoDS_Edge& theEdge, + TopTools_ListOfShape& theLF, + const Handle(IntTools_Context)& theContext); + + //! Returns True if the face theFace is inside the + //! solid theSolid. + //! theMEF - Map Edge/Faces for theSolid + //! theTol - value of precision of computation + //! theContext- cahed geometrical tools + Standard_EXPORT static Standard_Boolean IsInternalFace(const TopoDS_Face& theFace, + const TopoDS_Solid& theSolid, + TopTools_IndexedDataMapOfShapeListOfShape& theMEF, + const Standard_Real theTol, + const Handle(IntTools_Context)& theContext); + + +public: //! @name PCurve construction + //! Makes 2d curve of the edge <theE> on the faces <theF1> and <theF2>.<br> //! <theContext> - storage for caching the geometrical tools Standard_EXPORT static void MakePCurve (const TopoDS_Edge& theE, @@ -73,123 +283,121 @@ public: const Standard_Boolean thePC1, const Standard_Boolean thePC2, const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)()); - - Standard_EXPORT static void MakeContainer (const TopAbs_ShapeEnum theType, TopoDS_Shape& theShape); - - Standard_EXPORT static Standard_Boolean IsHole (const TopoDS_Shape& aW, const TopoDS_Shape& aF); - - //! Returns True if the shape theSplit has opposite - //! direction than theShape - //! theContext - cashed geometrical tools - Standard_EXPORT static Standard_Boolean IsSplitToReverse (const TopoDS_Shape& theSplit, const TopoDS_Shape& theShape, Handle(IntTools_Context)& theContext); - - //! Returns True if normal direction of the face - //! theShape is not the same as for the face - //! theSplit - //! theContext - cashed geometrical tools - Standard_EXPORT static Standard_Boolean IsSplitToReverse (const TopoDS_Face& theSplit, const TopoDS_Face& theShape, Handle(IntTools_Context)& theContext); - - Standard_EXPORT static Standard_Boolean IsSplitToReverse (const TopoDS_Edge& aE1, const TopoDS_Edge& aE2, Handle(IntTools_Context)& aContext); - - Standard_EXPORT static Standard_Boolean AreFacesSameDomain (const TopoDS_Face& theF1, - const TopoDS_Face& theF2, - Handle(IntTools_Context)& theContext, - const Standard_Real theFuzz = Precision::Confusion()); - - Standard_EXPORT static Standard_Boolean CheckSameGeom (const TopoDS_Face& theF1, const TopoDS_Face& theF2, Handle(IntTools_Context)& theContext); - - //! Basing on the normals directions of the faces the method - //! Defines whether to reverse the second face or not.<br> - //! <theContext> - storage for caching the geometrical tools - Standard_EXPORT static Standard_Integer Sense (const TopoDS_Face& theF1, - const TopoDS_Face& theF2, - const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)()); - - //! Returns True if the face theFace contains - //! the edge theEdge but with opposite orientation. - //! If the method returns True theEdgeOff is the - //! edge founded - Standard_EXPORT static Standard_Boolean GetEdgeOff (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace, TopoDS_Edge& theEdgeOff); - - //! For the face theFace and its edge theEdge - //! finds the face suitable to produce shell. - //! theLCEF - set of faces to search. All faces - //! from theLCEF must share edge theEdge - Standard_EXPORT static Standard_Boolean GetFaceOff (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace, BOPTools_ListOfCoupleOfShape& theLCEF, TopoDS_Face& theFaceOff, Handle(IntTools_Context)& theContext); - - //! Returns True if the face theFace is inside of the - //! couple of faces theFace1, theFace2. - //! The faces theFace, theFace1, theFace2 must - //! share the edge theEdge - //! Return values: - //! * 0 state is not IN - //! * 1 state is IN - //! * 2 state can not be found by the method of angles - Standard_EXPORT static Standard_Integer IsInternalFace (const TopoDS_Face& theFace, const TopoDS_Edge& theEdge, const TopoDS_Face& theFace1, const TopoDS_Face& theFace2, Handle(IntTools_Context)& theContext); - - //! Returns True if the face theFace is inside of the - //! appropriate couple of faces (from the set theLF) . - //! The faces of the set theLF and theFace must - //! share the edge theEdge - //! * 0 state is not IN - //! * 1 state is IN - //! * 2 state can not be found by the method of angles - Standard_EXPORT static Standard_Integer IsInternalFace (const TopoDS_Face& theFace, const TopoDS_Edge& theEdge, TopTools_ListOfShape& theLF, Handle(IntTools_Context)& theContext); - - //! Returns True if the face theFace is inside the - //! solid theSolid. - //! theMEF - Map Edge/Faces for theSolid - //! theTol - value of precision of computation - //! theContext- cahed geometrical tools - Standard_EXPORT static Standard_Boolean IsInternalFace (const TopoDS_Face& theFace, const TopoDS_Solid& theSolid, TopTools_IndexedDataMapOfShapeListOfShape& theMEF, const Standard_Real theTol, Handle(IntTools_Context)& theContext); - - //! For the face theFace gets the edge theEdgeOnF - //! that is the same as theEdge - //! Returns True if such edge exists - //! Returns False if there is no such edge - Standard_EXPORT static Standard_Boolean GetEdgeOnFace (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace, TopoDS_Edge& theEdgeOnF); - - //! Computes the 3-D state of the point thePoint - //! toward solid theSolid. - //! theTol - value of precision of computation - //! theContext- cahed geometrical tools - //! Returns 3-D state. - Standard_EXPORT static TopAbs_State ComputeState (const gp_Pnt& thePoint, const TopoDS_Solid& theSolid, const Standard_Real theTol, Handle(IntTools_Context)& theContext); - - //! Computes the 3-D state of the vertex theVertex - //! toward solid theSolid. - //! theTol - value of precision of computation - //! theContext- cahed geometrical tools - //! Returns 3-D state. - Standard_EXPORT static TopAbs_State ComputeState (const TopoDS_Vertex& theVertex, const TopoDS_Solid& theSolid, const Standard_Real theTol, Handle(IntTools_Context)& theContext); - - //! Computes the 3-D state of the edge theEdge - //! toward solid theSolid. - //! theTol - value of precision of computation - //! theContext- cahed geometrical tools - //! Returns 3-D state. - Standard_EXPORT static TopAbs_State ComputeState (const TopoDS_Edge& theEdge, const TopoDS_Solid& theSolid, const Standard_Real theTol, Handle(IntTools_Context)& theContext); - - //! Computes the 3-D state of the face theFace - //! toward solid theSolid. - //! theTol - value of precision of computation - //! theBounds - set of edges of theFace to avoid - //! theContext- cahed geometrical tools - //! Returns 3-D state. - Standard_EXPORT static TopAbs_State ComputeState (const TopoDS_Face& theFace, const TopoDS_Solid& theSolid, const Standard_Real theTol, TopTools_IndexedMapOfShape& theBounds, Handle(IntTools_Context)& theContext); - - //! Computes the 3-D state of the shape theShape - //! toward solid theSolid. - //! theTol - value of precision of computation - //! theContext- cahed geometrical tools - //! Returns 3-D state. - Standard_EXPORT static TopAbs_State ComputeStateByOnePoint (const TopoDS_Shape& theShape, const TopoDS_Solid& theSolid, const Standard_Real theTol, Handle(IntTools_Context)& theContext); - + + +public: //! @name Wire classification relatively face + + //! Checks if the wire is a hole for the face. + Standard_EXPORT static Standard_Boolean IsHole(const TopoDS_Shape& theW, + const TopoDS_Shape& theF); + + +public: //! @name Choosing correct orientation for the split shape + + //! Checks if the direction of the split shape is opposite to + //! the direction of the original shape. + //! The method is an overload for (Edge,Edge) and (Face,Face) corresponding + //! methods and checks only these types of shapes. + //! For faces the method checks if normal directions are opposite. + //! For edges the method checks if tangent vectors are opposite. + //! + //! In case the directions do not coincide, it returns TRUE, meaning + //! that split shape has to be reversed to match the direction of the + //! original shape. + //! + //! If requested (<theError> is not null), the method returns the status of the operation: + //! - 0 - no error; + //! - Error from (Edge,Edge) or (Face,Face) corresponding method + //! - 100 - bad types. + //! In case of any error the method always returns FALSE. + //! + //! @param theSplit [in] Split shape + //! @param theShape [in] Original shape + //! @param theContext [in] Cashed geometrical tools + //! @param theError [out] Error Status of the operation + Standard_EXPORT static Standard_Boolean IsSplitToReverse(const TopoDS_Shape& theSplit, + const TopoDS_Shape& theShape, + const Handle(IntTools_Context)& theContext, + Standard_Integer *theError = NULL); + + //! Add-on for the *IsSplitToReverse()* to check for its errors + //! and in case of any add the *BOPAlgo_AlertUnableToOrientTheShape* + //! warning to the report. + Standard_EXPORT static Standard_Boolean IsSplitToReverseWithWarn(const TopoDS_Shape& theSplit, + const TopoDS_Shape& theShape, + const Handle(IntTools_Context)& theContext, + const Handle(Message_Report)& theReport = NULL); + + //! Checks if the normal direction of the split face is opposite to + //! the normal direction of the original face. + //! The normal directions for both faces are taken in the same point - + //! point inside the split face is projected onto the original face. + //! Returns TRUE if the normals do not coincide, meaning the necessity + //! to revert the orientation of the split face to match the direction + //! of the original face. + //! + //! If requested (<theError> is not null), the method returns the status of the operation: + //! - 0 - no error; + //! - 1 - unable to find the point inside split face; + //! - 2 - unable to compute the normal for the split face; + //! - 3 - unable to project the point inside the split face on the original face; + //! - 4 - unable to compute the normal for the original face. + //! In case of any error the method always returns FALSE. + //! + //! @param theSplit [in] Split face + //! @param theShape [in] Original face + //! @param theContext [in] Cashed geometrical tools + //! @param theError [out] Error Status of the operation + Standard_EXPORT static Standard_Boolean IsSplitToReverse(const TopoDS_Face& theSplit, + const TopoDS_Face& theShape, + const Handle(IntTools_Context)& theContext, + Standard_Integer *theError = NULL); + + //! Checks if the tangent vector of the split edge is opposite to + //! the tangent vector of the original edge. + //! The tangent vectors for both edges are computed in the same point - + //! point inside the split edge is projected onto the original edge. + //! Returns TRUE if the tangent vectors do not coincide, meaning the necessity + //! to revert the orientation of the split edge to match the direction + //! of the original edge. + //! + //! If requested (<theError> is not null), the method returns the status of the operation: + //! - 0 - no error; + //! - 1 - degenerated edges are given; + //! - 2 - unable to compute the tangent vector for the split edge; + //! - 3 - unable to project the point inside the split edge on the original edge; + //! - 4 - unable to compute the tangent vector for the original edge; + //! In case of any error the method always returns FALSE. + //! + //! @param theSplit [in] Split edge + //! @param theShape [in] Original edge + //! @param theContext [in] Cashed geometrical tools + //! @param theError [out] Error Status of the operation + Standard_EXPORT static Standard_Boolean IsSplitToReverse(const TopoDS_Edge& theSplit, + const TopoDS_Edge& theShape, + const Handle(IntTools_Context)& theContext, + Standard_Integer *theError = NULL); + + //! Checks if the normals direction of the given faces computed near + //! the shared edge coincide. + //! Returns the status of operation: + //! * 0 - in case of error (shared edge not found or directions are not collinear) + //! * 1 - normal directions coincide; + //! * -1 - normal directions are opposite. + Standard_EXPORT static Standard_Integer Sense(const TopoDS_Face& theF1, + const TopoDS_Face& theF2, + const Handle(IntTools_Context)& theContext); + +public: //! @name Making connexity blocks + //! For the list of faces theLS build block //! theLSCB in terms of connexity by edges //! theMapAvoid - set of edges to avoid for //! the treatment - Standard_EXPORT static void MakeConnexityBlock (TopTools_ListOfShape& theLS, TopTools_IndexedMapOfShape& theMapAvoid, TopTools_ListOfShape& theLSCB, const Handle(NCollection_BaseAllocator)& theAllocator); + Standard_EXPORT static void MakeConnexityBlock(TopTools_ListOfShape& theLS, + TopTools_IndexedMapOfShape& theMapAvoid, + TopTools_ListOfShape& theLSCB, + const Handle(NCollection_BaseAllocator)& theAllocator); //! For the compound <theS> builds the blocks (compounds) of //! elements of type <theElementType> connected through the shapes @@ -219,139 +427,136 @@ public: const TopAbs_ShapeEnum theElementType, BOPTools_ListOfConnexityBlock& theLCB); +public: //! @name Orienting elements in container + //! Correctly orients edges on the wire - Standard_EXPORT static void OrientEdgesOnWire (TopoDS_Shape& theWire); + Standard_EXPORT static void OrientEdgesOnWire(TopoDS_Shape& theWire); //! Correctly orients faces on the shell - Standard_EXPORT static void OrientFacesOnShell (TopoDS_Shape& theShell); - + Standard_EXPORT static void OrientFacesOnShell(TopoDS_Shape& theShell); + + +public: //! @name Methods for shape validation (correction) //! Provides valid values of tolerances for the shape <theS> //! <theTolMax> is max value of the tolerance that can be //! accepted for correction. If real value of the tolerance //! will be greater than <aTolMax>, the correction does not //! perform. - Standard_EXPORT static void CorrectTolerances - (const TopoDS_Shape& theS, - const TopTools_IndexedMapOfShape& theMapToAvoid, - const Standard_Real theTolMax = 0.0001, - const Standard_Boolean theRunParallel = Standard_False); + Standard_EXPORT static void CorrectTolerances(const TopoDS_Shape& theS, + const TopTools_IndexedMapOfShape& theMapToAvoid, + const Standard_Real theTolMax = 0.0001, + const Standard_Boolean theRunParallel = Standard_False); //! Provides valid values of tolerances for the shape <theS> //! in terms of BRepCheck_InvalidCurveOnSurface. - Standard_EXPORT static void CorrectCurveOnSurface - (const TopoDS_Shape& theS, - const TopTools_IndexedMapOfShape& theMapToAvoid, - const Standard_Real theTolMax = 0.0001, - const Standard_Boolean theRunParallel = Standard_False); + Standard_EXPORT static void CorrectCurveOnSurface(const TopoDS_Shape& theS, + const TopTools_IndexedMapOfShape& theMapToAvoid, + const Standard_Real theTolMax = 0.0001, + const Standard_Boolean theRunParallel = Standard_False); //! Provides valid values of tolerances for the shape <theS> //! in terms of BRepCheck_InvalidPointOnCurve. - Standard_EXPORT static void CorrectPointOnCurve - (const TopoDS_Shape& theS, - const TopTools_IndexedMapOfShape& theMapToAvoid, - const Standard_Real theTolMax = 0.0001, - const Standard_Boolean theRunParallel = Standard_False); + Standard_EXPORT static void CorrectPointOnCurve(const TopoDS_Shape& theS, + const TopTools_IndexedMapOfShape& theMapToAvoid, + const Standard_Real theTolMax = 0.0001, + const Standard_Boolean theRunParallel = Standard_False); - //! Make a vertex using 3D-point <aP1> and 3D-tolerance value <aTol> - Standard_EXPORT static void MakeNewVertex (const gp_Pnt& aP1, const Standard_Real aTol, TopoDS_Vertex& aNewVertex); - + //! Corrects tolerance values of the sub-shapes of the shape <theS> if needed. + Standard_EXPORT static void CorrectShapeTolerances(const TopoDS_Shape& theS, + const TopTools_IndexedMapOfShape& theMapToAvoid, + const Standard_Boolean theRunParallel = Standard_False); - //! Make a vertex using couple of vertices <aV1, aV2> - Standard_EXPORT static void MakeNewVertex (const TopoDS_Vertex& aV1, const TopoDS_Vertex& aV2, TopoDS_Vertex& aNewVertex); - - //! Make a vertex in place of intersection between two edges - //! <aE1, aE2> with parameters <aP1, aP2> - Standard_EXPORT static void MakeNewVertex (const TopoDS_Edge& aE1, const Standard_Real aP1, const TopoDS_Edge& aE2, const Standard_Real aP2, TopoDS_Vertex& aNewVertex); - +public: //! Checking if the faces are coinciding - //! Make a vertex in place of intersection between the edge <aE1> - //! with parameter <aP1> and the face <aF2> - Standard_EXPORT static void MakeNewVertex (const TopoDS_Edge& aE1, const Standard_Real aP1, const TopoDS_Face& aF2, TopoDS_Vertex& aNewVertex); - + //! Checks if the given faces are same-domain, i.e. coincide. + Standard_EXPORT static Standard_Boolean AreFacesSameDomain(const TopoDS_Face& theF1, + const TopoDS_Face& theF2, + const Handle(IntTools_Context)& theContext, + const Standard_Real theFuzz = Precision::Confusion()); - //! Compute a 3D-point on the edge <aEdge> at parameter <aPrm> - Standard_EXPORT static void PointOnEdge (const TopoDS_Edge& aEdge, const Standard_Real aPrm, gp_Pnt& aP); +public: //! @name Looking for the edge in the face - //! Makes a copy of <theEdge> with vertices. - Standard_EXPORT static TopoDS_Edge CopyEdge(const TopoDS_Edge& theEdge); + //! Returns True if the face theFace contains + //! the edge theEdge but with opposite orientation. + //! If the method returns True theEdgeOff is the + //! edge founded + Standard_EXPORT static Standard_Boolean GetEdgeOff(const TopoDS_Edge& theEdge, + const TopoDS_Face& theFace, + TopoDS_Edge& theEdgeOff); - //! Make the edge from base edge <aE1> and two vertices <aV1,aV2> - //! at parameters <aP1,aP2> - Standard_EXPORT static void MakeSplitEdge (const TopoDS_Edge& aE1, const TopoDS_Vertex& aV1, const Standard_Real aP1, const TopoDS_Vertex& aV2, const Standard_Real aP2, TopoDS_Edge& aNewEdge); - + //! For the face theFace gets the edge theEdgeOnF + //! that is the same as theEdge + //! Returns True if such edge exists + //! Returns False if there is no such edge + Standard_EXPORT static Standard_Boolean GetEdgeOnFace(const TopoDS_Edge& theEdge, + const TopoDS_Face& theFace, + TopoDS_Edge& theEdgeOnF); - //! Make the edge from 3D-Curve <aIC> and two vertices <aV1,aV2> - //! at parameters <aP1,aP2> - Standard_EXPORT static void MakeSectEdge (const IntTools_Curve& aIC, const TopoDS_Vertex& aV1, const Standard_Real aP1, const TopoDS_Vertex& aV2, const Standard_Real aP2, TopoDS_Edge& aNewEdge); - - //! Update the tolerance value for vertex <aV> - //! taking into account the fact that <aV> lays on - //! the curve <aIC> - Standard_EXPORT static void UpdateVertex (const IntTools_Curve& aIC, const Standard_Real aT, const TopoDS_Vertex& aV); - +public: //! @name Correction of the edges range - //! Update the tolerance value for vertex <aV> - //! taking into account the fact that <aV> lays on - //! the edge <aE> - Standard_EXPORT static void UpdateVertex (const TopoDS_Edge& aE, const Standard_Real aT, const TopoDS_Vertex& aV); - - - //! Update the tolerance value for vertex <aVN> - //! taking into account the fact that <aVN> should - //! cover tolerance zone of <aVF> - Standard_EXPORT static void UpdateVertex (const TopoDS_Vertex& aVF, const TopoDS_Vertex& aVN); + //! Correct shrunk range <aSR> taking into account 3D-curve + //! resolution and corresponding tolerance values of <aE1>, <aE2> + Standard_EXPORT static void CorrectRange(const TopoDS_Edge& aE1, + const TopoDS_Edge& aE2, + const IntTools_Range& aSR, + IntTools_Range& aNewSR); //! Correct shrunk range <aSR> taking into account 3D-curve - //! resolution and corresp. tolerances' values of <aE1>, <aE2> - Standard_EXPORT static void CorrectRange (const TopoDS_Edge& aE1, const TopoDS_Edge& aE2, const IntTools_Range& aSR, IntTools_Range& aNewSR); - + //! resolution and corresponding tolerance values of <aE>, <aF> + Standard_EXPORT static void CorrectRange(const TopoDS_Edge& aE, + const TopoDS_Face& aF, + const IntTools_Range& aSR, + IntTools_Range& aNewSR); - //! Correct shrunk range <aSR> taking into account 3D-curve - //! resolution and corresp. tolerances' values of <aE>, <aF> - Standard_EXPORT static void CorrectRange (const TopoDS_Edge& aE, const TopoDS_Face& aF, const IntTools_Range& aSR, IntTools_Range& aNewSR); - - - //! Returns TRUE if PaveBlock <aPB> lays on the face <aF>, i.e - //! the <PB> is IN or ON in 2D of <aF> - Standard_EXPORT static Standard_Boolean IsBlockInOnFace (const IntTools_Range& aShR, const TopoDS_Face& aF, const TopoDS_Edge& aE, Handle(IntTools_Context)& aContext); - +public: //! @name Checking edge on micro status //! Checks if it is possible to compute shrunk range for the edge <aE> //! Flag <theCheckSplittable> defines whether to take into account - //! the possiblity to split the edge or not. - Standard_EXPORT static Standard_Boolean IsMicroEdge (const TopoDS_Edge& theEdge, - const Handle(IntTools_Context)& theContext, - const Standard_Boolean theCheckSplittable = Standard_True); - + //! the possibility to split the edge or not. + Standard_EXPORT static Standard_Boolean IsMicroEdge(const TopoDS_Edge& theEdge, + const Handle(IntTools_Context)& theContext, + const Standard_Boolean theCheckSplittable = Standard_True); - //! Corrects tolerance values of the sub-shapes of the shape <theS> if needed. - Standard_EXPORT static void CorrectShapeTolerances - (const TopoDS_Shape& theS, - const TopTools_IndexedMapOfShape& theMapToAvoid, - const Standard_Boolean theRunParallel = Standard_False); +public: //! @name Solid classification - //! Retutns dimension of the shape <theS>. - Standard_EXPORT static Standard_Integer Dimension (const TopoDS_Shape& theS); - - //! Returns true if the shell <theShell> is open - Standard_EXPORT static Standard_Boolean IsOpenShell (const TopoDS_Shell& theShell); - //! Returns true if the solid <theSolid> is inverted - Standard_EXPORT static Standard_Boolean IsInvertedSolid (const TopoDS_Solid& theSolid); - + Standard_EXPORT static Standard_Boolean IsInvertedSolid(const TopoDS_Solid& theSolid); + +public: //! @name Edge/Face Deviation computation //! Computes the necessary value of the tolerance for the edge - Standard_EXPORT static Standard_Boolean ComputeTolerance (const TopoDS_Face& theFace, const TopoDS_Edge& theEdge, Standard_Real& theMaxDist, Standard_Real& theMaxPar); + Standard_EXPORT static Standard_Boolean ComputeTolerance(const TopoDS_Face& theFace, + const TopoDS_Edge& theEdge, + Standard_Real& theMaxDist, + Standard_Real& theMaxPar); +public: //! @name Other methods -protected: + //! Makes empty container of requested type + Standard_EXPORT static void MakeContainer(const TopAbs_ShapeEnum theType, + TopoDS_Shape& theShape); + //! Compute a 3D-point on the edge <aEdge> at parameter <aPrm> + Standard_EXPORT static void PointOnEdge(const TopoDS_Edge& aEdge, + const Standard_Real aPrm, + gp_Pnt& aP); -private: + //! Returns TRUE if PaveBlock <aPB> lays on the face <aF>, i.e + //! the <PB> is IN or ON in 2D of <aF> + Standard_EXPORT static Standard_Boolean IsBlockInOnFace(const IntTools_Range& aShR, + const TopoDS_Face& aF, + const TopoDS_Edge& aE, + const Handle(IntTools_Context)& aContext); + + //! Retutns dimension of the shape <theS>. + Standard_EXPORT static Standard_Integer Dimension(const TopoDS_Shape& theS); + + //! Returns true if the shell <theShell> is open + Standard_EXPORT static Standard_Boolean IsOpenShell(const TopoDS_Shell& theShell); }; diff --git a/src/BOPTools/BOPTools_AlgoTools2D.hxx b/src/BOPTools/BOPTools_AlgoTools2D.hxx index a867d0d9aa..8db49a549d 100644 --- a/src/BOPTools/BOPTools_AlgoTools2D.hxx +++ b/src/BOPTools/BOPTools_AlgoTools2D.hxx @@ -42,19 +42,17 @@ public: DEFINE_STANDARD_ALLOC - - //! Compute P-Curve for the edge <aE> on the face <aF>.<br> //! Raises exception Standard_ConstructionError if projection algorithm fails.<br> //! <theContext> - storage for caching the geometrical tools - Standard_EXPORT static void BuildPCurveForEdgeOnFace (const TopoDS_Edge& aE, - const TopoDS_Face& aF, - const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)()); - + Standard_EXPORT static void BuildPCurveForEdgeOnFace(const TopoDS_Edge& aE, + const TopoDS_Face& aF, + const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)()); //! Compute tangent for the edge <aE> [in 3D] at parameter <aT> - Standard_EXPORT static Standard_Boolean EdgeTangent (const TopoDS_Edge& anE, const Standard_Real aT, gp_Vec& Tau); - + Standard_EXPORT static Standard_Boolean EdgeTangent(const TopoDS_Edge& anE, + const Standard_Real aT, + gp_Vec& Tau); //! Compute surface parameters <U,V> of the face <aF> //! for the point from the edge <aE> at parameter <aT>.<br> @@ -62,24 +60,23 @@ public: //! projection and can //! raise exception Standard_ConstructionError if projection algorithm fails.<br> //! <theContext> - storage for caching the geometrical tools - Standard_EXPORT static void PointOnSurface (const TopoDS_Edge& aE, - const TopoDS_Face& aF, - const Standard_Real aT, - Standard_Real& U, - Standard_Real& V, - const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)()); - + Standard_EXPORT static void PointOnSurface(const TopoDS_Edge& aE, + const TopoDS_Face& aF, + const Standard_Real aT, + Standard_Real& U, + Standard_Real& V, + const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)()); //! Get P-Curve <aC> for the edge <aE> on surface <aF> .<br> //! If the P-Curve does not exist, build it using Make2D().<br> //! [aToler] - reached tolerance //! Raises exception Standard_ConstructionError if algorithm Make2D() fails.<br> //! <theContext> - storage for caching the geometrical tools - Standard_EXPORT static void CurveOnSurface (const TopoDS_Edge& aE, - const TopoDS_Face& aF, - Handle(Geom2d_Curve)& aC, - Standard_Real& aToler, - const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)()); + Standard_EXPORT static void CurveOnSurface(const TopoDS_Edge& aE, + const TopoDS_Face& aF, + Handle(Geom2d_Curve)& aC, + Standard_Real& aToler, + const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)()); //! Get P-Curve <aC> for the edge <aE> on surface <aF> .<br> //! If the P-Curve does not exist, build it using Make2D().<br> @@ -87,102 +84,108 @@ public: //! [aToler] - reached tolerance<br> //! Raises exception Standard_ConstructionError if algorithm Make2D() fails.<br> //! <theContext> - storage for caching the geometrical tools - Standard_EXPORT static void CurveOnSurface (const TopoDS_Edge& aE, - const TopoDS_Face& aF, - Handle(Geom2d_Curve)& aC, - Standard_Real& aFirst, - Standard_Real& aLast, - Standard_Real& aToler, - const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)()); - + Standard_EXPORT static void CurveOnSurface(const TopoDS_Edge& aE, + const TopoDS_Face& aF, + Handle(Geom2d_Curve)& aC, + Standard_Real& aFirst, + Standard_Real& aLast, + Standard_Real& aToler, + const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)()); //! Returns TRUE if the edge <aE> has P-Curve <aC> //! on surface <aF> . //! [aFirst, aLast] - range of the P-Curve //! [aToler] - reached tolerance //! If the P-Curve does not exist, aC.IsNull()=TRUE. - Standard_EXPORT static Standard_Boolean HasCurveOnSurface (const TopoDS_Edge& aE, const TopoDS_Face& aF, Handle(Geom2d_Curve)& aC, Standard_Real& aFirst, Standard_Real& aLast, Standard_Real& aToler); - + Standard_EXPORT static Standard_Boolean HasCurveOnSurface(const TopoDS_Edge& aE, + const TopoDS_Face& aF, + Handle(Geom2d_Curve)& aC, + Standard_Real& aFirst, + Standard_Real& aLast, + Standard_Real& aToler); //! Returns TRUE if the edge <aE> has P-Curve <aC> //! on surface <aF> . //! If the P-Curve does not exist, aC.IsNull()=TRUE. - Standard_EXPORT static Standard_Boolean HasCurveOnSurface (const TopoDS_Edge& aE, const TopoDS_Face& aF); - + Standard_EXPORT static Standard_Boolean HasCurveOnSurface(const TopoDS_Edge& aE, + const TopoDS_Face& aF); //! Adjust P-Curve <theC2D> (3D-curve <theC3D>) on surface of the face <theF>.<br> //! <theContext> - storage for caching the geometrical tools - Standard_EXPORT static void AdjustPCurveOnFace (const TopoDS_Face& theF, - const Handle(Geom_Curve)& theC3D, - const Handle(Geom2d_Curve)& theC2D, - Handle(Geom2d_Curve)& theC2DA, - const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)()); - + Standard_EXPORT static void AdjustPCurveOnFace(const TopoDS_Face& theF, + const Handle(Geom_Curve)& theC3D, + const Handle(Geom2d_Curve)& theC2D, + Handle(Geom2d_Curve)& theC2DA, + const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)()); //! Adjust P-Curve <aC2D> (3D-curve <C3D>) on surface <aF> .<br> //! [aT1, aT2] - range to adjust<br> //! <theContext> - storage for caching the geometrical tools - Standard_EXPORT static void AdjustPCurveOnFace (const TopoDS_Face& theF, - const Standard_Real theFirst, - const Standard_Real theLast, - const Handle(Geom2d_Curve)& theC2D, - Handle(Geom2d_Curve)& theC2DA, - const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)()); + Standard_EXPORT static void AdjustPCurveOnFace(const TopoDS_Face& theF, + const Standard_Real theFirst, + const Standard_Real theLast, + const Handle(Geom2d_Curve)& theC2D, + Handle(Geom2d_Curve)& theC2DA, + const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)()); //! Adjust P-Curve <aC2D> (3D-curve <C3D>) on surface <aF> . //! [aT1, aT2] - range to adjust - Standard_EXPORT static void AdjustPCurveOnSurf (const BRepAdaptor_Surface& aF, const Standard_Real aT1, const Standard_Real aT2, const Handle(Geom2d_Curve)& aC2D, Handle(Geom2d_Curve)& aC2DA); - + Standard_EXPORT static void AdjustPCurveOnSurf(const BRepAdaptor_Surface& aF, + const Standard_Real aT1, + const Standard_Real aT2, + const Handle(Geom2d_Curve)& aC2D, + Handle(Geom2d_Curve)& aC2DA); //! Compute intermediate value in between [aFirst, aLast] . - Standard_EXPORT static Standard_Real IntermediatePoint (const Standard_Real aFirst, const Standard_Real aLast); - + Standard_EXPORT static Standard_Real IntermediatePoint(const Standard_Real aFirst, + const Standard_Real aLast); //! Compute intermediate value of parameter for the edge <anE>. - Standard_EXPORT static Standard_Real IntermediatePoint (const TopoDS_Edge& anE); + Standard_EXPORT static Standard_Real IntermediatePoint(const TopoDS_Edge& anE); //! Make P-Curve <aC> for the edge <aE> on surface <aF> .<br> //! [aFirst, aLast] - range of the P-Curve<br> //! [aToler] - reached tolerance<br> //! Raises exception Standard_ConstructionError if algorithm fails.<br> //! <theContext> - storage for caching the geometrical tools - Standard_EXPORT static void Make2D (const TopoDS_Edge& aE, - const TopoDS_Face& aF, - Handle(Geom2d_Curve)& aC, - Standard_Real& aFirst, - Standard_Real& aLast, - Standard_Real& aToler, - const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)()); - + Standard_EXPORT static void Make2D(const TopoDS_Edge& aE, + const TopoDS_Face& aF, + Handle(Geom2d_Curve)& aC, + Standard_Real& aFirst, + Standard_Real& aLast, + Standard_Real& aToler, + const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)()); //! Make P-Curve <aC> for the 3D-curve <C3D> on surface <aF> .<br> //! [aToler] - reached tolerance<br> //! Raises exception Standard_ConstructionError if projection algorithm fails.<br> //! <theContext> - storage for caching the geometrical tools - Standard_EXPORT static void MakePCurveOnFace (const TopoDS_Face& aF, - const Handle(Geom_Curve)& C3D, - Handle(Geom2d_Curve)& aC, - Standard_Real& aToler, - const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)()); - + Standard_EXPORT static void MakePCurveOnFace(const TopoDS_Face& aF, + const Handle(Geom_Curve)& C3D, + Handle(Geom2d_Curve)& aC, + Standard_Real& aToler, + const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)()); //! Make P-Curve <aC> for the 3D-curve <C3D> on surface <aF> .<br> //! [aT1, aT2] - range to build<br> //! [aToler] - reached tolerance<br> //! Raises exception Standard_ConstructionError if projection algorithm fails.<br> //! <theContext> - storage for caching the geometrical tools - Standard_EXPORT static void MakePCurveOnFace (const TopoDS_Face& aF, - const Handle(Geom_Curve)& C3D, - const Standard_Real aT1, - const Standard_Real aT2, - Handle(Geom2d_Curve)& aC, - Standard_Real& aToler, - const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)()); - + Standard_EXPORT static void MakePCurveOnFace(const TopoDS_Face& aF, + const Handle(Geom_Curve)& C3D, + const Standard_Real aT1, + const Standard_Real aT2, + Handle(Geom2d_Curve)& aC, + Standard_Real& aToler, + const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)()); + //! Attach P-Curve from the edge <aEold> on surface <aF> //! to the edge <aEnew> //! Returns 0 in case of success - Standard_EXPORT static Standard_Integer AttachExistingPCurve (const TopoDS_Edge& aEold, const TopoDS_Edge& aEnew, const TopoDS_Face& aF, const Handle(IntTools_Context)& aCtx); + Standard_EXPORT static Standard_Integer AttachExistingPCurve(const TopoDS_Edge& aEold, + const TopoDS_Edge& aEnew, + const TopoDS_Face& aF, + const Handle(IntTools_Context)& aCtx); //! Checks if CurveOnSurface of theE on theF matches with isoline of theF surface. //! Sets corresponding values for isTheUIso and isTheVIso variables. @@ -199,25 +202,6 @@ public: Standard_Boolean& isTheUIso, Standard_Boolean& isTheVIso); - -protected: - - - - - -private: - - - - - }; - - - - - - #endif // _BOPTools_AlgoTools2D_HeaderFile diff --git a/src/BOPTools/BOPTools_AlgoTools2D_1.cxx b/src/BOPTools/BOPTools_AlgoTools2D_1.cxx index 0434b142f0..e6591cf698 100644 --- a/src/BOPTools/BOPTools_AlgoTools2D_1.cxx +++ b/src/BOPTools/BOPTools_AlgoTools2D_1.cxx @@ -40,7 +40,7 @@ #include <IntTools_Context.hxx> #include <IntTools_Tools.hxx> -#include <BOPTools_AlgoTools2D.hxx> +#include <BOPTools_AlgoTools.hxx> @@ -49,10 +49,6 @@ static const TopoDS_Edge& , const TopoDS_Face& , const Handle(IntTools_Context)& ); -static - Standard_Boolean IsToReverse(const TopoDS_Edge& , - const TopoDS_Edge& , - const Handle(IntTools_Context)& ); static Standard_Boolean IsClosed(const TopoDS_Edge& , const TopoDS_Face& ); @@ -85,7 +81,7 @@ Standard_Integer BOPTools_AlgoTools2D::AttachExistingPCurve // aC2DoldC=Handle(Geom2d_Curve)::DownCast(aC2Dold->Copy()); // - bIsToReverse=IsToReverse(aE2, aE1, aCtx); + bIsToReverse = BOPTools_AlgoTools::IsSplitToReverse(aE1, aE2, aCtx); if (bIsToReverse) { Standard_Real aT21r, aT22r; // @@ -281,49 +277,6 @@ Standard_Integer UpdateClosedPCurve(const TopoDS_Edge& aEold, return iRet; } //======================================================================= -//function : IsToReverse -//purpose : -//======================================================================= -Standard_Boolean IsToReverse(const TopoDS_Edge& aEold, - const TopoDS_Edge& aEnew, - const Handle(IntTools_Context)& aCtx) -{ - Standard_Boolean bRet, bIsDegenerated; - Standard_Real aTnew, aTold, aScPr, aTa, aTb, aT1, aT2; - gp_Vec aVold, aVnew, aVE, aVS; - gp_Pnt aP; - Handle(Geom_Curve) aCold, aCnew; - // - bRet=Standard_False; - // - bIsDegenerated=(BRep_Tool::Degenerated(aEold) || - BRep_Tool::Degenerated(aEnew)); - if (bIsDegenerated) { - return bRet; - } - // - aCold=BRep_Tool::Curve(aEold, aT1, aT2); - aCnew=BRep_Tool::Curve(aEnew, aTa, aTb); - // - if (aCold==aCnew) { - return bRet; - } - // - aTnew=BOPTools_AlgoTools2D::IntermediatePoint(aTa, aTb); - aCnew->D1(aTnew, aP, aVnew); - aVnew.Normalize(); - // - if (!aCtx->ProjectPointOnEdge(aP, aEold, aTold)) - return Standard_False; - aCold->D1(aTold, aP, aVold); - aVold.Normalize(); - // - aScPr=aVnew*aVold; - bRet=(aScPr<0.); - // - return bRet; -} -//======================================================================= //function : IsClosed //purpose : //======================================================================= diff --git a/src/BOPTools/BOPTools_AlgoTools3D.cxx b/src/BOPTools/BOPTools_AlgoTools3D.cxx index d45c8a139f..06653d1605 100644 --- a/src/BOPTools/BOPTools_AlgoTools3D.cxx +++ b/src/BOPTools/BOPTools_AlgoTools3D.cxx @@ -369,7 +369,7 @@ Standard_Boolean BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge const Standard_Real aT, gp_Pnt& aPNear, gp_Dir& aDNF, - Handle(IntTools_Context)& theContext) + const Handle(IntTools_Context)& theContext) { gp_Pnt2d aPx2DNear; Standard_Integer iErr = BOPTools_AlgoTools3D::PointNearEdge @@ -398,7 +398,7 @@ Standard_Boolean BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge const Standard_Real theStep, gp_Pnt& aPNear, gp_Dir& aDNF, - Handle(IntTools_Context)& theContext) + const Handle(IntTools_Context)& theContext) { gp_Pnt2d aPx2DNear; Standard_Integer iErr = BOPTools_AlgoTools3D::PointNearEdge @@ -510,7 +510,7 @@ Standard_Integer BOPTools_AlgoTools3D::PointNearEdge const Standard_Real aT, gp_Pnt2d& aPx2DNear, gp_Pnt& aPxNear, - Handle(IntTools_Context)& theContext) + const Handle(IntTools_Context)& theContext) { Standard_Real aTolE, aTolF, dTx, dT2D; Handle(Geom_Surface) aS; @@ -563,7 +563,7 @@ Standard_Integer BOPTools_AlgoTools3D::PointNearEdge const Standard_Real theStep, gp_Pnt2d& aPx2DNear, gp_Pnt& aPxNear, - Handle(IntTools_Context)& theContext) + const Handle(IntTools_Context)& theContext) { Standard_Integer iErr = BOPTools_AlgoTools3D::PointNearEdge (aE, aF, aT, theStep, aPx2DNear, aPxNear); @@ -593,7 +593,7 @@ Standard_Integer BOPTools_AlgoTools3D::PointNearEdge const TopoDS_Face& aF, gp_Pnt2d& aPInFace2D, gp_Pnt& aPInFace, - Handle(IntTools_Context)& theContext) + const Handle(IntTools_Context)& theContext) { Standard_Real aT, aT1, aT2; // @@ -783,7 +783,7 @@ Standard_Integer BOPTools_AlgoTools3D::PointInFace (const TopoDS_Face& theF, gp_Pnt& theP, gp_Pnt2d& theP2D, - Handle(IntTools_Context)& theContext) + const Handle(IntTools_Context)& theContext) { Standard_Integer i, iErr = 1; Standard_Real aUMin, aUMax, aVMin, aVMax, aUx; @@ -822,7 +822,7 @@ Standard_Integer BOPTools_AlgoTools3D::PointInFace const Standard_Real theDt2D, gp_Pnt& theP, gp_Pnt2d& theP2D, - Handle(IntTools_Context)& theContext) + const Handle(IntTools_Context)& theContext) { Standard_Integer iErr; Standard_Real f, l; @@ -870,7 +870,7 @@ Standard_Integer BOPTools_AlgoTools3D::PointInFace const Handle(Geom2d_Curve)& theL2D, gp_Pnt& theP, gp_Pnt2d& theP2D, - Handle(IntTools_Context)& theContext, + const Handle(IntTools_Context)& theContext, const Standard_Real theDt2D) { Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint; diff --git a/src/BOPTools/BOPTools_AlgoTools3D.hxx b/src/BOPTools/BOPTools_AlgoTools3D.hxx index a9567b779a..9a3d5de623 100644 --- a/src/BOPTools/BOPTools_AlgoTools3D.hxx +++ b/src/BOPTools/BOPTools_AlgoTools3D.hxx @@ -100,7 +100,7 @@ public: const Standard_Real aT, gp_Pnt& aPx, gp_Dir& aD, - Handle(IntTools_Context)& theContext); + const Handle(IntTools_Context)& theContext); //! Computes normal to the face <aF> for the 3D-point that //! belongs to the edge <aE> at parameter <aT>.<br> @@ -142,7 +142,7 @@ public: const Standard_Real aDt2D, gp_Pnt& aP, gp_Dir& aDNF, - Handle(IntTools_Context)& theContext); + const Handle(IntTools_Context)& theContext); //! Compute the point <aPx>, (<aP2D>) that is near to //! the edge <aE> at parameter <aT> towards to the @@ -160,7 +160,7 @@ public: const Standard_Real aDt2D, gp_Pnt2d& aP2D, gp_Pnt& aPx, - Handle(IntTools_Context)& theContext); + const Handle(IntTools_Context)& theContext); //! Compute the point <aPx>, (<aP2D>) that is near to //! the edge <aE> at parameter <aT> towards to the @@ -191,7 +191,7 @@ public: const Standard_Real aT, gp_Pnt2d& aP2D, gp_Pnt& aPx, - Handle(IntTools_Context)& theContext); + const Handle(IntTools_Context)& theContext); //! Compute the point <aPx>, (<aP2D>) that is near to @@ -208,7 +208,7 @@ public: const TopoDS_Face& aF, gp_Pnt2d& aP2D, gp_Pnt& aPx, - Handle(IntTools_Context)& theContext); + const Handle(IntTools_Context)& theContext); //! Returns simple step value that is used in 2D-computations @@ -232,7 +232,7 @@ public: Standard_EXPORT static Standard_Integer PointInFace (const TopoDS_Face& theF, gp_Pnt& theP, gp_Pnt2d& theP2D, - Handle(IntTools_Context)& theContext); + const Handle(IntTools_Context)& theContext); //! Computes a point <theP> inside the face <theF> //! using starting point taken by the parameter <theT> @@ -249,7 +249,7 @@ public: const Standard_Real theDt2D, gp_Pnt& theP, gp_Pnt2d& theP2D, - Handle(IntTools_Context)& theContext); + const Handle(IntTools_Context)& theContext); //! Computes a point <theP> inside the face <theF> //! using the line <theL> so that 2D point @@ -260,7 +260,7 @@ public: const Handle(Geom2d_Curve)& theL, gp_Pnt& theP, gp_Pnt2d& theP2D, - Handle(IntTools_Context)& theContext, + const Handle(IntTools_Context)& theContext, const Standard_Real theDt2D = 0.0); diff --git a/tests/bugs/modalg_7/bug29698 b/tests/bugs/modalg_7/bug29698 new file mode 100644 index 0000000000..04deaadc2c --- /dev/null +++ b/tests/bugs/modalg_7/bug29698 @@ -0,0 +1,43 @@ +puts "============" +puts "OCC29698" +puts "============" +puts "" +############################### +## Regression vs 7.2.0: Common operation raises FLT_INVALID_OPERATION exception +############################### + +# the case is a copy of the test case +# bugs/modalg_6/bug26952_1 +# to test the BOP operation on the same arguments +# with FPE signals switched on + +restore [locate_data_file bug26952_B41.brep] b1 +restore [locate_data_file bug26952_Tank41_1.brep] b2 + +# enable FPE signals +dsetsignal 1 + +bclearobjects +bcleartools +baddobjects b1 +baddtools b2 +bfillds +bbop result 0 + +# disable FPE signals +dsetsignal 0 + +checkprops result -s 424.666 +checknbshapes result -wire 2 -face 1 + +# check modification of the front face of the solid +savehistory h +explode b2 f +modified f_mod h b2_12 + +explode result f +checkprops f_mod -equal result_1 + +checknbshapes f_mod -ref [nbshapes result_1] + +checkview -display result -2d -path ${imagedir}/${test_image}.png