]> OCCT Git - occt-copy.git/commitdiff
0026426: Draft angle algorithm modifies input argument + the result of the operation...
authorifv <ifv@opencascade.com>
Fri, 17 Jul 2015 06:43:21 +0000 (09:43 +0300)
committermsv <msv@opencascade.com>
Thu, 17 Sep 2015 15:34:34 +0000 (18:34 +0300)
This is not yet final version of the fix.

16 files changed:
src/BRepOffsetAPI/BRepOffsetAPI_DraftAngle.cdl
src/BRepOffsetAPI/BRepOffsetAPI_DraftAngle.cxx
src/Draft/Draft_Modification.cxx
src/Draft/Draft_Modification_1.cxx
src/Geom/Geom_BSplineCurve.cdl
src/Geom/Geom_BSplineCurve_1.cxx
src/Geom2d/Geom2d_BSplineCurve.cdl
src/Geom2d/Geom2d_BSplineCurve_1.cxx
src/GeomLib/FILES
src/GeomLib/GeomLib_CheckCurveOnSurface.cxx [new file with mode: 0644]
src/GeomLib/GeomLib_CheckCurveOnSurface.hxx [new file with mode: 0644]
tests/draft/angle/G2
tests/draft/angle/K5
tests/draft/angle/K7
tests/draft/angle/M2
tests/draft/angle/M4

index fb8ea45146f5f9496d4a9bad6444ed7f5db97444..d15e837305562c97c62ca995b5e8134862216f47 100644 (file)
@@ -46,6 +46,7 @@ uses
     Face              from TopoDS,
     ShapeModification from BRepBuilderAPI,
     ListOfShape       from TopTools,
+    DataMapOfShapeShape from TopTools,
     Dir               from gp,
     Pln               from gp,
     ErrorStatus       from Draft
@@ -261,9 +262,18 @@ is
     returns ListOfShape from TopTools
     is redefined virtual;
 
+    ModifiedShape (me; S : Shape from TopoDS)
+    ---Purpose: Returns the modified shape corresponding to <S>.
+    -- S can correspond to the entire initial shape or to its subshape.
+    -- Raises exceptions Standard_NoSuchObject if S is not the initial shape or
+    -- a subshape of the initial shape to which the transformation has been applied. 
+    returns Shape from TopoDS is redefined virtual;
+
+    CorrectVertexTol(me: in out) is private;
+
 fields 
 
-    myModifiedShapes : ListOfShape from TopTools;
+    myVtxToReplace : DataMapOfShapeShape from TopTools;
 
 end DraftAngle;
 
index 98bd5c8f5c0b0e9e94326e692fb7239083d65815..b4189bb76920eef788e323a4542f865af63e7b16 100644 (file)
@@ -107,12 +107,12 @@ void BRepOffsetAPI_DraftAngle::Init (const TopoDS_Shape& S)
 //=======================================================================
 
 void BRepOffsetAPI_DraftAngle::Add(const TopoDS_Face& F,
-                            const gp_Dir& D,
-                            const Standard_Real Angle,
-                            const gp_Pln& Plane,
-                             const Standard_Boolean Flag)
+  const gp_Dir& D,
+  const Standard_Real Angle,
+  const gp_Pln& Plane,
+  const Standard_Boolean Flag)
 {
-// POP-DPF : protection
+  // POP-DPF : protection
   if ( Abs(Angle) <= 1.e-04 ) 
     return;
   Standard_NullObject_Raise_if(myInitialShape.IsNull(),"");
@@ -175,7 +175,7 @@ Draft_ErrorStatus BRepOffsetAPI_DraftAngle::Status () const
 //=======================================================================
 
 const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::ConnectedFaces
-   (const TopoDS_Face& F) const
+  (const TopoDS_Face& F) const
 {
   Standard_NullObject_Raise_if(myInitialShape.IsNull(),"");
   return (*((Handle(Draft_Modification)*)&myModification))->ConnectedFaces(F);
@@ -211,7 +211,7 @@ const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::Generated(const TopoDS_Sha
     Standard_Boolean     RW,RF;
     if (DMod->NewSurface(TopoDS::Face(S), Surf, L, Tol, RW, RF)) {
       myGenerated.Append(ModifiedShape (S));
+
     }
   }
   return myGenerated;
@@ -233,18 +233,35 @@ const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::Modified(const TopoDS_Shap
     TopLoc_Location      L;
     Standard_Real        Tol;
     Standard_Boolean     RW,RF;
-    
+
     if (!DMod->NewSurface(TopoDS::Face(S), Surf, L, Tol, RW, RF)) {
       // Ce n est pas une generation => peut etre une  modif
       myGenerated.Append(ModifiedShape (S));
       if (myGenerated.Extent() == 1 && myGenerated.First().IsSame(S)) {
-       myGenerated.Clear();
+        myGenerated.Clear();
       }
     }
   }
   return myGenerated;
 }
 
+//=======================================================================
+//function : ModifiedShape
+//purpose  : 
+//=======================================================================
+
+TopoDS_Shape BRepOffsetAPI_DraftAngle::ModifiedShape
+  (const TopoDS_Shape& S) const
+{
+  if(S.ShapeType() == TopAbs_VERTEX)
+  {
+    if(myVtxToReplace.IsBound(S))
+    {
+      return myVtxToReplace(S);
+    }
+  }
+  return myModifier.ModifiedShape(S);
+}
 
 //=======================================================================
 //function : Build
@@ -259,9 +276,8 @@ void BRepOffsetAPI_DraftAngle::Build()
   }
   else {
     DoModif(myInitialShape);
-    //BRepLib::SameParameter( myShape, 1.0e-7, Standard_True ); //patch
     CorrectWires();
-    BRepLib::SameParameter( myShape, 1.0e-7, Standard_True ); //patch
+    CorrectVertexTol();
   }
 }
 
@@ -283,29 +299,29 @@ void BRepOffsetAPI_DraftAngle::CorrectWires()
 
   TopExp_Explorer fexp( myShape, TopAbs_FACE );
   for (; fexp.More(); fexp.Next())
+  {
+    CurFace = fexp.Current();
+    wit.Initialize( CurFace );
+    for (; wit.More(); wit.Next())
     {
-      CurFace = fexp.Current();
-      wit.Initialize( CurFace );
-      for (; wit.More(); wit.Next())
-       {
-         CurWire = wit.Value();
-         TopTools_MapOfShape emap;
-         eit.Initialize( CurWire );
-         for (; eit.More(); eit.Next())
-           emap.Add( eit.Value() );
-         TopTools_MapIteratorOfMapOfShape mapit( emap );
-         for (; mapit.More(); mapit.Next())
-           {
-             CurEdge = mapit.Key();
-             if (BRepTools::IsReallyClosed( TopoDS::Edge(CurEdge), TopoDS::Face(CurFace) ))
-               {
-                 Eseq.Append( CurEdge );
-                 Wseq.Append( CurWire );
-                 Fseq.Append( CurFace );
-               }
-           }
-       }
+      CurWire = wit.Value();
+      TopTools_MapOfShape emap;
+      eit.Initialize( CurWire );
+      for (; eit.More(); eit.Next())
+        emap.Add( eit.Value() );
+      TopTools_MapIteratorOfMapOfShape mapit( emap );
+      for (; mapit.More(); mapit.Next())
+      {
+        CurEdge = mapit.Key();
+        if (BRepTools::IsReallyClosed( TopoDS::Edge(CurEdge), TopoDS::Face(CurFace) ))
+        {
+          Eseq.Append( CurEdge );
+          Wseq.Append( CurWire );
+          Fseq.Append( CurFace );
+        }
+      }
     }
+  }
 
   BRepFill_DataMapOfShapeSequenceOfReal Emap;
 
@@ -318,551 +334,639 @@ void BRepOffsetAPI_DraftAngle::CorrectWires()
   TopTools_DataMapOfShapeShape WFmap;
   TopTools_DataMapOfShapeListOfShape WWmap;
   for (i = 1; i <= Eseq.Length(); i++)
