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