0027540: Run-to-run differences in the 3D Offset algorithm
authoremv <emv@opencascade.com>
Fri, 27 May 2016 08:19:25 +0000 (11:19 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 2 Jun 2016 11:23:27 +0000 (14:23 +0300)
Calculating the offset vertices by the superposition of intersection vertices
between pairs of edges (BRepOffset_Inter2d::FuseVertices()).

To obtain stable result when calculating the superposition of vertices
they are sorted (BOPTools_AlgoTools::MakeVertex()).

The support of vertices has been added in nexplode command.

Small correction of tests cases for issue CR27540

17 files changed:
src/BOPTools/BOPTools_AlgoTools.cxx
src/BRepAlgo/BRepAlgo_AsDes.cxx
src/BRepOffset/BRepOffset_Inter2d.cxx
src/BRepOffset/BRepOffset_Inter2d.hxx
src/BRepOffset/BRepOffset_MakeOffset.cxx
src/BiTgte/BiTgte_Blend.cxx
src/DBRep/DBRep.cxx
tests/bugs/modalg_6/bug27540_1 [new file with mode: 0644]
tests/bugs/modalg_6/bug27540_2 [new file with mode: 0644]
tests/bugs/modalg_6/bug27540_3 [new file with mode: 0644]
tests/offset/compshape/A1
tests/offset/faces_type_i/C8
tests/offset/shape_type_i/C8
tests/offset/with_intersect_80/K2
tests/offset/with_intersect_80/L3
tests/offset/with_intersect_80/L7
tests/offset/with_intersect_80/L9

index 67d46d8..fc330e5 100644 (file)
 #include <TopoDS_Solid.hxx>
 #include <TopoDS_Vertex.hxx>
 #include <TopoDS_Wire.hxx>
+#include <NCollection_Array1.hxx>
+#include <algorithm>
 
 //
-//
-//
-//
-//
-//
-//
-//
-//
-//
-//
 static
   Standard_Real AngleWithRef(const gp_Dir& theD1,
                              const gp_Dir& theD2,
@@ -116,6 +108,25 @@ static
                           const gp_Pnt& aP);
 
 //=======================================================================
+// function: BOPTools_AlgoTools_ComparePoints
+// purpose:  implementation of IsLess() function for two points
+//=======================================================================
+struct BOPTools_AlgoTools_ComparePoints {
+  bool operator()(const gp_Pnt& theP1, const gp_Pnt& theP2)
+  {
+    for (Standard_Integer i = 1; i <= 3; ++i) {
+      if (theP1.Coord(i) < theP2.Coord(i)) {
+        return Standard_True;
+      }
+      else if (theP1.Coord(i) > theP2.Coord(i)) {
+        return Standard_False;
+      }
+    }
+    return Standard_False;
+  }
+};
+
+//=======================================================================
 // function: MakeConnexityBlocks
 // purpose: 
 //=======================================================================
@@ -1525,8 +1536,8 @@ void BOPTools_AlgoTools::MakeVertex(const BOPCol_ListOfShape& aLV,
     aEps=RealEpsilon();
     for (m=0; m<aNb; ++m) {
       aV[m]=(!m)? 
-       *((TopoDS_Vertex*)(&aLV.First())):
-       *((TopoDS_Vertex*)(&aLV.Last()));
+        *((TopoDS_Vertex*)(&aLV.First())):
+        *((TopoDS_Vertex*)(&aLV.Last()));
       aP[m]=BRep_Tool::Pnt(aV[m]);
       aR[m]=BRep_Tool::Tolerance(aV[m]);
     }  
@@ -1559,28 +1570,38 @@ void BOPTools_AlgoTools::MakeVertex(const BOPCol_ListOfShape& aLV,
     return;
   }// else if (aNb==2) {
   //
-  else { // if (aNb>2) 
-    Standard_Real aTi, aDi, aDmax;
-    gp_Pnt aPi, aP;
-    gp_XYZ aXYZ(0.,0.,0.), aXYZi;
-    BOPCol_ListIteratorOfListOfShape aIt;
+  else { // if (aNb>2)
+    // compute the point
     //
-    aIt.Initialize(aLV);
-    for (; aIt.More(); aIt.Next()) {
-      TopoDS_Vertex& aVi=*((TopoDS_Vertex*)(&aIt.Value()));
-      aPi=BRep_Tool::Pnt(aVi);
-      aXYZi=aPi.XYZ();
-      aXYZ=aXYZ+aXYZi;
+    // issue 0027540 - sum of doubles may depend on the order
+    // of addition, thus sort the coordinates for stable result
+    Standard_Integer i;
+    NCollection_Array1<gp_Pnt> aPoints(0, aNb-1);
+    BOPCol_ListIteratorOfListOfShape aIt(aLV);
+    for (i = 0; aIt.More(); aIt.Next(), ++i) {
+      const TopoDS_Vertex& aVi = *((TopoDS_Vertex*)(&aIt.Value()));
+      gp_Pnt aPi = BRep_Tool::Pnt(aVi);
+      aPoints(i) = aPi;
     }
     //
+    std::sort(aPoints.begin(), aPoints.end(), BOPTools_AlgoTools_ComparePoints());
+    //
+    gp_XYZ aXYZ(0., 0., 0.);
+    for (i = 0; i < aNb; ++i) {
+      aXYZ += aPoints(i).XYZ();
+    }
     aXYZ.Divide((Standard_Real)aNb);
-    aP.SetXYZ(aXYZ);
+    //
+    gp_Pnt aP(aXYZ);
+    //
+    // compute the tolerance for the new vertex
+    Standard_Real aTi, aDi, aDmax;
     //
     aDmax=-1.;
     aIt.Initialize(aLV);
     for (; aIt.More(); aIt.Next()) {
       TopoDS_Vertex& aVi=*((TopoDS_Vertex*)(&aIt.Value()));
-      aPi=BRep_Tool::Pnt(aVi);
+      gp_Pnt aPi=BRep_Tool::Pnt(aVi);
       aTi=BRep_Tool::Tolerance(aVi);
       aDi=aP.SquareDistance(aPi);
       aDi=sqrt(aDi);
index 97641ab..a9f359e 100644 (file)
@@ -20,6 +20,7 @@
 #include <Standard_Type.hxx>
 #include <TopoDS_Shape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_MapOfOrientedShape.hxx>
 
 IMPLEMENT_STANDARD_RTTIEXT(BRepAlgo_AsDes,MMgt_TShared)
 
@@ -149,12 +150,18 @@ static void ReplaceInList(const TopoDS_Shape&   OldS,
                          const TopoDS_Shape&   NewS,
                          TopTools_ListOfShape& L)
 {
+  TopTools_MapOfOrientedShape aMS;
   TopTools_ListIteratorOfListOfShape it(L);
-  
+  for (; it.More(); it.Next()) {
+    aMS.Add(it.Value());
+  }
+  it.Initialize(L);
   while(it.More()) {
     if (it.Value().IsSame(OldS)) {
       TopAbs_Orientation O = it.Value().Orientation();
-      L.InsertBefore(NewS.Oriented(O),it);
+      if (aMS.Add(NewS.Oriented(O))) {
+        L.InsertBefore(NewS.Oriented(O),it);
+      }
       L.Remove(it);
     }
     else it.Next();
@@ -235,34 +242,52 @@ void BRepAlgo_AsDes::BackReplace(const TopoDS_Shape&         OldS,
 //function : Replace
 //purpose  : 
 //=======================================================================
-
 void BRepAlgo_AsDes::Replace(const TopoDS_Shape& OldS,
-                              const TopoDS_Shape& NewS)
+                             const TopoDS_Shape& NewS)
 {
-  Standard_Boolean InUp;
-
-  if (up.IsBound(OldS)) {
-    InUp = Standard_False;
-    BackReplace (OldS,NewS,up(OldS),InUp);
-    if (up.IsBound(NewS)) {
-      up(NewS).Append(up(OldS));
+  for (Standard_Integer i = 0; i < 2; ++i) {
+    TopTools_DataMapOfShapeListOfShape& aMap = !i ? up : down;
+    TopTools_ListOfShape* pLSOld = aMap.ChangeSeek(OldS);
+    if (!pLSOld) {
+      continue;
     }
-    else {
-      up.Bind(NewS,up(OldS));
-    }
-    up.UnBind(OldS);
-  }
-  
-  if (down.IsBound(OldS)) {
-    InUp = Standard_True;
-    BackReplace(OldS,NewS,down (OldS),InUp);
-    if (down.IsBound(NewS)) {
-      down(NewS).Append(down(OldS));
+    //
+    Standard_Boolean InUp = !i ? Standard_False : Standard_True;
+    BackReplace(OldS, NewS, *pLSOld, InUp);
+    //
+    TopTools_ListOfShape* pLSNew = aMap.ChangeSeek(NewS);
+    if (!pLSNew) {
+      // filter the list
+      TopTools_MapOfOrientedShape aMS;
+      TopTools_ListIteratorOfListOfShape aIt(*pLSOld);
+      for (; aIt.More(); ) {
+        if (!aMS.Add(aIt.Value())) {
+          pLSOld->Remove(aIt);
+        }
+        else {
+          aIt.Next();
+        }
+      }
+      aMap.Bind(NewS, *pLSOld);
     }
     else {
-      down.Bind(NewS,down(OldS));
+      // avoid duplicates
+      TopTools_MapOfOrientedShape aMS;
+      TopTools_ListIteratorOfListOfShape aIt(*pLSNew);
+      for (; aIt.More(); aIt.Next()) {
+        aMS.Add(aIt.Value());
+      }
+      //
+      aIt.Initialize(*pLSOld);
+      for (; aIt.More(); aIt.Next()) {
+        const TopoDS_Shape& aS = aIt.Value();
+        if (aMS.Add(aS)) {
+          pLSNew->Append(aS);
+        }
+      }
     }
-    down.UnBind(OldS);
+    //
+    aMap.UnBind(OldS);
   }
 }
 
index 0b8d7f6..c559e96 100644 (file)
@@ -76,6 +76,8 @@
 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_ListOfShape.hxx>
+#include <BOPCol_ListOfShape.hxx>
+#include <BOPTools_AlgoTools.hxx>
 
 #include <stdio.h>
 #ifdef DRAW 
@@ -100,167 +102,100 @@ static TopoDS_Vertex CommonVertex(TopoDS_Edge& E1,
                                  TopoDS_Edge& E2)
 {
   TopoDS_Vertex V1[2],V2[2],V;
-  //  Modified by skv - Wed Dec 24 18:08:39 2003 OCC4455 Begin
-//  TopExp::Vertices(E1,V1[0],V1[1]);
-//  TopExp::Vertices(E2,V2[0],V2[1]);
-
+  //
   TopExp::Vertices(E1,V1[0],V1[1], Standard_True);
   TopExp::Vertices(E2,V2[0],V2[1], Standard_True);
   // The first edge is the current one, the second edge is the next one.
   // We check last vertex of the first edge first.
-//  if (V1[0].IsSame(V2[0]) || V1[0].IsSame(V2[1])) return V1[0];
-//  if (V1[1].IsSame(V2[0]) || V1[1].IsSame(V2[1])) return V1[1];
   if (V1[1].IsSame(V2[0]) || V1[1].IsSame(V2[1])) return V1[1];
   if (V1[0].IsSame(V2[0]) || V1[0].IsSame(V2[1])) return V1[0];
-  //  Modified by skv - Wed Dec 24 18:08:40 2003 OCC4455 End
+  //
   return V;
 }
 
 //=======================================================================
 //function : Store
-//purpose  : 
+//purpose  : The vertices are added despite of the coincidence with
+//           already added vertices. When all vertices for all edges
+//           are added the coinciding chains of vertices should be fused
+//           using FuseVertices() method.
 //=======================================================================
-
-static void  Store (const TopoDS_Edge&       E1,
-                    const TopoDS_Edge&       E2,
-                    TopTools_ListOfShape&    LV1,
-                    TopTools_ListOfShape&    LV2,
-                    Handle(BRepAlgo_AsDes)   AsDes,
-                    Standard_Real            Tol)
+static void  Store (const TopoDS_Edge&     E1,
+                    const TopoDS_Edge&     E2,
+                    const TopTools_ListOfShape&  LV1,
+                    const TopTools_ListOfShape&  LV2,
+                    Handle(BRepAlgo_AsDes) AsDes,
+                    Standard_Real          Tol,
+                    TopTools_IndexedDataMapOfShapeListOfShape& aDMVV)
 {
-  //-------------------------------------------------------------
-  // Test if the points of intersection correspond to existing 
-  // vertices. Otherwise add edges in the descendants.
-  // Note: at this stage only vertices of intersection are in the descendants.
-  //-------------------------------------------------------------
-  const TopTools_ListOfShape& VOnE1 = AsDes->Descendant(E1);
-  const TopTools_ListOfShape& VOnE2 = AsDes->Descendant(E2);
-  TopTools_ListOfShape        NewVOnE1;   
-  TopTools_ListOfShape        NewVOnE2; 
-  gp_Pnt                      P,P1,P2;
-  TopoDS_Vertex               V1,V2;
-  TopTools_ListIteratorOfListOfShape it, itLV1, itLV2;
-  BRep_Builder                       B;
-  TopAbs_Orientation                 O1,O2;
-  Standard_Real                      U1,U2;
-  Standard_Boolean                   OnE1,OnE2;
-
-  for (itLV1.Initialize(LV1),itLV2.Initialize(LV2); 
-       itLV1.More(); 
-       itLV1.Next()  ,itLV2.Next()) {
-
-    TopoDS_Vertex V    = TopoDS::Vertex(itLV1.Value());
-
-    U1 = (BRep_Tool::Degenerated(E1))?
-      BRep_Tool::Parameter(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)), E1) :
-      BRep_Tool::Parameter(V, E1);
-    U2 = (BRep_Tool::Degenerated(E2))?
-      BRep_Tool::Parameter(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)), E2) :
-      BRep_Tool::Parameter(V, E2);
-    O1 = V.Orientation();
-    O2 = itLV2.Value().Orientation();
-    P  = BRep_Tool::Pnt(V);
-    OnE1 = OnE2 = Standard_False;
-    
-    if (!VOnE1.IsEmpty()) {
-      //-----------------------------------------------------------------
-      // Find if the point of intersection corresponds to a vertex of E1.
-      //-----------------------------------------------------------------
-      for (it.Initialize(VOnE1); it.More(); it.Next()) {
-        P1 = BRep_Tool::Pnt(TopoDS::Vertex(it.Value()));
-        if (P.IsEqual(P1,Tol)) {
-          V    = TopoDS::Vertex(it.Value());
-          V1   = V;
-          OnE1 = Standard_True;
-          break;
-        }
-      }
+  BRep_Builder aBB;
+  for (Standard_Integer i = 0; i < 2; ++i) {
+    const TopoDS_Edge& aE = !i ? E1 : E2;
+    const TopTools_ListOfShape& aLV = !i ? LV1 : LV2;
+    const TopTools_ListOfShape& aLVEx = AsDes->Descendant(aE);
+    if (aLVEx.IsEmpty()) {
+      if (aLV.Extent()) AsDes->Add(aE, aLV);
+      continue;
     }
-    if (!VOnE2.IsEmpty()) {
-      if (OnE1) {
-        //-----------------------------------------------------------------
-        // Find if the vertex found on E1 is not already on E2.
-        //-----------------------------------------------------------------
-        for (it.Initialize(VOnE2); it.More(); it.Next()) {
-          if (it.Value().IsSame(V)) {
-            OnE2 = Standard_True;
-            V2   = V;
-            break;
-          }
-        }
+    //
+    TopTools_MapOfShape aMV;
+    TopTools_ListIteratorOfListOfShape aIt(aLV);
+    for (; aIt.More(); aIt.Next()) {
+      const TopoDS_Vertex& aV = TopoDS::Vertex(aIt.Value());
+      if (!aMV.Add(aV)) {
+        continue;
       }
-      for (it.Initialize(VOnE2); it.More(); it.Next()) {
-        //-----------------------------------------------------------------
-        // Find if the point of intersection corresponds to a vertex of E2.
-        //-----------------------------------------------------------------
-        P2 = BRep_Tool::Pnt(TopoDS::Vertex(it.Value()));
-        if (P.IsEqual(P2,Tol)) {
-          V  = TopoDS::Vertex(it.Value());
-          V2 = V;
-          OnE2 = Standard_True;
+      gp_Pnt aP = BRep_Tool::Pnt(aV);
+      //
+      TopTools_ListOfShape aLVC;
+      TopTools_ListIteratorOfListOfShape aItEx(aLVEx);
+      for (; aItEx.More(); aItEx.Next()) {
+        const TopoDS_Vertex& aVEx = TopoDS::Vertex(aItEx.Value());
+        if (aV.IsSame(aVEx)) {
           break;
         }
-      }      
-    }  
-    if (OnE1 && OnE2) {
-      if (!V1.IsSame(V2)) {
-        //---------------------------------------------------------------
-        // Two vertices are actually the same.
-        // V2 will be replaced by V1. 
-        // update the parameters of vertex on edges.
-        //---------------------------------------------------------------
-        Standard_Real UV2;
-        TopoDS_Edge   EWE2;
-        const TopTools_ListOfShape& EdgeWithV2 = AsDes->Ascendant(V2);
-
-        for (it.Initialize(EdgeWithV2); it.More(); it.Next()) {
-          EWE2  = TopoDS::Edge(it.Value());
-          TopoDS_Shape aLocalShape =V2.Oriented(TopAbs_INTERNAL);
-          UV2   = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),EWE2);
-//          UV2   = 
-//            BRep_Tool::Parameter(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),EWE2);
-          aLocalShape = V1.Oriented(TopAbs_INTERNAL);
-          B.UpdateVertex(TopoDS::Vertex(aLocalShape),UV2,EWE2,Tol);
-//          B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),
-//                         UV2,EWE2,Tol);
+        gp_Pnt aPEx = BRep_Tool::Pnt(aVEx);
+        //
+        if (aP.IsEqual(aPEx, Tol)) {
+          aLVC.Append(aVEx);
         }
-        AsDes->Replace(V2,V1);
       }
-    }
-    if (!OnE1) {
-      if (OnE2) {
-        TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
-        B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
-//        B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-//                       U1,E1,Tol);
+      //
+      if (aItEx.More()) {
+        continue;
       }
-      NewVOnE1.Append(V.Oriented(O1));
-    }
-    if (!OnE2) {
-      if (OnE1) {
-        TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
-        B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
-//        B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-//                       U2,E2,Tol);
+      //
+      if (aLVC.Extent()) {
+        TopTools_ListOfShape aLVN;
+        aLVN.Append(aV);
+        //
+        TopTools_ListIteratorOfListOfShape aItLV(aLVC);
+        for (; aItLV.More(); aItLV.Next()) {
+          const TopoDS_Shape& aVC = aItLV.Value();
+          TopTools_ListOfShape* pLV = aDMVV.ChangeSeek(aVC);
+          if (!pLV) {
+            aDMVV.Add(aVC, aLVN);
+          }
+          else {
+            pLV->Append(aV);
+          }
+        }
+        //
+        TopTools_ListOfShape* pLV = aDMVV.ChangeSeek(aV);
+        if (!pLV) {
+          aDMVV.Add(aV, aLVC);
+        }
+        else {
+          pLV->Append(aLVC);
+        }
       }
-      NewVOnE2.Append(V.Oriented(O2));
+      //
+      aBB.UpdateVertex(aV, Tol);
+      AsDes->Add(aE, aV);
     }
-    
-#ifdef DRAW
-   if (Inter2dAffichInt2d) {          
-     if (!OnE1 && !OnE2) {
-       char name[256];
-       sprintf(name,"VV_%d",NbNewVertices++);        
-       DBRep::Set(name,V);
-     }
-   }  
-#endif    
   }
-  if (!NewVOnE1.IsEmpty()) AsDes->Add(E1,NewVOnE1);
-  if (!NewVOnE2.IsEmpty()) AsDes->Add(E2,NewVOnE2);
 }
 
-
 //=======================================================================
 //function : EdgeInter
 //purpose  : 
@@ -272,7 +207,8 @@ static void EdgeInter(const TopoDS_Face&              F,
                       const TopoDS_Edge&              E2,
                       const Handle(BRepAlgo_AsDes)&   AsDes,
                       Standard_Real                   Tol,
-                      Standard_Boolean                WithOri)
+                      Standard_Boolean                WithOri,
+                      TopTools_IndexedDataMapOfShapeListOfShape& aDMVV)
 {
 #ifdef DRAW
   if (Inter2dAffichInt2d) {
@@ -444,32 +380,26 @@ static void EdgeInter(const TopoDS_Face&              F,
     if (V1[j].IsNull()) continue;
     for (Standard_Integer k = 0; k < 2; k++) {
       if (V2[k].IsNull()) continue;
+      if (V1[j].IsSame(V2[k])) {
+        if (AsDes->HasAscendant(V1[j])) {
+          continue;
+        }
+      }
+      //
       gp_Pnt P1 = BRep_Tool::Pnt(V1[j]);
       gp_Pnt P2 = BRep_Tool::Pnt(V2[k]);
       Standard_Real Dist = P1.Distance(P2); 
       if (Dist < TolConf) {
+        Standard_Real aTol = 
+          Max(BRep_Tool::Tolerance(V1[j]), BRep_Tool::Tolerance(V2[k]));
         TopoDS_Vertex V = BRepLib_MakeVertex(P1);
         U1 = (j == 0) ? f[1] : l[1];
         U2 = (k == 0) ? f[2] : l[2];
+        //
         TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
-//  Modified by skv - Thu Jan 22 18:16:01 2004 OCC4455 Begin
-        Standard_Real aTol = BRep_Tool::Tolerance(V1[j]);
-
-        if (!V1[j].IsSame(V2[k])) {
-          Standard_Real aTol2 = BRep_Tool::Tolerance(V2[k]);
-
-          aTol = Max(aTol, aTol2);
-        }
-
         B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,aTol);
         B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,aTol);
-//         B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
-//         B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
-//        B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-//                       U1,E1,Tol);
-//        B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-//                       U2,E2,Tol);
-//  Modified by skv - Thu Jan 22 18:16:01 2004 OCC4455 End
+        //
         LV1.Prepend(V.Oriented(V1[j].Orientation()));
         LV2.Prepend(V.Oriented(V2[k].Orientation()));
       }
@@ -521,15 +451,9 @@ static void EdgeInter(const TopoDS_Face&              F,
     //---------------------------------
     // Vertex storage in DS.
     //---------------------------------
-//  Modified by skv - Tue Jan 13 15:14:30 2004 Begin
     Standard_Real TolStore = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
-
     TolStore = Max(TolStore, 10.*Tol);
-
-    Store (E1,E2,LV1,LV2,AsDes,TolStore);
-//    Store (E1,E2,LV1,LV2,AsDes,10.*Tol);
-//    Store (E1,E2,LV1,LV2,AsDes,Tol);
-//  Modified by skv - Tue Jan 13 15:14:30 2004 End
+    Store (E1,E2,LV1,LV2,AsDes,TolStore, aDMVV);
   }
 }
 //=======================================================================
@@ -544,7 +468,8 @@ static void RefEdgeInter(const TopoDS_Face&              F,
                          const Handle(BRepAlgo_AsDes)&   AsDes,
                          Standard_Real                   Tol,
                          Standard_Boolean                WithOri,
-                         gp_Pnt&                         Pref)
+                         gp_Pnt&                         Pref,
+                         TopTools_IndexedDataMapOfShapeListOfShape& aDMVV)
 {
 #ifdef DRAW
   if (Inter2dAffichInt2d) {
@@ -712,6 +637,12 @@ static void RefEdgeInter(const TopoDS_Face&              F,
     if (V1[j].IsNull()) continue;
     for (Standard_Integer k = 0; k < 2; k++) {
       if (V2[k].IsNull()) continue;
+      if (V1[j].IsSame(V2[k])) {
+        if (AsDes->HasAscendant(V1[j])) {
+          continue;
+        }
+      }
+      //
       gp_Pnt P1 = BRep_Tool::Pnt(V1[j]);
       gp_Pnt P2 = BRep_Tool::Pnt(V2[k]);
       Standard_Real Dist = P1.Distance(P2); 
@@ -722,10 +653,6 @@ static void RefEdgeInter(const TopoDS_Face&              F,
         TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
         B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
         B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
-//        B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-//                       U1,E1,Tol);
-//        B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
-//                       U2,E2,Tol);
         LV1.Prepend(V.Oriented(V1[j].Orientation()));
         LV2.Prepend(V.Oriented(V2[k].Orientation()));
       }
@@ -794,16 +721,9 @@ static void RefEdgeInter(const TopoDS_Face&              F,
     }
       
 ////-----------------------------------------------------
-
-//  Modified by skv - Tue Jan 13 15:14:30 2004 Begin
     Standard_Real TolStore = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
-
     TolStore = Max(TolStore, 10.*Tol);
-
-    Store (E1,E2,LV1,LV2,AsDes,TolStore);
-//    Store (E1,E2,LV1,LV2,AsDes,10.*Tol);
-//    Store (E1,E2,LV1,LV2,AsDes,Tol);
-//  Modified by skv - Tue Jan 13 15:14:30 2004 End
+    Store (E1,E2,LV1,LV2,AsDes,TolStore, aDMVV);
   }
 }
 
@@ -1403,7 +1323,8 @@ static Standard_Boolean  UpdateVertex(TopoDS_Vertex V,
 void BRepOffset_Inter2d::Compute (const Handle(BRepAlgo_AsDes)&     AsDes,
                                   const TopoDS_Face&                F,
                                   const TopTools_IndexedMapOfShape& NewEdges,
-                                  const Standard_Real               Tol)
+                                  const Standard_Real               Tol,
+                                  TopTools_IndexedDataMapOfShapeListOfShape& theDMVV)
 {
 #ifdef DRAW
   NbF2d++;
@@ -1445,7 +1366,7 @@ void BRepOffset_Inter2d::Compute (const Handle(BRepAlgo_AsDes)&     AsDes,
       if ( (!EdgesOfFace.Contains(E1) || !EdgesOfFace.Contains(E2)) &&
            (NewEdges.Contains(E1) || NewEdges.Contains(E2)) ) {
         TopoDS_Shape aLocalShape = F.Oriented(TopAbs_FORWARD);
-        EdgeInter(TopoDS::Face(aLocalShape),BAsurf,E1,E2,AsDes,Tol,Standard_True);
+        EdgeInter(TopoDS::Face(aLocalShape),BAsurf,E1,E2,AsDes,Tol,Standard_True, theDMVV);
 //          EdgeInter(TopoDS::Face(F.Oriented(TopAbs_FORWARD)),E1,E2,AsDes,Tol,Standard_True);
       }
       it2LE.Next();
@@ -1470,7 +1391,8 @@ void BRepOffset_Inter2d::ConnexIntByInt
  const Handle(BRepAlgo_AsDes)& AsDes,
  const Handle(BRepAlgo_AsDes)& AsDes2d,
  const Standard_Real           Offset,
- const Standard_Real           Tol)
+ const Standard_Real           Tol,
+ TopTools_IndexedDataMapOfShapeListOfShape& theDMVV)
 //  Modified by skv - Fri Dec 26 16:53:18 2003 OCC4455 End
 {  
 
@@ -1584,7 +1506,7 @@ void BRepOffset_Inter2d::ConnexIntByInt
         for (Exp1.Init(NE1,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) {
           for (Exp2.Init(NE2,TopAbs_EDGE) ; Exp2.More(); Exp2.Next()) {
             RefEdgeInter(FIO,BAsurf,TopoDS::Edge(Exp1.Current()),TopoDS::Edge(Exp2.Current()),
-                      AsDes2d,Tol,Standard_True/*Standard_False*/, Pref);
+                      AsDes2d,Tol,Standard_True/*Standard_False*/, Pref, theDMVV);
           }
         }
         //
@@ -1599,12 +1521,12 @@ void BRepOffset_Inter2d::ConnexIntByInt
             //
             for (Exp1.Init(NE1,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) {
               RefEdgeInter(FIO,BAsurf,TopoDS::Edge(Exp1.Current()),aE3,
-                           AsDes2d,Tol,Standard_True/*Standard_False*/, Pref);
+                           AsDes2d,Tol,Standard_True/*Standard_False*/, Pref, theDMVV);
             }
             //
             for (Exp1.Init(NE2,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) {
               RefEdgeInter(FIO,BAsurf,TopoDS::Edge(Exp1.Current()),aE3,
-                           AsDes2d,Tol,Standard_True/*Standard_False*/, Pref);
+                           AsDes2d,Tol,Standard_True/*Standard_False*/, Pref, theDMVV);
             }
           }
         }
@@ -1625,3 +1547,71 @@ void BRepOffset_Inter2d::ConnexIntByInt
     }
   }
 }
+
+//=======================================================================
+//function : MakeChain
+//purpose  : 
+//=======================================================================
+static void MakeChain(const TopoDS_Shape& theV,
+                      const TopTools_IndexedDataMapOfShapeListOfShape& theDMVV,
+                      TopTools_MapOfShape& theMDone,
+                      BOPCol_ListOfShape& theChain)
+{
+  if (theMDone.Add(theV)) {
+    theChain.Append(theV);
+    const TopTools_ListOfShape* pLV = theDMVV.Seek(theV);
+    if (pLV) {
+      TopTools_ListIteratorOfListOfShape aIt(*pLV);
+      for (; aIt.More(); aIt.Next()) {
+        MakeChain(aIt.Value(), theDMVV, theMDone, theChain);
+      }
+    }
+  }
+}
+
+//=======================================================================
+//function : FuseVertices
+//purpose  : 
+//=======================================================================
+void BRepOffset_Inter2d::FuseVertices(const TopTools_IndexedDataMapOfShapeListOfShape& theDMVV,
+                                      const Handle(BRepAlgo_AsDes)& theAsDes)
+{
+  BRep_Builder aBB;
+  TopTools_MapOfShape aMVDone;
+  Standard_Integer i, aNb = theDMVV.Extent();
+  for (i = 1; i <= aNb; ++i) {
+    const TopoDS_Vertex& aV = TopoDS::Vertex(theDMVV.FindKey(i));
+    //
+    // find chain of vertices
+    BOPCol_ListOfShape aLVChain;
+    MakeChain(aV, theDMVV, aMVDone, aLVChain);
+    //
+    if (aLVChain.Extent() < 2) {
+      continue;
+    }
+    //
+    // make new vertex
+    TopoDS_Vertex aVNew;
+    BOPTools_AlgoTools::MakeVertex(aLVChain, aVNew);
+    //
+    TopoDS_Vertex aVNewInt = TopoDS::Vertex(aVNew.Oriented(TopAbs_INTERNAL));
+    //
+    BOPCol_ListIteratorOfListOfShape aIt(aLVChain);
+    for (; aIt.More(); aIt.Next()) {
+      const TopoDS_Shape& aVOld = aIt.Value();
+      // update the parameters on edges
+      TopoDS_Vertex aVOldInt = TopoDS::Vertex(aVOld.Oriented(TopAbs_INTERNAL));
+      const TopTools_ListOfShape& aLE = theAsDes->Ascendant(aVOld);
+      //
+      TopTools_ListIteratorOfListOfShape aItLE(aLE);
+      for (; aItLE.More(); aItLE.Next()) {
+        const TopoDS_Edge& aE = TopoDS::Edge(aItLE.Value());
+        Standard_Real aTolE = BRep_Tool::Tolerance(aE);
+        Standard_Real aT = BRep_Tool::Parameter(aVOldInt, aE);
+        aBB.UpdateVertex(aVNewInt, aT, aE, aTolE);
+      }
+      // and replace the vertex
+      theAsDes->Replace(aVOld, aVNew);
+    }
+  }
+}
index d49720a..5254350 100644 (file)
@@ -24,6 +24,7 @@
 #include <TopTools_IndexedMapOfShape.hxx>
 #include <Standard_Real.hxx>
 #include <TopTools_DataMapOfShapeShape.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
 class BRepAlgo_AsDes;
 class TopoDS_Face;
 class BRepOffset_Offset;
@@ -41,11 +42,21 @@ public:
   //! Computes the intersections between the edges stored
   //! is AsDes as descendants of <F> . Intersections is computed
   //! between two edges if one of them is bound in NewEdges.
+  //! When all faces of the shape are treated the intersection
+  //! vertices have to be fused using the FuseVertices method.
+  //! theDMVV contains the vertices that should be fused
   Standard_EXPORT static void Compute (const Handle(BRepAlgo_AsDes)& AsDes, 
                                        const TopoDS_Face& F, 
                                        const TopTools_IndexedMapOfShape& NewEdges, 
-                                       const Standard_Real Tol);
-  
+                                       const Standard_Real Tol,
+                                       TopTools_IndexedDataMapOfShapeListOfShape& theDMVV);
+
+  //! Computes the intersection between the offset edges
+  //! stored in AsDes as descendatnds on <F>. All intersection
+  //! vertices will be stored in AsDes2d. When all faces of the
+  //! shape are treated the intersection vertices have to be fused
+  //! using the FuseVertices method.
+  //! theDMVV contains the vertices that should be fused.
   Standard_EXPORT static void ConnexIntByInt (const TopoDS_Face& FI, 
                                               BRepOffset_Offset& OFI, 
                                               TopTools_DataMapOfShapeShape& MES, 
@@ -53,10 +64,14 @@ public:
                                               const Handle(BRepAlgo_AsDes)& AsDes, 
                                               const Handle(BRepAlgo_AsDes)& AsDes2d, 
                                               const Standard_Real Offset, 
-                                              const Standard_Real Tol);
-
-
+                                              const Standard_Real Tol,
+                                              TopTools_IndexedDataMapOfShapeListOfShape& theDMVV);
 
+  //! Fuses the chains of vertices in the theDMVV
+  //! and updates AsDes by replacing the old vertices
+  //! with the new ones.
+  Standard_EXPORT static void FuseVertices(const TopTools_IndexedDataMapOfShapeListOfShape& theDMVV,
+                                           const Handle(BRepAlgo_AsDes)& theAsDes);
 
 protected:
 
index 5cb57c0..8fa0fd1 100644 (file)
@@ -1189,14 +1189,18 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
   //---------------------------------------------------------------------------------
   // Extension of neighbor edges of new edges and intersection between neighbors.
   //--------------------------------------------------------------------------------
+  TopTools_IndexedDataMapOfShapeListOfShape aDMVV;
   Handle(BRepAlgo_AsDes) AsDes2d = new BRepAlgo_AsDes();
   for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next())
   {
     const TopoDS_Face& FI = TopoDS::Face(Exp.Current());
     Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(FI);
     BRepOffset_Inter2d::ConnexIntByInt (FI, MapSF(FI), MES, Build, 
-                                        AsDes, AsDes2d, myOffset, aCurrFaceTol);
+                                        AsDes, AsDes2d, myOffset, aCurrFaceTol, aDMVV);
   }
+  //
+  // fuse vertices on edges
+  BRepOffset_Inter2d::FuseVertices(aDMVV, AsDes2d);
   //-----------------------------------------------------------
   // Great restriction of new edges and update of AsDes.
   //------------------------------------------ ----------------
@@ -1326,12 +1330,13 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
     }
   }
   
+  aDMVV.Clear();
   TopTools_ListIteratorOfListOfShape itLFE(LFE);
   for (; itLFE.More(); itLFE.Next())
   {
     const TopoDS_Face& NEF = TopoDS::Face(itLFE.Value());
     Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(NEF);
-    BRepOffset_Inter2d::Compute(AsDes, NEF, NewEdges, aCurrFaceTol);
+    BRepOffset_Inter2d::Compute(AsDes, NEF, NewEdges, aCurrFaceTol, aDMVV);
   }
   //----------------------------------------------
   // Intersections 2d on caps.
@@ -1341,9 +1346,10 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
   {
     const TopoDS_Face& Cork = TopoDS::Face(myFaces(i));
     Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(Cork);
-    BRepOffset_Inter2d::Compute(AsDes, Cork, NewEdges, aCurrFaceTol);
+    BRepOffset_Inter2d::Compute(AsDes, Cork, NewEdges, aCurrFaceTol, aDMVV);
   }
-
+  //
+  BRepOffset_Inter2d::FuseVertices(aDMVV, AsDes);
   //-------------------------------
   // Unwinding of extended Faces.
   //-------------------------------
@@ -2909,12 +2915,15 @@ void BRepOffset_MakeOffset::Intersection2D(const TopTools_IndexedMapOfShape& Mod
   //-----------------------------------------------
   // Intersection of edges 2 by 2.
   //-----------------------------------------------
+  TopTools_IndexedDataMapOfShapeListOfShape aDMVV;
   Standard_Integer i;
   for (i = 1; i <= Modif.Extent(); i++) {
     const TopoDS_Face& F  = TopoDS::Face(Modif(i));
-    BRepOffset_Inter2d::Compute(myAsDes,F,NewEdges,myTol);
+    BRepOffset_Inter2d::Compute(myAsDes,F,NewEdges,myTol, aDMVV);
   }
-
+  //
+  BRepOffset_Inter2d::FuseVertices(aDMVV, myAsDes);
+  //
 #ifdef OCCT_DEBUG
   if (AffichInt2d) {
     DEBVerticesControl (NewEdges,myAsDes);
index 577535c..1b1cb70 100644 (file)
@@ -1726,7 +1726,7 @@ void BiTgte_Blend::ComputeCenters()
   // -------------------------------------------------------------------
 
   // Proceed with MakeLoops 
-
+  TopTools_IndexedDataMapOfShapeListOfShape aDMVV;
   BRepOffset_Type    OT = BRepOffset_Concave;
   if (myRadius < 0.) OT = BRepOffset_Convex; 
    
@@ -1779,7 +1779,8 @@ void BiTgte_Blend::ComputeCenters()
       BRepOffset_Inter2d::Compute(myAsDes,
                                  CurOF,
                                  myEdges,
-                                 myTol);
+                                 myTol,
+                                 aDMVV);
     }
   }
 
@@ -1811,8 +1812,12 @@ void BiTgte_Blend::ComputeCenters()
     BRepOffset_Inter2d::Compute(myAsDes,
                                CurOF,
                                myEdges,
-                               myTol);
+                               myTol,
+                               aDMVV);
   }
+  //
+  // fuse vertices on edges stored in AsDes
+  BRepOffset_Inter2d::FuseVertices(aDMVV, myAsDes);
   // ------------
   // unwinding 
   // ------------
index a39484f..18e438e 100644 (file)
@@ -584,6 +584,11 @@ static Standard_Integer nexplode(Draw_Interpretor& di,
     typ = TopAbs_EDGE;
     break;
     
+  case 'V' :
+  case 'v' :
+    typ = TopAbs_VERTEX;
+    break;
+    
     default :
       return 1;
   }
@@ -604,20 +609,26 @@ static Standard_Integer nexplode(Draw_Interpretor& di,
     }
     Exp.Next();
   }
-  
+  //
   TColStd_Array1OfInteger OrderInd(1,MaxShapes);
-//  gp_Pnt GPoint;
+  gp_Pnt GPoint;
   GProp_GProps GPr;
-//  Standard_Integer InOfminX = 1,aTemp;
   Standard_Integer aTemp;
   TColStd_Array1OfReal MidXYZ(1,MaxShapes); //X,Y,Z;
   Standard_Boolean NoSort = Standard_True;
-  
-  // Computing of CentreOfMass
+  //
+  // Computing of CentreOfMass for edge and face
+  // and for vertex use its point
   for (Index=1; Index <= MaxShapes; Index++) {
     OrderInd.SetValue(Index,Index);
-    BRepGProp::LinearProperties(aShapes(Index),GPr);
-    gp_Pnt GPoint = GPr.CentreOfMass();
+    const TopoDS_Shape& aS = aShapes(Index);
+    if (aS.ShapeType() != TopAbs_VERTEX) {
+      BRepGProp::LinearProperties(aS, GPr);
+      GPoint = GPr.CentreOfMass();
+    }
+    else {
+      GPoint = BRep_Tool::Pnt(TopoDS::Vertex(aS));
+    }
     MidXYZ.SetValue(Index, GPoint.X()*999 + GPoint.Y()*99 +
                    GPoint.Z()*0.9);
   }   
@@ -1288,7 +1299,7 @@ void  DBRep::BasicCommands(Draw_Interpretor& theCommands)
   theCommands.Add("compound","compound [name1 name2 ..] compound",__FILE__,compound,g);
   theCommands.Add("add","add name1 name2",__FILE__,add,g);
   theCommands.Add("explode","explode name [Cd/C/So/Sh/F/W/E/V]",__FILE__,explode,g);
-  theCommands.Add("nexplode","stable numbered explode for edge and face: nexplode name [F/E]",__FILE__,nexplode,g);
+  theCommands.Add("nexplode","stable numbered explode for vertex, edge and face: nexplode name [V/E/F]",__FILE__,nexplode,g);
   theCommands.Add("exwire","exwire wirename",__FILE__,exwire,g);
   theCommands.Add("emptycopy","emptycopy [copyshape] originalshape",__FILE__,emptycopy,g);
   theCommands.Add("check","check shape1 shape2 ...",__FILE__,check,g);
diff --git a/tests/bugs/modalg_6/bug27540_1 b/tests/bugs/modalg_6/bug27540_1
new file mode 100644 (file)
index 0000000..ac6fc41
--- /dev/null
@@ -0,0 +1,67 @@
+puts "=========================================================="
+puts "0027540: Run-to-run differences in the 3D Offset algorithm"
+puts "=========================================================="
+puts ""
+
+pload MODELING
+
+restore [locate_data_file bug27540_shapes1.brep] s
+explode s
+
+# make offset operations on two shapes
+# first shape
+offsetparameter 1e-7 c i
+# set offset 10 for top faces (normal direction 0 0 1), 0 for all other faces
+offsetload s_1 0
+set faces [explode s_1 f]
+foreach f $faces {
+  mksurface surf $f
+  set found [regexp {Axis   :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump surf] full x y z]
+  if {$found && abs($z - 1) < 1.e-7} {
+    offsetonface $f 10
+  }
+}
+offsetperform result1
+checkprops result1 -s 3.26459e+006
+checkprops result1 -v 1.067e+008
+checknbshapes result1 -vertex 28 -edge 44 -wire 20 -face 19 -shell 1 -solid 1
+
+
+# second shape
+offsetparameter 1e-7 c i
+# set offset 10 for top faces (normal direction 0 0 1), 0 for all other faces
+offsetload s_2 0
+set faces [explode s_2 f]
+foreach f $faces {
+  mksurface surf $f
+  set found [regexp {Axis   :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump surf] full x y z]
+  if {$found && abs($z - 1) < 1.e-7} {
+    offsetonface $f 10
+  }
+}
+offsetperform result2
+checkprops result2 -s 3.26459e+006
+checkprops result2 -v 1.067e+008
+checknbshapes result2 -vertex 28 -edge 44 -wire 20 -face 19 -shell 1 -solid 1
+
+
+# compare the results
+set vertices1 [nexplode result1 v]
+set vertices2 [nexplode result2 v]
+
+set nbv1 [llength $vertices1]
+
+for {set i 0} {$i < $nbv1} {incr i} {
+  set v1 [lindex $vertices1 $i]
+  set v2 [lindex $vertices2 $i]
+
+  mkpoint px $v1
+  set dump_v1 [dump px]
+  
+  mkpoint px $v2
+  set dump_v2 [dump px]
+
+  if {$dump_v1 != $dump_v2} {
+    puts "Error: the results are not the same - $v1 and $v2"
+  }
+}
diff --git a/tests/bugs/modalg_6/bug27540_2 b/tests/bugs/modalg_6/bug27540_2
new file mode 100644 (file)
index 0000000..1acf324
--- /dev/null
@@ -0,0 +1,67 @@
+puts "=========================================================="
+puts "0027540: Run-to-run differences in the 3D Offset algorithm"
+puts "=========================================================="
+puts ""
+
+pload MODELING
+
+restore [locate_data_file bug27540_shapes2.brep] s
+explode s
+
+# make offset operations on two shapes
+# first shape
+offsetparameter 1e-7 c i
+# set offset 30 for top faces (normal direction 0 0 1), 10 for all other faces
+offsetload s_1 10
+set faces [explode s_1 f]
+foreach f $faces {
+  mksurface surf $f
+  set found [regexp {Axis   :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump surf] full x y z]
+  if {$found && abs($z - 1) < 1.e-7} {
+    offsetonface $f 30
+  }
+}
+offsetperform result1
+checkprops result1 -s 3.76166e+006
+checkprops result1 -v 1.74521e+008
+checknbshapes result1 -vertex 36 -edge 56 -wire 24 -face 23 -shell 1 -solid 1
+
+
+# second shape
+offsetparameter 1e-7 c i
+# set offset 30 for top faces (normal direction 0 0 1), 10 for all other faces
+offsetload s_2 10
+set faces [explode s_2 f]
+foreach f $faces {
+  mksurface surf $f
+  set found [regexp {Axis   :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump surf] full x y z]
+  if {$found && abs($z - 1) < 1.e-7} {
+    offsetonface $f 30
+  }
+}
+offsetperform result2
+checkprops result2 -s 3.76166e+006
+checkprops result2 -v 1.74521e+008
+checknbshapes result2 -vertex 36 -edge 56 -wire 24 -face 23 -shell 1 -solid 1
+
+
+# compare the results
+set vertices1 [nexplode result1 v]
+set vertices2 [nexplode result2 v]
+
+set nbv1 [llength $vertices1]
+
+for {set i 0} {$i < $nbv1} {incr i} {
+  set v1 [lindex $vertices1 $i]
+  set v2 [lindex $vertices2 $i]
+
+  mkpoint px $v1
+  set dump_v1 [dump px]
+  
+  mkpoint px $v2
+  set dump_v2 [dump px]
+
+  if {$dump_v1 != $dump_v2} {
+    puts "Error: the results are not the same - $v1 and $v2"
+  }
+}
diff --git a/tests/bugs/modalg_6/bug27540_3 b/tests/bugs/modalg_6/bug27540_3
new file mode 100644 (file)
index 0000000..8d14371
--- /dev/null
@@ -0,0 +1,67 @@
+puts "=========================================================="
+puts "0027540: Run-to-run differences in the 3D Offset algorithm"
+puts "=========================================================="
+puts ""
+
+pload MODELING
+
+restore [locate_data_file bug27540_shapes3.brep] s
+explode s
+
+# make offset operations on two shapes
+# first shape
+offsetparameter 1e-7 c i
+# set offset 20 for top faces (normal direction 0 0 1), 0 for all other faces
+offsetload s_1 0
+set faces [explode s_1 f]
+foreach f $faces {
+  mksurface surf $f
+  set found [regexp {Axis   :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump surf] full x y z]
+  if {$found && abs($z - 1) < 1.e-7} {
+    offsetonface $f 20
+  }
+}
+offsetperform result1
+checkprops result1 -s 464088
+checkprops result1 -v 1.29909e+007
+checknbshapes result1 -vertex 48 -edge 74 -wire 32 -face 30 -shell 1 -solid 1
+
+
+# second shape
+offsetparameter 1e-7 c i
+# set offset 20 for top faces (normal direction 0 0 1), 0 for all other faces
+offsetload s_2 0
+set faces [explode s_2 f]
+foreach f $faces {
+  mksurface surf $f
+  set found [regexp {Axis   :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump surf] full x y z]
+  if {$found && abs($z - 1) < 1.e-7} {
+    offsetonface $f 20
+  }
+}
+offsetperform result2
+checkprops result2 -s 464088
+checkprops result2 -v 1.29909e+007
+checknbshapes result2 -vertex 48 -edge 74 -wire 32 -face 30 -shell 1 -solid 1
+
+
+# compare the results
+set vertices1 [nexplode result1 v]
+set vertices2 [nexplode result2 v]
+
+set nbv1 [llength $vertices1]
+
+for {set i 0} {$i < $nbv1} {incr i} {
+  set v1 [lindex $vertices1 $i]
+  set v2 [lindex $vertices2 $i]
+
+  mkpoint px $v1
+  set dump_v1 [dump px]
+  
+  mkpoint px $v2
+  set dump_v2 [dump px]
+
+  if {$dump_v1 != $dump_v2} {
+    puts "Error: the results are not the same - $v1 and $v2"
+  }
+}
index d31ead0..4b86d70 100644 (file)
@@ -1,7 +1,5 @@
 puts "TODO ?OCC23068 ALL: ERROR. offsetperform operation not done."
-puts "TODO ?OCC23068 ALL: Error: The command cannot be built"
-puts "TODO ?OCC23068 ALL: result is not a topological shape!!!"
-puts "TODO ?OCC23068 ALL: TEST INCOMPLETE"
+puts "TODO ?OCC23068 ALL: Error : The volume of result shape "
 
 ## ======================================
 ## Grid    : CCV002
index cea1bed..bf09fb3 100644 (file)
@@ -1,5 +1,6 @@
 puts "TODO OCC25406 ALL: Error : The volume of result shape is"
-puts "TODO OCC25406 ALL: Faulty shapes in variables faulty_1 to"
+puts "TODO OCC25406 Windows: Faulty shapes in variables faulty_1 to"
+puts "TODO OCC25406 ALL: Error: bsection of the result and s is not equal to zero"
 
 ellipse w1 0 0 0 15 10
 mkedge w1 w1 0 pi/2
index ce6fe5c..83cc4b9 100644 (file)
@@ -1,5 +1,6 @@
 puts "TODO OCC23068 ALL: Error : The volume of result shape is"
-puts "TODO OCC23068 ALL: Faulty shapes in variables faulty_1 to"
+puts "TODO OCC23068 Windows: Faulty shapes in variables faulty_1 to"
+puts "TODO OCC23068 ALL: Error: bsection of the result and s is not equal to zero"
 
 ellipse w1 0 0 0 15 10
 mkedge w1 w1 0 pi/2
index fd81bcb..897496f 100644 (file)
@@ -1,5 +1,3 @@
-puts "TODO OCC26577 All: Error :  is WRONG because number of EDGE entities in shape"
-puts "TODO OCC26577 All: Error :  is WRONG because number of SHELL entities in shape"
 restore [locate_data_file bug26663_test_offset_K2.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
 checknbshapes result -ref [lrange [nbshapes s] 8 19]
index d3ee909..d4bdb23 100644 (file)
@@ -1,4 +1,3 @@
-puts "TODO OCC26577 All: Error :  is WRONG because number of EDGE entities in shape"
 puts "TODO OCC26577 All: Faulty shapes in variables faulty_1 to faulty"
 restore [locate_data_file bug26663_test_offset_L3.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
index 444cd7f..cdba2a0 100644 (file)
@@ -1,5 +1,3 @@
-puts "TODO OCC26577 All: Error :  is WRONG because number of EDGE entities in shape"
-puts "TODO OCC26577 All: Error :  is WRONG because number of SHELL entities in shape"
 restore [locate_data_file bug26663_test_offset_L7.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}
 checknbshapes result -ref [lrange [nbshapes s] 8 19]
index ce308dd..ecb18c5 100644 (file)
@@ -1,4 +1,3 @@
-puts "TODO OCC26577 All: Error :  is WRONG because number of EDGE entities in shape"
 puts "TODO OCC26577 All: Faulty shapes in variables faulty_1 to faulty"
 restore [locate_data_file bug26663_test_offset_L9.brep] s
 OFFSETSHAPE ${off_param} {} ${calcul} ${type}