+  {
+    CurEdge = Eseq(i);
+    CurWire = Wseq(i);
+    CurFace = Fseq(i);
+    wit.Initialize( CurFace );
+    for (; wit.More(); wit.Next())
     {
-      CurEdge = Eseq(i);
-      CurWire = Wseq(i);
-      CurFace = Fseq(i);
-      wit.Initialize( CurFace );
-      for (; wit.More(); wit.Next())
-       {
-         TopoDS_Shape aWire = wit.Value();
-         if (! aWire.IsSame( CurWire ))
-           {
-             TColgp_SequenceOfPnt pts;
-             TopTools_SequenceOfShape edges;
-             TColStd_SequenceOfReal pars;
-             Standard_Boolean Wadd = Standard_False;
-             eit.Initialize( aWire );
-             for (; eit.More(); eit.Next())
-               {
-                 TopoDS_Shape anEdge = eit.Value();
-                 TopOpeBRep_EdgesIntersector EInter;
-                 EInter.SetFaces( CurFace, CurFace );
-                 EInter.ForceTolerances( TolInter, TolInter );
-                 EInter.Perform( CurEdge, anEdge );
-                 if (EInter.IsEmpty())
-                   {
-                     EInter.Perform( CurEdge.Reversed(), anEdge );
-                     if (EInter.IsEmpty())
-                       continue;
-                   }
-                 Wadd = Standard_True;
-                 if (! WFmap.IsBound( aWire ))
-                   WFmap.Bind( aWire, CurFace );
-                 Standard_Integer ind = 0;
-                 for (j = 1; j <= NonSeam.Length(); j++)
-                   if (anEdge.IsSame( NonSeam(j) ))
-                     {
-                       ind = j;
-                       break;
-                     }
-                 if (ind == 0)
-                   {
-                     NonSeam.Append( anEdge );
-                     NonSeamWires.Append( aWire );
-                     ind = NonSeam.Length();
-                     TColStd_SequenceOfReal emptyseq1, emptyseq2;
-                     TopTools_SequenceOfShape emptyedgeseq;
-                     ParsNonSeam.Append( emptyseq1 );
-                     Seam.Append( emptyedgeseq );
-                     ParsSeam.Append( emptyseq2 );
-                   }
-                 if (! Emap.IsBound( CurEdge ))
-                   {
-                     TColStd_SequenceOfReal emptyseq;
-                     Emap.Bind( CurEdge, emptyseq );
-                   }
-                 EInter.InitPoint();
-                 for (; EInter.MorePoint(); EInter.NextPoint())
-                   {
-                     const TopOpeBRep_Point2d& bp = EInter.Point();
-                     if (bp.IsVertex(2))
-                       {
-                         gp_Pnt Pnt = bp.Value();
-                         Standard_Integer ied = 0;
-                         for (j = 1; j <= pts.Length(); j++)
-                           if (Pnt.IsEqual( pts(j), Precision::Confusion() ))
-                             {
-                               ied = j;
-                               break;
-                             }
-                         if (ied == 0)
-                           {
-                             pts.Append( Pnt );
-                             edges.Append( anEdge );
-                             pars.Append( bp.Parameter(2) );
-                             Emap(CurEdge).Append( bp.Parameter(1) );
-                             ParsNonSeam(ind).Append( bp.Parameter(2) );
-                             Seam(ind).Append( CurEdge );
-                             ParsSeam(ind).Append( bp.Parameter(1) );
-                           }
-                         /*
-                         else
-                           {
-                             Standard_Real ParOnSeam = bp.Parameter(1);
-                             Standard_Real Par1 = pars(ied);
-                             Standard_Real Par2 = bp.Parameter(2);
-                             BRepAdaptor_Curve2d SeamCurve( CurEdge, CurFace );
-                             BRepAdaptor_Curve2d Curve1( edges(ied), CurFace );
-                             BRepAdaptor_Curve2d Curve2( anEdge. CurFace );
-                             gp_Pnt2d P2d;
-                             gp_Vec2d SeamDer, Der1, Der2;
-                             //SeamCurve->D1( ParOnSeam, P2d, SeamDer );
-                             //Curve1->D1( Par1, P2d, Der1 );
-                             //Curve2->D1( Par2, P2d, Der2 );
-                             Standard_Real Crossed1 = SeamDer ^ Der1;
-                             Standard_Real Crossed2 = SeamDer ^ Der2;
-                             //if (Crossed1 > 0
-                           }
-                         */
-                       }
-                     else // ! bp.IsVertex(2)
-                       {
-                         //Temporary the case of tangency is not implemented
-                         Emap(CurEdge).Append( bp.Parameter(1) );
-                         ParsNonSeam(ind).Append( bp.Parameter(2) );
-                         Seam(ind).Append( CurEdge );
-                         ParsSeam(ind).Append( bp.Parameter(1) );
-                       }
-                   } //for (; EInter.MorePoint(); EInter.NextPoint())
-               } //for (; eit.More(); eit.Next())
-             if (Wadd)
-               {
-                 if (! WWmap.IsBound( CurWire ))
-                   {
-                     TopTools_ListOfShape emptylist;
-                     WWmap.Bind( CurWire, emptylist );
-                   }
-                 WWmap(CurWire).Append( aWire );
-               }
-           } //if (! aWire.IsSame( CurWire ))
-       } //for (; wit.More(); wit.Next())
-    } //for (i = 1; i <= Eseq.Length(); i++)
+      TopoDS_Shape aWire = wit.Value();
+      if (! aWire.IsSame( CurWire ))
+      {
+        TColgp_SequenceOfPnt pts;
+        TopTools_SequenceOfShape edges;
+        TColStd_SequenceOfReal pars;
+        Standard_Boolean Wadd = Standard_False;
+        eit.Initialize( aWire );
+        for (; eit.More(); eit.Next())
+        {
+          TopoDS_Shape anEdge = eit.Value();
+          TopOpeBRep_EdgesIntersector EInter;
+          EInter.SetFaces( CurFace, CurFace );
+          EInter.ForceTolerances( TolInter, TolInter );
+          EInter.Perform( CurEdge, anEdge );
+          if (EInter.IsEmpty())
+          {
+            EInter.Perform( CurEdge.Reversed(), anEdge );
+            if (EInter.IsEmpty())
+              continue;
+          }
+          Wadd = Standard_True;
+          if (! WFmap.IsBound( aWire ))
+            WFmap.Bind( aWire, CurFace );
+          Standard_Integer ind = 0;
+          for (j = 1; j <= NonSeam.Length(); j++)
+            if (anEdge.IsSame( NonSeam(j) ))
+            {
+              ind = j;
+              break;
+            }
+            if (ind == 0)
+            {
+              NonSeam.Append( anEdge );
+              NonSeamWires.Append( aWire );
+              ind = NonSeam.Length();
+              TColStd_SequenceOfReal emptyseq1, emptyseq2;
+              TopTools_SequenceOfShape emptyedgeseq;
+              ParsNonSeam.Append( emptyseq1 );
+              Seam.Append( emptyedgeseq );
+              ParsSeam.Append( emptyseq2 );
+            }
+            if (! Emap.IsBound( CurEdge ))
+            {
+              TColStd_SequenceOfReal emptyseq;
+              Emap.Bind( CurEdge, emptyseq );
+            }
+            EInter.InitPoint();
+            for (; EInter.MorePoint(); EInter.NextPoint())
+            {
+              const TopOpeBRep_Point2d& bp = EInter.Point();
+              if (bp.IsVertex(2))
+              {
+                gp_Pnt Pnt = bp.Value();
+                Standard_Integer ied = 0;
+                for (j = 1; j <= pts.Length(); j++)
+                  if (Pnt.IsEqual( pts(j), Precision::Confusion() ))
+                  {
+                    ied = j;
+                    break;
+                  }
+                  if (ied == 0)
+                  {
+                    pts.Append( Pnt );
+                    edges.Append( anEdge );
+                    pars.Append( bp.Parameter(2) );
+                    Emap(CurEdge).Append( bp.Parameter(1) );
+                    ParsNonSeam(ind).Append( bp.Parameter(2) );
+                    Seam(ind).Append( CurEdge );
+                    ParsSeam(ind).Append( bp.Parameter(1) );
+                  }
+                  /*
+                  else
+                  {
+                  Standard_Real ParOnSeam = bp.Parameter(1);
+                  Standard_Real Par1 = pars(ied);
+                  Standard_Real Par2 = bp.Parameter(2);
+                  BRepAdaptor_Curve2d SeamCurve( CurEdge, CurFace );
+                  BRepAdaptor_Curve2d Curve1( edges(ied), CurFace );
+                  BRepAdaptor_Curve2d Curve2( anEdge. CurFace );
+                  gp_Pnt2d P2d;
+                  gp_Vec2d SeamDer, Der1, Der2;
+                  //SeamCurve->D1( ParOnSeam, P2d, SeamDer );
+                  //Curve1->D1( Par1, P2d, Der1 );
+                  //Curve2->D1( Par2, P2d, Der2 );
+                  Standard_Real Crossed1 = SeamDer ^ Der1;
+                  Standard_Real Crossed2 = SeamDer ^ Der2;
+                  //if (Crossed1 > 0
+                  }
+                  */
+              }
+              else // ! bp.IsVertex(2)
+              {
+                //Temporary the case of tangency is not implemented
+                Emap(CurEdge).Append( bp.Parameter(1) );
+                ParsNonSeam(ind).Append( bp.Parameter(2) );
+                Seam(ind).Append( CurEdge );
+                ParsSeam(ind).Append( bp.Parameter(1) );
+              }
+            } //for (; EInter.MorePoint(); EInter.NextPoint())
+        } //for (; eit.More(); eit.Next())
+        if (Wadd)
+        {
+          if (! WWmap.IsBound( CurWire ))
+          {
+            TopTools_ListOfShape emptylist;
+            WWmap.Bind( CurWire, emptylist );
+          }
+          WWmap(CurWire).Append( aWire );
+        }
+      } //if (! aWire.IsSame( CurWire ))
+    } //for (; wit.More(); wit.Next())
+  } //for (i = 1; i <= Eseq.Length(); i++)
 
   //Sorting
   for (i = 1; i <= NonSeam.Length(); i++)
     for (j = 1; j < ParsNonSeam(i).Length(); j++)
       for (k = j+1; k <= ParsNonSeam(i).Length(); k++)
