]> OCCT Git - occt-copy.git/commitdiff
0030470: Modeling Algorithms - Invalid result of offset operation in mode "Complete...
authoremv <emv@opencascade.com>
Tue, 5 Feb 2019 11:58:41 +0000 (14:58 +0300)
committeremv <emv@opencascade.com>
Thu, 21 Feb 2019 10:07:57 +0000 (13:07 +0300)
Added treatment of the inverted edges while removing the inside faces (collapsed ones) - RemoveInsideFaces method:
- Removing the invalid hanging blocks containing the inverted edges.
- Considering the face containing the inverted edges as the invalid one.

Test cases for the issue.

src/BRepOffset/BRepOffset_MakeOffset_1.cxx
tests/offset/shape_type_i_c/XS4 [new file with mode: 0644]
tests/offset/shape_type_i_c/XS5 [new file with mode: 0644]
tests/offset/shape_type_i_c/XS6 [new file with mode: 0644]
tests/offset/shape_type_i_c/XS7 [new file with mode: 0644]
tests/offset/shape_type_i_c/XS8 [new file with mode: 0644]
tests/offset/shape_type_i_c/XS9 [new file with mode: 0644]
tests/offset/shape_type_i_c/XT1 [new file with mode: 0644]
tests/offset/shape_type_i_c/XT2 [new file with mode: 0644]
tests/offset/shape_type_i_c/ZC7
tests/offset/shape_type_i_c/begin

index c4794c92457df69f68529dff8aa9c445bd64ac46..2afb51e5559c07dc92c5ee6d2d02cb09b0b6bc32 100644 (file)
@@ -179,7 +179,8 @@ static
                         const TopTools_MapOfShape& theEdgesInvalidByVertex,
                         const TopTools_MapOfShape& theMFHoles,
                         TopTools_IndexedMapOfShape& theMFInvInHole,
-                        TopTools_ListOfShape& theInvFaces);
+                        TopTools_ListOfShape& theInvFaces,
+                        TopTools_ListOfShape& theInvertedFaces);
 
 static
   void FindFacesInsideHoleWires(const TopoDS_Face& theFOrigin,
@@ -238,6 +239,8 @@ static
                          TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
                          const TopTools_DataMapOfShapeShape& theArtInvFaces,
                          const TopTools_IndexedMapOfShape& theInvEdges,
+                         const TopTools_MapOfShape& theInvertedEdges,
+                         const TopTools_ListOfShape& theInvertedFaces,
                          const TopTools_IndexedMapOfShape& theMFToCheckInt,
                          const TopTools_IndexedMapOfShape& theMFInvInHole,
                          const TopoDS_Shape& theFHoles,
@@ -258,6 +261,7 @@ static
                           const TopTools_DataMapOfShapeShape& theDMFImF,
                           const TopTools_IndexedMapOfShape& theMFInv,
                           const TopTools_IndexedMapOfShape& theInvEdges,
+                          const TopTools_MapOfShape& theInvertedEdges,
                           TopTools_MapOfShape& theMFToRem);
 
 static
@@ -596,6 +600,12 @@ static
   void AppendToList(TopTools_ListOfShape& theL,
                     const TopoDS_Shape& theS);
 
+template <class ContainerType, class FenceMapType = TopTools_MapOfShape>
+static Standard_Boolean TakeModified(const TopoDS_Shape& theS,
+                                     const TopTools_DataMapOfShapeListOfShape& theImages,
+                                     ContainerType& theMapOut,
+                                     FenceMapType* theMFence = NULL);
+
 //=======================================================================
 //function : BuildSplitsOfTrimmedFaces
 //purpose  : Building splits of already trimmed faces
@@ -988,6 +998,12 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
   }
 #endif
 
+#ifdef OFFSET_DEBUG
+  // Show all obtained splits of faces
+  TopoDS_Compound aCFIm1;
+  BRep_Builder().MakeCompound(aCFIm1);
+#endif
+
   // Build Edge-Face connectivity map to find faces which removal
   // may potentially lead to creation of the holes in the faces
   // preventing from obtaining closed volume in the result
@@ -997,7 +1013,12 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
   {
     TopTools_ListIteratorOfListOfShape itLFIm(theFImages(i));
     for (; itLFIm.More(); itLFIm.Next())
+    {
       TopExp::MapShapesAndAncestors(itLFIm.Value(), TopAbs_EDGE, TopAbs_FACE, anEFMap);
+#ifdef OFFSET_DEBUG
+      BRep_Builder().Add(aCFIm1, itLFIm.Value());
+#endif
+    }
   }
 
   TopTools_ListOfShape anEmptyList;
@@ -1006,6 +1027,8 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
   // all hole faces
   TopoDS_Compound aFHoles;
   aBB.MakeCompound(aFHoles);
+  // Find the faces containing only the inverted edges and the invalid ones
+  TopTools_ListOfShape anInvertedFaces;
   // find invalid faces
   // considering faces containing only invalid edges as invalid
   aItLF.Initialize(aLFDone);
