0031125: BRepMesh_IncrementalMesh crash in constructor for empty compound shape
[occt.git] / src / IMeshTools / IMeshTools_ShapeExplorer.cxx
1 // Created on: 2016-04-07
2 // Copyright (c) 2016 OPEN CASCADE SAS
3 // Created by: Oleg AGASHIN
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 #include <IMeshTools_ShapeExplorer.hxx>
17 #include <TopExp.hxx>
18 #include <TopExp_Explorer.hxx>
19 #include <TopoDS.hxx>
20 #include <TopoDS_Face.hxx>
21 #include <TopoDS_Edge.hxx>
22 #include <TopTools_ListOfShape.hxx>
23 #include <BRepLib.hxx>
24 #include <BRep_Tool.hxx>
25 #include <TopTools_MapOfShape.hxx>
26 #include <Geom_Surface.hxx>
27
28 namespace
29 {
30   //=======================================================================
31   // Function: visitEdges
32   // Purpose : Explodes the given shape on edges according to the specified
33   //           criteria and visits each one in order to add it to data model.
34   //=======================================================================
35   void visitEdges (const Handle (IMeshTools_ShapeVisitor)& theVisitor,
36                    const TopoDS_Shape&                     theShape,
37                    const TopAbs_ShapeEnum                  theToFind,
38                    const TopAbs_ShapeEnum                  theToAvoid = TopAbs_SHAPE)
39   {
40     TopExp_Explorer aEdgesIt (theShape, theToFind, theToAvoid);
41     for (; aEdgesIt.More (); aEdgesIt.Next ())
42     {
43       const TopoDS_Edge& aEdge = TopoDS::Edge (aEdgesIt.Current ());
44       if (!BRep_Tool::IsGeometric (aEdge))
45       {
46         continue;
47       }
48
49       theVisitor->Visit (aEdge);
50     }
51   }
52 }
53
54 //=======================================================================
55 // Function: Constructor
56 // Purpose : 
57 //=======================================================================
58 IMeshTools_ShapeExplorer::IMeshTools_ShapeExplorer (
59   const TopoDS_Shape& theShape)
60   : IMeshData_Shape (theShape)
61 {
62 }
63
64 //=======================================================================
65 // Function: Destructor
66 // Purpose : 
67 //=======================================================================
68 IMeshTools_ShapeExplorer::~IMeshTools_ShapeExplorer ()
69 {
70 }
71
72 //=======================================================================
73 // Function: Accept
74 // Purpose : 
75 //=======================================================================
76 void IMeshTools_ShapeExplorer::Accept (
77   const Handle (IMeshTools_ShapeVisitor)& theVisitor)
78 {
79   // Explore all free edges in shape.
80   visitEdges (theVisitor, GetShape (), TopAbs_EDGE, TopAbs_FACE);
81
82   // Explore all related to some face edges in shape.
83   // make array of faces suitable for processing (excluding faces without surface)
84   TopTools_ListOfShape aFaceList;
85   BRepLib::ReverseSortFaces (GetShape (), aFaceList);
86   TopTools_MapOfShape aFaceMap;
87
88   TopLoc_Location aDummyLoc;
89   const TopLoc_Location aEmptyLoc;
90   TopTools_ListIteratorOfListOfShape aFaceIter (aFaceList);
91   for (; aFaceIter.More (); aFaceIter.Next ())
92   {
93     TopoDS_Shape aFaceNoLoc = aFaceIter.Value ();
94     aFaceNoLoc.Location (aEmptyLoc);
95     if (!aFaceMap.Add(aFaceNoLoc))
96     {
97       continue; // already processed
98     }
99
100     const TopoDS_Face& aFace = TopoDS::Face (aFaceIter.Value ());
101     const Handle (Geom_Surface)& aSurf = BRep_Tool::Surface (aFace, aDummyLoc);
102     if (aSurf.IsNull())
103     {
104       continue;
105     }
106
107     // Explore all edges in face.
108     visitEdges (theVisitor, aFace, TopAbs_EDGE);
109
110     // Store only forward faces in order to prevent inverse issue.
111     theVisitor->Visit (TopoDS::Face (aFace.Oriented (TopAbs_FORWARD)));
112   }
113 }