0023024: Update headers of OCCT files
[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       const TopTools_ListOfShape& aList1 = edgeNaborFaces.Find(anEdge1);
249       TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itr(edgeNaborFaces);
250       for (; itr.More(); itr.Next()) {
251         TopoDS_Shape anEdge2 = itr.Key();
252         if (anEdge1.IsSame(anEdge2)) continue;
253         const TopTools_ListOfShape& aList2 = itr.Value();
254         // compare lists of the neighbour faces of edge1 and edge2
255         if (aList1.Extent() == aList2.Extent()) {
256           Standard_Integer aMatches = 0;
257           for(TopTools_ListIteratorOfListOfShape aLIter1(aList1);aLIter1.More();aLIter1.Next())
258             for(TopTools_ListIteratorOfListOfShape aLIter2(aList2);aLIter2.More();aLIter2.Next())
259               if (aLIter1.Value().IsSame(aLIter2.Value())) aMatches++;
260           if (aMatches == aList1.Extent()) {
261             aC0=Standard_True;
262             TNaming_Builder bC0Edge(Tagger->NewChild());
263             bC0Edge.Generated(anEdge2);
264             edgeNaborFaces.UnBind(anEdge2);
265           }
266         }
267       }
268       edgeNaborFaces.UnBind(anEdge1);
269     }
270     if (aC0) {
271       TNaming_Builder bC0Edge(Tagger->NewChild());
272       bC0Edge.Generated(anEdge1);
273     }
274   }
275 }
276
277
278 //=======================================================================
279 //function : LoadC0Vertices
280 //purpose  : Method for internal use. It is used by Load() method.
281 //=======================================================================
282
283 void QANewBRepNaming_ImportShape::LoadC0Vertices(const TopoDS_Shape& S,
284                                             const Handle(TDF_TagSource)& Tagger) const 
285 {
286   TopTools_DataMapOfShapeListOfShape vertexNaborFaces;
287   TopTools_ListOfShape empty;
288   TopExp_Explorer explF(S, TopAbs_FACE);
289   for (; explF.More(); explF.Next()) {
290     const TopoDS_Shape& aFace = explF.Current();
291     TopExp_Explorer explV(aFace, TopAbs_VERTEX);
292     for (; explV.More(); explV.Next()) {
293       const TopoDS_Shape& aVertex = explV.Current();
294       if (!vertexNaborFaces.IsBound(aVertex)) vertexNaborFaces.Bind(aVertex, empty);
295       Standard_Boolean faceIsNew = Standard_True;
296       TopTools_ListIteratorOfListOfShape itrF(vertexNaborFaces.Find(aVertex));
297       for (; itrF.More(); itrF.Next()) {
298         if (itrF.Value().IsSame(aFace)) {
299           faceIsNew = Standard_False;
300           break;
301         }
302       }
303       if (faceIsNew) {
304         vertexNaborFaces.ChangeFind(aVertex).Append(aFace);
305       }
306     }
307   }
308
309   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itr(vertexNaborFaces);
310   for (; itr.More(); itr.Next()) {
311     const TopTools_ListOfShape& naborFaces = itr.Value();
312     if (naborFaces.Extent() < 3) {
313       TNaming_Builder bC0Vertex(Tagger->NewChild());
314       bC0Vertex.Generated(itr.Key());
315     }
316   }
317 }
318
319 //=======================================================================
320 //function : NamedFaces
321 //purpose  : Returns the labels of all the named faces. Returns the number of faces.
322 //=======================================================================
323
324 Standard_Integer QANewBRepNaming_ImportShape::NamedFaces(TDF_LabelMap& theNamedFaces) const {
325   theNamedFaces.Clear();
326   Handle(TNaming_NamedShape) aFace;
327   TDF_ChildIterator itr(ResultLabel());
328   for (; itr.More(); itr.Next()) {
329     if (itr.Value().FindAttribute(TNaming_NamedShape::GetID(), aFace) &&
330         !aFace->IsEmpty() && aFace->Get().ShapeType() == TopAbs_FACE)
331       theNamedFaces.Add(itr.Value());
332   }
333   return theNamedFaces.Extent();
334 }
335
336 //=======================================================================
337 //function : NamedEdges
338 //purpose  : Returns the labels of all the named free edges.
339 //           Returns the number of edges.
340 //=======================================================================
341
342 Standard_Integer QANewBRepNaming_ImportShape::NamedEdges(TDF_LabelMap& theNamedEdges) const {
343   theNamedEdges.Clear();
344   Handle(TNaming_NamedShape) anEdge;
345   TDF_ChildIterator itr(ResultLabel());
346   for (; itr.More(); itr.Next()) {
347     if (itr.Value().FindAttribute(TNaming_NamedShape::GetID(), anEdge) &&
348         !anEdge->IsEmpty() && anEdge->Get().ShapeType() == TopAbs_EDGE)
349       theNamedEdges.Add(itr.Value());
350   }
351   return theNamedEdges.Extent();
352 }
353
354 //=======================================================================
355 //function : NamedVertices
356 //purpose  : Returns the labels of all the named free vertices.
357 //           Returns the number of verices.
358 //=======================================================================
359
360 Standard_Integer QANewBRepNaming_ImportShape::NamedVertices(TDF_LabelMap& theNamedVertices) const {
361   theNamedVertices.Clear();
362   Handle(TNaming_NamedShape) aVertex;
363   TDF_ChildIterator itr(ResultLabel());
364   for (; itr.More(); itr.Next()) {
365     if (itr.Value().FindAttribute(TNaming_NamedShape::GetID(), aVertex) &&
366         !aVertex->IsEmpty() && aVertex->Get().ShapeType() == TopAbs_VERTEX)
367       theNamedVertices.Add(itr.Value());
368   }
369   return theNamedVertices.Extent();
370 }
371