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 |
49 | QANewBRepNaming_ImportShape::QANewBRepNaming_ImportShape() {} |
50 | |
51 | //======================================================================= |
52 | //function : QANewBRepNaming_ImportShape |
53 | //purpose : Constructor |
54 | //======================================================================= |
55 | |
56 | QANewBRepNaming_ImportShape::QANewBRepNaming_ImportShape(const TDF_Label& L):QANewBRepNaming_TopNaming(L) {} |
57 | |
58 | //======================================================================= |
59 | //function : Init |
60 | //purpose : Initialization |
61 | //======================================================================= |
62 | |
63 | void 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 | |
75 | void 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 | |
94 | void 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 | |
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); |
120 | } |
121 | } else LoadNextLevels(S, Tagger); |
122 | } |
123 | |
124 | //======================================================================= |
125 | //function : LoadNextLevels |
126 | //purpose : Method for internal use. Is used by LoadFirstLevel() |
127 | //======================================================================= |
128 | |
129 | void 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 | |
205 | void 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 | |
248 | void 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 | |
289 | Standard_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 | |
307 | Standard_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 | |
325 | Standard_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 | |