-       if (ParsNonSeam(i)(k) < ParsNonSeam(i)(j))
-         {
-           Standard_Real temp = ParsNonSeam(i)(j);
-           ParsNonSeam(i)(j) = ParsNonSeam(i)(k);
-           ParsNonSeam(i)(k) = temp;
-           TopoDS_Shape tmp = Seam(i)(j);
-           Seam(i)(j) = Seam(i)(k);
-           Seam(i)(k) = tmp;
-           temp = ParsSeam(i)(j);
-           ParsSeam(i)(j) = ParsSeam(i)(k);
-           ParsSeam(i)(k) = temp;
-         }
-  BRepFill_DataMapIteratorOfDataMapOfShapeSequenceOfReal iter( Emap );
-  for (; iter.More(); iter.Next())
-    {
-      TColStd_SequenceOfReal Seq;
-      Seq = iter.Value();
-      for (i = 1; i < Seq.Length(); i++)
-      for (j = i+1; j <= Seq.Length(); j++)
-       if (Seq(j) < Seq(i))
-         {
-           Standard_Real temp = Seq(i);
-           Seq(i) = Seq(j);
-           Seq(j) = temp;
-         }
-      Emap( iter.Key() ) = Seq;
-    }
-  BRepFill_DataMapOfShapeSequenceOfReal EPmap;
-  TopTools_DataMapOfShapeSequenceOfShape EVmap; //Seam
-  TopTools_DataMapOfShapeSequenceOfShape EWmap; //Seam and wires intersecting it
-  iter.Initialize( Emap );
-  for (; iter.More(); iter.Next())
-    {
-      TColStd_SequenceOfReal parseq;
-      EPmap.Bind( iter.Key(), parseq );
-      TopTools_SequenceOfShape shapeseq;
-      EVmap.Bind( iter.Key(), shapeseq );
-      TopTools_SequenceOfShape shapeseq2;
-      EWmap.Bind( iter.Key(), shapeseq2 );
-    }
+        if (ParsNonSeam(i)(k) < ParsNonSeam(i)(j))
+        {
+          Standard_Real temp = ParsNonSeam(i)(j);
+          ParsNonSeam(i)(j) = ParsNonSeam(i)(k);
+          ParsNonSeam(i)(k) = temp;
+          TopoDS_Shape tmp = Seam(i)(j);
+          Seam(i)(j) = Seam(i)(k);
+          Seam(i)(k) = tmp;
+          temp = ParsSeam(i)(j);
+          ParsSeam(i)(j) = ParsSeam(i)(k);
+          ParsSeam(i)(k) = temp;
+        }
+        BRepFill_DataMapIteratorOfDataMapOfShapeSequenceOfReal iter( Emap );
+        for (; iter.More(); iter.Next())
+        {
+          TColStd_SequenceOfReal Seq;
+          Seq = iter.Value();
+          for (i = 1; i < Seq.Length(); i++)
+            for (j = i+1; j <= Seq.Length(); j++)
+              if (Seq(j) < Seq(i))
+              {
+                Standard_Real temp = Seq(i);
+                Seq(i) = Seq(j);
+                Seq(j) = temp;
+              }
+              Emap( iter.Key() ) = Seq;
+        }
+        BRepFill_DataMapOfShapeSequenceOfReal EPmap;
+        TopTools_DataMapOfShapeSequenceOfShape EVmap; //Seam
+        TopTools_DataMapOfShapeSequenceOfShape EWmap; //Seam and wires intersecting it
+        iter.Initialize( Emap );
+        for (; iter.More(); iter.Next())
+        {
+          TColStd_SequenceOfReal parseq;
+          EPmap.Bind( iter.Key(), parseq );
+          TopTools_SequenceOfShape shapeseq;
+          EVmap.Bind( iter.Key(), shapeseq );
+          TopTools_SequenceOfShape shapeseq2;
+          EWmap.Bind( iter.Key(), shapeseq2 );
+        }
+
+        //Reconstruction of non-seam edges
+        BRepTools_Substitution aSub;
+        BRep_Builder BB;
+        for (i = 1; i <= NonSeam.Length(); i++)
+        {
+          TopoDS_Edge anEdge = TopoDS::Edge( NonSeam(i) );
+          TopTools_ListOfShape NewEdges;
+          TopoDS_Edge NewE;
+          TopoDS_Vertex Vfirst, Vlast;
+          TopExp::Vertices( anEdge, Vfirst, Vlast );
+          Standard_Real par, FirstPar, LastPar;
+          BRep_Tool::Range( anEdge, FirstPar, LastPar );
+          Standard_Integer firstind = 1;
+          par = ParsNonSeam(i)(1);
+          TopoDS_Edge SeamEdge = TopoDS::Edge( Seam(i)(1) );
+          //Find the face
+          for (j = 1; j <= Eseq.Length(); j++)
+            if (SeamEdge.IsSame( Eseq(j) ))
+              break;
+          TopoDS_Face theFace = TopoDS::Face( Fseq(j) );
+          TopLoc_Location L;
+          Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( theFace, L );
+          if (Abs(par-FirstPar) <= Precision::Confusion())
+          {
+            BB.UpdateVertex( Vfirst, ParsSeam(i)(1), SeamEdge, BRep_Tool::Tolerance(Vfirst) );
+            EPmap( SeamEdge ).Append( ParsSeam(i)(1) );
+            EVmap( SeamEdge ).Append( Vfirst );
+            EWmap( SeamEdge ).Append( NonSeamWires(i) );
+            firstind = 2;
+          }
+          Standard_Real prevpar = FirstPar;
+          TopoDS_Vertex PrevV = Vfirst;
+          for (j = firstind; j <= ParsNonSeam(i).Length(); j++)
+          {
+            TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
+            NewE = TopoDS::Edge( aLocalShape );
+            //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
+            TopoDS_Vertex NewV;
+            par = ParsNonSeam(i)(j);
+            BB.Range( NewE, prevpar, par );
+            SeamEdge = TopoDS::Edge( Seam(i)(j) );
+            if (j == ParsNonSeam(i).Length() && Abs(par-LastPar) <= Precision::Confusion())
+            {
+              NewV = Vlast;
+              if (firstind == 2 && j == 2)
+              {
+                BB.UpdateVertex( Vlast, ParsSeam(i)(j), SeamEdge, BRep_Tool::Tolerance(Vlast) );
+                EPmap( SeamEdge ).Append( ParsSeam(i)(j) );
+                EVmap( SeamEdge ).Append( Vlast );
+                EWmap( SeamEdge ).Append( NonSeamWires(i) );
+                break;
+              }
+            }
+            else
+            {
+              BRepAdaptor_Curve bcur( NewE );
+              gp_Pnt Point = bcur.Value( par );
+              NewV = BRepLib_MakeVertex( Point );
+              BB.UpdateVertex( NewV, par, NewE, 10.*Precision::Confusion() );
+            }
+            BB.UpdateVertex( NewV, ParsSeam(i)(j), SeamEdge, 10.*Precision::Confusion() );
+            NewE.Orientation( TopAbs_FORWARD );
+            BB.Add( NewE, PrevV.Oriented(TopAbs_FORWARD) );
+            BB.Add( NewE, NewV.Oriented(TopAbs_REVERSED) );
+
+            NewEdges.Append( NewE );
+            EPmap( SeamEdge ).Append( ParsSeam(i)(j) );
+            EVmap( SeamEdge ).Append( NewV );
+            EWmap( SeamEdge ).Append( NonSeamWires(i) );
+
+            prevpar = par;
+            PrevV = NewV;
+          }
+          //The last edge
+          TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
+          NewE = TopoDS::Edge( aLocalShape );
+          //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
+          par = LastPar;
+          if (Abs(prevpar-par) > Precision::Confusion())
+          {
+            BB.Range( NewE, prevpar, par );
+            NewE.Orientation( TopAbs_FORWARD );
+            BB.Add( NewE, PrevV.Oriented(TopAbs_FORWARD) );
+            BB.Add( NewE, Vlast.Oriented(TopAbs_REVERSED) );
+            NewEdges.Append( NewE );
+          }
+
+          //Substitute anEdge by NewEdges
+          aSub.Substitute( anEdge, NewEdges );
+        }
+
+        //Sorting of EPmap and EVmap and removing repeating points from them
+        iter.Initialize( EPmap );
+        for (; iter.More(); iter.Next())
+        {
+          TColStd_SequenceOfReal Seq;
+          Seq = iter.Value();
+          TopTools_SequenceOfShape SeqShape;
+          SeqShape = EVmap( iter.Key() );
+          TopTools_SequenceOfShape SeqShape2;
+          SeqShape2 = EWmap( iter.Key() );
+          for (i = 1; i < Seq.Length(); i++)
+            for (j = i+1; j <= Seq.Length(); j++)
+              if (Seq(j) < Seq(i))
+              {
+                Standard_Real temp = Seq(i);
+                Seq(i) = Seq(j);
+                Seq(j) = temp;
+                TopoDS_Shape tmp = SeqShape(i);
+                SeqShape(i) = SeqShape(j);
+                SeqShape(j) = tmp;
+                tmp = SeqShape2(i);
+                SeqShape2(i) = SeqShape2(j);
+                SeqShape2(j) = tmp;
+              }
+              EPmap( iter.Key() ) = Seq;
+              EVmap( iter.Key() ) = SeqShape;
+              EWmap( iter.Key() ) = SeqShape2;
+        }
+        iter.Initialize( EPmap );
+        for (; iter.More(); iter.Next())
+        {
+          TColStd_SequenceOfReal Seq;
+          Seq = iter.Value();
+          TopTools_SequenceOfShape SeqShape;
+          SeqShape = EVmap( iter.Key() );
+          TopTools_SequenceOfShape SeqShape2;
+          SeqShape2 = EWmap( iter.Key() );
+          Standard_Boolean remove = Standard_True;
+          while (remove)
+          {
+            remove = Standard_False;
+            for (i = 1; i < Seq.Length(); i++)
+              if (Abs(Seq(i)-Seq(i+1)) <= Precision::Confusion())
+              {
+                Seq.Remove(i+1);
+                SeqShape.Remove(i+1);
+                SeqShape2.Remove(i+1);
+                remove = Standard_True;
+              }
+          }
+          EPmap( iter.Key() ) = Seq;
+          EVmap( iter.Key() ) = SeqShape;
+          EWmap( iter.Key() ) = SeqShape2;
+        }
+
+        //Reconstruction of seam edges
+        TopTools_DataMapOfShapeShape VEmap;
+        iter.Initialize( Emap );
+        for (; iter.More(); iter.Next())
+        {
+          TopoDS_Edge anEdge = TopoDS::Edge( iter.Key() );
+          Standard_Boolean onepoint = Standard_False;
+          TopTools_ListOfShape NewEdges;
+          TColStd_SequenceOfReal Seq;
+          Seq = iter.Value();
+          TColStd_SequenceOfReal Seq2;
+          Seq2 = EPmap( anEdge );
+          TopTools_SequenceOfShape SeqVer;
+          SeqVer = EVmap( anEdge );
+          TopTools_SequenceOfShape SeqWire;
+          SeqWire = EWmap( anEdge );
+          TopoDS_Vertex Vfirst, Vlast;
+          TopExp::Vertices( anEdge, Vfirst, Vlast );
+          Standard_Real fpar, lpar, FirstPar, LastPar;
+          BRep_Tool::Range( anEdge, FirstPar, LastPar );
+          fpar = FirstPar;
+          lpar = Seq(1);
+          TopoDS_Edge NewE;
+          Standard_Integer firstind = 1;
+          if (Abs(fpar-lpar) <= Precision::Confusion())
+          {
+            firstind = 2;
+            fpar = Seq(1);
+            lpar = Seq(2);
+          }
+          else
+          {
+            if (Seq.Length()%2 != 0)
+            {
+              VEmap.Bind( Vfirst, anEdge );
+              firstind = 2;
+              fpar = Seq(1);
+              if (Seq.Length() > 2)
+                lpar = Seq(2);
+              else
+                onepoint = Standard_True;
+            }
+          }
+          if (!onepoint)
+          {
+            TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
+            NewE = TopoDS::Edge( aLocalShape );
+            //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
+            BB.Range( NewE, fpar, lpar );
+            NewE.Orientation( TopAbs_FORWARD );
+            if (firstind == 1)
+            {
+              BB.Add( NewE, Vfirst.Oriented(TopAbs_FORWARD) );
+              aLocalShape = SeqVer(1).Oriented(TopAbs_REVERSED);
+              BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
+              //BB.Add( NewE, TopoDS::Vertex( SeqVer(1).Oriented(TopAbs_REVERSED) ) );
+            }
+            else
+            {
+              aLocalShape = SeqVer(1).Oriented(TopAbs_FORWARD);
+              BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
+              aLocalShape = SeqVer(2).Oriented(TopAbs_REVERSED);
+              BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
+              //BB.Add( NewE, TopoDS::Vertex( SeqVer(1).Oriented(TopAbs_FORWARD) ) );
+              //BB.Add( NewE, TopoDS::Vertex( SeqVer(2).Oriented(TopAbs_REVERSED) ) );
+            }
+            NewEdges.Append( NewE );
+
+            firstind++;
+            for (i = firstind; i < Seq.Length(); i += 2)
+            {
+              aLocalShape = anEdge.EmptyCopied();
+              NewE = TopoDS::Edge( aLocalShape );
+              //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
+              fpar = Seq(i);
+              lpar = Seq(i+1);
+              BB.Range( NewE, fpar, lpar );
+              //Find vertices
+              for (j = 1; j <= Seq2.Length(); j++)
+                if (Abs(fpar-Seq2(j)) <= Precision::Confusion())
+                  break;
+              NewE.Orientation( TopAbs_FORWARD );
+              TopoDS_Shape aLocalShape = SeqVer(j).Oriented(TopAbs_FORWARD);
+              BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
+              aLocalShape = SeqVer(j+1).Oriented(TopAbs_REVERSED);
+              BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
+              //BB.Add( NewE, TopoDS::Vertex( SeqVer(j).Oriented(TopAbs_FORWARD) ) );
+              //BB.Add( NewE, TopoDS::Vertex( SeqVer(j+1).Oriented(TopAbs_REVERSED) ) );
+              NewEdges.Append( NewE );
+            }
+          }
+
+          i = Seq.Length();
+          fpar = Seq(i);
+          lpar = LastPar;
+          if (Abs(fpar-lpar) <= Precision::Confusion())
+            continue;
+          TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
+          NewE = TopoDS::Edge( aLocalShape );
+          //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
+          BB.Range( NewE, fpar, lpar );
+          NewE.Orientation( TopAbs_FORWARD );
+          aLocalShape = SeqVer(SeqVer.Length()).Oriented(TopAbs_FORWARD);
+          BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
+          //BB.Add( NewE, TopoDS::Vertex( SeqVer(SeqVer.Length()).Oriented(TopAbs_FORWARD) ) );
+          BB.Add( NewE, Vlast.Oriented(TopAbs_REVERSED) );
+          NewEdges.Append( NewE );
+
+          //Substitute anEdge by NewEdges
+          aSub.Substitute( anEdge, NewEdges );
+        }
+
+        //Removing edges connected with missing extremities of seam edges
+        TopTools_DataMapIteratorOfDataMapOfShapeShape itve( VEmap );
+        for (; itve.More(); itve.Next())
+        {
+          TopoDS_Shape V = itve.Key();
+          TopoDS_Shape E = itve.Value();
+          TopoDS_Shape W;
+          for (i = 1; i <= Eseq.Length(); i++)
+            if (E.IsSame( Eseq(i) ))
+            {
+              W = Wseq(i);
+              break;
+            }
+            TopoDS_Shape Etoremove;
+            eit.Initialize( W );
+            for (; eit.More(); eit.Next())
+            {
+              TopoDS_Edge CurE = TopoDS::Edge( eit.Value() );
+              if (CurE.IsSame( E ))
+                continue;
+              TopoDS_Vertex Vfirst, Vlast;
+              TopExp::Vertices( CurE, Vfirst, Vlast );
+              if (Vfirst.IsSame( V ) || Vlast.IsSame( V ))
+              {
+                Etoremove = CurE;
+                break;
+              }
+            }
+            if (! Etoremove.IsNull())
+            {
+              W.Free( Standard_True );
+              BB.Remove( W, Etoremove );
+            }
+        }
+
+        aSub.Build( myShape );
+        if (aSub.IsCopied( myShape ))
+        {
+          const TopTools_ListOfShape& listSh = aSub.Copy( myShape );
+          if (! listSh.IsEmpty())
+            myShape = listSh.First();
+        }
+
+        //Reconstruction of wires
+        TopTools_ListOfShape theCopy;
+        TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itww( WWmap );
+        for (; itww.More(); itww.Next())
+        {
+          CurWire = itww.Key();
+          theCopy = aSub.Copy( CurWire );
+          CurWire = theCopy.First();
+          CurWire.Free( Standard_True );
+          TopTools_ListIteratorOfListOfShape itl( itww.Value() );
+          for (; itl.More(); itl.Next())
+          {
+            TopoDS_Shape aWire = itl.Value();
+            CurFace = WFmap( aWire );
+            theCopy = aSub.Copy( aWire );
+            aWire = theCopy.First();
+            //Adjusting period
+            TopLoc_Location L;
+            Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( TopoDS::Face(CurFace), L );
+            eit.Initialize( aWire );
+            for (; eit.More(); eit.Next())
+            {
+              TopoDS_Edge anEdge = TopoDS::Edge( eit.Value() );
+              gp_Pnt2d Pfirst, Plast, Pmid;
+              BRep_Tool::UVPoints( anEdge, TopoDS::Face(CurFace), Pfirst, Plast );
+              BRepAdaptor_Curve2d bc2d( anEdge, TopoDS::Face(CurFace) );
+              Pmid = bc2d.Value( (bc2d.FirstParameter()+bc2d.LastParameter())/2. );
+              gp_Vec2d offset;
+              Standard_Boolean translate = Standard_False;
+              if (Pfirst.X()-2.*M_PI > Precision::Confusion() ||
+                Plast.X()-2.*M_PI > Precision::Confusion()  ||
+                Pmid.X()-2.*M_PI > Precision::Confusion())
+              {
+                offset.SetCoord( -2.*M_PI, 0 );
+                translate = Standard_True;
+              }
+              if (Pfirst.X() < -Precision::Confusion() ||
+                Plast.X() < -Precision::Confusion()  ||
+                Pmid.X() < -Precision::Confusion())
+              {
+                offset.SetCoord( 2.*M_PI, 0 );
+                translate = Standard_True;
+              }
+              if (translate)
+              {
+                const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &anEdge.TShape());
+                BRep_ListIteratorOfListOfCurveRepresentation itcr( TE->ChangeCurves() );
+                Handle(BRep_GCurve) GC;
+
+                for (; itcr.More(); itcr.Next())
+                {
+                  GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
+                  if (!GC.IsNull() && GC->IsCurveOnSurface( theSurf, L ))
+                  {
+                    Handle(Geom2d_Curve) PC = GC->PCurve();
+                    PC = Handle(Geom2d_Curve)::DownCast( PC->Translated( offset ) );
+                    GC->PCurve( PC );
+                    TE->ChangeCurves().Remove( itcr );
+                    TE->ChangeCurves().Append( GC );
+                    break;
+                  }
+                }
+              }
+            }
+            ///////////////////
+            eit.Initialize( aWire, Standard_False );
+            for (; eit.More(); eit.Next())
+            {
+              TopoDS_Shape anEdge = eit.Value();
+              BB.Add( CurWire, anEdge );
+            }
+            if (aSub.IsCopied( CurFace ))
+            {
+              theCopy = aSub.Copy( CurFace );
+              CurFace = theCopy.First();
+            }
+            CurFace.Free( Standard_True );
+            BB.Remove( CurFace, aWire );
+          }
+        }
+}
+//=======================================================================
+//function : CorrectVertexTol
+//purpose  : 
+//=======================================================================
 
