0026682: TopExp::MapShapesAndAncestors() will build map with duplicated ancestors.
[occt.git] / src / QANewBRepNaming / QANewBRepNaming_ImportShape.cxx
CommitLineData
b311480e 1// Created on: 1999-10-05
2// Created by: Vladislav ROMASHKO
3// Copyright (c) 1999-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
7fd59977 17
7fd59977 18#include <BRepTools.hxx>
42cf5bc1 19#include <QANewBRepNaming_ImportShape.hxx>
20#include <QANewBRepNaming_LoaderParent.hxx>
7fd59977 21#include <ShapeExtend_WireData.hxx>
42cf5bc1 22#include <Standard_NullObject.hxx>
23#include <TDF_ChildIterator.hxx>
7fd59977 24#include <TDF_Label.hxx>
25#include <TDF_LabelMap.hxx>
26#include <TDF_TagSource.hxx>
7fd59977 27#include <TNaming_Builder.hxx>
28#include <TNaming_NamedShape.hxx>
42cf5bc1 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>
f1191d30 43#include <TopTools_MapOfShape.hxx>
42cf5bc1 44
7fd59977 45//=======================================================================
46//function : QANewBRepNaming_ImportShape
47//purpose : Constructor
48//=======================================================================
7fd59977 49QANewBRepNaming_ImportShape::QANewBRepNaming_ImportShape() {}
50
51//=======================================================================
52//function : QANewBRepNaming_ImportShape
53//purpose : Constructor
54//=======================================================================
55
56QANewBRepNaming_ImportShape::QANewBRepNaming_ImportShape(const TDF_Label& L):QANewBRepNaming_TopNaming(L) {}
57
58//=======================================================================
59//function : Init
60//purpose : Initialization
61//=======================================================================
62
63void QANewBRepNaming_ImportShape::Init(const TDF_Label& Label) {
64 if(Label.IsNull())
9775fa61 65 throw Standard_NullObject("QANewBRepNaming_ImportShape::Init The Result label is Null ...");
7fd59977 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
75void 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
94void 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
110void 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
129void 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
205void QANewBRepNaming_ImportShape::LoadC0Edges(const TopoDS_Shape& S,
206 const Handle(TDF_TagSource)& Tagger) const
207{
f1191d30 208 TopTools_IndexedDataMapOfShapeListOfShape edgeNaborFaces;
209 TopExp::MapShapesAndUniqueAncestors(S, TopAbs_EDGE, TopAbs_FACE, edgeNaborFaces);
7fd59977 210
f1191d30 211 TopTools_MapOfShape aEdgesToRemove;
212 for(Standard_Integer i = 1; i <= edgeNaborFaces.Extent(); i++) {
7fd59977 213 Standard_Boolean aC0 = Standard_False;
f1191d30 214 TopoDS_Shape anEdge1 = edgeNaborFaces.FindKey(i);
215 if (aEdgesToRemove.Add(anEdge1)) {
216 const TopTools_ListOfShape& aList1 = edgeNaborFaces.FindFromIndex(i);
217 for(Standard_Integer j = i + 1; j <= edgeNaborFaces.Extent(); j++) {
218 TopoDS_Shape anEdge2 = edgeNaborFaces.FindKey(j);
219 const TopTools_ListOfShape& aList2 = edgeNaborFaces.FindFromIndex(j);
4e57c75e 220 // compare lists of the neighbour faces of edge1 and edge2
221 if (aList1.Extent() == aList2.Extent()) {
222 Standard_Integer aMatches = 0;
223 for(TopTools_ListIteratorOfListOfShape aLIter1(aList1);aLIter1.More();aLIter1.Next())
224 for(TopTools_ListIteratorOfListOfShape aLIter2(aList2);aLIter2.More();aLIter2.Next())
225 if (aLIter1.Value().IsSame(aLIter2.Value())) aMatches++;
226 if (aMatches == aList1.Extent()) {
227 aC0=Standard_True;
228 TNaming_Builder bC0Edge(Tagger->NewChild());
229 bC0Edge.Generated(anEdge2);
f1191d30 230 aEdgesToRemove.Add(anEdge2);
4e57c75e 231 }
232 }
7fd59977 233 }
f1191d30 234 }
7fd59977 235 if (aC0) {
236 TNaming_Builder bC0Edge(Tagger->NewChild());
237 bC0Edge.Generated(anEdge1);
238 }
239 }
240}
241
242
243//=======================================================================
244//function : LoadC0Vertices
245//purpose : Method for internal use. It is used by Load() method.
246//=======================================================================
247
248void QANewBRepNaming_ImportShape::LoadC0Vertices(const TopoDS_Shape& S,
249 const Handle(TDF_TagSource)& Tagger) const
250{
251 TopTools_DataMapOfShapeListOfShape vertexNaborFaces;
252 TopTools_ListOfShape empty;
253 TopExp_Explorer explF(S, TopAbs_FACE);
254 for (; explF.More(); explF.Next()) {
255 const TopoDS_Shape& aFace = explF.Current();
256 TopExp_Explorer explV(aFace, TopAbs_VERTEX);
257 for (; explV.More(); explV.Next()) {
258 const TopoDS_Shape& aVertex = explV.Current();
259 if (!vertexNaborFaces.IsBound(aVertex)) vertexNaborFaces.Bind(aVertex, empty);
260 Standard_Boolean faceIsNew = Standard_True;
261 TopTools_ListIteratorOfListOfShape itrF(vertexNaborFaces.Find(aVertex));
262 for (; itrF.More(); itrF.Next()) {
263 if (itrF.Value().IsSame(aFace)) {
264 faceIsNew = Standard_False;
265 break;
266 }
267 }
268 if (faceIsNew) {
269 vertexNaborFaces.ChangeFind(aVertex).Append(aFace);
270 }
271 }
272 }
273
274 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itr(vertexNaborFaces);
275 for (; itr.More(); itr.Next()) {
276 const TopTools_ListOfShape& naborFaces = itr.Value();
277 if (naborFaces.Extent() < 3) {
278 TNaming_Builder bC0Vertex(Tagger->NewChild());
279 bC0Vertex.Generated(itr.Key());
280 }
281 }
282}
283
284//=======================================================================
285//function : NamedFaces
286//purpose : Returns the labels of all the named faces. Returns the number of faces.
287//=======================================================================
288
289Standard_Integer QANewBRepNaming_ImportShape::NamedFaces(TDF_LabelMap& theNamedFaces) const {
290 theNamedFaces.Clear();
291 Handle(TNaming_NamedShape) aFace;
292 TDF_ChildIterator itr(ResultLabel());
293 for (; itr.More(); itr.Next()) {
294 if (itr.Value().FindAttribute(TNaming_NamedShape::GetID(), aFace) &&
295 !aFace->IsEmpty() && aFace->Get().ShapeType() == TopAbs_FACE)
296 theNamedFaces.Add(itr.Value());
297 }
298 return theNamedFaces.Extent();
299}
300
301//=======================================================================
302//function : NamedEdges
303//purpose : Returns the labels of all the named free edges.
304// Returns the number of edges.
305//=======================================================================
306
307Standard_Integer QANewBRepNaming_ImportShape::NamedEdges(TDF_LabelMap& theNamedEdges) const {
308 theNamedEdges.Clear();
309 Handle(TNaming_NamedShape) anEdge;
310 TDF_ChildIterator itr(ResultLabel());
311 for (; itr.More(); itr.Next()) {
312 if (itr.Value().FindAttribute(TNaming_NamedShape::GetID(), anEdge) &&
313 !anEdge->IsEmpty() && anEdge->Get().ShapeType() == TopAbs_EDGE)
314 theNamedEdges.Add(itr.Value());
315 }
316 return theNamedEdges.Extent();
317}
318
319//=======================================================================
320//function : NamedVertices
321//purpose : Returns the labels of all the named free vertices.
322// Returns the number of verices.
323//=======================================================================
324
325Standard_Integer QANewBRepNaming_ImportShape::NamedVertices(TDF_LabelMap& theNamedVertices) const {
326 theNamedVertices.Clear();
327 Handle(TNaming_NamedShape) aVertex;
328 TDF_ChildIterator itr(ResultLabel());
329 for (; itr.More(); itr.Next()) {
330 if (itr.Value().FindAttribute(TNaming_NamedShape::GetID(), aVertex) &&
331 !aVertex->IsEmpty() && aVertex->Get().ShapeType() == TopAbs_VERTEX)
332 theNamedVertices.Add(itr.Value());
333 }
334 return theNamedVertices.Extent();
335}
336