0024023: Revamp the OCCT Handle -- downcast (automatic)
[occt.git] / src / DNaming / DNaming.cxx
1 // Created on: 1997-01-09
2 // Created by: VAUTHIER Jean-Claude & Fricaud Yves
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
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) {
129 #ifdef OCCT_DEBUG
130     cout <<"no labels"<<endl;
131 #endif
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())
139 #ifdef OCCT_DEBUG
140       cout <<"current shape from "<< LabelName <<" is deleted"<<endl;
141 #endif
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;
568
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));
894 #ifdef OCCT_DEBUG
895     Standard_CString s = aSurf->DynamicType()->Name();
896     cout<<"Surface Dynamic TYPE = "<<s<<endl;
897 #endif
898     if (aSurf->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) 
899       aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf)->BasisSurface();
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 }