-  //Reconstruction of non-seam edges
-  BRepTools_Substitution aSub;
-  BRep_Builder BB;
-  for (i = 1; i <= NonSeam.Length(); i++)
-    {
-      TopoDS_Edge anEdge = TopoDS::Edge( NonSeam(i) );
-      TopTools_ListOfShape NewEdges;
-      TopoDS_Edge NewE;
-      TopoDS_Vertex Vfirst, Vlast;
-      TopExp::Vertices( anEdge, Vfirst, Vlast );
-      Standard_Real par, FirstPar, LastPar;
-      BRep_Tool::Range( anEdge, FirstPar, LastPar );
-      Standard_Integer firstind = 1;
-      par = ParsNonSeam(i)(1);
-      TopoDS_Edge SeamEdge = TopoDS::Edge( Seam(i)(1) );
-      //Find the face
-      for (j = 1; j <= Eseq.Length(); j++)
-       if (SeamEdge.IsSame( Eseq(j) ))
-         break;
-      TopoDS_Face theFace = TopoDS::Face( Fseq(j) );
-      TopLoc_Location L;
-      Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( theFace, L );
-      if (Abs(par-FirstPar) <= Precision::Confusion())
-       {
-         BB.UpdateVertex( Vfirst, ParsSeam(i)(1), SeamEdge, BRep_Tool::Tolerance(Vfirst) );
-         EPmap( SeamEdge ).Append( ParsSeam(i)(1) );
-         EVmap( SeamEdge ).Append( Vfirst );
-         EWmap( SeamEdge ).Append( NonSeamWires(i) );
-         firstind = 2;
-       }
-      Standard_Real prevpar = FirstPar;
-      TopoDS_Vertex PrevV = Vfirst;
-      for (j = firstind; j <= ParsNonSeam(i).Length(); j++)
-       {
-         TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
-         NewE = TopoDS::Edge( aLocalShape );
-         //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
-         TopoDS_Vertex NewV;
-         par = ParsNonSeam(i)(j);
-         BB.Range( NewE, prevpar, par );
-         SeamEdge = TopoDS::Edge( Seam(i)(j) );
-         if (j == ParsNonSeam(i).Length() && Abs(par-LastPar) <= Precision::Confusion())
-           {
-             NewV = Vlast;
-             if (firstind == 2 && j == 2)
-               {
-                 BB.UpdateVertex( Vlast, ParsSeam(i)(j), SeamEdge, BRep_Tool::Tolerance(Vlast) );
-                 EPmap( SeamEdge ).Append( ParsSeam(i)(j) );
-                 EVmap( SeamEdge ).Append( Vlast );
-                 EWmap( SeamEdge ).Append( NonSeamWires(i) );
-                 break;
-               }
-           }
-         else
-           {
-             BRepAdaptor_Curve bcur( NewE );
-             gp_Pnt Point = bcur.Value( par );
-             NewV = BRepLib_MakeVertex( Point );
-             BB.UpdateVertex( NewV, par, NewE, 10.*Precision::Confusion() );
-           }
-         BB.UpdateVertex( NewV, ParsSeam(i)(j), SeamEdge, 10.*Precision::Confusion() );
-         NewE.Orientation( TopAbs_FORWARD );
-         BB.Add( NewE, PrevV.Oriented(TopAbs_FORWARD) );
-         BB.Add( NewE, NewV.Oriented(TopAbs_REVERSED) );
-
-         NewEdges.Append( NewE );
-         EPmap( SeamEdge ).Append( ParsSeam(i)(j) );
-         EVmap( SeamEdge ).Append( NewV );
-         EWmap( SeamEdge ).Append( NonSeamWires(i) );
-
-         prevpar = par;
-         PrevV = NewV;
-       }
-      //The last edge
-      TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
-      NewE = TopoDS::Edge( aLocalShape );
-      //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
-      par = LastPar;
-      if (Abs(prevpar-par) > Precision::Confusion())
-       {
-         BB.Range( NewE, prevpar, par );
-         NewE.Orientation( TopAbs_FORWARD );
-         BB.Add( NewE, PrevV.Oriented(TopAbs_FORWARD) );
-         BB.Add( NewE, Vlast.Oriented(TopAbs_REVERSED) );
-         NewEdges.Append( NewE );
-       }
-
-      //Substitute anEdge by NewEdges
-      aSub.Substitute( anEdge, NewEdges );
-    }
-  
-  //Sorting of EPmap and EVmap and removing repeating points from them
-  iter.Initialize( EPmap );
-  for (; iter.More(); iter.Next())
-    {
-      TColStd_SequenceOfReal Seq;
-      Seq = iter.Value();
-      TopTools_SequenceOfShape SeqShape;
-      SeqShape = EVmap( iter.Key() );
-      TopTools_SequenceOfShape SeqShape2;
-      SeqShape2 = EWmap( iter.Key() );
-      for (i = 1; i < Seq.Length(); i++)
-      for (j = i+1; j <= Seq.Length(); j++)
-       if (Seq(j) < Seq(i))
-         {
-           Standard_Real temp = Seq(i);
-           Seq(i) = Seq(j);
-           Seq(j) = temp;
-           TopoDS_Shape tmp = SeqShape(i);
-           SeqShape(i) = SeqShape(j);
-           SeqShape(j) = tmp;
-           tmp = SeqShape2(i);
-           SeqShape2(i) = SeqShape2(j);
-           SeqShape2(j) = tmp;
-         }
-      EPmap( iter.Key() ) = Seq;
-      EVmap( iter.Key() ) = SeqShape;
-      EWmap( iter.Key() ) = SeqShape2;
-    }
-  iter.Initialize( EPmap );
-  for (; iter.More(); iter.Next())
+void BRepOffsetAPI_DraftAngle::CorrectVertexTol()
+{
+  TopTools_MapOfShape anInitVertices, anInitEdges, aNewEdges;
+  TopExp_Explorer anExp(myInitialShape, TopAbs_EDGE);
+  for(; anExp.More(); anExp.Next())
+  {
+    anInitEdges.Add(anExp.Current());
+    TopoDS_Iterator anIter(anExp.Current());
+    for(; anIter.More(); anIter.Next())
     {
-      TColStd_SequenceOfReal Seq;
-      Seq = iter.Value();
-      TopTools_SequenceOfShape SeqShape;
-      SeqShape = EVmap( iter.Key() );
-      TopTools_SequenceOfShape SeqShape2;
-      SeqShape2 = EWmap( iter.Key() );
-      Standard_Boolean remove = Standard_True;
-      while (remove)
-       {
-         remove = Standard_False;
-         for (i = 1; i < Seq.Length(); i++)
-           if (Abs(Seq(i)-Seq(i+1)) <= Precision::Confusion())
-             {
-               Seq.Remove(i+1);
-               SeqShape.Remove(i+1);
-               SeqShape2.Remove(i+1);
-               remove = Standard_True;
-             }
-       }
-      EPmap( iter.Key() ) = Seq;
-      EVmap( iter.Key() ) = SeqShape;
-      EWmap( iter.Key() ) = SeqShape2;
+      anInitVertices.Add(anIter.Value());
     }
-
-  //Reconstruction of seam edges
-  TopTools_DataMapOfShapeShape VEmap;
-  iter.Initialize( Emap );
-  for (; iter.More(); iter.Next())
+  }
+  //
+
+  BRep_Builder aBB;
+  myVtxToReplace.Clear();
+  anExp.Init(myShape, TopAbs_EDGE);
+  for(; anExp.More(); anExp.Next())
+  {
+    const TopoDS_Shape& anE = anExp.Current();
+    //Skip old (not modified) edges
+    if(anInitEdges.Contains(anE))
+      continue;
+    //
+    //Skip processed edges
+    if(aNewEdges.Contains(anE))
+      continue;
+    //
+    aNewEdges.Add(anE);
+    //
+    Standard_Real anETol = BRep_Tool::Tolerance(TopoDS::Edge(anE));
+    TopoDS_Iterator anIter(anE);
+    for(; anIter.More(); anIter.Next())
     {
-      TopoDS_Edge anEdge = TopoDS::Edge( iter.Key() );
-      Standard_Boolean onepoint = Standard_False;
-      TopTools_ListOfShape NewEdges;
-      TColStd_SequenceOfReal Seq;
-      Seq = iter.Value();
-      TColStd_SequenceOfReal Seq2;
-      Seq2 = EPmap( anEdge );
-      TopTools_SequenceOfShape SeqVer;
-      SeqVer = EVmap( anEdge );
-      TopTools_SequenceOfShape SeqWire;
-      SeqWire = EWmap( anEdge );
-      TopoDS_Vertex Vfirst, Vlast;
-      TopExp::Vertices( anEdge, Vfirst, Vlast );
-      Standard_Real fpar, lpar, FirstPar, LastPar;
-      BRep_Tool::Range( anEdge, FirstPar, LastPar );
-      fpar = FirstPar;
-      lpar = Seq(1);
-      TopoDS_Edge NewE;
-      Standard_Integer firstind = 1;
-      if (Abs(fpar-lpar) <= Precision::Confusion())
-       {
-         firstind = 2;
-         fpar = Seq(1);
-         lpar = Seq(2);
-       }
+      const TopoDS_Vertex& aVtx = TopoDS::Vertex(anIter.Value());
+      if(anInitVertices.Contains(aVtx))
+      {
+        if(myVtxToReplace.IsBound(aVtx))
+        {
+          aBB.UpdateVertex(TopoDS::Vertex(myVtxToReplace(aVtx)), anETol + Epsilon(anETol));
+        }
+        else
+        {
+          Standard_Real aVTol = BRep_Tool::Tolerance(aVtx);
+          if(aVTol < anETol)
+          {
+            TopoDS_Vertex aNewVtx;
+            gp_Pnt aVPnt = BRep_Tool::Pnt(aVtx);
+            aBB.MakeVertex(aNewVtx, aVPnt,anETol + Epsilon(anETol));
+            myVtxToReplace.Bind(aVtx, aNewVtx);
+          }
+        }
+      }
       else
-       {
-         if (Seq.Length()%2 != 0)
-           {
-             VEmap.Bind( Vfirst, anEdge );
-             firstind = 2;
-             fpar = Seq(1);
-             if (Seq.Length() > 2)
-               lpar = Seq(2);
-             else
-               onepoint = Standard_True;
-           }
-       }
-      if (!onepoint)
-       {
-         TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
-         NewE = TopoDS::Edge( aLocalShape );
-         //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
-         BB.Range( NewE, fpar, lpar );
-         NewE.Orientation( TopAbs_FORWARD );
-         if (firstind == 1)
-           {
-             BB.Add( NewE, Vfirst.Oriented(TopAbs_FORWARD) );
-             aLocalShape = SeqVer(1).Oriented(TopAbs_REVERSED);
-             BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
-             //BB.Add( NewE, TopoDS::Vertex( SeqVer(1).Oriented(TopAbs_REVERSED) ) );
-           }
-         else
-           {
-             aLocalShape = SeqVer(1).Oriented(TopAbs_FORWARD);
-             BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
-             aLocalShape = SeqVer(2).Oriented(TopAbs_REVERSED);
-             BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
-             //BB.Add( NewE, TopoDS::Vertex( SeqVer(1).Oriented(TopAbs_FORWARD) ) );
-             //BB.Add( NewE, TopoDS::Vertex( SeqVer(2).Oriented(TopAbs_REVERSED) ) );
-           }
-         NewEdges.Append( NewE );
-         
-         firstind++;
-         for (i = firstind; i < Seq.Length(); i += 2)
-           {
-             aLocalShape = anEdge.EmptyCopied();
-             NewE = TopoDS::Edge( aLocalShape );
-             //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
-             fpar = Seq(i);
-             lpar = Seq(i+1);
-             BB.Range( NewE, fpar, lpar );
-             //Find vertices
-             for (j = 1; j <= Seq2.Length(); j++)
-               if (Abs(fpar-Seq2(j)) <= Precision::Confusion())
-                 break;
-             NewE.Orientation( TopAbs_FORWARD );
-             TopoDS_Shape aLocalShape = SeqVer(j).Oriented(TopAbs_FORWARD);
-             BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
-             aLocalShape = SeqVer(j+1).Oriented(TopAbs_REVERSED);
-             BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
-             //BB.Add( NewE, TopoDS::Vertex( SeqVer(j).Oriented(TopAbs_FORWARD) ) );
-             //BB.Add( NewE, TopoDS::Vertex( SeqVer(j+1).Oriented(TopAbs_REVERSED) ) );
-             NewEdges.Append( NewE );
-           }
-       }
-
-      i = Seq.Length();
-      fpar = Seq(i);
-      lpar = LastPar;
-      if (Abs(fpar-lpar) <= Precision::Confusion())
-       continue;
-      TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
-      NewE = TopoDS::Edge( aLocalShape );
-      //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
-      BB.Range( NewE, fpar, lpar );
-      NewE.Orientation( TopAbs_FORWARD );
-      aLocalShape = SeqVer(SeqVer.Length()).Oriented(TopAbs_FORWARD);
-      BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
-      //BB.Add( NewE, TopoDS::Vertex( SeqVer(SeqVer.Length()).Oriented(TopAbs_FORWARD) ) );
-      BB.Add( NewE, Vlast.Oriented(TopAbs_REVERSED) );
-      NewEdges.Append( NewE );
-
-      //Substitute anEdge by NewEdges
-      aSub.Substitute( anEdge, NewEdges );
-    }
-
-  //Removing edges connected with missing extremities of seam edges
-  TopTools_DataMapIteratorOfDataMapOfShapeShape itve( VEmap );
-  for (; itve.More(); itve.Next())
-    {
-      TopoDS_Shape V = itve.Key();
-      TopoDS_Shape E = itve.Value();
-      TopoDS_Shape W;
-      for (i = 1; i <= Eseq.Length(); i++)
-       if (E.IsSame( Eseq(i) ))
-         {
-           W = Wseq(i);
-           break;
-         }
-      TopoDS_Shape Etoremove;
-      eit.Initialize( W );
-      for (; eit.More(); eit.Next())
-       {
-         TopoDS_Edge CurE = TopoDS::Edge( eit.Value() );
-         if (CurE.IsSame( E ))
-           continue;
-         TopoDS_Vertex Vfirst, Vlast;
-         TopExp::Vertices( CurE, Vfirst, Vlast );
-         if (Vfirst.IsSame( V ) || Vlast.IsSame( V ))
-           {
-             Etoremove = CurE;
-             break;
-           }
-       }
-      if (! Etoremove.IsNull())
-       {
-         W.Free( Standard_True );
-         BB.Remove( W, Etoremove );
-       }
+      {
+        aBB.UpdateVertex(aVtx, anETol + Epsilon(anETol));
+      }
     }
-
+  }
+  //
+  if(myVtxToReplace.IsEmpty())
+  {
+    return;
+  }
+  //
+  BRepTools_Substitution aSub;
+  TopTools_DataMapIteratorOfDataMapOfShapeShape anIter(myVtxToReplace);
+  for(; anIter.More(); anIter.Next())
+  {
+    TopTools_ListOfShape aSubVtx;
+    aSubVtx.Append(anIter.Value());
+    aSub.Substitute(anIter.Key(), aSubVtx);
+  }
   aSub.Build( myShape );
   if (aSub.IsCopied( myShape ))
-    {
-      const TopTools_ListOfShape& listSh = aSub.Copy( myShape );
-      if (! listSh.IsEmpty())
-       myShape = listSh.First();
-    }
-
-  //Reconstruction of wires
-  TopTools_ListOfShape theCopy;
-  TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itww( WWmap );
-  for (; itww.More(); itww.Next())
-    {
-      CurWire = itww.Key();
-      theCopy = aSub.Copy( CurWire );
-      CurWire = theCopy.First();
-      CurWire.Free( Standard_True );
-      TopTools_ListIteratorOfListOfShape itl( itww.Value() );
-      for (; itl.More(); itl.Next())
-       {
-         TopoDS_Shape aWire = itl.Value();
-         CurFace = WFmap( aWire );
-         theCopy = aSub.Copy( aWire );
-         aWire = theCopy.First();
-         //Adjusting period
-         TopLoc_Location L;
-         Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( TopoDS::Face(CurFace), L );
-         eit.Initialize( aWire );
-         for (; eit.More(); eit.Next())
-           {
-             TopoDS_Edge anEdge = TopoDS::Edge( eit.Value() );
-             gp_Pnt2d Pfirst, Plast, Pmid;
-             BRep_Tool::UVPoints( anEdge, TopoDS::Face(CurFace), Pfirst, Plast );
-             BRepAdaptor_Curve2d bc2d( anEdge, TopoDS::Face(CurFace) );
-             Pmid = bc2d.Value( (bc2d.FirstParameter()+bc2d.LastParameter())/2. );
-             gp_Vec2d offset;
-             Standard_Boolean translate = Standard_False;
-             if (Pfirst.X()-2.*M_PI > Precision::Confusion() ||
-                 Plast.X()-2.*M_PI > Precision::Confusion()  ||
-                 Pmid.X()-2.*M_PI > Precision::Confusion())
-               {
-                 offset.SetCoord( -2.*M_PI, 0 );
-                 translate = Standard_True;
-               }
-             if (Pfirst.X() < -Precision::Confusion() ||
-                 Plast.X() < -Precision::Confusion()  ||
-                 Pmid.X() < -Precision::Confusion())
-               {
-                 offset.SetCoord( 2.*M_PI, 0 );
-                 translate = Standard_True;
-               }
-             if (translate)
-               {
-                 const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &anEdge.TShape());
-                 BRep_ListIteratorOfListOfCurveRepresentation itcr( TE->ChangeCurves() );
-                 Handle(BRep_GCurve) GC;
-                 
-                 for (; itcr.More(); itcr.Next())
-                   {
-                     GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
-                     if (!GC.IsNull() && GC->IsCurveOnSurface( theSurf, L ))
-                       {
-                         Handle(Geom2d_Curve) PC = GC->PCurve();
-                         PC = Handle(Geom2d_Curve)::DownCast( PC->Translated( offset ) );
-                         GC->PCurve( PC );
-                         TE->ChangeCurves().Remove( itcr );
-                         TE->ChangeCurves().Append( GC );
-                         break;
-                       }
-                   }
-               }
-           }
-         ///////////////////
-         eit.Initialize( aWire, Standard_False );
-         for (; eit.More(); eit.Next())
-           {
-             TopoDS_Shape anEdge = eit.Value();
-             BB.Add( CurWire, anEdge );
-           }
-         if (aSub.IsCopied( CurFace ))
-           {
-             theCopy = aSub.Copy( CurFace );
-             CurFace = theCopy.First();
-           }
-         CurFace.Free( Standard_True );
-         BB.Remove( CurFace, aWire );
-       }
-    }
+  {
+    const TopTools_ListOfShape& listSh = aSub.Copy( myShape );
+    if (! listSh.IsEmpty())
+      myShape = listSh.First();
+  }
+  //
 }
