b311480e |
1 | // Created on: 1998-11-19 |
2 | // Created by: Jean-Michel BOULCOURT |
3 | // Copyright (c) 1998-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
16 | |
7fd59977 |
17 | |
42cf5bc1 |
18 | #include <BRepTools_Substitution.hxx> |
19 | #include <Standard_ConstructionError.hxx> |
20 | #include <Standard_NullObject.hxx> |
7fd59977 |
21 | #include <TopExp.hxx> |
22 | #include <TopExp_Explorer.hxx> |
7fd59977 |
23 | #include <TopoDS.hxx> |
42cf5bc1 |
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> |
7fd59977 |
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 | //======================================================================= |
7fd59977 |
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 | // Standard_ConstructionError::Raise("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 | |
487bf1ce |
70 | Standard_Integer TopOpeBRepTool_PurgeInternalEdges::NbEdges() const |
7fd59977 |
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 | |