0025068: ShapeAnalysis_FreeBounds::ConnectEdgesToWires returns wires with not valid...
authorifv <ifv@opencascade.com>
Thu, 4 Sep 2014 10:07:04 +0000 (14:07 +0400)
committerbugmaster <bugmaster@opencascade.com>
Thu, 4 Sep 2014 10:08:15 +0000 (14:08 +0400)
Test case for issue CR25068

src/ShapeAnalysis/ShapeAnalysis_FreeBounds.cxx
src/ShapeBuild/ShapeBuild_Edge.cxx
tests/bugs/heal/bug25068 [new file with mode: 0755]
tests/heal/data/advanced/H5

index 77385fa..6ed060a 100644 (file)
@@ -199,6 +199,15 @@ ShapeAnalysis_FreeBounds::ShapeAnalysis_FreeBounds(const TopoDS_Shape& shape,
   Handle(ShapeExtend_WireData)
     sewd = new ShapeExtend_WireData (TopoDS::Wire (arrwires->Value (1)));
 
+  Standard_Boolean isUsedManifoldMode = Standard_True;
+
+  if((sewd->NbEdges() < 1) && (sewd->NbNonManifoldEdges() > 0))
+  {
+    isUsedManifoldMode = Standard_False;
+    sewd = new ShapeExtend_WireData (TopoDS::Wire (arrwires->Value (1)), Standard_True,
+                                     isUsedManifoldMode);
+  }
+
   Handle(ShapeAnalysis_Wire) saw = new ShapeAnalysis_Wire;
   saw->Load (sewd);
   saw->SetPrecision (tolerance);
@@ -227,12 +236,6 @@ ShapeAnalysis_FreeBounds::ShapeAnalysis_FreeBounds(const TopoDS_Shape& shape,
   ShapeAnalysis_Edge sae; //szv#4:S4163:12Mar99 moved
   Standard_Boolean done = Standard_False;
 
-  Standard_Boolean isUsedManifoldMode = Standard_True;
-
-  if((sewd->NbEdges() < 1) && (sewd->NbNonManifoldEdges() > 0))
-  {
-    isUsedManifoldMode = Standard_False;
-  }
   
   while (!done)
   {
@@ -241,10 +244,8 @@ ShapeAnalysis_FreeBounds::ShapeAnalysis_FreeBounds(const TopoDS_Shape& shape,
     aSel.SetStop();
     Bnd_Box FVBox, LVBox;
     TopoDS_Vertex Vf, Vl;
-    Vf = isUsedManifoldMode ? sae.FirstVertex(sewd->Edge(1)) : 
-      sae.FirstVertex(sewd->NonmanifoldEdge(1));
-    Vl = isUsedManifoldMode ? sae.LastVertex(sewd->Edge(sewd->NbEdges())) :
-      sae.LastVertex(sewd->NonmanifoldEdge(sewd->NbNonManifoldEdges()));
+    Vf = sae.FirstVertex(sewd->Edge(1));
+    Vl = sae.LastVertex(sewd->Edge(sewd->NbEdges()));
 
     gp_Pnt pf, pl;
     pf = BRep_Tool::Pnt(Vf);
@@ -284,7 +285,7 @@ ShapeAnalysis_FreeBounds::ShapeAnalysis_FreeBounds(const TopoDS_Shape& shape,
 
       TopoDS_Wire aCurW = TopoDS::Wire (arrwires->Value (lwire));
       Handle(ShapeExtend_WireData) acurwd = new 
-        ShapeExtend_WireData ( TopoDS::Wire (arrwires->Value (lwire)));
+        ShapeExtend_WireData ( TopoDS::Wire (arrwires->Value (lwire)), Standard_True, isUsedManifoldMode);
       sewd->Add (acurwd, (tail ? 0 : 1));
     }
     else
@@ -328,11 +329,42 @@ ShapeAnalysis_FreeBounds::ShapeAnalysis_FreeBounds(const TopoDS_Shape& shape,
 
       //2.making wire
       TopoDS_Wire wire = sewd->Wire();
-      if (!saw->CheckConnected (1) && saw->LastCheckStatus (ShapeExtend_OK))
-        wire.Closed (Standard_True);
+      if(isUsedManifoldMode)
+      {
+        if (!saw->CheckConnected (1) && saw->LastCheckStatus (ShapeExtend_OK))
+          wire.Closed (Standard_True);
+      }
+      else
+      {
+        //Try to check connection by number of free vertices
+        TopTools_MapOfShape vmap;
+        TopoDS_Iterator it(wire);
+
+        for(; it.More(); it.Next())
+        {
+          const TopoDS_Shape& E = it.Value();
+          TopoDS_Iterator ite(E, Standard_False, Standard_True);
+          for(; ite.More(); ite.Next())
+          {
+            const TopoDS_Shape& V = ite.Value();
+            if (V.Orientation() == TopAbs_FORWARD ||
+                V.Orientation() == TopAbs_REVERSED)
+            {
+              // add or remove in the vertex map
+              if (!vmap.Add(V)) vmap.Remove(V);
+            }
+          }
+
+        }
+        if(vmap.IsEmpty())
+        {
+          wire.Closed(Standard_True);
+        }
+      }
 
       owires->Append (wire);
       sewd->Clear();
+      sewd->ManifoldMode() = isUsedManifoldMode;
         
       // Recherche de la premier edge non traitee pour un autre wire.
       //Searching for first edge for next wire
index 6a334a6..197c1c0 100644 (file)
 //=======================================================================
 
 TopoDS_Edge ShapeBuild_Edge::CopyReplaceVertices (const TopoDS_Edge& edge,
-                                                 const TopoDS_Vertex& V1,
-                                                 const TopoDS_Vertex& V2) const
+  const TopoDS_Vertex& V1,
+  const TopoDS_Vertex& V2) const
 {
   TopTools_SequenceOfShape aNMVertices;
   TopoDS_Vertex newV1 = V1, newV2 = V2;
   if ( newV1.IsNull() || newV2.IsNull() ) {
-    for ( TopoDS_Iterator it(edge); it.More(); it.Next() ) {
+    TopoDS_Iterator it;
+    if(edge.Orientation() == TopAbs_FORWARD ||
+       edge.Orientation() == TopAbs_REVERSED)
+    {
+      it.Initialize(edge, Standard_True, Standard_True);
+    }
+    else
+    {
+      it.Initialize(edge, Standard_False, Standard_True);
+    }
+    for ( ; it.More(); it.Next() ) {
       TopoDS_Vertex V = TopoDS::Vertex ( it.Value() );
       if ( V.Orientation() == TopAbs_FORWARD ) {
-       if ( newV1.IsNull() ) newV1 = V;
+        if ( newV1.IsNull() ) newV1 = V;
       }
       else if ( V.Orientation() == TopAbs_REVERSED ) {
-       if ( newV2.IsNull() ) newV2 = V;
+        if ( newV2.IsNull() ) newV2 = V;
       }
       else if(V1.IsNull() && V2.IsNull())
-       aNMVertices.Append(V);
+        aNMVertices.Append(V);
     }
   }
   newV1.Orientation ( TopAbs_FORWARD );
@@ -82,7 +92,7 @@ TopoDS_Edge ShapeBuild_Edge::CopyReplaceVertices (const TopoDS_Edge& edge,
   //szv#4:S4163:12Mar99 SGI warns
   TopoDS_Shape sh = edge.EmptyCopied();
   TopoDS_Edge E = TopoDS::Edge( sh );
-  
+
   BRep_Builder B;
   if ( ! newV1.IsNull() ) B.Add ( E, newV1 );
   if ( ! newV2.IsNull() ) B.Add ( E, newV2 );
@@ -91,23 +101,23 @@ TopoDS_Edge ShapeBuild_Edge::CopyReplaceVertices (const TopoDS_Edge& edge,
   Standard_Integer i =1; 
   for( ; i <= aNMVertices.Length(); i++)
     B.Add ( E,TopoDS::Vertex(aNMVertices.Value(i)));
-  
+
   //S4054, rln 17.11.98 annie_surf.igs entity D77, 3D and pcurve have different
   //ranges, after B.Range all the ranges become as 3D
   CopyRanges ( E, edge );
-/*
+  /*
   for (BRep_ListIteratorOfListOfCurveRepresentation itcr
-    ((*((Handle(BRep_TEdge)*)&edge.TShape()))->ChangeCurves()); itcr.More(); itcr.Next()) {
-    Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
-    if ( GC.IsNull() ) continue;
-    Standard_Real first, last;
-    GC->Range ( first, last );
-    if ( GC->IsCurve3D() ) 
-      B.Range ( E, first, last );
-    else if ( GC->IsCurveOnSurface() )
-      B.Range (E, GC->Surface(), edge.Location().Multiplied (GC->Location()), first, last);//BUC50003 entity 132 edge 1
+  ((*((Handle(BRep_TEdge)*)&edge.TShape()))->ChangeCurves()); itcr.More(); itcr.Next()) {
+  Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
+  if ( GC.IsNull() ) continue;
+  Standard_Real first, last;
+  GC->Range ( first, last );
+  if ( GC->IsCurve3D() ) 
+  B.Range ( E, first, last );
+  else if ( GC->IsCurveOnSurface() )
+  B.Range (E, GC->Surface(), edge.Location().Multiplied (GC->Location()), first, last);//BUC50003 entity 132 edge 1
   }
-*/
+  */
   return E;
 }
 
@@ -118,8 +128,8 @@ TopoDS_Edge ShapeBuild_Edge::CopyReplaceVertices (const TopoDS_Edge& edge,
 
 // Added, cause invoke ShapeAnalysis leads to cyclic dependancy.
 static Standard_Real AdjustByPeriod(const Standard_Real Val,
-                                    const Standard_Real ToVal,
-                                    const Standard_Real Period)
+  const Standard_Real ToVal,
+  const Standard_Real Period)
 {
   Standard_Real diff = Val - ToVal;
   Standard_Real D = Abs ( diff );
@@ -136,11 +146,11 @@ static Standard_Boolean IsPeriodic(const Handle(Geom_Curve)& theCurve)
   // ask IsPeriodic on BasisCurve
   Handle(Geom_Curve) aTmpCurve = theCurve;
   while ( (aTmpCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) ||
-          (aTmpCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) ) {
-    if (aTmpCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)))
-      aTmpCurve = Handle(Geom_OffsetCurve)::DownCast(aTmpCurve)->BasisCurve();
-    if (aTmpCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
-      aTmpCurve = Handle(Geom_TrimmedCurve)::DownCast(aTmpCurve)->BasisCurve();
+    (aTmpCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) ) {
+      if (aTmpCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)))
+        aTmpCurve = Handle(Geom_OffsetCurve)::DownCast(aTmpCurve)->BasisCurve();
+      if (aTmpCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
+        aTmpCurve = Handle(Geom_TrimmedCurve)::DownCast(aTmpCurve)->BasisCurve();
   }
   return aTmpCurve->IsPeriodic();
 }
@@ -152,103 +162,103 @@ Standard_Boolean IsPeriodic(const Handle(Geom2d_Curve)& theCurve)
   // ask IsPeriodic on BasisCurve
   Handle(Geom2d_Curve) aTmpCurve = theCurve;
   while ( (aTmpCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))) ||
-          (aTmpCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) ) {
-    if (aTmpCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve)))
-      aTmpCurve = Handle(Geom2d_OffsetCurve)::DownCast(aTmpCurve)->BasisCurve();
-    if (aTmpCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
-      aTmpCurve = Handle(Geom2d_TrimmedCurve)::DownCast(aTmpCurve)->BasisCurve();
+    (aTmpCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) ) {
+      if (aTmpCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve)))
+        aTmpCurve = Handle(Geom2d_OffsetCurve)::DownCast(aTmpCurve)->BasisCurve();
+      if (aTmpCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
+        aTmpCurve = Handle(Geom2d_TrimmedCurve)::DownCast(aTmpCurve)->BasisCurve();
   }
   return aTmpCurve->IsPeriodic();
 }
 
 void ShapeBuild_Edge::CopyRanges (const TopoDS_Edge& toedge, 
-                                 const TopoDS_Edge& fromedge,
-                                 const Standard_Real alpha,
-                                 const Standard_Real beta) const
+  const TopoDS_Edge& fromedge,
+  const Standard_Real alpha,
+  const Standard_Real beta) const
 {
-/*  BRep_Builder B;
-    for (BRep_ListIteratorOfListOfCurveRepresentation itcr
-    ((*((Handle(BRep_TEdge)*)&fromedge.TShape()))->ChangeCurves()); itcr.More(); itcr.Next()) {
-    Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
-    if ( GC.IsNull() ) continue;
-    Standard_Real first, last;
-    GC->Range ( first, last );
-    if ( GC->IsCurve3D() ) 
-      B.Range ( toedge, first, last );
-    else if ( GC->IsCurveOnSurface() )
-      B.Range ( toedge, GC->Surface(), fromedge.Location().Multiplied (GC->Location()), first, last);
+  /*  BRep_Builder B;
+  for (BRep_ListIteratorOfListOfCurveRepresentation itcr
+  ((*((Handle(BRep_TEdge)*)&fromedge.TShape()))->ChangeCurves()); itcr.More(); itcr.Next()) {
+  Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
+  if ( GC.IsNull() ) continue;
+  Standard_Real first, last;
+  GC->Range ( first, last );
+  if ( GC->IsCurve3D() ) 
+  B.Range ( toedge, first, last );
+  else if ( GC->IsCurveOnSurface() )
+  B.Range ( toedge, GC->Surface(), fromedge.Location().Multiplied (GC->Location()), first, last);
   }
-*/
+  */
   for (BRep_ListIteratorOfListOfCurveRepresentation fromitcr
-       ((*((Handle(BRep_TEdge)*)&fromedge.TShape()))->ChangeCurves()); fromitcr.More(); fromitcr.Next()) {
-    Handle(BRep_GCurve) fromGC = Handle(BRep_GCurve)::DownCast(fromitcr.Value());
-    if ( fromGC.IsNull() ) continue;
-    Standard_Boolean isC3d = fromGC->IsCurve3D();
-    if(isC3d) {
-      if(fromGC->Curve3D().IsNull()) continue; }
-    else {
-       if(fromGC->PCurve().IsNull()) continue; }
-      
-    if ( ! isC3d && ! fromGC->IsCurveOnSurface()) continue; // only 3d curves and pcurves are treated
-
-    Handle(Geom_Surface) surface;
-    TopLoc_Location L;
-    if ( ! isC3d ) {
-      surface = fromGC->Surface();
-      L = fromGC->Location();
-    } 
+    ((*((Handle(BRep_TEdge)*)&fromedge.TShape()))->ChangeCurves()); fromitcr.More(); fromitcr.Next()) {
+      Handle(BRep_GCurve) fromGC = Handle(BRep_GCurve)::DownCast(fromitcr.Value());
+      if ( fromGC.IsNull() ) continue;
+      Standard_Boolean isC3d = fromGC->IsCurve3D();
+      if(isC3d) {
+        if(fromGC->Curve3D().IsNull()) continue; }
+      else {
+        if(fromGC->PCurve().IsNull()) continue; }
+
+      if ( ! isC3d && ! fromGC->IsCurveOnSurface()) continue; // only 3d curves and pcurves are treated
+
+      Handle(Geom_Surface) surface;
+      TopLoc_Location L;
+      if ( ! isC3d ) {
+        surface = fromGC->Surface();
+        L = fromGC->Location();
+      } 
 
-    BRep_ListOfCurveRepresentation& tolist = (*((Handle(BRep_TEdge)*)&toedge.TShape()))->ChangeCurves();
-    Handle(BRep_GCurve) toGC;
-    for (BRep_ListIteratorOfListOfCurveRepresentation toitcr (tolist); toitcr.More(); toitcr.Next()) {
-      toGC = Handle(BRep_GCurve)::DownCast(toitcr.Value());
-      if ( toGC.IsNull() ) continue;
-      if ( isC3d ) {
-       if ( ! toGC->IsCurve3D() ) continue;
-      }
-      else if ( ! toGC->IsCurveOnSurface() || 
-              surface != toGC->Surface() || L != toGC->Location() ) continue;
-      Standard_Real first = fromGC->First();
-      Standard_Real last = fromGC->Last();
-      Standard_Real len = last - first;
-      Standard_Real newF = first+alpha*len;
-      Standard_Real newL = first+beta*len;
-
-      // PTV: 22.03.2002 fix for edge range. 
-      // file test-m020306-v2.step Shell #665 (Faces #40110. #40239).
-      Standard_Real aPeriod=1., aCrvF=0., aCrvL=1.;
-      Standard_Boolean doCheck = Standard_False;
-      if (toGC->IsKind(STANDARD_TYPE(BRep_Curve3D))) {
-        Handle(Geom_Curve) aCrv3d = Handle(BRep_Curve3D)::DownCast(toGC)->Curve3D();
-        // 15.11.2002 PTV OCC966
-        if ( ! aCrv3d.IsNull() && IsPeriodic(aCrv3d) ) {
-          aPeriod = aCrv3d->Period();
-          aCrvF = aCrv3d->FirstParameter();
-          aCrvL = aCrv3d->LastParameter();
-          doCheck = Standard_True;
+      BRep_ListOfCurveRepresentation& tolist = (*((Handle(BRep_TEdge)*)&toedge.TShape()))->ChangeCurves();
+      Handle(BRep_GCurve) toGC;
+      for (BRep_ListIteratorOfListOfCurveRepresentation toitcr (tolist); toitcr.More(); toitcr.Next()) {
+        toGC = Handle(BRep_GCurve)::DownCast(toitcr.Value());
+        if ( toGC.IsNull() ) continue;
+        if ( isC3d ) {
+          if ( ! toGC->IsCurve3D() ) continue;
         }
-      }
-      else if  (toGC->IsKind(STANDARD_TYPE(BRep_CurveOnSurface))) {
-        Handle(Geom2d_Curve) aCrv2d = Handle(BRep_CurveOnSurface)::DownCast(toGC)->PCurve();
-        // 15.11.2002 PTV OCC966
-        if (!aCrv2d.IsNull() && IsPeriodic(aCrv2d)) {
-          aPeriod = aCrv2d->Period();
-          aCrvF = aCrv2d->FirstParameter();
-          aCrvL = aCrv2d->LastParameter();
-          doCheck = Standard_True;
+        else if ( ! toGC->IsCurveOnSurface() || 
+          surface != toGC->Surface() || L != toGC->Location() ) continue;
+        Standard_Real first = fromGC->First();
+        Standard_Real last = fromGC->Last();
+        Standard_Real len = last - first;
+        Standard_Real newF = first+alpha*len;
+        Standard_Real newL = first+beta*len;
+
+        // PTV: 22.03.2002 fix for edge range. 
+        // file test-m020306-v2.step Shell #665 (Faces #40110. #40239).
+        Standard_Real aPeriod=1., aCrvF=0., aCrvL=1.;
+        Standard_Boolean doCheck = Standard_False;
+        if (toGC->IsKind(STANDARD_TYPE(BRep_Curve3D))) {
+          Handle(Geom_Curve) aCrv3d = Handle(BRep_Curve3D)::DownCast(toGC)->Curve3D();
+          // 15.11.2002 PTV OCC966
+          if ( ! aCrv3d.IsNull() && IsPeriodic(aCrv3d) ) {
+            aPeriod = aCrv3d->Period();
+            aCrvF = aCrv3d->FirstParameter();
+            aCrvL = aCrv3d->LastParameter();
+            doCheck = Standard_True;
+          }
         }
+        else if  (toGC->IsKind(STANDARD_TYPE(BRep_CurveOnSurface))) {
+          Handle(Geom2d_Curve) aCrv2d = Handle(BRep_CurveOnSurface)::DownCast(toGC)->PCurve();
+          // 15.11.2002 PTV OCC966
+          if (!aCrv2d.IsNull() && IsPeriodic(aCrv2d)) {
+            aPeriod = aCrv2d->Period();
+            aCrvF = aCrv2d->FirstParameter();
+            aCrvL = aCrv2d->LastParameter();
+            doCheck = Standard_True;
+          }
+        }
+        if ( doCheck && ( (fabs(newF -aCrvF ) > Precision::PConfusion() && newF < aCrvF) || newF >= aCrvL ) ) {
+          Standard_Real aShift = AdjustByPeriod(newF, 0.5*(aCrvF+aCrvL), aPeriod);
+          newF += aShift;
+          newL += aShift;
+          BRep_Builder().SameRange(toedge,Standard_False);
+          BRep_Builder().SameParameter(toedge,Standard_False);
+        }
+
+        toGC->SetRange ( newF, newL );
+        break;
       }
-      if ( doCheck && ( (fabs(newF -aCrvF ) > Precision::PConfusion() && newF < aCrvF) || newF >= aCrvL ) ) {
-        Standard_Real aShift = AdjustByPeriod(newF, 0.5*(aCrvF+aCrvL), aPeriod);
-        newF += aShift;
-        newL += aShift;
-        BRep_Builder().SameRange(toedge,Standard_False);
-        BRep_Builder().SameParameter(toedge,Standard_False);
-      }
-      
-      toGC->SetRange ( newF, newL );
-      break;
-    }
   }
 }
 
@@ -258,16 +268,16 @@ void ShapeBuild_Edge::CopyRanges (const TopoDS_Edge& toedge,
 //=======================================================================
 
 void ShapeBuild_Edge::SetRange3d (const TopoDS_Edge& edge, 
-                                 const Standard_Real first,
-                                 const Standard_Real last) const
+  const Standard_Real first,
+  const Standard_Real last) const
 {
 
   for (BRep_ListIteratorOfListOfCurveRepresentation itcr
-       ((*((Handle(BRep_TEdge)*)&edge.TShape()))->ChangeCurves()); itcr.More(); itcr.Next()) {
-    Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
-    if ( GC.IsNull() || !GC->IsCurve3D() ) continue;
-    GC->SetRange ( first, last );
-    break;
+    ((*((Handle(BRep_TEdge)*)&edge.TShape()))->ChangeCurves()); itcr.More(); itcr.Next()) {
+      Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
+      if ( GC.IsNull() || !GC->IsCurve3D() ) continue;
+      GC->SetRange ( first, last );
+      break;
   }
 }
 
@@ -282,36 +292,36 @@ void ShapeBuild_Edge::CopyPCurves (const TopoDS_Edge& toedge, const TopoDS_Edge&
   TopLoc_Location toLoc = toedge.Location();
   for (BRep_ListIteratorOfListOfCurveRepresentation fromitcr
     ((*((Handle(BRep_TEdge)*)&fromedge.TShape()))->ChangeCurves()); fromitcr.More(); fromitcr.Next()) {
-    Handle(BRep_GCurve) fromGC = Handle(BRep_GCurve)::DownCast(fromitcr.Value());
-    if ( fromGC.IsNull() ) continue;
-    if ( fromGC->IsCurveOnSurface() ) {
-      Handle(Geom_Surface) surface = fromGC->Surface();
-      TopLoc_Location L = fromGC->Location();
-      Standard_Boolean found = Standard_False;
-      BRep_ListOfCurveRepresentation& tolist = (*((Handle(BRep_TEdge)*)&toedge.TShape()))->ChangeCurves();
-      Handle(BRep_GCurve) toGC;
-      for (BRep_ListIteratorOfListOfCurveRepresentation toitcr (tolist); toitcr.More() && !found; toitcr.Next()) {
-       toGC = Handle(BRep_GCurve)::DownCast(toitcr.Value());
-       if ( toGC.IsNull() || !toGC->IsCurveOnSurface() || 
-            surface != toGC->Surface() || L != toGC->Location() ) continue;
-       found = Standard_True;
-       break;
-      }
-      if (!found) {
-       toGC = Handle(BRep_GCurve)::DownCast(fromGC->Copy());
-       tolist.Append (toGC);
-      }
-      Handle(Geom2d_Curve) pcurve = fromGC->PCurve();
-      toGC->PCurve(Handle(Geom2d_Curve)::DownCast(pcurve->Copy()));
-      
-      //bug OCC209 invalid location of pcurve in the edge after copying
-      TopLoc_Location newLoc = (fromLoc*L).Predivided(toLoc);//(L * fromLoc).Predivided(toLoc);
-      toGC->Location(newLoc);
-      if ( fromGC->IsCurveOnClosedSurface() ) {
-        pcurve = fromGC->PCurve2();
-        toGC->PCurve2(Handle(Geom2d_Curve)::DownCast(pcurve->Copy()));
+      Handle(BRep_GCurve) fromGC = Handle(BRep_GCurve)::DownCast(fromitcr.Value());
+      if ( fromGC.IsNull() ) continue;
+      if ( fromGC->IsCurveOnSurface() ) {
+        Handle(Geom_Surface) surface = fromGC->Surface();
+        TopLoc_Location L = fromGC->Location();
+        Standard_Boolean found = Standard_False;
+        BRep_ListOfCurveRepresentation& tolist = (*((Handle(BRep_TEdge)*)&toedge.TShape()))->ChangeCurves();
+        Handle(BRep_GCurve) toGC;
+        for (BRep_ListIteratorOfListOfCurveRepresentation toitcr (tolist); toitcr.More() && !found; toitcr.Next()) {
+          toGC = Handle(BRep_GCurve)::DownCast(toitcr.Value());
+          if ( toGC.IsNull() || !toGC->IsCurveOnSurface() || 
+            surface != toGC->Surface() || L != toGC->Location() ) continue;
+          found = Standard_True;
+          break;
+        }
+        if (!found) {
+          toGC = Handle(BRep_GCurve)::DownCast(fromGC->Copy());
+          tolist.Append (toGC);
+        }
+        Handle(Geom2d_Curve) pcurve = fromGC->PCurve();
+        toGC->PCurve(Handle(Geom2d_Curve)::DownCast(pcurve->Copy()));
+
+        //bug OCC209 invalid location of pcurve in the edge after copying
+        TopLoc_Location newLoc = (fromLoc*L).Predivided(toLoc);//(L * fromLoc).Predivided(toLoc);
+        toGC->Location(newLoc);
+        if ( fromGC->IsCurveOnClosedSurface() ) {
+          pcurve = fromGC->PCurve2();
+          toGC->PCurve2(Handle(Geom2d_Curve)::DownCast(pcurve->Copy()));
+        }
       }
-    }
   }
 }
 //=======================================================================
@@ -320,27 +330,27 @@ void ShapeBuild_Edge::CopyPCurves (const TopoDS_Edge& toedge, const TopoDS_Edge&
 //=======================================================================
 
 TopoDS_Edge ShapeBuild_Edge::Copy (const TopoDS_Edge &edge, 
-                                   const Standard_Boolean sharepcurves) const
+  const Standard_Boolean sharepcurves) const
 {
   TopoDS_Vertex dummy1, dummy2;
   TopoDS_Edge newedge = CopyReplaceVertices ( edge, dummy1, dummy2 );
   if ( ! sharepcurves ) CopyPCurves ( newedge, edge );
   return newedge;
 }
-     
+
 //=======================================================================
 //function : RemovePCurve
 //purpose  : 
 //=======================================================================
 
 void ShapeBuild_Edge::RemovePCurve (const TopoDS_Edge& edge, 
-                                    const TopoDS_Face& face) const
+  const TopoDS_Face& face) const
 {
   BRep_Builder B;
   Handle(Geom2d_Curve) c2dNull;
-//:S4136  Standard_Real tol = BRep_Tool::Tolerance ( edge );
+  //:S4136  Standard_Real tol = BRep_Tool::Tolerance ( edge );
   if ( BRep_Tool::IsClosed ( edge, face ) )
-       B.UpdateEdge ( edge, c2dNull, c2dNull, face, 0. ); //:S4136: tol
+    B.UpdateEdge ( edge, c2dNull, c2dNull, face, 0. ); //:S4136: tol
   else B.UpdateEdge ( edge, c2dNull,          face, 0. ); //:S4136: tol
 }
 
@@ -350,25 +360,25 @@ void ShapeBuild_Edge::RemovePCurve (const TopoDS_Edge& edge,
 //=======================================================================
 
 void ShapeBuild_Edge::RemovePCurve (const TopoDS_Edge& edge,
-                                    const Handle(Geom_Surface)& surf) const
+  const Handle(Geom_Surface)& surf) const
 {
   RemovePCurve ( edge, surf, TopLoc_Location() );
 }
-  
+
 //=======================================================================
 //function : RemovePCurve
 //purpose  : 
 //=======================================================================
 
 void ShapeBuild_Edge::RemovePCurve (const TopoDS_Edge& edge,
-                                    const Handle(Geom_Surface)& surf,
-                                    const TopLoc_Location &loc) const
+  const Handle(Geom_Surface)& surf,
+  const TopLoc_Location &loc) const
 {
   BRep_Builder B;
   Handle(Geom2d_Curve) c2dNull;
-//:S4136  Standard_Real tol = BRep_Tool::Tolerance ( edge );
+  //:S4136  Standard_Real tol = BRep_Tool::Tolerance ( edge );
   if ( BRep_Tool::IsClosed ( edge, surf, loc ) )
-       B.UpdateEdge ( edge, c2dNull, c2dNull, surf, loc, 0. ); //:S4136: tol
+    B.UpdateEdge ( edge, c2dNull, c2dNull, surf, loc, 0. ); //:S4136: tol
   else B.UpdateEdge ( edge, c2dNull,          surf, loc, 0. ); //:S4136: tol
 }
 
@@ -378,8 +388,8 @@ void ShapeBuild_Edge::RemovePCurve (const TopoDS_Edge& edge,
 //=======================================================================
 
 void ShapeBuild_Edge::ReplacePCurve (const TopoDS_Edge& edge,
-                                     const Handle(Geom2d_Curve)& pcurve,
-                                     const TopoDS_Face& face) const
+  const Handle(Geom2d_Curve)& pcurve,
+  const TopoDS_Face& face) const
 {
   BRep_Builder B;
   Standard_Real f,l;
@@ -411,24 +421,24 @@ void ShapeBuild_Edge::ReplacePCurve (const TopoDS_Edge& edge,
 // This makes difference for faces based on plane surfaces where pcurves can be 
 // not stored but returned by BRep_Tools::CurveOnSurface
 static Standard_Integer CountPCurves (const TopoDS_Edge &edge, 
-                                     const TopoDS_Face &face)
+  const TopoDS_Face &face)
 {
   TopLoc_Location L;
   Handle(Geom_Surface) S = BRep_Tool::Surface ( face, L );
   TopLoc_Location l = L.Predivided(edge.Location());
-  
+
   for (BRep_ListIteratorOfListOfCurveRepresentation itcr
     ((*((Handle(BRep_TEdge)*)&edge.TShape()))->ChangeCurves()); itcr.More(); itcr.Next()) {
-    Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
-    if ( ! GC.IsNull() && GC->IsCurveOnSurface ( S, l ) ) 
-      return ( GC->IsCurveOnClosedSurface() ? 2 : 1 );
+      Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
+      if ( ! GC.IsNull() && GC->IsCurveOnSurface ( S, l ) ) 
+        return ( GC->IsCurveOnClosedSurface() ? 2 : 1 );
   }
   return 0;
 }
 
 Standard_Boolean ShapeBuild_Edge::ReassignPCurve (const TopoDS_Edge& edge,
-                                                 const TopoDS_Face& old,
-                                                 const TopoDS_Face& sub) const
+  const TopoDS_Face& old,
+  const TopoDS_Face& sub) const
 {
   Standard_Integer npcurves = CountPCurves ( edge, old );
   //if ( npcurves <1 ) return Standard_False; //gka
@@ -438,8 +448,8 @@ Standard_Boolean ShapeBuild_Edge::ReassignPCurve (const TopoDS_Edge& edge,
   pc = BRep_Tool::CurveOnSurface ( edge, old, f, l );
   if ( pc.IsNull() ) return Standard_False;
   else if( npcurves == 0)  npcurves =1; //gka
-          
-          
+
+
   BRep_Builder B;
 
   // if the pcurve was only one, remove; else leave second one
@@ -452,23 +462,23 @@ Standard_Boolean ShapeBuild_Edge::ReassignPCurve (const TopoDS_Edge& edge,
     B.Range ( edge, old, f, l );
   }
   else RemovePCurve ( edge, old );
-  
+
   // if edge does not have yet pcurves on sub, just add; else add as first
   Standard_Integer npcs = CountPCurves ( edge, sub );
   if ( npcs <1 ) B.UpdateEdge ( edge, pc, sub, 0. );
   else {
-//smh#8 Porting AIX
+    //smh#8 Porting AIX
     TopoDS_Shape tmpshape = edge.Reversed();
     TopoDS_Edge erev = TopoDS::Edge (tmpshape);
     Standard_Real cf, cl;
     Handle(Geom2d_Curve) pcs = BRep_Tool::CurveOnSurface ( erev, sub, cf, cl );
     if ( edge.Orientation() == TopAbs_REVERSED ) // because B.UpdateEdge does not check edge orientation
-         B.UpdateEdge ( edge, pcs, pc, sub, 0. );
+      B.UpdateEdge ( edge, pcs, pc, sub, 0. );
     else B.UpdateEdge ( edge, pc, pcs, sub, 0. );
   }
-  
+
   B.Range ( edge, sub, f, l );
-  
+
   return Standard_True;
 }
 
@@ -478,10 +488,10 @@ Standard_Boolean ShapeBuild_Edge::ReassignPCurve (const TopoDS_Edge& edge,
 //=======================================================================
 
 Handle(Geom2d_Curve) ShapeBuild_Edge::TransformPCurve(const Handle(Geom2d_Curve)& pcurve,
-                                                     const gp_Trsf2d& trans,
-                                                     const Standard_Real uFact,
-                                                     Standard_Real& aFirst,
-                                                     Standard_Real& aLast) const
+  const gp_Trsf2d& trans,
+  const Standard_Real uFact,
+  Standard_Real& aFirst,
+  Standard_Real& aLast) const
 {
   Handle(Geom2d_Curve) result = Handle(Geom2d_Curve)::DownCast(pcurve->Copy());
   if(trans.Form()!=gp_Identity) {
@@ -496,11 +506,11 @@ Handle(Geom2d_Curve) ShapeBuild_Edge::TransformPCurve(const Handle(Geom2d_Curve)
     Handle(Geom2d_TrimmedCurve) thecurve = Handle(Geom2d_TrimmedCurve)::DownCast(result);
     result = thecurve->BasisCurve();
   }
-  
+
   gp_GTrsf2d  tMatu;
   tMatu.SetAffinity(gp::OY2d(), uFact);
   gp_XY  pXY;
-  
+
   if (result->IsKind(STANDARD_TYPE(Geom2d_Line))) {
     Handle(Geom2d_Line) aLine2d = Handle(Geom2d_Line)::DownCast(result);
     gp_Pnt2d Pf, Pl;
@@ -537,11 +547,11 @@ Handle(Geom2d_Curve) ShapeBuild_Edge::TransformPCurve(const Handle(Geom2d_Curve)
       //Handle(Geom_Curve) curve = GeomAPI::To3d(result,pln);
       Handle(Geom2d_TrimmedCurve) tcurve = new Geom2d_TrimmedCurve(result,aFirst,aLast); //protection agains parabols ets
       Geom2dConvert_ApproxCurve approx (tcurve, Precision::Approximation(), 
-                                      GeomAbs_C1, 100, 6 );
+        GeomAbs_C1, 100, 6 );
       if ( approx.HasResult() )
-       aBSpline2d = Handle(Geom2d_BSplineCurve)::DownCast(approx.Curve());
+        aBSpline2d = Handle(Geom2d_BSplineCurve)::DownCast(approx.Curve());
       else
-       aBSpline2d = Geom2dConvert::CurveToBSplineCurve(tcurve,Convert_QuasiAngular);
+        aBSpline2d = Geom2dConvert::CurveToBSplineCurve(tcurve,Convert_QuasiAngular);
       aFirst = aBSpline2d->FirstParameter();
       aLast =  aBSpline2d->LastParameter();
     } 
@@ -550,7 +560,7 @@ Handle(Geom2d_Curve) ShapeBuild_Edge::TransformPCurve(const Handle(Geom2d_Curve)
     }
     else
       aBSpline2d = Handle(Geom2d_BSplineCurve)::DownCast(result);
-      
+
     // transform the Poles of the BSplineCurve 
     Standard_Integer nbPol = aBSpline2d->NbPoles();
     gp_Pnt2d Pt1;
@@ -573,7 +583,7 @@ void ShapeBuild_Edge::RemoveCurve3d (const TopoDS_Edge& edge) const
 {
   BRep_Builder B;
   Handle(Geom_Curve) c3dNull;
-//:S4136  Standard_Real tol = BRep_Tool::Tolerance (edge);
+  //:S4136  Standard_Real tol = BRep_Tool::Tolerance (edge);
   B.UpdateEdge (edge, c3dNull, 0. ); //:S4136: tol
 }
 
@@ -586,42 +596,42 @@ Standard_Boolean ShapeBuild_Edge::BuildCurve3d (const TopoDS_Edge& edge) const
 {
   try {
     OCC_CATCH_SIGNALS
-   //#48 rln 10.12.98 S4054 UKI60107-5 entity 365
-    //C0 surface (but curve 3d is required as C1) and tolerance is 1e-07
-    //lets use maximum of tolerance and default parameter 1.e-5
-    //Another solutions: use quite big Tolerance or require C0 curve on C0 surface
-    if ( BRepLib::BuildCurve3d (edge, Max (1.e-5, BRep_Tool::Tolerance(edge) ) ) ) {
-      //#50 S4054 rln 14.12.98 write cylinder in BRep mode into IGES and read back
-      //with 2DUse_Forced - pcurve and removed 3D curves have different ranges
-      if (BRep_Tool::SameRange (edge)) {
-       Standard_Real first, last;
-       BRep_Tool::Range (edge, first, last);
-       BRep_Builder().Range (edge, first, last);//explicit setting for all reps
-      }
-      Handle(Geom_Curve) c3d;
-      Standard_Real f,l;
-      c3d = BRep_Tool::Curve(edge,f,l);
-      if (c3d.IsNull())
-        return Standard_False;
-      // 15.11.2002 PTV OCC966
-      if(!IsPeriodic(c3d)) {
-       Standard_Boolean isLess = Standard_False;
-       if(f < c3d->FirstParameter()) {
-         isLess = Standard_True;
-         f = c3d->FirstParameter();
-       }
-       if(l > c3d->LastParameter()) {
-         isLess = Standard_True;
-         l = c3d->LastParameter();
-       }
-       if(isLess) {
-         SetRange3d(edge,f,l);
-         BRep_Builder().SameRange(edge,Standard_False);
-       }
+      //#48 rln 10.12.98 S4054 UKI60107-5 entity 365
+      //C0 surface (but curve 3d is required as C1) and tolerance is 1e-07
+      //lets use maximum of tolerance and default parameter 1.e-5
+      //Another solutions: use quite big Tolerance or require C0 curve on C0 surface
+      if ( BRepLib::BuildCurve3d (edge, Max (1.e-5, BRep_Tool::Tolerance(edge) ) ) ) {
+        //#50 S4054 rln 14.12.98 write cylinder in BRep mode into IGES and read back
+        //with 2DUse_Forced - pcurve and removed 3D curves have different ranges
+        if (BRep_Tool::SameRange (edge)) {
+          Standard_Real first, last;
+          BRep_Tool::Range (edge, first, last);
+          BRep_Builder().Range (edge, first, last);//explicit setting for all reps
+        }
+        Handle(Geom_Curve) c3d;
+        Standard_Real f,l;
+        c3d = BRep_Tool::Curve(edge,f,l);
+        if (c3d.IsNull())
+          return Standard_False;
+        // 15.11.2002 PTV OCC966
+        if(!IsPeriodic(c3d)) {
+          Standard_Boolean isLess = Standard_False;
+          if(f < c3d->FirstParameter()) {
+            isLess = Standard_True;
+            f = c3d->FirstParameter();
+          }
+          if(l > c3d->LastParameter()) {
+            isLess = Standard_True;
+            l = c3d->LastParameter();
+          }
+          if(isLess) {
+            SetRange3d(edge,f,l);
+            BRep_Builder().SameRange(edge,Standard_False);
+          }
+        }
+
+        return Standard_True;
       }
-      
-      return Standard_True;
-    }
   }
   catch(Standard_Failure) {
 #ifdef DEB
@@ -638,7 +648,7 @@ Standard_Boolean ShapeBuild_Edge::BuildCurve3d (const TopoDS_Edge& edge) const
 //purpose  : 
 //=======================================================================
 
- void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom_Curve)& curve,const TopLoc_Location& L) const
+void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom_Curve)& curve,const TopLoc_Location& L) const
 {
   MakeEdge (edge,curve, L, curve->FirstParameter(), curve->LastParameter());
 }
@@ -648,7 +658,7 @@ Standard_Boolean ShapeBuild_Edge::BuildCurve3d (const TopoDS_Edge& edge) const
 //purpose  : 
 //=======================================================================
 
- void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom_Curve)& curve,const TopLoc_Location& L,const Standard_Real p1,const Standard_Real p2) const
+void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom_Curve)& curve,const TopLoc_Location& L,const Standard_Real p1,const Standard_Real p2) const
 {
   BRepBuilderAPI_MakeEdge ME (curve, p1, p2);
   if (!ME.IsDone()) {
@@ -662,7 +672,7 @@ Standard_Boolean ShapeBuild_Edge::BuildCurve3d (const TopoDS_Edge& edge) const
     BRep_Builder B;
     B.UpdateEdge (E, curve, L, 0.);
     B.Range (E, p1, p2);
-    
+
     TopoDS_Vertex V1, V2;
     TopExp::Vertices (E, V1, V2);
     gp_Pnt P1 = BRep_Tool::Pnt (V1), P2 = BRep_Tool::Pnt (V2);
@@ -678,7 +688,7 @@ Standard_Boolean ShapeBuild_Edge::BuildCurve3d (const TopoDS_Edge& edge) const
 //purpose  : 
 //=======================================================================
 
- void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom2d_Curve)& pcurve,const TopoDS_Face& face) const
+void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom2d_Curve)& pcurve,const TopoDS_Face& face) const
 {
   MakeEdge (edge, pcurve, face, pcurve->FirstParameter(), pcurve->LastParameter());
 }