index 5faf59e8b05f4d0ff938816f8536abd17bfbeaa1..b57867bca86ce33189f02408f33fae7ff9232d59 100644 (file)
@@ -17,6 +17,7 @@
 #include <Draft_Modification.ixx>
 
 #include <BRep_Tool.hxx>
+#include <BRep_Builder.hxx>
 #include <TopLoc_Location.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopoDS.hxx>
 #include <TopExp.hxx>
 #include <GeomProjLib.hxx>
+#include <GeomLib_CheckCurveOnSurface.hxx>
+//
+static Standard_Real EvalTol(const Handle(Geom_Curve)& C3d, 
+                             const Handle(Geom2d_Curve) C2d, 
+                             const Handle(Geom_Surface)& S,
+                             const Standard_Real f,
+                             const Standard_Real l)
+{
+  Standard_Real first = f, last = l;
+  //Set first, last to avoid ErrosStatus = 2 because of 
+  //too strong checking of limits in class CheckCurveOnSurface
+  //
+  if(!C3d->IsPeriodic())
+  {
+    first = Max(first, C3d->FirstParameter());
+    last = Min(last, C3d->LastParameter());
+  }
+  if(!C2d->IsPeriodic())
+  {
+    first = Max(first, C2d->FirstParameter());
+    last = Min(last, C2d->LastParameter());
+  }
 
-#include <Precision.hxx>
+  GeomLib_CheckCurveOnSurface CT(C3d, S, first, last);
+  CT.Perform(C2d);
+  if(CT.IsDone())
+  {
+    return CT.MaxDistance();
+  }
+  else
+  {
+    if(CT.ErrorStatus() == 3 || (CT.ErrorStatus() == 2 &&
+      (C3d->IsPeriodic() || C2d->IsPeriodic())))
+    {
+      //Try to estimate by sample points
+      Standard_Integer nbint = 22;
+      Standard_Real dt = (last - first) / nbint;
+      dt = Max(dt, Precision::Confusion());
+      Standard_Real d, dmax = 0.;
+      gp_Pnt2d aP2d;
+      gp_Pnt aPC, aPS;
+      Standard_Integer cnt = 0; 
+      Standard_Real t = first;
+      for(; t <= last; t += dt)
+      {
+        cnt++;
+        C2d->D0(t, aP2d);
+        C3d->D0(t, aPC);
+        S->D0(aP2d.X(), aP2d.Y(), aPS);
+        d = aPS.SquareDistance(aPC);
+        if(d > dmax)
+        {
+          dmax = d;
+        }
+      }
+      if(cnt < nbint + 1)
+      {
+        t = last;
+        C2d->D0(t, aP2d);
+        C3d->D0(t, aPC);
+        S->D0(aP2d.X(), aP2d.Y(), aPS);
+        d = aPS.SquareDistance(aPC);
+        if(d > dmax)
+        {
+          dmax = d;
+        }
+      }
 
-#include <BRep_Builder.hxx>
-#include <BRepTools.hxx>
+      dmax = 1.2 * Sqrt(dmax);
+      return dmax;
+    }
+    else
+    {
+      return 0.;
+    }
+  }
+}
 
 //=======================================================================
 //function : Draft_Modification
@@ -445,6 +518,15 @@ Standard_Boolean Draft_Modification::NewCurve2d(const TopoDS_Edge& E,
       C->Translate(aV2DT);
     }
   }
+  //
+  Handle(Geom_Curve) aC3d = BRep_Tool::Curve(NewE, Fp, Lp);
+  Standard_Real newtol = EvalTol(aC3d, C, SB, Fp, Lp);
+  if(newtol > Tol)
+  {
+    Tol = newtol;
+    BRep_Builder B;
+    B.UpdateEdge(NewE, newtol);
+  }
   return Standard_True;
 }
 
index 072f21e443934371c2e11f23ba46a378e5ce905f..7e53f85bf1c238111b3f8c67e12f078940e03f9f 100644 (file)
@@ -1211,14 +1211,14 @@ void Draft_Modification::Perform ()
                Extrema_ExtPC myExtPC( pfv, TheCurve );
                Dist2Min = RealLast();
                for (i = 1; i <= myExtPC.NbExt(); i++)
-                 {
-                   Dist2 = myExtPC.SquareDistance(i);
-                   if (Dist2 < Dist2Min)
-                     {
-                       Dist2Min = Dist2;
-                       pmin = myExtPC.Point(i).Parameter();
-                     }
-                 }
+               {
+                  Dist2 = myExtPC.SquareDistance(i);
+                  if (Dist2 < Dist2Min)
+                  {
+                    Dist2Min = Dist2;
+                    pmin = myExtPC.Point(i).Parameter();
+                  }
+                }
 
                newC->D1(pmin,pfv,newd1);
                Standard_Boolean YaRev = d1fv.Dot(newd1) < 0.; 
@@ -1503,6 +1503,7 @@ void Draft_Modification::Perform ()
 
       for (Vinf.InitEdgeIterator();Vinf.MoreEdge(); Vinf.NextEdge()) {
        const TopoDS_Edge& Edg = Vinf.Edge();
+        Standard_Real initpar = Vinf.Parameter(Edg);
        //const Draft_EdgeInfo& Einf = myEMap(Edg);
        Draft_EdgeInfo& Einf = myEMap(Edg);
        //Vinf.ChangeParameter(Edg) = Parameter(Einf.Geometry(),pvt);
@@ -1515,8 +1516,20 @@ void Draft_Modification::Perform ()
            Vinf.ChangeParameter(Edg) = SmartParameter( Einf, BRep_Tool::Tolerance(Edg), pvt, done, S1, S2 );
          }
        else
+        {
+          if(Abs(initpar - param) > Precision::PConfusion())
+          {
+            Standard_Real f, l;
+            TopLoc_Location Loc;
+            const Handle(Geom_Curve)& aC = BRep_Tool::Curve(Edg, Loc, f, l);
+            if(aC->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve))
+            {
+              Einf.SetNewGeometry(Standard_True);
+            }
+          }
          Vinf.ChangeParameter(Edg) = param;
       }
+      }
       itv.Next();
     }
   }
index 40ba005ce48d57a8e3b3b6c4d6b9f0e9afa794eb..37ab870949a31ae8c8bc4c1cc96d9b40a916ddaf 100644 (file)
@@ -789,6 +789,15 @@ is
      raises DimensionError;
         ---Purpose :
         --  Raised if the length of K is not equal to the number of knots.
+  Knots (me)
+  returns Array1OfReal from TColStd
+        ---Purpose : returns the knot values of the B-spline curve; 
+       -- Warning
+       -- A knot with a multiplicity greater than 1 is not
+       -- repeated in the knot table. The Multiplicity function
+       -- can be used to obtain the multiplicity of each knot.
+        ---C++ : return const &
+  is static;
 
 
   KnotSequence (me; K : out Array1OfReal from TColStd)
