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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <BRepTools.hxx>
19 #include <QANewBRepNaming_ImportShape.hxx>
20 #include <QANewBRepNaming_LoaderParent.hxx>
21 #include <ShapeExtend_WireData.hxx>
22 #include <Standard_NullObject.hxx>
23 #include <TDF_ChildIterator.hxx>
24 #include <TDF_Label.hxx>
25 #include <TDF_LabelMap.hxx>
26 #include <TDF_TagSource.hxx>
27 #include <TNaming_Builder.hxx>
28 #include <TNaming_NamedShape.hxx>
30 #include <TopExp_Explorer.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>
43 #include <TopTools_ListOfShape.hxx>
45 //=======================================================================
46 //function : QANewBRepNaming_ImportShape
47 //purpose : Constructor
48 //=======================================================================
49 QANewBRepNaming_ImportShape::QANewBRepNaming_ImportShape() {}
51 //=======================================================================
52 //function : QANewBRepNaming_ImportShape
53 //purpose : Constructor
54 //=======================================================================
56 QANewBRepNaming_ImportShape::QANewBRepNaming_ImportShape(const TDF_Label& L):QANewBRepNaming_TopNaming(L) {}
58 //=======================================================================
60 //purpose : Initialization
61 //=======================================================================
63 void QANewBRepNaming_ImportShape::Init(const TDF_Label& Label) {
65 throw Standard_NullObject("QANewBRepNaming_ImportShape::Init The Result label is Null ...");
66 myResultLabel = Label;
69 //=======================================================================
71 //purpose : To load an ImportShape
72 // Use this method for a topological naming of an imported shape
73 //=======================================================================
75 void QANewBRepNaming_ImportShape::Load(const TopoDS_Shape& theShape) const {
76 ResultLabel().ForgetAllAttributes();
77 TNaming_Builder b(ResultLabel());
78 b.Generated(theShape);
80 Handle(TDF_TagSource) Tagger = TDF_TagSource::Set(ResultLabel());
81 if (Tagger.IsNull()) return;
84 LoadFirstLevel(theShape, Tagger);
85 LoadC0Edges(theShape, Tagger);
86 LoadC0Vertices(theShape, Tagger);
89 //=======================================================================
90 //function : LoadPrime
92 //=======================================================================
94 void QANewBRepNaming_ImportShape::LoadPrime(const TopoDS_Shape& theShape) const {
96 Handle(TDF_TagSource) Tagger = TDF_TagSource::Set(ResultLabel());
97 if (Tagger.IsNull()) return;
100 LoadFirstLevel(theShape, Tagger);
101 LoadC0Edges(theShape, Tagger);
102 LoadC0Vertices(theShape, Tagger);
105 //=======================================================================
106 //function : LoadFirstLevel
107 //purpose : Method for internal use. Is used by Load()
108 //=======================================================================
110 void 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);
121 } else LoadNextLevels(S, Tagger);
124 //=======================================================================
125 //function : LoadNextLevels
126 //purpose : Method for internal use. Is used by LoadFirstLevel()
127 //=======================================================================
129 void QANewBRepNaming_ImportShape::LoadNextLevels(const TopoDS_Shape& S,
130 const Handle(TDF_TagSource)& Tagger) const {
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());
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());
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));
157 TopTools_ListIteratorOfListOfShape anIter(aLL);
158 const TopoDS_Face aFace = TopoDS::Face(anIter.Value());
160 if(aFace.IsEqual(anIter.Value())) {
161 TNaming_Builder bFreeEdges(Tagger->NewChild());
162 bFreeEdges.Generated(anEdgeAndNeighbourFaces.FindKey(i));
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());
178 TopExp_Explorer expl(S, TopAbs_EDGE);
179 for (; expl.More(); expl.Next()) {
180 TNaming_Builder bEdge(Tagger->NewChild());
181 bEdge.Generated(expl.Current());
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);
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());
200 //=======================================================================
201 //function : LoadC0Edges
202 //purpose : Method for internal use. It is used by Load() method.
203 //=======================================================================
205 void QANewBRepNaming_ImportShape::LoadC0Edges(const TopoDS_Shape& S,
206 const Handle(TDF_TagSource)& Tagger) const
208 // vro: It sets vertices twicely:
209 // TopTools_IndexedDataMapOfShapeListOfShape vertexNaborFaces;
210 // TopExp::MapShapesAndAncestors(S, TopAbs_VERTEX, TopAbs_FACE, vertexNaborFaces);
211 TopTools_DataMapOfShapeListOfShape edgeNaborFaces;
212 TopTools_ListOfShape empty;
213 TopExp_Explorer explF(S, TopAbs_FACE);
214 for (; explF.More(); explF.Next()) {
215 const TopoDS_Shape& aFace = explF.Current();
216 TopExp_Explorer explV(aFace, TopAbs_EDGE);
217 for (; explV.More(); explV.Next()) {
218 const TopoDS_Shape& anEdge = explV.Current();
219 if (!edgeNaborFaces.IsBound(anEdge)) edgeNaborFaces.Bind(anEdge, empty);
220 Standard_Boolean faceIsNew = Standard_True;
221 TopTools_ListIteratorOfListOfShape itrF(edgeNaborFaces.Find(anEdge));
222 for (; itrF.More(); itrF.Next()) {
223 if (itrF.Value().IsSame(aFace)) {
224 faceIsNew = Standard_False;
229 edgeNaborFaces.ChangeFind(anEdge).Append(aFace);
234 TopExp_Explorer anEx(S,TopAbs_EDGE); // mpv: new explorer iterator becouse we need keep edges order
235 for(;anEx.More();anEx.Next()) {
236 Standard_Boolean aC0 = Standard_False;
237 TopoDS_Shape anEdge1 = anEx.Current();
238 if (edgeNaborFaces.IsBound(anEdge1)) {
239 TopTools_ListOfShape aEdgesToRemove; // record items to be removed from the map (should be done after iteration)
240 aEdgesToRemove.Append (anEdge1);
241 const TopTools_ListOfShape& aList1 = edgeNaborFaces.Find(anEdge1);
242 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itr(edgeNaborFaces);
243 for (; itr.More(); itr.Next()) {
244 TopoDS_Shape anEdge2 = itr.Key();
245 if (anEdge1.IsSame(anEdge2)) continue;
246 const TopTools_ListOfShape& aList2 = itr.Value();
247 // compare lists of the neighbour faces of edge1 and edge2
248 if (aList1.Extent() == aList2.Extent()) {
249 Standard_Integer aMatches = 0;
250 for(TopTools_ListIteratorOfListOfShape aLIter1(aList1);aLIter1.More();aLIter1.Next())
251 for(TopTools_ListIteratorOfListOfShape aLIter2(aList2);aLIter2.More();aLIter2.Next())
252 if (aLIter1.Value().IsSame(aLIter2.Value())) aMatches++;
253 if (aMatches == aList1.Extent()) {
255 TNaming_Builder bC0Edge(Tagger->NewChild());
256 bC0Edge.Generated(anEdge2);
257 aEdgesToRemove.Append (anEdge2);
261 // remove items from the data map
262 for(TopTools_ListIteratorOfListOfShape anIt(aEdgesToRemove); anIt.More(); anIt.Next())
263 edgeNaborFaces.UnBind(anIt.Value());
266 TNaming_Builder bC0Edge(Tagger->NewChild());
267 bC0Edge.Generated(anEdge1);
273 //=======================================================================
274 //function : LoadC0Vertices
275 //purpose : Method for internal use. It is used by Load() method.
276 //=======================================================================
278 void QANewBRepNaming_ImportShape::LoadC0Vertices(const TopoDS_Shape& S,
279 const Handle(TDF_TagSource)& Tagger) const
281 TopTools_DataMapOfShapeListOfShape vertexNaborFaces;
282 TopTools_ListOfShape empty;
283 TopExp_Explorer explF(S, TopAbs_FACE);
284 for (; explF.More(); explF.Next()) {
285 const TopoDS_Shape& aFace = explF.Current();
286 TopExp_Explorer explV(aFace, TopAbs_VERTEX);
287 for (; explV.More(); explV.Next()) {
288 const TopoDS_Shape& aVertex = explV.Current();
289 if (!vertexNaborFaces.IsBound(aVertex)) vertexNaborFaces.Bind(aVertex, empty);
290 Standard_Boolean faceIsNew = Standard_True;
291 TopTools_ListIteratorOfListOfShape itrF(vertexNaborFaces.Find(aVertex));
292 for (; itrF.More(); itrF.Next()) {
293 if (itrF.Value().IsSame(aFace)) {
294 faceIsNew = Standard_False;
299 vertexNaborFaces.ChangeFind(aVertex).Append(aFace);
304 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itr(vertexNaborFaces);
305 for (; itr.More(); itr.Next()) {
306 const TopTools_ListOfShape& naborFaces = itr.Value();
307 if (naborFaces.Extent() < 3) {
308 TNaming_Builder bC0Vertex(Tagger->NewChild());
309 bC0Vertex.Generated(itr.Key());
314 //=======================================================================
315 //function : NamedFaces
316 //purpose : Returns the labels of all the named faces. Returns the number of faces.
317 //=======================================================================
319 Standard_Integer QANewBRepNaming_ImportShape::NamedFaces(TDF_LabelMap& theNamedFaces) const {
320 theNamedFaces.Clear();
321 Handle(TNaming_NamedShape) aFace;
322 TDF_ChildIterator itr(ResultLabel());
323 for (; itr.More(); itr.Next()) {
324 if (itr.Value().FindAttribute(TNaming_NamedShape::GetID(), aFace) &&
325 !aFace->IsEmpty() && aFace->Get().ShapeType() == TopAbs_FACE)
326 theNamedFaces.Add(itr.Value());
328 return theNamedFaces.Extent();
331 //=======================================================================
332 //function : NamedEdges
333 //purpose : Returns the labels of all the named free edges.
334 // Returns the number of edges.
335 //=======================================================================
337 Standard_Integer QANewBRepNaming_ImportShape::NamedEdges(TDF_LabelMap& theNamedEdges) const {
338 theNamedEdges.Clear();
339 Handle(TNaming_NamedShape) anEdge;
340 TDF_ChildIterator itr(ResultLabel());
341 for (; itr.More(); itr.Next()) {
342 if (itr.Value().FindAttribute(TNaming_NamedShape::GetID(), anEdge) &&
343 !anEdge->IsEmpty() && anEdge->Get().ShapeType() == TopAbs_EDGE)
344 theNamedEdges.Add(itr.Value());
346 return theNamedEdges.Extent();
349 //=======================================================================
350 //function : NamedVertices
351 //purpose : Returns the labels of all the named free vertices.
352 // Returns the number of verices.
353 //=======================================================================
355 Standard_Integer QANewBRepNaming_ImportShape::NamedVertices(TDF_LabelMap& theNamedVertices) const {
356 theNamedVertices.Clear();
357 Handle(TNaming_NamedShape) aVertex;
358 TDF_ChildIterator itr(ResultLabel());
359 for (; itr.More(); itr.Next()) {
360 if (itr.Value().FindAttribute(TNaming_NamedShape::GetID(), aVertex) &&
361 !aVertex->IsEmpty() && aVertex->Get().ShapeType() == TopAbs_VERTEX)
362 theNamedVertices.Add(itr.Value());
364 return theNamedVertices.Extent();