@@ -688,7 +698,7 @@ Standard_Boolean ShapeBuild_Edge::BuildCurve3d (const TopoDS_Edge& edge) const
 //purpose  : 
 //=======================================================================
 
- void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom2d_Curve)& pcurve,const TopoDS_Face& face,const Standard_Real p1,const Standard_Real p2) const
+void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom2d_Curve)& pcurve,const TopoDS_Face& face,const Standard_Real p1,const Standard_Real p2) const
 {
   TopLoc_Location L;
   const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
@@ -700,8 +710,8 @@ Standard_Boolean ShapeBuild_Edge::BuildCurve3d (const TopoDS_Edge& edge) const
 //purpose  : 
 //=======================================================================
 
- void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom2d_Curve)& pcurve,
-                               const Handle(Geom_Surface)& S,const TopLoc_Location& L) const
+void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom2d_Curve)& pcurve,
+  const Handle(Geom_Surface)& S,const TopLoc_Location& L) const
 {
   MakeEdge(edge, pcurve, S, L, pcurve->FirstParameter(), pcurve->LastParameter());
 }
@@ -711,9 +721,9 @@ Standard_Boolean ShapeBuild_Edge::BuildCurve3d (const TopoDS_Edge& edge) const
 //purpose  : 
 //=======================================================================
 