@@ -845,6 +854,12 @@ is
        -- Standard_DimensionError if the array K is not of
        -- the appropriate length.Returns the knots sequence.
              raises DimensionError;
+  KnotSequence (me)
+  returns Array1OfReal from TColStd
+        ---Purpose : returns the knots of the B-spline curve. 
+       -- Knots with multiplicit greater than 1 are repeated
+        ---C++ : return const &
+  is static;
        
 
 
@@ -910,6 +925,11 @@ is
      raises DimensionError;
         ---Purpose :
         --  Raised if the length of M is not equal to NbKnots.
+  Multiplicities (me)
+  returns Array1OfInteger from TColStd
+        ---Purpose : returns the multiplicity of the knots of the curve.
+        ---C++ : return const &
+  is static;
 
 
   NbKnots (me)  returns Integer;
@@ -933,6 +953,11 @@ is
      raises DimensionError;
         ---Purpose : 
         --  Raised if the length of P is not equal to the number of poles.
+  Poles (me)
+  returns Array1OfPnt from TColgp
+        ---Purpose : Returns the poles of the B-spline curve;
+        ---C++ : return const &
+  is static;
 
 
   StartPoint (me)  returns Pnt;
@@ -954,6 +979,11 @@ is
      raises DimensionError;
         ---Purpose :
         --  Raised if the length of W is not equal to NbPoles.
+  Weights (me)
+  returns Array1OfReal from TColStd
+        ---Purpose : Returns the weights of the B-spline curve;
+        ---C++ : return const &
+  is static;
 
 
 
index ec08ce5a4396eaf918eecbbc79bfab7817dd4630..7cc8d4f8037e0e374ea103e9462915804b5ddc04 100644 (file)
@@ -437,6 +437,11 @@ void Geom_BSplineCurve::Knots (TColStd_Array1OfReal& K) const
   K = knots->Array1();
 }
 
+const TColStd_Array1OfReal& Geom_BSplineCurve::Knots() const
+{
+  return knots->Array1();
+}
+
 //=======================================================================
 //function : KnotSequence
 //purpose  : 
@@ -449,6 +454,11 @@ void Geom_BSplineCurve::KnotSequence (TColStd_Array1OfReal& K) const
   K = flatknots->Array1();
 }
 
+const TColStd_Array1OfReal& Geom_BSplineCurve::KnotSequence() const
+{
+  return flatknots->Array1();
+}
+
 //=======================================================================
 //function : LastUKnotIndex
 //purpose  : 
@@ -668,6 +678,11 @@ void Geom_BSplineCurve::Multiplicities (TColStd_Array1OfInteger& M) const
   M = mults->Array1();
 }
 
+const TColStd_Array1OfInteger& Geom_BSplineCurve::Multiplicities() const
+{
+  return mults->Array1();
+}
+
 //=======================================================================
 //function : NbKnots
 //purpose  : 
@@ -708,6 +723,11 @@ void Geom_BSplineCurve::Poles (TColgp_Array1OfPnt& P) const
   P = poles->Array1();
 }
 
+const TColgp_Array1OfPnt& Geom_BSplineCurve::Poles() const
+{
+  return poles->Array1();
+}
+
 //=======================================================================
 //function : StartPoint
 //purpose  : 
@@ -757,6 +777,13 @@ void Geom_BSplineCurve::Weights
   }
 }
 
+const TColStd_Array1OfReal& Geom_BSplineCurve::Weights() const
+{
+  if (IsRational())
+    return weights->Array1();
+  return BSplCLib::NoWeights();
+}
+
 //=======================================================================
 //function : IsRational
 //purpose  : 
index 0196187a54ec777a134d10896f5e78ff3a5bc8b4..64c93263c9ed98014367962ba3ee0c66ab8ab2f0 100644 (file)
@@ -843,6 +843,11 @@ is
      raises DimensionError;
         --- Purpose :
         --  Raised if the length of K is not equal to the number of knots.
+  Knots (me)
+  returns Array1OfReal from TColStd
+        ---Purpose : returns the knot values of the B-spline curve;
+        ---C++ : return const &
+  is static;
 
 
   KnotSequence (me; K : out Array1OfReal from TColStd)
@@ -854,6 +859,15 @@ is
      raises DimensionError;
         --- Purpose :
         --  Raised if the length of K is not equal to NbPoles + Degree + 1
+  KnotSequence (me)
+  returns Array1OfReal from TColStd
+        ---Purpose : Returns the knots sequence.
+        --  In this sequence the knots with a multiplicity greater than 1
+        --  are repeated. 
+        -- Example :
+        --  K = {k1, k1, k1, k2, k3, k3, k4, k4, k4}
+        ---C++ : return const &
+  is static;
 
 
 
@@ -919,6 +933,11 @@ is
      raises DimensionError;
         --- Purpose :
         --  Raised if the length of M is not equal to NbKnots.
+  Multiplicities (me)
+  returns Array1OfInteger from TColStd
+        ---Purpose : returns the multiplicity of the knots of the curve.
+        ---C++ : return const &
+  is static;
 
 
   NbKnots (me)  returns Integer;
@@ -942,6 +961,11 @@ is
      raises DimensionError;
         --- Purpose : 
         --  Raised if the length of P is not equal to the number of poles.
+  Poles (me)
+  returns Array1OfPnt2d from TColgp
+        ---Purpose : Returns the poles of the B-spline curve;
+        ---C++ : return const &
+  is static;
 
 
   StartPoint (me)  returns Pnt2d;
@@ -963,6 +987,11 @@ is
      raises DimensionError;
         --- Purpose :
         --  Raised if the length of W is not equal to NbPoles.
+  Weights (me)
+  returns Array1OfReal from TColStd
+        ---Purpose : Returns the weights of the B-spline curve;
+        ---C++ : return const &
+  is static;
 
 
 
index b80b4151e250a94b2db2ea5f859b7def9ac3292a..3541ed8e976572c7afd695a0bed26d7cd2a486e6 100644 (file)
@@ -440,6 +440,11 @@ void Geom2d_BSplineCurve::Knots (TColStd_Array1OfReal& K) const
   K = knots->Array1();
 }
 
+const TColStd_Array1OfReal& Geom2d_BSplineCurve::Knots() const
+{
+  return knots->Array1();
+}
+
 //=======================================================================
 //function : KnotSequence
 //purpose  : 
@@ -452,6 +457,11 @@ void Geom2d_BSplineCurve::KnotSequence (TColStd_Array1OfReal& K) const
   K = flatknots->Array1();
 }
 
+const TColStd_Array1OfReal& Geom2d_BSplineCurve::KnotSequence() const
+{
+  return flatknots->Array1();
+}
+
 //=======================================================================
 //function : LastUKnotIndex
 //purpose  : 
@@ -676,6 +686,11 @@ void Geom2d_BSplineCurve::Multiplicities (TColStd_Array1OfInteger& M) const
   M = mults->Array1();
 }
 
+const TColStd_Array1OfInteger& Geom2d_BSplineCurve::Multiplicities() const
+{
+  return mults->Array1();
+}
+
 //=======================================================================
 //function : NbKnots
 //purpose  : 
@@ -716,6 +731,11 @@ void Geom2d_BSplineCurve::Poles (TColgp_Array1OfPnt2d& P) const
   P = poles->Array1();
 }
 
+const TColgp_Array1OfPnt2d& Geom2d_BSplineCurve::Poles() const
+{
+  return poles->Array1();
+}
+
 //=======================================================================
 //function : StartPoint
 //purpose  : 
@@ -764,6 +784,13 @@ void Geom2d_BSplineCurve::Weights
   }
 }
 
+const TColStd_Array1OfReal& Geom2d_BSplineCurve::Weights() const
+{
+  if (IsRational())
+    return weights->Array1();
+  return BSplCLib::NoWeights();
+}
+
 //=======================================================================
 //function : IsRational
 //purpose  : 
index a6b44fa64d34a556393025db2594b6777b83deb9..b02600b998b44341b3e86782ca2f0ac10aa6a2e6 100755 (executable)
@@ -1 +1,3 @@
 GeomLib_CMPLRS.edl
