0027720: HLRBrep_Algo BSpline missing edges
authorjgv <jgv@opencascade.com>
Thu, 8 Sep 2016 15:20:57 +0000 (18:20 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 23 Sep 2016 06:57:50 +0000 (09:57 +0300)
    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

16 files changed:
src/Contap/Contap_Contour.cxx
src/Contap/Contap_TheIWalking.hxx
src/HLRTest/HLRTest.cxx
src/IntPatch/IntPatch_TheIWalking.hxx
src/IntSurf/IntSurf_PntOn2S.cxx
src/IntSurf/IntSurf_PntOn2S.hxx
src/IntWalk/IntWalk_IWalking_1.gxx
src/IntWalk/IntWalk_IWalking_2.gxx
src/IntWalk/IntWalk_IWalking_3.gxx
src/IntWalk/IntWalk_IWalking_4.gxx
src/IntWalk/IntWalk_IWalking_6.gxx
tests/bugs/modalg_6/bug27341_303
tests/bugs/modalg_6/bug27720_1 [new file with mode: 0644]
tests/bugs/modalg_6/bug27720_2
tests/bugs/modalg_6/bug27720_4 [new file with mode: 0644]
tests/bugs/modalg_6/bug27720_5 [new file with mode: 0644]

index 34c457d..d5e7aa5 100644 (file)
@@ -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;
index 1a4d886..d61312b 100644 (file)
@@ -31,6 +31,7 @@
 #include <gp_Vec.hxx>
 #include <gp_Dir2d.hxx>
 #include <TColStd_SequenceOfInteger.hxx>
+#include <TColStd_DataMapOfIntegerListOfInteger.hxx>
 #include <Contap_SequenceOfIWLineOfTheIWalking.hxx>
 #include <IntSurf_SequenceOfInteriorPoint.hxx>
 #include <Standard_Integer.hxx>
@@ -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;
 
 
 };
index 2af070d..6379df6 100644 (file)
@@ -502,6 +502,61 @@ static Standard_Integer hlrin3d(Draw_Interpretor& , Standard_Integer n, const ch
 }
 
 //=======================================================================
+//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();
 }
 
index ff296da..98f16f1 100644 (file)
@@ -31,6 +31,7 @@
 #include <gp_Vec.hxx>
 #include <gp_Dir2d.hxx>
 #include <TColStd_SequenceOfInteger.hxx>
+#include <TColStd_DataMapOfIntegerListOfInteger.hxx>
 #include <IntPatch_SequenceOfIWLineOfTheIWalking.hxx>
 #include <IntSurf_SequenceOfInteriorPoint.hxx>
 #include <Standard_Integer.hxx>
@@ -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;
 
 
 };
index 4397630..df167df 100644 (file)
@@ -16,7 +16,9 @@
 #include <gp_Pnt.hxx>
 #include <IntSurf_PntOn2S.hxx>
 
-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,
index a6cc213..773bd9d 100644 (file)
@@ -25,6 +25,7 @@
 #include <Standard_Real.hxx>
 #include <Standard_Boolean.hxx>
 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;
 
 
 
index 5b3b7d8..88ba783 100644 (file)
@@ -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));
index f54b7a4..30f8bb3 100644 (file)
@@ -14,6 +14,8 @@
 
 //-- IntWalk_IWalking_2.gxx
 
+#include <TColStd_MapOfInteger.hxx>
+
 #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,
index 6bc7b7a..203ee5f 100644 (file)
@@ -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 <SaveN> from <seqAlone>
+              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);
           }  
         }
index 635ed1c..4d704e4 100644 (file)
@@ -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 <SaveN> from <seqAlone> and, if it is first found point,
+                //from <seqAjout> 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 <SaveN> from <seqAlone> and, if it is first found point,
+                //from <seqAjout> 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);
+            */
           }  
         }
 
index 5bf7f34..d9eda77 100644 (file)
@@ -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;
+}
index 0d5fe66..b67fd64 100644 (file)
@@ -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 (file)
index 0000000..20febdf
--- /dev/null
@@ -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
index f9b7190..9191cb6 100644 (file)
@@ -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 (file)
index 0000000..4c63aae
--- /dev/null
@@ -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 (file)
index 0000000..167ba2a
--- /dev/null
@@ -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