- void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom2d_Curve)& pcurve,
-                               const Handle(Geom_Surface)& S,const TopLoc_Location& L,
-                               const Standard_Real p1,const Standard_Real p2) const
+void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom2d_Curve)& pcurve,
+  const Handle(Geom_Surface)& S,const TopLoc_Location& L,
+  const Standard_Real p1,const Standard_Real p2) const
 {
   BRepBuilderAPI_MakeEdge ME (pcurve, S, p1, p2);
   if (!ME.IsDone()) {
@@ -728,7 +738,7 @@ Standard_Boolean ShapeBuild_Edge::BuildCurve3d (const TopoDS_Edge& edge) const
     BRep_Builder B;
     B.UpdateEdge (E, pcurve, S, L, 0.);
     B.Range (E, S, L, p1, p2);
-    
+
     TopoDS_Vertex V1, V2;
     TopExp::Vertices (E, V1, V2);
     gp_Pnt P1 = BRep_Tool::Pnt (V1), P2 = BRep_Tool::Pnt (V2);
diff --git a/tests/bugs/heal/bug25068 b/tests/bugs/heal/bug25068
new file mode 100755 (executable)
index 0000000..5210b86
--- /dev/null
@@ -0,0 +1,19 @@
+puts "============"
+puts "OCC25068"
+puts "============"
+puts ""
+###################################################
+## ShapeAnalysis_FreeBounds::ConnectEdgesToWires returns wires with not valid Closed flag
+###################################################
+
+restore [locate_data_file bug24807_Compound.brep] a
+connectedges r a 1.e-7 0
+explode r
+
+set info [whatis r_1]
+
+if { [regexp "Closed" ${info}] == 1 } {
+    puts "Error: Closed flag is not valid"
+} else {
+    puts "OK: Closed flag is valid"
+}
index 2e785c0..ed63a3a 100644 (file)
@@ -2,7 +2,7 @@ if {[string compare $command "ShapeConvertRev"] == 0 } {
     puts "TODO OCC23127 ALL: Error : The resulting shape is not correct"
 }
 if {[string compare $command "SplitAngle"] == 0 } {
-    puts "TODO OCC23127 ALL: Faulty shapes in variables faulty_1 to faulty_9 "
+    puts "TODO OCC23127 ALL: Faulty shapes in variables faulty_1 to faulty_"
     puts "TODO ?DEBUG_OCC24121 Debian60-64 Windows: Error: Exception in ShapeUpgrade_FaceDivide"
 }
 restore [locate_data_file CTO900_ger60598c.rle] a