0027814: Parallelize BRepCheck_Analyzer
authorasuraven <asuraven@opencascade.com>
Mon, 21 Jun 2021 16:15:09 +0000 (19:15 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 23 Jul 2021 15:15:55 +0000 (18:15 +0300)
Change BRepCheck_Analyzer::Perform algorithm from recursion to 'for' loop
Add parallelization to BRepCheck_Analyzer::Perform
Add '-parallel' option to checkshape command to use parallelization. Default mode is single-thread.

mutex as Handle

40 files changed:
dox/user_guides/draw_test_harness/draw_test_harness.md
src/BRepCheck/BRepCheck_Analyzer.cxx
src/BRepCheck/BRepCheck_Analyzer.hxx
src/BRepCheck/BRepCheck_Analyzer.lxx [deleted file]
src/BRepCheck/BRepCheck_DataMapIteratorOfDataMapOfShapeListOfStatus.hxx [deleted file]
src/BRepCheck/BRepCheck_DataMapIteratorOfDataMapOfShapeResult.hxx [deleted file]
src/BRepCheck/BRepCheck_DataMapOfShapeListOfStatus.hxx
src/BRepCheck/BRepCheck_DataMapOfShapeResult.hxx [deleted file]
src/BRepCheck/BRepCheck_Edge.cxx
src/BRepCheck/BRepCheck_Face.cxx
src/BRepCheck/BRepCheck_IndexedDataMapOfShapeResult.hxx [new file with mode: 0644]
src/BRepCheck/BRepCheck_ListOfStatus.hxx
src/BRepCheck/BRepCheck_Result.cxx
src/BRepCheck/BRepCheck_Result.hxx
src/BRepCheck/BRepCheck_Result.lxx [deleted file]
src/BRepCheck/BRepCheck_Shell.cxx
src/BRepCheck/BRepCheck_Solid.cxx
src/BRepCheck/BRepCheck_Vertex.cxx
src/BRepCheck/BRepCheck_Wire.cxx
src/BRepCheck/FILES
src/BRepTest/BRepTest_CheckCommands.cxx
src/Graphic3d/Graphic3d_MediaTexture.cxx
src/Graphic3d/Graphic3d_MediaTexture.hxx
src/Graphic3d/Graphic3d_MediaTextureSet.cxx
src/Graphic3d/Graphic3d_MediaTextureSet.hxx
src/Standard/Standard_Mutex.hxx
tests/heal/checkshape/begin [new file with mode: 0644]
tests/heal/checkshape/bug27814_1 [new file with mode: 0644]
tests/heal/checkshape/bug27814_10 [new file with mode: 0644]
tests/heal/checkshape/bug27814_11 [new file with mode: 0644]
tests/heal/checkshape/bug27814_2 [new file with mode: 0644]
tests/heal/checkshape/bug27814_3 [new file with mode: 0644]
tests/heal/checkshape/bug27814_4 [new file with mode: 0644]
tests/heal/checkshape/bug27814_5 [new file with mode: 0644]
tests/heal/checkshape/bug27814_6 [new file with mode: 0644]
tests/heal/checkshape/bug27814_7 [new file with mode: 0644]
tests/heal/checkshape/bug27814_8 [new file with mode: 0644]
tests/heal/checkshape/bug27814_9 [new file with mode: 0644]
tests/heal/end
tests/heal/grids.list

index b10b73d..f86168f 100644 (file)
@@ -7618,7 +7618,7 @@ xdistc2dc2dss c2d1_1 c2d2_1 s1 s2 0 1 1000
 
 Syntax:
 ~~~~{.php}
-checkshape [-top] shape [result] [-short] 
+checkshape [-top] shape [result] [-short] [-parallel]
 ~~~~
 
 Where: 
@@ -7626,6 +7626,7 @@ Where:
 * *shape* -- the only required parameter, defines the name of the shape to check. 
 * *result* -- optional parameter, defines custom prefix for the output shape names.
 * *short* -- a short description of the check. 
+* *parallel* -- run check in multithread mode.
 
 **checkshape** examines the selected object for topological and geometric coherence. The object should be a three dimensional shape. 
 
index a4aee46..f478ef8 100644 (file)
@@ -14,8 +14,8 @@
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-
 #include <BRepCheck_Analyzer.hxx>
+
 #include <BRepCheck_Edge.hxx>
 #include <BRepCheck_Face.hxx>
 #include <BRepCheck_ListIteratorOfListOfStatus.hxx>
 #include <BRepCheck_Solid.hxx>
 #include <BRepCheck_Vertex.hxx>
 #include <BRepCheck_Wire.hxx>
+#include <NCollection_Array1.hxx>
+#include <NCollection_Shared.hxx>
+#include <OSD_Parallel.hxx>
 #include <Standard_ErrorHandler.hxx>
 #include <Standard_Failure.hxx>
+#include <Standard_Mutex.hxx>
 #include <Standard_NoSuchObject.hxx>
 #include <Standard_NullObject.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopoDS_Shape.hxx>
 #include <TopTools_MapOfShape.hxx>
 
-//=======================================================================
-//function : Init
-//purpose  : 
-//=======================================================================
-void BRepCheck_Analyzer::Init(const TopoDS_Shape& S,
-         const Standard_Boolean B)
-{
-  if (S.IsNull()) {
-    throw Standard_NullObject();
-  }
-  myShape = S;
-  myMap.Clear();
-  Put(S,B);
-  Perform(S);
-}
-//=======================================================================
-//function : Put
-//purpose  : 
-//=======================================================================
-void BRepCheck_Analyzer::Put(const TopoDS_Shape& S,
-                             const Standard_Boolean B)
+//! Functor for multi-threaded execution.
+class BRepCheck_ParallelAnalyzer
 {
-  if (!myMap.IsBound(S)) {
-    Handle(BRepCheck_Result) HR;
-    switch (S.ShapeType()) {
-    case TopAbs_VERTEX:
-      HR = new BRepCheck_Vertex(TopoDS::Vertex(S));
-      break;
-    case TopAbs_EDGE:
-      HR = new BRepCheck_Edge(TopoDS::Edge(S));
-      Handle(BRepCheck_Edge)::DownCast(HR)->GeometricControls(B);
-      break;
-    case TopAbs_WIRE:
-      HR = new BRepCheck_Wire(TopoDS::Wire(S));
-      Handle(BRepCheck_Wire)::DownCast(HR)->GeometricControls(B);
-      break;
-    case TopAbs_FACE:
-      HR = new BRepCheck_Face(TopoDS::Face(S));
-      Handle(BRepCheck_Face)::DownCast(HR)->GeometricControls(B);
-      break;
-    case TopAbs_SHELL:
-      HR = new BRepCheck_Shell(TopoDS::Shell(S));
-      break;
-    case TopAbs_SOLID:
-      HR = new BRepCheck_Solid(TopoDS::Solid(S));
-      break;
-    case TopAbs_COMPSOLID:
-    case TopAbs_COMPOUND:
-      break;
-    default:
-      break;
-    }
-    myMap.Bind(S,HR);
-    for(TopoDS_Iterator theIterator(S);theIterator.More();theIterator.Next()) {
-      Put(theIterator.Value(),B); // performs minimum on each shape
-    }
+public:
+  BRepCheck_ParallelAnalyzer (NCollection_Array1< NCollection_Array1<TopoDS_Shape> >& theArray,
+                              const BRepCheck_IndexedDataMapOfShapeResult& theMap)
+  : myArray (theArray),
+    myMap (theMap)
+  {
+    //
   }
-}
-//=======================================================================
-//function : Perform
-//purpose  : 
-//=======================================================================
-void BRepCheck_Analyzer::Perform(const TopoDS_Shape& S)
-{
-  for(TopoDS_Iterator theIterator(S);theIterator.More();theIterator.Next()) 
-    Perform(theIterator.Value());
-  
-  //
-  TopAbs_ShapeEnum styp;
-  TopExp_Explorer exp;
-  //
-  styp = S.ShapeType();
-  
-  switch (styp) 
+
+  void operator() (const Standard_Integer theVectorIndex) const
   {
-  case TopAbs_VERTEX: 
-    // modified by NIZHNY-MKK  Wed May 19 16:56:16 2004.BEGIN
-    // There is no need to check anything.
-    //       if (myShape.IsSame(S)) {
-    //  myMap(S)->Blind();
-    //       }
-    // modified by NIZHNY-MKK  Wed May 19 16:56:23 2004.END
-  
-    break;
-  case TopAbs_EDGE:
+    TopExp_Explorer exp;
+    for (Standard_Integer aShapeIter = myArray[theVectorIndex].Lower();
+         aShapeIter <= myArray[theVectorIndex].Upper(); ++aShapeIter)
     {
-      Handle(BRepCheck_Result)& aRes = myMap(S);
-
-      try
+      const TopoDS_Shape& aShape = myArray[theVectorIndex][aShapeIter];
+      const TopAbs_ShapeEnum aType = aShape.ShapeType();
+      const Handle(BRepCheck_Result)& aResult = myMap.FindFromKey (aShape);
+      switch (aType)
       {
-        BRepCheck_Status ste = Handle(BRepCheck_Edge)::
-          DownCast(aRes)->CheckPolygonOnTriangulation(TopoDS::Edge(S));
-
-        if(ste != BRepCheck_NoError)
+        case TopAbs_VERTEX:
         {
-          Handle(BRepCheck_Edge)::DownCast(aRes)->SetStatus(ste);
+          // modified by NIZHNY-MKK  Wed May 19 16:56:16 2004.BEGIN
+          // There is no need to check anything.
+          //       if (aShape.IsSame(S)) {
+          //  myMap(S)->Blind();
+          //       }
+          // modified by NIZHNY-MKK  Wed May 19 16:56:23 2004.END
+          break;
         }
-      }
-      catch(Standard_Failure const& anException) {
-#ifdef OCCT_DEBUG
-        std::cout<<"BRepCheck_Analyzer : ";
-        anException.Print(std::cout);  
-        std::cout<<std::endl;
-#endif
-        (void)anException;
-        if ( ! myMap(S).IsNull() )
-        {
-          myMap(S)->SetFailStatus(S);
-        }
-
-        if ( ! aRes.IsNull() )
-        {
-          aRes->SetFailStatus(S);
-        }
-      }
-
-      TopTools_MapOfShape MapS;
-      
-      for (exp.Init(S,TopAbs_VERTEX);exp.More(); exp.Next())
-      {
-        const TopoDS_Shape& aVertex = exp.Current();
-        try
-        {
-          OCC_CATCH_SIGNALS
-          if (MapS.Add(aVertex))
-            myMap(aVertex)->InContext(S);
-        }
-        catch(Standard_Failure const& anException) {
-#ifdef OCCT_DEBUG
-          std::cout<<"BRepCheck_Analyzer : ";
-          anException.Print(std::cout);  
-          std::cout<<std::endl;
-#endif
-          (void)anException;
-          if ( ! myMap(S).IsNull() )
-            myMap(S)->SetFailStatus(S);
-
-          Handle(BRepCheck_Result) aResOfVertex = myMap(aVertex);
-
-          if ( !aResOfVertex.IsNull() )
-          {
-            aResOfVertex->SetFailStatus(aVertex);
-            aResOfVertex->SetFailStatus(S);
-          }
-        }//catch(Standard_Failure)
-      }//for (exp.Init(S,TopAbs_VERTEX);exp.More(); exp.Next())
-    }
-    break;
-  case TopAbs_WIRE:
-    {
-    }
-    break;
-  case TopAbs_FACE:
-    {
-      TopTools_MapOfShape MapS;
-      for (exp.Init(S,TopAbs_VERTEX);exp.More(); exp.Next())
-      {
-        try
+        case TopAbs_EDGE:
         {
-          OCC_CATCH_SIGNALS
-          if (MapS.Add(exp.Current()))
+          try
           {
-            myMap(exp.Current())->InContext(S);
+            Handle(BRepCheck_Edge) aResEdge = Handle(BRepCheck_Edge)::DownCast(aResult);
+            const BRepCheck_Status ste = aResEdge->CheckPolygonOnTriangulation (TopoDS::Edge (aShape));
+            if (ste != BRepCheck_NoError)
+            {
+              aResEdge->SetStatus (ste);
+            }
           }
-        }
-        catch(Standard_Failure const& anException) {
-#ifdef OCCT_DEBUG
-          std::cout<<"BRepCheck_Analyzer : ";
-          anException.Print(std::cout);  
-          std::cout<<std::endl;
-#endif
-          (void)anException;
-          if ( ! myMap(S).IsNull() )
+          catch (Standard_Failure const& anException)
           {
-            myMap(S)->SetFailStatus(S);
+            (void)anException;
+            if (!aResult.IsNull())
+            {
+              aResult->SetFailStatus (aShape);
+            }
           }
-          
-          Handle(BRepCheck_Result) aRes = myMap(exp.Current());
 
-          if ( ! aRes.IsNull() )
+          TopTools_MapOfShape MapS;
+          for (exp.Init (aShape, TopAbs_VERTEX); exp.More(); exp.Next())
           {
-            aRes->SetFailStatus(exp.Current());
-            aRes->SetFailStatus(S);
-          }
-        }
-      }
-
-      Standard_Boolean performwire = Standard_True;
-      Standard_Boolean isInvalidTolerance = Standard_False;
-      MapS.Clear();
-      for (exp.Init(S,TopAbs_EDGE);exp.More(); exp.Next())
-      {
-        try
-        {
-          OCC_CATCH_SIGNALS
-          if (MapS.Add(exp.Current()))
-          {
-            Handle(BRepCheck_Result)& res = myMap(exp.Current());
-            res->InContext(S);
-            if (performwire)
+            const TopoDS_Shape& aVertex = exp.Current();
+            Handle(BRepCheck_Result) aResOfVertex = myMap.FindFromKey (aVertex);
+            try
+            {
+              OCC_CATCH_SIGNALS
+              if (MapS.Add (aVertex))
+              {
+                aResOfVertex->InContext (aShape);
+              }
+            }
+            catch (Standard_Failure const& anException)
             {
-              for ( res->InitContextIterator();
-                    res->MoreShapeInContext();
-                    res->NextShapeInContext())
+              (void)anException;
+              if (!aResult.IsNull())
               {
-                if(res->ContextualShape().IsSame(S))
-                  break;
+                aResult->SetFailStatus (aShape);
               }
 
-              BRepCheck_ListIteratorOfListOfStatus itl(res->StatusOnShape());
-              for (; itl.More(); itl.Next())
+              if (!aResOfVertex.IsNull())
               {
-                BRepCheck_Status ste = itl.Value();
-                if (ste == BRepCheck_NoCurveOnSurface  ||
-                    ste == BRepCheck_InvalidCurveOnSurface ||
-                    ste == BRepCheck_InvalidRange ||
-                    ste == BRepCheck_InvalidCurveOnClosedSurface)
-                {
-                  performwire = Standard_False;
-                  break;
-                }
+                aResOfVertex->SetFailStatus (aVertex);
+                aResOfVertex->SetFailStatus (aShape);
               }
             }
           }
+          break;
         }
-        catch(Standard_Failure const& anException) {
-#ifdef OCCT_DEBUG
-          std::cout<<"BRepCheck_Analyzer : ";
-          anException.Print(std::cout);  
-          std::cout<<std::endl;
-#endif
-          (void)anException;
-          if ( ! myMap(S).IsNull() )
-          {
-            myMap(S)->SetFailStatus(S);
-          }
-
-          Handle(BRepCheck_Result) aRes = myMap(exp.Current());
-
-          if ( ! aRes.IsNull() )
-          {
-            aRes->SetFailStatus(exp.Current());
-            aRes->SetFailStatus(S);
-          }
+        case TopAbs_WIRE:
+        {
+          break;
         }
-      }
-
-      Standard_Boolean orientofwires = performwire;
-      for (exp.Init(S,TopAbs_WIRE);exp.More(); exp.Next())
-      {
-        try
+        case TopAbs_FACE:
         {
-          OCC_CATCH_SIGNALS
-          Handle(BRepCheck_Result)& res = myMap(exp.Current());
-          res->InContext(S);
-          if (orientofwires)
+          TopTools_MapOfShape MapS;
+          for (exp.Init (aShape, TopAbs_VERTEX); exp.More(); exp.Next())
           {
-            for ( res->InitContextIterator();
-                  res->MoreShapeInContext();
-                  res->NextShapeInContext())
+            Handle(BRepCheck_Result) aFaceVertexRes = myMap.FindFromKey (exp.Current());
+            try
             {
-              if(res->ContextualShape().IsSame(S))
+              OCC_CATCH_SIGNALS
+              if (MapS.Add (exp.Current()))
               {
-                break;
+                aFaceVertexRes->InContext (aShape);
               }
             }
-            BRepCheck_ListIteratorOfListOfStatus itl(res->StatusOnShape());
-            for (; itl.More(); itl.Next())
+            catch (Standard_Failure const& anException)
             {
-              BRepCheck_Status ste = itl.Value();
-              if (ste != BRepCheck_NoError)
+              (void)anException;
+              if (!aResult.IsNull())
+              {
+                aResult->SetFailStatus (aShape);
+              }
+              if (!aFaceVertexRes.IsNull())
               {
-                orientofwires = Standard_False;
-                break;
+                aFaceVertexRes->SetFailStatus (exp.Current());
+                aFaceVertexRes->SetFailStatus (aShape);
               }
             }
           }
-        }
-        catch(Standard_Failure const& anException) {
-#ifdef OCCT_DEBUG
-          std::cout<<"BRepCheck_Analyzer : ";
-          anException.Print(std::cout);  
-          std::cout<<std::endl;
-#endif
-          (void)anException;
-          if ( ! myMap(S).IsNull() )
+
+          Standard_Boolean performwire = Standard_True;
+          Standard_Boolean isInvalidTolerance = Standard_False;
+          MapS.Clear();
+          for (exp.Init (aShape, TopAbs_EDGE); exp.More(); exp.Next())
           {
-            myMap(S)->SetFailStatus(S);
-          }
+            const Handle(BRepCheck_Result)& aFaceEdgeRes = myMap.FindFromKey (exp.Current());
+            try
+            {
+              OCC_CATCH_SIGNALS
+              if (MapS.Add (exp.Current()))
+              {
+                aFaceEdgeRes->InContext (aShape);
 
-          Handle(BRepCheck_Result) aRes = myMap(exp.Current());
+                if (performwire)
+                {
+                  Standard_Mutex::Sentry aLock (aFaceEdgeRes->GetMutex());
+                  if (aFaceEdgeRes->IsStatusOnShape(aShape))
+                  {
+                    BRepCheck_ListIteratorOfListOfStatus itl (aFaceEdgeRes->StatusOnShape (aShape));
+                    for (; itl.More(); itl.Next())
+                    {
+                      const BRepCheck_Status ste = itl.Value();
+                      if (ste == BRepCheck_NoCurveOnSurface ||
+                          ste == BRepCheck_InvalidCurveOnSurface ||
+                          ste == BRepCheck_InvalidRange ||
+                          ste == BRepCheck_InvalidCurveOnClosedSurface)
+                      {
+                        performwire = Standard_False;
+                        break;
+                      }
+                    }
+                  }
+                }
+              }
+            }
+            catch (Standard_Failure const& anException)
+            {
+              (void)anException;
+              if (!aResult.IsNull())
+              {
+                aResult->SetFailStatus (aShape);
+              }
+              if (!aFaceEdgeRes.IsNull())
+              {
+                aFaceEdgeRes->SetFailStatus (exp.Current());
+                aFaceEdgeRes->SetFailStatus (aShape);
+              }
+            }
+          }
 
-          if ( ! aRes.IsNull() )
+          Standard_Boolean orientofwires = performwire;
+          for (exp.Init (aShape, TopAbs_WIRE); exp.More(); exp.Next())
           {
-            aRes->SetFailStatus(exp.Current());
-            aRes->SetFailStatus(S);
+            const Handle(BRepCheck_Result)& aFaceWireRes = myMap.FindFromKey (exp.Current());
+            try
+            {
+              OCC_CATCH_SIGNALS
+              aFaceWireRes->InContext (aShape);
+
+              if (orientofwires)
+              {
+                Standard_Mutex::Sentry aLock (aFaceWireRes->GetMutex());
+                if (aFaceWireRes->IsStatusOnShape (aShape))
+                {
+                  const BRepCheck_ListOfStatus& aStatusList = aFaceWireRes->StatusOnShape (aShape);
+                  BRepCheck_ListIteratorOfListOfStatus itl (aStatusList);
+                  for (; itl.More(); itl.Next())
+                  {
+                    BRepCheck_Status ste = itl.Value();
+                    if (ste != BRepCheck_NoError)
+                    {
+                      orientofwires = Standard_False;
+                      break;
+                    }
+                  }
+                }
+              }
+            }
+            catch (Standard_Failure const& anException)
+            {
+              (void)anException;
+              if (!aResult.IsNull())
+              {
+                aResult->SetFailStatus (aShape);
+              }
+              if (!aFaceWireRes.IsNull())
+              {
+                aFaceWireRes->SetFailStatus (exp.Current());
+                aFaceWireRes->SetFailStatus (aShape);
+              }
+            }
           }
-        }
-      }
 
-      try
-      {
-        OCC_CATCH_SIGNALS
-        if(isInvalidTolerance)
-        {
-          Handle(BRepCheck_Face)::
-              DownCast(myMap(S))->SetStatus(BRepCheck_InvalidToleranceValue);
-        }
-        else if (performwire)
-        {
-          if (orientofwires)
+          try
           {
-            Handle(BRepCheck_Face)::DownCast(myMap(S))->
-                        OrientationOfWires(Standard_True);// on enregistre
+            OCC_CATCH_SIGNALS
+            const Handle(BRepCheck_Face) aFaceRes = Handle(BRepCheck_Face)::DownCast(aResult);
+            if (isInvalidTolerance)
+            {
+              aFaceRes->SetStatus (BRepCheck_InvalidToleranceValue);
+            }
+            else if (performwire)
+            {
+              if (orientofwires)
+              {
+                aFaceRes->OrientationOfWires (Standard_True);// on enregistre
+              }
+              else
+              {
+                aFaceRes->SetUnorientable();
+              }
+            }
+            else
+            {
+              aFaceRes->SetUnorientable();
+            }
           }
-          else
+          catch (Standard_Failure const& anException)
           {
-            Handle(BRepCheck_Face)::DownCast(myMap(S))->SetUnorientable();
+            (void)anException;
+            if (!aResult.IsNull())
+            {
+              aResult->SetFailStatus (aShape);
+            }
+
+            for (exp.Init (aShape, TopAbs_WIRE); exp.More(); exp.Next())
+            {
+              Handle(BRepCheck_Result) aFaceCatchRes = myMap.FindFromKey (exp.Current());
+              if (!aFaceCatchRes.IsNull())
+              {
+                aFaceCatchRes->SetFailStatus (exp.Current());
+                aFaceCatchRes->SetFailStatus (aShape);
+                aResult->SetFailStatus (exp.Current());
+              }
+            }
           }
+          break;
         }
-        else
-        {
-          Handle(BRepCheck_Face)::DownCast(myMap(S))->SetUnorientable();
-        }
-      }
-      catch(Standard_Failure const& anException) {
-#ifdef OCCT_DEBUG
-        std::cout<<"BRepCheck_Analyzer : ";
-        anException.Print(std::cout);  
-        std::cout<<std::endl;
-#endif
-        (void)anException;
-        if ( ! myMap(S).IsNull() )
+        case TopAbs_SHELL:
         {
-          myMap(S)->SetFailStatus(S);
+          break;
         }
-
-        for (exp.Init(S,TopAbs_WIRE);exp.More(); exp.Next())
+        case TopAbs_SOLID:
         {
-          Handle(BRepCheck_Result) aRes = myMap(exp.Current());
-          
-          if ( ! aRes.IsNull() )
+          exp.Init (aShape, TopAbs_SHELL);
+          for (; exp.More(); exp.Next())
           {
-            aRes->SetFailStatus(exp.Current());
-            aRes->SetFailStatus(S);
-            myMap(S)->SetFailStatus(exp.Current());
+            const TopoDS_Shape& aShell = exp.Current();
+            Handle(BRepCheck_Result) aSolidRes = myMap.FindFromKey (aShell);
+            try
+            {
+              OCC_CATCH_SIGNALS
+              aSolidRes->InContext (aShape);
+            }
+            catch (Standard_Failure const& anException)
+            {
+              (void)anException;
+              if (!aResult.IsNull())
+              {
+                aResult->SetFailStatus (aShape);
+              }
+              if (!aSolidRes.IsNull())
+              {
+                aSolidRes->SetFailStatus (exp.Current());
+                aSolidRes->SetFailStatus (aShape);
+              }
+            }
           }
+          break;
+        }
+        default:
+        {
+          break;
         }
       }
     }
-    break;
-    
-  case TopAbs_SHELL:   
-    break;
+  }
 
-  case TopAbs_SOLID:
+private:
+
+  NCollection_Array1< NCollection_Array1<TopoDS_Shape> >& myArray;
+  const BRepCheck_IndexedDataMapOfShapeResult& myMap;
+};
+
+//=======================================================================
+//function : Init
+//purpose  :
+//=======================================================================
+void BRepCheck_Analyzer::Init (const TopoDS_Shape& theShape,
+                               const Standard_Boolean B,
+                               const Standard_Boolean theIsParallel)
+{
+  if (theShape.IsNull())
+  {
+    throw Standard_NullObject ("BRepCheck_Analyzer::Init() - NULL shape");
+  }
+
+  myShape = theShape;
+  myMap.Clear();
+  Put (theShape, B, theIsParallel);
+  Perform (theIsParallel);
+}
+
+//=======================================================================
+//function : Put
+//purpose  :
+//=======================================================================
+void BRepCheck_Analyzer::Put (const TopoDS_Shape& theShape,
+                              const Standard_Boolean B,
+                              const Standard_Boolean theIsParallel)
+{
+  if (myMap.Contains (theShape))
+  {
+    return;
+  }
+
+  Handle(BRepCheck_Result) HR;
+  switch (theShape.ShapeType())
+  {
+    case TopAbs_VERTEX:
+      HR = new BRepCheck_Vertex (TopoDS::Vertex (theShape));
+      break;
+    case TopAbs_EDGE:
+      HR = new BRepCheck_Edge (TopoDS::Edge (theShape));
+      Handle(BRepCheck_Edge)::DownCast(HR)->GeometricControls (B);
+      break;
+    case TopAbs_WIRE:
+      HR = new BRepCheck_Wire (TopoDS::Wire (theShape));
+      Handle(BRepCheck_Wire)::DownCast(HR)->GeometricControls (B);
+      break;
+    case TopAbs_FACE:
+      HR = new BRepCheck_Face (TopoDS::Face (theShape));
+      Handle(BRepCheck_Face)::DownCast(HR)->GeometricControls (B);
+      break;
+    case TopAbs_SHELL:
+      HR = new BRepCheck_Shell (TopoDS::Shell (theShape));
+      break;
+    case TopAbs_SOLID:
+      HR = new BRepCheck_Solid (TopoDS::Solid (theShape));
+      break;
+    case TopAbs_COMPSOLID:
+    case TopAbs_COMPOUND:
+      break;
+    default:
+      break;
+  }
+
+  if (!HR.IsNull())
+  {
+    HR->SetParallel (theIsParallel);
+  }
+  myMap.Add (theShape, HR);
+
+  for (TopoDS_Iterator theIterator (theShape); theIterator.More(); theIterator.Next())
+  {
+    Put (theIterator.Value(), B, theIsParallel); // performs minimum on each shape
+  }
+}
+
+//=======================================================================
+//function : Perform
+//purpose  :
+//=======================================================================
+void BRepCheck_Analyzer::Perform (Standard_Boolean theIsParallel)
+{
+  const Standard_Integer aMapSize = myMap.Size();
+  const Standard_Integer aMinTaskSize = 10;
+  const Handle(OSD_ThreadPool)& aThreadPool = OSD_ThreadPool::DefaultPool();
+  const Standard_Integer aNbThreads = aThreadPool->NbThreads();
+  Standard_Integer aNbTasks = aNbThreads * 10;
+  Standard_Integer aTaskSize = (Standard_Integer)Ceiling ((double)aMapSize / aNbTasks);
+  if (aTaskSize < aMinTaskSize)
+  {
+    aTaskSize = aMinTaskSize;
+    aNbTasks = (Standard_Integer)Ceiling ((double)aMapSize / aTaskSize);
+  }
+
+  NCollection_Array1< NCollection_Array1<TopoDS_Shape> > aArrayOfArray (0, aNbTasks - 1);
+  for (Standard_Integer anI = 1; anI <= aMapSize; ++anI)
+  {
+    Standard_Integer aVectIndex  = (anI-1) / aTaskSize;
+    Standard_Integer aShapeIndex = (anI-1) % aTaskSize;
+    if (aShapeIndex == 0)
     {
-      exp.Init(S,TopAbs_SHELL);
-      for (; exp.More(); exp.Next())
-        {
-          const TopoDS_Shape& aShell=exp.Current();
-          try 
-            {
-              OCC_CATCH_SIGNALS
-                myMap(aShell)->InContext(S);
-            }
-          catch(Standard_Failure const& anException) {
-#ifdef OCCT_DEBUG
-              std::cout<<"BRepCheck_Analyzer : ";
-              anException.Print(std::cout);  
-              std::cout<<std::endl;
-#endif
-              (void)anException;
-              if ( ! myMap(S).IsNull() )
-                {
-                  myMap(S)->SetFailStatus(S);
-                }
-              
-              //
-              Handle(BRepCheck_Result) aRes = myMap(aShell);
-              if (!aRes.IsNull() )
-                {
-                  aRes->SetFailStatus(exp.Current());
-                  aRes->SetFailStatus(S);
-                }
-            }//catch(Standard_Failure)
-        }//for (; exp.More(); exp.Next())
+      Standard_Integer aVectorSize = aTaskSize;
+      Standard_Integer aTailSize = aMapSize - aVectIndex * aTaskSize;
+      if (aTailSize < aTaskSize)
+      {
+        aVectorSize = aTailSize;
+      }
+      aArrayOfArray[aVectIndex].Resize (0, aVectorSize - 1, Standard_False);
     }
-  break;//case TopAbs_SOLID
-  default:
-    break;
-  }//switch (styp) {
-}
+    aArrayOfArray[aVectIndex][aShapeIndex] = myMap.FindKey (anI);
+  }
 
+  BRepCheck_ParallelAnalyzer aParallelAnalyzer (aArrayOfArray, myMap);
+  OSD_Parallel::For (0, aArrayOfArray.Size(), aParallelAnalyzer, !theIsParallel);
+}
 
 //=======================================================================
 //function : IsValid
