From 8d795b5130df6b6df54f1179767fe27a22232ddd Mon Sep 17 00:00:00 2001 From: jgv Date: Thu, 8 Sep 2016 18:20:57 +0300 Subject: [PATCH] 0027720: HLRBrep_Algo BSpline missing edges The algorithm that builds outlines ("silhouettes") makes an outline in 2d parametric space of the surface starting from some previously detected point where normal is orthogonal to direction of view. So, the surface is previously discretized into (m*n) sample points and some of them become starting points for future outlines. If the surface has non-uniform parametrization and/or some local extremums of curvature, the outlines can not be built without breaks, so there are several groups of consequent outlines in this case. Unfortunately, it leads to the situation when current number of sample points becomes insufficient to build all the parts of outlines. The idea is to detect the "holes" between already constructed parts of outlines and then complete the construction. New auxiliary draw command for testing of HLR. Correction according to the remarks. Update of test case according to the developer's directive --- src/Contap/Contap_Contour.cxx | 3 +- src/Contap/Contap_TheIWalking.hxx | 20 +++- src/HLRTest/HLRTest.cxx | 59 ++++++++++ src/IntPatch/IntPatch_TheIWalking.hxx | 20 +++- src/IntSurf/IntSurf_PntOn2S.cxx | 27 ++++- src/IntSurf/IntSurf_PntOn2S.hxx | 18 ++- src/IntWalk/IntWalk_IWalking_1.gxx | 36 +++++- src/IntWalk/IntWalk_IWalking_2.gxx | 154 ++++++++++++++++++++++++++ src/IntWalk/IntWalk_IWalking_3.gxx | 21 +++- src/IntWalk/IntWalk_IWalking_4.gxx | 133 +++++++++++++++++++++- src/IntWalk/IntWalk_IWalking_6.gxx | 55 ++++++++- tests/bugs/modalg_6/bug27341_303 | 2 +- tests/bugs/modalg_6/bug27720_1 | 26 +++++ tests/bugs/modalg_6/bug27720_2 | 4 +- tests/bugs/modalg_6/bug27720_4 | 26 +++++ tests/bugs/modalg_6/bug27720_5 | 26 +++++ 16 files changed, 600 insertions(+), 30 deletions(-) create mode 100644 tests/bugs/modalg_6/bug27720_1 create mode 100644 tests/bugs/modalg_6/bug27720_4 create mode 100644 tests/bugs/modalg_6/bug27720_5 diff --git a/src/Contap/Contap_Contour.cxx b/src/Contap/Contap_Contour.cxx index 34c457deeb..d5e7aa5785 100644 --- a/src/Contap/Contap_Contour.cxx +++ b/src/Contap/Contap_Contour.cxx @@ -1491,7 +1491,8 @@ void Contap_Contour::Perform if (seqpdep.Length() != 0 || seqpins.Length() != 0) { - Contap_TheIWalking iwalk(Preci,Fleche,Pas); + Standard_Boolean theToFillHoles = Standard_True; + Contap_TheIWalking iwalk(Preci,Fleche,Pas,theToFillHoles); iwalk.Perform(seqpdep,seqpins,mySFunc ,Surf); if(!iwalk.IsDone()) { return; diff --git a/src/Contap/Contap_TheIWalking.hxx b/src/Contap/Contap_TheIWalking.hxx index 1a4d886e6d..d61312ba1c 100644 --- a/src/Contap/Contap_TheIWalking.hxx +++ b/src/Contap/Contap_TheIWalking.hxx @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -61,7 +62,11 @@ public: //! consecutive points (in 2d space). //! Epsilon is the tolerance beyond which 2 points //! are confused. - Standard_EXPORT Contap_TheIWalking(const Standard_Real Epsilon, const Standard_Real Deflection, const Standard_Real Step); + //! theToFillHoles is the flag defining whether possible holes + //! between resulting curves are filled or not + //! in case of Contap walking theToFillHoles is True + Standard_EXPORT Contap_TheIWalking(const Standard_Real Epsilon, const Standard_Real Deflection, const Standard_Real Step, + const Standard_Boolean theToFillHoles = Standard_False); //! Deflection is the maximum deflection admitted between two //! consecutive points on a resulting polyline. @@ -117,6 +122,10 @@ protected: Standard_EXPORT Standard_Boolean TestArretAjout (Contap_SurfFunction& Section, math_Vector& UV, Standard_Integer& Irang, IntSurf_PntOn2S& PSol); + Standard_EXPORT void FillPntsInHoles (Contap_SurfFunction& Section, + TColStd_SequenceOfInteger& CopySeqAlone, + IntSurf_SequenceOfInteriorPoint& PntsInHoles); + Standard_EXPORT void TestArretCadre (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const Handle(Contap_TheIWLineOfTheIWalking)& Line, Contap_SurfFunction& Section, math_Vector& UV, Standard_Integer& Irang); Standard_EXPORT IntWalk_StatusDeflection TestDeflection (Contap_SurfFunction& Section, const Standard_Boolean Finished, const math_Vector& UV, const IntWalk_StatusDeflection StatusPrecedent, Standard_Integer& NbDivision, Standard_Real& Step, const Standard_Integer StepSign); @@ -125,6 +134,12 @@ protected: Standard_EXPORT void OpenLine (const Standard_Integer N, const IntSurf_PntOn2S& Psol, const IntSurf_SequenceOfPathPoint& Pnts1, Contap_SurfFunction& Section, const Handle(Contap_TheIWLineOfTheIWalking)& Line); + Standard_EXPORT Standard_Boolean IsValidEndPoint (const Standard_Integer IndOfPoint, const Standard_Integer IndOfLine); + + Standard_EXPORT void RemoveTwoEndPoints (const Standard_Integer IndOfPoint); + + Standard_EXPORT Standard_Boolean IsPointOnLine (const gp_Pnt2d& theP2d, const Standard_Integer Irang); + Standard_EXPORT void ComputeCloseLine (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const IntSurf_SequenceOfPathPoint& Pnts1, const IntSurf_SequenceOfInteriorPoint& Pnts2, Contap_SurfFunction& Section, Standard_Boolean& Rajout); Standard_EXPORT void AddPointInCurrentLine (const Standard_Integer N, const IntSurf_PathPoint& PathPnt, const Handle(Contap_TheIWLineOfTheIWalking)& CurrentLine) const; @@ -159,7 +174,10 @@ private: gp_Vec previousd3d; gp_Dir2d previousd2d; TColStd_SequenceOfInteger seqAjout; + TColStd_SequenceOfInteger seqAlone; + TColStd_DataMapOfIntegerListOfInteger PointLineLine; Contap_SequenceOfIWLineOfTheIWalking lines; + Standard_Boolean ToFillHoles; }; diff --git a/src/HLRTest/HLRTest.cxx b/src/HLRTest/HLRTest.cxx index 2af070ded8..6379df6376 100644 --- a/src/HLRTest/HLRTest.cxx +++ b/src/HLRTest/HLRTest.cxx @@ -501,6 +501,61 @@ static Standard_Integer hlrin3d(Draw_Interpretor& , Standard_Integer n, const ch return 0; } +//======================================================================= +//function : hlrin2d +//purpose : +//======================================================================= + +static Standard_Integer hlrin2d(Draw_Interpretor& , Standard_Integer n, const char** a) +{ + if (n < 9) + return 1; + + TopoDS_Shape aShape = DBRep::Get(a[2]); + if (aShape.IsNull()) + return 1; + + Standard_Real anAISViewProjX = atof(a[3]); + Standard_Real anAISViewProjY = atof(a[4]); + Standard_Real anAISViewProjZ = atof(a[5]); + + Standard_Real Eye_X = atof(a[6]); + Standard_Real Eye_Y = atof(a[7]); + Standard_Real Eye_Z = atof(a[8]); + + + + gp_Pnt anOrigin(0.,0.,0.); + gp_Dir aNormal(anAISViewProjX, anAISViewProjY, anAISViewProjZ); + gp_Dir aDX(Eye_X, Eye_Y, Eye_Z); + + HLRAppli_ReflectLines Reflector(aShape); + + Reflector.SetAxes(aNormal.X(), aNormal.Y(), aNormal.Z(), + anOrigin.X(), anOrigin.Y(), anOrigin.Z(), + aDX.X(), aDX.Y(), aDX.Z()); + + Reflector.Perform(); + + TopoDS_Compound Result; + BRep_Builder BB; + BB.MakeCompound(Result); + + TopoDS_Shape SharpEdges = Reflector.GetCompoundOf3dEdges(HLRBRep_Sharp, Standard_True, Standard_False); + if (!SharpEdges.IsNull()) + BB.Add(Result, SharpEdges); + TopoDS_Shape OutLines = Reflector.GetCompoundOf3dEdges(HLRBRep_OutLine, Standard_True, Standard_False); + if (!OutLines.IsNull()) + BB.Add(Result, OutLines); + TopoDS_Shape SmoothEdges = Reflector.GetCompoundOf3dEdges(HLRBRep_Rg1Line, Standard_True, Standard_False); + if (!SmoothEdges.IsNull()) + BB.Add(Result, SmoothEdges); + + DBRep::Set(a[1], Result); + + return 0; +} + //======================================================================= //function : Commands //purpose : @@ -533,6 +588,10 @@ void HLRTest::Commands (Draw_Interpretor& theCommands) "hlrin3d res shape proj_X proj_Y proj_Z", __FILE__, hlrin3d, g); + theCommands.Add("hlrin2d", + "hlrin2d res shape proj_X proj_Y proj_Z eye_x eye_y eye_z", + __FILE__, hlrin2d, g); + hider = new HLRBRep_Algo(); } diff --git a/src/IntPatch/IntPatch_TheIWalking.hxx b/src/IntPatch/IntPatch_TheIWalking.hxx index ff296da799..98f16f13ee 100644 --- a/src/IntPatch/IntPatch_TheIWalking.hxx +++ b/src/IntPatch/IntPatch_TheIWalking.hxx @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -61,7 +62,11 @@ public: //! consecutive points (in 2d space). //! Epsilon is the tolerance beyond which 2 points //! are confused. - Standard_EXPORT IntPatch_TheIWalking(const Standard_Real Epsilon, const Standard_Real Deflection, const Standard_Real Step); + //! theToFillHoles is the flag defining whether possible holes + //! between resulting curves are filled or not + //! in case of IntPatch walking theToFillHoles is False + Standard_EXPORT IntPatch_TheIWalking(const Standard_Real Epsilon, const Standard_Real Deflection, const Standard_Real Step, + const Standard_Boolean theToFillHoles = Standard_False); //! Deflection is the maximum deflection admitted between two //! consecutive points on a resulting polyline. @@ -117,6 +122,10 @@ protected: Standard_EXPORT Standard_Boolean TestArretAjout (IntPatch_TheSurfFunction& Section, math_Vector& UV, Standard_Integer& Irang, IntSurf_PntOn2S& PSol); + Standard_EXPORT void FillPntsInHoles (IntPatch_TheSurfFunction& Section, + TColStd_SequenceOfInteger& CopySeqAlone, + IntSurf_SequenceOfInteriorPoint& PntsInHoles); + Standard_EXPORT void TestArretCadre (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const Handle(IntPatch_TheIWLineOfTheIWalking)& Line, IntPatch_TheSurfFunction& Section, math_Vector& UV, Standard_Integer& Irang); Standard_EXPORT IntWalk_StatusDeflection TestDeflection (IntPatch_TheSurfFunction& Section, const Standard_Boolean Finished, const math_Vector& UV, const IntWalk_StatusDeflection StatusPrecedent, Standard_Integer& NbDivision, Standard_Real& Step, const Standard_Integer StepSign); @@ -125,6 +134,12 @@ protected: Standard_EXPORT void OpenLine (const Standard_Integer N, const IntSurf_PntOn2S& Psol, const IntSurf_SequenceOfPathPoint& Pnts1, IntPatch_TheSurfFunction& Section, const Handle(IntPatch_TheIWLineOfTheIWalking)& Line); + Standard_EXPORT Standard_Boolean IsValidEndPoint (const Standard_Integer IndOfPoint, const Standard_Integer IndOfLine); + + Standard_EXPORT void RemoveTwoEndPoints (const Standard_Integer IndOfPoint); + + Standard_EXPORT Standard_Boolean IsPointOnLine (const gp_Pnt2d& theP2d, const Standard_Integer Irang); + Standard_EXPORT void ComputeCloseLine (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const IntSurf_SequenceOfPathPoint& Pnts1, const IntSurf_SequenceOfInteriorPoint& Pnts2, IntPatch_TheSurfFunction& Section, Standard_Boolean& Rajout); Standard_EXPORT void AddPointInCurrentLine (const Standard_Integer N, const IntSurf_PathPoint& PathPnt, const Handle(IntPatch_TheIWLineOfTheIWalking)& CurrentLine) const; @@ -159,7 +174,10 @@ private: gp_Vec previousd3d; gp_Dir2d previousd2d; TColStd_SequenceOfInteger seqAjout; + TColStd_SequenceOfInteger seqAlone; + TColStd_DataMapOfIntegerListOfInteger PointLineLine; IntPatch_SequenceOfIWLineOfTheIWalking lines; + Standard_Boolean ToFillHoles; }; diff --git a/src/IntSurf/IntSurf_PntOn2S.cxx b/src/IntSurf/IntSurf_PntOn2S.cxx index 4397630da9..df167df6a4 100644 --- a/src/IntSurf/IntSurf_PntOn2S.cxx +++ b/src/IntSurf/IntSurf_PntOn2S.cxx @@ -16,7 +16,9 @@ #include #include -IntSurf_PntOn2S::IntSurf_PntOn2S () : pt(0,0,0),u1(0),v1(0),u2(0),v2(0) {} +IntSurf_PntOn2S::IntSurf_PntOn2S () + : pt(0,0,0),u1(0),v1(0),u2(0),v2(0) +{} void IntSurf_PntOn2S::SetValue (const gp_Pnt& Pt, const Standard_Boolean OnFirst, @@ -49,6 +51,29 @@ void IntSurf_PntOn2S::SetValue (const Standard_Boolean OnFirst, } } +gp_Pnt2d IntSurf_PntOn2S::ValueOnSurface(const Standard_Boolean OnFirst) const +{ + gp_Pnt2d PointOnSurf; + if (OnFirst) + PointOnSurf.SetCoord(u1,v1); + else + PointOnSurf.SetCoord(u2,v2); + return PointOnSurf; +} + +void IntSurf_PntOn2S::ParametersOnSurface(const Standard_Boolean OnFirst, + Standard_Real& U, + Standard_Real& V) const +{ + if (OnFirst) { + U = u1; + V = v1; + } + else { + U = u2; + V = v2; + } +} Standard_Boolean IntSurf_PntOn2S::IsSame( const IntSurf_PntOn2S& theOterPoint, const Standard_Real theTol3D, diff --git a/src/IntSurf/IntSurf_PntOn2S.hxx b/src/IntSurf/IntSurf_PntOn2S.hxx index a6cc213d48..773bd9d544 100644 --- a/src/IntSurf/IntSurf_PntOn2S.hxx +++ b/src/IntSurf/IntSurf_PntOn2S.hxx @@ -25,6 +25,7 @@ #include #include class gp_Pnt; +class gp_Pnt2d; //! This class defines the geometric informations @@ -58,24 +59,31 @@ public: //! Set the values of the point in the parametric //! space of one of the surface. - void SetValue (const Standard_Real U1, const Standard_Real V1, const Standard_Real U2, const Standard_Real V2); + void SetValue (const Standard_Real U1, const Standard_Real V1, const Standard_Real U2, const Standard_Real V2) ; //! Returns the point in 3d space. - const gp_Pnt& Value() const; + const gp_Pnt& Value() const; + + //! Returns the point in 2d space of one of the surfaces. + Standard_EXPORT gp_Pnt2d ValueOnSurface (const Standard_Boolean OnFirst) const; //! Returns the parameters of the point on the first surface. void ParametersOnS1 (Standard_Real& U1, Standard_Real& V1) const; //! Returns the parameters of the point on the second surface. - void ParametersOnS2 (Standard_Real& U2, Standard_Real& V2) const; + void ParametersOnS2 (Standard_Real& U2, Standard_Real& V2) const; + + //! Returns the parameters of the point in the + //! parametric space of one of the surface. + Standard_EXPORT void ParametersOnSurface (const Standard_Boolean OnFirst, Standard_Real& U, Standard_Real& V) const; //! Returns the parameters of the point on both surfaces. - void Parameters (Standard_Real& U1, Standard_Real& V1, Standard_Real& U2, Standard_Real& V2) const; + void Parameters (Standard_Real& U1, Standard_Real& V1, Standard_Real& U2, Standard_Real& V2) const; //! Returns TRUE if 2D- and 3D-coordinates of theOterPoint are equal to //! corresponding coordinates of me (with given tolerance). //! If theTol2D < 0.0 we will compare 3D-points only. - Standard_EXPORT Standard_Boolean IsSame (const IntSurf_PntOn2S& theOterPoint, const Standard_Real theTol3D = 0.0, const Standard_Real theTol2D = -1.0) const; + Standard_EXPORT Standard_Boolean IsSame (const IntSurf_PntOn2S& theOtherPoint, const Standard_Real theTol3D = 0.0, const Standard_Real theTol2D = -1.0) const; diff --git a/src/IntWalk/IntWalk_IWalking_1.gxx b/src/IntWalk/IntWalk_IWalking_1.gxx index 5b3b7d8ce0..88ba783e8d 100644 --- a/src/IntWalk/IntWalk_IWalking_1.gxx +++ b/src/IntWalk/IntWalk_IWalking_1.gxx @@ -70,7 +70,8 @@ static Standard_Boolean IsTangentExtCheck(TheIWFunction& theFunc, IntWalk_IWalking::IntWalk_IWalking (const Standard_Real Epsilon, const Standard_Real Deflection, - const Standard_Real Increment ) : + const Standard_Real Increment, + const Standard_Boolean theToFillHoles) : done(Standard_False), fleche(Deflection), pas(Increment), @@ -78,7 +79,8 @@ IntWalk_IWalking::IntWalk_IWalking (const Standard_Real Epsilon, epsilon(Epsilon*Epsilon), wd1 (IntWalk_VectorOfWalkingData::allocator_type (new NCollection_IncAllocator)), wd2 (wd1.get_allocator()), - nbMultiplicities (wd1.get_allocator()) + nbMultiplicities (wd1.get_allocator()), + ToFillHoles(theToFillHoles) { } @@ -215,7 +217,35 @@ void IntWalk_IWalking::Perform(const ThePOPIterator& Pnts1, // calculation of all closed lines if (nbPnts2 != 0) - ComputeCloseLine(Umult,Vmult,Pnts1,Pnts2,Func,Rajout); + ComputeCloseLine(Umult,Vmult,Pnts1,Pnts2,Func,Rajout); + + if (ToFillHoles) + { + Standard_Integer MaxNbIter = 10, nb_iter = 0; + while (seqAlone.Length() > 1 && nb_iter < MaxNbIter) + { + nb_iter++; + IntSurf_SequenceOfInteriorPoint PntsInHoles; + TColStd_SequenceOfInteger CopySeqAlone = seqAlone; + FillPntsInHoles(Func, CopySeqAlone, PntsInHoles); + wd2.clear(); + IntWalk_WalkingData aDummy; + aDummy.etat = -10; + aDummy.ustart = aDummy.vstart = 0.; + wd2.push_back (aDummy); + Standard_Integer nbHoles = PntsInHoles.Length(); + wd2.reserve(nbHoles); + for (I = 1; I <= nbHoles; I++) + { + IntWalk_WalkingData aWD2; + aWD2.etat = 13; + const IntSurf_InteriorPoint& anIP = PntsInHoles.Value(I); + ThePointOfLoopTool::Value2d(anIP, aWD2.ustart, aWD2.vstart); + wd2.push_back (aWD2); + } + ComputeCloseLine(Umult,Vmult,Pnts1,PntsInHoles,Func,Rajout); + } + } for (I = 1; I <= nbPnts1; I++) { if (wd1[I].etat >0) seqSingle.Append(Pnts1(I)); diff --git a/src/IntWalk/IntWalk_IWalking_2.gxx b/src/IntWalk/IntWalk_IWalking_2.gxx index f54b7a498a..30f8bb3928 100644 --- a/src/IntWalk/IntWalk_IWalking_2.gxx +++ b/src/IntWalk/IntWalk_IWalking_2.gxx @@ -14,6 +14,8 @@ //-- IntWalk_IWalking_2.gxx +#include + #ifndef OCCT_DEBUG #define No_Standard_RangeError #define No_Standard_OutOfRange @@ -573,6 +575,158 @@ Standard_Boolean IntWalk_IWalking::TestArretAjout return Arrive; } +void IntWalk_IWalking::FillPntsInHoles(TheIWFunction& sp, + TColStd_SequenceOfInteger& CopySeqAlone, + IntSurf_SequenceOfInteriorPoint& PntsInHoles) +{ + math_Vector BornInf(1,2), BornSup(1,2); + BornInf(1) = Um; + BornSup(1) = UM; + BornInf(2) = Vm; + BornSup(2) = VM; + PointLineLine.Clear(); + TColStd_SequenceOfInteger SeqToRemove; + TColStd_MapOfInteger BadSolutions; + + for (Standard_Integer i = 1; i < CopySeqAlone.Length(); i++) + { + Standard_Integer Irang1 = CopySeqAlone(i); + if (Irang1 == 0) + continue; + Standard_Boolean ToRemove = Standard_False; + IntSurf_PntOn2S PointAlone1, PointAlone2; + const Handle(IntWalk_TheIWLine)& Line1 = lines.Value(Abs(Irang1)); + if (Irang1 > 0) + PointAlone1 = Line1->Value(Line1->NbPoints()); + else + PointAlone1 = Line1->Value(1); + gp_Pnt2d P2d1 = PointAlone1.ValueOnSurface(reversed), P2d2; + Standard_Real MinSqDist = RealLast(); + Standard_Integer MinRang = 0, MinIndex = 0; + for (Standard_Integer j = i+1; j <= CopySeqAlone.Length(); j++) + { + Standard_Integer Irang2 = CopySeqAlone(j); + if (Irang2 == 0 || + BadSolutions.Contains(Irang2)) + continue; + const Handle(IntWalk_TheIWLine)& Line2 = lines.Value(Abs(Irang2)); + if (Irang2 > 0) + PointAlone2 = Line2->Value(Line2->NbPoints()); + else + PointAlone2 = Line2->Value(1); + P2d2 = PointAlone2.ValueOnSurface(reversed); + Standard_Real aSqDist = P2d1.SquareDistance(P2d2); + if (aSqDist < MinSqDist) + { + MinSqDist = aSqDist; + MinRang = Irang2; + MinIndex = j; + } + } + //processing points from Irang1 and MinRang + if (MinRang == 0) + { + SeqToRemove.Append(Irang1); + BadSolutions.Clear(); + continue; + } + //Ends of same line + if (Abs(Irang1) == Abs(MinRang) && + lines.Value(Abs(Irang1))->NbPoints() == 2) + { + SeqToRemove.Append(Irang1); + SeqToRemove.Append(MinRang); + CopySeqAlone(i) = 0; + CopySeqAlone(MinIndex) = 0; + BadSolutions.Clear(); + continue; + } + /////////////////// + const Handle(IntWalk_TheIWLine)& Line2 = lines.Value(Abs(MinRang)); + if (MinRang > 0) + PointAlone2 = Line2->Value(Line2->NbPoints()); + else + PointAlone2 = Line2->Value(1); + gp_Pnt Pnt1 = PointAlone1.Value(); + gp_Pnt Pnt2 = PointAlone2.Value(); + P2d2 = PointAlone2.ValueOnSurface(reversed); + Standard_Real MinSqDist3d = Pnt1.SquareDistance(Pnt2); + if (MinSqDist3d <= epsilon || + (Abs(P2d1.X() - P2d2.X()) <= tolerance(1) && + Abs(P2d1.Y() - P2d2.Y()) <= tolerance(2))) //close points + ToRemove = Standard_True; + else //real curve + { + math_Vector UVap(1,2), UV(1,2); + UVap(1) = (P2d1.X() + P2d2.X())/2; + UVap(2) = (P2d1.Y() + P2d2.Y())/2; + math_FunctionSetRoot Rsnld(sp, tolerance); + Rsnld.Perform(sp, UVap, BornInf, BornSup); + if (Rsnld.IsDone() && + Abs(sp.Root()) <= sp.Tolerance() && + !sp.IsTangent()) + { + Rsnld.Root(UV); + gp_Pnt2d Pmid(UV(1),UV(2)); + gp_Vec2d P1P2(P2d1, P2d2); + gp_Vec2d P1Pmid(P2d1, Pmid); + gp_Vec2d P2Pmid(P2d2, Pmid); + Standard_Real ScalProd1 = P1P2 * P1Pmid; + Standard_Real ScalProd2 = P1P2 * P2Pmid; + Standard_Boolean IsPmidValid = (ScalProd1 > 0. && ScalProd2 < 0); //Pmid is in the middle + if (IsPmidValid) + { + for (Standard_Integer iline = 1; iline <= lines.Length(); iline++) + if (IsPointOnLine(Pmid,iline)) + { + IsPmidValid = Standard_False; + break; + } + } + if (IsPmidValid) + { + IntSurf_InteriorPoint aPoint(sp.Point(), UV(1), UV(2), + sp.Direction3d(), + sp.Direction2d()); + PntsInHoles.Append(aPoint); + TColStd_ListOfInteger LineLine; + LineLine.Append(Irang1); + LineLine.Append(MinRang); + PointLineLine.Bind(PntsInHoles.Length(), LineLine); + } + else + { + BadSolutions.Add(MinRang); + i--; + continue; + } + } + else + { + BadSolutions.Add(MinRang); + i--; + continue; + } + } + CopySeqAlone(i) = 0; + CopySeqAlone(MinIndex) = 0; + if (ToRemove) + { + SeqToRemove.Append(Irang1); + SeqToRemove.Append(MinRang); + } + BadSolutions.Clear(); + } + + for (Standard_Integer i = 1; i <= SeqToRemove.Length(); i++) + for (Standard_Integer j = 1; j <= seqAlone.Length(); j++) + if (seqAlone(j) == SeqToRemove(i)) + { + seqAlone.Remove(j); + break; + } +} + void IntWalk_IWalking::TestArretCadre (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, diff --git a/src/IntWalk/IntWalk_IWalking_3.gxx b/src/IntWalk/IntWalk_IWalking_3.gxx index 6bc7b7a133..203ee5f1f3 100644 --- a/src/IntWalk/IntWalk_IWalking_3.gxx +++ b/src/IntWalk/IntWalk_IWalking_3.gxx @@ -63,7 +63,7 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, // end of conditions. { - Standard_Integer I, N; + Standard_Integer I, N = 0, SaveN = 0; Standard_Real aBornInf[2], aBornSup[2], aUVap[2]; math_Vector BornInf(aBornInf,1,2), BornSup(aBornSup,1,2), UVap(aUVap,1,2); Standard_Real PasC, PasCu, PasCv; @@ -190,6 +190,7 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, CurrentLine->AddStatusLast(Standard_False); Tgtend = Standard_True; // check Rajout = Standard_True; + seqAlone.Append(lines.Length() + 1); seqAjout.Append(lines.Length() + 1); } } @@ -203,6 +204,7 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, else { if (Rajout) { ArretAjout =TestArretAjout(Func, UVap, N, Psol); + SaveN = N; if (ArretAjout) { // jag 940615 Tgtend = lines.Value(N)->IsTangentAtEnd(); @@ -253,9 +255,16 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, else if (ArretAjout || Cadre) { Arrive = Standard_True; CurrentLine->AddStatusLast(Standard_False); - if (Status != IntWalk_ArretSurPointPrecedent) { - CurrentLine->AddPoint(Psol); - } + //if (Status != IntWalk_ArretSurPointPrecedent) + CurrentLine->AddPoint(Psol); + //Remove from + for (Standard_Integer iseq = 1; iseq <= seqAlone.Length(); iseq++) + if (seqAlone(iseq) == SaveN) + { + seqAlone.Remove(iseq); + break; + } + if (Cadre && N==0) { Rajout = Standard_True; seqAjout.Append(lines.Length()+1); @@ -268,6 +277,8 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, } Arrive = Standard_True; Rajout = Standard_True; + //AddAlonePoint(); + seqAlone.Append(lines.Length() + 1); seqAjout.Append(lines.Length() + 1); CurrentLine->AddStatusLast(Standard_False); Tgtend = Standard_True; // check @@ -329,6 +340,7 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, MakeWalkingPoint(1, UVap(1), UVap(2), Func, Psol); CurrentLine->AddPoint(Psol); Rajout = Standard_True; + seqAlone.Append(lines.Length() + 1); seqAjout.Append(lines.Length() + 1); } else if (Status == IntWalk_OK) { @@ -353,6 +365,7 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, CurrentLine->AddStatusLast(Standard_False); Tgtend = Standard_True; // need check Rajout = Standard_True; + seqAlone.Append(lines.Length() + 1); seqAjout.Append(lines.Length() + 1); } } diff --git a/src/IntWalk/IntWalk_IWalking_4.gxx b/src/IntWalk/IntWalk_IWalking_4.gxx index 635ed1c674..4d704e4003 100644 --- a/src/IntWalk/IntWalk_IWalking_4.gxx +++ b/src/IntWalk/IntWalk_IWalking_4.gxx @@ -41,7 +41,7 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, // // ******************************************************************** { - Standard_Integer I,N = 0; + Standard_Integer I,N = 0,SaveN = 0; Standard_Real aBornInf[2], aBornSup[2], aUVap[2]; math_Vector BornInf(aBornInf,1,2), BornSup(aBornSup,1,2); math_Vector Uvap(aUVap,1,2);// parameters of current approach @@ -180,13 +180,40 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, PasCv = Abs(PasC*previousd2d.Y()); if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) { - if (CurrentLine->NbPoints()==1) break; + if (CurrentLine->NbPoints()==1) + { + RemoveTwoEndPoints(I); + break; //cancel the line + } + if (wd2[I].etat >12) { //the line should become open + wd2[I].etat = 12; //declare it open + ArretAjout = Standard_False; + OpenLine(0,Psol,Pnts1,Func,CurrentLine); + StepSign = -1; + StatusPrecedent = IntWalk_OK; + Arrive = Standard_False; + PasC = PasSav; + Rajout = Standard_True; + seqAlone.Append(-lines.Length()-1); + seqAjout.Append(-lines.Length()-1); + } + else { // line s is open + Arrive =Standard_True; + CurrentLine->AddStatusLast(Standard_False); + Rajout = Standard_True; + seqAlone.Append(lines.Length()+1); + seqAjout.Append(lines.Length()+1); + Tgtend = Standard_True; + } + /* Arrive = Standard_True; CurrentLine->AddStatusFirstLast(Standard_False, Standard_False,Standard_False); Rajout = Standard_True; + seqAlone.Append(lines.Length()+1); seqAjout.Append(lines.Length()+1); Tgtend = Standard_True; + */ } } else { // there is a solution @@ -246,6 +273,7 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, else { // modif jag 940615 if (Rajout) { // test on added points ArretAjout =TestArretAjout(Func,Uvap,N,Psol); + SaveN = N; if (ArretAjout) { if (N >0) { Tgtend = lines.Value(N)->IsTangentAtEnd(); @@ -259,8 +287,13 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, } if (!ArretAjout&& Cadre) { // test on already marked points - if (CurrentLine->NbPoints() == 1) break; // cancel the line + if (CurrentLine->NbPoints() == 1) + { + RemoveTwoEndPoints(I); + break; // cancel the line + } TestArretCadre(Umult,Vmult,CurrentLine,Func,Uvap,N); + SaveN = N; // if (N==0) { if (N <= 0) { // jag 941017 MakeWalkingPoint(2,Uvap(1),Uvap(2),Func,Psol); @@ -289,11 +322,42 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, if (Arrive) { // line s is open CurrentLine->AddStatusLast(Standard_False); - if (Status != IntWalk_ArretSurPointPrecedent) { - CurrentLine->AddPoint(Psol); + //if (Status != IntWalk_ArretSurPointPrecedent) + CurrentLine->AddPoint(Psol); + + //Remove from and, if it is first found point, + //from too + if (IsValidEndPoint(I, SaveN)) + { + for (Standard_Integer iseq = 1; iseq <= seqAlone.Length(); iseq++) + if (seqAlone(iseq) == SaveN) + { + seqAlone.Remove(iseq); + break; + } + if (CurrentLine->NbPoints() <= 3) + for (Standard_Integer iseq = 1; iseq <= seqAjout.Length(); iseq++) + if (seqAjout(iseq) == SaveN) + { + seqAjout.Remove(iseq); + break; + } } + else + { + if (seqAlone.Last() == -lines.Length()-1) + { + seqAlone.Remove(seqAlone.Length()); + seqAjout.Remove(seqAjout.Length()); + } + RemoveTwoEndPoints(I); + Arrive = Standard_False; + break; //cancel the line + } + if (Cadre && N==0) { Rajout = Standard_True; + //seqAlone.Append(lines.Length()+1); seqAjout.Append(lines.Length()+1); } @@ -307,11 +371,36 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, StatusPrecedent = IntWalk_OK; PasC = PasSav; if (Status == IntWalk_ArretSurPointPrecedent) { + CurrentLine->AddPoint(Psol); OpenLine(0,Psol,Pnts1,Func,CurrentLine); } else { OpenLine(-lines.Length()-1,Psol,Pnts1,Func,CurrentLine); } + //Remove from and, if it is first found point, + //from too + if (IsValidEndPoint(I, SaveN)) + { + for (Standard_Integer iseq = 1; iseq <= seqAlone.Length(); iseq++) + if (seqAlone(iseq) == SaveN) + { + seqAlone.Remove(iseq); + break; + } + if (CurrentLine->NbPoints() <= 2) + for (Standard_Integer iseq = 1; iseq <= seqAjout.Length(); iseq++) + if (seqAjout(iseq) == SaveN) + { + seqAjout.Remove(iseq); + break; + } + } + else + { + RemoveTwoEndPoints(I); + break; //cancel the line + } + if (Cadre && N==0) { Rajout = Standard_True; seqAjout.Append(-lines.Length()-1); @@ -321,6 +410,7 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, else if ( Status == IntWalk_ArretSurPointPrecedent) { if (CurrentLine->NbPoints() == 1) { //cancel the line Arrive = Standard_False; + RemoveTwoEndPoints(I); break; } if (wd2[I].etat >12) { //the line should become open @@ -332,12 +422,14 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, Arrive = Standard_False; PasC = PasSav; Rajout = Standard_True; + seqAlone.Append(-lines.Length()-1); seqAjout.Append(-lines.Length()-1); } else { // line s is open Arrive =Standard_True; CurrentLine->AddStatusLast(Standard_False); Rajout = Standard_True; + seqAlone.Append(lines.Length()+1); seqAjout.Append(lines.Length()+1); } } @@ -363,6 +455,7 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, OpenLine(N,Psol,Pnts1,Func,CurrentLine); StepSign = -1; Rajout = Standard_True; + seqAlone.Append(N); seqAjout.Append(N); StatusPrecedent = IntWalk_OK; Arrive = Standard_False; @@ -381,6 +474,7 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, newP.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2)); CurrentLine->AddPoint(newP); Rajout = Standard_True; + seqAlone.Append(lines.Length()+1); seqAjout.Append(lines.Length()+1); } } @@ -404,13 +498,40 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, PasCv = Abs(PasC*previousd2d.Y()); if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) { - if (CurrentLine->NbPoints() == 1) break; // cancel the line + if (CurrentLine->NbPoints() == 1) + { + RemoveTwoEndPoints(I); + break; // cancel the line + } + if (wd2[I].etat >12) { //the line should become open + wd2[I].etat = 12; //declare it open + ArretAjout = Standard_False; + OpenLine(0,Psol,Pnts1,Func,CurrentLine); + StepSign = -1; + StatusPrecedent = IntWalk_OK; + Arrive = Standard_False; + PasC = PasSav; + Rajout = Standard_True; + seqAlone.Append(-lines.Length()-1); + seqAjout.Append(-lines.Length()-1); + } + else { // line s is open + Arrive =Standard_True; + CurrentLine->AddStatusLast(Standard_False); + Tgtend = Standard_True; + Rajout = Standard_True; + seqAlone.Append(lines.Length()+1); + seqAjout.Append(lines.Length()+1); + } + /* Arrive = Standard_True; CurrentLine->AddStatusFirstLast(Standard_False,Standard_False, Standard_False); Tgtend = Standard_True; Rajout = Standard_True; + seqAlone.Append(lines.Length()+1); seqAjout.Append(lines.Length()+1); + */ } } diff --git a/src/IntWalk/IntWalk_IWalking_6.gxx b/src/IntWalk/IntWalk_IWalking_6.gxx index 5bf7f34958..d9eda77990 100644 --- a/src/IntWalk/IntWalk_IWalking_6.gxx +++ b/src/IntWalk/IntWalk_IWalking_6.gxx @@ -115,10 +115,55 @@ void IntWalk_IWalking::OpenLine(const Standard_Integer N, Line->SetTangentVector(previousd3d.Reversed(),Line->NbPoints()); } +Standard_Boolean IntWalk_IWalking::IsValidEndPoint(const Standard_Integer IndOfPoint, + const Standard_Integer IndOfLine) +{ + if (PointLineLine.IsEmpty()) + return Standard_True; + + TColStd_ListIteratorOfListOfInteger itl(PointLineLine(IndOfPoint)); + for (; itl.More(); itl.Next()) + if (itl.Value() == IndOfLine) + { + PointLineLine(IndOfPoint).Remove(itl); + return Standard_True; + } + return Standard_False; +} +void IntWalk_IWalking::RemoveTwoEndPoints(const Standard_Integer IndOfPoint) +{ + if (PointLineLine.IsBound(IndOfPoint)) + { + Standard_Integer Line1 = PointLineLine(IndOfPoint).First(); + Standard_Integer Line2 = PointLineLine(IndOfPoint).Last(); + for (Standard_Integer iseq = 1; iseq <= seqAlone.Length(); iseq++) + { + if (seqAlone(iseq) == Line1 || + seqAlone(iseq) == Line2) + seqAlone.Remove(iseq--); + } + } +} - - - - - +Standard_Boolean IntWalk_IWalking::IsPointOnLine(const gp_Pnt2d& theP2d, + const Standard_Integer Irang) +{ + const Handle(IntWalk_TheIWLine)& aLine = lines.Value(Abs(Irang)); + for (Standard_Integer i = 1; i <= aLine->NbPoints(); i++) + { + gp_Pnt2d P2d1 = aLine->Value(i).ValueOnSurface(reversed); + if (Abs(P2d1.X() - theP2d.X()) <= tolerance(1) && + Abs(P2d1.Y() - theP2d.Y()) <= tolerance(2)) + return Standard_True; + if (i < aLine->NbPoints()) + { + gp_Pnt2d P2d2 = aLine->Value(i+1).ValueOnSurface(reversed); + gp_Vec2d PP1(theP2d, P2d1); + gp_Vec2d PP2(theP2d, P2d2); + if (PP1 * PP2 < 0) + return Standard_True; + } + } + return Standard_False; +} diff --git a/tests/bugs/modalg_6/bug27341_303 b/tests/bugs/modalg_6/bug27341_303 index 0d5fe66e3b..b67fd6482c 100644 --- a/tests/bugs/modalg_6/bug27341_303 +++ b/tests/bugs/modalg_6/bug27341_303 @@ -23,6 +23,6 @@ build3d result fit checkprops result -l 3249.9 -checknbshapes result -vertex 634 -edge 317 +checknbshapes result -vertex 636 -edge 318 checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/modalg_6/bug27720_1 b/tests/bugs/modalg_6/bug27720_1 new file mode 100644 index 0000000000..20febdf229 --- /dev/null +++ b/tests/bugs/modalg_6/bug27720_1 @@ -0,0 +1,26 @@ +puts "============" +puts "OCC27720" +puts "============" +puts "" +###################################################### +# HLRBrep_Algo BSpline missing edges +###################################################### + +pload QAcommands + +restore [locate_data_file bug27720_BSpline.brep] a + +set viewname "axo" + +top +clear + +OCC27341 result a ${viewname} +build3d result + +fit + +checkprops result -l 0.883462 +checknbshapes result -vertex 86 -edge 43 + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/modalg_6/bug27720_2 b/tests/bugs/modalg_6/bug27720_2 index f9b7190fca..9191cb67d8 100644 --- a/tests/bugs/modalg_6/bug27720_2 +++ b/tests/bugs/modalg_6/bug27720_2 @@ -20,7 +20,7 @@ build3d result fit -checkprops result -l 0.980942 -checknbshapes result -vertex 54 -edge 27 +checkprops result -l 0.980943 +checknbshapes result -vertex 58 -edge 29 checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/modalg_6/bug27720_4 b/tests/bugs/modalg_6/bug27720_4 new file mode 100644 index 0000000000..4c63aae3cf --- /dev/null +++ b/tests/bugs/modalg_6/bug27720_4 @@ -0,0 +1,26 @@ +puts "============" +puts "OCC27720" +puts "============" +puts "" +###################################################### +# HLRBrep_Algo BSpline missing edges +###################################################### + +pload QAcommands + +restore [locate_data_file bug27720_BSpline.brep] a + +set viewname "left" + +top +clear + +OCC27341 result a ${viewname} +build3d result + +fit + +checkprops result -l 0.820309 +checknbshapes result -vertex 74 -edge 37 + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/modalg_6/bug27720_5 b/tests/bugs/modalg_6/bug27720_5 new file mode 100644 index 0000000000..167ba2a564 --- /dev/null +++ b/tests/bugs/modalg_6/bug27720_5 @@ -0,0 +1,26 @@ +puts "============" +puts "OCC27720" +puts "============" +puts "" +###################################################### +# HLRBrep_Algo BSpline missing edges +###################################################### + +pload QAcommands + +restore [locate_data_file bug27720_BSpline.brep] a + +set viewname "right" + +top +clear + +OCC27341 result a ${viewname} +build3d result + +fit + +checkprops result -l 0.841499 +checknbshapes result -vertex 92 -edge 46 + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png