0026937: Eliminate NO_CXX_EXCEPTION macro support
[occt.git] / src / TopOpeBRepTool / TopOpeBRepTool_PurgeInternalEdges.cxx
1 // Created on: 1998-11-19
2 // Created by: Jean-Michel BOULCOURT
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <BRepTools_Substitution.hxx>
19 #include <Standard_ConstructionError.hxx>
20 #include <Standard_NullObject.hxx>
21 #include <TopExp.hxx>
22 #include <TopExp_Explorer.hxx>
23 #include <TopoDS.hxx>
24 #include <TopoDS_Shape.hxx>
25 #include <TopOpeBRepTool_PurgeInternalEdges.hxx>
26 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
27 #include <TopTools_DataMapOfShapeListOfShape.hxx>
28 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
29 #include <TopTools_ListIteratorOfListOfShape.hxx>
30 #include <TopTools_ListOfShape.hxx>
31 #include <TopTools_MapOfShape.hxx>
32
33 //=======================================================================
34 //function : TopOpeBRepTool_PurgeInternalEdges
35 //purpose  : Initializes some variables for the algorithm and perform
36 // the computation of the internal edges of the shape
37 //=======================================================================
38 TopOpeBRepTool_PurgeInternalEdges::TopOpeBRepTool_PurgeInternalEdges(const TopoDS_Shape& theShape,const Standard_Boolean PerformNow):myShape(theShape),myIsDone(Standard_False)
39 {
40 //  if (theShape.ShapeType() != TopAbs_SHELL && theShape.ShapeType() != TopAbs_SOLID)
41 //    throw Standard_ConstructionError("PurgeInternalEdges");
42   Standard_NullObject_Raise_if(theShape.IsNull(),"PurgeInternalEdges");
43   
44   if (PerformNow) {
45     Perform();
46   }
47 }
48
49 //=======================================================================
50 //function : Faces
51 //purpose  : 
52 //=======================================================================
53
54  void TopOpeBRepTool_PurgeInternalEdges::Faces(TopTools_DataMapOfShapeListOfShape& theMapFacLstEdg) 
55 {
56
57   if (!myIsDone) {
58     BuildList();
59   }
60
61   theMapFacLstEdg = myMapFacLstEdg;
62 }
63
64
65 //=======================================================================
66 //function : NbEdges
67 //purpose  : 
68 //=======================================================================
69
70 Standard_Integer TopOpeBRepTool_PurgeInternalEdges::NbEdges() const
71 {
72
73   Standard_NullObject_Raise_if(myShape.IsNull(),"PurgeInternalEdges : No Shape");
74   Standard_Integer nbedges = 0;
75
76   // if we have at least on internal (or external) edge to remove
77   if (myMapFacLstEdg.Extent() > 0) {
78
79     TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itFacEdg;
80 //    TopTools_ListIteratorOfListOfShape itEdg;
81
82     for (itFacEdg.Initialize(myMapFacLstEdg); itFacEdg.More(); itFacEdg.Next()) {
83       const TopoDS_Shape& facecur = itFacEdg.Key();
84       const TopTools_ListOfShape& LmapEdg = myMapFacLstEdg.Find(facecur);
85      
86       nbedges += LmapEdg.Extent();      
87     }
88     
89   }
90
91   return nbedges;
92
93 }
94
95
96
97
98 //=======================================================================
99 //function : Shape
100 //purpose  : 
101 //=======================================================================
102
103 TopoDS_Shape& TopOpeBRepTool_PurgeInternalEdges::Shape() 
104 {
105
106   Standard_NullObject_Raise_if(myShape.IsNull(),"PurgeInternalEdges : No Shape");
107
108   return myShape;
109
110 }
111
112 //=======================================================================
113 //function : BuildList
114 //purpose  : Build the map of faces with the list of inernal edges.
115 //=======================================================================
116
117 void TopOpeBRepTool_PurgeInternalEdges::BuildList()
118 {
119
120   TopExp_Explorer ExpEdge;
121   TopAbs_Orientation orien;
122   
123
124   //--------------------------------------------------------
125   // Step One : Build the map of the faces ancestor of edges
126   //--------------------------------------------------------
127   
128   // Clear the maps
129   myMapEdgLstFac.Clear();
130   
131   TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,myMapEdgLstFac);
132   
133   
134   //----------------------------------------------------------------
135   // Step Two : Explore the map myMapFacLstEdg to keep only the internal
136   // or external edges which have no connex faces
137   //----------------------------------------------------------------
138   
139   
140   Standard_Boolean ToKeep;
141   Standard_Integer iEdg;
142   TopTools_ListIteratorOfListOfShape itFac,itFacToTreat;
143   TopTools_ListOfShape LstFacToTreat;
144   
145   // for each edge of myMapEdgLstFac
146   for (iEdg = 1; iEdg <= myMapEdgLstFac.Extent(); iEdg++) {
147     const TopoDS_Shape& edgecur = myMapEdgLstFac.FindKey(iEdg);
148     const TopTools_ListOfShape& LmapFac = myMapEdgLstFac.FindFromKey(edgecur);
149     
150     
151     // if there are more than on face connex to the edge then examine the orientation of
152     // the edge in the faces to see it is only Internal or External. In that case the edge
153     // can be removed
154
155     itFac.Initialize(LmapFac);
156     LstFacToTreat.Clear();
157
158     if (LmapFac.Extent() > 1) {
159
160       ToKeep = Standard_False;
161       // for each face in the list of the edge
162       while (itFac.More() && !ToKeep) {
163         const TopoDS_Shape& facecur = itFac.Value();
164         
165         // find the edge in the face to get its relative orientation to the face
166         for (ExpEdge.Init(facecur,TopAbs_EDGE); ExpEdge.More(); ExpEdge.Next()) {
167           const TopoDS_Shape& edge = ExpEdge.Current();
168           
169           orien = edge.Orientation();
170
171           if (edge.IsSame(edgecur)) {
172             // we found the edge. Now check if its orientation is internal or external
173             // then the face is candidate to be modified. So put it in a temporary List of shapes
174             if (orien == TopAbs_INTERNAL || orien == TopAbs_EXTERNAL) {
175               LstFacToTreat.Append(facecur);
176             }
177             else {
178               // there is at least one face that contains that edge with a forward
179               // or reversed orientation. So we must keep that edge.
180               LstFacToTreat.Clear();
181               ToKeep = Standard_True;
182             }
183             break;
184           }
185         }
186         
187         itFac.Next();
188       }
189       
190     }
191
192     else {
193        if (edgecur.Orientation() == TopAbs_INTERNAL || edgecur.Orientation() == TopAbs_EXTERNAL) {
194          LstFacToTreat.Append(itFac.Value());
195        }
196     }
197     
198     // at that point, we have in the list LstFacToTreat the faces in which edgecur is
199     // connex and is coded only Internal or External.
200     if (!LstFacToTreat.IsEmpty()) {
201       TopTools_MapOfShape mapUniqEdg;
202       for (itFacToTreat.Initialize(LstFacToTreat); itFacToTreat.More(); itFacToTreat.Next()) {
203         const TopoDS_Shape& face = itFacToTreat.Value();
204         
205         //we build the resulting map with a face as a key and a list of internal (or external)
206         // edges to remove from the face.
207         if (!myMapFacLstEdg.IsBound(face)) {
208           TopTools_ListOfShape LmapEdg;
209           if (!mapUniqEdg.Contains(edgecur)) {
210             mapUniqEdg.Add(edgecur);
211             LmapEdg.Append(edgecur);
212             myMapFacLstEdg.Bind(face,LmapEdg);
213           }
214         }
215         else { // just append the edge to the list of edges of the face
216           TopTools_ListOfShape& LmapEdg = myMapFacLstEdg.ChangeFind(face);
217           if (!mapUniqEdg.Contains(edgecur)) {
218             mapUniqEdg.Add(edgecur);
219             LmapEdg.Append(edgecur);
220           }
221         } 
222         
223       }
224     }
225     
226   } 
227
228   myIsDone = Standard_True;
229
230 }
231
232
233
234 //=======================================================================
235 //function : Perform
236 //purpose  : 
237 //=======================================================================
238
239  void TopOpeBRepTool_PurgeInternalEdges::Perform() 
240 {
241
242   // if the list has not been yet built then do it
243   if (!myIsDone) {
244     BuildList();
245   }
246
247   // if we have at least on internal (or external) edge to remove
248   if (myMapFacLstEdg.Extent() > 0) {
249
250     TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itFacEdg;
251     TopTools_ListIteratorOfListOfShape itEdg;
252     TopTools_ListOfShape EmptyList;
253     BRepTools_Substitution Bsub;
254
255     for (itFacEdg.Initialize(myMapFacLstEdg); itFacEdg.More(); itFacEdg.Next()) {
256       const TopoDS_Shape& facecur = itFacEdg.Key();
257       const TopTools_ListOfShape& LmapEdg = myMapFacLstEdg.Find(facecur);
258       
259       for (itEdg.Initialize(LmapEdg); itEdg.More(); itEdg.Next()) {
260         Bsub.Substitute(itEdg.Value(),EmptyList);
261       }
262     }
263
264     Bsub.Build(myShape);
265     if (Bsub.IsCopied(myShape)) {
266       myShape=(Bsub.Copy(myShape)).First();
267     }
268   }
269 }
270
271