0026937: Eliminate NO_CXX_EXCEPTION macro support
[occt.git] / src / QANewBRepNaming / QANewBRepNaming_ImportShape.cxx
1 // Created on: 1999-10-05
2 // Created by: Vladislav ROMASHKO
3 // Copyright (c) 1999-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.hxx>
19 #include <QANewBRepNaming_ImportShape.hxx>
20 #include <QANewBRepNaming_LoaderParent.hxx>
21 #include <ShapeExtend_WireData.hxx>
22 #include <Standard_NullObject.hxx>
23 #include <TDF_ChildIterator.hxx>
24 #include <TDF_Label.hxx>
25 #include <TDF_LabelMap.hxx>
26 #include <TDF_TagSource.hxx>
27 #include <TNaming_Builder.hxx>
28 #include <TNaming_NamedShape.hxx>
29 #include <TopExp.hxx>
30 #include <TopExp_Explorer.hxx>
31 #include <TopoDS.hxx>
32 #include <TopoDS_Edge.hxx>
33 #include <TopoDS_Face.hxx>
34 #include <TopoDS_Iterator.hxx>
35 #include <TopoDS_Shape.hxx>
36 #include <TopoDS_Wire.hxx>
37 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
38 #include <TopTools_DataMapOfShapeListOfShape.hxx>
39 #include <TopTools_DataMapOfShapeShape.hxx>
40 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
41 #include <TopTools_IndexedMapOfShape.hxx>
42 #include <TopTools_ListIteratorOfListOfShape.hxx>
43 #include <TopTools_ListOfShape.hxx>
44
45 //=======================================================================
46 //function : QANewBRepNaming_ImportShape
47 //purpose  : Constructor
48 //=======================================================================
49 QANewBRepNaming_ImportShape::QANewBRepNaming_ImportShape() {}
50
51 //=======================================================================
52 //function : QANewBRepNaming_ImportShape
53 //purpose  : Constructor
54 //=======================================================================
55
56 QANewBRepNaming_ImportShape::QANewBRepNaming_ImportShape(const TDF_Label& L):QANewBRepNaming_TopNaming(L) {}
57
58 //=======================================================================
59 //function : Init
60 //purpose  : Initialization
61 //=======================================================================
62
63 void QANewBRepNaming_ImportShape::Init(const TDF_Label& Label) {
64   if(Label.IsNull()) 
65     throw Standard_NullObject("QANewBRepNaming_ImportShape::Init The Result label is Null ...");
66   myResultLabel = Label;
67 }  
68
69 //=======================================================================
70 //function : Load
71 //purpose  : To load an ImportShape
72 //           Use this method for a topological naming of an imported shape
73 //=======================================================================
74
75 void QANewBRepNaming_ImportShape::Load(const TopoDS_Shape& theShape) const {
76   ResultLabel().ForgetAllAttributes();
77   TNaming_Builder b(ResultLabel());
78   b.Generated(theShape);
79
80   Handle(TDF_TagSource) Tagger = TDF_TagSource::Set(ResultLabel());
81   if (Tagger.IsNull()) return;
82   Tagger->Set(0);
83
84   LoadFirstLevel(theShape, Tagger);
85   LoadC0Edges(theShape, Tagger);
86   LoadC0Vertices(theShape, Tagger);
87 }  
88
89 //=======================================================================
90 //function : LoadPrime
91 //purpose  : 
92 //=======================================================================
93
94 void QANewBRepNaming_ImportShape::LoadPrime(const TopoDS_Shape& theShape) const {
95
96   Handle(TDF_TagSource) Tagger = TDF_TagSource::Set(ResultLabel());
97   if (Tagger.IsNull()) return;
98   Tagger->Set(0);
99
100   LoadFirstLevel(theShape, Tagger);
101   LoadC0Edges(theShape, Tagger);
102   LoadC0Vertices(theShape, Tagger);
103 }  
104     
105 //=======================================================================
106 //function : LoadFirstLevel
107 //purpose  : Method for internal use. Is used by Load()
108 //=======================================================================
109
110 void QANewBRepNaming_ImportShape::LoadFirstLevel(const TopoDS_Shape& S,
111                                             const Handle(TDF_TagSource)& Tagger) const {
112   if (S.ShapeType() == TopAbs_COMPOUND || S.ShapeType() == TopAbs_COMPSOLID) {
113     TopoDS_Iterator itr(S);
114     for (; itr.More(); itr.Next()) {
115       TNaming_Builder bIndependantShapes(Tagger->NewChild());
116       bIndependantShapes.Generated(itr.Value());
117       if (itr.Value().ShapeType() == TopAbs_COMPOUND || itr.Value().ShapeType() == TopAbs_COMPSOLID) {
118         LoadFirstLevel(itr.Value(), Tagger);
119       } else LoadNextLevels(itr.Value(), Tagger);
120     }
121   } else LoadNextLevels(S, Tagger); 
122
123
124 //=======================================================================
125 //function : LoadNextLevels
126 //purpose  : Method for internal use. Is used by LoadFirstLevel()
127 //=======================================================================
128
129 void QANewBRepNaming_ImportShape::LoadNextLevels(const TopoDS_Shape& S,
130                                             const Handle(TDF_TagSource)& Tagger) const {
131
132   if (S.ShapeType() == TopAbs_SOLID) {              
133     TopExp_Explorer expl(S, TopAbs_FACE);
134     for (; expl.More(); expl.Next()) {
135       TNaming_Builder bFace(Tagger->NewChild());
136       bFace.Generated(expl.Current());
137     }
138   } else if (S.ShapeType() == TopAbs_SHELL || S.ShapeType() == TopAbs_FACE) {
139     // load faces and all the free edges
140     TopTools_IndexedMapOfShape Faces;
141     TopExp::MapShapes(S, TopAbs_FACE, Faces);
142     if (Faces.Extent() > 1 || (S.ShapeType() == TopAbs_SHELL && Faces.Extent() == 1)) {
143       TopExp_Explorer expl(S, TopAbs_FACE);
144       for (; expl.More(); expl.Next()) {
145         TNaming_Builder bFace(Tagger->NewChild());
146         bFace.Generated(expl.Current());
147       }
148     }
149     TopTools_IndexedDataMapOfShapeListOfShape anEdgeAndNeighbourFaces;
150     TopExp::MapShapesAndAncestors(S, TopAbs_EDGE, TopAbs_FACE, anEdgeAndNeighbourFaces);
151     for (Standard_Integer i = 1; i <= anEdgeAndNeighbourFaces.Extent(); i++) {
152       const TopTools_ListOfShape& aLL = anEdgeAndNeighbourFaces.FindFromIndex(i);
153       if (aLL.Extent() < 2) {
154         TNaming_Builder bFreeEdges(Tagger->NewChild());
155         bFreeEdges.Generated(anEdgeAndNeighbourFaces.FindKey(i));
156       } else {
157         TopTools_ListIteratorOfListOfShape anIter(aLL);
158         const TopoDS_Face aFace = TopoDS::Face(anIter.Value());
159         anIter.Next();
160         if(aFace.IsEqual(anIter.Value())) {
161           TNaming_Builder bFreeEdges(Tagger->NewChild());
162           bFreeEdges.Generated(anEdgeAndNeighbourFaces.FindKey(i));
163         }
164       }
165     }
166   } else if (S.ShapeType() == TopAbs_WIRE) {
167     TopTools_IndexedMapOfShape Edges;
168     BRepTools::Map3DEdges(S, Edges);
169     if (Edges.Extent() == 1) {
170       TNaming_Builder bEdge(Tagger->NewChild());
171       bEdge.Generated(Edges.FindKey(1));
172       TopExp_Explorer expl(S, TopAbs_VERTEX);
173       for (; expl.More(); expl.Next()) {
174         TNaming_Builder bVertex(Tagger->NewChild());
175         bVertex.Generated(expl.Current());    
176       }
177     } else {
178       TopExp_Explorer expl(S, TopAbs_EDGE); 
179       for (; expl.More(); expl.Next()) {
180         TNaming_Builder bEdge(Tagger->NewChild());
181         bEdge.Generated(expl.Current());
182       }   
183       // and load generated vertices.
184       TopTools_DataMapOfShapeShape generated;
185       if (QANewBRepNaming_LoaderParent::GetDangleShapes(S, TopAbs_EDGE, generated)) {
186         TNaming_Builder bGenVertices(Tagger->NewChild());
187         QANewBRepNaming_LoaderParent::LoadGeneratedDangleShapes(S, TopAbs_EDGE, bGenVertices);
188       }
189     }
190   } else if (S.ShapeType() == TopAbs_EDGE) {
191     TopExp_Explorer expl(S, TopAbs_VERTEX);
192     for (; expl.More(); expl.Next()) {
193       TNaming_Builder bVertex(Tagger->NewChild());
194       bVertex.Generated(expl.Current());    
195     }
196   }
197 }
198
199
200 //=======================================================================
201 //function : LoadC0Edges
202 //purpose  : Method for internal use. It is used by Load() method.
203 //=======================================================================
204
205 void QANewBRepNaming_ImportShape::LoadC0Edges(const TopoDS_Shape& S,
206                                               const Handle(TDF_TagSource)& Tagger) const 
207 {
208 // vro: It sets vertices twicely:
209 //   TopTools_IndexedDataMapOfShapeListOfShape vertexNaborFaces;
210 //   TopExp::MapShapesAndAncestors(S, TopAbs_VERTEX, TopAbs_FACE, vertexNaborFaces);
211   TopTools_DataMapOfShapeListOfShape edgeNaborFaces;
212   TopTools_ListOfShape empty;
213   TopExp_Explorer explF(S, TopAbs_FACE);
214   for (; explF.More(); explF.Next()) {
215     const TopoDS_Shape& aFace = explF.Current();
216     TopExp_Explorer explV(aFace, TopAbs_EDGE);
217     for (; explV.More(); explV.Next()) {
218       const TopoDS_Shape& anEdge = explV.Current();
219       if (!edgeNaborFaces.IsBound(anEdge)) edgeNaborFaces.Bind(anEdge, empty);
220       Standard_Boolean faceIsNew = Standard_True;
221       TopTools_ListIteratorOfListOfShape itrF(edgeNaborFaces.Find(anEdge));
222       for (; itrF.More(); itrF.Next()) {
223         if (itrF.Value().IsSame(aFace)) {
224           faceIsNew = Standard_False;
225           break;
226         }
227       }
228       if (faceIsNew) {
229         edgeNaborFaces.ChangeFind(anEdge).Append(aFace);
230       }
231     }
232   }
233   
234   TopExp_Explorer anEx(S,TopAbs_EDGE); // mpv: new explorer iterator becouse we need keep edges order
235   for(;anEx.More();anEx.Next()) {
236     Standard_Boolean aC0 = Standard_False;
237     TopoDS_Shape anEdge1 = anEx.Current();
238     if (edgeNaborFaces.IsBound(anEdge1)) {
239       TopTools_ListOfShape aEdgesToRemove; // record items to be removed from the map (should be done after iteration)
240       aEdgesToRemove.Append (anEdge1);
241       const TopTools_ListOfShape& aList1 = edgeNaborFaces.Find(anEdge1);
242       TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itr(edgeNaborFaces);
243       for (; itr.More(); itr.Next()) {
244         TopoDS_Shape anEdge2 = itr.Key();
245         if (anEdge1.IsSame(anEdge2)) continue;
246         const TopTools_ListOfShape& aList2 = itr.Value();
247         // compare lists of the neighbour faces of edge1 and edge2
248         if (aList1.Extent() == aList2.Extent()) {
249           Standard_Integer aMatches = 0;
250           for(TopTools_ListIteratorOfListOfShape aLIter1(aList1);aLIter1.More();aLIter1.Next())
251             for(TopTools_ListIteratorOfListOfShape aLIter2(aList2);aLIter2.More();aLIter2.Next())
252               if (aLIter1.Value().IsSame(aLIter2.Value())) aMatches++;
253           if (aMatches == aList1.Extent()) {
254             aC0=Standard_True;
255             TNaming_Builder bC0Edge(Tagger->NewChild());
256             bC0Edge.Generated(anEdge2);
257             aEdgesToRemove.Append (anEdge2);
258           }
259         }
260       }
261       // remove items from the data map
262       for(TopTools_ListIteratorOfListOfShape anIt(aEdgesToRemove); anIt.More(); anIt.Next())
263         edgeNaborFaces.UnBind(anIt.Value());
264       }
265     if (aC0) {
266       TNaming_Builder bC0Edge(Tagger->NewChild());
267       bC0Edge.Generated(anEdge1);
268     }
269   }
270 }
271
272
273 //=======================================================================
274 //function : LoadC0Vertices
275 //purpose  : Method for internal use. It is used by Load() method.
276 //=======================================================================
277
278 void QANewBRepNaming_ImportShape::LoadC0Vertices(const TopoDS_Shape& S,
279                                             const Handle(TDF_TagSource)& Tagger) const 
280 {
281   TopTools_DataMapOfShapeListOfShape vertexNaborFaces;
282   TopTools_ListOfShape empty;
283   TopExp_Explorer explF(S, TopAbs_FACE);
284   for (; explF.More(); explF.Next()) {
285     const TopoDS_Shape& aFace = explF.Current();
286     TopExp_Explorer explV(aFace, TopAbs_VERTEX);
287     for (; explV.More(); explV.Next()) {
288       const TopoDS_Shape& aVertex = explV.Current();
289       if (!vertexNaborFaces.IsBound(aVertex)) vertexNaborFaces.Bind(aVertex, empty);
290       Standard_Boolean faceIsNew = Standard_True;
291       TopTools_ListIteratorOfListOfShape itrF(vertexNaborFaces.Find(aVertex));
292       for (; itrF.More(); itrF.Next()) {
293         if (itrF.Value().IsSame(aFace)) {
294           faceIsNew = Standard_False;
295           break;
296         }
297       }
298       if (faceIsNew) {
299         vertexNaborFaces.ChangeFind(aVertex).Append(aFace);
300       }
301     }
302   }
303
304   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itr(vertexNaborFaces);
305   for (; itr.More(); itr.Next()) {
306     const TopTools_ListOfShape& naborFaces = itr.Value();
307     if (naborFaces.Extent() < 3) {
308       TNaming_Builder bC0Vertex(Tagger->NewChild());
309       bC0Vertex.Generated(itr.Key());
310     }
311   }
312 }
313
314 //=======================================================================
315 //function : NamedFaces
316 //purpose  : Returns the labels of all the named faces. Returns the number of faces.
317 //=======================================================================
318
319 Standard_Integer QANewBRepNaming_ImportShape::NamedFaces(TDF_LabelMap& theNamedFaces) const {
320   theNamedFaces.Clear();
321   Handle(TNaming_NamedShape) aFace;
322   TDF_ChildIterator itr(ResultLabel());
323   for (; itr.More(); itr.Next()) {
324     if (itr.Value().FindAttribute(TNaming_NamedShape::GetID(), aFace) &&
325         !aFace->IsEmpty() && aFace->Get().ShapeType() == TopAbs_FACE)
326       theNamedFaces.Add(itr.Value());
327   }
328   return theNamedFaces.Extent();
329 }
330
331 //=======================================================================
332 //function : NamedEdges
333 //purpose  : Returns the labels of all the named free edges.
334 //           Returns the number of edges.
335 //=======================================================================
336
337 Standard_Integer QANewBRepNaming_ImportShape::NamedEdges(TDF_LabelMap& theNamedEdges) const {
338   theNamedEdges.Clear();
339   Handle(TNaming_NamedShape) anEdge;
340   TDF_ChildIterator itr(ResultLabel());
341   for (; itr.More(); itr.Next()) {
342     if (itr.Value().FindAttribute(TNaming_NamedShape::GetID(), anEdge) &&
343         !anEdge->IsEmpty() && anEdge->Get().ShapeType() == TopAbs_EDGE)
344       theNamedEdges.Add(itr.Value());
345   }
346   return theNamedEdges.Extent();
347 }
348
349 //=======================================================================
350 //function : NamedVertices
351 //purpose  : Returns the labels of all the named free vertices.
352 //           Returns the number of verices.
353 //=======================================================================
354
355 Standard_Integer QANewBRepNaming_ImportShape::NamedVertices(TDF_LabelMap& theNamedVertices) const {
356   theNamedVertices.Clear();
357   Handle(TNaming_NamedShape) aVertex;
358   TDF_ChildIterator itr(ResultLabel());
359   for (; itr.More(); itr.Next()) {
360     if (itr.Value().FindAttribute(TNaming_NamedShape::GetID(), aVertex) &&
361         !aVertex->IsEmpty() && aVertex->Get().ShapeType() == TopAbs_VERTEX)
362       theNamedVertices.Add(itr.Value());
363   }
364   return theNamedVertices.Extent();
365 }
366