@@ -437,9 +461,10 @@ void BRepCheck_Analyzer::Perform(const TopoDS_Shape& S)
 
 Standard_Boolean BRepCheck_Analyzer::IsValid(const TopoDS_Shape& S) const
 {
-  if (!myMap(S).IsNull()) {
+  if (!myMap.FindFromKey (S).IsNull())
+  {
     BRepCheck_ListIteratorOfListOfStatus itl;
-    itl.Initialize(myMap(S)->Status());
+    itl.Initialize (myMap.FindFromKey (S)->Status());
     if (itl.Value() != BRepCheck_NoError) { // a voir
       return Standard_False;
     }
@@ -494,7 +519,7 @@ Standard_Boolean BRepCheck_Analyzer::ValidSub
   TopExp_Explorer exp;
   for (exp.Init(S,SubType);exp.More(); exp.Next()) {
 //  for (TopExp_Explorer exp(S,SubType);exp.More(); exp.Next()) {
-    const Handle(BRepCheck_Result)& RV = myMap(exp.Current());
+    const Handle(BRepCheck_Result)& RV = myMap.FindFromKey(exp.Current());
     for (RV->InitContextIterator();
          RV->MoreShapeInContext(); 
          RV->NextShapeInContext()) {
index bdf5b0e..d921efd 100644 (file)
@@ -22,7 +22,7 @@
 #include <Standard_Handle.hxx>
 
 #include <TopoDS_Shape.hxx>
-#include <BRepCheck_DataMapOfShapeResult.hxx>
+#include <BRepCheck_IndexedDataMapOfShapeResult.hxx>
 #include <Standard_Boolean.hxx>
 #include <TopAbs_ShapeEnum.hxx>
 class Standard_NullObject;
@@ -30,7 +30,6 @@ class Standard_NoSuchObject;
 class TopoDS_Shape;
 class BRepCheck_Result;
 
-
 //! A framework to check the overall
 //! validity of a shape. For a shape to be valid in Open
 //! CASCADE, it - or its component subshapes - must respect certain
@@ -44,7 +43,6 @@ public:
 
   DEFINE_STANDARD_ALLOC
 
-  
   //! Constructs a shape validation object defined by the shape S.
   //! <S> is the  shape  to control.  <GeomControls>  If
   //! False   only topological informaions  are checked.
@@ -62,8 +60,13 @@ public:
   //! BRepCheck_InvalidToleranceValue  NYI
   //! For a wire :
   //! BRepCheck_SelfIntersectingWire
-    BRepCheck_Analyzer(const TopoDS_Shape& S, const Standard_Boolean GeomControls = Standard_True);
-  
+  BRepCheck_Analyzer (const TopoDS_Shape& S,
+                      const Standard_Boolean GeomControls = Standard_True,
+                      const Standard_Boolean theIsParallel = Standard_False)
+  {
+    Init (S, GeomControls, theIsParallel);
+  }
+
   //! <S> is the  shape  to control.  <GeomControls>  If
   //! False   only topological informaions  are checked.
   //! The geometricals controls are
@@ -80,8 +83,10 @@ public:
   //! BRepCheck_InvalidTolerance  NYI
   //! For a wire :
   //! BRepCheck_SelfIntersectingWire
-  Standard_EXPORT void Init (const TopoDS_Shape& S, const Standard_Boolean GeomControls = Standard_True);
-  
+  Standard_EXPORT void Init (const TopoDS_Shape& S,
+                             const Standard_Boolean GeomControls = Standard_True,
+                             const Standard_Boolean theIsParallel = Standard_False);
+
   //! <S> is a  subshape of the  original shape. Returns
   //! <STandard_True> if no default has been detected on
   //! <S> and any of its subshape.
@@ -126,40 +131,31 @@ public:
   //! surface of the reference face), this checks that |C(t) - S(P(t))|
   //! is less than or equal to tolerance, where tolerance is the tolerance
   //! value coded on the edge.
-    Standard_Boolean IsValid() const;
-  
-    const Handle(BRepCheck_Result)& Result (const TopoDS_Shape& SubS) const;
-
-
-
-
-protected:
+  Standard_Boolean IsValid() const
+  {
+    return IsValid (myShape);
+  }
 
+  const Handle(BRepCheck_Result)& Result (const TopoDS_Shape& theSubS) const
+  {
+    return myMap.FindFromKey (theSubS);
+  }
 
+private:
 
+  Standard_EXPORT void Put (const TopoDS_Shape& S,
+                            const Standard_Boolean Gctrl,
+                            const Standard_Boolean theIsParallel);
 
+  Standard_EXPORT void Perform (Standard_Boolean theIsParallel);
 
-private:
-
-  
-  Standard_EXPORT void Put (const TopoDS_Shape& S, const Standard_Boolean Gctrl);
-  
-  Standard_EXPORT void Perform (const TopoDS_Shape& S);
-  
   Standard_EXPORT Standard_Boolean ValidSub (const TopoDS_Shape& S, const TopAbs_ShapeEnum SubType) const;
 
+private:
 
   TopoDS_Shape myShape;
-  BRepCheck_DataMapOfShapeResult myMap;
-
+  BRepCheck_IndexedDataMapOfShapeResult myMap;
 
 };
 
-
-#include <BRepCheck_Analyzer.lxx>
-
-
-
-
-
 #endif // _BRepCheck_Analyzer_HeaderFile
diff --git a/src/BRepCheck/BRepCheck_Analyzer.lxx b/src/BRepCheck/BRepCheck_Analyzer.lxx
deleted file mode 100644 (file)
index 5d3351e..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-// Created on: 1995-12-08
-// Created by: Jacques GOUSSARD
-// Copyright (c) 1995-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-//=======================================================================
-//function : BRepCheck_Analyzer
-//purpose  : 
-//=======================================================================
-
-inline BRepCheck_Analyzer::BRepCheck_Analyzer (const TopoDS_Shape& S,
-                                              const Standard_Boolean B)
-{
-  Init(S,B);
-}
-
-
-
-//=======================================================================
-//function : Result
-//purpose  : 
-//=======================================================================
-
-inline const Handle(BRepCheck_Result)& BRepCheck_Analyzer::Result
-   (const TopoDS_Shape& S) const
-{
-  return myMap(S);
-}
-
-//=======================================================================
-//function : IsValid
-//purpose  : 
-//=======================================================================
-
-inline Standard_Boolean BRepCheck_Analyzer::IsValid() const
-{
-  return IsValid(myShape);
-}
-
diff --git a/src/BRepCheck/BRepCheck_DataMapIteratorOfDataMapOfShapeListOfStatus.hxx b/src/BRepCheck/BRepCheck_DataMapIteratorOfDataMapOfShapeListOfStatus.hxx
deleted file mode 100644 (file)
index 2f5fc7a..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2015 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-
-#ifndef BRepCheck_DataMapIteratorOfDataMapOfShapeListOfStatus_HeaderFile
-#define BRepCheck_DataMapIteratorOfDataMapOfShapeListOfStatus_HeaderFile
-
-#include <BRepCheck_DataMapOfShapeListOfStatus.hxx>
-
-#endif
diff --git a/src/BRepCheck/BRepCheck_DataMapIteratorOfDataMapOfShapeResult.hxx b/src/BRepCheck/BRepCheck_DataMapIteratorOfDataMapOfShapeResult.hxx
deleted file mode 100644 (file)
index f390be9..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2015 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-
-#ifndef BRepCheck_DataMapIteratorOfDataMapOfShapeResult_HeaderFile
-#define BRepCheck_DataMapIteratorOfDataMapOfShapeResult_HeaderFile
-
-#include <BRepCheck_DataMapOfShapeResult.hxx>
-
-#endif
index 8ca24b3..69c1383 100644 (file)
 #include <BRepCheck_ListOfStatus.hxx>
 #include <TopTools_ShapeMapHasher.hxx>
 #include <NCollection_DataMap.hxx>
+#include <NCollection_Shared.hxx>
 
-typedef NCollection_DataMap<TopoDS_Shape,BRepCheck_ListOfStatus,TopTools_ShapeMapHasher> BRepCheck_DataMapOfShapeListOfStatus;
-typedef NCollection_DataMap<TopoDS_Shape,BRepCheck_ListOfStatus,TopTools_ShapeMapHasher>::Iterator BRepCheck_DataMapIteratorOfDataMapOfShapeListOfStatus;
-
+typedef NCollection_DataMap<TopoDS_Shape,
+                            Handle(NCollection_Shared <BRepCheck_ListOfStatus>),
+                            TopTools_ShapeMapHasher> 
+  BRepCheck_DataMapOfShapeListOfStatus;
+typedef NCollection_DataMap<TopoDS_Shape,
+                            Handle(NCollection_Shared <BRepCheck_ListOfStatus>),
+                            TopTools_ShapeMapHasher>::Iterator 
+  BRepCheck_DataMapIteratorOfDataMapOfShapeListOfStatus;
 
 #endif
diff --git a/src/BRepCheck/BRepCheck_DataMapOfShapeResult.hxx b/src/BRepCheck/BRepCheck_DataMapOfShapeResult.hxx
deleted file mode 100644 (file)
index 52a24df..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// Created on: 1995-12-06
-// Created by: Jacques GOUSSARD
-// Copyright (c) 1995-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#ifndef BRepCheck_DataMapOfShapeResult_HeaderFile
-#define BRepCheck_DataMapOfShapeResult_HeaderFile
-
-#include <TopoDS_Shape.hxx>
-#include <BRepCheck_Result.hxx>
-#include <TopTools_OrientedShapeMapHasher.hxx>
-#include <NCollection_DataMap.hxx>
-
-typedef NCollection_DataMap<TopoDS_Shape,Handle(BRepCheck_Result),TopTools_OrientedShapeMapHasher> BRepCheck_DataMapOfShapeResult;
-typedef NCollection_DataMap<TopoDS_Shape,Handle(BRepCheck_Result),TopTools_OrientedShapeMapHasher>::Iterator BRepCheck_DataMapIteratorOfDataMapOfShapeResult;
-
-
-#endif
index 5b0e789..48c3b8c 100644 (file)
@@ -79,16 +79,14 @@ BRepCheck_Edge::BRepCheck_Edge(const TopoDS_Edge& E)
 
 //=======================================================================
 //function : Minimum
-//purpose  : 
+//purpose  :
 //=======================================================================
-
 void BRepCheck_Edge::Minimum()
 {
-
-  if (!myMin) {
-    BRepCheck_ListOfStatus thelist;
-    myMap.Bind(myShape, thelist);
-    BRepCheck_ListOfStatus& lst = myMap(myShape);
+  if (!myMin)
+  {
+    Handle(BRepCheck_HListOfStatus) aNewList = new BRepCheck_HListOfStatus();
+    BRepCheck_ListOfStatus& lst = **myMap.Bound(myShape, aNewList);
     myCref.Nullify();
 
     // Existence et unicite d`une representation 3D
@@ -253,24 +251,30 @@ void BRepCheck_Edge::Minimum()
 
 //=======================================================================
 //function : InContext
-//purpose  : 
+//purpose  :
 //=======================================================================
-
 void BRepCheck_Edge::InContext(const TopoDS_Shape& S)
 {
-  if (myMap.IsBound(S)) {
-    return;
+  Handle(BRepCheck_HListOfStatus) aHList;
+  {
+    Standard_Mutex::Sentry aLock(myMutex.get());
+    if (myMap.IsBound(S))
+    {
+      return;
+    }
+
+    Handle(BRepCheck_HListOfStatus) aNewList = new BRepCheck_HListOfStatus();
+    aHList = *myMap.Bound (S, aNewList);
   }
-  BRepCheck_ListOfStatus thelist;
-  myMap.Bind(S, thelist);
-  BRepCheck_ListOfStatus& lst = myMap(S);
+
+  BRepCheck_ListOfStatus& lst = *aHList;
 
   Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&myShape.TShape());
   Standard_Real Tol = BRep_Tool::Tolerance(TopoDS::Edge(myShape));
 
   TopAbs_ShapeEnum styp = S.ShapeType();
   //  for (TopExp_Explorer exp(S,TopAbs_EDGE); exp.More(); exp.Next()) {
-  TopExp_Explorer exp(S,TopAbs_EDGE) ;
+  TopExp_Explorer exp (S, TopAbs_EDGE);
   for ( ; exp.More(); exp.Next()) {
     if (exp.Current().IsSame(myShape)) {
       break;
@@ -321,7 +325,7 @@ void BRepCheck_Edge::InContext(const TopoDS_Shape& S)
         const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
         if (cr != myCref && cr->IsCurveOnSurface(Su,L)) {
           pcurvefound = Standard_True;
-          Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (cr));
+          Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast(cr));
           Standard_Real f,l;
           GC->Range(f,l);
           Standard_Real ff = f, ll = l;
@@ -349,7 +353,7 @@ void BRepCheck_Edge::InContext(const TopoDS_Shape& S)
           Standard_Real fp = pc->FirstParameter(), lp = pc->LastParameter();
           if (pc->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
           {
-            const Handle(Geom2d_Curve)& aC = Handle(Geom2d_TrimmedCurve)::DownCast (pc)->BasisCurve(); 
+            const Handle(Geom2d_Curve) aC = Handle(Geom2d_TrimmedCurve)::DownCast (pc)->BasisCurve();
             fp = aC->FirstParameter();
             lp = aC->LastParameter();
             IsPeriodic = aC->IsPeriodic();
@@ -448,7 +452,7 @@ void BRepCheck_Edge::InContext(const TopoDS_Shape& S)
               GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3d,First,Last),
               P, P->Position().Direction(),
               Standard_True);
-            Handle(GeomAdaptor_Curve) aHCurve = 
+            Handle(GeomAdaptor_Curve) aHCurve =
               new GeomAdaptor_Curve(ProjOnPlane);
 
             ProjLib_ProjectedCurve proj(GAHS,aHCurve);
@@ -483,25 +487,25 @@ void BRepCheck_Edge::InContext(const TopoDS_Shape& S)
         for (exp2.Init(fac,TopAbs_EDGE); exp2.More(); exp2.Next()) {
           if (exp2.Current().IsSame(myShape)) {
             nbconnection++;
-          }
         }
       }
-      if (nbconnection < 2 && !TE->Degenerated()) {
-        BRepCheck::Add(myMap(S),BRepCheck_FreeEdge);
-      }
-      else if (nbconnection > 2) {
-        BRepCheck::Add(myMap(S),BRepCheck_InvalidMultiConnexity);
-      }
-      else {
-        BRepCheck::Add(myMap(S),BRepCheck_NoError);
-      }
     }
-    break;
+    if (nbconnection < 2 && !TE->Degenerated()) {
+      BRepCheck::Add (lst, BRepCheck_FreeEdge);
+    }
+    else if (nbconnection > 2) {
+      BRepCheck::Add (lst, BRepCheck_InvalidMultiConnexity);
+    }
+    else {
+      BRepCheck::Add (lst, BRepCheck_NoError);
+    }
+  }
+  break;
   default:
     break;
   }
-  if (myMap(S).IsEmpty()) {
-    myMap(S).Append(BRepCheck_NoError);
+  if (lst.IsEmpty()) {
+    lst.Append (BRepCheck_NoError);
   }
 }
 
@@ -549,7 +553,8 @@ Standard_Boolean BRepCheck_Edge::GeometricControls() const
 //=======================================================================
 void BRepCheck_Edge::SetStatus(const BRepCheck_Status theStatus)
 {
-  BRepCheck::Add(myMap(myShape),theStatus);
+  Standard_Mutex::Sentry aLock(myMutex.get());
+  BRepCheck::Add (*myMap (myShape), theStatus);
 }
 
 
index 6de003e..c8ee81d 100644 (file)
@@ -100,10 +100,10 @@ BRepCheck_Face::BRepCheck_Face (const TopoDS_Face& F)
 
 void BRepCheck_Face::Minimum()
 {
-  if (!myMin) {
-    BRepCheck_ListOfStatus thelist;
-    myMap.Bind(myShape, thelist);
-    BRepCheck_ListOfStatus& lst = myMap(myShape);
+  if (!myMin)
+  {
+    Handle(BRepCheck_HListOfStatus) aNewList = new BRepCheck_HListOfStatus();
+    BRepCheck_ListOfStatus& lst = **myMap.Bound (myShape, aNewList);
 
     Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &myShape.TShape());
     if (TF->Surface().IsNull()) {
@@ -127,14 +127,19 @@ void BRepCheck_Face::Minimum()
 
 void BRepCheck_Face::InContext(const TopoDS_Shape& S)
 {
-  if (myMap.IsBound(S)) {
-    return;
+  Handle(BRepCheck_HListOfStatus) aHList;
+  {
+    Standard_Mutex::Sentry aLock(myMutex.get());
+    if (myMap.IsBound (S))
+    {
+      return;
+    }
+
+    Handle(BRepCheck_HListOfStatus) aNewList = new BRepCheck_HListOfStatus();
+    aHList = *myMap.Bound (S, aNewList);
   }
-  BRepCheck_ListOfStatus thelist;
-  myMap.Bind(S, thelist);
+  BRepCheck_ListOfStatus& lst = *aHList;
 
-  BRepCheck_ListOfStatus& lst = myMap(S);
-  
   TopExp_Explorer exp(S,TopAbs_FACE);
   for (; exp.More(); exp.Next()) {
     if (exp.Current().IsSame(myShape)) {
@@ -173,9 +178,18 @@ void BRepCheck_Face::Blind()
 
 BRepCheck_Status BRepCheck_Face::IntersectWires(const Standard_Boolean Update)
 {
-  if (myIntdone) {
-    if (Update) {
-      BRepCheck::Add(myMap(myShape),myIntres);
+  Handle(BRepCheck_HListOfStatus) aHList;
+  {
+    Standard_Mutex::Sentry aLock(myMutex.get());
+    aHList = myMap (myShape);
+  }
+
+  BRepCheck_ListOfStatus& aStatusList = *aHList;
+  if (myIntdone)
+  {
+    if (Update)
+    {
+      BRepCheck::Add (aStatusList, myIntres);
     }
     return myIntres;
   }
@@ -196,8 +210,9 @@ BRepCheck_Status BRepCheck_Face::IntersectWires(const Standard_Boolean Update)
     }
     else { // the same wire is met twice...
       myIntres = BRepCheck_RedundantWire;
-      if (Update) {
-       BRepCheck::Add(myMap(myShape),myIntres);
+      if (Update)
+      {
+        BRepCheck::Add (aStatusList, myIntres);
       }
       return myIntres;
     }
@@ -263,18 +278,21 @@ BRepCheck_Status BRepCheck_Face::IntersectWires(const Standard_Boolean Update)
       {
         continue;
       }
-      if (Intersect(wir1,wir2,TopoDS::Face(myShape), aMapShapeBox2d)) {
-       myIntres = BRepCheck_IntersectingWires;
-       if (Update) {
-         BRepCheck::Add(myMap(myShape),myIntres);
-       }
-       return myIntres;
+      if (Intersect(wir1,wir2,TopoDS::Face(myShape), aMapShapeBox2d))
+      {
+        myIntres = BRepCheck_IntersectingWires;
+        if (Update)
+        {
+          BRepCheck::Add (aStatusList, myIntres);
+        }
+        return myIntres;
       }
     }
     Index++;
   }
-  if (Update) {
-    BRepCheck::Add(myMap(myShape),myIntres);
+  if (Update)
+  {
+    BRepCheck::Add(aStatusList, myIntres);
   }
   return myIntres;
 }
@@ -287,27 +305,41 @@ BRepCheck_Status BRepCheck_Face::IntersectWires(const Standard_Boolean Update)
 
 BRepCheck_Status BRepCheck_Face::ClassifyWires(const Standard_Boolean Update)
 {
+  Handle(BRepCheck_HListOfStatus) aHList;
+  {
+    Standard_Mutex::Sentry aLock(myMutex.get());
+    aHList = myMap (myShape);
+  }
+
+  BRepCheck_ListOfStatus& aStatusList = *aHList;
+
   // It is assumed that each wire does not intersect any other one.
-  if (myImbdone) {
-    if (Update) {
-      BRepCheck::Add(myMap(myShape),myImbres);
+  if (myImbdone)
+  {
+    if (Update)
+    {
+      BRepCheck::Add (aStatusList, myImbres);
     }
     return myImbres;
   }
 
   myImbdone = Standard_True;
   myImbres = IntersectWires();
-  if (myImbres != BRepCheck_NoError) {
-    if (Update) {
-      BRepCheck::Add(myMap(myShape),myImbres);
+  if (myImbres != BRepCheck_NoError)
+  {
+    if (Update)
+    {
+      BRepCheck::Add (aStatusList, myImbres);
     }
     return myImbres;
   }
 
   Standard_Integer Nbwire = myMapImb.Extent();
-  if (Nbwire < 1) {
-    if (Update) {
-      BRepCheck::Add(myMap(myShape),myImbres);
+  if (Nbwire < 1)
+  {
+    if (Update)
+    {
+      BRepCheck::Add (aStatusList, myImbres);
     }
     return myImbres;
   }
@@ -358,60 +390,72 @@ BRepCheck_Status BRepCheck_Face::ClassifyWires(const Standard_Boolean Update)
       if (Wext.IsNull()) {
        Wext = TopoDS::Wire(itm.Key());
       }
-      else {
-       myImbres = BRepCheck_InvalidImbricationOfWires;
-       if (Update) {
-         BRepCheck::Add(myMap(myShape),myImbres);
-       }
-       return myImbres;
+      else
+      {
+        myImbres = BRepCheck_InvalidImbricationOfWires;
+        if (Update)
+        {
+          BRepCheck::Add (aStatusList, myImbres);
+        }
+        return myImbres;
       }
     }
   }
 
-  if (!Wext.IsNull()) {
+  if (!Wext.IsNull())
+  {
     // verifies that the list contains nbwire-1 elements
     if (myMapImb(Wext).Extent() != Nbwire-1) {
       myImbres = BRepCheck_InvalidImbricationOfWires;
-      if (Update) {
-       BRepCheck::Add(myMap(myShape),myImbres);
+      if (Update)
+      {
+        BRepCheck::Add (aStatusList, myImbres);
       }
       return myImbres;
     }
   }
+
   // quit without errors
-  if (Update) {
-    BRepCheck::Add(myMap(myShape),myImbres);
+  if (Update)
+  {
+    BRepCheck::Add (aStatusList, myImbres);
   }
+
   return myImbres;
-  
 }
 
 
 //=======================================================================
 //function : OrientationOfWires
-//purpose  : 
+//purpose  :
 //=======================================================================
-
-BRepCheck_Status BRepCheck_Face::OrientationOfWires
-   (const Standard_Boolean Update)
+BRepCheck_Status BRepCheck_Face::OrientationOfWires (const Standard_Boolean Update)
 {
-  // WARNING : it is assumed that the edges of a wire are correctly oriented
-
+  Handle(BRepCheck_HListOfStatus) aHList;
+  {
+    Standard_Mutex::Sentry aLock(myMutex.get());
+    aHList = myMap (myShape);
+  }
 
+  BRepCheck_ListOfStatus& aStatusList = *aHList;
+  // WARNING : it is assumed that the edges of a wire are correctly oriented
   Standard_Boolean Infinite = myShape.Infinite();
-
-  if (myOridone) {
-    if (Update) {
-      BRepCheck::Add(myMap(myShape),myOrires);
+  if (myOridone)
+  {
+    if (Update)
+    {
+      BRepCheck::Add (aStatusList, myOrires);
     }
     return myOrires;
   }
 
   myOridone = Standard_True;
   myOrires = ClassifyWires();
-  if (myOrires != BRepCheck_NoError) {
-    if (Update) {
-      BRepCheck::Add(myMap(myShape),myOrires);
+  if (myOrires != BRepCheck_NoError)
+  {
+    if (Update)
+    {
+      BRepCheck::Add (aStatusList, myOrires);
     }
     return myOrires;
   }
@@ -432,73 +476,86 @@ BRepCheck_Status BRepCheck_Face::OrientationOfWires
     }
   }
 
-  if (Wext.IsNull() && !Infinite) {
+  if (Wext.IsNull() && !Infinite)
+  {
     if (Nbwire>0) myOrires = BRepCheck_InvalidImbricationOfWires;
-    if (Update) {
-      BRepCheck::Add(myMap(myShape),myOrires);
+    if (Update)
+    {
+      BRepCheck::Add (aStatusList, myOrires);
     }
     return myOrires;
   }
 
   // BRep_Builder B;
   TopExp_Explorer exp(myShape.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
-  for (; exp.More(); exp.Next()) {
+  for (; exp.More(); exp.Next())
+  {
     const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
-    if (!Wext.IsNull() && wir.IsSame(Wext)) {
-      if (wir.Orientation() != Wext.Orientation()) {
-       //the exterior wire defines a hole 
-       if( CheckThin(wir,myShape.Oriented(TopAbs_FORWARD)) )
-         return myOrires;
-       myOrires = BRepCheck_BadOrientationOfSubshape;
-       if (Update) {
-         BRepCheck::Add(myMap(myShape),myOrires);
-       }
-       return myOrires;
+    if (!Wext.IsNull() && wir.IsSame(Wext))
+    {
+      if (wir.Orientation() != Wext.Orientation())
+      {
+        //the exterior wire defines a hole
+        if (CheckThin(wir,myShape.Oriented (TopAbs_FORWARD)))
+        {
+          return myOrires;
+        }
+        myOrires = BRepCheck_BadOrientationOfSubshape;
+        if (Update)
+        {
+          BRepCheck::Add (aStatusList, myOrires);
+        }
+        return myOrires;
       }
     }
-    else {
-      for (itm.Reset(); itm.More(); itm.Next()) {
-       if (itm.Key().IsSame(wir)) {
+    else
+    {
+      for (itm.Reset(); itm.More(); itm.Next())
+      {
+       if (itm.Key().IsSame(wir))
+        {
          break;
        }
       }
       // No control on More()
-      if (itm.Key().Orientation() == wir.Orientation()) {
-       // the given wire does not define a hole
-       myOrires = BRepCheck_BadOrientationOfSubshape;
-       if (Update) {
-         BRepCheck::Add(myMap(myShape),myOrires);
-       }
-       return myOrires;
+      if (itm.Key().Orientation() == wir.Orientation())
+      {
+        // the given wire does not define a hole
+        myOrires = BRepCheck_BadOrientationOfSubshape;
+        if (Update)
+        {
+          BRepCheck::Add (aStatusList, myOrires);
+        }
+        return myOrires;
       }
     }
   }
   // quit without error
-  if (Update) {
-    BRepCheck::Add(myMap(myShape),myOrires);
+  if (Update)
+  {
+    BRepCheck::Add (aStatusList, myOrires);
   }
   return myOrires;
 }
 
-
 //=======================================================================
 //function : SetUnorientable
-//purpose  : 
+//purpose  :
 //=======================================================================
-
 void BRepCheck_Face::SetUnorientable()
 {
-  BRepCheck::Add(myMap(myShape),BRepCheck_UnorientableShape);
+  Standard_Mutex::Sentry aLock(myMutex.get());
+  BRepCheck::Add (*myMap (myShape), BRepCheck_UnorientableShape);
 }
 
 //=======================================================================
-//function :   SetStatus
-//purpose  : 
+//function : SetStatus
+//purpose  :
 //=======================================================================
-
 void BRepCheck_Face::SetStatus(const BRepCheck_Status theStatus)
 {
-    BRepCheck::Add(myMap(myShape),theStatus);
+  Standard_Mutex::Sentry aLock(myMutex.get());
+  BRepCheck::Add (*myMap (myShape), theStatus);
 }
 
 //=======================================================================
@@ -511,7 +568,7 @@ Standard_Boolean BRepCheck_Face::IsUnorientable() const
   if (myOridone) {
     return (myOrires != BRepCheck_NoError);
   }
-  for (BRepCheck_ListIteratorOfListOfStatus itl(myMap(myShape));
+  for (BRepCheck_ListIteratorOfListOfStatus itl(*myMap(myShape));
        itl.More();
        itl.Next()) {
     if (itl.Value() == BRepCheck_UnorientableShape) {
diff --git a/src/BRepCheck/BRepCheck_IndexedDataMapOfShapeResult.hxx b/src/BRepCheck/BRepCheck_IndexedDataMapOfShapeResult.hxx
new file mode 100644 (file)
index 0000000..3d01836
--- /dev/null
@@ -0,0 +1,28 @@
+// Created on: 1995-12-06
+// Created by: Jacques GOUSSARD
+// Copyright (c) 1995-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef BRepCheck_DataMapOfShapeResult_HeaderFile
+#define BRepCheck_DataMapOfShapeResult_HeaderFile
+
+#include <TopoDS_Shape.hxx>
+#include <BRepCheck_Result.hxx>
+#include <TopTools_OrientedShapeMapHasher.hxx>
+#include <NCollection_IndexedDataMap.hxx>
+
+typedef NCollection_IndexedDataMap<TopoDS_Shape,Handle(BRepCheck_Result),TopTools_OrientedShapeMapHasher> BRepCheck_IndexedDataMapOfShapeResult;
+
+
+#endif
index 081dc77..edf7b0b 100644 (file)
 
 #include <BRepCheck_Status.hxx>
 #include <NCollection_List.hxx>
+#include <NCollection_Shared.hxx>
 
 typedef NCollection_List<BRepCheck_Status> BRepCheck_ListOfStatus;
 typedef NCollection_List<BRepCheck_Status>::Iterator BRepCheck_ListIteratorOfListOfStatus;
+typedef NCollection_Shared<BRepCheck_ListOfStatus> BRepCheck_HListOfStatus;
 
 
 #endif
index 20da833..cb84fb4 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+#include <BRepCheck_Result.hxx>
 
 #include <BRepCheck.hxx>
-#include <BRepCheck_Result.hxx>
-#include <Standard_NoSuchObject.hxx>
 #include <Standard_Type.hxx>
 #include <TopoDS_Shape.hxx>
 
@@ -25,14 +24,15 @@ IMPLEMENT_STANDARD_RTTIEXT(BRepCheck_Result,Standard_Transient)
 
 //=======================================================================
 //function : BRepCheck_Result
-//purpose  : 
+//purpose  :
 //=======================================================================
-BRepCheck_Result::BRepCheck_Result() :
-   myMin(Standard_False),myBlind(Standard_False)
+BRepCheck_Result::BRepCheck_Result()
+: myMin (Standard_False),
+  myBlind (Standard_False)
 {
+  //
 }
 
-
 //=======================================================================
 //function : Init
 //purpose  : 
@@ -49,33 +49,21 @@ void BRepCheck_Result::Init(const TopoDS_Shape& S)
 
 //=======================================================================
 //function : SetFailStatus
-//purpose  : 
+//purpose  :
 //=======================================================================
-void BRepCheck_Result::SetFailStatus(const TopoDS_Shape& S) 
+void BRepCheck_Result::SetFailStatus (const TopoDS_Shape& S)
 {
-  if(!myMap.IsBound(S)) {
-    BRepCheck_ListOfStatus thelist;
-    myMap.Bind(S, thelist);
+  Standard_Mutex::Sentry aLock(myMutex.get());
+  Handle(BRepCheck_HListOfStatus) aList;
+  if (!myMap.Find (S, aList))
+  {
+    aList = new BRepCheck_HListOfStatus();
+    myMap.Bind (S, aList);
   }
-  BRepCheck::Add(myMap(S), BRepCheck_CheckFail);
-}
-
-
-//=======================================================================
-//function : StatusOnShape
-//purpose  : 
-//=======================================================================
 
-const BRepCheck_ListOfStatus& BRepCheck_Result::StatusOnShape
-   (const TopoDS_Shape& S)
-{
-  if (!myMap.IsBound(S)) {
-    InContext(S);
-  }
-  return myMap(S);
+  BRepCheck::Add (*aList, BRepCheck_CheckFail);
 }
 
-
 //=======================================================================
 //function : InitContextIterator
 //purpose  : 
@@ -102,4 +90,16 @@ void BRepCheck_Result::NextShapeInContext()
   if (myIter.More() && myIter.Key().IsSame(myShape)) {
     myIter.Next();
   }
-}  
+}
+
+//=======================================================================
+//function : SetParallel
+//purpose  : 
+//=======================================================================
+void BRepCheck_Result::SetParallel(Standard_Boolean theIsParallel)
+{
+  if (theIsParallel && myMutex.IsNull())
+  {
+    myMutex.reset(new Standard_HMutex());
+  }
+}
index e3a0e9c..f731ef6 100644 (file)
 
 #include <TopoDS_Shape.hxx>
 #include <Standard_Boolean.hxx>
-#include <BRepCheck_DataMapOfShapeListOfStatus.hxx>
-#include <BRepCheck_DataMapIteratorOfDataMapOfShapeListOfStatus.hxx>
+#include <Standard_Mutex.hxx>
 #include <Standard_Transient.hxx>
+#include <BRepCheck_DataMapOfShapeListOfStatus.hxx>
 #include <BRepCheck_ListOfStatus.hxx>
+
+class BRepCheck_ParallelAnalyzer;
 class Standard_NoSuchObject;
 class TopoDS_Shape;
 
-
-class BRepCheck_Result;
 DEFINE_STANDARD_HANDLE(BRepCheck_Result, Standard_Transient)
 
 
@@ -39,7 +39,6 @@ class BRepCheck_Result : public Standard_Transient
 
 public:
 
-  
   Standard_EXPORT void Init (const TopoDS_Shape& S);
   
   Standard_EXPORT virtual void InContext (const TopoDS_Shape& ContextShape) = 0;
@@ -47,58 +46,64 @@ public:
   Standard_EXPORT virtual void Minimum() = 0;
   
   Standard_EXPORT virtual void Blind() = 0;
-  
+
   Standard_EXPORT void SetFailStatus (const TopoDS_Shape& S);
-  
-    const BRepCheck_ListOfStatus& Status() const;
-  
-    Standard_Boolean IsMinimum() const;
-  
-    Standard_Boolean IsBlind() const;
-  
-  //! If  not  already   done,  performs the   InContext
-  //! control and returns the list of status.
-  Standard_EXPORT const BRepCheck_ListOfStatus& StatusOnShape (const TopoDS_Shape& S);
-  
+
+  const BRepCheck_ListOfStatus& Status() const { return *myMap (myShape); }
+
+  Standard_Boolean IsMinimum() const { return myMin; }
+
+  Standard_Boolean IsBlind() const { return myBlind; }
+
   Standard_EXPORT void InitContextIterator();
-  
-    Standard_Boolean MoreShapeInContext() const;
-  
-    const TopoDS_Shape& ContextualShape() const;
-  
-    const BRepCheck_ListOfStatus& StatusOnShape() const;
-  
+
+  Standard_Boolean MoreShapeInContext() const { return myIter.More(); }
+
+  const TopoDS_Shape& ContextualShape() const { return myIter.Key(); }
+
+  const BRepCheck_ListOfStatus& StatusOnShape() const { return *myIter.Value(); }
+
   Standard_EXPORT void NextShapeInContext();
 
+  Standard_EXPORT void SetParallel (Standard_Boolean theIsParallel);
 
+  Standard_Boolean IsStatusOnShape (const TopoDS_Shape& theShape) const
+  {
+    return myMap.IsBound (theShape);
+  }
 
+  const BRepCheck_ListOfStatus& StatusOnShape (const TopoDS_Shape& theShape) const
+  {
+    return *myMap.Find (theShape);
+  }
+
+  friend class BRepCheck_ParallelAnalyzer;
 
   DEFINE_STANDARD_RTTIEXT(BRepCheck_Result,Standard_Transient)
 
 protected:
 
-  
   Standard_EXPORT BRepCheck_Result();
 
+protected:
+
   TopoDS_Shape myShape;
   Standard_Boolean myMin;
   Standard_Boolean myBlind;
   BRepCheck_DataMapOfShapeListOfStatus myMap;
-
+  mutable Handle(Standard_HMutex) myMutex;
 
 private:
 
+  Standard_HMutex* GetMutex()
+  {
+    return myMutex.get();
+  }
 
-  BRepCheck_DataMapIteratorOfDataMapOfShapeListOfStatus myIter;
+private:
 
+  BRepCheck_DataMapIteratorOfDataMapOfShapeListOfStatus myIter;
 
 };
 
-
-#include <BRepCheck_Result.lxx>
-
-
-
-
-
 #endif // _BRepCheck_Result_HeaderFile
diff --git a/src/BRepCheck/BRepCheck_Result.lxx b/src/BRepCheck/BRepCheck_Result.lxx
deleted file mode 100644 (file)
index 859bdae..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-// Created on: 1995-12-07
-// Created by: Jacques GOUSSARD
-// Copyright (c) 1995-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-//=======================================================================
-//function : Status
-//purpose  : 
-//=======================================================================
-
-inline const BRepCheck_ListOfStatus& BRepCheck_Result::Status() const
-{
-  return myMap(myShape);
-}
-
-//=======================================================================
-//function : IsMinimum
-//purpose  : 
-//=======================================================================
-
-inline Standard_Boolean BRepCheck_Result::IsMinimum() const
-{
-  return myMin;
-}
-
-//=======================================================================
-//function : IsBlind
-//purpose  : 
-//=======================================================================
-
-inline Standard_Boolean BRepCheck_Result::IsBlind() const
-{
-  return myBlind;
-}
-
-
-//=======================================================================
-//function : MoreShapeInContext
-//purpose  : 
-//=======================================================================
-
-inline Standard_Boolean BRepCheck_Result::MoreShapeInContext () const
-{
-  return myIter.More();
-}
-
-
-//=======================================================================
-//function : ContextualShape
-//purpose  : 
-//=======================================================================
-
-inline const TopoDS_Shape& BRepCheck_Result::ContextualShape () const
-{
-  return myIter.Key();
-}
-
-
-//=======================================================================
-//function : StatusOnShape
-//purpose  : 
-//=======================================================================
-
-inline const BRepCheck_ListOfStatus& BRepCheck_Result::StatusOnShape () const
-{
-  return myIter.Value();
-}
-
index d15b330..e5daa1c 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+#include <BRepCheck_Shell.hxx>
 
 #include <BRep_Builder.hxx>
 #include <BRep_Tool.hxx>
 #include <BRepCheck.hxx>
 #include <BRepCheck_ListIteratorOfListOfStatus.hxx>
 #include <BRepCheck_ListOfStatus.hxx>
-#include <BRepCheck_Shell.hxx>
 #include <Standard_Type.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
@@ -132,9 +132,8 @@ void BRepCheck_Shell::Minimum()
 
   if (!myMin)
   {
-    BRepCheck_ListOfStatus thelist;
-    myMap.Bind(myShape, thelist);
-    BRepCheck_ListOfStatus& lst = myMap(myShape);
+    Handle(BRepCheck_HListOfStatus) aNewList = new BRepCheck_HListOfStatus();
+    BRepCheck_ListOfStatus& lst = **myMap.Bound(myShape, aNewList);
 
     // it is checked if the shell is "connected"
     TopExp_Explorer exp(myShape,TopAbs_FACE);
@@ -193,18 +192,21 @@ void BRepCheck_Shell::Minimum()
 
 void BRepCheck_Shell::InContext(const TopoDS_Shape& S)
 {
-
-  if (myMap.IsBound(S)) {
-    return;
+  Handle(BRepCheck_HListOfStatus) aHList;
+  {
+    Standard_Mutex::Sentry aLock(myMutex.get());
+    if (myMap.IsBound (S))
+    {
+      return;
+    }
+    Handle(BRepCheck_HListOfStatus) aNewList = new BRepCheck_HListOfStatus();
+    aHList = *myMap.Bound(S, aNewList);
   }
-  BRepCheck_ListOfStatus thelist;
-  myMap.Bind(S, thelist);
-
-  BRepCheck_ListOfStatus& lst = myMap(S);
+  BRepCheck_ListOfStatus& lst = *aHList;
 
-//  for (TopExp_Explorer exp(S,TopAbs_SHELL); exp.More(); exp.Next()) {
-  TopExp_Explorer exp(S,TopAbs_SHELL) ;
-  for ( ; exp.More(); exp.Next()) {
+  //  for (TopExp_Explorer exp(S,TopAbs_SHELL); exp.More(); exp.Next()) {
+  TopExp_Explorer exp(S, TopAbs_SHELL);
+  for (; exp.More(); exp.Next()) {
     if (exp.Current().IsSame(myShape)) {
       break;
     }
@@ -262,11 +264,18 @@ void BRepCheck_Shell::Blind()
 //=======================================================================
 BRepCheck_Status BRepCheck_Shell::Closed(const Standard_Boolean Update)
 {
+  Handle(BRepCheck_HListOfStatus) aHList;
+  {
+    Standard_Mutex::Sentry aLock(myMutex.get());
+    aHList = myMap (myShape);
+  }
+
+  BRepCheck_ListOfStatus& aStatusList = *aHList;
   if (myCdone)
   {
     if (Update)
     {
-      BRepCheck::Add(myMap(myShape), myCstat);
+      BRepCheck::Add (aStatusList, myCstat);
     }
 
     return myCstat;
@@ -274,7 +283,7 @@ BRepCheck_Status BRepCheck_Shell::Closed(const Standard_Boolean Update)
 
   myCdone = Standard_True; // it will be done...
 
-  BRepCheck_ListIteratorOfListOfStatus itl(myMap(myShape));
+  BRepCheck_ListIteratorOfListOfStatus itl (aStatusList);
   if (itl.Value() != BRepCheck_NoError)
   {
     myCstat = itl.Value();
@@ -325,7 +334,7 @@ BRepCheck_Status BRepCheck_Shell::Closed(const Standard_Boolean Update)
         
         if (Update)
         {
-          BRepCheck::Add(myMap(myShape),myCstat);
+          BRepCheck::Add (aStatusList, myCstat);
         }
 
         return myCstat;
@@ -383,7 +392,7 @@ BRepCheck_Status BRepCheck_Shell::Closed(const Standard_Boolean Update)
     myCstat = BRepCheck_NotConnected;
     if (Update)
     {
-      BRepCheck::Add(myMap(myShape),myCstat);
+      BRepCheck::Add (aStatusList, myCstat);
     }
     return myCstat;
   }
@@ -406,7 +415,7 @@ BRepCheck_Status BRepCheck_Shell::Closed(const Standard_Boolean Update)
         myCstat = BRepCheck_InvalidMultiConnexity;
         if (Update)
         {
-          BRepCheck::Add(myMap(myShape),myCstat);
+          BRepCheck::Add (aStatusList, myCstat);
         }
 
         return myCstat;
@@ -419,7 +428,7 @@ BRepCheck_Status BRepCheck_Shell::Closed(const Standard_Boolean Update)
         myCstat=BRepCheck_NotClosed;
         if (Update)
         {
-          BRepCheck::Add(myMap(myShape),myCstat);
+          BRepCheck::Add (aStatusList ,myCstat);
         }
 
         return myCstat;
@@ -428,7 +437,7 @@ BRepCheck_Status BRepCheck_Shell::Closed(const Standard_Boolean Update)
   }
   
   if (Update) {
-    BRepCheck::Add(myMap(myShape),myCstat);
+    BRepCheck::Add (aStatusList, myCstat);
   }
   return myCstat;
 }
@@ -436,14 +445,20 @@ BRepCheck_Status BRepCheck_Shell::Closed(const Standard_Boolean Update)
 
 //=======================================================================
 //function : Orientation
-//purpose  : 
+//purpose  :
 //=======================================================================
-
 BRepCheck_Status BRepCheck_Shell::Orientation(const Standard_Boolean Update)
 {
+  Handle(BRepCheck_HListOfStatus) aHList;
+  {
+    Standard_Mutex::Sentry aLock(myMutex.get());
+    aHList = myMap (myShape);
+  }
+  BRepCheck_ListOfStatus& aStatusList = *aHList;
+
   if (myOdone) {
     if (Update) {
-      BRepCheck::Add(myMap(myShape), myOstat);
+      BRepCheck::Add (aStatusList, myOstat);
     }
     return myOstat;
   }
@@ -452,7 +467,7 @@ BRepCheck_Status BRepCheck_Shell::Orientation(const Standard_Boolean Update)
   myOstat = Closed();
   if (myOstat != BRepCheck_NotClosed && myOstat != BRepCheck_NoError) {
     if (Update) {
-      BRepCheck::Add(myMap(myShape), myOstat);
+      BRepCheck::Add (aStatusList, myOstat);
     }
     return myOstat;
   }
@@ -470,7 +485,7 @@ BRepCheck_Status BRepCheck_Shell::Orientation(const Standard_Boolean Update)
     if (!MapOfShapeOrientation.Bind(exp.Current(), (Standard_Integer)(exp.Current().Orientation()))) {
       myOstat = BRepCheck_RedundantFace;
       if (Update) {
-       BRepCheck::Add(myMap(myShape), myOstat);
+       BRepCheck::Add (aStatusList, myOstat);
       }
       else {
        return myOstat;
@@ -507,137 +522,163 @@ BRepCheck_Status BRepCheck_Shell::Orientation(const Standard_Boolean Update)
     TopTools_ListIteratorOfListOfShape lite(lface);
 
     if (lface.Extent() <= 2)
+    {
+      lite.Initialize(lface);
+      Fref = TopoDS::Face(lite.Value());
+
+      if (!MapOfShapeOrientation.IsBound(Fref))
       {
-       lite.Initialize(lface);
-       Fref = TopoDS::Face(lite.Value());
-       
-       if (!MapOfShapeOrientation.IsBound(Fref)) {
-         myOstat = BRepCheck_SubshapeNotInShape;
-         if (Update) {
-           BRepCheck::Add(myMap(myShape), myOstat);
-           }
-         // quit because no workaround for the incoherence is possible
-         return myOstat;
-       }
-       lite.Next();
-       
-       if (lite.More()) { // Edge of connectivity
-         //JR/Hp :
-         Standard_Integer iorf = MapOfShapeOrientation.Find(Fref);
-         orf = (TopAbs_Orientation) iorf;
-         //orf = (TopAbs_Orientation)MapOfShapeOrientation.Find(Fref);
-         Fref.Orientation(orf);
-         
-         // edge is examined
-         if (!lite.Value().IsSame(Fref)) { // edge non "closed"
-           for (ede.Init(Fref,TopAbs_EDGE); ede.More(); ede.Next()) {
-             if (ede.Current().IsSame(edg)) {
-               break;
-             }
-           }
-           TopAbs_Orientation orient = ede.Current().Orientation();
-           TopoDS_Face Fcur= TopoDS::Face(lite.Value());
-           
-           if (!MapOfShapeOrientation.IsBound(Fcur)) {
-             myOstat = BRepCheck_SubshapeNotInShape;
-             if (Update) {
-               BRepCheck::Add(myMap(myShape), myOstat);
-               }
-             // quit because no workaround for the incoherence is possible
-             return myOstat;
-           }
-           
-           //JR/Hp :
-           Standard_Integer anOriFCur = MapOfShapeOrientation.Find(Fcur) ;
-           orf = (TopAbs_Orientation)anOriFCur;
-           //  orf = (TopAbs_Orientation)MapOfShapeOrientation.Find(Fcur);
-           Fcur.Orientation(orf);
-           
-           for (ede.Init(Fcur, TopAbs_EDGE); ede.More(); ede.Next()) {
-             if (ede.Current().IsSame(edg)) {
-               break;
-             }
-           }
-           if (ede.Current().Orientation() == orient) {
-             // The loop is continued on the edges as many times 
-             // as the same edge is present in the wire
-
-             // modified by NIZHNY-MKK  Tue Sep 30 11:11:42 2003
-             Standard_Boolean bfound = Standard_False;
-             ede.Next();
-             for (; ede.More(); ede.Next()) {
-               if (ede.Current().IsSame(edg)) {
-                 // modified by NIZHNY-MKK  Tue Sep 30 11:12:03 2003
-                 bfound = Standard_True;
-                 break;
-               }
-             }
-             //              if (ede.Current().Orientation() == orient) {
-             // modified by NIZHNY-MKK  Thu Oct  2 17:56:47 2003
-             if (!bfound || (ede.Current().Orientation() == orient)) {
-               myOstat = BRepCheck_BadOrientationOfSubshape;
-               if (Update) {
-                 BRepCheck::Add(myMap(myShape), myOstat);
-                   break;
-                 }
-               return myOstat;
-             }
-           }
-         }
-       }
+        myOstat = BRepCheck_SubshapeNotInShape;
+        if (Update) 
+        {
+          BRepCheck::Add (aStatusList, myOstat);
+        }
+        // quit because no workaround for the incoherence is possible
+        return myOstat;
       }
+      lite.Next();
+      
+      if (lite.More()) // Edge of connectivity
+      {
+        //JR/Hp :
+        Standard_Integer iorf = MapOfShapeOrientation.Find(Fref);
+        orf = (TopAbs_Orientation) iorf;
+        //orf = (TopAbs_Orientation)MapOfShapeOrientation.Find(Fref);
+        Fref.Orientation(orf);
+
+        // edge is examined
+        if (!lite.Value().IsSame(Fref)) // edge non "closed"
+        {
+          for (ede.Init(Fref,TopAbs_EDGE); ede.More(); ede.Next())
+          {
+            if (ede.Current().IsSame(edg))
+            {
+              break;
+            }
+          }
+          TopAbs_Orientation orient = ede.Current().Orientation();
+          TopoDS_Face Fcur = TopoDS::Face(lite.Value());
+          if (!MapOfShapeOrientation.IsBound(Fcur))
+          {
+            myOstat = BRepCheck_SubshapeNotInShape;
+            if (Update)
+            {
+              BRepCheck::Add (aStatusList, myOstat);
+            }
+            // quit because no workaround for the incoherence is possible
+            return myOstat;
+          }
+
+          //JR/Hp :
+          Standard_Integer anOriFCur = MapOfShapeOrientation.Find(Fcur);
+          orf = (TopAbs_Orientation)anOriFCur;
+          //   orf = (TopAbs_Orientation)MapOfShapeOrientation.Find(Fcur);
+          Fcur.Orientation(orf);
+
+          for (ede.Init(Fcur, TopAbs_EDGE); ede.More(); ede.Next())
+          {
+            if (ede.Current().IsSame(edg))
+            {
+              break;
+            }
+          }
+          if (ede.Current().Orientation() == orient)
+          {
+            // The loop is continued on the edges as many times 
+            // as the same edge is present in the wire
+
+            // modified by NIZHNY-MKK  Tue Sep 30 11:11:42 2003
+            Standard_Boolean bfound = Standard_False;
+            ede.Next();
+            for (; ede.More(); ede.Next())
+            {
+              if (ede.Current().IsSame(edg))
+              {
+                // modified by NIZHNY-MKK  Tue Sep 30 11:12:03 2003
+                bfound = Standard_True;
+                break;
+              }
+            }
+            // if (ede.Current().Orientation() == orient) {
+            // modified by NIZHNY-MKK  Thu Oct  2 17:56:47 2003
+            if (!bfound || (ede.Current().Orientation() == orient)) 
+            {
+              myOstat = BRepCheck_BadOrientationOfSubshape;
+              if (Update) 
+              {
+                BRepCheck::Add (aStatusList, myOstat);
+                break;
+              }
+              return myOstat;
+            }
+          }
+        }
+      }
+    }
     else //more than two faces
+    {
+      Standard_Integer numF = 0, numR = 0;
+      TopTools_MapOfShape Fmap;
+
+      for (lite.Initialize(lface); lite.More(); lite.Next())
       {
-       Standard_Integer numF = 0, numR = 0;
-       TopTools_MapOfShape Fmap;
-
-       for (lite.Initialize(lface); lite.More(); lite.Next())
-         {
-           TopoDS_Face Fcur= TopoDS::Face(lite.Value());
-           if (!MapOfShapeOrientation.IsBound(Fcur))
-             {
-               myOstat = BRepCheck_SubshapeNotInShape;
-               if (Update)
-                 BRepCheck::Add(myMap(myShape), myOstat);
-             // quit because no workaround for the incoherence is possible
-               return myOstat;
-             }
+        TopoDS_Face Fcur= TopoDS::Face(lite.Value());
+        if (!MapOfShapeOrientation.IsBound(Fcur))
+        {
+          myOstat = BRepCheck_SubshapeNotInShape;
+          if (Update)
+          {
+            BRepCheck::Add (aStatusList, myOstat);
+          }
+          // quit because no workaround for the incoherence is possible
+          return myOstat;
+        }
 
-           Standard_Integer iorf = MapOfShapeOrientation.Find(Fcur);
-           orf = (TopAbs_Orientation) iorf;
-           //orf = (TopAbs_Orientation)MapOfShapeOrientation.Find(Fcur);
-           Fcur.Orientation(orf);
-
-           for (ede.Init(Fcur,TopAbs_EDGE); ede.More(); ede.Next())
-             if (ede.Current().IsSame(edg))
-               break;
-           if (Fmap.Contains(Fcur)) //edge is "closed" on Fcur, we meet Fcur twice
-             {
-               ede.Next();
-               for (; ede.More(); ede.Next())
-                 if (ede.Current().IsSame(edg))
-                   break;
-             }
-           TopAbs_Orientation orient = ede.Current().Orientation();
-           if (orient == TopAbs_FORWARD)
-             numF++;
-           else
-             numR++;
+        Standard_Integer iorf = MapOfShapeOrientation.Find(Fcur);
+        orf = (TopAbs_Orientation) iorf;
+        //orf = (TopAbs_Orientation)MapOfShapeOrientation.Find(Fcur);
+        Fcur.Orientation(orf);
+    
+        for (ede.Init(Fcur,TopAbs_EDGE); ede.More(); ede.Next())
+        if (ede.Current().IsSame(edg))
+        {
+          break;
+        }
+        if (Fmap.Contains(Fcur)) //edge is "closed" on Fcur, we meet Fcur twice
+        {
+          ede.Next();
+          for (; ede.More(); ede.Next())
+          {
+            if (ede.Current().IsSame(edg))
+            {
+              break;
+            }
+          }
+        }
+        TopAbs_Orientation orient = ede.Current().Orientation();
+        if (orient == TopAbs_FORWARD)
+        {
+          numF++;
+        }
+        else
+        {
+          numR++;
+        }
 
-           Fmap.Add(Fcur);
-         }
+        Fmap.Add (Fcur);
+      }
 
-       if (numF != numR)
-         {
-           myOstat = BRepCheck_BadOrientationOfSubshape;
-           if (Update)
-             {
-               BRepCheck::Add(myMap(myShape), myOstat);
-               break;
-             }
-           return myOstat;
-         }
+      if (numF != numR)
+      {
+        myOstat = BRepCheck_BadOrientationOfSubshape;
+        if (Update)
+        {
+          BRepCheck::Add (aStatusList, myOstat);
+          break;
+        }
+        return myOstat;
       }
+    }
   }
 
 // If at least one incorrectly oriented face has been found, it is checked if the shell can be oriented. 
@@ -645,93 +686,112 @@ BRepCheck_Status BRepCheck_Shell::Orientation(const Standard_Boolean Update)
 //          a coherent orientation. (it is not possible on a Moebius band)
 //          BRepCheck_UnorientableShape is checked
 
-  if (myOstat == BRepCheck_BadOrientationOfSubshape) {
-    if (!Fref.IsNull()) {
-      if (Nbedges > 0) {
-       TopTools_MapOfShape alre;
-       TopTools_ListOfShape voisin;
-       voisin.Append(Fref);
-       alre.Clear();
-       while (!voisin.IsEmpty()) {
-         Fref=TopoDS::Face(voisin.First());
-         voisin.RemoveFirst();
-         if (!MapOfShapeOrientation.IsBound(Fref)) {
-           myOstat = BRepCheck_SubshapeNotInShape;
-           if (Update) {
-             BRepCheck::Add(myMap(myShape), myOstat);
-           }
-           // quit because no workaround for the incoherence is possible
-           return myOstat;
-         }
+  if (myOstat == BRepCheck_BadOrientationOfSubshape)
+  {
+    if (!Fref.IsNull())
+    {
+      if (Nbedges > 0)
+      {
+        TopTools_MapOfShape alre;
+        TopTools_ListOfShape voisin;
+        voisin.Append (Fref);
+        alre.Clear();
+        while (!voisin.IsEmpty())
+        {
+          Fref=TopoDS::Face (voisin.First());
+          voisin.RemoveFirst();
+          if (!MapOfShapeOrientation.IsBound (Fref))
+          {
+            myOstat = BRepCheck_SubshapeNotInShape;
+            if (Update) 
+            {
+              BRepCheck::Add (aStatusList, myOstat);
+            }
+            // quit because no workaround for the incoherence is possible
+            return myOstat;
+          }
 //JR/Hp :
           Standard_Integer iorf = MapOfShapeOrientation.Find(Fref) ;
-         orf = (TopAbs_Orientation) iorf ;
-//       orf = (TopAbs_Orientation)MapOfShapeOrientation.Find(Fref);
-         Fref.Orientation(orf);
+          orf = (TopAbs_Orientation) iorf ;
+//        orf = (TopAbs_Orientation)MapOfShapeOrientation.Find(Fref);
+          Fref.Orientation(orf);
 
 #ifdef OCCT_DEBUG
-  if (BRepCheck_Trace(0) > 3) {
+  if (BRepCheck_Trace(0) > 3)
+  {
     std::cout << "Fref : " ;
     PrintShape(Fref, MapOfShapeOrientation.NbBuckets());
   }
 #endif
 
-         TopExp_Explorer edFcur;
-         alre.Add(Fref);
-
-         for (ede.Init(Fref,TopAbs_EDGE); ede.More(); ede.Next()) {
-           const TopoDS_Edge& edg = TopoDS::Edge(ede.Current());
-           TopAbs_Orientation orient = edg.Orientation();
-           TopTools_ListOfShape& lface = myMapEF.ChangeFromKey(edg);
-           TopTools_ListIteratorOfListOfShape lite(lface);
-         
-           TopoDS_Face Fcur= TopoDS::Face(lite.Value());
-           if (Fcur.IsSame(Fref)) {
-             lite.Next();
-             if (lite.More()) {
-               Fcur=TopoDS::Face(lite.Value());
-             }
-             else {
-               // from the free border one goes to the next edge
-               continue;
-             }
-           }
+          TopExp_Explorer edFcur;
+          alre.Add(Fref);
 
-           if (!MapOfShapeOrientation.IsBound(Fcur)) {
-             myOstat = BRepCheck_SubshapeNotInShape;
-             if (Update) {
-               BRepCheck::Add(myMap(myShape), myOstat);
-             }
-             // quit because no workaround for the incoherence is possible
-             return myOstat;
-           }
+          for (ede.Init(Fref,TopAbs_EDGE); ede.More(); ede.Next())
+          {
+            const TopoDS_Edge& edg = TopoDS::Edge (ede.Current());
+            TopAbs_Orientation orient = edg.Orientation();
+            TopTools_ListOfShape& lface = myMapEF.ChangeFromKey (edg);
+            TopTools_ListIteratorOfListOfShape lite (lface);
+
+            TopoDS_Face Fcur = TopoDS::Face (lite.Value());
+            if (Fcur.IsSame(Fref))
+            {
+              lite.Next();
+              if (lite.More())
+              {
+                Fcur = TopoDS::Face (lite.Value());
+              }
+              else
+              {
+                // from the free border one goes to the next edge
+                continue;
+              }
+            }
+
+            if (!MapOfShapeOrientation.IsBound(Fcur))
+            {
+              myOstat = BRepCheck_SubshapeNotInShape;
+              if (Update)
+              {
+                BRepCheck::Add (aStatusList, myOstat);
+              }
+              // quit because no workaround for the incoherence is possible
+              return myOstat;
+            }
 
 //JR/Hp :
             Standard_Integer anOriFCur = MapOfShapeOrientation.Find(Fcur) ;
-           orf = (TopAbs_Orientation)anOriFCur;
-//         orf = (TopAbs_Orientation)MapOfShapeOrientation.Find(Fcur);
-           Fcur.Orientation(orf);
+            orf = (TopAbs_Orientation)anOriFCur;
+//          orf = (TopAbs_Orientation)MapOfShapeOrientation.Find(Fcur);
+            Fcur.Orientation(orf);
 
 #ifdef OCCT_DEBUG
-  if (BRepCheck_Trace(0) > 3) {
+  if (BRepCheck_Trace(0) > 3)
+  {
     std::cout << "    Fcur : " ;
     PrintShape(Fcur, MapOfShapeOrientation.NbBuckets());
   }
 #endif
-           for (edFcur.Init(Fcur, TopAbs_EDGE); edFcur.More(); edFcur.Next()) {
-             if (edFcur.Current().IsSame(edg)) {
-               break;
-             }
-           }
-           if (edFcur.Current().Orientation() == orient) {
-             if (alre.Contains(Fcur)) {
-               // It is necessary to return a face that has been already examined or returned
-               // if one gets nowhere, the shell cannot be oriented.
-               myOstat = BRepCheck_UnorientableShape;
-               if (Update) {
-                 BRepCheck::Add(myMap(myShape), myOstat);
-               }
-               // quit, otherwise there is a risk of taking too much time.
+            for (edFcur.Init(Fcur, TopAbs_EDGE); edFcur.More(); edFcur.Next())
+            {
+              if (edFcur.Current().IsSame(edg))
+              {
+                break;
+              }
+            }
+            if (edFcur.Current().Orientation() == orient)
+            {
+              if (alre.Contains(Fcur))
+              {
+                // It is necessary to return a face that has been already examined or returned
+                // if one gets nowhere, the shell cannot be oriented.
+                myOstat = BRepCheck_UnorientableShape;
+                if (Update)
+                {
+                  BRepCheck::Add (aStatusList, myOstat);
+                }
+                // quit, otherwise there is a risk of taking too much time.
 #ifdef OCCT_DEBUG
   if (BRepCheck_Trace(0) > 3) {
     orf = (TopAbs_Orientation)MapOfShapeOrientation.Find(Fcur);
@@ -741,14 +801,15 @@ BRepCheck_Status BRepCheck_Shell::Orientation(const Standard_Boolean Update)
     PrintShape(Fcur, MapOfShapeOrientation.NbBuckets());
   }
 #endif
-               return myOstat;
-             }
-             orf = TopAbs::Reverse(orf);
-             MapOfShapeOrientation(Fcur)=orf;
+                return myOstat;
+              }
+              orf = TopAbs::Reverse(orf);
+              MapOfShapeOrientation(Fcur)=orf;
 
 
 #ifdef OCCT_DEBUG
-  if (BRepCheck_Trace(0) > 3) {
+  if (BRepCheck_Trace(0) > 3)
+  {
     orf = (TopAbs_Orientation)MapOfShapeOrientation.Find(Fcur);
     Fcur.Orientation(orf);
     std::cout << "    Resulting Fcur is returned : " ;
@@ -756,47 +817,56 @@ BRepCheck_Status BRepCheck_Shell::Orientation(const Standard_Boolean Update)
   }
 #endif
 
-           }
-           if (alre.Add(Fcur)) {
-             voisin.Append(Fcur);
-           }
-         }
-       }
+            }
+            if (alre.Add (Fcur))
+            {
+              voisin.Append (Fcur);
+            }
+          }
+        }
       }
     }
   }
 
-  if (Update) {
-    BRepCheck::Add(myMap(myShape), myOstat);
+  if (Update) 
+  {
+    BRepCheck::Add (aStatusList, myOstat);
   }
   return myOstat;
 }
 
 //=======================================================================
 //function : SetUnorientable
-//purpose  : 
+//purpose  :
 //=======================================================================
-
 void BRepCheck_Shell::SetUnorientable()
 {
-  BRepCheck::Add(myMap(myShape),BRepCheck_UnorientableShape);
+  Standard_Mutex::Sentry aLock(myMutex.get());
+  BRepCheck::Add (*myMap (myShape), BRepCheck_UnorientableShape);
 }
 
-
 //=======================================================================
 //function : IsUnorientable
-//purpose  : 
+//purpose  :
 //=======================================================================
-
 Standard_Boolean BRepCheck_Shell::IsUnorientable() const
 {
-  if (myOdone) {
+  if (myOdone)
+  {
     return (myOstat != BRepCheck_NoError);
   }
-  for (BRepCheck_ListIteratorOfListOfStatus itl(myMap(myShape));
-       itl.More();
-       itl.Next()) {
-    if (itl.Value() == BRepCheck_UnorientableShape) {
+
+  Handle(BRepCheck_HListOfStatus) aHList;
+  {
+    Standard_Mutex::Sentry aLock(myMutex.get());
+    aHList = myMap (myShape);
+  }
+  BRepCheck_ListOfStatus& aStatusList = *aHList;
+
+  for (BRepCheck_ListIteratorOfListOfStatus itl(aStatusList); itl.More(); itl.Next())
+  {
+    if (itl.Value() == BRepCheck_UnorientableShape)
+    {
       return Standard_True;
     }
   }
index 2a6d1af..1e1cb92 100644 (file)
@@ -208,10 +208,9 @@ void BRepCheck_Solid::Minimum()
   TopTools_MapOfShape aMSS;
   TopAbs_Orientation aOr; 
   BRepCheck_VectorOfToolSolid aVTS;
-  BRepCheck_ListOfStatus thelist;
-  //
-  myMap.Bind(myShape, thelist);
-  BRepCheck_ListOfStatus& aLST = myMap(myShape);
+
+  Handle(BRepCheck_HListOfStatus) aNewList = new BRepCheck_HListOfStatus();
+  BRepCheck_ListOfStatus& aLST = **myMap.Bound (myShape, aNewList);
   aLST.Append(BRepCheck_NoError);
   //
   //-------------------------------------------------
@@ -221,8 +220,7 @@ void BRepCheck_Solid::Minimum()
   for (; !bFound && aExp.More(); aExp.Next()) {
     const TopoDS_Shape& aF=aExp.Current();
     if (!aMSS.Add(aF)) {
-      BRepCheck::Add(myMap(myShape), 
-                     BRepCheck_InvalidImbricationOfShells);
+      BRepCheck::Add (aLST, BRepCheck_InvalidImbricationOfShells);
       bFound=!bFound;
     }
   } 
@@ -240,8 +238,7 @@ void BRepCheck_Solid::Minimum()
     if (aSx.ShapeType()!=TopAbs_SHELL) {
       aOr=aSx.Orientation();
       if (aOr!=TopAbs_INTERNAL) {
-        BRepCheck::Add(myMap(myShape), 
-                       BRepCheck_BadOrientationOfSubshape);
+        BRepCheck::Add (aLST, BRepCheck_BadOrientationOfSubshape);
       } 
       continue;
     }
@@ -281,8 +278,7 @@ void BRepCheck_Solid::Minimum()
   //
   if (!iCntSh && iCntShInt) {
     // all shells in the solid are internal
-    BRepCheck::Add(myMap(myShape), 
-                   BRepCheck_BadOrientationOfSubshape);
+    BRepCheck::Add (aLST, BRepCheck_BadOrientationOfSubshape);
   }
   //
   aNbVTS=aVTS.Size();
@@ -300,8 +296,7 @@ void BRepCheck_Solid::Minimum()
       ++aNbVTS1;
       if (aNbVTS1>1) {
         // Too many growths
-        BRepCheck::Add(myMap(myShape), 
-                       BRepCheck_EnclosedRegion);
+        BRepCheck::Add (aLST, BRepCheck_EnclosedRegion);
         break;
       }
     }
@@ -318,8 +313,7 @@ void BRepCheck_Solid::Minimum()
       bFlag=aTSi.IsOut(aTSj);
       if (bFlag) {
         // smt of solid is out of solid
-        BRepCheck::Add(myMap(myShape), 
-                       BRepCheck_SubshapeNotInShape);
+        BRepCheck::Add (aLST, BRepCheck_SubshapeNotInShape);
         bFound=!bFound;
       }
     }
index a6eaec1..89c5769 100644 (file)
@@ -56,16 +56,16 @@ BRepCheck_Vertex::BRepCheck_Vertex(const TopoDS_Vertex& V)
 
 //=======================================================================
 //function : Minimum
-//purpose  : 
+//purpose  :
 //=======================================================================
-
 void BRepCheck_Vertex::Minimum()
 {
-  if (!myMin) {
+  if (!myMin)
+  {
     // checks the existence of a point 3D
-    BRepCheck_ListOfStatus thelist;
-    myMap.Bind(myShape, thelist);
-    myMap(myShape).Append(BRepCheck_NoError);
+    Handle(BRepCheck_HListOfStatus) aNewList = new BRepCheck_HListOfStatus();
+    BRepCheck_ListOfStatus& lst = **myMap.Bound (myShape, aNewList);
+    lst.Append (BRepCheck_NoError);
     myMin = Standard_True;
   }
 }
@@ -78,21 +78,29 @@ void BRepCheck_Vertex::Minimum()
 
 void BRepCheck_Vertex::InContext(const TopoDS_Shape& S)
 {
-  if (myMap.IsBound(S)) {
-    return;
+  Handle(BRepCheck_HListOfStatus) aHList;
+  {
+    Standard_Mutex::Sentry aLock(myMutex.get());
+    if (myMap.IsBound (S))
+    {
+      return;
+    }
+
+    Handle(BRepCheck_HListOfStatus) aNewList = new BRepCheck_HListOfStatus();
+    aHList = *myMap.Bound (S, aNewList);
   }
-  BRepCheck_ListOfStatus thelist;
-  myMap.Bind(S, thelist);
+  BRepCheck_ListOfStatus& lst = *aHList;
 
-//  for (TopExp_Explorer exp(S,TopAbs_VERTEX); exp.More(); exp.Next()) {
-  TopExp_Explorer exp(S,TopAbs_VERTEX) ;
-  for ( ; exp.More(); exp.Next()) {
+  TopExp_Explorer exp(S, TopAbs_VERTEX);
+  for (; exp.More(); exp.Next())
+  {
     if (exp.Current().IsSame(myShape)) {
       break;
     }
   }
-  if (!exp.More()) {
-    BRepCheck::Add(myMap(S),BRepCheck_SubshapeNotInShape);
+  if (!exp.More())
+  {
+    BRepCheck::Add (lst, BRepCheck_SubshapeNotInShape);
     return; // leaves
   }
 
@@ -102,47 +110,53 @@ void BRepCheck_Vertex::InContext(const TopoDS_Shape& S)
   gp_Pnt Controlp;
 
   TopAbs_ShapeEnum styp = S.ShapeType();
-  switch (styp) {
-
-  case TopAbs_EDGE:
+  switch (styp)
+  {
+    case TopAbs_EDGE:
     {
       // Try to find the vertex on the edge
-      
       const TopoDS_Edge& E = TopoDS::Edge(S);
       TopoDS_Iterator itv(E.Oriented(TopAbs_FORWARD));
       TopoDS_Vertex VFind;
       Standard_Boolean multiple = Standard_False;
-      while (itv.More()) {
-       const TopoDS_Vertex& VF = TopoDS::Vertex(itv.Value());
-       if (itv.Value().IsSame(myShape)) {
-         if (VFind.IsNull()) {
-           VFind = VF;
-         }
-         else {
-           if ((VFind.Orientation() == TopAbs_FORWARD && 
-                VF.Orientation() == TopAbs_REVERSED) ||
-               (VFind.Orientation() == TopAbs_REVERSED &&
-                VF.Orientation() == TopAbs_FORWARD)) {
-             // the vertex on the edge is at once F and R
-             multiple = Standard_True; 
-           }
-           if (VFind.Orientation() != TopAbs_FORWARD && 
-               VFind.Orientation() != TopAbs_REVERSED) {
-             if (VF.Orientation() == TopAbs_FORWARD ||
-                 VF.Orientation() == TopAbs_REVERSED) {
-               VFind = VF;
-             }
-           }
-         }
-       }
-       itv.Next();
+      while (itv.More())
+      {
+        const TopoDS_Vertex& VF = TopoDS::Vertex(itv.Value());
+        if (itv.Value().IsSame(myShape))
+        {
+          if (VFind.IsNull())
+          {
+            VFind = VF;
+          }
+          else
+          {
+            if ((VFind.Orientation() == TopAbs_FORWARD &&
+                    VF.Orientation() == TopAbs_REVERSED) ||
+              (VFind.Orientation() == TopAbs_REVERSED &&
+                  VF.Orientation() == TopAbs_FORWARD))
+            {
+              // the vertex on the edge is at once F and R
+              multiple = Standard_True;
+            }
+            if (VFind.Orientation() != TopAbs_FORWARD &&
+                VFind.Orientation() != TopAbs_REVERSED)
+            {
+              if (VF.Orientation() == TopAbs_FORWARD ||
+                  VF.Orientation() == TopAbs_REVERSED)
+              {
+                VFind = VF;
+              }
+            }
+          }
+        }
+        itv.Next();
       }
 
       // VFind is not null for sure
       TopAbs_Orientation orv = VFind.Orientation();
 
-      Standard_Real Tol  = BRep_Tool::Tolerance(TopoDS::Vertex(myShape));
-      Tol = Max(Tol,BRep_Tool::Tolerance(E)); // to check
+      Standard_Real Tol = BRep_Tool::Tolerance(TopoDS::Vertex(myShape));
+      Tol = Max(Tol, BRep_Tool::Tolerance(E)); // to check
       Tol *= Tol;
 
       Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
@@ -150,124 +164,141 @@ void BRepCheck_Vertex::InContext(const TopoDS_Shape& S)
       const TopLoc_Location& Eloc = E.Location();
 
       BRep_ListIteratorOfListOfPointRepresentation itpr;
-      while (itcr.More()) {
-       // For each CurveRepresentation, the provided parameter is checked
-       const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
-       const TopLoc_Location& loc = cr->Location();
-       TopLoc_Location L = (Eloc * loc).Predivided(myShape.Location());
-
-       if (cr->IsCurve3D()) {
-         const Handle(Geom_Curve)& C = cr->Curve3D();
-         if (!C.IsNull()) { // edge non degenerated
-           itpr.Initialize(TV->Points());
-           while (itpr.More()) {
-             const Handle(BRep_PointRepresentation)& pr = itpr.Value();
-             if (pr->IsPointOnCurve(C,L)) {
-               Controlp = C->Value(pr->Parameter());
-               Controlp.Transform(L.Transformation());
-               if (prep.SquareDistance(Controlp)> Tol) {
-                 BRepCheck::Add(myMap(S),BRepCheck_InvalidPointOnCurve);
-               }
-             }
-             itpr.Next();
-           }
-           if (orv == TopAbs_FORWARD || orv == TopAbs_REVERSED) {
-             Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (cr));
-             if (orv == TopAbs_FORWARD || multiple) {
-               Controlp = C->Value(GC->First());
-               Controlp.Transform(L.Transformation());
-               if (prep.SquareDistance(Controlp)> Tol) {
-                 BRepCheck::Add(myMap(S),BRepCheck_InvalidPointOnCurve);
-               }
-             }
-             if (orv == TopAbs_REVERSED || multiple) {
-               Controlp = C->Value(GC->Last());
-               Controlp.Transform(L.Transformation());
-               if (prep.SquareDistance(Controlp)> Tol) {
-                 BRepCheck::Add(myMap(S),BRepCheck_InvalidPointOnCurve);
-               }
-             }
-           }
-         }
-       }
-       else if (cr->IsCurveOnSurface()) {
-         const Handle(Geom_Surface)& Su = cr->Surface();
-         const Handle(Geom2d_Curve)& PC = cr->PCurve();
-         Handle(Geom2d_Curve) PC2;
-         if (cr->IsCurveOnClosedSurface()) {
-           PC2 = cr->PCurve2();
-         }
-         itpr.Initialize(TV->Points());
-         while (itpr.More()) {
-           const Handle(BRep_PointRepresentation)& pr = itpr.Value();
-           if (pr->IsPointOnCurveOnSurface(PC,Su,L)) {
-             gp_Pnt2d p2d = PC->Value(pr->Parameter());
-             Controlp = Su->Value(p2d.X(),p2d.Y());
-             Controlp.Transform(L.Transformation());
-             if (prep.SquareDistance(Controlp)> Tol) {
-               BRepCheck::Add(myMap(S),
-                              BRepCheck_InvalidPointOnCurveOnSurface);
-             }
-           }
-           if (!PC2.IsNull() && pr->IsPointOnCurveOnSurface(PC2,Su,L)) {
-             gp_Pnt2d p2d = PC2->Value(pr->Parameter());
-             Controlp = Su->Value(p2d.X(),p2d.Y());
-             Controlp.Transform(L.Transformation());
-             if (prep.SquareDistance(Controlp)> Tol) {
-               BRepCheck::Add(myMap(S),
-                              BRepCheck_InvalidPointOnCurveOnSurface);
-             }
-           }
-           itpr.Next();
-         }
-       }
-       itcr.Next();
+      while (itcr.More())
+      {
+        // For each CurveRepresentation, the provided parameter is checked
+        const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
+        const TopLoc_Location& loc = cr->Location();
+        TopLoc_Location L = (Eloc * loc).Predivided(myShape.Location());
+
+        if (cr->IsCurve3D())
+        {
+          const Handle(Geom_Curve)& C = cr->Curve3D();
+          if (!C.IsNull()) // edge non degenerated
+          {
+            itpr.Initialize(TV->Points());
+            while (itpr.More())
+            {
+              const Handle(BRep_PointRepresentation)& pr = itpr.Value();
+              if (pr->IsPointOnCurve (C, L))
+              {
+                Controlp = C->Value (pr->Parameter());
+                Controlp.Transform (L.Transformation());
+                if (prep.SquareDistance (Controlp) > Tol)
+                {
+                  BRepCheck::Add (lst, BRepCheck_InvalidPointOnCurve);
+                }
+              }
+              itpr.Next();
+            }
+            if (orv == TopAbs_FORWARD || orv == TopAbs_REVERSED)
+            {
+              Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(cr);
+              if (orv == TopAbs_FORWARD || multiple)
+              {
+                Controlp = C->Value(GC->First());
+                Controlp.Transform(L.Transformation());
+                if (prep.SquareDistance(Controlp) > Tol)
+                {
+                  BRepCheck::Add (lst, BRepCheck_InvalidPointOnCurve);
+                }
+              }
+              if (orv == TopAbs_REVERSED || multiple)
+              {
+                Controlp = C->Value(GC->Last());
+                Controlp.Transform(L.Transformation());
+                if (prep.SquareDistance (Controlp) > Tol)
+                {
+                  BRepCheck::Add (lst, BRepCheck_InvalidPointOnCurve);
+                }
+              }
+            }
+          }
+        }
+        else if (cr->IsCurveOnSurface())
+        {
+          const Handle(Geom_Surface)& Su = cr->Surface();
+          const Handle(Geom2d_Curve)& PC = cr->PCurve();
+          Handle(Geom2d_Curve) PC2;
+          if (cr->IsCurveOnClosedSurface())
+          {
+            PC2 = cr->PCurve2();
+          }
+          itpr.Initialize(TV->Points());
+          while (itpr.More())
+          {
+            const Handle(BRep_PointRepresentation)& pr = itpr.Value();
+            if (pr->IsPointOnCurveOnSurface(PC, Su, L))
+            {
+              gp_Pnt2d p2d = PC->Value(pr->Parameter());
+              Controlp = Su->Value(p2d.X(), p2d.Y());
+              Controlp.Transform(L.Transformation());
+              if (prep.SquareDistance(Controlp) > Tol)
+              {
+                BRepCheck::Add (lst, BRepCheck_InvalidPointOnCurveOnSurface);
+              }
+            }
+            if (!PC2.IsNull() && pr->IsPointOnCurveOnSurface (PC2, Su, L))
+            {
+              gp_Pnt2d p2d = PC2->Value(pr->Parameter());
+              Controlp = Su->Value(p2d.X(), p2d.Y());
+              Controlp.Transform(L.Transformation());
+              if (prep.SquareDistance(Controlp) > Tol)
+              {
+                BRepCheck::Add (lst, BRepCheck_InvalidPointOnCurveOnSurface);
+              }
+            }
+            itpr.Next();
+          }
+        }
+        itcr.Next();
       }
-      if (myMap(S).IsEmpty()) {
-       myMap(S).Append(BRepCheck_NoError);
+      if (lst.IsEmpty())
+      {
+        lst.Append (BRepCheck_NoError);
       }
-
+      break;
     }
-    break;
-
-  case TopAbs_FACE:
+    case TopAbs_FACE:
     {
-
       Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &S.TShape());
       const TopLoc_Location& Floc = S.Location();
       const TopLoc_Location& TFloc = TF->Location();
       const Handle(Geom_Surface)& Su = TF->Surface();
       TopLoc_Location L = (Floc * TFloc).Predivided(myShape.Location());
 
-      Standard_Real Tol  = BRep_Tool::Tolerance(TopoDS::Vertex(myShape));
-      Tol = Max(Tol,BRep_Tool::Tolerance(TopoDS::Face(S))); // to check
+      Standard_Real Tol = BRep_Tool::Tolerance(TopoDS::Vertex(myShape));
+      Tol = Max (Tol, BRep_Tool::Tolerance(TopoDS::Face(S))); // to check
       Tol *= Tol;
 
       BRep_ListIteratorOfListOfPointRepresentation itpr(TV->Points());
-      while (itpr.More()) {
-       const Handle(BRep_PointRepresentation)& pr = itpr.Value();
-       if (pr->IsPointOnSurface(Su,L)) {
-         Controlp = Su->Value(pr->Parameter(),pr->Parameter2());
-         Controlp.Transform(L.Transformation());
-         if (prep.SquareDistance(Controlp)> Tol) {
-           BRepCheck::Add(myMap(S),BRepCheck_InvalidPointOnSurface);
-         }
-       }
-       itpr.Next();
+      while (itpr.More())
+      {
+        const Handle(BRep_PointRepresentation)& pr = itpr.Value();
+        if (pr->IsPointOnSurface (Su, L))
+        {
+          Controlp = Su->Value (pr->Parameter(), pr->Parameter2());
+          Controlp.Transform(L.Transformation());
+          if (prep.SquareDistance(Controlp) > Tol)
+          {
+            BRepCheck::Add (lst, BRepCheck_InvalidPointOnSurface);
+          }
+        }
+        itpr.Next();
       }
-      if (myMap(S).IsEmpty()) {
-       myMap(S).Append(BRepCheck_NoError);
+      if (lst.IsEmpty())
+      {
+        lst.Append (BRepCheck_NoError);
       }
+      break;
+    }
+    default:
+    {
+      break;
     }
-
-  default:
-    break;
-
   }
-
 }
 
-
 //=======================================================================
 //function : Blind
 //purpose  : 
@@ -365,4 +396,3 @@ Standard_Real BRepCheck_Vertex::Tolerance()
   return sqrt(Tol*1.05);
 }
 
-
index 7845d76..7177add 100644 (file)
@@ -142,10 +142,10 @@ void BRepCheck_Wire::Minimum()
 {
   myCdone = Standard_False;
   myGctrl = Standard_True;
-  if (!myMin) {
-    BRepCheck_ListOfStatus thelist;
-    myMap.Bind(myShape, thelist);
-    BRepCheck_ListOfStatus& lst = myMap(myShape);
+  if (!myMin)
+  {
+    Handle(BRepCheck_HListOfStatus) aNewList = new BRepCheck_HListOfStatus();
+    BRepCheck_ListOfStatus& lst = **myMap.Bound (myShape, aNewList);
 
     // check that the wire is "connex"
     TopExp_Explorer exp(myShape,TopAbs_EDGE);
@@ -195,53 +195,65 @@ void BRepCheck_Wire::Minimum()
 //=======================================================================
 void BRepCheck_Wire::InContext(const TopoDS_Shape& S)
 {
+  Handle(BRepCheck_HListOfStatus) aHList;
+  {
+    Standard_Mutex::Sentry aLock(myMutex.get());
+    if (myMap.IsBound (S))
+    {
+      return;
+    }
 
-  if (myMap.IsBound(S)) {
-    return;
+    Handle(BRepCheck_HListOfStatus) aNewList = new BRepCheck_HListOfStatus();
+    aHList = *myMap.Bound(S, aNewList);
   }
-  BRepCheck_ListOfStatus thelist;
-  myMap.Bind(S, thelist);
-
-  BRepCheck_ListOfStatus& lst = myMap(S);
+  BRepCheck_ListOfStatus& lst = *aHList;
 
   // check if my wire is in <S>
-  TopExp_Explorer exp(S,TopAbs_WIRE); 
-  for ( ; exp.More(); exp.Next()) {
+  TopExp_Explorer exp(S, TopAbs_WIRE);
+  for (; exp.More(); exp.Next()) {
     if (exp.Current().IsSame(myShape)) {
       break;
     }
   }
   if (!exp.More()) {
-    BRepCheck::Add(lst,BRepCheck_SubshapeNotInShape);
+    BRepCheck::Add(lst, BRepCheck_SubshapeNotInShape);
     return;
   }
 
   BRepCheck_Status st = BRepCheck_NoError;
   TopAbs_ShapeEnum styp = S.ShapeType();
-  switch (styp) {
-
-  case TopAbs_FACE:
+  switch (styp)
+  {
+    case TopAbs_FACE:
     {
-      TopoDS_Edge ed1,ed2; 
-      if (myGctrl) 
-        st = SelfIntersect(TopoDS::Face(S),ed1,ed2,Standard_True);
-      if (st != BRepCheck_NoError) break;
+      TopoDS_Edge ed1, ed2;
+      if (myGctrl)
+      {
+        st = SelfIntersect(TopoDS::Face(S), ed1, ed2, Standard_True);
+      }
+      if (st != BRepCheck_NoError) { break; }
       st = Closed();
-      if (st != BRepCheck_NoError) break;
+      if (st != BRepCheck_NoError) { break; }
       st = Orientation(TopoDS::Face(S));
-      if (st != BRepCheck_NoError) break;
+      if (st != BRepCheck_NoError) { break; }
       st = Closed2d(TopoDS::Face(S));
+      break;
+    }
+    default:
+    {
+      break;
     }
-    break;
-  default:
-    break;
   }
-  
-  if (st != BRepCheck_NoError) 
-    BRepCheck::Add(lst,st);
-      
-  if (lst.IsEmpty()) 
-    lst.Append(BRepCheck_NoError);
+
+  if (st != BRepCheck_NoError)
+  {
+    BRepCheck::Add (lst, st);
+  }
+
+  if (lst.IsEmpty())
+  {
+    lst.Append (BRepCheck_NoError);
+  }
 }
 //=======================================================================
 //function : Blind
@@ -260,17 +272,25 @@ void BRepCheck_Wire::Blind()
 //=======================================================================
 BRepCheck_Status BRepCheck_Wire::Closed(const Standard_Boolean Update)
 {
+  Handle(BRepCheck_HListOfStatus) aHList;
+  {
+    Standard_Mutex::Sentry aLock(myMutex.get());
+    aHList = myMap (myShape);
+  }
 
-  if (myCdone) {
-    if (Update) {
-      BRepCheck::Add(myMap(myShape),myCstat);
+  BRepCheck_ListOfStatus& aStatusList = *aHList;
+  if (myCdone)
+  {
+    if (Update)
+    {
+      BRepCheck::Add (aStatusList, myCstat);
     }
     return myCstat;
   }
 
   myCdone = Standard_True;
 
-  BRepCheck_ListIteratorOfListOfStatus itl(myMap(myShape));
+  BRepCheck_ListIteratorOfListOfStatus itl (aStatusList);
   if (itl.Value() != BRepCheck_NoError) {
     myCstat = itl.Value();
     return myCstat; // already saved 
@@ -320,8 +340,9 @@ BRepCheck_Status BRepCheck_Wire::Closed(const Standard_Boolean Update)
   }
   if (theNbori != mapS.Extent()) {
     myCstat = BRepCheck_NotConnected;
-    if (Update) {
-      BRepCheck::Add(myMap(myShape),myCstat);
+    if (Update)
+    {
+      BRepCheck::Add (aStatusList, myCstat);
     }
     return myCstat;
   }
@@ -343,8 +364,9 @@ BRepCheck_Status BRepCheck_Wire::Closed(const Standard_Boolean Update)
     }
     if (yabug) {
       myCstat = BRepCheck_RedundantEdge;
-      if (Update) {
-        BRepCheck::Add(myMap(myShape),myCstat);
+      if (Update)
+      {
+        BRepCheck::Add (aStatusList, myCstat);
       }
       return myCstat;
     }
@@ -353,15 +375,17 @@ BRepCheck_Status BRepCheck_Wire::Closed(const Standard_Boolean Update)
   for (Standard_Integer i = 1; i<= myMapVE.Extent(); i++) {
     if (myMapVE(i).Extent()%2 != 0) {
       myCstat=BRepCheck_NotClosed;
-      if (Update) {
-        BRepCheck::Add(myMap(myShape),myCstat);
+      if (Update)
+      {
+        BRepCheck::Add (aStatusList, myCstat);
       }
       return myCstat;
     }
   }
 
-  if (Update) {
-    BRepCheck::Add(myMap(myShape),myCstat);
+  if (Update)
+  {
+    BRepCheck::Add (aStatusList, myCstat);
   }
   return myCstat;
 }
@@ -500,14 +524,22 @@ Standard_Boolean IsDistanceIn2DTolerance (const BRepAdaptor_Surface& aFaceSurfac
 //=======================================================================
 BRepCheck_Status BRepCheck_Wire::Closed2d(const TopoDS_Face& theFace,
                                           const Standard_Boolean Update)
+{
+  Handle(BRepCheck_HListOfStatus) aHList;
   {
+    Standard_Mutex::Sentry aLock(myMutex.get());
+    aHList = myMap (myShape);
+  }
+  BRepCheck_ListOfStatus& aStatusList = *aHList;
+
   // 3d closure checked too
   BRepCheck_Status aClosedStat = Closed();
   if (aClosedStat != BRepCheck_NoError)
     {
     if (Update)
-      BRepCheck::Add(myMap(myShape),aClosedStat);
-
+    {
+      BRepCheck::Add (aStatusList, aClosedStat);
+    }
     return aClosedStat;
     }
 
@@ -535,8 +567,9 @@ BRepCheck_Status BRepCheck_Wire::Closed2d(const TopoDS_Face& theFace,
   if (aNbOrirntedEdges==0)
     {
     if (Update)
-      BRepCheck::Add(myMap(myShape),aClosedStat);
-
+    {
+      BRepCheck::Add (aStatusList, aClosedStat);
+    }
     return aClosedStat;
     }
 
@@ -557,9 +590,10 @@ BRepCheck_Status BRepCheck_Wire::Closed2d(const TopoDS_Face& theFace,
   if (aNbFoundEdges != aNbOrirntedEdges)
     {
     aClosedStat = BRepCheck_NotClosed;
-    if (Update) 
-      BRepCheck::Add(myMap(myShape),aClosedStat);
-    
+    if (Update)
+    {
+      BRepCheck::Add (aStatusList, aClosedStat);
+    }
     return aClosedStat;
     }
 
@@ -588,17 +622,19 @@ BRepCheck_Status BRepCheck_Wire::Closed2d(const TopoDS_Face& theFace,
   if (isFirstInfinite && isLastInfinite)
     {
     if (Update)
-      BRepCheck::Add(myMap(myShape),aClosedStat);
-
+    {
+      BRepCheck::Add (aStatusList, aClosedStat);
+    }
     return aClosedStat;
     }
   else if (aFirstVertex.IsNull())
     {
     aClosedStat = BRepCheck_NotClosed;
     
-    if (Update) 
-      BRepCheck::Add(myMap(myShape),aClosedStat);
-    
+    if (Update)
+    {
+      BRepCheck::Add (aStatusList, aClosedStat);
+    }
     return aClosedStat;
     }
 //  Modified by Sergey KHROMOV - Mon May 13 12:42:10 2002 End
@@ -629,8 +665,9 @@ BRepCheck_Status BRepCheck_Wire::Closed2d(const TopoDS_Face& theFace,
     {
     aClosedStat = BRepCheck_NotClosed;
     if (Update)
-      BRepCheck::Add(myMap(myShape),aClosedStat);
-    
+    {
+      BRepCheck::Add (aStatusList, aClosedStat);
+    }
     return aClosedStat;
     }
 //  Modified by Sergey KHROMOV - Thu Jun 20 10:58:05 2002 End
@@ -652,9 +689,10 @@ BRepCheck_Status BRepCheck_Wire::Closed2d(const TopoDS_Face& theFace,
   if(!IsDistanceIn3DTolerance(aPntRef, aPnt, aTol3d))
     aClosedStat = BRepCheck_NotClosed;
 
-  if (Update) 
-    BRepCheck::Add(myMap(myShape),aClosedStat);
-
+  if (Update)
+  {
+    BRepCheck::Add (aStatusList, aClosedStat);
+  }
   return aClosedStat;
   }
 //=======================================================================
@@ -665,9 +703,18 @@ BRepCheck_Status BRepCheck_Wire::Orientation(const TopoDS_Face& F,
                                              const Standard_Boolean Update)
 {
   BRepCheck_Status theOstat = Closed();
-  if (theOstat != BRepCheck_NotClosed && theOstat != BRepCheck_NoError) {
-    if (Update) {
-      BRepCheck::Add(myMap(myShape),theOstat);
+  Handle(BRepCheck_HListOfStatus) aHList;
+  {
+    Standard_Mutex::Sentry aLock(myMutex.get());
+    aHList = myMap (myShape);
+  }
+  BRepCheck_ListOfStatus& aStatusList = *aHList;
+
+  if (theOstat != BRepCheck_NotClosed && theOstat != BRepCheck_NoError)
+  {
+    if (Update)
+    {
+      BRepCheck::Add (aStatusList, theOstat);
     }
     return theOstat;
   }
@@ -794,8 +841,9 @@ BRepCheck_Status BRepCheck_Wire::Orientation(const TopoDS_Face& F,
       if (nbconnex == 0) {
         if (myCstat == BRepCheck_NotClosed) {
           if (VL.IsNull()) {
-            if (Update) {
-              BRepCheck::Add(myMap(myShape),theOstat);
+            if (Update)
+            {
+              BRepCheck::Add (aStatusList, theOstat);
             }
             return theOstat; // leave
           }
@@ -808,9 +856,10 @@ BRepCheck_Status BRepCheck_Wire::Orientation(const TopoDS_Face& F,
         }
         else {
           theOstat = BRepCheck_BadOrientationOfSubshape;
-          if (Update) {
-            BRepCheck::Add(myMap(myShape),theOstat);
-           }
+          if (Update)
+          {
+            BRepCheck::Add (aStatusList, theOstat);
+          }
           return theOstat;
         }
       }
@@ -841,9 +890,10 @@ BRepCheck_Status BRepCheck_Wire::Orientation(const TopoDS_Face& F,
 
       if (nbconnex >= 2) {
         theOstat = BRepCheck_BadOrientationOfSubshape;
-        if (Update) {
-          BRepCheck::Add(myMap(myShape),theOstat);
-          }
+        if (Update)
+        {
+          BRepCheck::Add (aStatusList, theOstat);
+        }
         return theOstat;
       }
       else if (nbconnex == 1) {
@@ -876,10 +926,11 @@ BRepCheck_Status BRepCheck_Wire::Orientation(const TopoDS_Face& F,
       }
       else if (!Changedesens) { //nbconnex == 0
         theOstat = BRepCheck_NotClosed;
-        if (Update) {
-          BRepCheck::Add(myMap(myShape),theOstat);
-         }
-       return theOstat;
+        if (Update)
+        {
+          BRepCheck::Add (aStatusList, theOstat);
+        }
+        return theOstat;
       }
 
       // Check the closure of the wire in 2d (not done in Closed())
@@ -888,52 +939,54 @@ BRepCheck_Status BRepCheck_Wire::Orientation(const TopoDS_Face& F,
       Standard_Boolean isCheckClose = Standard_False;
 
       if (isGoFwd && !VF.IsNull()) {
-       aVRef        = VF;
-       isCheckClose = Standard_True;
+        aVRef        = VF;
+        isCheckClose = Standard_True;
       } else if (!isGoFwd && !VL.IsNull()) {
-       aVRef        = VL;
-       isCheckClose = Standard_True;
+        aVRef        = VL;
+        isCheckClose = Standard_True;
       }
 
 //       if (Index==1 && myCstat!=BRepCheck_NotClosed && 
-//       !VF.IsNull() && !F.IsNull()) {
+//       !VF.IsNull() && !F.IsNull()) {
       if (Index==1 && myCstat!=BRepCheck_NotClosed && 
-         isCheckClose && !F.IsNull()) {
-       ledge.Clear();
-//     ind = myMapVE.FindIndex(VF);
-       ind = myMapVE.FindIndex(aVRef);
-       for (TopTools_ListIteratorOfListOfShape itlsh(myMapVE(ind));
-            itlsh.More(); itlsh.Next()) {
-         const TopoDS_Edge & edg = TopoDS::Edge(itlsh.Value());
-         orient = edg.Orientation();
-         if (!theRef.IsSame(edg)) {
-           for (vte.Init(edg,TopAbs_VERTEX);vte.More(); vte.Next()) {
-             TopAbs_Orientation vto = vte.Current().Orientation();
-//           if (vto == TopAbs_REVERSED && VF.IsSame(vte.Current())) {
-             if (vto == TopAbs_REVERSED && aVRef.IsSame(vte.Current())) {
-               ledge.Append(edg);
-               break;
-             }
-           }
-         }
-       }
-//     ChoixUV(VF, theRef, F, ledge);
-       ChoixUV(aVRef, theRef, F, ledge);
-       if (ledge.Extent()==0) {
-         theOstat = BRepCheck_NotClosed;
-         if (Update) {
-           BRepCheck::Add(myMap(myShape),theOstat);
-         }
-         return theOstat;
-       }
+        isCheckClose && !F.IsNull()) {
+      ledge.Clear();
+//    ind = myMapVE.FindIndex(VF);
+      ind = myMapVE.FindIndex(aVRef);
+      for (TopTools_ListIteratorOfListOfShape itlsh(myMapVE(ind));
+           itlsh.More(); itlsh.Next()) {
+        const TopoDS_Edge & edg = TopoDS::Edge(itlsh.Value());
+        orient = edg.Orientation();
+        if (!theRef.IsSame(edg)) {
+          for (vte.Init(edg,TopAbs_VERTEX);vte.More(); vte.Next()) {
+            TopAbs_Orientation vto = vte.Current().Orientation();
+//          if (vto == TopAbs_REVERSED && VF.IsSame(vte.Current())) {
+            if (vto == TopAbs_REVERSED && aVRef.IsSame(vte.Current())) {
+              ledge.Append(edg);
+              break;
+            }
+          }
+        }
       }
+//    ChoixUV(VF, theRef, F, ledge);
+      ChoixUV(aVRef, theRef, F, ledge);
+      if (ledge.Extent()==0) {
+        theOstat = BRepCheck_NotClosed;
+        if (Update)
+        {
+          BRepCheck::Add (aStatusList, theOstat);
+        }
+        return theOstat;
+      }
+    }
       // End control closure 2d
 
       Index ++;
     }
   }
-  if (Update) {
-    BRepCheck::Add(myMap(myShape),theOstat);
+  if (Update)
+  {
+    BRepCheck::Add(aStatusList, theOstat);
   }
   return theOstat;
 }
@@ -946,7 +999,12 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
                                               TopoDS_Edge& retE2,
                                               const Standard_Boolean Update)
 {
-
+  Handle(BRepCheck_HListOfStatus) aHList;
+  {
+    Standard_Mutex::Sentry aLock(myMutex.get());
+    aHList = myMap (myShape);
+  }
+  BRepCheck_ListOfStatus& aStatusList = *aHList;
 
   Standard_Integer i,j,Nbedges;
   Standard_Real first1,last1,first2,last2, tolint;
@@ -972,9 +1030,11 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
   }
   //
   Nbedges=EMap.Extent();
-  if (!Nbedges) {
-    if (Update) {
-      BRepCheck::Add(myMap(myShape),BRepCheck_EmptyWire);
+  if (!Nbedges)
+  {
+    if (Update)
+    {
+      BRepCheck::Add (aStatusList, BRepCheck_EmptyWire);
     }
     return(BRepCheck_EmptyWire);
   }
@@ -987,13 +1047,15 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
     const TopoDS_Edge& E1 = TopoDS::Edge(EMap.FindKey(i));
     if (i == 1) {
       Handle(Geom2d_Curve) pcu = BRep_Tool::CurveOnSurface(E1, F, first1, last1);
-      if (pcu.IsNull()) {
-       retE1=E1;
-       if (Update) {
-         BRepCheck::Add(myMap(myShape),BRepCheck_SelfIntersectingWire);
-       }
-       delete [] tabDom;
-       return(BRepCheck_SelfIntersectingWire);
+      if (pcu.IsNull())
+      {
+        retE1=E1;
+        if (Update)
+        {
+          BRepCheck::Add (aStatusList, BRepCheck_SelfIntersectingWire);
+        }
+        delete [] tabDom;
+        return(BRepCheck_SelfIntersectingWire);
       }
       //
       C1.Load(pcu);
@@ -1025,51 +1087,52 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
       //Standard_Integer nbs = Inter.NbSegments();
       //
       for(Standard_Integer p=1;p<=nbp;p++) {
-       const IntRes2d_IntersectionPoint& IP=Inter.Point(p);
-       const IntRes2d_Transition& Tr1 = IP.TransitionOfFirst();
-       const IntRes2d_Transition& Tr2 = IP.TransitionOfSecond();
-       if(   Tr1.PositionOnCurve() == IntRes2d_Middle
-          || Tr2.PositionOnCurve() == IntRes2d_Middle) { 
-         //-- Checking of points with true tolerances (ie Tol in 3d)
-         //-- If the point of intersection is within the tolearnce of a vertex
-         //-- this intersection is considered correct (no error)
-         Standard_Boolean localok = Standard_False;
-         Standard_Real f,l;
-         TopLoc_Location L;
-         const Handle(Geom_Curve) ConS = BRep_Tool::Curve(E1,L,f,l);
-         if(!ConS.IsNull()) { 
-           //-- try to test in 3d. (ParamOnSecond gives the same result)
-           P3d = ConS->Value(IP.ParamOnFirst()); 
-           P3d.Transform(L.Transformation());
-           //  Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
-         } 
-         else {
-           gp_Pnt2d aP2d  = C1.Value(IP.ParamOnFirst());
-           P3d = HS->Value(aP2d.X(), aP2d.Y());
-         }
-         //  Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 End
-         TopExp_Explorer ExplVtx;
-         for(ExplVtx.Init(E1,TopAbs_VERTEX); 
-             localok==Standard_False && ExplVtx.More();
-             ExplVtx.Next()) { 
-           gp_Pnt p3dvtt;
-           Standard_Real tolvtt, p3dvttDistanceP3d;
-           //
-           const TopoDS_Vertex& vtt = TopoDS::Vertex(ExplVtx.Current());
-           p3dvtt = BRep_Tool::Pnt(vtt);
-           tolvtt =  BRep_Tool::Tolerance(vtt);
-           tolvtt=tolvtt*tolvtt;
-           p3dvttDistanceP3d=p3dvtt.SquareDistance(P3d);
-           if(p3dvttDistanceP3d <=  tolvtt) { 
-             localok=Standard_True;
-           }
-         }
-         if(localok==Standard_False) { 
-           retE1=E1;
-           if (Update) {
-             BRepCheck::Add(myMap(myShape),BRepCheck_SelfIntersectingWire);
-             }
-           delete [] tabDom;
+        const IntRes2d_IntersectionPoint& IP=Inter.Point(p);
+        const IntRes2d_Transition& Tr1 = IP.TransitionOfFirst();
+        const IntRes2d_Transition& Tr2 = IP.TransitionOfSecond();
+        if(   Tr1.PositionOnCurve() == IntRes2d_Middle
+           || Tr2.PositionOnCurve() == IntRes2d_Middle) {
+          //-- Checking of points with true tolerances (ie Tol in 3d)
+          //-- If the point of intersection is within the tolearnce of a vertex
+          //-- this intersection is considered correct (no error)
+          Standard_Boolean localok = Standard_False;
+          Standard_Real f,l;
+          TopLoc_Location L;
+          const Handle(Geom_Curve) ConS = BRep_Tool::Curve(E1,L,f,l);
+          if(!ConS.IsNull()) {
+            //-- try to test in 3d. (ParamOnSecond gives the same result)
+            P3d = ConS->Value(IP.ParamOnFirst());
+            P3d.Transform(L.Transformation());
+            //  Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
+          }
+          else {
+            gp_Pnt2d aP2d  = C1.Value(IP.ParamOnFirst());
+            P3d = HS->Value(aP2d.X(), aP2d.Y());
+          }
+          //  Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 End
+          TopExp_Explorer ExplVtx;
+          for(ExplVtx.Init(E1,TopAbs_VERTEX);
+              localok==Standard_False && ExplVtx.More();
+              ExplVtx.Next()) {
+            gp_Pnt p3dvtt;
+            Standard_Real tolvtt, p3dvttDistanceP3d;
+            //
+            const TopoDS_Vertex& vtt = TopoDS::Vertex(ExplVtx.Current());
+            p3dvtt = BRep_Tool::Pnt(vtt);
+            tolvtt =  BRep_Tool::Tolerance(vtt);
+            tolvtt=tolvtt*tolvtt;
+            p3dvttDistanceP3d=p3dvtt.SquareDistance(P3d);
+            if(p3dvttDistanceP3d <=  tolvtt) {
+              localok=Standard_True;
+            }
+          }
+          if(localok==Standard_False) {
+            retE1=E1;
+            if (Update)
+            {
+              BRepCheck::Add(aStatusList, BRepCheck_SelfIntersectingWire);
+            }
+            delete [] tabDom;
 #ifdef OCCT_DEBUG
            static Standard_Integer numpoint=0;
            std::cout<<"point p"<<++numpoint<<" "<<P3d.X()<<" "<<P3d.Y()<<" "<<P3d.Z()<<std::endl;std::cout.flush();
@@ -1352,9 +1415,10 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
            if(localok==Standard_False)   { 
              retE1=E1;
              retE2=E2;
-             if (Update) {
-               BRepCheck::Add(myMap(myShape),BRepCheck_SelfIntersectingWire);
-               }
+             if (Update)
+             {
+               BRepCheck::Add (aStatusList, BRepCheck_SelfIntersectingWire);
+             }
 #ifdef OCCT_DEBUG
              static Standard_Integer numpoint1=0;
              std::cout<<"point p"<<++numpoint1<<" "<<P3d.X()<<" "<<P3d.Y()<<" "<<P3d.Z()<<std::endl;
@@ -1482,8 +1546,9 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
            if(localok==Standard_False)   { 
              retE1=E1;
              retE2=E2;
-             if (Update) {
-               BRepCheck::Add(myMap(myShape),BRepCheck_SelfIntersectingWire);
+             if (Update)
+             {
+               BRepCheck::Add (aStatusList, BRepCheck_SelfIntersectingWire);
              }
 #ifdef OCCT_DEBUG
              static Standard_Integer numpoint1=0;
@@ -1500,8 +1565,9 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
   } //end of for(i = 1; i <= Nbedges; i++)
   //
   delete [] tabDom;
-  if (Update) {
-    BRepCheck::Add(myMap(myShape),BRepCheck_NoError);
+  if (Update)
+  {
+    BRepCheck::Add(aStatusList, BRepCheck_NoError);
   }
   //
   return (BRepCheck_NoError);
@@ -1514,7 +1580,7 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
 
 void BRepCheck_Wire::SetStatus(const BRepCheck_Status theStatus)
 {
-    BRepCheck::Add(myMap(myShape),theStatus);
+    BRepCheck::Add(*myMap(myShape),theStatus);
 }
 
 //=======================================================================
index 27ff341..134942d 100644 (file)
@@ -2,20 +2,16 @@ BRepCheck.cxx
 BRepCheck.hxx
 BRepCheck_Analyzer.cxx
 BRepCheck_Analyzer.hxx
-BRepCheck_Analyzer.lxx
-BRepCheck_DataMapIteratorOfDataMapOfShapeListOfStatus.hxx
-BRepCheck_DataMapIteratorOfDataMapOfShapeResult.hxx
 BRepCheck_DataMapOfShapeListOfStatus.hxx
-BRepCheck_DataMapOfShapeResult.hxx
 BRepCheck_Edge.cxx
 BRepCheck_Edge.hxx
 BRepCheck_Face.cxx
 BRepCheck_Face.hxx
+BRepCheck_IndexedDataMapOfShapeResult.hxx
 BRepCheck_ListIteratorOfListOfStatus.hxx
 BRepCheck_ListOfStatus.hxx
 BRepCheck_Result.cxx
 BRepCheck_Result.hxx
-BRepCheck_Result.lxx
 BRepCheck_Shell.cxx
 BRepCheck_Shell.hxx
 BRepCheck_Solid.cxx
index deb8809..5f52c7a 100644 (file)
@@ -424,66 +424,11 @@ static Standard_Integer checkdiff(Draw_Interpretor& di,
 
   return 0;
 }
-//=======================================================================
-
-//  Modified by skv - Tue Apr 27 13:38:44 2004 Begin
-//=======================================================================
-//function : CHK
-//purpose  : Checks a shape
-//=======================================================================
-
-// static Standard_Integer CHK(Draw_Interpretor& theCommands,
-//                         Standard_Integer narg, const char** a)
-// {
-//   if (narg < 2) {
-//     return 1;
-//   }
-
-//   Standard_Boolean doprint = Standard_True;
-//   if (narg == 3) { if (!strcmp(a[2],"-short")) doprint = Standard_False; }
-
-//   TopoDS_Shape S = DBRep::Get(a[1]);
-//   if (S.IsNull()) {
-//     std::cout<<"not a topological shape"<<std::endl;
-//     return 1;
-//   }
-
-//   Standard_Boolean GeomCtrl = Standard_True;
-//   if (!strcasecmp(a[0],"CHECKTOPSHAPE")) {
-//     GeomCtrl = Standard_False;
-//   }
-
-//   BRepCheck_Analyzer ana(S,GeomCtrl);
-//   if (ana.IsValid()) {
-//     theCommands<<"This shape seems to be valid";
-//   }
-//   else {
-//     theMap.Clear();
-//     nbfaulty = 0;
-//     lfaulty.Clear();
-//     theMap.Clear();
-//     if (doprint) {
-//       Print(cout,ana,S);
-//       std::cout<<"\n";
-//       theMap.Clear();
-//       if (nbfaulty !=0)
-//     std::cout<<"Faulty shapes in variables "<<checkfaultyname<<"1 to "<<checkfaultyname<<nbfaulty<<" \n";
-//       std::cout<<std::endl;
-//     }
-//     else {
-//       theCommands<<"This shape has faulty shapes";
-//     }
-//   }
-//   return 0;
-// }
 
 //=======================================================================
 //function : ContextualDump
 //purpose  : Contextual (modeling) style of output.
 //=======================================================================
-
-//void ContextualDump(const BRepCheck_Analyzer &theAna,
-//                 const TopoDS_Shape       &theShape)
 void ContextualDump(Draw_Interpretor& theCommands,
                    const BRepCheck_Analyzer &theAna,
                    const TopoDS_Shape       &theShape)
@@ -492,19 +437,16 @@ void ContextualDump(Draw_Interpretor& theCommands,
   nbfaulty = 0;
   lfaulty.Clear();
 
-  //Print(cout, theAna, theShape);
   Standard_SStream aSStream;
   Print(aSStream, theAna, theShape);
   theCommands << aSStream;
-  //std::cout<<"\n";
+
   theCommands<<"\n";
   theMap.Clear();
 
   if (nbfaulty !=0)
     theCommands<<"Faulty shapes in variables "<<checkfaultyname<<"1 to "<<checkfaultyname<<nbfaulty<<" \n";
-    //std::cout<<"Faulty shapes in variables "<<checkfaultyname<<"1 to "<<checkfaultyname<<nbfaulty<<" \n";
 
-  //std::cout<<std::endl;
   theCommands<<"\n";
 }
 
@@ -626,11 +568,6 @@ static void GetProblemShapes(const BRepCheck_Analyzer& Ana,
 //function : StructuralDump
 //purpose  : Structural (data exchange) style of output.
 //=======================================================================
-
-//void StructuralDump(const BRepCheck_Analyzer &theAna,
-//                    const Standard_CString   ShName,
-//                    const Standard_CString   Pref,
-//                 const TopoDS_Shape       &theShape)
 void StructuralDump(Draw_Interpretor& theCommands,
                    const BRepCheck_Analyzer &theAna,
                     const Standard_CString   ShName,
@@ -638,10 +575,6 @@ void StructuralDump(Draw_Interpretor& theCommands,
                    const TopoDS_Shape       &theShape)
 {
   Standard_Integer i;
-  //std::cout << "StructuralDump" << std::endl;
-  //std::cout << " -- The Shape " << ShName << " has problems :"<<std::endl;
-  //std::cout<<"  Check                                    Count"<<std::endl;
-  //std::cout<<" ------------------------------------------------"<<std::endl;
   theCommands << " -- The Shape " << ShName << " has problems :\n";
   theCommands<<"  Check                                    Count\n";
   theCommands<<" ------------------------------------------------\n";
@@ -835,7 +768,6 @@ void StructuralDump(Draw_Interpretor& theCommands,
     char aName[20];
     Sprintf(aName,"%s_v",Pref);
     DBRep::Set(aName,comp);
-    //std::cout<<"VERTEX       : "<<(nb > 9 ? "" : " ")<<nb<<" Items -> compound named "<<aName<<std::endl;
     if (nb > 9)
       theCommands<<"VERTEX     : "<<nb<<" Items -> compound named "<<aName<<"\n";
     else
@@ -850,7 +782,6 @@ void StructuralDump(Draw_Interpretor& theCommands,
     char aName[20];
     Sprintf(aName,"%s_e",Pref);
     DBRep::Set(aName,comp);
-    //std::cout<<"EDGE : "<<(nb > 9 ? "" : " ")<<nb<<" Items -> compound named "<<aName<<std::endl;
     if (nb > 9)
       theCommands<<"EDGE       : "<<nb<<" Items -> compound named "<<aName<<"\n";
     else
@@ -865,7 +796,6 @@ void StructuralDump(Draw_Interpretor& theCommands,
     char aName[20];
     Sprintf(aName,"%s_w",Pref);
     DBRep::Set(aName,comp);
-    //std::cout<<"WIRE : "<<(nb > 9 ? "" : " ")<<nb<<" Items -> compound named "<<aName<<std::endl;
     if (nb > 9)
       theCommands<<"WIRE       : "<<nb<<" Items -> compound named "<<aName<<"\n";
     else
@@ -880,7 +810,6 @@ void StructuralDump(Draw_Interpretor& theCommands,
     char aName[20];
     Sprintf(aName,"%s_f",Pref);
     DBRep::Set(aName,comp);
-    //std::cout<<"FACE : "<<(nb > 9 ? "" : " ")<<nb<<" Items -> compound named "<<aName<<std::endl;
     if (nb > 9)
       theCommands<<"FACE       : "<<nb<<" Items -> compound named "<<aName<<"\n";
     else
@@ -895,7 +824,6 @@ void StructuralDump(Draw_Interpretor& theCommands,
     char aName[20];
     Sprintf(aName,"%s_s",Pref);
     DBRep::Set(aName,comp);
-    //std::cout<<"SHELL        : "<<(nb > 9 ? "" : " ")<<nb<<" Items -> compound named "<<aName<<std::endl;
     if (nb > 9)
       theCommands<<"SHELL      : "<<nb<<" Items -> compound named "<<aName<<"\n";
     else
@@ -910,7 +838,6 @@ void StructuralDump(Draw_Interpretor& theCommands,
     char aName[20];
     Sprintf(aName,"%s_o",Pref);
     DBRep::Set(aName,comp);
-    //std::cout<<"SOLID        : "<<(nb > 9 ? "" : " ")<<nb<<" Items -> compound named "<<aName<<std::endl;
     if (nb > 9)
       theCommands<<"SOLID      : "<<nb<<" Items -> compound named "<<aName<<"\n";
     else
@@ -922,22 +849,13 @@ void StructuralDump(Draw_Interpretor& theCommands,
 //function : checkshape
 //purpose  : Checks a shape
 //=======================================================================
-
-static Standard_Integer checkshape(Draw_Interpretor& theCommands,
-                                  Standard_Integer narg, const char** a)
+static Standard_Integer checkshape (Draw_Interpretor& theCommands,
+                                    Standard_Integer narg, const char** a)
 {
-  if (narg == 1) {
-    //std::cout << std::endl;
-    //std::cout << "Usage : checkshape [-top] shape [result] [-short]" << std::endl;
-    //std::cout << std::endl;
-    //std::cout << "Where :" << std::endl;
-    //std::cout << "   -top   - check topology only." << std::endl;
-    //std::cout << "   shape  - the name of the shape to test." << std::endl;
-    //std::cout << "   result - the prefix of the output shape names. If it is used, structural" << std::endl;
-    //std::cout << "            output style will be used. Otherwise - contextual one." << std::endl;
-    //std::cout << "   -short - short description of check." << std::endl;
+  if (narg == 1)
+  {
     theCommands << "\n";
-    theCommands << "Usage : checkshape [-top] shape [result] [-short]\n";
+    theCommands << "Usage : checkshape [-top] shape [result] [-short] [-parallel]\n";
     theCommands << "\n";
     theCommands << "Where :\n";
     theCommands << "   -top   - check topology only.\n";
@@ -945,104 +863,118 @@ static Standard_Integer checkshape(Draw_Interpretor& theCommands,
     theCommands << "   result - the prefix of the output shape names. If it is used, structural\n";
     theCommands << "            output style will be used. Otherwise - contextual one.\n";
     theCommands << "   -short - short description of check.\n";
-
+    theCommands << "   -parallel - run check in parallel.\n";
     return 0;
   }
 
-  if (narg > 5) {
-    //std::cout << "Invalid number of args!!!" << std::endl;
-    //std::cout << "No args to have help." << std::endl;
+  if (narg > 6)
+  {
     theCommands << "Invalid number of args!!!\n";
     theCommands << "No args to have help.\n";
-
     return 1;
   }
 
   Standard_Boolean aGeomCtrl = Standard_True;
-  Standard_Integer aCurInd  = 1;
-
-  if (!strcmp(a[1],"-top")) {
+  Standard_Integer aCurInd = 1;
+  if (!strcmp (a[1], "-top"))
+  {
     aGeomCtrl = Standard_False;
     aCurInd++;
   }
 
-  if (aCurInd > narg - 1) {
-    //std::cout << "Invalid number of args!!!" << std::endl;
-    //std::cout << "No args to have help." << std::endl;
+  if (aCurInd > narg - 1)
+  {
     theCommands << "Invalid number of args!!!\n";
     theCommands << "No args to have help.\n";
-
     return 1;
   }
 
   Standard_CString aShapeName = a[aCurInd];
-  TopoDS_Shape     aShape     = DBRep::Get(aShapeName);
-
-  if (aShape.IsNull()) {
-    //std::cout << a[aCurInd] << " is not a topological shape!!!" << std::endl;
+  TopoDS_Shape     aShape = DBRep::Get(aShapeName);
+  if (aShape.IsNull()) 
+  {
     theCommands << a[aCurInd] << " is not a topological shape!!!\n";
-
     return 1;
   }
+  aCurInd++;
 
-  Standard_Boolean IsShortDump   = Standard_False;
+  Standard_Boolean IsShortDump = Standard_False;
   Standard_Boolean IsContextDump = Standard_True;
-  Standard_Integer aBackInd      = narg - 1;
+  Standard_Boolean IsParallel = Standard_False;
+  Standard_CString aPref(NULL);
+  if (aCurInd < narg && strncmp(a[aCurInd], "-", 1))
+  {
+    IsContextDump = Standard_False;
+    aPref = a[aCurInd];
+    aCurInd++;
+  }
 
-  if (aCurInd < aBackInd) {
-    if (!strcmp(a[aBackInd],"-short")) {
+  for (Standard_Integer anAI = aCurInd; anAI < narg; anAI++)
+  {
+    TCollection_AsciiString anArg(a[anAI]);
+    anArg.LowerCase();
+    if (anArg == "-short")
+    {
       IsShortDump = Standard_True;
-      aBackInd--;
+    }
+    else if (anArg == "-parallel")
+    {
+      IsParallel = Standard_True;
+    }
+    else
+    {
+      theCommands << "Syntax error at '" << anArg << "'";
+      return 1;
     }
   }
 
-  if (aCurInd < aBackInd - 1) {
-    //std::cout << "Invalid number of args!!!" << std::endl;
-    //std::cout << "No args to have help." << std::endl;
-    theCommands << "Invalid number of args!!!\n";
-    theCommands << "No args to have help.\n";
-
-    return 1;
-  } else if (aCurInd < aBackInd) {
-    IsContextDump = Standard_False;
-  }
-
-  try {
+  try 
+  {
     OCC_CATCH_SIGNALS
-    BRepCheck_Analyzer anAna(aShape,aGeomCtrl);
+    BRepCheck_Analyzer anAna (aShape, aGeomCtrl, IsParallel);
     Standard_Boolean   isValid = anAna.IsValid();
 
-    if (isValid) {
-      if (IsContextDump) {
-       theCommands << "This shape seems to be valid";
-      } else {
-       theCommands << " -- The Shape " << aShapeName << " looks OK";
+    if (isValid)
+    {
+      if (IsContextDump)
+      {
+        theCommands << "This shape seems to be valid";
       }
-    } else {
-      if (IsShortDump) {
-       theCommands<<"This shape has faulty shapes";
-      } else {
-       if (IsContextDump) {
-         //ContextualDump(anAna, aShape);
-         ContextualDump(theCommands, anAna, aShape);
-       } else {
-         Standard_CString aPref = a[aCurInd+1];
-         //StructuralDump(anAna, aShapeName, aPref, aShape);
-         StructuralDump(theCommands, anAna, aShapeName, aPref, aShape);
-       }
+      else
+      {
+        theCommands << " -- The Shape " << aShapeName << " looks OK";
+      }
+    }
+    else
+    {
+      if (IsShortDump)
+      {
+        theCommands << "This shape has faulty shapes";
+      }
+      else
+      {
+        if (IsContextDump)
+        {
+          ContextualDump(theCommands, anAna, aShape);
+        }
+        else
+        {
+          StructuralDump(theCommands, anAna, aShapeName, aPref, aShape);
+        }
       }
     }
   }
-  catch(Standard_Failure const& anException) {
-    theCommands<<"checkshape exception : ";
+  catch (Standard_Failure const& anException)
+  {
+    theCommands << "checkshape exception : ";
     theCommands << anException.GetMessageString();
-    theCommands<<"\n";
+    theCommands << "\n";
     return 1;
   }
 
   return 0;
 }
-//  Modified by skv - Tue Apr 27 13:38:24 2004 End
+
 /***************************************************************/
 static void InitEpsSurf(Standard_Real& epsnl,Standard_Real& epsdis, Standard_Real& epsangk1, 
                        Standard_Real& epsangk2, Standard_Real& epsangn1, 
@@ -1725,23 +1657,11 @@ void BRepTest::CheckCommands(Draw_Interpretor& theCommands)
 
   const char* g = "TOPOLOGY Check commands";
 
-//  Modified by skv - Tue Apr 27 13:35:35 2004 Begin
   theCommands.Add("checkshape", 
                  "checkshape : no args to have help",
                  __FILE__,
                  checkshape,
                  g);
-//   theCommands.Add("checkshape", 
-//               "checks the validity of a shape : checkshape name,\n                      short description of check : checkshape name -short",
-//               __FILE__,
-//               CHK,
-//               g);
-//   theCommands.Add("checktopshape", 
-//               "checks the topological validity of a shape : checktopshape name",
-//               __FILE__,
-//               CHK,
-//               g);
-//  Modified by skv - Tue Apr 27 13:35:39 2004 End
 
   theCommands.Add("checksection", 
                  "checks the closure of a section : checksection name [-r <RefVal>]\n"
index 46a987c..15dde8e 100644 (file)
@@ -40,7 +40,7 @@ IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_MediaTexture, Graphic3d_Texture2D)
 // Function : Graphic3d_MediaTexture
 // Purpose  :
 // ================================================================
-Graphic3d_MediaTexture::Graphic3d_MediaTexture (const Handle(Media_HMutex)& theMutex,
+Graphic3d_MediaTexture::Graphic3d_MediaTexture (const Handle(Standard_HMutex)& theMutex,
                                                 Standard_Integer thePlane)
 : Graphic3d_Texture2D ("", Graphic3d_TOT_2D),
   myMutex (theMutex),
index c081e47..8fb1ecb 100644 (file)
@@ -21,7 +21,6 @@
 #include <Standard_Mutex.hxx>
 
 class Media_Frame;
-typedef NCollection_Shared<Standard_Mutex> Media_HMutex;
 
 //! Texture adapter for Media_Frame.
 class Graphic3d_MediaTexture : public Graphic3d_Texture2D
@@ -30,7 +29,7 @@ class Graphic3d_MediaTexture : public Graphic3d_Texture2D
 public:
 
   //! Main constructor.
-  Standard_EXPORT Graphic3d_MediaTexture (const Handle(Media_HMutex)& theMutex,
+  Standard_EXPORT Graphic3d_MediaTexture (const Handle(Standard_HMutex)& theMutex,
                                           Standard_Integer thePlane = -1);
 
   //! Image reader.
@@ -47,10 +46,10 @@ public:
 
 protected:
 
-  mutable Handle(Media_HMutex) myMutex;
-  Handle(Media_Frame)          myFrame;
-  Standard_Integer             myPlane;
-  mutable Handle(Image_PixMap) myPixMapWrapper;
+  mutable Handle(Standard_HMutex) myMutex;
+  Handle(Media_Frame)             myFrame;
+  Standard_Integer                myPlane;
+  mutable Handle(Image_PixMap)    myPixMapWrapper;
 
 };
 
index 8a482c7..92134e1 100644 (file)
@@ -41,7 +41,7 @@ IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_MediaTextureSet, Graphic3d_TextureSet)
 // ================================================================
 Graphic3d_MediaTextureSet::Graphic3d_MediaTextureSet()
 : Graphic3d_TextureSet (4),
-  myMutex (new Media_HMutex()),
+  myMutex (new Standard_HMutex()),
   myCallbackFunction(NULL),
   myCallbackUserPtr (NULL),
   myProgress (0.0),
index 1e21b39..68200ca 100644 (file)
@@ -96,7 +96,7 @@ protected:
   Handle(Media_Frame)             myFramePair[2];      //!< front/back frames pair
   Handle(Graphic3d_ShaderProgram) myShaderYUV;         //!< shader program for YUV  texture set
   Handle(Graphic3d_ShaderProgram) myShaderYUVJ;        //!< shader program for YUVJ texture set
-  Handle(Media_HMutex)            myMutex;             //!< mutex for accessing frames
+  Handle(Standard_HMutex)         myMutex;             //!< mutex for accessing frames
   TCollection_AsciiString         myInput;             //!< input media
   CallbackOnUpdate_t              myCallbackFunction;  //!< callback function
   void*                           myCallbackUserPtr;   //!< callback data
index dfdfb6a..7197979 100644 (file)
@@ -19,6 +19,7 @@
 #include <Standard_Integer.hxx>
 #include <Standard_Boolean.hxx>
 #include <Standard_ErrorHandler.hxx>
+#include <NCollection_Shared.hxx>
 
 #if defined(_WIN32)
   #include <windows.h>
@@ -169,6 +170,8 @@ private:
 #endif  
 };
 
+typedef NCollection_Shared<Standard_Mutex> Standard_HMutex;
+
 // Implementation of the method Unlock is inline, since it is 
 // just a shortcut to system function
 inline void Standard_Mutex::Unlock ()
diff --git a/tests/heal/checkshape/begin b/tests/heal/checkshape/begin
new file mode 100644 (file)
index 0000000..398409d
--- /dev/null
@@ -0,0 +1,24 @@
+set no_result 1
+
+proc CheckPerform {path} {
+  puts ""
+  puts "model: $path"
+  restore $path c
+  dchrono s reset; dchrono s start;
+  set cres [checkshape c]
+  dchrono s stop;
+  regexp {Elapsed time: +([-0-9.+eE]+) Hours +([-0-9.+eE]+) Minutes +([-0-9.+eE]+) Seconds} [dchrono s show] full s_Hours s_Minutes s_Seconds
+  set s_Time [expr ${s_Hours}*60.*60. + ${s_Minutes}*60. + ${s_Seconds} ]
+  puts "single-threaded time: $s_Time"  
+  dchrono p reset; dchrono p start;
+  set pres [checkshape c -parallel]
+  dchrono p stop;
+  regexp {Elapsed time: +([-0-9.+eE]+) Hours +([-0-9.+eE]+) Minutes +([-0-9.+eE]+) Seconds} [dchrono p show] full p_Hours p_Minutes p_Seconds
+  set p_Time [expr ${p_Hours}*60.*60. + ${p_Minutes}*60. + ${p_Seconds} ]
+  puts "multithreaded time: $p_Time"  
+  set ratio [expr ${s_Time}/${p_Time} ]
+  puts "acceleration in multi-threaded work: $ratio" 
+    if {[string compare $cres $pres] != 0} {
+    puts "Error: different result between single-thread and parallel on $path"
+  }
+}
diff --git a/tests/heal/checkshape/bug27814_1 b/tests/heal/checkshape/bug27814_1
new file mode 100644 (file)
index 0000000..cdec7e6
--- /dev/null
@@ -0,0 +1,6 @@
+puts "=========="
+puts "0027814: Parallelize BRepCheck_Analyzer"
+puts "=========="
+puts ""
+
+CheckPerform [locate_data_file bug27814.brep]
\ No newline at end of file
diff --git a/tests/heal/checkshape/bug27814_10 b/tests/heal/checkshape/bug27814_10
new file mode 100644 (file)
index 0000000..c1862aa
--- /dev/null
@@ -0,0 +1,7 @@
+puts "REQUIRED All: Faulty shapes in variables faulty_1 to faulty_51"
+puts "=========="
+puts "0027814: Parallelize BRepCheck_Analyzer"
+puts "=========="
+puts ""
+
+CheckPerform [locate_data_file OCC394.brep]
\ No newline at end of file
diff --git a/tests/heal/checkshape/bug27814_11 b/tests/heal/checkshape/bug27814_11
new file mode 100644 (file)
index 0000000..7137456
--- /dev/null
@@ -0,0 +1,7 @@
+puts "REQUIRED All: Faulty shapes in variables faulty_1 to faulty_31"
+puts "=========="
+puts "0027814: Parallelize BRepCheck_Analyzer"
+puts "=========="
+puts ""
+
+CheckPerform [locate_data_file OCC396.brep]
\ No newline at end of file
diff --git a/tests/heal/checkshape/bug27814_2 b/tests/heal/checkshape/bug27814_2
new file mode 100644 (file)
index 0000000..c4baf0f
--- /dev/null
@@ -0,0 +1,6 @@
+puts "=========="
+puts "0027814: Parallelize BRepCheck_Analyzer"
+puts "=========="
+puts ""
+
+CheckPerform [locate_data_file 5000-12.brep]
\ No newline at end of file
diff --git a/tests/heal/checkshape/bug27814_3 b/tests/heal/checkshape/bug27814_3
new file mode 100644 (file)
index 0000000..3094d52
--- /dev/null
@@ -0,0 +1,7 @@
+puts "REQUIRED All: Faulty shapes in variables faulty_1 to faulty_12"
+puts "=========="
+puts "0027814: Parallelize BRepCheck_Analyzer"
+puts "=========="
+puts ""
+
+CheckPerform [locate_data_file BPLSEITLI.brep]
\ No newline at end of file
diff --git a/tests/heal/checkshape/bug27814_4 b/tests/heal/checkshape/bug27814_4
new file mode 100644 (file)
index 0000000..635da1f
--- /dev/null
@@ -0,0 +1,6 @@
+puts "=========="
+puts "0027814: Parallelize BRepCheck_Analyzer"
+puts "=========="
+puts ""
+
+CheckPerform [locate_data_file bug24525_License.brep]
\ No newline at end of file
diff --git a/tests/heal/checkshape/bug27814_5 b/tests/heal/checkshape/bug27814_5
new file mode 100644 (file)
index 0000000..41475af
--- /dev/null
@@ -0,0 +1,7 @@
+puts "REQUIRED All: Faulty shapes in variables faulty_1 to faulty_40"
+puts "=========="
+puts "0027814: Parallelize BRepCheck_Analyzer"
+puts "=========="
+puts ""
+
+CheckPerform [locate_data_file bug26278_E01754_000000_P00_01_0_VS3_1_20070102_sewed_fixed.brep]
\ No newline at end of file
diff --git a/tests/heal/checkshape/bug27814_6 b/tests/heal/checkshape/bug27814_6
new file mode 100644 (file)
index 0000000..45049ae
--- /dev/null
@@ -0,0 +1,10 @@
+puts "REQUIRED All: Faulty shapes in variables faulty_1 to faulty_"
+# The number of identified faults in this model is unstable,
+# but it's not a parallelization problem
+
+puts "=========="
+puts "0027814: Parallelize BRepCheck_Analyzer"
+puts "=========="
+puts ""
+
+CheckPerform [locate_data_file bug28871_50056.brep]
\ No newline at end of file
diff --git a/tests/heal/checkshape/bug27814_7 b/tests/heal/checkshape/bug27814_7
new file mode 100644 (file)
index 0000000..2919124
--- /dev/null
@@ -0,0 +1,7 @@
+puts "REQUIRED All: Faulty shapes in variables faulty_1 to faulty_114"
+puts "=========="
+puts "0027814: Parallelize BRepCheck_Analyzer"
+puts "=========="
+puts ""
+
+CheckPerform [locate_data_file bug30360_GES-13500-000.brep]
\ No newline at end of file
diff --git a/tests/heal/checkshape/bug27814_8 b/tests/heal/checkshape/bug27814_8
new file mode 100644 (file)
index 0000000..9f645cb
--- /dev/null
@@ -0,0 +1,7 @@
+puts "REQUIRED All: Faulty shapes in variables faulty_1 to faulty_10"
+puts "=========="
+puts "0027814: Parallelize BRepCheck_Analyzer"
+puts "=========="
+puts ""
+
+CheckPerform [locate_data_file OCC187_from_bug_description.brep]
\ No newline at end of file
diff --git a/tests/heal/checkshape/bug27814_9 b/tests/heal/checkshape/bug27814_9
new file mode 100644 (file)
index 0000000..c1862aa
--- /dev/null
@@ -0,0 +1,7 @@
+puts "REQUIRED All: Faulty shapes in variables faulty_1 to faulty_51"
+puts "=========="
+puts "0027814: Parallelize BRepCheck_Analyzer"
+puts "=========="
+puts ""
+
+CheckPerform [locate_data_file OCC394.brep]
\ No newline at end of file
index 801e45c..eb51530 100755 (executable)
@@ -1,9 +1,11 @@
- if { [isdraw result] } {
-  checkview -display result -2d -path ${imagedir}/${test_image}.png
-} elseif { [isdraw r] } {
-  pload VISUALIZATION
-  checkview -display r -3d -vdispmode 0 -path ${imagedir}/${test_image}.png
-} else {
-   puts "Error : the resulting shape is not done."
+if { ![info exists no_result] } {
+   if { [isdraw result] } {
+    checkview -display result -2d -path ${imagedir}/${test_image}.png
+  } elseif { [isdraw r] } {
+    pload VISUALIZATION
+    checkview -display r -3d -vdispmode 0 -path ${imagedir}/${test_image}.png
+  } else {
+     puts "Error : the resulting shape is not done."
+  }
 }
 puts "TEST COMPLETED"
index 2e75e21..53e9a0a 100644 (file)
@@ -21,5 +21,6 @@
 021 wire_tails_real
 022 reshape
 023 unify_same_domain
-014 same_parameter_locked
-015 update_tolerance_locked
\ No newline at end of file
+024 same_parameter_locked
+025 update_tolerance_locked
+026 checkshape
\ No newline at end of file