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