+GeomLib_CheckCurveOnSurface.cxx
+GeomLib_CheckCurveOnSurface.hxx
diff --git a/src/GeomLib/GeomLib_CheckCurveOnSurface.cxx b/src/GeomLib/GeomLib_CheckCurveOnSurface.cxx
new file mode 100644 (file)
index 0000000..1fde4f5
--- /dev/null
@@ -0,0 +1,653 @@
+// Created by: Nikolai BUKHALOV
+// Copyright (c) 2015 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Adaptor2d_HCurve2d.hxx>
+#include <Adaptor3d_Curve.hxx>
+#include <Adaptor3d_CurveOnSurface.hxx>
+#include <Adaptor3d_HSurface.hxx>
+#include <Geom_BSplineCurve.hxx>
+#include <Geom_TrimmedCurve.hxx>
+#include <Geom2d_BSplineCurve.hxx>
+#include <Geom2d_TrimmedCurve.hxx>
+#include <Geom2dAdaptor_GHCurve.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <GeomAdaptor_HSurface.hxx>
+#include <GeomLib_CheckCurveOnSurface.hxx>
+#include <gp_Pnt.hxx>
+#include <math_Matrix.hxx>
+#include <math_MultipleVarFunctionWithHessian.hxx>
+#include <math_NewtonMinimum.hxx>
+#include <math_PSO.hxx>
+#include <math_PSOParticlesPool.hxx>
+#include <OSD_Parallel.hxx>
+#include <Standard_ErrorHandler.hxx>
+#include <TColStd_Array1OfReal.hxx>
+
+class GeomLib_CheckCurveOnSurface_TargetFunc;
+
+static 
+Standard_Boolean MinComputing(
+                GeomLib_CheckCurveOnSurface_TargetFunc& theFunction,
+                const Standard_Real theEpsilon, //1.0e-3
+                const Standard_Integer theNbParticles,
+                Standard_Real& theBestValue,
+                Standard_Real& theBestParameter);
+
+static Standard_Integer FillSubIntervals( const Handle(Geom_Curve)& theCurve3d,
+                                          const Handle(Geom2d_Curve)& theCurve2d,
+                                          const Standard_Real theFirst,
+                                          const Standard_Real theLast,
+                                          Standard_Integer &theNbParticles,
+                                          TColStd_Array1OfReal* const theSubIntervals = 0);
+
+//=======================================================================
+//class   : GeomLib_CheckCurveOnSurface_TargetFunc
+//purpose : Target function (to be minimized)
+//=======================================================================
+class GeomLib_CheckCurveOnSurface_TargetFunc :
+  public math_MultipleVarFunctionWithHessian
+{
+ public:
+  GeomLib_CheckCurveOnSurface_TargetFunc( const Adaptor3d_Curve& theC3D,
+                                          const Adaptor3d_Curve& theAdCS,
+                                          const Standard_Real theFirst,
+                                          const Standard_Real theLast):
+  myCurve1(theC3D),
+  myCurve2(theAdCS),
+  myFirst(theFirst),
+  myLast(theLast)
+  {
+  }
+  
+  //returns the number of parameters of the function
+  //(the function is one-dimension).
+  virtual Standard_Integer NbVariables() const {
+    return 1;
+  }
+  
+  //returns value of the function when parameters are equal to theX
+  virtual Standard_Boolean Value(const math_Vector& theX,
+                                 Standard_Real& theFVal)
+  {
+    return Value(theX(1), theFVal);
+  }
+
+  //returns value of the one-dimension-function when parameter
+  //is equal to theX
+  Standard_Boolean Value( const  Standard_Real theX,
+                          Standard_Real& theFVal) const
+  {
+    try
+    {
+      OCC_CATCH_SIGNALS
+      if (!CheckParameter(theX))
+        return Standard_False;
+
+      const gp_Pnt  aP1(myCurve1.Value(theX)),
+                    aP2(myCurve2.Value(theX));
+      
+      theFVal = -1.0*aP1.SquareDistance(aP2);
+    }
+    catch(Standard_Failure) {
+      return Standard_False;
+    }
+    //
+    return Standard_True;
+  }
+
+  //see analogical method for abstract owner class math_MultipleVarFunction
+  virtual Standard_Integer GetStateNumber()
+  {
+    return 0;
+  }
+  
+  //returns the gradient of the function when parameters are
+  //equal to theX
+  virtual Standard_Boolean Gradient(const math_Vector& theX,
+                                    math_Vector& theGrad)
+  {
+    return Derive(theX(1), theGrad(1));
+  }
+
+  //returns 1st derivative of the the one-dimension-function when
+  //parameter is equal to theX
+  Standard_Boolean Derive(const Standard_Real theX, Standard_Real& theDeriv) const
+  {
+    try
+    {
+      OCC_CATCH_SIGNALS
+      if (!CheckParameter(theX))
+      {
+        return Standard_False;
+      }
+      //
+      gp_Pnt aP1, aP2;
+      gp_Vec aDC1, aDC2;
+      //
+      myCurve1.D1(theX, aP1, aDC1);
+      myCurve2.D1(theX, aP2, aDC2);
+
+      const gp_Vec aVec1(aP1, aP2), aVec2(aDC2-aDC1);
+      //
+      theDeriv = -2.0*aVec1.Dot(aVec2);
+    }
+    catch(Standard_Failure)
+    {
+      return Standard_False;
+    }
+
+    return Standard_True;
+  }
+  
+  //returns value and gradient   
+  virtual Standard_Boolean Values(const math_Vector& theX,
+                                  Standard_Real& theVal,
+                                  math_Vector& theGrad) 
+  {
+    if (!Value(theX, theVal))
+    {
+      return Standard_False;
+    }
+    //
+    if (!Gradient(theX, theGrad)) {
+      return Standard_False;
+    }
+    //
+    return Standard_True;
+  }
+
+  //returns value, gradient and hessian
+  virtual Standard_Boolean Values(const math_Vector& theX,
+                                  Standard_Real& theVal,
+                                  math_Vector& theGrad,
+                                  math_Matrix& theHessian)
+  {
+    if (!Value(theX, theVal))
+    {
+      return Standard_False;
+    }
+    //
+    if (!Gradient(theX, theGrad))
+    {
+      return Standard_False;
+    }
+    //
+    theHessian(1,1) = theGrad(1);
+    //
+    return Standard_True;
+  }
+  //
+  Standard_Real FirstParameter() const
+  {
+    return myFirst;
+  }
+
+  //
+  Standard_Real LastParameter() const
+  {
+    return myLast;
+  }
+  
+ private:
+  GeomLib_CheckCurveOnSurface_TargetFunc operator=(GeomLib_CheckCurveOnSurface_TargetFunc&);
+
+  //checks if the function can be computed when its parameter is
+  //equal to theParam
+   Standard_Boolean CheckParameter(const Standard_Real theParam) const
+   {
+     return ((myFirst <= theParam) && (theParam <= myLast));
+   }
+
+   const Adaptor3d_Curve& myCurve1;
+   const Adaptor3d_Curve& myCurve2;
+   const Standard_Real myFirst;
+   const Standard_Real myLast;
+};
+
+//=======================================================================
+//class   : GeomLib_CheckCurveOnSurface_Local
+//purpose : Created for parallelization possibility only
+//=======================================================================
+class GeomLib_CheckCurveOnSurface_Local
+{
+public:
+  GeomLib_CheckCurveOnSurface_Local(
+              const Handle(Geom_Curve)& theCurve3D,
+              const Handle(Geom2d_Curve)& theCurve2D,
+              const Handle(Geom_Surface)& theSurface,
+              const TColStd_Array1OfReal& theIntervalsArr,
+              const Standard_Real theEpsilonRange,
+              const Standard_Integer theNbParticles):
+  myCurve3D(theCurve3D),
+  myCurve2D(theCurve2D),
+  mySurface(theSurface),
+  mySubIntervals(theIntervalsArr),
+  myEpsilonRange(theEpsilonRange),
+  myNbParticles(theNbParticles),
+  myArrOfDist(theIntervalsArr.Lower(), theIntervalsArr.Upper()-1),
+  myArrOfParam(theIntervalsArr.Lower(), theIntervalsArr.Upper()-1)
+  {
+  }
+  
+  void operator()(const Standard_Integer& theIndex) const
+  {
+    //For every sub-interval (which is set by mySubIntervals array) this method
+    //computes optimal value of GeomLib_CheckCurveOnSurface_TargetFunc function.
+    //This optimal value will be put in corresponding (depending on theIndex - the
+    //identificator of the current interval in mySubIntervals array) cell of 
+    //myArrOfDist and myArrOfParam arrays.
+    const GeomAdaptor_Curve anAC(myCurve3D);
+    const Handle(Adaptor2d_HCurve2d) anAd2dC = new Geom2dAdaptor_GHCurve(myCurve2D);
+    const Handle(Adaptor3d_HSurface) anAdS = new GeomAdaptor_HSurface(mySurface);
+
+    const Adaptor3d_CurveOnSurface anACS(anAd2dC, anAdS);
+
+    GeomLib_CheckCurveOnSurface_TargetFunc aFunc( anAC, anACS,
+                                                  mySubIntervals.Value(theIndex),
+                                                  mySubIntervals.Value(theIndex+1));
+
+    Standard_Real aMinDist = RealLast(), aPar = 0.0;
+    if(!MinComputing(aFunc, myEpsilonRange, myNbParticles, aMinDist, aPar))
+    {
+      myArrOfDist(theIndex) = RealLast();
+      myArrOfParam(theIndex) = aFunc.FirstParameter();
+      return;
+    }
+
+    myArrOfDist(theIndex) = aMinDist;
+    myArrOfParam(theIndex) = aPar;
+  }
+
+  //Returns optimal value (inverse of square of maximal distance)
+  void OptimalValues(Standard_Real& theMinimalValue, Standard_Real& theParameter) const
+  {
+    //This method looks for the minimal value of myArrOfDist.
+
+    const Standard_Integer aStartInd = myArrOfDist.Lower();
+    theMinimalValue = myArrOfDist(aStartInd);
+    theParameter = myArrOfParam(aStartInd);
+    for(Standard_Integer i = aStartInd + 1; i <= myArrOfDist.Upper(); i++)
+    {
+      if(myArrOfDist(i) < theMinimalValue)
+      {
+        theMinimalValue = myArrOfDist(i);
+        theParameter = myArrOfParam(i);
+      }
+    }
+  }
+
+private:
+  GeomLib_CheckCurveOnSurface_Local operator=(GeomLib_CheckCurveOnSurface_Local&);
+  const Handle(Geom_Curve)& myCurve3D;
+  const Handle(Geom2d_Curve)& myCurve2D;
+  const Handle(Geom_Surface)& mySurface;
+
+  const TColStd_Array1OfReal& mySubIntervals;
+  const Standard_Real myEpsilonRange;
+  const Standard_Integer myNbParticles;
+  mutable NCollection_Array1<Standard_Real> myArrOfDist;
+  mutable NCollection_Array1<Standard_Real> myArrOfParam;
+};
+
+//=======================================================================
+//function : GeomLib_CheckCurveOnSurface
+//purpose  : 
+//=======================================================================
+GeomLib_CheckCurveOnSurface::GeomLib_CheckCurveOnSurface()
+:
+  myFirst(0.),
+  myLast(0.),
+  myErrorStatus(0),
+  myMaxDistance(RealLast()),
+  myMaxParameter(0.)
+{
+}
+
+//=======================================================================
+//function : GeomLib_CheckCurveOnSurface
+//purpose  : 
+//=======================================================================
+GeomLib_CheckCurveOnSurface::
+  GeomLib_CheckCurveOnSurface(const Handle(Geom_Curve)& theCurve,
+                              const Handle(Geom_Surface)& theSurface,
+                              const Standard_Real theFirst,
+                              const Standard_Real theLast):
+  myCurve(theCurve),
+  mySurface(theSurface),
+  myFirst(theFirst),
+  myLast(theLast),
+  myErrorStatus(0),
+  myMaxDistance(RealLast()),
+  myMaxParameter(0.)
+{
+}
+
+//=======================================================================
+//function : Init
+//purpose  : 
+//=======================================================================
+void GeomLib_CheckCurveOnSurface::Init()
+{
+  myCurve.Nullify();
+  mySurface.Nullify();
+  myFirst = 0.0;
+  myLast = 0.0;
+  myErrorStatus = 0;
+  myMaxDistance = RealLast();
+  myMaxParameter = 0.0;
+}
+
+//=======================================================================
+//function : Init
+//purpose  : 
+//=======================================================================
+void GeomLib_CheckCurveOnSurface::Init( const Handle(Geom_Curve)& theCurve,
+                                        const Handle(Geom_Surface)& theSurface,
+                                        const Standard_Real theFirst,
+                                        const Standard_Real theLast)
+{
+  myCurve = theCurve;
+  mySurface = theSurface;
+  myFirst = theFirst;
+  myLast = theLast;
+  myErrorStatus = 0;
+  myMaxDistance = RealLast();
+  myMaxParameter = 0.0;
+}
+
+//=======================================================================
+//function : Perform
+//purpose  : 
+//=======================================================================
+
+#ifndef HAVE_TBB
+//After fixing bug # 26365, this fragment should be deleted
+//(together the text "#ifdef HAVE_TBB")
+
+void GeomLib_CheckCurveOnSurface::Perform(const Handle(Geom2d_Curve)& thePCurve,
+                                          const Standard_Boolean)
+{
+  const Standard_Boolean isTheMTDisabled = Standard_True;
+#else
+void GeomLib_CheckCurveOnSurface::Perform(const Handle(Geom2d_Curve)& thePCurve,
+                                          const Standard_Boolean isTheMTDisabled)
+{
+#endif
+  if( myCurve.IsNull() ||
+      mySurface.IsNull() ||
+      thePCurve.IsNull())
+  {
+    myErrorStatus = 1;
+    return;
+  }
+
+  if( (myCurve->FirstParameter() > myFirst) ||
+      (myCurve->LastParameter() < myLast) ||
+      (thePCurve->FirstParameter() > myFirst) ||
+      (thePCurve->LastParameter() < myLast))
+  {
+    myErrorStatus = 2;
+    return;
+  }
+
+  const Standard_Real anEpsilonRange = 1.e-3;
+
+  Standard_Integer aNbParticles = 3;
+
+  //Polynomial function with degree n has not more than n-1 maxima and
+  //minima (degree of 1st derivative is equal to n-1 => 1st derivative has
+  //no greater than n-1 roots). Consequently, this function has
+  //maximum n monotonicity intervals. That is a good idea to try to put
+  //at least one particle in every monotonicity interval. Therefore,
+  //number of particles should be equal to n. 
+
+  const Standard_Integer aNbSubIntervals = 
+                              FillSubIntervals( myCurve, thePCurve,
+                                                myFirst, myLast, aNbParticles);
+
+  if(!aNbSubIntervals)
+  {
+    myErrorStatus = 3;
+    return;
+  }
+
+  try {
+    OCC_CATCH_SIGNALS
+
+    TColStd_Array1OfReal anIntervals(1, aNbSubIntervals+1);
+    FillSubIntervals(myCurve, thePCurve, myFirst, myLast, aNbParticles, &anIntervals);
+
+    GeomLib_CheckCurveOnSurface_Local aComp(myCurve, thePCurve,
+                                mySurface, anIntervals, anEpsilonRange, aNbParticles);
+
+    OSD_Parallel::For(anIntervals.Lower(), anIntervals.Upper(), aComp, isTheMTDisabled);
+
+    aComp.OptimalValues(myMaxDistance, myMaxParameter);
+
+    myMaxDistance = sqrt(Abs(myMaxDistance));
+  }
+  catch (Standard_Failure) {
+    myErrorStatus = 3;
+  }
+}
+
+//=======================================================================
+// Function : FillSubIntervals
+// purpose : Divides [theFirst, theLast] interval on parts
+//            in order to make searching-algorithm more precisely
+//            (fills theSubIntervals array).
+//            Returns number of subintervals.
+//=======================================================================
+Standard_Integer FillSubIntervals(const Handle(Geom_Curve)& theCurve3d,
+                                  const Handle(Geom2d_Curve)& theCurve2d,
+                                  const Standard_Real theFirst,
+                                  const Standard_Real theLast,
+                                  Standard_Integer &theNbParticles,
+                                  TColStd_Array1OfReal* const theSubIntervals)
+{
+  const Standard_Real anArrTempC[2] = {theFirst, theLast};
+  const TColStd_Array1OfReal anArrTemp(anArrTempC[0], 1, 2);
+
+  theNbParticles = 3;
+  Handle(Geom2d_BSplineCurve) aBS2DCurv;
+  Handle(Geom_BSplineCurve) aBS3DCurv;
+
+  //
+  if (theCurve3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
+  {
+    aBS3DCurv = Handle(Geom_BSplineCurve)::
+                      DownCast(Handle(Geom_TrimmedCurve)::
+                      DownCast(theCurve3d)->BasisCurve());
+  }
+  else
+  {
+    aBS3DCurv = Handle(Geom_BSplineCurve)::DownCast(theCurve3d);
+  }
+
+  if (theCurve2d->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
+  {
+    aBS2DCurv = Handle(Geom2d_BSplineCurve)::
+                      DownCast(Handle(Geom2d_TrimmedCurve)::
+                      DownCast(theCurve2d)->BasisCurve());
+  }
+  else
+  {
+    aBS2DCurv = Handle(Geom2d_BSplineCurve)::DownCast(theCurve2d);
+  }
+
+  const TColStd_Array1OfReal &anArrKnots3D = !aBS3DCurv.IsNull() ? 
+                                              aBS3DCurv->Knots() :
+                                              anArrTemp;
+  const TColStd_Array1OfReal &anArrKnots2D = !aBS2DCurv.IsNull() ?
+                                              aBS2DCurv->Knots() :
+                                              anArrTemp;
+
+  Standard_Integer aNbSubIntervals = 1;
+
+  try
+  {
+    OCC_CATCH_SIGNALS
+    const Standard_Integer  anIndMax3D = anArrKnots3D.Upper(),
+                            anIndMax2D = anArrKnots2D.Upper();
+
+    Standard_Integer  anIndex3D = anArrKnots3D.Lower(),
+                      anIndex2D = anArrKnots2D.Lower();
+
+    if(theSubIntervals)
+      theSubIntervals->ChangeValue(aNbSubIntervals) = theFirst;
+
+    while((anIndex3D <= anIndMax3D) && (anIndex2D <= anIndMax2D))
+    {
+      const Standard_Real aVal3D = anArrKnots3D.Value(anIndex3D),
+                          aVal2D = anArrKnots2D.Value(anIndex2D);
+      const Standard_Real aDelta = aVal3D - aVal2D;
+
+      if(aDelta < Precision::PConfusion())
+      {//aVal3D <= aVal2D
+        if((aVal3D > theFirst) && (aVal3D < theLast))
+        {
+          aNbSubIntervals++;
+        
+          if(theSubIntervals)
+            theSubIntervals->ChangeValue(aNbSubIntervals) = aVal3D;
+        }
+
+        anIndex3D++;
+
+        if(-aDelta < Precision::PConfusion())
+        {//aVal3D == aVal2D
+          anIndex2D++;
+        }
+      }
+      else
+      {//aVal2D < aVal3D
+        if((aVal2D > theFirst) && (aVal2D < theLast))
+        {
+          aNbSubIntervals++;
+          
+          if(theSubIntervals)
+            theSubIntervals->ChangeValue(aNbSubIntervals) = aVal2D;
+        }
+
+        anIndex2D++;
+      }
+    }
+
+    if(theSubIntervals)
+      theSubIntervals->ChangeValue(aNbSubIntervals+1) = theLast;
+
+    if(!aBS3DCurv.IsNull())
+    {
+      theNbParticles = Max(theNbParticles, aBS3DCurv->Degree());
+    }
+
+    if(!aBS2DCurv.IsNull())
+    {
+      theNbParticles = Max(theNbParticles, aBS2DCurv->Degree());
+    }
+  }
+  catch(Standard_Failure)
+  {
+#ifdef OCCT_DEBUG
+    cout << "ERROR! BRepLib_CheckCurveOnSurface.cxx, "
+            "FillSubIntervals(): Incorrect filling!" << endl;
+#endif
+
+    aNbSubIntervals = 0;
+  }
+
+  return aNbSubIntervals;
+}
+
+//=======================================================================
+//class   : MinComputing
+//purpose : Performs computing minimal value
+//=======================================================================
+Standard_Boolean MinComputing (
+                GeomLib_CheckCurveOnSurface_TargetFunc& theFunction,
+                const Standard_Real theEpsilon, //1.0e-3
+                const Standard_Integer theNbParticles,
+                Standard_Real& theBestValue,
+                Standard_Real& theBestParameter)
+{
+  try
+  {
+    OCC_CATCH_SIGNALS
+
+    //They are used for finding a position of theNbParticles worst places
+    const Standard_Integer aNbControlPoints = 3*theNbParticles;
+    //
+    math_Vector aParInf(1, 1), aParSup(1, 1), anOutputParam(1, 1), aStepPar(1,1);
+    aParInf(1) = theFunction.FirstParameter();
+    aParSup(1) = theFunction.LastParameter();
+    theBestParameter = aParInf(1);
+    theBestValue = RealLast();
+
+    const Standard_Real aDeltaParam = aParSup(1) - aParInf(1);
+    if(aDeltaParam < Precision::PConfusion())
+        return Standard_False;
+
+    aStepPar(1) = theEpsilon*aDeltaParam;
+
+    math_PSOParticlesPool aParticles(theNbParticles, 1);
+
+    const Standard_Real aStep = aDeltaParam/(aNbControlPoints-1);
+    Standard_Integer aCount = 1;
+    for(Standard_Real aPrm = aParInf(1); aCount <= aNbControlPoints; aCount++,
+                      aPrm = (aCount == aNbControlPoints)? aParSup(1) : aPrm+aStep)
+    {
+      Standard_Real aVal = RealLast();
+      theFunction.Value(aPrm, aVal);
+
+      PSO_Particle* aParticle = aParticles.GetWorstParticle();
+
+      if(aVal > aParticle->BestDistance)
+        continue;
+
+      aParticle->Position[0] = aPrm;
+      aParticle->BestPosition[0] = aPrm;
+      aParticle->Distance     = aVal;
+      aParticle->BestDistance = aVal;
+    }
+
+    math_PSO aPSO(&theFunction, aParInf, aParSup, aStepPar);
+    aPSO.Perform(aParticles, theNbParticles, theBestValue, anOutputParam);
+
+    //Here, anOutputParam contains parameter, which is near to optimal.
+    //It needs to be more precise. Precision is made by math_NewtonMinimum.
+    math_NewtonMinimum anA(theFunction);
+    anA.Perform(theFunction, anOutputParam);
+
+    if(!anA.IsDone())
+    {
+#ifdef OCCT_DEBUG
+      cout << "BRepLib_CheckCurveOnSurface::Compute(): No solution found!" << endl;
+#endif
+      return Standard_False;
+    }
+
+    anA.Location(anOutputParam);
+    theBestParameter =  anOutputParam(1);
+    theBestValue = anA.Minimum();
+  }
+  catch(Standard_Failure)
+  {
+#ifdef OCCT_DEBUG
+    cout << "BRepLib_CheckCurveOnSurface.cxx: Exception in MinComputing()!" << endl;
+#endif
+    return Standard_False;
+  }
+
+  return Standard_True;
+}
diff --git a/src/GeomLib/GeomLib_CheckCurveOnSurface.hxx b/src/GeomLib/GeomLib_CheckCurveOnSurface.hxx
new file mode 100644 (file)
index 0000000..f0ff6ad
--- /dev/null
@@ -0,0 +1,117 @@
+// Created by: Nikolai BUKHALOV
+// Copyright (c) 2015 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _GeomLib_CheckCurveOnSurface_HeaderFile
+#define _GeomLib_CheckCurveOnSurface_HeaderFile
+
+#include <Geom_Curve.hxx>
+#include <Standard.hxx>
+
+class Geom_Surface;
+class Geom2d_Curve;
+
+//! Computes the max distance between 3D-curve and 2D-curve
+//! in some surface.
+class GeomLib_CheckCurveOnSurface 
+{
+public:
+
+  DEFINE_STANDARD_ALLOC
+
+  //! Default contructor
+  Standard_EXPORT GeomLib_CheckCurveOnSurface(void);
+  
+  //! Contructor
+  Standard_EXPORT GeomLib_CheckCurveOnSurface(const Handle(Geom_Curve)& theCurve, 
+                                              const Handle(Geom_Surface)& theSurface, 
+                                              const Standard_Real theFirst, 
+                                              const Standard_Real theLast);
+  
+  //! Sets the data for the algorithm
+  Standard_EXPORT void Init (const Handle(Geom_Curve)& theCurve, 
+                             const Handle(Geom_Surface)& theSurface, 
+                             const Standard_Real theFirst, 
+                             const Standard_Real theLast);
+
+  //! Initializes all members by dafault values
+  Standard_EXPORT void Init();
+
+  //! Computes the max distance for the 3d curve <myCurve>
+  //! and 2d curve <thePCurve>
+  //! If isTheMultyTheadDisabled == TRUE then computation will be made
+  //! without any parallelization.
+  Standard_EXPORT void Perform(const Handle(Geom2d_Curve)& thePCurve, 
+                               const Standard_Boolean isTheMultyTheradDisabled = Standard_False);
+
+  //! Returns my3DCurve
+  const Handle(Geom_Curve)& Curve() const
+  {
+    return myCurve;
+  }  
+
+  //! Returns mySurface
+  const Handle(Geom_Surface)& Surface() const
+  {
+    return mySurface;
+  }
+  
+  //! Returns first and last parameter of the curves
+  //! (2D- and 3D-curves are considered to have same range)
+  void Range (Standard_Real& theFirst, Standard_Real& theLast)
+  {
+    theFirst = myFirst;
+    theLast  = myLast;
+  }
+
+  //! Returns true if the max distance has been found
+  Standard_Boolean IsDone() const
+  {
+    return (myErrorStatus == 0);
+  }
+  
+  //! Returns error status
+  //! The possible values are:
+  //! 0 - OK;
+  //! 1 - null curve or surface or 2d curve;
+  //! 2 - invalid parametric range;
+  //! 3 - error in calculations.
+  Standard_Integer ErrorStatus() const
+  {
+    return myErrorStatus;
+  }
+  
+  //! Returns max distance
+  Standard_Real MaxDistance() const
+  {
+    return myMaxDistance;
+  }
+  
+  //! Returns parameter in which the distance is maximal
+  Standard_Real MaxParameter() const
+  {
+    return myMaxParameter;
+  }
+
+private:
+
+  Handle(Geom_Curve) myCurve;
+  Handle(Geom_Surface) mySurface;
+  Standard_Real myFirst;
+  Standard_Real myLast;
+  Standard_Integer myErrorStatus;
+  Standard_Real myMaxDistance;
+  Standard_Real myMaxParameter;
+};
+
+#endif // _BRepLib_CheckCurveOnSurface_HeaderFile
index bb32173844f152044b6a293c394f749b8b4c0c51..c6579f443b04bb914e68e0b0e277545eaea8440d 100755 (executable)
@@ -1,5 +1,7 @@
 #E6----------------------------------------------
-puts "TODO OCC22803 ALL: Faulty shapes in variables faulty_1 to faulty_"
+#puts "TODO OCC22803 ALL: Faulty shapes in variables faulty_1 to faulty_"
+puts "TODO OCC26426 ALL: Error: The tolerance of the resulting shape is too big "
+
 
 ptorus pt 25 24 90
 profile pr o 20 18 5  p 0 -1 0 1 0 0 l 10 t 0 30 \
index 068e4c6946490d579d075d3e896c36d88a91ddc6..7ce428eee4891bb639b46d0e87a2e167b24dd38c 100644 (file)
@@ -1,5 +1,5 @@
 #C5----------------------------------------------
-puts "TODO OCC22803 All:Faulty shapes in variables faulty_1 to faulty_6"
+puts "TODO OCC22803 All:Faulty shapes in variables faulty_1 to faulty_"
 
 plane ps 10 -3 0  1 0 0  0 .2 1
 psphere ps ps 20
index 9f0420c7159239a7eac4f365b7ea82a3ea8de7e6..7c6034450767bf491fae4ba48f3427ff5b5ec9af 100644 (file)
@@ -1,5 +1,5 @@
 #D3---------------------------------------------
-puts "TODO OCC22803 All:Faulty shapes in variables faulty_1 to faulty_6"
+puts "TODO OCC22803 All:Faulty shapes in variables faulty_1 to faulty_"
 
 plane pt 0 0 0 1 0 0
 ptorus pt pt 9 7
index 264566958f4c19a972ba430bf0a9d11fc3a3931c..ba4bd0cb83e9acb8f6d8d84372994971ebd1fec9 100644 (file)
@@ -1,8 +1,9 @@
 # Original bug : pro12877
 # Date : 02 Dec 98
 
-puts "TODO OCC22803 All: Error: The tolerance of the resulting shape is too big"
+#puts "TODO OCC22803 All: Error: The tolerance of the resulting shape is too big"
 #puts "TODO OCC23511 Debian60-64: The area of the resulting shape is 186543"
+puts "TODO OCC26426 All: Faulty shapes in variables faulty_1 to faulty_"
 
 restore [locate_data_file CFE903_pro12ggx.rle] base
 
index 9b556461533953b1afd090c5e2203d988b1aced1..993347f5a274de9c0a50ba0eaabb691bd7670f2e 100644 (file)
@@ -1,7 +1,7 @@
 # Original bug : pro16449
 # Date : 18 Dec 98
 
-puts "TODO OCC22803 All:Faulty shapes in variables faulty_1 to faulty_4"
+puts "TODO OCC22803 All:Faulty shapes in variables faulty_1 to faulty_"
 
 restore [locate_data_file CFE903_pro16gha.rle] base