0025503: BRepMesh - IncrementalMesh always re-meshes the shape even if existing trian...
authormsv <msv@opencascade.com>
Fri, 28 Nov 2014 10:03:57 +0000 (13:03 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 28 Nov 2014 10:49:43 +0000 (13:49 +0300)
Test case for issue CR25503

Correction of test cases for issue CR25503

src/BRepMesh/BRepMesh.hxx
src/BRepMesh/BRepMesh_EdgeChecker.hxx [deleted file]
src/BRepMesh/BRepMesh_FaceChecker.hxx [deleted file]
src/BRepMesh/BRepMesh_IncrementalMesh.cxx
src/BRepMesh/BRepMesh_IncrementalMesh.hxx
src/BRepMesh/FILES
tests/bugs/mesh/bug25503_1 [new file with mode: 0644]
tests/bugs/mesh/bug25503_2 [new file with mode: 0755]
tests/mesh/data/standard/M1

index 121abdd..139e380 100644 (file)
@@ -94,7 +94,7 @@ namespace BRepMesh
 
   //! Maps
   typedef NCollection_Map<Standard_Integer>                                                         MapOfInteger;
-  typedef NCollection_Map<Handle(Poly_Triangulation)>                                               MapOfTriangulation;
+  typedef NCollection_DataMap<Handle(Poly_Triangulation), Standard_Boolean>                         DMapOfTriangulationBool;
   typedef NCollection_Map<TopoDS_Shape, TopTools_ShapeMapHasher>                                    MapOfShape;
 
   typedef NCollection_DataMap<Standard_Integer, Standard_Integer>                                   MapOfIntegerInteger;
@@ -104,7 +104,7 @@ namespace BRepMesh
   typedef NCollection_DataMap<Standard_Integer, gp_Pnt>                                             DMapOfIntegerPnt;
   typedef NCollection_DataMap<Standard_Integer, ListOfXY>                                           DMapOfIntegerListOfXY;
   typedef NCollection_DataMap<Standard_Integer, ListOfInteger>                                      DMapOfIntegerListOfInteger;
-  typedef NCollection_DataMap<TopoDS_Edge, MapOfTriangulation, TopTools_ShapeMapHasher>             DMapOfEdgeListOfTriangulation;
+  typedef NCollection_DataMap<TopoDS_Edge, DMapOfTriangulationBool, TopTools_ShapeMapHasher>        DMapOfEdgeListOfTriangulationBool;
 
   typedef NCollection_IndexedMap<Standard_Integer>                                                  IMapOfInteger;
   typedef NCollection_IndexedMap<Standard_Real>                                                     IMapOfReal;
diff --git a/src/BRepMesh/BRepMesh_EdgeChecker.hxx b/src/BRepMesh/BRepMesh_EdgeChecker.hxx
deleted file mode 100644 (file)
index f558708..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-// Created on: 2014-05-28
-// Created by: Oleg AGASHIN
-// Copyright (c) 2011-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 _BRepMesh_EdgeChecker_HeaderFile
-#define _BRepMesh_EdgeChecker_HeaderFile
-
-#include <Standard.hxx>
-#include <Standard_Mutex.hxx>
-#include <Poly_Triangulation.hxx>
-#include <TopLoc_Location.hxx>
-#include <TopoDS_Edge.hxx>
-#include <Poly_PolygonOnTriangulation.hxx>
-#include <BRep_Tool.hxx>
-
-//! Auxilary class implementing functionality for checking consistency 
-//! of polygon on triangulation of the given edge.
-class BRepMesh_EdgeChecker
-{
-public:
-
-  //! Constructor
-  //! @param theFaceTri Poly triangulation of face the edges relie to.
-  //! @param theFaceLoc Face location to be used to extract polygon on triangulation.
-  //! @param theMutex Upper level shared mutex to protect isFailed flag from concurrent write access.
-  //! @param isFailed Upper level shared flag indicating that polygon on triangulation of checked 
-  //! edge is not consistent. If this flag is set to TRUE, other tasks will not check details of their data.
-  BRepMesh_EdgeChecker( Handle(Poly_Triangulation)& theFaceTri,
-                        TopLoc_Location&            theFaceLoc,
-                        Standard_Mutex&             theMutex,
-                        Standard_Boolean&           isFailed)
-    : myMutex(theMutex),
-      myIsFailed(isFailed),
-      myFaceLoc(theFaceLoc),
-      myFaceTri(theFaceTri)
-  {
-  }
-
-  //! Checker's body.
-  //! @param theEdge edge to be checked.
-  void operator ()(const TopoDS_Edge& theEdge) const
-  {
-    if (theEdge.IsNull() || myIsFailed)
-      return;
-
-    const Handle(Poly_PolygonOnTriangulation)& aPoly =
-      BRep_Tool::PolygonOnTriangulation(theEdge, myFaceTri, myFaceLoc);
-
-    if (!aPoly.IsNull())
-      return;
-
-    // Trianglulation stored inside a face is different 
-    // than the one an edge data connected to.
-    Standard_Mutex::Sentry aSentry(myMutex);
-    myIsFailed = Standard_True;
-  }
-
-private:
-
-  void operator =(const BRepMesh_EdgeChecker& /*theOther*/)
-  {
-  }
-
-private:
-  Standard_Mutex&             myMutex;
-  Standard_Boolean&           myIsFailed;
-  TopLoc_Location&            myFaceLoc;
-  Handle(Poly_Triangulation)& myFaceTri;
-};
-
-#endif
diff --git a/src/BRepMesh/BRepMesh_FaceChecker.hxx b/src/BRepMesh/BRepMesh_FaceChecker.hxx
deleted file mode 100644 (file)
index 350e345..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-// Created on: 2014-05-28
-// Created by: Oleg AGASHIN
-// Copyright (c) 2011-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 _BRepMesh_FaceChecker_HeaderFile
-#define _BRepMesh_FaceChecker_HeaderFile
-
-#include <Standard.hxx>
-#include <Standard_Mutex.hxx>
-#include <TopoDS.hxx>
-#include <TopoDS_Face.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopLoc_Location.hxx>
-#include <Poly_Triangulation.hxx>
-#include <TopExp_Explorer.hxx>
-#include <BRepMesh_EdgeChecker.hxx>
-
-#include <vector>
-
-#ifdef HAVE_TBB
-  // paralleling using Intel TBB
-  #include <tbb/parallel_for_each.h>
-#endif
-
-//! Auxilary class implementing functionality for 
-//! checking consistency of triangulation on the given face.
-class BRepMesh_FaceChecker
-{
-public:
-
-  //! Constructor
-  //! @param isInParallel Flag indicates that face edges should be checked in parallel.
-  BRepMesh_FaceChecker(const Standard_Boolean isInParallel)
-    : myIsFailed(Standard_False),
-      myIsInParallel(isInParallel)
-  {
-  }
-
-  //! Checker's body.
-  //! @param theFace Face to be checked.
-  void operator ()(const TopoDS_Face& theFace) const
-  {
-    if (theFace.IsNull() || myIsFailed)
-      return;
-
-    TopLoc_Location aFaceLoc;
-    Handle(Poly_Triangulation) aFaceT =
-      BRep_Tool::Triangulation(theFace, aFaceLoc);
-
-    if (aFaceT.IsNull())
-      return;
-
-    std::vector<TopoDS_Edge> aEdges;
-    TopExp_Explorer aEdgeIt(theFace, TopAbs_EDGE);
-    for ( ; aEdgeIt.More(); aEdgeIt.Next())
-      aEdges.push_back(TopoDS::Edge(aEdgeIt.Current()));
-
-    BRepMesh_EdgeChecker aEdgeChecker(aFaceT, aFaceLoc, myMutex, myIsFailed);
-#ifdef HAVE_TBB
-    if (myIsInParallel)
-    {
-      // check faces in parallel threads using TBB
-      tbb::parallel_for_each(aEdges.begin(), aEdges.end(), aEdgeChecker);
-    }
-    else
-    {
-#endif
-      for (std::vector<TopoDS_Edge>::iterator it(aEdges.begin()); it != aEdges.end(); it++)
-        aEdgeChecker(*it);
-#ifdef HAVE_TBB
-    }
-#endif
-  }
-
-  //! Returns status of the check.
-  Standard_Boolean IsValid() const 
-  {
-    return !myIsFailed;
-  }
-
-private:
-  mutable Standard_Mutex   myMutex;
-  mutable Standard_Boolean myIsFailed;
-  Standard_Boolean         myIsInParallel;
-};
-
-#endif
index 9c614e9..358a44b 100644 (file)
@@ -19,7 +19,6 @@
 #include <Precision.hxx>
 #include <Standard_ErrorHandler.hxx>
 
-#include <BRepMesh_FaceChecker.hxx>
 #include <BRepMesh_ShapeTool.hxx>
 #include <BRepMesh_Edge.hxx>
 #include <BRepMesh_PluginMacro.hxx>
@@ -112,7 +111,7 @@ BRepMesh_IncrementalMesh::~BRepMesh_IncrementalMesh()
 //=======================================================================
 void BRepMesh_IncrementalMesh::clear()
 {
-  myEmptyEdges.Clear();
+  myEdges.Clear();
   myEdgeDeflection.Clear();
   myFaces.Clear();
   myMesh.Nullify();
@@ -130,8 +129,7 @@ void BRepMesh_IncrementalMesh::init()
   setDone();
   clear();
 
-  if (!isCorrectPolyData())
-    BRepTools::Clean(myShape);
+  collectFaces();
 
   Bnd_Box aBox;
   BRepBndLib::Add(myShape, aBox, Standard_False);
@@ -151,35 +149,6 @@ void BRepMesh_IncrementalMesh::init()
 }
 
 //=======================================================================
-//function : isCorrectPolyData
-//purpose  : 
-//=======================================================================
-Standard_Boolean BRepMesh_IncrementalMesh::isCorrectPolyData()
-{
-  collectFaces();
-
-  BRepMesh_FaceChecker aFaceChecker(myInParallel);
-
-#ifdef HAVE_TBB
-  if (myInParallel)
-  {
-    // check faces in parallel threads using TBB
-    tbb::parallel_for_each(myFaces.begin(), myFaces.end(), aFaceChecker);
-  }
-  else
-  {
-#endif
-    NCollection_Vector<TopoDS_Face>::Iterator aFaceIt(myFaces);
-    for (; aFaceIt.More(); aFaceIt.Next())
-      aFaceChecker(aFaceIt.Value());
-#ifdef HAVE_TBB
-  }
-#endif
-
-  return aFaceChecker.IsValid();
-}
-
-//=======================================================================
 //function : collectFaces
 //purpose  : 
 //=======================================================================
@@ -357,59 +326,46 @@ Standard_Real BRepMesh_IncrementalMesh::faceDeflection(
 //=======================================================================
 void BRepMesh_IncrementalMesh::update(const TopoDS_Edge& theEdge)
 {
-  Standard_Integer aPolyIndex   = 1;
+  if (!myEdges.IsBound(theEdge))
+    myEdges.Bind(theEdge, BRepMesh::DMapOfTriangulationBool());
+
   Standard_Real aEdgeDeflection = edgeDeflection(theEdge);
-  Handle(Poly_PolygonOnTriangulation) aPolygon;
-  do
+  // Check that triangulation relies to face of the given shape.
+  const TopTools_IndexedDataMapOfShapeListOfShape& aMapOfSharedFaces = 
+    myMesh->SharedFaces();
+
+  const TopTools_ListOfShape& aSharedFaces = 
+    aMapOfSharedFaces.FindFromKey(theEdge);
+
+  TopTools_ListIteratorOfListOfShape aSharedFaceIt(aSharedFaces);
+  for (; aSharedFaceIt.More(); aSharedFaceIt.Next())
   {
     TopLoc_Location aLoc;
-    Handle(Poly_Triangulation) aTriangulation;
-    BRep_Tool::PolygonOnTriangulation(theEdge, aPolygon, 
-      aTriangulation, aLoc, aPolyIndex++);
-
-    if (!aTriangulation.IsNull() && !aPolygon.IsNull())
-    {
-      if (aPolygon->Deflection() < 1.1 * aEdgeDeflection &&
-          aPolygon->HasParameters())
-      {
-        continue;
-      }
-      else
-      {
-        // Check that triangulation relies to face of the given shape.
-        const TopTools_IndexedDataMapOfShapeListOfShape& aMapOfSharedFaces = 
-          myMesh->SharedFaces();
+    const TopoDS_Face& aFace = TopoDS::Face(aSharedFaceIt.Value());
+    const Handle(Poly_Triangulation)& aFaceTriangulation = 
+      BRep_Tool::Triangulation(aFace, aLoc);
 
-        const TopTools_ListOfShape& aSharedFaces = 
-          aMapOfSharedFaces.FindFromKey(theEdge);
+    if (aFaceTriangulation.IsNull())
+      continue;
 
-        Standard_Boolean isCurrentShape = Standard_False;
-        TopTools_ListIteratorOfListOfShape aSharedFaceIt(aSharedFaces);
-        for (; aSharedFaceIt.More() && !isCurrentShape; aSharedFaceIt.Next())
-        {
-          TopLoc_Location aLoc;
-          const TopoDS_Face& aFace = TopoDS::Face(aSharedFaceIt.Value());
-          Handle(Poly_Triangulation) aFaceTriangulation = 
-            BRep_Tool::Triangulation(aFace, aLoc);
+    Standard_Boolean isConsistent = Standard_False;
+    const Handle(Poly_PolygonOnTriangulation)& aPolygon =
+      BRep_Tool::PolygonOnTriangulation(theEdge, aFaceTriangulation, aLoc);
 
-          isCurrentShape = (aFaceTriangulation == aTriangulation);
-        }
+    if (!aPolygon.IsNull())
+    {
+      isConsistent = aPolygon->Deflection() < 1.1 * aEdgeDeflection &&
+        aPolygon->HasParameters();
 
-        if (!isCurrentShape)
-          continue;
+      if (!isConsistent)
+      {
+        myModified = Standard_True;
+        BRepMesh_ShapeTool::NullifyEdge(theEdge, aFaceTriangulation, aLoc);
       }
-
-      myModified = Standard_True;
-      BRepMesh_ShapeTool::NullifyEdge(theEdge, aTriangulation, aLoc);
     }
 
-    if (!myEmptyEdges.IsBound(theEdge))
-      myEmptyEdges.Bind(theEdge, BRepMesh::MapOfTriangulation());
-
-    if (!aTriangulation.IsNull())
-      myEmptyEdges(theEdge).Add(aTriangulation);
+    myEdges(theEdge).Bind(aFaceTriangulation, isConsistent);
   }
-  while (!aPolygon.IsNull());
 }
 
 //=======================================================================
@@ -437,15 +393,33 @@ Standard_Boolean BRepMesh_IncrementalMesh::toBeMeshed(
       for (; aEdgeIt.More() && isEdgesConsistent; aEdgeIt.Next())
       {
         const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current());
-        if (!myEmptyEdges.IsBound(aEdge))
+        if (!myEdges.IsBound(aEdge))
           continue;
 
-        BRepMesh::MapOfTriangulation& aTriMap = myEmptyEdges(aEdge);
-        isEdgesConsistent &= !aTriMap.IsEmpty() && !aTriMap.Contains(aTriangulation);
+        BRepMesh::DMapOfTriangulationBool& aTriMap = myEdges(aEdge);
+        isEdgesConsistent &= aTriMap.IsBound(aTriangulation) &&
+          aTriMap(aTriangulation);
       }
 
       if (isEdgesConsistent)
-        return Standard_False;
+      {
+        // #25080: check that indices of links forming triangles are in range.
+        Standard_Boolean isTriangulationConsistent = Standard_True;
+        const Standard_Integer aNodesNb = aTriangulation->NbNodes();
+        const Poly_Array1OfTriangle& aTriangles = aTriangulation->Triangles();
+        Standard_Integer i = aTriangles.Lower();
+        for (; i <= aTriangles.Upper() && isTriangulationConsistent; ++i)
+        {
+          const Poly_Triangle& aTriangle = aTriangles(i);
+          Standard_Integer n[3];
+          aTriangle.Get(n[0], n[1], n[2]);
+          for (Standard_Integer j = 0; j < 3 && isTriangulationConsistent; ++j)
+            isTriangulationConsistent = (n[j] >= 1 && n[j] <= aNodesNb);
+        }
+
+        if (isTriangulationConsistent)
+          return Standard_False;
+      }
     }
   }
 
index dc0f3c1..879b9b8 100644 (file)
@@ -132,13 +132,6 @@ protected:
 
 private:
 
-  //! Checks is the shape to be meshed has correct poly data, 
-  //! i.e. PolygonOnTriangulation of particular edge connected 
-  //! to the same Triangulation data structure as stored inside 
-  //! a parent face.
-  //! @return TRUE on success, FALSE in case of inconsistencies.
-  Standard_Boolean isCorrectPolyData();
-
   //! Builds the incremental mesh for the shape.
   void update();
 
@@ -191,15 +184,15 @@ private:
 
 protected:
 
-  Standard_Boolean                        myRelative;
-  Standard_Boolean                        myInParallel;
-  BRepMesh::DMapOfEdgeListOfTriangulation myEmptyEdges;
-  Handle(BRepMesh_FastDiscret)            myMesh;
-  Standard_Boolean                        myModified;
-  TopTools_DataMapOfShapeReal             myEdgeDeflection;
-  Standard_Real                           myMaxShapeSize;
-  Standard_Integer                        myStatus;
-  NCollection_Vector<TopoDS_Face>         myFaces;
+  Standard_Boolean                            myRelative;
+  Standard_Boolean                            myInParallel;
+  BRepMesh::DMapOfEdgeListOfTriangulationBool myEdges;
+  Handle(BRepMesh_FastDiscret)                myMesh;
+  Standard_Boolean                            myModified;
+  TopTools_DataMapOfShapeReal                 myEdgeDeflection;
+  Standard_Real                               myMaxShapeSize;
+  Standard_Integer                            myStatus;
+  NCollection_Vector<TopoDS_Face>             myFaces;
 };
 
 DEFINE_STANDARD_HANDLE(BRepMesh_IncrementalMesh,BRepMesh_DiscretRoot)
index 683eed9..a047677 100755 (executable)
@@ -33,8 +33,6 @@ BRepMesh_PairOfIndex.hxx
 BRepMesh_Status.hxx
 BRepMesh_CMPLRS.edl
 BRepMesh_VertexInspector.hxx
-BRepMesh_EdgeChecker.hxx
-BRepMesh_FaceChecker.hxx
 BRepMesh_SelectorOfDataStructureOfDelaun.hxx
 BRepMesh_SelectorOfDataStructureOfDelaun.cxx
 BRepMesh_EdgeParameterProvider.hxx
diff --git a/tests/bugs/mesh/bug25503_1 b/tests/bugs/mesh/bug25503_1
new file mode 100644 (file)
index 0000000..744889d
--- /dev/null
@@ -0,0 +1,19 @@
+puts "============"
+puts "CR25503"
+puts "============"
+puts ""
+###################################################################################
+# BRepMesh - IncrementalMesh always re-meshes the shape even if existing triangulation satisfies the given deflection
+###################################################################################
+
+puts "===> meshing segment of sphere"
+psphere a 100 -45 45 180
+puts ""
+puts "incmesh first time"
+set t1 [expr [lindex [time {incmesh a 0.003}] 0]/1000000]
+puts "spent $t1 sec"
+puts ""
+puts "incmesh second time"
+set t2 [expr [lindex [time {incmesh a 0.003}] 0]/1000000]
+puts "spent $t2 sec"
+if {$t2 != 0} {puts "Error: second time must be quicker"}
diff --git a/tests/bugs/mesh/bug25503_2 b/tests/bugs/mesh/bug25503_2
new file mode 100755 (executable)
index 0000000..b04b521
--- /dev/null
@@ -0,0 +1,23 @@
+puts "TODO CR25469 ALL: Error: second time must be quicker"
+
+puts "============"
+puts "CR25503"
+puts "============"
+puts ""
+###################################################################################
+# BRepMesh - IncrementalMesh always re-meshes the shape even if existing triangulation satisfies the given deflection
+###################################################################################
+
+puts ""
+puts "===> meshing full sphere"
+psphere a 100
+puts ""
+puts "incmesh first time"
+set t3 [expr [lindex [time {incmesh a 0.015}] 0]/1000000]
+puts "spent $t3 sec"
+puts ""
+puts "incmesh second time"
+set t4 [expr [lindex [time {incmesh a 0.015}] 0]/1000000]
+puts "spent $t4 sec"
+if {$t4 != 0} {puts "Error: second time must be quicker"}
+puts ""
index d78592a..a1ed0ff 100755 (executable)
@@ -1,6 +1,7 @@
 set TheFileName shading_109.brep
 if { [string compare ${command} "shading"] == 0 && [string compare ${group} "standard"] == 0} {
-   # 
+  set bug_cross "OCC25503"
+  set nbcross(All) 2
 } else {
   set bug_cross "OCC22687"
   set nbcross(All) 4