b311480e |
1 | // Created on: 1997-01-09 |
2 | // Created by: VAUTHIER Jean-Claude & Fricaud Yves |
3 | // Copyright (c) 1997-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 | |
17 | #include <DNaming.ixx> |
18 | |
19 | #include <DDF.hxx> |
20 | #include <DDF_Data.hxx> |
21 | #include <Draw.hxx> |
22 | #include <TColStd_HArray1OfInteger.hxx> |
23 | #include <TColStd_ListIteratorOfListOfInteger.hxx> |
24 | #include <TColStd_ListOfInteger.hxx> |
25 | #include <TCollection_AsciiString.hxx> |
26 | #include <TDF_ChildIterator.hxx> |
27 | #include <TDF_LabelList.hxx> |
28 | #include <TDF_LabelMap.hxx> |
29 | #include <TDF_Tool.hxx> |
30 | #include <TDF_TagSource.hxx> |
31 | #include <TNaming_Iterator.hxx> |
32 | #include <TNaming_Tool.hxx> |
33 | #include <TNaming_NamedShape.hxx> |
34 | #include <TNaming_Builder.hxx> |
35 | #include <TopTools_ListOfShape.hxx> |
36 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
37 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> |
38 | #include <TopTools_IndexedMapOfShape.hxx> |
39 | #include <TopTools_DataMapOfShapeShape.hxx> |
40 | #include <TopTools_DataMapOfShapeListOfShape.hxx> |
41 | #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx> |
42 | #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx> |
43 | #include <TopTools_MapOfShape.hxx> |
44 | #include <TopTools_MapIteratorOfMapOfShape.hxx> |
45 | #include <TopExp_Explorer.hxx> |
46 | #include <TopExp.hxx> |
47 | #include <TopoDS.hxx> |
48 | #include <TopoDS_Face.hxx> |
49 | #include <BRepTools.hxx> |
50 | #include <TDF_Reference.hxx> |
51 | #include <TDataStd_TreeNode.hxx> |
52 | #include <BRepAlgoAPI_BooleanOperation.hxx> |
53 | #include <gp_Vec.hxx> |
54 | #include <gp_Ax1.hxx> |
55 | #include <gp_Pln.hxx> |
56 | #include <TopoDS_Edge.hxx> |
57 | #include <Geom_Curve.hxx> |
58 | #include <BRep_Tool.hxx> |
59 | #include <Geom_Line.hxx> |
60 | #include <Geom_Plane.hxx> |
61 | #include <Geom_Surface.hxx> |
62 | #include <BRepLib_FindSurface.hxx> |
63 | #include <Geom_RectangularTrimmedSurface.hxx> |
64 | #include <ModelDefinitions.hxx> |
65 | |
66 | //======================================================================= |
67 | //function : DNaming_DFandUS |
68 | //purpose : |
69 | //======================================================================= |
70 | |
71 | // Standard_Boolean DNaming_DFandUS(char* a, |
72 | // Handle(TDF_Data)& ND, |
73 | // Handle(TNaming_UsedShapes)& US) |
74 | // { |
75 | // Handle(DDF_Data) DND = Handle(DDF_Data)::DownCast (Draw::Get(a)); |
76 | // if (DND.IsNull ()) return 0; |
77 | // ND = DND->DataFramework (); |
78 | // ND->Root().FindAttribute(TNaming_UsedShapes::GetID(),US); |
79 | // return 1; |
80 | // } |
81 | |
82 | //======================================================================= |
83 | //function : GetShape |
84 | //purpose : |
85 | //======================================================================= |
86 | |
87 | void DNaming::GetShape (const Standard_CString LabelName, |
88 | const Handle(TDF_Data)& DF, |
89 | TopTools_ListOfShape& L) |
90 | { |
91 | L.Clear(); |
92 | TDF_Label Label; |
93 | Standard_Boolean Found = DDF::AddLabel (DF, LabelName, Label); |
94 | if (Found) { |
95 | TNaming_Iterator it (Label, DF->Transaction ()); |
96 | for (; it.More(); it.Next()) { |
97 | L.Append(it.NewShape()); |
98 | } |
99 | } |
100 | } |
101 | |
102 | //======================================================================= |
103 | //function : BuildMap |
104 | //purpose : |
105 | //======================================================================= |
106 | |
107 | void DNaming_BuildMap(TDF_LabelMap& Updated, |
108 | const TDF_Label& Lab) |
109 | { |
110 | TDF_ChildIterator it(Lab); |
111 | for (; it.More(); it.Next()) { |
112 | Updated.Add(it.Value()); |
113 | DNaming_BuildMap(Updated,it.Value()); |
114 | } |
115 | } |
116 | |
117 | //======================================================================= |
118 | //function : CurrentShape |
119 | //purpose : |
120 | //======================================================================= |
121 | |
122 | TopoDS_Shape DNaming::CurrentShape (const Standard_CString LabelName, |
123 | const Handle(TDF_Data)& DF) |
124 | { |
125 | TopoDS_Shape S; |
126 | TDF_Label Label; |
127 | Standard_Boolean Found = DDF::AddLabel (DF, LabelName, Label); |
128 | if (!Found) { |
0797d9d3 |
129 | #ifdef OCCT_DEBUG |
7fd59977 |
130 | cout <<"no labels"<<endl; |
63c629aa |
131 | #endif |
7fd59977 |
132 | return S; |
133 | } |
134 | if (Found) { |
135 | Handle(TNaming_NamedShape) NS; |
136 | Label.FindAttribute(TNaming_NamedShape::GetID(),NS); |
137 | S = TNaming_Tool::CurrentShape(NS); |
138 | if (S.IsNull()) |
0797d9d3 |
139 | #ifdef OCCT_DEBUG |
7fd59977 |
140 | cout <<"current shape from "<< LabelName <<" is deleted"<<endl; |
63c629aa |
141 | #endif |
7fd59977 |
142 | return S; |
143 | } |
144 | return S; |
145 | } |
146 | |
147 | |
148 | //======================================================================= |
149 | //function : GetEntry |
150 | //purpose : |
151 | //======================================================================= |
152 | |
153 | TCollection_AsciiString DNaming::GetEntry (const TopoDS_Shape& Shape, |
154 | const Handle(TDF_Data)& DF, |
155 | Standard_Integer& Status) |
156 | { |
157 | Status = 0; |
158 | //Handle(TNaming_UsedShapes) US; |
159 | //DF->Root().FindAttribute(TNaming_UsedShapes::GetID(),US); |
160 | |
161 | if (!TNaming_Tool::HasLabel (DF->Root(), Shape)) { |
162 | return TCollection_AsciiString (); |
163 | } |
164 | Standard_Integer Transdef; |
165 | TDF_Label Lab = TNaming_Tool::Label (DF->Root(), Shape,Transdef); |
166 | TCollection_AsciiString entry; TDF_Tool::Entry(Lab,entry); |
167 | //Update Status; |
168 | TNaming_Iterator it(Lab,DF->Transaction()); |
169 | for (; it.More(); it.Next()) { |
170 | Status++; |
171 | if (Status == 2) break; |
172 | } |
173 | return entry; |
174 | } |
175 | |
176 | //======================================================================= |
177 | //function : AllCommands |
178 | //purpose : |
179 | //======================================================================= |
180 | |
181 | void DNaming::AllCommands(Draw_Interpretor& theCommands) |
182 | { |
183 | static Standard_Boolean done = Standard_False; |
184 | if (done) return; |
185 | done = Standard_True; |
186 | |
187 | DNaming::BasicCommands (theCommands); |
188 | DNaming::ToolsCommands (theCommands); |
189 | DNaming::SelectionCommands (theCommands); |
190 | DNaming::ModelingCommands (theCommands); |
191 | // define the TCL variable Draw_NamingData |
192 | const char* com = "set Draw_NamingData 1"; |
193 | theCommands.Eval(com); |
194 | } |
195 | |
196 | //======================================================================= |
197 | //======================================================================= |
198 | //function : LoadC0Vertices |
199 | //purpose : Method for internal use. It is used by Load() method. |
200 | //======================================================================= |
201 | |
202 | static void LoadC0Vertices(const TopoDS_Shape& S, |
203 | const Handle(TDF_TagSource)& Tagger) |
204 | { |
205 | TopTools_DataMapOfShapeListOfShape vertexNaborFaces; |
206 | TopTools_ListOfShape empty; |
207 | TopExp_Explorer explF(S, TopAbs_FACE); |
208 | for (; explF.More(); explF.Next()) { |
209 | const TopoDS_Shape& aFace = explF.Current(); |
210 | TopExp_Explorer explV(aFace, TopAbs_VERTEX); |
211 | for (; explV.More(); explV.Next()) { |
212 | const TopoDS_Shape& aVertex = explV.Current(); |
213 | if (!vertexNaborFaces.IsBound(aVertex)) vertexNaborFaces.Bind(aVertex, empty); |
214 | Standard_Boolean faceIsNew = Standard_True; |
215 | TopTools_ListIteratorOfListOfShape itrF(vertexNaborFaces.Find(aVertex)); |
216 | for (; itrF.More(); itrF.Next()) { |
217 | if (itrF.Value().IsSame(aFace)) { |
218 | faceIsNew = Standard_False; |
219 | break; |
220 | } |
221 | } |
222 | if (faceIsNew) { |
223 | vertexNaborFaces.ChangeFind(aVertex).Append(aFace); |
224 | } |
225 | } |
226 | } |
227 | |
228 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itr(vertexNaborFaces); |
229 | for (; itr.More(); itr.Next()) { |
230 | const TopTools_ListOfShape& naborFaces = itr.Value(); |
231 | if (naborFaces.Extent() < 3) { |
232 | TNaming_Builder bC0Vertex(Tagger->NewChild()); |
233 | bC0Vertex.Generated(itr.Key()); |
234 | } |
235 | } |
236 | } |
237 | |
238 | //======================================================================= |
239 | //function : LoadC0Edges |
240 | //purpose : Method for internal use. It is used by Load() method. |
241 | //======================================================================= |
242 | |
243 | static void LoadC0Edges(const TopoDS_Shape& S, |
244 | const Handle(TDF_TagSource)& Tagger) |
245 | { |
246 | TopTools_DataMapOfShapeListOfShape edgeNaborFaces; |
247 | TopTools_ListOfShape empty; |
248 | TopExp_Explorer explF(S, TopAbs_FACE); |
249 | for (; explF.More(); explF.Next()) { |
250 | const TopoDS_Shape& aFace = explF.Current(); |
251 | TopExp_Explorer explV(aFace, TopAbs_EDGE); |
252 | for (; explV.More(); explV.Next()) { |
253 | const TopoDS_Shape& anEdge = explV.Current(); |
254 | if (!edgeNaborFaces.IsBound(anEdge)) edgeNaborFaces.Bind(anEdge, empty); |
255 | Standard_Boolean faceIsNew = Standard_True; |
256 | TopTools_ListIteratorOfListOfShape itrF(edgeNaborFaces.Find(anEdge)); |
257 | for (; itrF.More(); itrF.Next()) { |
258 | if (itrF.Value().IsSame(aFace)) { |
259 | faceIsNew = Standard_False; |
260 | break; |
261 | } |
262 | } |
263 | if (faceIsNew) { |
264 | edgeNaborFaces.ChangeFind(anEdge).Append(aFace); |
265 | } |
266 | } |
267 | } |
268 | |
269 | TopTools_MapOfShape anEdgesToDelete; |
270 | TopExp_Explorer anEx(S,TopAbs_EDGE); // mpv: new explorer iterator becouse we need keep edges order |
271 | for(;anEx.More();anEx.Next()) { |
272 | Standard_Boolean aC0 = Standard_False; |
273 | TopoDS_Shape anEdge1 = anEx.Current(); |
274 | if (edgeNaborFaces.IsBound(anEdge1)) { |
275 | const TopTools_ListOfShape& aList1 = edgeNaborFaces.Find(anEdge1); |
276 | if (aList1.Extent()<2) continue; // mpv (06.09.2002): these edges already was loaded |
277 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itr(edgeNaborFaces); |
278 | for (; itr.More(); itr.Next()) { |
279 | TopoDS_Shape anEdge2 = itr.Key(); |
280 | if(anEdgesToDelete.Contains(anEdge2)) continue; |
281 | if (anEdge1.IsSame(anEdge2)) continue; |
282 | const TopTools_ListOfShape& aList2 = itr.Value(); |
283 | // compare lists of the neighbour faces of edge1 and edge2 |
284 | if (aList1.Extent() == aList2.Extent()) { |
285 | Standard_Integer aMatches = 0; |
286 | for(TopTools_ListIteratorOfListOfShape aLIter1(aList1);aLIter1.More();aLIter1.Next()) |
287 | for(TopTools_ListIteratorOfListOfShape aLIter2(aList2);aLIter2.More();aLIter2.Next()) |
288 | if (aLIter1.Value().IsSame(aLIter2.Value())) aMatches++; |
289 | if (aMatches == aList1.Extent()) { |
290 | aC0=Standard_True; |
291 | TNaming_Builder bC0Edge(Tagger->NewChild()); |
292 | bC0Edge.Generated(anEdge2); |
293 | //edgeNaborFaces.UnBind(anEdge2); |
294 | anEdgesToDelete.Add(anEdge2); |
295 | } |
296 | } |
297 | } |
298 | //VUN (10/2/2005) avoid UnBind during iterating -^ |
299 | TopTools_MapIteratorOfMapOfShape itDelete(anEdgesToDelete); |
300 | for(;itDelete.More();itDelete.Next()) { |
301 | edgeNaborFaces.UnBind(itDelete.Key()); |
302 | } |
303 | edgeNaborFaces.UnBind(anEdge1); |
304 | } |
305 | if (aC0) { |
306 | TNaming_Builder bC0Edge(Tagger->NewChild()); |
307 | bC0Edge.Generated(anEdge1); |
308 | } |
309 | } |
310 | } |
311 | // |
312 | //======================================================================= |
313 | //function : GetDangleShapes |
314 | //purpose : Returns dangle sub shapes Generator - Dangle. |
315 | //======================================================================= |
316 | |
317 | static Standard_Boolean GetDangleShapes(const TopoDS_Shape& ShapeIn, |
318 | const TopAbs_ShapeEnum GeneratedFrom, |
319 | TopTools_DataMapOfShapeShape& Dangles) |
320 | { |
321 | Dangles.Clear(); |
322 | TopTools_IndexedDataMapOfShapeListOfShape subShapeAndAncestors; |
323 | TopAbs_ShapeEnum GeneratedTo; |
324 | if (GeneratedFrom == TopAbs_FACE) GeneratedTo = TopAbs_EDGE; |
325 | else if (GeneratedFrom == TopAbs_EDGE) GeneratedTo = TopAbs_VERTEX; |
326 | else return Standard_False; |
327 | TopExp::MapShapesAndAncestors(ShapeIn, GeneratedTo, GeneratedFrom, subShapeAndAncestors); |
328 | for (Standard_Integer i = 1; i <= subShapeAndAncestors.Extent(); i++) { |
329 | const TopoDS_Shape& mayBeDangle = subShapeAndAncestors.FindKey(i); |
330 | const TopTools_ListOfShape& ancestors = subShapeAndAncestors.FindFromIndex(i); |
331 | if (ancestors.Extent() == 1) Dangles.Bind(ancestors.First(), mayBeDangle); |
332 | } |
333 | return Dangles.Extent(); |
334 | } |
335 | |
336 | //======================================================================= |
337 | //function : LoadGeneratedDangleShapes |
338 | //purpose : |
339 | //======================================================================= |
340 | |
341 | static void LoadGeneratedDangleShapes(const TopoDS_Shape& ShapeIn, |
342 | const TopAbs_ShapeEnum GeneratedFrom, |
343 | TNaming_Builder& Builder) |
344 | { |
345 | TopTools_DataMapOfShapeShape dangles; |
346 | if (!GetDangleShapes(ShapeIn, GeneratedFrom, dangles)) return; |
347 | TopTools_DataMapIteratorOfDataMapOfShapeShape itr(dangles); |
348 | for (; itr.More(); itr.Next()) Builder.Generated(itr.Key(), itr.Value()); |
349 | } |
350 | |
351 | //======================================================================= |
352 | //function : LoadNextLevels |
353 | //purpose : Method for internal use. Is used by LoadFirstLevel() |
354 | //======================================================================= |
355 | |
356 | static void LoadNextLevels(const TopoDS_Shape& S, |
357 | const Handle(TDF_TagSource)& Tagger) |
358 | { |
359 | |
360 | if (S.ShapeType() == TopAbs_SOLID) { |
361 | TopExp_Explorer expl(S, TopAbs_FACE); |
362 | for (; expl.More(); expl.Next()) { |
363 | TNaming_Builder bFace(Tagger->NewChild()); |
364 | bFace.Generated(expl.Current()); |
365 | } |
366 | } else if (S.ShapeType() == TopAbs_SHELL || S.ShapeType() == TopAbs_FACE) { |
367 | // load faces and all the free edges |
368 | TopTools_IndexedMapOfShape Faces; |
369 | TopExp::MapShapes(S, TopAbs_FACE, Faces); |
370 | if (Faces.Extent() > 1 || (S.ShapeType() == TopAbs_SHELL && Faces.Extent() == 1)) { |
371 | TopExp_Explorer expl(S, TopAbs_FACE); |
372 | for (; expl.More(); expl.Next()) { |
373 | TNaming_Builder bFace(Tagger->NewChild()); |
374 | bFace.Generated(expl.Current()); |
375 | } |
376 | } |
377 | TopTools_IndexedDataMapOfShapeListOfShape anEdgeAndNeighbourFaces; |
378 | TopExp::MapShapesAndAncestors(S, TopAbs_EDGE, TopAbs_FACE, anEdgeAndNeighbourFaces); |
379 | for (Standard_Integer i = 1; i <= anEdgeAndNeighbourFaces.Extent(); i++) { |
380 | const TopTools_ListOfShape& aLL = anEdgeAndNeighbourFaces.FindFromIndex(i); |
381 | if (aLL.Extent() < 2) { |
382 | TNaming_Builder bFreeEdges(Tagger->NewChild()); |
383 | bFreeEdges.Generated(anEdgeAndNeighbourFaces.FindKey(i)); |
384 | } else { |
385 | TopTools_ListIteratorOfListOfShape anIter(aLL); |
386 | const TopoDS_Face& aFace = TopoDS::Face(anIter.Value()); |
387 | anIter.Next(); |
388 | if(aFace.IsEqual(anIter.Value())) { |
389 | TNaming_Builder bFreeEdges(Tagger->NewChild()); |
390 | bFreeEdges.Generated(anEdgeAndNeighbourFaces.FindKey(i)); |
391 | } |
392 | } |
393 | } |
394 | } else if (S.ShapeType() == TopAbs_WIRE) { |
395 | TopTools_IndexedMapOfShape Edges; |
396 | BRepTools::Map3DEdges(S, Edges); |
397 | if (Edges.Extent() == 1) { |
398 | TNaming_Builder bEdge(Tagger->NewChild()); |
399 | bEdge.Generated(Edges.FindKey(1)); |
400 | TopExp_Explorer expl(S, TopAbs_VERTEX); |
401 | for (; expl.More(); expl.Next()) { |
402 | TNaming_Builder bVertex(Tagger->NewChild()); |
403 | bVertex.Generated(expl.Current()); |
404 | } |
405 | } else { |
406 | TopExp_Explorer expl(S, TopAbs_EDGE); |
407 | for (; expl.More(); expl.Next()) { |
408 | TNaming_Builder bEdge(Tagger->NewChild()); |
409 | bEdge.Generated(expl.Current()); |
410 | } |
411 | // and load generated vertices. |
412 | TopTools_DataMapOfShapeShape generated; |
413 | if (GetDangleShapes(S, TopAbs_EDGE, generated)) { |
414 | TNaming_Builder bGenVertices(Tagger->NewChild()); |
415 | LoadGeneratedDangleShapes(S, TopAbs_EDGE, bGenVertices); |
416 | } |
417 | } |
418 | } else if (S.ShapeType() == TopAbs_EDGE) { |
419 | TopExp_Explorer expl(S, TopAbs_VERTEX); |
420 | for (; expl.More(); expl.Next()) { |
421 | TNaming_Builder bVertex(Tagger->NewChild()); |
422 | bVertex.Generated(expl.Current()); |
423 | } |
424 | } |
425 | } |
426 | |
427 | //======================================================================= |
428 | //function : LoadFirstLevel |
429 | //purpose : Method for internal use. Is used by Load() |
430 | //======================================================================= |
431 | |
432 | static void LoadFirstLevel(const TopoDS_Shape& S, |
433 | const Handle(TDF_TagSource)& Tagger) |
434 | { |
435 | if (S.ShapeType() == TopAbs_COMPOUND || S.ShapeType() == TopAbs_COMPSOLID) { |
436 | TopoDS_Iterator itr(S); |
437 | for (; itr.More(); itr.Next()) { |
438 | TNaming_Builder bIndependantShapes(Tagger->NewChild()); |
439 | bIndependantShapes.Generated(itr.Value()); |
440 | if (itr.Value().ShapeType() == TopAbs_COMPOUND || itr.Value().ShapeType() == TopAbs_COMPSOLID) { |
441 | LoadFirstLevel(itr.Value(), Tagger); |
442 | } else LoadNextLevels(itr.Value(), Tagger); |
443 | } |
444 | } else LoadNextLevels(S, Tagger); |
445 | } |
446 | |
447 | //======================================================================= |
448 | //function : Load |
449 | //purpose : To load an ImportShape |
450 | // Use this method for a topological naming of an imported shape |
451 | //======================================================================= |
452 | |
453 | void DNaming::LoadImportedShape(const TDF_Label& theResultLabel, |
454 | const TopoDS_Shape& theShape) { |
455 | theResultLabel.ForgetAllAttributes(); |
456 | TNaming_Builder aBuilder(theResultLabel); |
457 | aBuilder.Generated(theShape); |
458 | |
459 | Handle(TDF_TagSource) aTagger = TDF_TagSource::Set(theResultLabel); |
460 | if (aTagger.IsNull()) return; |
461 | aTagger->Set(0); |
462 | |
463 | LoadFirstLevel(theShape, aTagger); |
464 | LoadC0Edges(theShape, aTagger); |
465 | LoadC0Vertices(theShape, aTagger); |
466 | } |
467 | |
468 | //======================================================================= |
469 | //function : LoadPrime |
470 | //purpose : |
471 | //======================================================================= |
472 | |
473 | void DNaming::LoadPrime(const TDF_Label& theResultLabel, |
474 | const TopoDS_Shape& theShape) { |
475 | |
476 | Handle(TDF_TagSource) aTagger = TDF_TagSource::Set(theResultLabel); |
477 | if (aTagger.IsNull()) return; |
478 | aTagger->Set(0); |
479 | |
480 | LoadFirstLevel(theShape, aTagger); |
481 | LoadC0Edges(theShape, aTagger); |
482 | LoadC0Vertices(theShape, aTagger); |
483 | } |
484 | |
485 | // |
486 | //======================================================================= |
487 | //function : Real |
488 | //purpose : Gives the access to a real argument |
489 | //======================================================================= |
490 | Handle(TDataStd_Real) DNaming::GetReal(const Handle(TFunction_Function)& theFunction, |
491 | const Standard_Integer thePosition) { |
492 | Handle(TDataStd_Real) aReal; |
493 | if (!POSITION(theFunction, thePosition).FindAttribute(TDataStd_Real::GetID(),aReal)) |
494 | aReal = TDataStd_Real::Set(POSITION(theFunction,thePosition),0.0); |
495 | return aReal; |
496 | } |
497 | |
498 | |
499 | |
500 | //======================================================================= |
501 | //function : Integer |
502 | //purpose : Give an access to integer attribute |
503 | //======================================================================= |
504 | Handle(TDataStd_Integer) DNaming::GetInteger(const Handle(TFunction_Function)& theFunction, |
505 | const Standard_Integer thePosition) { |
506 | Handle(TDataStd_Integer) anInteger; |
507 | if (!POSITION(theFunction,thePosition).FindAttribute(TDataStd_Integer::GetID(),anInteger)) |
508 | anInteger = TDataStd_Integer::Set(POSITION(theFunction,thePosition),0); |
509 | return anInteger; |
510 | } |
511 | |
512 | //======================================================================= |
513 | //function : String |
514 | //purpose : Returns Name attribute |
515 | //======================================================================= |
516 | Handle(TDataStd_Name) DNaming::GetString(const Handle(TFunction_Function)& theFunction, |
517 | const Standard_Integer thePosition) { |
518 | Handle(TDataStd_Name) aString; |
519 | if (!POSITION(theFunction,thePosition).FindAttribute(TDataStd_Name::GetID(),aString)) |
520 | aString = TDataStd_Name::Set(POSITION(theFunction,thePosition),""); |
521 | return aString; |
522 | } |
523 | |
524 | //======================================================================= |
525 | //function : GetResult |
526 | //purpose : Returns a result of a function, which is stored on a second label |
527 | //======================================================================= |
528 | Handle(TNaming_NamedShape) DNaming::GetFunctionResult(const Handle(TFunction_Function)& theFunction) |
529 | { |
530 | Handle(TNaming_NamedShape) aNShape; |
531 | theFunction->Label().FindChild(FUNCTION_RESULT_LABEL).FindAttribute(TNaming_NamedShape::GetID(),aNShape); |
532 | return aNShape; |
533 | } |
534 | //======================================================================= |
535 | //function : Object |
536 | //purpose : Returns UAttribute associated with Object |
537 | //======================================================================= |
538 | Handle(TDataStd_UAttribute) DNaming::GetObjectArg(const Handle(TFunction_Function)& theFunction, |
539 | const Standard_Integer thePosition) { |
540 | Handle(TDataStd_UAttribute) anObject; |
541 | Handle(TDF_Reference) aReference; |
542 | if (POSITION(theFunction,thePosition).FindAttribute(TDF_Reference::GetID(), aReference)) |
543 | aReference->Get().FindAttribute(GEOMOBJECT_GUID, anObject); |
544 | return anObject; |
545 | } |
546 | |
547 | //======================================================================= |
548 | //function : SetObject |
549 | //purpose : Replace the argument by new value. |
550 | //======================================================================= |
551 | void DNaming::SetObjectArg (const Handle(TFunction_Function)& theFunction, |
552 | const Standard_Integer thePosition, |
553 | const Handle(TDataStd_UAttribute)& theNewValue) |
554 | { |
555 | |
556 | if(theNewValue.IsNull()) return; |
557 | TDF_Reference::Set(POSITION(theFunction, thePosition),theNewValue->Label()); |
558 | |
559 | } |
560 | |
561 | //======================================================================= |
562 | //function : GetObjectValue |
563 | //purpose : Returns NamedShape of the Object |
564 | //======================================================================= |
565 | Handle(TNaming_NamedShape) DNaming::GetObjectValue(const Handle(TDataStd_UAttribute)& theObject) |
566 | { |
567 | Handle(TNaming_NamedShape) aNS; |
63c629aa |
568 | |
7fd59977 |
569 | if(!theObject.IsNull() && theObject->ID() == GEOMOBJECT_GUID) { |
570 | |
571 | Handle(TDF_Reference) aReference; |
572 | if(theObject->FindAttribute(TDF_Reference::GetID(), aReference)) |
573 | aReference->Get().FindAttribute(TNaming_NamedShape::GetID(), aNS); |
574 | } |
575 | return aNS; |
576 | |
577 | /* |
578 | Handle(TFunction_Function) aFun; |
579 | Handle(TDataStd_TreeNode) aNode; |
580 | objLabel.FindAttribute(TDataStd_TreeNode::GetDefaultTreeID(), aNode); |
581 | if(aNode.IsNull()) return aFun; |
582 | if(!aNode->HasFirst()) return aFun; |
583 | else |
584 | aNode = aNode->First(); |
585 | while(!aNode.IsNull()) { |
586 | if(aNode->FindAttribute(TFunction_Function::GetID(), aFun)) { |
587 | const Standard_GUID& aGUID = aFun->GetDriverGUID(); |
588 | if(aGUID == funGUID) break; |
589 | else aFun.Nullify(); |
590 | } |
591 | aNode = aNode->Next(); |
592 | } |
593 | */ |
594 | |
595 | } |
596 | |
597 | //======================================================================= |
598 | //function : GetPrevFunction |
599 | //purpose : Returns previus function |
600 | //======================================================================= |
601 | Handle(TFunction_Function) DNaming::GetPrevFunction(const Handle(TFunction_Function)& theFunction) |
602 | { |
603 | Handle(TFunction_Function) aPrevFun; |
604 | if(!theFunction.IsNull() ) { |
605 | Handle(TDataStd_TreeNode) aNode; |
606 | theFunction->FindAttribute(TDataStd_TreeNode::GetDefaultTreeID(), aNode); |
607 | while(!aNode.IsNull()) { |
608 | if(!aNode->HasPrevious()) return aPrevFun; |
609 | else |
610 | aNode = aNode->Previous(); |
611 | aNode->FindAttribute(TFunction_Function::GetID(),aPrevFun ); |
612 | if(!aPrevFun.IsNull()) |
613 | break; |
614 | } |
615 | } |
616 | return aPrevFun; |
617 | /* |
618 | while(!aNode.IsNull()) { |
619 | if(aNode->FindAttribute(TFunction_Function::GetID(), aFun)) { |
620 | const Standard_GUID& aGUID = aFun->GetDriverGUID(); |
621 | if(aGUID == funGUID) break; |
622 | else aFun.Nullify(); |
623 | } |
624 | aNode = aNode->Next(); |
625 | } |
626 | */ |
627 | |
628 | } |
629 | |
630 | //======================================================================= |
631 | //function : GetFirstFunction |
632 | //purpose : Returns first function |
633 | //======================================================================= |
634 | Handle(TFunction_Function) DNaming::GetFirstFunction(const Handle(TDataStd_UAttribute)& theObject) |
635 | { |
636 | Handle(TFunction_Function) aFirstFun; |
637 | if(!theObject.IsNull() ) { |
638 | Handle(TDataStd_TreeNode) aNode; |
639 | theObject->FindAttribute(TDataStd_TreeNode::GetDefaultTreeID(), aNode); |
640 | if(aNode.IsNull()) return aFirstFun; |
641 | if(!aNode->HasFirst()) return aFirstFun; |
642 | else |
643 | aNode = aNode->First(); |
644 | |
645 | while(!aNode.IsNull()) { |
646 | aNode->FindAttribute(TFunction_Function::GetID(), aFirstFun ); |
647 | if(!aFirstFun.IsNull()) |
648 | break; |
649 | aNode = aNode->Next(); |
650 | } |
651 | } |
652 | return aFirstFun; |
653 | } |
654 | |
655 | //======================================================================= |
656 | //function : GetLastFunction |
657 | //purpose : Returns Last function |
658 | //======================================================================= |
659 | Handle(TFunction_Function) DNaming::GetLastFunction(const Handle(TDataStd_UAttribute)& theObject) |
660 | { |
661 | Handle(TFunction_Function) aLastFun; |
662 | if(!theObject.IsNull() ) { |
663 | Handle(TDataStd_TreeNode) aNode; |
664 | theObject->FindAttribute(TDataStd_TreeNode::GetDefaultTreeID(), aNode); |
665 | if(aNode.IsNull()) return aLastFun; |
666 | if(!aNode->HasFirst()) return aLastFun; |
667 | else |
668 | aNode = aNode->First(); |
669 | |
670 | while(!aNode.IsNull()) { |
671 | if(aNode->IsAttribute(TFunction_Function::GetID())) |
672 | aNode->FindAttribute(TFunction_Function::GetID(), aLastFun); |
673 | aNode = aNode->Next(); |
674 | } |
675 | } |
676 | return aLastFun; |
677 | } |
678 | |
679 | //======================================================================= |
680 | //function : GetObjectFromFunction |
681 | //purpose : Returns Object |
682 | //======================================================================= |
683 | Handle(TDataStd_UAttribute) DNaming::GetObjectFromFunction(const Handle(TFunction_Function)& theFunction) |
684 | { |
685 | Handle(TDataStd_UAttribute) anObject; |
686 | if(!theFunction.IsNull() ) { |
687 | Handle(TDataStd_TreeNode) aNode; |
688 | theFunction->FindAttribute(TDataStd_TreeNode::GetDefaultTreeID(), aNode); |
689 | if(!aNode.IsNull()) { |
690 | if(!aNode->HasFather()) return anObject; |
691 | else |
692 | aNode = aNode->Father(); |
693 | aNode->FindAttribute(GEOMOBJECT_GUID, anObject); |
694 | } |
695 | } |
696 | return anObject; |
697 | /* |
698 | while(!aNode.IsNull()) { |
699 | if(aNode->FindAttribute(TFunction_Function::GetID(), aFun)) { |
700 | const Standard_GUID& aGUID = aFun->GetDriverGUID(); |
701 | if(aGUID == funGUID) break; |
702 | else aFun.Nullify(); |
703 | } |
704 | aNode = aNode->Next(); |
705 | } |
706 | */ |
707 | |
708 | } |
709 | //======================================================================= |
710 | //function : LoadResult |
711 | //purpose : |
712 | //======================================================================= |
713 | void DNaming::LoadResult(const TDF_Label& ResultLabel, BRepAlgoAPI_BooleanOperation& MS) |
714 | { |
715 | Handle(TDF_TagSource) Tagger = TDF_TagSource::Set(ResultLabel); |
716 | if (Tagger.IsNull()) return; |
717 | Tagger->Set(0); |
718 | TNaming_Builder Builder (ResultLabel); |
719 | TopoDS_Shape aResult = MS.Shape(); |
720 | if (aResult.ShapeType() == TopAbs_COMPOUND) { |
721 | Standard_Integer nbSubResults = 0; |
722 | TopoDS_Iterator itr(aResult); |
723 | for (; itr.More(); itr.Next()) nbSubResults++; |
724 | if (nbSubResults == 1) { |
725 | itr.Initialize(aResult); |
726 | if (itr.More()) aResult = itr.Value(); |
727 | } |
728 | } |
729 | if (MS.Shape1().IsNull()) Builder.Generated(aResult); |
730 | else { |
731 | Builder.Modify(MS.Shape1(), aResult); |
732 | } |
733 | } |
734 | //======================================================================= |
735 | //function : LoadAndOrientModifiedShapes |
736 | //purpose : |
737 | //======================================================================= |
738 | void DNaming::LoadAndOrientModifiedShapes (BRepBuilderAPI_MakeShape& MS, |
739 | const TopoDS_Shape& ShapeIn, |
740 | const TopAbs_ShapeEnum KindOfShape, |
741 | TNaming_Builder& Builder, |
742 | const TopTools_DataMapOfShapeShape& SubShapes) |
743 | { |
744 | TopTools_MapOfShape View; |
745 | TopExp_Explorer ShapeExplorer (ShapeIn, KindOfShape); |
746 | TopTools_ListOfShape Shapes; |
747 | for (; ShapeExplorer.More(); ShapeExplorer.Next ()) { |
748 | const TopoDS_Shape& Root = ShapeExplorer.Current (); |
749 | if (!View.Add(Root)) continue; |
750 | const TopTools_ListOfShape& Shapes = MS.Modified (Root); |
751 | TopTools_ListIteratorOfListOfShape ShapesIterator (Shapes); |
752 | for (;ShapesIterator.More (); ShapesIterator.Next ()) { |
753 | TopoDS_Shape newShape = ShapesIterator.Value (); |
754 | if (SubShapes.IsBound(newShape)) { |
755 | newShape.Orientation((SubShapes(newShape)).Orientation()); |
756 | } |
757 | if (!Root.IsSame (newShape)) Builder.Modify (Root, newShape ); |
758 | } |
759 | } |
760 | } |
761 | //======================================================================= |
762 | //function : LoadDeletedShapes |
763 | //purpose : |
764 | //======================================================================= |
765 | void DNaming::LoadDeletedShapes (BRepBuilderAPI_MakeShape& MS, |
766 | const TopoDS_Shape& ShapeIn, |
767 | const TopAbs_ShapeEnum KindOfShape, |
768 | TNaming_Builder& Builder) |
769 | { |
770 | TopTools_MapOfShape View; |
771 | TopExp_Explorer ShapeExplorer (ShapeIn, KindOfShape); |
772 | for (; ShapeExplorer.More(); ShapeExplorer.Next ()) { |
773 | const TopoDS_Shape& Root = ShapeExplorer.Current (); |
774 | if (!View.Add(Root)) continue; |
775 | if (MS.IsDeleted (Root)) { |
776 | Builder.Delete (Root); |
777 | } |
778 | } |
779 | } |
780 | |
781 | //======================================================================= |
782 | //function : LoadAndOrientGeneratedShapes |
783 | //purpose : |
784 | //======================================================================= |
785 | |
786 | void DNaming::LoadAndOrientGeneratedShapes (BRepBuilderAPI_MakeShape& MS, |
787 | const TopoDS_Shape& ShapeIn, |
788 | const TopAbs_ShapeEnum KindOfShape, |
789 | TNaming_Builder& Builder, |
790 | const TopTools_DataMapOfShapeShape& SubShapes) |
791 | { |
792 | TopTools_MapOfShape View; |
793 | TopExp_Explorer ShapeExplorer (ShapeIn, KindOfShape); |
794 | for (; ShapeExplorer.More(); ShapeExplorer.Next ()) { |
795 | const TopoDS_Shape& Root = ShapeExplorer.Current (); |
796 | if (!View.Add(Root)) continue; |
797 | const TopTools_ListOfShape& Shapes = MS.Generated (Root); |
798 | TopTools_ListIteratorOfListOfShape ShapesIterator (Shapes); |
799 | for (;ShapesIterator.More (); ShapesIterator.Next ()) { |
800 | TopoDS_Shape newShape = ShapesIterator.Value (); |
801 | if (SubShapes.IsBound(newShape)) { |
802 | newShape.Orientation((SubShapes(newShape)).Orientation()); |
803 | } |
804 | if (!Root.IsSame (newShape)) Builder.Generated (Root,newShape ); |
805 | } |
806 | } |
807 | } |
808 | |
809 | //======================================================================= |
810 | //function : ComputeNormalizedVector |
811 | //purpose : Computes normalized vector from shape if it is possible |
812 | //======================================================================= |
813 | Standard_Boolean DNaming::ComputeAxis (const Handle(TNaming_NamedShape)& theNS, |
814 | gp_Ax1& theAx1) |
815 | { |
816 | if(theNS.IsNull() || theNS->IsEmpty()) return Standard_False; |
817 | TopoDS_Shape aShape = theNS->Get(); |
818 | if(aShape.IsNull()) return Standard_False; |
819 | if(aShape.ShapeType() == TopAbs_EDGE || aShape.ShapeType() == TopAbs_WIRE) { |
820 | if (aShape.ShapeType() == TopAbs_WIRE) { |
821 | TopExp_Explorer anExplorer(aShape, TopAbs_EDGE); |
822 | aShape = anExplorer.Current(); |
823 | } |
824 | const TopoDS_Edge& anEdge = TopoDS::Edge(aShape); |
825 | Standard_Real aFirst, aLast; |
826 | Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge,aFirst,aLast) ; |
827 | if (aCurve->IsKind (STANDARD_TYPE(Geom_Line)) ) { |
828 | Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast(aCurve) ; |
829 | if(!aLine.IsNull()) { |
830 | theAx1 = aLine->Position() ; |
831 | return Standard_True; |
832 | } |
833 | } |
834 | } |
835 | return Standard_False; |
836 | } |
837 | |
838 | //======================================================================= |
839 | //function : IsAttachment |
840 | //purpose : |
841 | //======================================================================= |
842 | Standard_Boolean DNaming::IsAttachment(const Handle(TDataStd_UAttribute)& anObj) |
843 | { |
844 | |
845 | Handle(TFunction_Function) aFun = GetFirstFunction(anObj); |
846 | if(!aFun.IsNull()) { |
847 | const Standard_GUID& aGUID = aFun->GetDriverGUID(); |
848 | if(aGUID == ATTCH_GUID || aGUID == XTTCH_GUID) { |
849 | return |
850 | aFun->Label().FindChild(FUNCTION_ARGUMENTS_LABEL).FindChild(ATTACH_ARG).IsAttribute(TDF_Reference::GetID()); |
851 | } |
852 | } |
853 | return Standard_False; |
854 | } |
855 | |
856 | //======================================================================= |
857 | //function : GetAttachmentsContext |
858 | //purpose : |
859 | //======================================================================= |
860 | Handle(TNaming_NamedShape) DNaming::GetAttachmentsContext(const Handle(TDataStd_UAttribute)& anObj) |
861 | { |
862 | Handle(TNaming_NamedShape) aNS; |
863 | Handle(TFunction_Function) aFun = GetFirstFunction(anObj); |
864 | if(!aFun.IsNull()) { |
865 | const Standard_GUID& aGUID = aFun->GetDriverGUID(); |
866 | if(aGUID == ATTCH_GUID) { |
867 | const TDF_Label& aLabel = aFun->Label().FindChild(FUNCTION_ARGUMENTS_LABEL).FindChild(ATTACH_ARG); |
868 | Handle(TDF_Reference) aRef; |
869 | Handle(TFunction_Function) aFunCnt; |
870 | if(aLabel.FindAttribute(TDF_Reference::GetID(), aRef)) { |
871 | if(aRef->Get().FindAttribute(TFunction_Function::GetID(), aFunCnt)) { |
872 | const TDF_Label& aResultLabel = aFunCnt->Label().FindChild(FUNCTION_RESULT_LABEL, Standard_True); |
873 | aResultLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS); |
874 | } |
875 | } |
876 | } |
877 | } |
878 | return aNS; |
879 | } |
880 | |
881 | //======================================================================= |
882 | //function : ComputeSweepDir |
883 | //purpose : Computes direction for extrusion |
884 | //======================================================================= |
885 | Standard_Boolean DNaming::ComputeSweepDir (const TopoDS_Shape& theShape, |
886 | gp_Ax1& theAxis) |
887 | { |
888 | // Find surface |
889 | TopLoc_Location aLocation = theShape.Location(); |
890 | Handle(Geom_Plane) aPlane; |
891 | |
892 | if (theShape.ShapeType() == TopAbs_FACE) { |
893 | Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(theShape)); |
0797d9d3 |
894 | #ifdef OCCT_DEBUG |
7fd59977 |
895 | Standard_CString s = aSurf->DynamicType()->Name(); |
896 | cout<<"Surface Dynamic TYPE = "<<s<<endl; |
897 | #endif |
898 | if (aSurf->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) |
c5f3a425 |
899 | aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf)->BasisSurface(); |
7fd59977 |
900 | aPlane = Handle(Geom_Plane)::DownCast(aSurf); |
901 | } |
902 | |
903 | if(aPlane.IsNull()) { |
904 | BRepLib_FindSurface aFinder (theShape, 0., Standard_True); |
905 | if (!aFinder.Found()) return Standard_False; |
906 | aPlane = Handle(Geom_Plane)::DownCast(aFinder.Surface()); |
907 | } |
908 | |
909 | if (aPlane.IsNull()) return Standard_False; |
910 | |
911 | theAxis = aPlane->Pln().Axis(); |
912 | if (!aPlane->Pln().Direct()) theAxis.Reverse(); |
913 | |
914 | if (theShape.Orientation() == TopAbs_REVERSED) theAxis.Reverse(); |
915 | |
916 | return Standard_True; |
917 | } |