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