0023631: Infinite memory consumption in BRepMesh
[occt.git] / src / BRepMesh / BRepMesh_FaceChecker.hxx
1 // Created on: 2014-05-28
2 // Created by: Oleg AGASHIN
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #ifndef _BRepMesh_FaceChecker_HeaderFile
17 #define _BRepMesh_FaceChecker_HeaderFile
18
19 #include <Standard.hxx>
20 #include <Standard_Mutex.hxx>
21 #include <TopoDS_Face.hxx>
22 #include <TopoDS_Edge.hxx>
23 #include <TopLoc_Location.hxx>
24 #include <Poly_Triangulation.hxx>
25 #include <TopExp_Explorer.hxx>
26 #include <BRepMesh_EdgeChecker.hxx>
27
28 #include <vector>
29
30 #ifdef HAVE_TBB
31   // paralleling using Intel TBB
32   #include <tbb/parallel_for_each.h>
33 #endif
34
35 //! Auxilary class implementing functionality for 
36 //! checking consistency of triangulation on the given face.
37 class BRepMesh_FaceChecker
38 {
39 public:
40
41   //! Constructor
42   //! \param isInParallel Flag indicates that face edges should be checked in parallel.
43   BRepMesh_FaceChecker(const Standard_Boolean isInParallel)
44     : myIsFailed(Standard_False),
45       myIsInParallel(isInParallel)
46   {
47   }
48
49   //! Checker's body.
50   //! \param theFace Face to be checked.
51   void operator ()(const TopoDS_Face& theFace) const
52   {
53     if (theFace.IsNull() || myIsFailed)
54       return;
55
56     TopLoc_Location aFaceLoc;
57     Handle(Poly_Triangulation) aFaceT =
58       BRep_Tool::Triangulation(theFace, aFaceLoc);
59
60     if (aFaceT.IsNull())
61       return;
62
63     std::vector<TopoDS_Edge> aEdges;
64     TopExp_Explorer aEdgeIt(theFace, TopAbs_EDGE);
65     for ( ; aEdgeIt.More(); aEdgeIt.Next())
66       aEdges.push_back(TopoDS::Edge(aEdgeIt.Current()));
67
68     BRepMesh_EdgeChecker aEdgeChecker(aFaceT, aFaceLoc, myMutex, myIsFailed);
69     if (myIsInParallel)
70     {
71     #ifdef HAVE_TBB
72       // check faces in parallel threads using TBB
73       tbb::parallel_for_each(aEdges.begin(), aEdges.end(), aEdgeChecker);
74     #else
75       // alternative parallelization not yet available
76       for (std::vector<TopoDS_Edge>::iterator it(aEdges.begin()); it != aEdges.end(); it++)
77         aEdgeChecker(*it);
78     #endif
79     }
80     else
81     {
82       for (std::vector<TopoDS_Edge>::iterator it(aEdges.begin()); it != aEdges.end(); it++)
83         aEdgeChecker(*it);
84     }
85   }
86
87   //! Returns status of the check.
88   Standard_Boolean IsValid() const 
89   {
90     return !myIsFailed;
91   }
92
93 private:
94   mutable Standard_Mutex   myMutex;
95   mutable Standard_Boolean myIsFailed;
96   Standard_Boolean         myIsInParallel;
97 };
98
99 #endif