@@ -1044,7 +1067,7 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
       // find invalid faces
       FindInvalidFaces(aLFImages, theInvEdges, theValidEdges, aDMFLVE, aDMFLIE,
                        *pLNE, *pLIVE, theInvertedEdges, aMEdgeInvalidByVertex,
-                       aMFHoles, aMFInvInHole, aLFInv);
+                       aMFHoles, aMFInvInHole, aLFInv, anInvertedFaces);
     }
     //
     if (aLFInv.Extent()) {
@@ -1095,8 +1118,8 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
   //
   // remove inside faces
   TopTools_IndexedMapOfShape aMEInside;
-  RemoveInsideFaces(theFImages, theInvFaces, theArtInvFaces, theInvEdges,
-                    aMFToCheckInt, aMFInvInHole, aFHoles, theSSInterfs,
+  RemoveInsideFaces(theFImages, theInvFaces, theArtInvFaces, theInvEdges, theInvertedEdges,
+                    anInvertedFaces, aMFToCheckInt, aMFInvInHole, aFHoles, theSSInterfs,
                     aMERemoved, aMEInside, theSolids);
   //
   // make compound of valid splits
@@ -1819,7 +1842,8 @@ void FindInvalidFaces(TopTools_ListOfShape& theLFImages,
                       const TopTools_MapOfShape& theEdgesInvalidByVertex,
                       const TopTools_MapOfShape& theMFHoles,
                       TopTools_IndexedMapOfShape& theMFInvInHole,
-                      TopTools_ListOfShape& theInvFaces)
+                      TopTools_ListOfShape& theInvFaces,
+                      TopTools_ListOfShape& theInvertedFaces)
 {
   // The face should be considered as invalid in the following cases:
   // 1. It has been reverted, i.e. at least two not connected edges 
@@ -1832,7 +1856,8 @@ void FindInvalidFaces(TopTools_ListOfShape& theLFImages,
   // The face will be kept in the following cases:
   // 1. Some of the edges are valid for this face.
   Standard_Boolean bHasValid, bAllValid, bAllInvalid, bHasReallyInvalid, bAllInvNeutral;
-  Standard_Boolean bValid, bValidLoc, bInvalid, bInvalidLoc, bNeutral;
+  Standard_Boolean bValid, bValidLoc, bInvalid, bInvalidLoc, bNeutral, bInverted;
+  Standard_Boolean bIsInvalidByInverted;
   Standard_Integer i, aNbChecked;
   //
   // neutral edges
@@ -1849,7 +1874,7 @@ void FindInvalidFaces(TopTools_ListOfShape& theLFImages,
     aMEValInverted.Add(aItLE.Value());
   }
   //
-  Standard_Boolean bCheckInverted = (theLFImages.Extent() == 1);
+  Standard_Boolean bTreatInvertedAsInvalid = (theLFImages.Extent() == 1);
   //
   // neutral edges to remove
   TopTools_IndexedMapOfShape aMENRem;
@@ -1883,6 +1908,7 @@ void FindInvalidFaces(TopTools_ListOfShape& theLFImages,
     bAllInvalid = Standard_True;
     bHasReallyInvalid = Standard_False;
     bAllInvNeutral = Standard_True;
+    bIsInvalidByInverted = Standard_True;
     aNbChecked = 0;
     //
     const TopoDS_Wire& aWIm = BRepTools::OuterWire(aFIm);
@@ -1909,17 +1935,19 @@ void FindInvalidFaces(TopTools_ListOfShape& theLFImages,
       bNeutral = aMEN.Contains(aEIm);
       bValidLoc = aMVE.Contains(aEIm);
       //
-      if (!bInvalid && bCheckInverted) {
-        bInvalid = theMEInverted.Contains(aEIm);
+      bInverted = theMEInverted.Contains(aEIm);
+      if (!bInvalid && bTreatInvertedAsInvalid) {
+        bInvalid = bInverted;
       }
       //
       if (bValidLoc && (bNeutral || aMEValInverted.Contains(aEIm))) {
         bHasValid = Standard_True;
       }
       //
-      bAllValid = bAllValid && bValidLoc;
-      bAllInvalid = bAllInvalid && bInvalid;
-      bAllInvNeutral = bAllInvNeutral && bAllInvalid && bNeutral;
+      bAllValid &= bValidLoc;
+      bAllInvalid &= bInvalid;
+      bAllInvNeutral &= (bAllInvalid && bNeutral);
+      bIsInvalidByInverted &= (bInvalidLoc || bInverted);
     }
     //
     if (!aNbChecked) {
@@ -1954,6 +1982,12 @@ void FindInvalidFaces(TopTools_ListOfShape& theLFImages,
       continue;
     }
     //
+    if (bIsInvalidByInverted && !(bHasValid || bAllValid))
+    {
+      // The face contains only the inverted and localy invalid edges
+      theInvertedFaces.Append(aFIm);
+    }
+
     if (!bAllInvNeutral) {
       aLFPT.Append(aFIm);
     }
@@ -2003,7 +2037,7 @@ void FindInvalidFaces(TopTools_ListOfShape& theLFImages,
       bNeutral = aMEN.Contains(aEIm);
       bValidLoc = aMVE.Contains(aEIm);
       //
-      if (!bInvalid && bCheckInverted) {
+      if (!bInvalid && bTreatInvertedAsInvalid) {
         bInvalid = theMEInverted.Contains(aEIm);
       }
       //
@@ -2875,6 +2909,8 @@ void RemoveInsideFaces(TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
                        TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
                        const TopTools_DataMapOfShapeShape& theArtInvFaces,
                        const TopTools_IndexedMapOfShape& theInvEdges,
+                       const TopTools_MapOfShape& theInvertedEdges,
+                       const TopTools_ListOfShape& theInvertedFaces,
                        const TopTools_IndexedMapOfShape& theMFToCheckInt,
                        const TopTools_IndexedMapOfShape& theMFInvInHole,
                        const TopoDS_Shape& theFHoles,
@@ -2934,6 +2970,9 @@ void RemoveInsideFaces(TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
   aMV.SetArguments(aLS);
   aMV.SetIntersect(Standard_True);
   aMV.Perform();
+  if (aMV.HasErrors())
+    return;
+
   //
   // get shapes connection for using in the rebuilding process
   // for the cases in which some of the intersection left undetected
@@ -3018,19 +3057,21 @@ void RemoveInsideFaces(TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
       TopExp::MapShapes(aFIm, TopAbs_EDGE, aMEBoundary);
     }
   }
-  //
+
+  // Tool for getting the splits of faces
+  const TopTools_DataMapOfShapeListOfShape& aMVIms = aMV.Images();
+
   // update invalid faces with images
   aNb = aMFInv.Extent();
   for (i = 1; i <= aNb; ++i) {
     const TopoDS_Shape& aFInv = aMFInv(i);
-    const TopTools_ListOfShape& aLFInvIm = aMV.Modified(aFInv);
-    TopTools_ListIteratorOfListOfShape aItLFInvIm(aLFInvIm);
-    for (; aItLFInvIm.More(); aItLFInvIm.Next()) {
-      const TopoDS_Shape& aFInvIm = aItLFInvIm.Value();
-      aMFInv.Add(aFInvIm);
-    }
+    TakeModified(aFInv, aMVIms, aMFInv);
   }
-  //
+
+  // Take into account the faces invalid by inverted edges
+  for (TopTools_ListOfShape::Iterator itLF(theInvertedFaces); itLF.More(); itLF.Next())
+    TakeModified(itLF.Value(), aMVIms, aMFInv);
+
   // check if the invalid faces inside the holes are really invalid:
   // check its normal direction - if it has changed relatively the
   // original face the offset face is invalid and should be kept for rebuilding
@@ -3084,10 +3125,14 @@ void RemoveInsideFaces(TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
       //
       if (aFS.Orientation() == TopAbs_INTERNAL) {
         aMFToRem.Add(aFS);
+        continue;
       }
-      //
-      bAllRemoved = bAllRemoved && aMFToRem.Contains(aFS);
-      bAllInv = bAllInv && (aMFToRem.Contains(aFS) || aMFInv.Contains(aFS));
+
+      if (aMFToRem.Contains(aFS))
+        continue;
+
+      bAllRemoved = false;
+      bAllInv &= aMFInv.Contains(aFS);
     }
     //
     if (bAllInv && !bAllRemoved) {
@@ -3118,7 +3163,7 @@ void RemoveInsideFaces(TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
   }
 
   // Remove the invalid hanging parts external to the solids
-  RemoveHangingParts(aMV, aDMFImF, aMFInv, theInvEdges, aMFToRem);
+  RemoveHangingParts(aMV, aDMFImF, aMFInv, theInvEdges, theInvertedEdges, aMFToRem);
 
   // Remove newly found internal and hanging faces
   RemoveValidSplits(aMFToRem, theFImages, aMV, theMERemoved);
@@ -3304,6 +3349,7 @@ void RemoveHangingParts(const BOPAlgo_MakerVolume& theMV,
                         const TopTools_DataMapOfShapeShape& theDMFImF,
                         const TopTools_IndexedMapOfShape& theMFInv,
                         const TopTools_IndexedMapOfShape& theInvEdges,
+                        const TopTools_MapOfShape& theInvertedEdges,
                         TopTools_MapOfShape& theMFToRem)
 {
   // Map the faces of the result solids to filter them from avoided faces
@@ -3325,22 +3371,7 @@ void RemoveHangingParts(const BOPAlgo_MakerVolume& theMV,
     for (; anExpF.More(); anExpF.Next())
     {
       const TopoDS_Shape& aF = anExpF.Current();
-      const TopTools_ListOfShape* pLFIm = aMVIms.Seek(aF);
-      if (pLFIm)
-      {
-        TopTools_ListIteratorOfListOfShape aItLFIm(*pLFIm);
-        for (; aItLFIm.More(); aItLFIm.Next())
-        {
-          const TopoDS_Shape& aFIm = aItLFIm.Value();
-          if (!aMFS.Contains(aFIm))
-            aBB.Add(aCFHangs, aFIm);
-        }
-      }
-      else
-      {
-        if (!aMFS.Contains(aF))
-          aBB.Add(aCFHangs, aF);
-      }
+      TakeModified(aF, aMVIms, aCFHangs, &aMFS);
     }
   }
 
@@ -3366,27 +3397,41 @@ void RemoveHangingParts(const BOPAlgo_MakerVolume& theMV,
   // Update invalid edges with intersection results
   TopTools_MapOfShape aMEInv;
   Standard_Integer i, aNbE = theInvEdges.Extent();
-  for (i = 1; i <= aNbE; ++i) {
-    const TopoDS_Shape& aEInv = theInvEdges(i);
-    const TopTools_ListOfShape *pLEIm = aMVIms.Seek(aEInv);
-    if (pLEIm)
-    {
-      TopTools_ListIteratorOfListOfShape aItLEIm(*pLEIm);
-      for (; aItLEIm.More(); aItLEIm.Next())
-        aMEInv.Add(aItLEIm.Value());
-    }
-    else
-      aMEInv.Add(aEInv);
-  }
+  for (i = 1; i <= aNbE; ++i)
+    TakeModified(theInvEdges(i), aMVIms, aMEInv);
+
+  // Update inverted edges with intersection results
+  TopTools_MapOfShape aMEInverted;
+  for (TopTools_MapIteratorOfMapOfShape itM(theInvertedEdges); itM.More(); itM.Next())
+    TakeModified(itM.Value(), aMVIms, aMEInverted);
 
   // Tool for getting the origins of the splits
   const TopTools_DataMapOfShapeListOfShape& aMVOrs = theMV.Origins();
 
+  // Find hanging blocks to remove
+  TopTools_ListOfShape aBlocksToRemove;
+
   TopTools_ListIteratorOfListOfShape aItLCBH(aLCBHangs);
   for (; aItLCBH.More(); aItLCBH.Next())
   {
     const TopoDS_Shape& aCBH = aItLCBH.Value();
 
+    // Remove the block containing the inverted edges
+    Standard_Boolean bHasInverted = Standard_False;
+    TopExp_Explorer anExpE(aCBH, TopAbs_EDGE);
+    for (; anExpE.More() && !bHasInverted; anExpE.Next())
+    {
+      const TopoDS_Shape& aE = anExpE.Current();
+      bHasInverted = !aDMEF      .Contains(aE) &&
+                      aMEInverted.Contains(aE);
+    }
+
+    if (bHasInverted)
+    {
+      aBlocksToRemove.Append(aCBH);
+      continue;
+    }
+
     // Check the block to contain invalid split
     Standard_Boolean bHasInvalidFace = Standard_False;
     // Check connectivity to invalid parts
@@ -3408,7 +3453,7 @@ void RemoveHangingParts(const BOPAlgo_MakerVolume& theMV,
       if (!bIsConnected)
       {
         // check edges
-        TopExp_Explorer anExpE(aF, TopAbs_EDGE);
+        anExpE.Init(aF, TopAbs_EDGE);
         for (; anExpE.More() && !bIsConnected; anExpE.Next())
         {
           const TopoDS_Shape& aE = anExpE.Current();
@@ -3421,17 +3466,20 @@ void RemoveHangingParts(const BOPAlgo_MakerVolume& theMV,
           }
         }
         // check vertices
-        TopExp_Explorer anExpV(aF, TopAbs_VERTEX);
-        for (; anExpV.More() && !bIsConnected; anExpV.Next())
+        if (!bIsConnected)
         {
-          const TopoDS_Shape& aV = anExpV.Current();
-          const TopTools_ListOfShape *pLE = aDMVE.Seek(aV);
-          if (pLE)
+          TopExp_Explorer anExpV(aF, TopAbs_VERTEX);
+          for (; anExpV.More() && !bIsConnected; anExpV.Next())
           {
-            TopTools_ListIteratorOfListOfShape aItLE(*pLE);
-            for (; aItLE.More() && !bIsConnected; aItLE.Next())
-              bIsConnected = !aBlockME.Contains(aItLE.Value()) &&
-                              aMEInv  .Contains(aItLE.Value());
+            const TopoDS_Shape& aV = anExpV.Current();
+            const TopTools_ListOfShape *pLE = aDMVE.Seek(aV);
+            if (pLE)
+            {
+              TopTools_ListIteratorOfListOfShape aItLE(*pLE);
+              for (; aItLE.More() && !bIsConnected; aItLE.Next())
+                bIsConnected = !aBlockME.Contains(aItLE.Value()) &&
+                                aMEInv  .Contains(aItLE.Value());
+            }
           }
         }
       }
@@ -3460,12 +3508,17 @@ void RemoveHangingParts(const BOPAlgo_MakerVolume& theMV,
       (!bIsConnected || aMOffsetF.Extent() == 1);
 
     if (bRemove)
-    {
-      // remove the block
-      anExpF.Init(aCBH, TopAbs_FACE);
-      for (; anExpF.More(); anExpF.Next())
-        theMFToRem.Add(anExpF.Current());
-    }
+      aBlocksToRemove.Append(aCBH);
+  }
+
+  // remove the invalidated blocks
+  aItLCBH.Initialize(aBlocksToRemove);
+  for (; aItLCBH.More(); aItLCBH.Next())
+  {
+    const TopoDS_Shape& aCBH = aItLCBH.Value();
+    TopExp_Explorer anExpF(aCBH, TopAbs_FACE);
+    for (; anExpF.More(); anExpF.Next())
+      theMFToRem.Add(anExpF.Current());
   }
 }
 
@@ -6926,13 +6979,16 @@ void UpdateImages(const TopTools_ListOfShape& theLA,
                   TopTools_MapOfShape& theModified)
 {
   TopTools_ListIteratorOfListOfShape aIt(theLA);
-  for (; aIt.More(); aIt.Next()) {
+  for (; aIt.More(); aIt.Next())
+  {
     const TopoDS_Shape& aS = aIt.Value();
     //
     TopTools_ListOfShape* pLSIm = theImages.ChangeSeek(aS);
-    if (!pLSIm) {
+    if (!pLSIm)
+    {
       const TopTools_ListOfShape& aLSIm = theGF.Modified(aS);
-      if (aLSIm.Extent()) {
+      if (aLSIm.Extent())
+      {
         theImages.Bind(aS, aLSIm);
         theModified.Add(aS);
       }
@@ -6946,27 +7002,14 @@ void UpdateImages(const TopTools_ListOfShape& theLA,
     //
     // check modifications of the images
     TopTools_ListIteratorOfListOfShape aIt1(*pLSIm);
-    for (; aIt1.More(); aIt1.Next()) {
+    for (; aIt1.More(); aIt1.Next())
+    {
       const TopoDS_Shape& aSIm = aIt1.Value();
-      const TopTools_ListOfShape& aLSIm1 = theGF.Modified(aSIm);
-      if (aLSIm1.IsEmpty()) {
-        if (aMFence.Add(aSIm)) {
-          aLSImNew.Append(aSIm);
-        }
-      }
-      else {
-        TopTools_ListIteratorOfListOfShape aIt2(aLSIm1);
-        for (; aIt2.More(); aIt2.Next()) {
-          const TopoDS_Shape& aSImIm = aIt2.Value();
-          if (aMFence.Add(aSImIm)) {
-            aLSImNew.Append(aSImIm);
-          }
-        }
-        bModified = Standard_True;
-      }
+      bModified |= TakeModified(aSIm, theGF.Images(), aLSImNew, &aMFence);
     }
     //
-    if (bModified) {
+    if (bModified)
+    {
       *pLSIm = aLSImNew;
       theModified.Add(aS);
     }
@@ -7101,3 +7144,61 @@ void AppendToList(TopTools_ListOfShape& theList,
   }
   theList.Append(theShape);
 }
+
+//=======================================================================
+//function : AddToContainer
+//purpose  : Set of methods to add a shape into container
+//=======================================================================
+static void AddToContainer(const TopoDS_Shape& theS,
+                           TopTools_ListOfShape& theList)
+{
+  theList.Append(theS);
+}
+static Standard_Boolean AddToContainer(const TopoDS_Shape& theS,
+                                       TopTools_MapOfShape& theMap)
+{
+  return theMap.Add(theS);
+}
+static Standard_Boolean AddToContainer(const TopoDS_Shape& theS,
+                                       TopTools_IndexedMapOfShape& theMap)
+{
+  const Standard_Integer aNb = theMap.Extent();
+  const Standard_Integer anInd = theMap.Add(theS);
+  return anInd > aNb;
+}
+static void AddToContainer(const TopoDS_Shape& theS,
+                           TopoDS_Shape& theSOut)
+{
+  BRep_Builder().Add(theSOut, theS);
+}
+
+//=======================================================================
+//function : TakeModified
+//purpose  : Check if the shape has images in the given images map.
+//           Puts in the output map either the images or the shape itself.
+//=======================================================================
+template <class ContainerType, class FenceMapType>
+Standard_Boolean TakeModified(const TopoDS_Shape& theS,
+                              const TopTools_DataMapOfShapeListOfShape& theImages,
+                              ContainerType& theContainer,
+                              FenceMapType* theMFence)
+{
+  const TopTools_ListOfShape *pLSIm = theImages.Seek(theS);
+  if (pLSIm)
+  {
+    TopTools_ListIteratorOfListOfShape itLSIm(*pLSIm);
+    for (; itLSIm.More(); itLSIm.Next())
+    {
+      const TopoDS_Shape& aSIm = itLSIm.Value();
+      if (!theMFence || AddToContainer(aSIm, *theMFence))
+        AddToContainer(aSIm, theContainer);
+    }
+    return Standard_True;
+  }
+  else
+  {
+    if (!theMFence || AddToContainer(theS, *theMFence))
+      AddToContainer(theS, theContainer);
+    return Standard_False;
+  }
+}
diff --git a/tests/offset/shape_type_i_c/XS4 b/tests/offset/shape_type_i_c/XS4
new file mode 100644 (file)
index 0000000..9375d76
--- /dev/null
@@ -0,0 +1,54 @@
+restore [locate_data_file bug30470_input.brep] s
+
+# perform offset operation with increasing offset value
+
+# set props and nb reference values to compare with
+
+# area volume nb_wire nb_face
+set ref_values { { 2.1809e+06  4.43828e+07 50 49 } \
+                 { 2.13057e+06 4.65386e+07 50 49 } \
+                 { 2.0795e+06  4.86437e+07 50 49 } \
+                 { 2.02768e+06 5.06974e+07 50 49 } \
+                 { 1.97511e+06 5.26988e+07 50 49 } \
+                 { 1.9218e+06  5.46473e+07 50 49 } \
+                 { 1.86774e+06 5.65422e+07 50 49 } \
+                 { 1.81293e+06 5.83826e+07 50 49 } \
+                 { 1.81346e+06 6.01887e+07 23 23 } \
+                 { 1.82605e+06 6.20098e+07 25 25 } \
+                 { 1.83436e+06 6.384e+07   25 25 } \
+                 { 1.84239e+06 6.56784e+07 25 25 } \
+                 { 1.85014e+06 6.75247e+07 25 25 } \
+                 { 1.85761e+06 6.93786e+07 27 27 } \
+                 { 1.86443e+06 7.12397e+07 27 27 } \
+                 { 1.87034e+06 7.31071e+07 27 27 } \
+                 { 1.87534e+06 7.498e+07   27 27 } \
+                 { 1.87945e+06 7.68575e+07 27 27 } \
+                 { 1.88264e+06 7.87386e+07 27 27 } \
+                 { 1.88494e+06 8.06225e+07 27 27 } \
+                 { 1.88632e+06 8.25082e+07 27 27 } \
+                 { 1.88681e+06 8.43948e+07 27 27 } \
+                 { 1.88638e+06 8.62815e+07 27 27 } \
+                 { 1.88506e+06 8.81673e+07 27 27 } \
+                 { 1.88659e+06 9.0052e+07  25 25 } \
+                 { 1.89452e+06 9.19426e+07 25 25 } \
+                 { 1.90186e+06 9.38408e+07 25 25 } \
+                 { 1.90862e+06 9.57461e+07 25 25 } \
+                 { 1.91479e+06 9.76578e+07 25 25 } \
+                 { 1.9206e+06  9.95755e+07 27 26 } \
+                 { 1.92646e+06 1.01499e+08 27 26 } \
+                 { 1.93235e+06 1.03428e+08 27 26 } \
+                 { 1.9383e+06  1.05364e+08 27 26 } \
+                 { 1.94429e+06 1.07305e+08 27 26 } \
+                 { 1.95032e+06 1.09252e+08 27 26 } \
+                 { 1.95641e+06 1.11206e+08 27 26 } \
+                 { 1.96254e+06 1.13165e+08 27 26 } \
+                 { 1.96871e+06 1.15131e+08 27 26 } \
+                 { 1.97494e+06 1.17103e+08 27 26 } \
+                 { 1.9812e+06  1.19081e+08 27 26 } }
+
+perform_offset_increasing s 1 40 1 $ref_values
+
+copy r17 result
+copy r17_unif result_unif
+
+checkview -display result_unif -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/offset/shape_type_i_c/XS5 b/tests/offset/shape_type_i_c/XS5
new file mode 100644 (file)
index 0000000..03d1ac0
--- /dev/null
@@ -0,0 +1,54 @@
+restore [locate_data_file bug30470_input_trim1.brep] s
+
+# perform offset operation with increasing offset value
+
+# set props and nb reference values to compare with
+
+# area volume nb_wire nb_face
+set ref_values { { 1.31124e+06 2.58872e+07 43 42 } \
+                 { 1.27726e+06 2.71815e+07 43 42 } \
+                 { 1.24279e+06 2.84416e+07 43 42 } \
+                 { 1.20783e+06 2.96669e+07 43 42 } \
+                 { 1.17237e+06 3.08571e+07 43 42 } \
+                 { 1.13642e+06 3.20115e+07 43 42 } \
+                 { 1.09997e+06 3.31297e+07 43 42 } \
+                 { 1.06303e+06 3.42113e+07 43 42 } \
+                 { 1.06451e+06 3.52701e+07 19 19 } \
+                 { 1.07229e+06 3.63398e+07 21 21 } \
+                 { 1.07578e+06 3.74139e+07 21 21 } \
+                 { 1.07899e+06 3.84913e+07 21 21 } \
+                 { 1.08193e+06 3.95718e+07 21 21 } \
+                 { 1.0846e+06  4.06551e+07 21 21 } \
+                 { 1.08699e+06 4.17409e+07 21 21 } \
+                 { 1.0891e+06  4.28289e+07 21 21 } \
+                 { 1.09094e+06 4.3919e+07  21 21 } \
+                 { 1.0925e+06  4.50107e+07 21 21 } \
+                 { 1.09379e+06 4.61039e+07 21 21 } \
+                 { 1.09481e+06 4.71982e+07 21 21 } \
+                 { 1.09555e+06 4.82934e+07 21 21 } \
+                 { 1.09601e+06 4.93892e+07 21 21 } \
+                 { 1.0962e+06  5.04853e+07 21 21 } \
+                 { 1.09611e+06 5.15815e+07 21 21 } \
+                 { 1.09952e+06 5.26781e+07 19 19 } \
+                 { 1.10994e+06 5.37829e+07 19 19 } \
+                 { 1.12041e+06 5.4898e+07  19 19 } \
+                 { 1.13093e+06 5.60237e+07 19 19 } \
+                 { 1.1415e+06  5.71599e+07 19 19 } \
+                 { 1.15211e+06 5.83067e+07 19 19 } \
+                 { 1.16276e+06 5.94641e+07 19 19 } \
+                 { 1.17347e+06 6.06323e+07 19 19 } \
+                 { 1.18422e+06 6.18111e+07 19 19 } \
+                 { 1.19502e+06 6.30007e+07 19 19 } \
+                 { 1.20586e+06 6.42011e+07 19 19 } \
+                 { 1.21675e+06 6.54124e+07 19 19 } \
+                 { 1.22769e+06 6.66347e+07 19 19 } \
+                 { 1.23867e+06 6.78678e+07 19 19 } \
+                 { 1.2497e+06  6.9112e+07  19 19 } \
+                 { 1.26077e+06 7.03672e+07 19 19 } }
+
+perform_offset_increasing s 1 40 1 $ref_values
+
+copy r17 result
+copy r17_unif result_unif
+
+checkview -display result_unif -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/offset/shape_type_i_c/XS6 b/tests/offset/shape_type_i_c/XS6
new file mode 100644 (file)
index 0000000..d130c77
--- /dev/null
@@ -0,0 +1,54 @@
+restore [locate_data_file bug30470_input_trim2.brep] s
+
+# perform offset operation with increasing offset value
+
+# set props and nb reference values to compare with
+
+# area volume nb_wire nb_face
+set ref_values { { 1.0108e+06   1.99437e+07  33 32 } \
+                 { 981289       2.09398e+07  33 32 } \
+                 { 951548       2.19062e+07  33 32 } \
+                 { 921582       2.28428e+07  33 32 } \
+                 { 891389       2.37493e+07  33 32 } \
+                 { 860971       2.46255e+07  33 32 } \
+                 { 830326       2.54712e+07  33 32 } \
+                 { 799456       2.62861e+07  33 32 } \
+                 { 800096       2.70819e+07  16 16 } \
+                 { 808054       2.78866e+07  17 17 } \
+                 { 813891       2.86976e+07  17 17 } \
+                 { 819610       2.95143e+07  17 17 } \
+                 { 825212       3.03368e+07  17 17 } \
+                 { 830698       3.11647e+07  17 17 } \
+                 { 836069       3.19981e+07  17 17 } \
+                 { 841324       3.28368e+07  17 17 } \
+                 { 846463       3.36807e+07  17 17 } \
+                 { 851486       3.45297e+07  17 17 } \
+                 { 856393       3.53837e+07  17 17 } \
+                 { 861185       3.62425e+07  17 17 } \
+                 { 865860       3.7106e+07   17 17 } \
+                 { 870420       3.79741e+07  17 17 } \
+                 { 874865       3.88468e+07  17 17 } \
+                 { 879193       3.97238e+07  17 17 } \
+                 { 885288       4.06055e+07  16 16 } \
+                 { 894915       4.14956e+07  16 16 } \
+                 { 904587       4.23953e+07  16 16 } \
+                 { 914305       4.33047e+07  16 16 } \
+                 { 924067       4.42239e+07  16 16 } \
+                 { 933874       4.51529e+07  16 16 } \
+                 { 943726       4.60917e+07  16 16 } \
+                 { 953623       4.70404e+07  16 16 } \
+                 { 963565       4.7999e+07   16 16 } \
+                 { 973552       4.89675e+07  16 16 } \
+                 { 983584       4.99461e+07  16 16 } \
+                 { 993661       5.09347e+07  16 16 } \
+                 { 1.00378e+06  5.19334e+07  16 16 } \
+                 { 1.01395e+06  5.29423e+07  16 16 } \
+                 { 1.02416e+06  5.39613e+07  16 16 } \
+                 { 1.03442e+06  5.49906e+07  16 16 } }
+
+perform_offset_increasing s 1 40 1 $ref_values
+
+copy r17 result
+copy r17_unif result_unif
+
+checkview -display result_unif -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/offset/shape_type_i_c/XS7 b/tests/offset/shape_type_i_c/XS7
new file mode 100644 (file)
index 0000000..2843892
--- /dev/null
@@ -0,0 +1,54 @@
+restore [locate_data_file bug30470_input_trim3.brep] s
+
+# perform offset operation with increasing offset value
+
+# set props and nb reference values to compare with
+
+# area volume nb_wire nb_face
+set ref_values { { 773892 1.5856e+07  23 22 } \
+                 { 749115 1.66175e+07 23 22 } \
+                 { 724383 1.73543e+07 23 22 } \
+                 { 699696 1.80663e+07 23 22 } \
+                 { 675053 1.87537e+07 23 22 } \
+                 { 650456 1.94164e+07 23 22 } \
+                 { 625904 2.00546e+07 23 22 } \
+                 { 601396 2.06682e+07 23 22 } \
+                 { 601493 2.12666e+07 13 13 } \
+                 { 609929 2.18723e+07 13 13 } \
+                 { 618409 2.24865e+07 13 13 } \
+                 { 626935 2.31091e+07 13 13 } \
+                 { 635505 2.37403e+07 13 13 } \
+                 { 644121 2.43802e+07 13 13 } \
+                 { 652781 2.50286e+07 13 13 } \
+                 { 661486 2.56857e+07 13 13 } \
+                 { 670236 2.63516e+07 13 13 } \
+                 { 679032 2.70262e+07 13 13 } \
+                 { 687872 2.77097e+07 13 13 } \
+                 { 696757 2.8402e+07  13 13 } \
+                 { 705687 2.91032e+07 13 13 } \
+                 { 714662 2.98134e+07 13 13 } \
+                 { 723682 3.05325e+07 13 13 } \
+                 { 732747 3.12607e+07 13 13 } \
+                 { 741857 3.1998e+07  13 13 } \
+                 { 751012 3.27445e+07 13 13 } \
+                 { 760212 3.35001e+07 13 13 } \
+                 { 769456 3.42649e+07 13 13 } \
+                 { 778746 3.5039e+07  13 13 } \
+                 { 788081 3.58224e+07 13 13 } \
+                 { 797461 3.66152e+07 13 13 } \
+                 { 806885 3.74174e+07 13 13 } \
+                 { 816355 3.8229e+07  13 13 } \
+                 { 825869 3.90501e+07 13 13 } \
+                 { 835429 3.98807e+07 13 13 } \
+                 { 845033 4.07209e+07 13 13 } \
+                 { 854683 4.15708e+07 13 13 } \
+                 { 864377 4.24303e+07 13 13 } \
+                 { 874116 4.32996e+07 13 13 } \
+                 { 883901 4.41786e+07 13 13 } }
+
+perform_offset_increasing s 1 40 1 $ref_values
+
+copy r17 result
+copy r17_unif result_unif
+
+checkview -display result_unif -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/offset/shape_type_i_c/XS8 b/tests/offset/shape_type_i_c/XS8
new file mode 100644 (file)
index 0000000..7552036
--- /dev/null
@@ -0,0 +1,54 @@
+restore [locate_data_file bug30470_input_trim4.brep] s
+
+# perform offset operation with increasing offset value
+
+# set props and nb reference values to compare with
+
+# area volume nb_wire nb_face
+set ref_values { { 289134 4.40968e+06 16 16 } \
+                 { 288310 4.69842e+06 16 16 } \
+                 { 287307 4.98625e+06 16 16 } \
+                 { 286126 5.27298e+06 16 16 } \
+                 { 284767 5.55844e+06 16 16 } \
+                 { 283229 5.84245e+06 16 16 } \
+                 { 281513 6.12484e+06 16 16 } \
+                 { 279618 6.40542e+06 16 16 } \
+                 { 284722 6.68669e+06 9  9  } \
+                 { 292308 6.9752e+06  9  9  } \
+                 { 299985 7.27133e+06 9  9  } \
+                 { 307754 7.5752e+06  9  9  } \
+                 { 315614 7.88687e+06 9  9  } \
+                 { 323566 8.20645e+06 9  9  } \
+                 { 331611 8.53403e+06 9  9  } \
+                 { 339748 8.86971e+06 9  9  } \
+                 { 347978 9.21356e+06 9  9  } \
+                 { 356301 9.56569e+06 9  9  } \
+                 { 364716 9.92619e+06 9  9  } \
+                 { 373224 1.02952e+07 9  9  } \
+                 { 381824 1.06727e+07 9  9  } \
+                 { 390517 1.10588e+07 9  9  } \
+                 { 399302 1.14537e+07 9  9  } \
+                 { 408180 1.18575e+07 9  9  } \
+                 { 417150 1.22701e+07 9  9  } \
+                 { 426213 1.26918e+07 9  9  } \
+                 { 435369 1.31226e+07 9  9  } \
+                 { 444617 1.35626e+07 9  9  } \
+                 { 453958 1.40118e+07 9  9  } \
+                 { 463391 1.44705e+07 9  9  } \
+                 { 472917 1.49387e+07 9  9  } \
+                 { 482536 1.54164e+07 9  9  } \
+                 { 492247 1.59038e+07 9  9  } \
+                 { 502050 1.64009e+07 9  9  } \
+                 { 511947 1.69079e+07 9  9  } \
+                 { 521935 1.74248e+07 9  9  } \
+                 { 532017 1.79518e+07 9  9  } \
+                 { 542190 1.84889e+07 9  9  } \
+                 { 552457 1.90362e+07 9  9  } \
+                 { 562816 1.95938e+07 9  9  } }
+
+perform_offset_increasing s 1 40 1 $ref_values
+
+copy r17 result
+copy r17_unif result_unif
+
+checkview -display result_unif -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/offset/shape_type_i_c/XS9 b/tests/offset/shape_type_i_c/XS9
new file mode 100644 (file)
index 0000000..46e9515
--- /dev/null
@@ -0,0 +1,54 @@
+restore [locate_data_file bug30470_input_trim5.brep] s
+
+# perform offset operation with increasing offset value
+
+# set props and nb reference values to compare with
+
+# area volume nb_wire nb_face
+set ref_values { { 253148 3.95828e+06 17 17 } \
+                 { 250484 4.21012e+06 17 17 } \
+                 { 247598 4.45918e+06 17 17 } \
+                 { 244489 4.70524e+06 17 17 } \
+                 { 241158 4.94808e+06 17 17 } \
+                 { 237603 5.18748e+06 17 17 } \
+                 { 233826 5.42321e+06 17 17 } \
+                 { 229826 5.65506e+06 17 17 } \
+                 { 232781 5.88547e+06 10 10 } \
+                 { 238173 6.12094e+06 10 10 } \
+                 { 243612 6.36183e+06 10 10 } \
+                 { 249098 6.60818e+06 10 10 } \
+                 { 254631 6.86004e+06 10 10 } \
+                 { 260212 7.11746e+06 10 10 } \
+                 { 265841 7.38048e+06 10 10 } \
+                 { 271519 7.64915e+06 10 10 } \
+                 { 277245 7.92353e+06 10 10 } \
+                 { 283018 8.20366e+06 10 10 } \
+                 { 288841 8.48958e+06 10 10 } \
+                 { 294711 8.78136e+06 10 10 } \
+                 { 300630 9.07902e+06 10 10 } \
+                 { 306597 9.38263e+06 10 10 } \
+                 { 312612 9.69223e+06 10 10 } \
+                 { 318675 1.00079e+07 10 10 } \
+                 { 324787 1.03296e+07 10 10 } \
+                 { 330946 1.06575e+07 10 10 } \
+                 { 337154 1.09915e+07 10 10 } \
+                 { 343411 1.13318e+07 10 10 } \
+                 { 349715 1.16783e+07 10 10 } \
+                 { 356068 1.20312e+07 10 10 } \
+                 { 362469 1.23905e+07 10 10 } \
+                 { 368918 1.27562e+07 10 10 } \
+                 { 375415 1.31283e+07 10 10 } \
+                 { 381961 1.3507e+07  10 10 } \
+                 { 388555 1.38923e+07 10 10 } \
+                 { 395197 1.42842e+07 10 10 } \
+                 { 401887 1.46827e+07 10 10 } \
+                 { 408625 1.50879e+07 10 10 } \
+                 { 415412 1.55e+07    10 10 } \
+                 { 422247 1.59188e+07 10 10 } }
+
+perform_offset_increasing s 1 40 1 $ref_values
+
+copy r17 result
+copy r17_unif result_unif
+
+checkview -display result_unif -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/offset/shape_type_i_c/XT1 b/tests/offset/shape_type_i_c/XT1
new file mode 100644 (file)
index 0000000..2567e28
--- /dev/null
@@ -0,0 +1,20 @@
+puts "TODO CR27414 ALL: Error : The area of result shape is"
+puts "TODO CR27414 ALL: Error : The volume of result shape is"
+puts "TODO CR27414 ALL: Error :  is WRONG because number of"
+
+polyline p 0 0 0 0 0 10 2 0 10 2 0 2 3 0 6 5 0 6 5 0 0 0 0 0
+mkplane f p
+prism s f 0 5 0
+
+offsetparameter 1e-7 c i r
+offsetload s 1
+explode s f
+offsetonface s_4 6
+offsetperform result
+
+checkprops result -s 410 -v 504
+
+unifysamedom result_unif result
+checknbshapes result_unif -vertex 12 -edge 18 -wire 8 -face 8 -shell 1 -solid 1
+
+checkview -display result_unif -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/offset/shape_type_i_c/XT2 b/tests/offset/shape_type_i_c/XT2
new file mode 100644 (file)
index 0000000..35b34b8
--- /dev/null
@@ -0,0 +1,16 @@
+polyline p 0 0 0 0 0 10 2 0 10 2 0 2 3 0 6 5 0 6 5 0 0 0 0 0
+mkplane f p
+prism s f 0 5 0
+
+offsetparameter 1e-7 c i r
+offsetload s 1
+explode s f
+offsetonface s_4 4.5
+offsetperform result
+
+checkprops result -s 410 -v 504
+
+unifysamedom result_unif result
+checknbshapes result_unif -vertex 12 -edge 18 -wire 8 -face 8 -shell 1 -solid 1
+
+checkview -display result_unif -2d -path ${imagedir}/${test_image}.png
index eb86413722a6a7449a156a591d7b3996fea6790d..86335bbec9d6c6f9e0040e93ddc7e57bec308b4d 100644 (file)
@@ -1,11 +1,10 @@
-puts "TODO OCC27414 ALL: Error: The command cannot be built"
-puts "TODO OCC27414 ALL: gives an empty result"
-puts "TODO OCC27414 ALL: TEST INCOMPLETE"
+puts "TODO CR27414 ALL: Error : The area of result shape is"
+puts "TODO CR27414 ALL: Faulty shapes in variables faulty_1 to faulty_"
 
 restore [locate_data_file bug26917_M2_trim34.brep] s
 
 OFFSETSHAPE 8 {} $calcul $type
 
-checkprops result -v 0
+checkprops result -s 0
 
 checknbshapes result -shell 1
index f6dbca54c8fe412a4cbbe26e8a2825c44a683f36..559778754f5147ccce9ac2d5113432bafbed90b9 100644 (file)
@@ -1,4 +1,147 @@
-#Shell no rough and rounded mode
-
+# Mode - Complete
 set calcul "c"
+# Join type - Intersection
 set type "i"
+
+proc compare_prop_values {prop m_res m_ref} {
+  if { ($m_ref != 0 && abs (($m_ref - $m_res) / double($m_ref)) > 1.e-2) || ($m_res == 0 && $m_ref != 0) } {
+    puts "Error: The $prop of result shape is $m_res, expected $m_ref"
+    return 0
+  } else {
+    puts "OK: The $prop of result shape is as expected"
+    return 1
+  }
+}
+
+proc compare_nbs {entity nb_res nb_ref} {
+  if {$nb_res != $nb_ref} {
+    puts "Error: number of $entity entities in the result shape is $nb_res, expected $nb_ref"
+    return 0
+  } else {
+    puts "OK: number of $entity entities in the result shape is as expected"
+    return 1
+  }
+}
+
+proc perform_offset {theShape theValue} {
+  upvar $theShape TheShape
+  
+  global r${theValue}
+  global r${theValue}_unif
+
+  tcopy TheShape sx
+  offsetparameter 1.e-7 c i r
+  offsetload sx ${theValue}
+  offsetperform r${theValue}
+  
+  if {![catch { checkshape r${theValue} } ] } {
+    unifysamedom r${theValue}_unif r${theValue}
+    return 1
+  }
+  return 0
+}
+
+proc perform_offsets {theShape theOffsetValues theRefValues} {
+
+  upvar $theShape TheShape
+  
+  set nbRefValues [llength $theRefValues]
+  
+  set failed_operations {}
+  set statistics {}
+
+  set i 0
+  
+  foreach offset $theOffsetValues { 
+    
+    global r${offset}
+    global r${offset}_unif
+
+    set operation_done [perform_offset TheShape ${offset}]
+    
+    # stats
+    set area_value 0
+    set volume_value 0
+    set nbwires_value 0
+    set nbfaces_value 0
+    
+    set checks_res {}
+    
+    if { $operation_done } {
+   
+      set area_value [lindex [sprops r${offset}] 2]
+      set volume_value [lindex [vprops r${offset}] 2]
+      
+      set check 0
+      set refs {}
+      
+      if { $nbRefValues > $i } {
+        set refs [lindex $theRefValues $i]
+        if { [llength $refs] == 4} {
+          set check 1
+        }
+      }
+      
+      if { $check } {
+        lappend checks_res [compare_prop_values "area" ${area_value} [lindex $refs 0]]
+        lappend checks_res [compare_prop_values "volume" ${volume_value} [lindex $refs 1]]
+      }
+
+      set nbshapes_value [nbshapes r${offset}_unif]
+      set nbwires_value [lindex $nbshapes_value 13]
+      set nbfaces_value [lindex $nbshapes_value 16]
+      set nbshells_value [lindex $nbshapes_value 19]
+      set nbsolids_value [lindex $nbshapes_value 22]
+    
+      if { $check } {
+        lappend checks_res [compare_nbs "wire" $nbwires_value [lindex $refs 2]]
+        lappend checks_res [compare_nbs "face" $nbfaces_value [lindex $refs 3]]
+      }
+      
+      lappend checks_res [compare_nbs "shell" $nbshells_value 1]
+      lappend checks_res [compare_nbs "solid" $nbsolids_value 1]
+    }
+
+    set OK $operation_done
+    
+    if {$OK == 1} {
+      foreach x $checks_res {
+        if {$x == 0} {
+          set OK 0
+          break
+        }
+      }
+    }
+    
+    set status "OK"
+    if { $OK == 0 } {
+      puts "Error: operation with offset value ${offset} has failed"
+      
+      lappend failed_operations ${offset}
+      set status "KO"
+    }
+    
+    lappend statistics "Offset value ${offset} - $status: area - ${area_value};\t volume - ${volume_value};\t wires - ${nbwires_value};\t faces - ${nbfaces_value}"
+    incr i
+  }
+  
+  if {[llength $failed_operations] > 0} {
+    puts "Operations with following offset values have failed: $failed_operations"
+  }
+  
+  puts "Statistics:"
+  foreach str $statistics { puts "\t$str" }
+}
+
+proc perform_offset_increasing {theShape theMinVal theStopVal theStep theRefValues} {
+
+  upvar $theShape TheShape
+
+  set values {}
+  
+  for {set i $theMinVal} {$i <= $theStopVal} {set i [expr $i + $theStep]} {
+    lappend values $i
+  }
+  
+  perform_offsets TheShape $values $theRefValues
+}