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.
17 #include <QANewBRepNaming_ImportShape.ixx>
19 #include <Standard_NullObject.hxx>
20 #include <BRepTools.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>
29 #include <TopExp_Explorer.hxx>
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>
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 //=======================================================================
52 QANewBRepNaming_ImportShape::QANewBRepNaming_ImportShape() {}
54 //=======================================================================
55 //function : QANewBRepNaming_ImportShape
56 //purpose : Constructor
57 //=======================================================================
59 QANewBRepNaming_ImportShape::QANewBRepNaming_ImportShape(const TDF_Label& L):QANewBRepNaming_TopNaming(L) {}
61 //=======================================================================
63 //purpose : Initialization
64 //=======================================================================
66 void QANewBRepNaming_ImportShape::Init(const TDF_Label& Label) {
68 Standard_NullObject::Raise("QANewBRepNaming_ImportShape::Init The Result label is Null ...");
69 myResultLabel = Label;
72 //=======================================================================
74 //purpose : To load an ImportShape
75 // Use this method for a topological naming of an imported shape
76 //=======================================================================
78 void QANewBRepNaming_ImportShape::Load(const TopoDS_Shape& theShape) const {
79 ResultLabel().ForgetAllAttributes();
80 TNaming_Builder b(ResultLabel());
81 b.Generated(theShape);
83 Handle(TDF_TagSource) Tagger = TDF_TagSource::Set(ResultLabel());
84 if (Tagger.IsNull()) return;
87 LoadFirstLevel(theShape, Tagger);
88 LoadC0Edges(theShape, Tagger);
89 LoadC0Vertices(theShape, Tagger);
92 //=======================================================================
93 //function : LoadPrime
95 //=======================================================================
97 void QANewBRepNaming_ImportShape::LoadPrime(const TopoDS_Shape& theShape) const {
99 Handle(TDF_TagSource) Tagger = TDF_TagSource::Set(ResultLabel());
100 if (Tagger.IsNull()) return;
103 LoadFirstLevel(theShape, Tagger);
104 LoadC0Edges(theShape, Tagger);
105 LoadC0Vertices(theShape, Tagger);
108 //=======================================================================
109 //function : LoadFirstLevel
110 //purpose : Method for internal use. Is used by Load()
111 //=======================================================================
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);
124 } else LoadNextLevels(S, Tagger);
127 //=======================================================================
128 //function : LoadNextLevels
129 //purpose : Method for internal use. Is used by LoadFirstLevel()
130 //=======================================================================
132 void QANewBRepNaming_ImportShape::LoadNextLevels(const TopoDS_Shape& S,
133 const Handle(TDF_TagSource)& Tagger) const {
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());
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());
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));
160 TopTools_ListIteratorOfListOfShape anIter(aLL);
161 const TopoDS_Face aFace = TopoDS::Face(anIter.Value());
163 if(aFace.IsEqual(anIter.Value())) {
164 TNaming_Builder bFreeEdges(Tagger->NewChild());
165 bFreeEdges.Generated(anEdgeAndNeighbourFaces.FindKey(i));
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());
181 TopExp_Explorer expl(S, TopAbs_EDGE);
182 for (; expl.More(); expl.Next()) {
183 TNaming_Builder bEdge(Tagger->NewChild());
184 bEdge.Generated(expl.Current());
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);
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());
203 //=======================================================================
204 //function : LoadC0Edges
205 //purpose : Method for internal use. It is used by Load() method.
206 //=======================================================================
208 void QANewBRepNaming_ImportShape::LoadC0Edges(const TopoDS_Shape& S,
209 const Handle(TDF_TagSource)& Tagger) const
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;
232 edgeNaborFaces.ChangeFind(anEdge).Append(aFace);
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()) {
258 TNaming_Builder bC0Edge(Tagger->NewChild());
259 bC0Edge.Generated(anEdge2);
260 aEdgesToRemove.Append (anEdge2);
264 // remove items from the data map
265 for(TopTools_ListIteratorOfListOfShape anIt(aEdgesToRemove); anIt.More(); anIt.Next())
266 edgeNaborFaces.UnBind(anIt.Value());
269 TNaming_Builder bC0Edge(Tagger->NewChild());
270 bC0Edge.Generated(anEdge1);
276 //=======================================================================
277 //function : LoadC0Vertices
278 //purpose : Method for internal use. It is used by Load() method.
279 //=======================================================================
281 void QANewBRepNaming_ImportShape::LoadC0Vertices(const TopoDS_Shape& S,
282 const Handle(TDF_TagSource)& Tagger) const
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;
302 vertexNaborFaces.ChangeFind(aVertex).Append(aFace);
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());
317 //=======================================================================
318 //function : NamedFaces
319 //purpose : Returns the labels of all the named faces. Returns the number of faces.
320 //=======================================================================
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());
331 return theNamedFaces.Extent();
334 //=======================================================================
335 //function : NamedEdges
336 //purpose : Returns the labels of all the named free edges.
337 // Returns the number of edges.
338 //=======================================================================
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());
349 return theNamedEdges.Extent();
352 //=======================================================================
353 //function : NamedVertices
354 //purpose : Returns the labels of all the named free vertices.
355 // Returns the number of verices.
356 //=======================================================================
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());
367 return theNamedVertices.Extent();