0026173: Wrong result of ChFi3d_ChBuilder algorithm: incorrect processing of G1 junct...
authorjgv <jgv@opencascade.com>
Thu, 10 Sep 2015 12:30:55 +0000 (15:30 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 10 Sep 2015 12:31:53 +0000 (15:31 +0300)
Test case for issue CR26173

src/ChFi3d/ChFi3d.cxx
src/ChFi3d/ChFi3d_Builder.cxx
src/ChFi3d/ChFi3d_Builder_0.cxx
src/ChFi3d/ChFi3d_Builder_0.hxx
src/ChFi3d/ChFi3d_Builder_1.cxx
src/ChFi3d/ChFi3d_Builder_2.cxx
src/ChFi3d/ChFi3d_Builder_C1.cxx
src/ChFi3d/ChFi3d_Builder_CnCrn.cxx
src/ChFi3d/ChFi3d_FilBuilder_C2.cxx
src/ChFiDS/ChFiDS_Spine.cxx
tests/bugs/modalg_6/bug26173 [new file with mode: 0755]

index 66b4f30..0c05b9e 100644 (file)
@@ -52,8 +52,8 @@ Standard_Integer ChFi3d::ConcaveSide(const BRepAdaptor_Surface& S1,
   gp_Pnt pt, pt1, pt2; gp_Vec tgE, tgE1, tgE2, ns1, ns2, dint1, dint2;
   TopoDS_Face F1 = S1.Face();
   TopoDS_Face F2 = S2.Face();
-  F1.Orientation(TopAbs_FORWARD);
-  F2.Orientation(TopAbs_FORWARD);
+  //F1.Orientation(TopAbs_FORWARD);
+  //F2.Orientation(TopAbs_FORWARD);
   
   CE.D1(par,pt,tgE);
   tgE.Normalize();
@@ -100,9 +100,13 @@ Standard_Integer ChFi3d::ConcaveSide(const BRepAdaptor_Surface& S1,
   S1.D1(p2d1.X(),p2d1.Y(),pt1,DU1,DV1);
   ns1 = DU1.Crossed(DV1);
   ns1.Normalize();
+  if (F1.Orientation() == TopAbs_REVERSED)
+    ns1.Reverse();
   S2.D1(p2d2.X(),p2d2.Y(),pt2,DU2,DV2);
   ns2 = DU2.Crossed(DV2);
   ns2.Normalize();
+  if (F2.Orientation() == TopAbs_REVERSED)
+    ns2.Reverse();
 
   dint1 = ns1.Crossed(tgE1);
   dint2 = ns2.Crossed(tgE2);
@@ -129,11 +133,15 @@ Standard_Integer ChFi3d::ConcaveSide(const BRepAdaptor_Surface& S1,
       DV1 += ( DV1 * dint1 < 0) ? -DDV : DDV;
       ns1 = DU1.Crossed(DV1);
       ns1.Normalize();
+      if (F1.Orientation() == TopAbs_REVERSED)
+        ns1.Reverse();
       S2.D2(p2d2.X(),p2d2.Y(),pt2,DU2,DV2,DDU,DDV,DDUV);
       DU2 += ( DU2 * dint2 < 0) ? -DDU : DDU;
       DV2 += ( DV2 * dint2 < 0) ? -DDV : DDV;
       ns2 = DU2.Crossed(DV2);
       ns2.Normalize();
+      if (F2.Orientation() == TopAbs_REVERSED)
+        ns2.Reverse();
       
       dint1 = ns1.Crossed(tgE1);
       dint2 = ns2.Crossed(tgE2);
@@ -171,8 +179,12 @@ Standard_Integer ChFi3d::ConcaveSide(const BRepAdaptor_Surface& S1,
       p2d2.SetX(p2d2.X() + u); p2d2.SetY(p2d2.Y() + v);
       S1.D1(p2d1.X(),p2d1.Y(),pt1,DU1,DV1);
       ns1 = DU1.Crossed(DV1);
+      if (F1.Orientation() == TopAbs_REVERSED)
+        ns1.Reverse();
       S2.D1(p2d2.X(),p2d2.Y(),pt2,DU2,DV2);
       ns2 = DU2.Crossed(DV2);
+      if (F2.Orientation() == TopAbs_REVERSED)
+        ns2.Reverse();
       gp_Vec vref(pt1,pt2);
       if(ns1.Dot(vref) < 0.){
        Or1 = TopAbs_REVERSED;
index ae2b8e4..eb7bba3 100644 (file)
@@ -181,7 +181,8 @@ void ChFi3d_Builder::ExtentAnalyse ()
   for (Standard_Integer iv = 1; iv <= myVDataMap.Extent(); iv++) {
     nbs = myVDataMap(iv).Extent();
     const TopoDS_Vertex& Vtx = myVDataMap.FindKey(iv);
-    nbedges = ChFi3d_NumberOfEdges(Vtx, myVEMap); 
+    //nbedges = ChFi3d_NumberOfEdges(Vtx, myVEMap); 
+    nbedges = ChFi3d_NumberOfSharpEdges(Vtx, myVEMap, myEFMap); 
     switch (nbs) {
     case 1 :
       ExtentOneCorner(Vtx, myVDataMap.FindFromIndex(iv).First());
@@ -710,7 +711,7 @@ void ChFi3d_Builder::PerformFilletOnVertex
     if (BRep_Tool::Degenerated(cur)) nba--;
   }
   nba=nba/2;*/
-  Standard_Integer nba = ChFi3d_NumberOfEdges(Vtx, myVEMap);
+  Standard_Integer nba = ChFi3d_NumberOfSharpEdges(Vtx, myVEMap, myEFMap);
 
   if (nondegenere) { // Normal processing
     switch (i) {
index ee64130..9dc4e63 100644 (file)
@@ -82,6 +82,8 @@
 #include <BRepAdaptor_HCurve2d.hxx>
 #include <BRepAdaptor_Surface.hxx>
 #include <BRepTopAdaptor_HVertex.hxx>
+#include <BRepTopAdaptor_TopolTool.hxx>
+#include <LocalAnalysis_SurfaceContinuity.hxx>
 
 #include <BRep_Tool.hxx>
 #include <BRep_Builder.hxx>
 #include <TopOpeBRepDS_CurvePointInterference.hxx>
 #include <TopOpeBRepDS_ListOfInterference.hxx>
 #include <TopOpeBRepDS_InterferenceIterator.hxx>
+#include <TopOpeBRepTool_TOOL.hxx>
 #include <ProjLib_ProjectedCurve.hxx>
 
 #include <BRepBlend_PointOnRst.hxx>
@@ -410,11 +413,13 @@ ChFiDS_State ChFi3d_EdgeState(TopoDS_Edge* E,
 {
   ChFiDS_State sst;
   Standard_Integer i,j;
-  TopoDS_Face F[3];
+  //TopoDS_Face F[3];
   TopoDS_Face F1,F2,F3,F4,F5,F6;
   ChFi3d_conexfaces(E[0],F1,F2,EFMap);
   ChFi3d_conexfaces(E[1],F3,F4,EFMap);
   ChFi3d_conexfaces(E[2],F5,F6,EFMap);
+
+  /*
   if(F1.IsSame(F2)) {
     F[0] = F[1] = F1;
     if(F1.IsSame(F3)) F[2] = F4;
@@ -439,13 +444,22 @@ ChFiDS_State ChFi3d_EdgeState(TopoDS_Edge* E,
     else F[1] = F5;
 
   }
-
-  if(F[0].IsNull() || F[1].IsNull() || F[2].IsNull()) sst = ChFiDS_FreeBoundary;
+  */
+  
+  //if(F[0].IsNull() || F[1].IsNull() || F[2].IsNull()) sst = ChFiDS_FreeBoundary;
+  if (F2.IsNull() || F4.IsNull() || F6.IsNull())
+    sst = ChFiDS_FreeBoundary;
   else{
     TopAbs_Orientation o01,o02,o11,o12,o21,o22;
+    /*
     i=ChFi3d::ConcaveSide(F[0],F[1],E[0],o01,o02);
     i=ChFi3d::ConcaveSide(F[0],F[2],E[1],o11,o12);
     j=ChFi3d::ConcaveSide(F[1],F[2],E[2],o21,o22);
+    */
+    i=ChFi3d::ConcaveSide(F1, F2, E[0], o01, o02);
+    i=ChFi3d::ConcaveSide(F3, F4, E[1], o11, o12);
+    j=ChFi3d::ConcaveSide(F5, F6, E[2], o21, o22);
+    
     if(o01==o11 && o02==o21 && o12==o22) sst = ChFiDS_AllSame;
     else if(o12==o22 || i ==10 || j ==10) sst = ChFiDS_OnDiff;
     else sst = ChFiDS_OnSame;
@@ -4567,6 +4581,89 @@ void ChFi3d_ChercheBordsLibres(const  ChFiDS_Map & myVEMap,
   }
 }
 
+Standard_Boolean ChFi3d_isTangentFaces(const TopoDS_Edge &theEdge,
+                                       const TopoDS_Face &theFace1,
+                                       const TopoDS_Face &theFace2,
+                                       const GeomAbs_Shape Order)
+{
+  if (Order == GeomAbs_G1 &&
+      BRep_Tool::Continuity( theEdge, theFace1, theFace2 ) != GeomAbs_C0)
+    return Standard_True;
+
+  Standard_Real TolC0 = Max(0.001, 1.5*BRep_Tool::Tolerance(theEdge));
+
+  Standard_Real aFirst;
+  Standard_Real aLast;
+    
+// Obtaining of pcurves of edge on two faces.
+  const Handle(Geom2d_Curve) aC2d1 = BRep_Tool::CurveOnSurface
+                                                (theEdge, theFace1, aFirst, aLast);
+  const Handle(Geom2d_Curve) aC2d2 = BRep_Tool::CurveOnSurface
+                                                (theEdge, theFace2, aFirst, aLast);
+  if (aC2d1.IsNull() || aC2d2.IsNull())
+    return Standard_False;
+
+// Obtaining of two surfaces from adjacent faces.
+  Handle(Geom_Surface) aSurf1 = BRep_Tool::Surface(theFace1);
+  Handle(Geom_Surface) aSurf2 = BRep_Tool::Surface(theFace2);
+
+  if (aSurf1.IsNull() || aSurf2.IsNull())
+    return Standard_False;
+
+// Computation of the number of samples on the edge.
+  BRepAdaptor_Surface              aBAS1(theFace1);
+  BRepAdaptor_Surface              aBAS2(theFace2);
+  Handle(BRepAdaptor_HSurface)     aBAHS1      = new BRepAdaptor_HSurface(aBAS1);
+  Handle(BRepAdaptor_HSurface)     aBAHS2      = new BRepAdaptor_HSurface(aBAS2);
+  Handle(BRepTopAdaptor_TopolTool) aTool1      = new BRepTopAdaptor_TopolTool(aBAHS1);
+  Handle(BRepTopAdaptor_TopolTool) aTool2      = new BRepTopAdaptor_TopolTool(aBAHS2);
+  Standard_Integer                 aNbSamples1 =     aTool1->NbSamples();
+  Standard_Integer                 aNbSamples2 =     aTool2->NbSamples();
+  Standard_Integer                 aNbSamples  =     Max(aNbSamples1, aNbSamples2);
+
+
+// Computation of the continuity.
+  Standard_Real    aPar;
+  Standard_Real    aDelta = (aLast - aFirst)/(aNbSamples - 1);
+  Standard_Integer i, nbNotDone = 0;
+
+  for (i = 1, aPar = aFirst; i <= aNbSamples; i++, aPar += aDelta) {
+    if (i == aNbSamples) aPar = aLast;
+
+    LocalAnalysis_SurfaceContinuity aCont(aC2d1,  aC2d2,  aPar,
+                                         aSurf1, aSurf2, Order,
+                                         0.001, TolC0, 0.1, 0.1, 0.1);
+    if (!aCont.IsDone())
+      {
+       nbNotDone++;
+       continue;
+      }
+    
+    if (Order == GeomAbs_G1)
+    {
+      if (!aCont.IsG1())
+        return Standard_False;
+    }
+    else if (!aCont.IsG2())
+      return Standard_False;
+  }
+  
+  if (nbNotDone == aNbSamples)
+    return Standard_False;
+
+  //Compare normals of tangent faces in the middle point
+  Standard_Real MidPar = (aFirst + aLast)/2.;
+  gp_Pnt2d uv1 = aC2d1->Value(MidPar);
+  gp_Pnt2d uv2 = aC2d2->Value(MidPar);
+  gp_Dir normal1, normal2;
+  TopOpeBRepTool_TOOL::Nt( uv1, theFace1, normal1 );
+  TopOpeBRepTool_TOOL::Nt( uv2, theFace2, normal2 );
+  Standard_Real dot = normal1.Dot(normal2);
+  if (dot < 0.)
+    return Standard_False;
+  return Standard_True;
+}
+
 //=======================================================================
 //function : NbNotDegeneratedEdges
 //purpose  : calculate the number of non-degenerated edges of Map VEMap(Vtx)
@@ -4585,6 +4682,31 @@ Standard_Integer ChFi3d_NbNotDegeneratedEdges (const TopoDS_Vertex& Vtx,
 }
 
 //=======================================================================
+//function : NbSharpEdges
+//purpose  : calculate the number of sharp edges of Map VEMap(Vtx)
+// Attention the edges of junctions are taken into account twice
+//=======================================================================
+Standard_Integer ChFi3d_NbSharpEdges (const TopoDS_Vertex& Vtx,
+                                      const ChFiDS_Map& VEMap,
+                                      const ChFiDS_Map& EFMap)
+{
+  TopTools_ListIteratorOfListOfShape ItE;
+  Standard_Integer nba=VEMap(Vtx).Extent();
+  for (ItE.Initialize(VEMap(Vtx)); ItE.More(); ItE.Next()) {
+    const TopoDS_Edge& cur = TopoDS::Edge(ItE.Value());
+    if (BRep_Tool::Degenerated(cur)) nba--;
+    else
+    {
+      TopoDS_Face F1, F2;
+      ChFi3d_conexfaces(cur, F1, F2, EFMap);
+      if (!F2.IsNull() && ChFi3d_isTangentFaces(cur, F1, F2, GeomAbs_G2))
+        nba--;
+    }
+  }
+  return nba;
+}
+
+//=======================================================================
 //function : NumberOfEdges
 //purpose  : calculate the number of edges arriving to the top Vtx
 // degenerated edges are not taken into account. 
@@ -4601,6 +4723,26 @@ Standard_Integer ChFi3d_NumberOfEdges(const TopoDS_Vertex& Vtx,
   else  nba=nba/2;
   return nba;
 }
+
+//=======================================================================
+//function : NumberOfSharpEdges
+//purpose  : calculate the number of edges arriving to the top Vtx
+// degenerated edges are not taken into account. 
+//=======================================================================
+Standard_Integer ChFi3d_NumberOfSharpEdges(const TopoDS_Vertex& Vtx,
+                                           const ChFiDS_Map& VEMap,
+                                           const ChFiDS_Map& EFmap)
+{
+  Standard_Integer nba;
+  Standard_Boolean bordlibre;
+  TopoDS_Edge edgelibre1,edgelibre2;
+  nba=ChFi3d_NbSharpEdges(Vtx, VEMap, EFmap);
+  ChFi3d_ChercheBordsLibres(VEMap,Vtx,bordlibre,edgelibre1,edgelibre2);
+  if (bordlibre) nba=(nba-2)/2 +2;
+  else  nba=nba/2;
+  return nba;
+}
+
 //=====================================================
 // function cherche_vertex
 // finds common vertex between two edges 
index 5817598..f6c6af4 100644 (file)
@@ -551,11 +551,20 @@ void ChFi3d_ChercheBordsLibres(const  ChFiDS_Map & myVEMap,
                                 TopoDS_Edge & edgelibre1,
                                 TopoDS_Edge & edgelibre2);
 
+Standard_Boolean ChFi3d_isTangentFaces(const TopoDS_Edge &theEdge,
+                                       const TopoDS_Face &theFace1,
+                                       const TopoDS_Face &theFace2,
+                                       const GeomAbs_Shape Order = GeomAbs_G1);
+
 Standard_Integer ChFi3d_NbNotDegeneratedEdges (const TopoDS_Vertex& Vtx,
                                      const ChFiDS_Map& VEMap);
 Standard_Integer ChFi3d_NumberOfEdges(const TopoDS_Vertex& Vtx,
                                      const ChFiDS_Map& VEMap);
 
+Standard_Integer ChFi3d_NumberOfSharpEdges(const TopoDS_Vertex& Vtx,
+                                           const ChFiDS_Map& VEMap,
+                                           const ChFiDS_Map& EFmap);
+
 void ChFi3d_cherche_vertex (const TopoDS_Edge & E1,
                            const TopoDS_Edge & E2,
                            TopoDS_Vertex & vertex,
index 6c1c97a..8526465 100644 (file)
@@ -90,83 +90,6 @@ static TopOpeBRepDS_BuildTool mkbuildtool()
   return BT;
 }
 
-//  Modified by Sergey KHROMOV - Tue Dec 18 18:02:55 2001 Begin
-Standard_Boolean isTangentFaces(const TopoDS_Edge &theEdge,
-                               const TopoDS_Face &theFace1,
-                               const TopoDS_Face &theFace2)
-{
-  if (BRep_Tool::Continuity( theEdge, theFace1, theFace2 ) != GeomAbs_C0)
-    return Standard_True;
-
-  Standard_Real TolC0 = Max(0.001, 1.5*BRep_Tool::Tolerance(theEdge));
-
-  Standard_Real aFirst;
-  Standard_Real aLast;
-    
-// Obtaining of pcurves of edge on two faces.
-  const Handle(Geom2d_Curve) aC2d1 = BRep_Tool::CurveOnSurface
-                                                (theEdge, theFace1, aFirst, aLast);
-  const Handle(Geom2d_Curve) aC2d2 = BRep_Tool::CurveOnSurface
-                                                (theEdge, theFace2, aFirst, aLast);
-  if (aC2d1.IsNull() || aC2d2.IsNull())
-    return Standard_False;
-
-// Obtaining of two surfaces from adjacent faces.
-  Handle(Geom_Surface) aSurf1 = BRep_Tool::Surface(theFace1);
-  Handle(Geom_Surface) aSurf2 = BRep_Tool::Surface(theFace2);
-
-  if (aSurf1.IsNull() || aSurf2.IsNull())
-    return Standard_False;
-
-// Computation of the number of samples on the edge.
-  BRepAdaptor_Surface              aBAS1(theFace1);
-  BRepAdaptor_Surface              aBAS2(theFace2);
-  Handle(BRepAdaptor_HSurface)     aBAHS1      = new BRepAdaptor_HSurface(aBAS1);
-  Handle(BRepAdaptor_HSurface)     aBAHS2      = new BRepAdaptor_HSurface(aBAS2);
-  Handle(BRepTopAdaptor_TopolTool) aTool1      = new BRepTopAdaptor_TopolTool(aBAHS1);
-  Handle(BRepTopAdaptor_TopolTool) aTool2      = new BRepTopAdaptor_TopolTool(aBAHS2);
-  Standard_Integer                 aNbSamples1 =     aTool1->NbSamples();
-  Standard_Integer                 aNbSamples2 =     aTool2->NbSamples();
-  Standard_Integer                 aNbSamples  =     Max(aNbSamples1, aNbSamples2);
-
-
-// Computation of the continuity.
-  Standard_Real    aPar;
-  Standard_Real    aDelta = (aLast - aFirst)/(aNbSamples - 1);
-  Standard_Integer i, nbNotDone = 0;
-
-  for (i = 1, aPar = aFirst; i <= aNbSamples; i++, aPar += aDelta) {
-    if (i == aNbSamples) aPar = aLast;
-
-    LocalAnalysis_SurfaceContinuity aCont(aC2d1,  aC2d2,  aPar,
-                                         aSurf1, aSurf2, GeomAbs_G1,
-                                         0.001, TolC0, 0.1, 0.1, 0.1);
-    if (!aCont.IsDone())
-      {
-       nbNotDone++;
-       continue;
-      }
-    if (!aCont.IsG1())
-      return Standard_False;
-  }
-  
-  if (nbNotDone == aNbSamples)
-    return Standard_False;
-
-  //Compare normals of tangent faces in the middle point
-  Standard_Real MidPar = (aFirst + aLast)/2.;
-  gp_Pnt2d uv1 = aC2d1->Value(MidPar);
-  gp_Pnt2d uv2 = aC2d2->Value(MidPar);
-  gp_Dir normal1, normal2;
-  TopOpeBRepTool_TOOL::Nt( uv1, theFace1, normal1 );
-  TopOpeBRepTool_TOOL::Nt( uv2, theFace2, normal2 );
-  Standard_Real dot = normal1.Dot(normal2);
-  if (dot < 0.)
-    return Standard_False;
-  return Standard_True;
-}
-//  Modified by Sergey KHROMOV - Tue Dec 18 18:02:56 2001 End
-
 //=======================================================================
 //function : ChFi3d_Builder
 //purpose  : 
@@ -429,7 +352,7 @@ Standard_Boolean ChFi3d_Builder::FaceTangency(const TopoDS_Edge& E0,
   if(Nbf < 2) return Standard_False;
 //  Modified by Sergey KHROMOV - Fri Dec 21 17:44:19 2001 Begin
 //if (BRep_Tool::Continuity(E1,F[0],F[1]) != GeomAbs_C0) {
-  if (isTangentFaces(E1,F[0],F[1])) {
+  if (ChFi3d_isTangentFaces(E1,F[0],F[1])) {
 //  Modified by Sergey KHROMOV - Fri Dec 21 17:44:21 2001 End
     return Standard_False;
   }
@@ -448,7 +371,7 @@ Standard_Boolean ChFi3d_Builder::FaceTangency(const TopoDS_Edge& E0,
       if(Nbf < 2) return Standard_False;
 //  Modified by Sergey KHROMOV - Tue Dec 18 18:10:40 2001 Begin
 //    if (BRep_Tool::Continuity(Ec,F[0],F[1]) < GeomAbs_G1) {
-      if (!isTangentFaces(Ec,F[0],F[1])) {
+      if (!ChFi3d_isTangentFaces(Ec,F[0],F[1])) {
 //  Modified by Sergey KHROMOV - Tue Dec 18 18:10:41 2001 End
        return Standard_False;
       }
@@ -533,6 +456,8 @@ static Standard_Boolean TangentOnVertex(const TopoDS_Vertex&    V,
 
 void ChFi3d_Builder::PerformExtremity (const Handle(ChFiDS_Spine)& Spine) 
 {
+  Standard_Integer NbG1Connections = 0;
+  
   for(Standard_Integer ii = 1; ii <= 2; ii++){
     TopoDS_Edge E[3],Ec;
     TopoDS_Vertex V;
@@ -559,34 +484,41 @@ void ChFi3d_Builder::PerformExtremity (const Handle(ChFiDS_Spine)& Spine)
 
     if(sst == ChFiDS_BreakPoint){
       TopTools_ListIteratorOfListOfShape It;//,Jt;
-      Standard_Integer i = 0, j;
+      Standard_Integer i = 0;
       Standard_Boolean sommetpourri = Standard_False;
-      for (It.Initialize(myVEMap(V));It.More();It.Next()){
-       Ec = TopoDS::Edge(It.Value());
+      TopTools_IndexedMapOfShape EdgesOfV;
+      //to avoid repeating of edges
+      for (It.Initialize(myVEMap(V)); It.More(); It.Next())
+        EdgesOfV.Add(It.Value());
+      for (Standard_Integer ind = 1; ind <= EdgesOfV.Extent(); ind++) {
+       Ec = TopoDS::Edge(EdgesOfV(ind));
        Standard_Boolean bonedge = !BRep_Tool::Degenerated(Ec);
+        if (bonedge)
+        {
+          TopoDS_Face F1, F2;
+          ChFi3d_conexfaces(Ec, F1, F2, myEFMap);
+          if (!F2.IsNull() && ChFi3d_isTangentFaces(Ec, F1, F2, GeomAbs_G2))
+          {
+            bonedge = Standard_False;
+            if (!F1.IsSame(F2))
+              NbG1Connections++;
+          }
+        }
        if(bonedge){
-         Standard_Boolean eclosed = BRep_Tool::IsClosed(Ec);
-         Standard_Integer nboc = 0;
-         for(j = 0; j <= i && bonedge; j++){ 
-           if(!eclosed) bonedge = !Ec.IsSame(E[j]); 
-           else if(Ec.IsSame(E[j])){
-             nboc++;
-             bonedge = nboc<2;
-           }
-         }
-       }
-       if(bonedge){
-         if( i < 2 ){
-           i++;
-           E[i] = Ec;
-         }
-         else{
+          if (!Ec.IsSame(E[0]))
+          {
+            if( i < 2 ){
+              i++;
+              E[i] = Ec;
+            }
+            else{
 #ifdef OCCT_DEBUG
            cout<<"top has more than 3 edges"<<endl;
 #endif
-           sommetpourri = Standard_True;
-           break;
-         }
+              sommetpourri = Standard_True;
+              break;
+            }
+          }
        }
       }
       if(i != 2) sommetpourri = Standard_True;
@@ -610,6 +542,7 @@ void ChFi3d_Builder::PerformExtremity (const Handle(ChFiDS_Spine)& Spine)
       }
       if(kf == jf) nbf++;
     }
+    nbf -= NbG1Connections;
     if(nbf>3) {
       Spine->SetFirstStatus(ChFiDS_BreakPoint);
 #ifdef OCCT_DEBUG
@@ -626,6 +559,7 @@ void ChFi3d_Builder::PerformExtremity (const Handle(ChFiDS_Spine)& Spine)
       }
       if(kf == jf) nbf++;
     }
+    nbf -= NbG1Connections;
     if(nbf>3) {
       Spine->SetLastStatus(ChFiDS_BreakPoint);
 #ifdef OCCT_DEBUG
@@ -661,7 +595,7 @@ Standard_Boolean ChFi3d_Builder::PerformElement(const Handle(ChFiDS_Spine)& Spin
   if(ff1.IsNull() || ff2.IsNull()) return 0;
 //  Modified by Sergey KHROMOV - Fri Dec 21 17:46:22 2001 End
 //if(BRep_Tool::Continuity(Ec,ff1,ff2) != GeomAbs_C0) return 0;
-  if (isTangentFaces(Ec,ff1,ff2)) return 0;
+  if (ChFi3d_isTangentFaces(Ec,ff1,ff2)) return 0;
 //  Modified by Sergey KHROMOV - Fri Dec 21 17:46:24 2001 Begin
   
   BRepAdaptor_Curve CEc,CEv;
index a15dd4e..79f26ed 100644 (file)
@@ -114,11 +114,6 @@ extern void ChFi3d_InitChron(OSD_Chronometer& ch);
 extern void ChFi3d_ResultChron(OSD_Chronometer & ch, Standard_Real& time);
 #endif
 
-//  Modified by Sergey KHROMOV - Fri Dec 21 17:08:19 2001 Begin
-Standard_Boolean isTangentFaces(const TopoDS_Edge &theEdge,
-                               const TopoDS_Face &theFace1,
-                               const TopoDS_Face &theFace2);
-//  Modified by Sergey KHROMOV - Fri Dec 21 17:08:19 2001 End
 
 //===================================================================
 //   Definition by a plane   
@@ -255,7 +250,7 @@ static Standard_Boolean BonVoisin(const gp_Pnt& Point,
 //  Modified by Sergey KHROMOV - Fri Dec 21 17:12:48 2001 Begin
 //         Standard_Boolean istg = 
 //           BRep_Tool::Continuity(ecur,ff,F) != GeomAbs_C0;
-           Standard_Boolean istg = isTangentFaces(ecur,ff,F);
+           Standard_Boolean istg = ChFi3d_isTangentFaces(ecur,ff,F);
 //  Modified by Sergey KHROMOV - Fri Dec 21 17:12:51 2001 End
            if((!issame || (issame && isreallyclosed)) && istg) {
              found = 1;
@@ -461,7 +456,7 @@ Standard_Boolean IsG1(const ChFiDS_Map&         TheMap,
       FVoi = TopoDS::Face(It.Value());
 //  Modified by Sergey KHROMOV - Fri Dec 21 17:09:32 2001 Begin
 //    if (BRep_Tool::Continuity(E,FRef,FVoi) != GeomAbs_C0) {
-      if (isTangentFaces(E,FRef,FVoi)) {
+      if (ChFi3d_isTangentFaces(E,FRef,FVoi)) {
 //  Modified by Sergey KHROMOV - Fri Dec 21 17:09:33 2001 End
        return Standard_True;
       }
@@ -481,7 +476,7 @@ Standard_Boolean IsG1(const ChFiDS_Map&         TheMap,
        FVoi = FRef;
 //  Modified by Sergey KHROMOV - Fri Dec 21 17:15:12 2001 Begin
 //     if (BRep_Tool::Continuity(E,FRef,FRef) >= GeomAbs_G1) {   
-       if (isTangentFaces(E,FRef,FRef)) {
+       if (ChFi3d_isTangentFaces(E,FRef,FRef)) {
 //  Modified by Sergey KHROMOV - Fri Dec 21 17:15:16 2001 End
          return Standard_True;
        }
index 3273d66..bb920e7 100644 (file)
@@ -161,11 +161,6 @@ extern void ChFi3d_ResultChron(OSD_Chronometer & ch,Standard_Real& time);
 #include <Geom2dAdaptor_Curve.hxx>
 #include <IntRes2d_IntersectionSegment.hxx>
 #include <Geom_BezierCurve.hxx>
-//  Modified by Sergey KHROMOV - Fri Dec 21 17:08:19 2001 Begin
-Standard_Boolean isTangentFaces(const TopoDS_Edge &theEdge,
-                               const TopoDS_Face &theFace1,
-                               const TopoDS_Face &theFace2);
-//  Modified by Sergey KHROMOV - Fri Dec 21 17:08:19 2001 End
 
 static Standard_Real recadre(const Standard_Real p,
                             const Standard_Real ref,
@@ -338,7 +333,7 @@ static Standard_Boolean IntersUpdateOnSame(Handle(GeomAdaptor_HSurface)& HGs,
   if ( Update(HBs,Hc3df,FIop,CPop,FprolUV,isFirst,c3dU) )
     return Standard_True;
 
-  if (!isTangentFaces(Eprol,Fprol,Fop))
+  if (!ChFi3d_isTangentFaces(Eprol,Fprol,Fop))
     return Standard_False;
 
   Handle(Geom2d_Curve) gpcprol = BRep_Tool::CurveOnSurface(Eprol,Fprol,uf,ul);
@@ -1645,14 +1640,14 @@ void ChFi3d_Builder::PerformIntersectionAtEnd(const Standard_Integer Index)
     ChFi3d_edge_common_faces(myEFMap(Eadj1),Fga,Fdr);
 //  Modified by Sergey KHROMOV - Fri Dec 21 17:57:32 2001 Begin
 //  reg1=BRep_Tool::Continuity(Eadj1,Fga,Fdr)!=GeomAbs_C0;
-    reg1=isTangentFaces(Eadj1,Fga,Fdr);
+    reg1 = ChFi3d_isTangentFaces(Eadj1,Fga,Fdr);
 //  Modified by Sergey KHROMOV - Fri Dec 21 17:57:33 2001 End
     if (F2.IsSame(facecouture)) Eadj2=edgecouture;
     else ChFi3d_cherche_element(Vtx,EdgeSpine,F2,Eadj2,Vbid1);
     ChFi3d_edge_common_faces(myEFMap(Eadj2),Fga,Fdr);
 //  Modified by Sergey KHROMOV - Fri Dec 21 17:58:22 2001 Begin
 //  reg2=BRep_Tool::Continuity(Eadj2,Fga,Fdr)!=GeomAbs_C0;
-    reg2=isTangentFaces(Eadj2,Fga,Fdr);
+    reg2 = ChFi3d_isTangentFaces(Eadj2,Fga,Fdr);
 //  Modified by Sergey KHROMOV - Fri Dec 21 17:58:24 2001 End
 
 // two faces common to the edge are found
@@ -2075,9 +2070,9 @@ void ChFi3d_Builder::PerformIntersectionAtEnd(const Standard_Integer Index)
       else if (nbarete==5) {
        //pro15368
 //  Modified by Sergey KHROMOV - Fri Dec 21 18:07:43 2001 End
-       Standard_Boolean isTangent0 = isTangentFaces(Edge[0],F1,Face[0]);
-       Standard_Boolean isTangent1 = isTangentFaces(Edge[1],Face[0],Face[1]);
-       Standard_Boolean isTangent2 = isTangentFaces(Edge[2],Face[1],Face[2]);
+       Standard_Boolean isTangent0 = ChFi3d_isTangentFaces(Edge[0],F1,Face[0]);
+       Standard_Boolean isTangent1 = ChFi3d_isTangentFaces(Edge[1],Face[0],Face[1]);
+       Standard_Boolean isTangent2 = ChFi3d_isTangentFaces(Edge[2],Face[1],Face[2]);
        if ((isTangent0 || isTangent2) && isTangent1) {
 //         GeomAbs_Shape cont0,cont1,cont2;
 //         cont0=BRep_Tool::Continuity(Edge[0],F1,Face[0]);
@@ -3961,7 +3956,7 @@ void ChFi3d_Builder::IntersectMoreCorner(const Standard_Integer Index)
     inters = Update(HBs,Hc3df,FiopArc,CPopArc,p2dbout,isfirst,wop);
 //  Modified by Sergey KHROMOV - Fri Dec 21 18:08:27 2001 Begin
 //  if(!inters && BRep_Tool::Continuity(Arcprol,Fv,Fop) != GeomAbs_C0){
-    if(!inters && isTangentFaces(Arcprol,Fv,Fop)){
+    if(!inters && ChFi3d_isTangentFaces(Arcprol,Fv,Fop)){
 //  Modified by Sergey KHROMOV - Fri Dec 21 18:08:29 2001 End
       // Arcprol is an edge of tangency, ultimate adjustment by an extrema curve/curve is attempted.
       Standard_Real ff,ll;
index c291e61..05db58f 100644 (file)
@@ -153,11 +153,6 @@ extern void ChFi3d_InitChron(OSD_Chronometer& ch);
 extern void ChFi3d_ResultChron(OSD_Chronometer & ch,Standard_Real& time);
 #endif
 
-//  Modified by Sergey KHROMOV - Fri Dec 21 17:08:19 2001 Begin
-Standard_Boolean isTangentFaces(const TopoDS_Edge &theEdge,
-                               const TopoDS_Face &theFace1,
-                               const TopoDS_Face &theFace2);
-//  Modified by Sergey KHROMOV - Fri Dec 21 17:08:19 2001 End
 
 //=======================================================================
 //function : Indices
@@ -1267,7 +1262,7 @@ void  ChFi3d_Builder::PerformMoreThreeCorner(const Standard_Integer Jndex,
 //  Modified by Sergey KHROMOV - Fri Dec 21 18:11:02 2001 Begin
 //     regul.SetValue(ic,BRep_Tool::Continuity(TopoDS::Edge(Evive.Value(ic)),F1,F2)
 //                  !=GeomAbs_C0); 
-       regul.SetValue(ic,isTangentFaces(TopoDS::Edge(Evive.Value(ic)),F1,F2)); 
+       regul.SetValue(ic, ChFi3d_isTangentFaces(TopoDS::Edge(Evive.Value(ic)),F1,F2)); 
 //  Modified by Sergey KHROMOV - Fri Dec 21 18:11:07 2001 End
       }
     }
index 1c380dd..038b873 100644 (file)
@@ -784,6 +784,20 @@ void ChFi3d_FilBuilder::PerformTwoCorner(const Standard_Integer Index)
       curvopsam->D1(uintpcsam,PPfacsam,VVfacsam);
       BRepAdaptor_Curve2d PCArcFac(Arcopdif,Fopsam);
       PCArcFac.D0(cpopdif.ParameterOnArc(),ppfacdif);
+      //jgv for OCC26173
+      BRepAdaptor_Surface SurFopsam(Fopsam);
+      if (SurFopsam.IsUClosed())
+      {
+        Standard_Real Uperiod = SurFopsam.LastUParameter() - SurFopsam.FirstUParameter();
+        if (Abs(ppfacsam.X() - ppfacdif.X()) > Uperiod/2)
+        {
+          if (ppfacdif.X() < ppfacsam.X())
+            ppfacdif.SetX(ppfacdif.X() + Uperiod);
+          else
+            ppfacdif.SetX(ppfacdif.X() - Uperiod);
+        }
+      }
+      //////////////////
       BRepAdaptor_Curve CArcFac(Arcopdif);
       CArcFac.D1(cpopdif.ParameterOnArc(),PPfacdif,VVfacdif);
       Handle(BRepAdaptor_HSurface) HBRFopsam = new BRepAdaptor_HSurface();
index e924fb7..4816b18 100644 (file)
@@ -93,14 +93,19 @@ Handle(ChFiDS_HElSpine) ChFiDS_Spine::ElSpine(const Standard_Integer IE) const
 
 Handle(ChFiDS_HElSpine) ChFiDS_Spine::ElSpine(const Standard_Real W) const 
 {
-  ChFiDS_ListIteratorOfListOfHElSpine It(elspines);
-  for (; It.More(); It.Next()) {
-    Handle(ChFiDS_HElSpine) cur = It.Value();
-    Standard_Real uf = cur->FirstParameter();
-    Standard_Real ul = cur->LastParameter();
-    if(uf <= W && W <= ul) return cur;
-  }  
-  return Handle(ChFiDS_HElSpine)();
+  if (elspines.Extent() == 1)
+    return elspines.First();
+  else
+  {
+    ChFiDS_ListIteratorOfListOfHElSpine It(elspines);
+    for (; It.More(); It.Next()) {
+      Handle(ChFiDS_HElSpine) cur = It.Value();
+      Standard_Real uf = cur->FirstParameter();
+      Standard_Real ul = cur->LastParameter();
+      if(uf <= W && W <= ul) return cur;
+    }  
+    return Handle(ChFiDS_HElSpine)();
+  }
 }
 
 //=======================================================================
diff --git a/tests/bugs/modalg_6/bug26173 b/tests/bugs/modalg_6/bug26173
new file mode 100755 (executable)
index 0000000..c918901
--- /dev/null
@@ -0,0 +1,42 @@
+puts "============"
+puts "OCC26173"
+puts "============"
+puts ""
+#######################################################################
+# Wrong result of ChFi3d_ChBuilder algorithm: incorrect processing of G1 junctions at vertex
+#######################################################################
+
+restore [locate_data_file bug26173_lim1.brep] b
+
+explode b e
+copy b_10 e
+explode b f
+copy b_3 f1
+
+smallview
+donly b f1 e
+fit
+xwd $imagedir/${test_image}_1.png
+
+chamf result b e f1 1 1
+
+donly result
+fit
+xwd $imagedir/${test_image}_2.png
+
+set square 662.657
+
+set nbshapes_expected "
+Number of shapes in shape
+ VERTEX    : 22
+ EDGE      : 33
+ WIRE      : 15
+ FACE      : 14
+ SHELL     : 1
+ SOLID     : 1
+ COMPSOLID : 0
+ COMPOUND  : 1
+ SHAPE     : 87
+"
+
+checknbshapes result -ref ${nbshapes_expected} -t -m "Result of ChFi3d_ChBuilder algorithm"