0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[occt.git] / src / XCAFDoc / XCAFDoc_DimTolTool.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #include <XCAFDoc_DimTolTool.hxx>
15 #include <Precision.hxx>
16 #include <Standard_GUID.hxx>
17 #include <Standard_Type.hxx>
18 #include <TCollection_HAsciiString.hxx>
19 #include <TColStd_MapOfAsciiString.hxx>
20 #include <TDataStd_Name.hxx>
21 #include <TDataStd_TreeNode.hxx>
22 #include <TDataStd_UAttribute.hxx>
23 #include <TDF_Attribute.hxx>
24 #include <TDF_AttributeIterator.hxx>
25 #include <TDF_ChildIDIterator.hxx>
26 #include <TDF_Label.hxx>
27 #include <TDF_RelocationTable.hxx>
28 #include <XCAFDimTolObjects_DatumObject.hxx>
29 #include <XCAFDoc.hxx>
30 #include <XCAFDoc_Dimension.hxx>
31 #include <XCAFDoc_GeomTolerance.hxx>
32 #include <XCAFDoc_Datum.hxx>
33 #include <XCAFDoc_DimTol.hxx>
34 #include <XCAFDoc_DimTolTool.hxx>
35 #include <XCAFDoc_DocumentTool.hxx>
36 #include <XCAFDoc_GraphNode.hxx>
37 #include <XCAFDoc_ShapeTool.hxx>
38
39
40 IMPLEMENT_STANDARD_RTTIEXT(XCAFDoc_DimTolTool,TDF_Attribute)
41
42 //=======================================================================
43 //function : XCAFDoc_DimTolTool
44 //purpose  : 
45 //=======================================================================
46 XCAFDoc_DimTolTool::XCAFDoc_DimTolTool()
47 {
48 }
49
50
51 //=======================================================================
52 //function : Set
53 //purpose  : 
54 //=======================================================================
55
56 Handle(XCAFDoc_DimTolTool) XCAFDoc_DimTolTool::Set(const TDF_Label& L) 
57 {
58   Handle(XCAFDoc_DimTolTool) A;
59   if (!L.FindAttribute (XCAFDoc_DimTolTool::GetID(), A)) {
60     A = new XCAFDoc_DimTolTool ();
61     L.AddAttribute(A);
62     A->myShapeTool = XCAFDoc_DocumentTool::ShapeTool(L);
63   }
64   return A;
65 }
66
67
68 //=======================================================================
69 //function : GetID
70 //purpose  : 
71 //=======================================================================
72
73 const Standard_GUID& XCAFDoc_DimTolTool::GetID() 
74 {
75   static Standard_GUID DGTTblID ("72afb19b-44de-11d8-8776-001083004c77");
76   return DGTTblID; 
77 }
78
79
80 //=======================================================================
81 //function : BaseLabel
82 //purpose  : 
83 //=======================================================================
84
85 TDF_Label XCAFDoc_DimTolTool::BaseLabel() const
86 {
87   return Label();
88 }
89
90
91 //=======================================================================
92 //function : ShapeTool
93 //purpose  : 
94 //=======================================================================
95
96 const Handle(XCAFDoc_ShapeTool)& XCAFDoc_DimTolTool::ShapeTool() 
97 {
98   if(myShapeTool.IsNull())
99     myShapeTool = XCAFDoc_DocumentTool::ShapeTool(Label());
100   return myShapeTool;
101 }
102
103
104 //=======================================================================
105 //function : IsDimTol
106 //purpose  : 
107 //=======================================================================
108
109 Standard_Boolean XCAFDoc_DimTolTool::IsDimTol(const TDF_Label& theDimTolL) const
110 {
111   Handle(XCAFDoc_DimTol) aDimTolAttr;
112   if(theDimTolL.FindAttribute(XCAFDoc_DimTol::GetID(),aDimTolAttr)) {
113     return Standard_True;
114   }
115   return Standard_False;
116 }
117
118 //=======================================================================
119 //function : IsDimension
120 //purpose  : 
121 //=======================================================================
122
123 Standard_Boolean XCAFDoc_DimTolTool::IsDimension(const TDF_Label& theDimTolL) const
124 {
125   Handle(XCAFDoc_Dimension) aDimTolAttr;
126   if(theDimTolL.FindAttribute(XCAFDoc_Dimension::GetID(),aDimTolAttr)) {
127     return Standard_True;
128   }
129   return Standard_False;
130 }
131
132 //=======================================================================
133 //function : IsGeomTolerance
134 //purpose  : 
135 //=======================================================================
136
137 Standard_Boolean XCAFDoc_DimTolTool::IsGeomTolerance(const TDF_Label& theDimTolL) const
138 {
139   Handle(XCAFDoc_GeomTolerance) aDimTolAttr;
140   if(theDimTolL.FindAttribute(XCAFDoc_GeomTolerance::GetID(),aDimTolAttr)) {
141     return Standard_True;
142   }
143   return Standard_False;
144 }
145
146 //=======================================================================
147 //function : GetDimTolLabels
148 //purpose  : 
149 //=======================================================================
150
151 void XCAFDoc_DimTolTool::GetDimTolLabels(TDF_LabelSequence& theLabels) const
152 {
153   theLabels.Clear();
154   TDF_ChildIterator aChildIterator( Label() ); 
155   for (; aChildIterator.More(); aChildIterator.Next()) {
156     TDF_Label aL = aChildIterator.Value();
157     if ( IsDimTol(aL)) theLabels.Append(aL);
158   }
159 }
160
161 //=======================================================================
162 //function : GetDimensionLabels
163 //purpose  : 
164 //=======================================================================
165
166 void XCAFDoc_DimTolTool::GetDimensionLabels(TDF_LabelSequence& theLabels) const
167 {
168   theLabels.Clear();
169   TDF_ChildIterator aChildIterator( Label() ); 
170   for (; aChildIterator.More(); aChildIterator.Next()) {
171     TDF_Label aL = aChildIterator.Value();
172     if ( IsDimension(aL)) theLabels.Append(aL);
173   }
174 }
175
176 //=======================================================================
177 //function : GetGeomToleranceLabels
178 //purpose  : 
179 //=======================================================================
180
181 void XCAFDoc_DimTolTool::GetGeomToleranceLabels(TDF_LabelSequence& theLabels) const
182 {
183   theLabels.Clear();
184   TDF_ChildIterator aChildIterator( Label() ); 
185   for (; aChildIterator.More(); aChildIterator.Next()) {
186     TDF_Label aL = aChildIterator.Value();
187     if ( IsGeomTolerance(aL)) theLabels.Append(aL);
188   }
189 }
190
191 //=======================================================================
192 //function : FindDimTol
193 //purpose  : 
194 //=======================================================================
195
196 Standard_Boolean XCAFDoc_DimTolTool::FindDimTol(const Standard_Integer kind,
197                                                 const Handle(TColStd_HArray1OfReal)& aVal,
198                                                 const Handle(TCollection_HAsciiString)& aName,
199                                                 const Handle(TCollection_HAsciiString)& aDescription,
200                                                 TDF_Label& lab) const
201 {
202   TDF_ChildIDIterator it(Label(),XCAFDoc_DimTol::GetID());
203   for(; it.More(); it.Next()) {
204     TDF_Label DimTolL = it.Value()->Label();
205     Handle(XCAFDoc_DimTol) DimTolAttr;
206     if(!DimTolL.FindAttribute(XCAFDoc_DimTol::GetID(),DimTolAttr)) continue;
207     Standard_Integer kind1 = DimTolAttr->GetKind();
208     Handle(TColStd_HArray1OfReal) aVal1 = DimTolAttr->GetVal();
209     Handle(TCollection_HAsciiString) aName1 = DimTolAttr->GetName();
210     Handle(TCollection_HAsciiString) aDescription1 = DimTolAttr->GetDescription();
211     Standard_Boolean IsEqual = Standard_True;
212     if(!(kind1==kind)) continue;
213     if(!(aName==aName1)) continue;
214     if(!(aDescription==aDescription1)) continue;
215     if(kind<20) {  //dimension
216       for(Standard_Integer i=1; i<=aVal->Length(); i++) {
217         if(Abs(aVal->Value(i)-aVal1->Value(i))>Precision::Confusion())
218           IsEqual = Standard_False;
219       }
220     }
221     else if(kind<50) { //tolerance
222       if(Abs(aVal->Value(1)-aVal1->Value(1))>Precision::Confusion())
223         IsEqual = Standard_False;
224     }
225     if(IsEqual) {
226       lab = DimTolL;
227       return Standard_True;
228     }
229   }
230   return Standard_False;
231 }
232
233
234 //=======================================================================
235 //function : FindDimTol
236 //purpose  : 
237 //=======================================================================
238
239 TDF_Label XCAFDoc_DimTolTool::FindDimTol(const Standard_Integer kind,
240                                          const Handle(TColStd_HArray1OfReal)& aVal,
241                                          const Handle(TCollection_HAsciiString)& aName,
242                                          const Handle(TCollection_HAsciiString)& aDescription) const
243 {
244   TDF_Label L;
245   FindDimTol(kind,aVal,aName,aDescription,L);
246   return L;
247 }
248
249
250 //=======================================================================
251 //function : AddDimTol
252 //purpose  : 
253 //=======================================================================
254
255 TDF_Label XCAFDoc_DimTolTool::AddDimTol(const Standard_Integer kind,
256                                         const Handle(TColStd_HArray1OfReal)& aVal,
257                                         const Handle(TCollection_HAsciiString)& aName,
258                                         const Handle(TCollection_HAsciiString)& aDescription) const
259 {
260   TDF_Label DimTolL;
261   TDF_TagSource aTag;
262   DimTolL = aTag.NewChild ( Label() );
263   XCAFDoc_DimTol::Set(DimTolL,kind,aVal,aName,aDescription);
264   TCollection_AsciiString str = "DGT:";
265   if(kind<20) str.AssignCat("Dimension");
266   else str.AssignCat("Tolerance");
267   TDataStd_Name::Set(DimTolL,str);
268   return DimTolL;
269 }
270
271 //=======================================================================
272 //function : AddDimension
273 //purpose  : 
274 //=======================================================================
275
276 TDF_Label XCAFDoc_DimTolTool::AddDimension()
277 {
278   TDF_Label aDimTolL;
279   TDF_TagSource aTag;
280   aDimTolL = aTag.NewChild ( Label() );
281   Handle(XCAFDoc_Dimension) aDim = XCAFDoc_Dimension::Set(aDimTolL);
282   TCollection_AsciiString aStr = "DGT:Dimension";
283   TDataStd_Name::Set(aDimTolL,aStr);
284   return aDimTolL;
285 }
286
287 //=======================================================================
288 //function : AddGeomTolerance
289 //purpose  : 
290 //=======================================================================
291
292 TDF_Label XCAFDoc_DimTolTool::AddGeomTolerance()
293 {
294   TDF_Label aDimTolL;
295   TDF_TagSource aTag;
296   aDimTolL = aTag.NewChild ( Label() );
297   Handle(XCAFDoc_GeomTolerance) aTol = XCAFDoc_GeomTolerance::Set(aDimTolL);
298   TCollection_AsciiString aStr = "DGT:Tolerance";
299   TDataStd_Name::Set(aDimTolL,aStr);
300   return aDimTolL;
301 }
302
303 //=======================================================================
304 //function : SetDimension
305 //purpose  : 
306 //=======================================================================
307
308 void XCAFDoc_DimTolTool::SetDimension(const TDF_Label& theL,
309                                    const TDF_Label& theDimTolL) const
310 {
311   TDF_Label nullLab;
312   SetDimension(theL, nullLab, theDimTolL);
313 }
314
315 //=======================================================================
316 //function : SetDimension
317 //purpose  : 
318 //=======================================================================
319
320 void XCAFDoc_DimTolTool::SetDimension(const TDF_Label& theFirstL,
321                                    const TDF_Label& theSecondL,
322                                    const TDF_Label& theDimTolL) const
323 {
324   TDF_LabelSequence aFirstLS, aSecondLS;
325   if(!theFirstL.IsNull())
326     aFirstLS.Append(theFirstL);
327   if(!theSecondL.IsNull())
328     aSecondLS.Append(theSecondL);
329   SetDimension(aFirstLS, aSecondLS, theDimTolL);
330 }
331
332 //=======================================================================
333 //function : SetDimension
334 //purpose  : 
335 //=======================================================================
336
337 void XCAFDoc_DimTolTool::SetDimension(const TDF_LabelSequence& theFirstL,
338                                    const TDF_LabelSequence& theSecondL,
339                                    const TDF_Label& theDimTolL) const
340 {
341   if(!IsDimension(theDimTolL) || theFirstL.Length() == 0)
342   {
343     return;
344   }
345
346   Handle(XCAFDoc_GraphNode) aChGNode;
347   Handle(XCAFDoc_GraphNode) aFGNode;
348   Handle(XCAFDoc_GraphNode) aSecondFGNode;
349
350   if ( theDimTolL.FindAttribute (XCAFDoc::DimensionRefFirstGUID(), aChGNode) ) {
351     while (aChGNode->NbFathers() > 0) {
352       aFGNode = aChGNode->GetFather(1);
353       aFGNode->UnSetChild(aChGNode);
354       if(aFGNode->NbChildren() == 0)
355         aFGNode->ForgetAttribute( XCAFDoc::DimensionRefFirstGUID() );
356     }
357     theDimTolL.ForgetAttribute ( XCAFDoc::DimensionRefFirstGUID() );
358   }
359   if ( theDimTolL.FindAttribute (XCAFDoc::DimensionRefSecondGUID(), aChGNode) ) {
360     while (aChGNode->NbFathers() > 0) {
361       aFGNode = aChGNode->GetFather(1);
362       aFGNode->UnSetChild(aChGNode);
363       if(aFGNode->NbChildren() == 0)
364         aFGNode->ForgetAttribute( XCAFDoc::DimensionRefSecondGUID() );
365     }
366     theDimTolL.ForgetAttribute ( XCAFDoc::DimensionRefSecondGUID() );
367   }
368
369   if (!theDimTolL.FindAttribute(XCAFDoc::DimensionRefFirstGUID(), aChGNode)) {
370     aChGNode = new XCAFDoc_GraphNode;
371     aChGNode = XCAFDoc_GraphNode::Set(theDimTolL);
372     aChGNode->SetGraphID(XCAFDoc::DimensionRefFirstGUID());
373   }
374   for(Standard_Integer i = theFirstL.Lower(); i <= theFirstL.Upper(); i++)
375   {
376     if (!theFirstL.Value(i).FindAttribute(XCAFDoc::DimensionRefFirstGUID(), aFGNode) ) {
377       aFGNode = new XCAFDoc_GraphNode;
378       aFGNode = XCAFDoc_GraphNode::Set(theFirstL.Value(i));
379     }
380     aFGNode->SetGraphID(XCAFDoc::DimensionRefFirstGUID());
381     aFGNode->SetChild(aChGNode);
382     aChGNode->SetFather(aFGNode);
383   }
384
385   if (!theDimTolL.FindAttribute(XCAFDoc::DimensionRefSecondGUID(), aChGNode) && theSecondL.Length() > 0) {
386     aChGNode = new XCAFDoc_GraphNode;
387     aChGNode = XCAFDoc_GraphNode::Set(theDimTolL);
388     aChGNode->SetGraphID(XCAFDoc::DimensionRefSecondGUID());
389   }
390   for(Standard_Integer i = theSecondL.Lower(); i <= theSecondL.Upper(); i++)
391   {
392     if(!theSecondL.Value(i).FindAttribute(XCAFDoc::DimensionRefSecondGUID(), aSecondFGNode) ) {
393       aSecondFGNode = new XCAFDoc_GraphNode;
394       aSecondFGNode = XCAFDoc_GraphNode::Set(theSecondL.Value(i));
395     }
396     aSecondFGNode->SetGraphID(XCAFDoc::DimensionRefSecondGUID());
397     aSecondFGNode->SetChild(aChGNode);
398     aChGNode->SetFather(aSecondFGNode);
399   }
400 }
401
402 //=======================================================================
403 //function : SetGeomTolerance
404 //purpose  : 
405 //=======================================================================
406
407 void XCAFDoc_DimTolTool::SetGeomTolerance(const TDF_Label& theL,
408                                    const TDF_Label& theDimTolL) const
409 {
410   TDF_LabelSequence aSeq;
411   aSeq.Append(theL);
412   SetGeomTolerance(aSeq, theDimTolL);
413 }
414
415 //=======================================================================
416 //function : SetGeomTolerance
417 //purpose  : 
418 //=======================================================================
419
420 void XCAFDoc_DimTolTool::SetGeomTolerance(const TDF_LabelSequence& theL,
421                                    const TDF_Label& theDimTolL) const
422 {
423   //  // set reference
424   //  Handle(TDataStd_TreeNode) refNode, mainNode;
425   //  refNode = TDataStd_TreeNode::Set ( theDimTolL, XCAFDoc::GeomToleranceRefGUID() );
426   //  mainNode  = TDataStd_TreeNode::Set ( theL,       XCAFDoc::GeomToleranceRefGUID() );
427   //  refNode->Remove(); // abv: fix against bug in TreeNode::Append()
428   //  mainNode->Append(refNode);
429   
430   if(!IsGeomTolerance(theDimTolL) ||  theL.Length() == 0)
431   {
432     return;
433   }
434
435   Handle(XCAFDoc_GraphNode) aChGNode;
436   Handle(XCAFDoc_GraphNode) aFGNode;
437
438   //Handle(XCAFDoc_GraphNode) ChGNode, FGNode;
439   if ( theDimTolL.FindAttribute (XCAFDoc::GeomToleranceRefGUID(), aChGNode) ) {
440     while (aChGNode->NbFathers() > 0) {
441       aFGNode = aChGNode->GetFather(1);
442       aFGNode->UnSetChild(aChGNode);
443       if(aFGNode->NbChildren() == 0)
444         aFGNode->ForgetAttribute( XCAFDoc::GeomToleranceRefGUID() );
445     }
446     theDimTolL.ForgetAttribute ( XCAFDoc::GeomToleranceRefGUID() );
447   }
448
449   if (!theDimTolL.FindAttribute(XCAFDoc::GeomToleranceRefGUID(), aChGNode)) {
450     aChGNode = new XCAFDoc_GraphNode;
451     aChGNode = XCAFDoc_GraphNode::Set(theDimTolL);
452     aChGNode->SetGraphID(XCAFDoc::GeomToleranceRefGUID());
453   }
454   for(Standard_Integer i = theL.Lower(); i <= theL.Upper(); i++)
455   {
456     if (!theL.Value(i).FindAttribute(XCAFDoc::GeomToleranceRefGUID(), aFGNode) ) {
457       aFGNode = new XCAFDoc_GraphNode;
458       aFGNode = XCAFDoc_GraphNode::Set(theL.Value(i));
459     }
460     aFGNode->SetGraphID(XCAFDoc::GeomToleranceRefGUID());
461     aFGNode->SetChild(aChGNode);
462     aChGNode->SetFather(aFGNode);
463   }
464 }
465
466 //=======================================================================
467 //function : SetDimTol
468 //purpose  : 
469 //=======================================================================
470
471 void XCAFDoc_DimTolTool::SetDimTol(const TDF_Label& theL,
472                                    const TDF_Label& theDimTolL) const
473 {
474   // set reference
475   Handle(TDataStd_TreeNode) refNode, mainNode;
476   refNode = TDataStd_TreeNode::Set ( theDimTolL, XCAFDoc::DimTolRefGUID() );
477   mainNode  = TDataStd_TreeNode::Set (theL,       XCAFDoc::DimTolRefGUID() );
478   refNode->Remove(); // abv: fix against bug in TreeNode::Append()
479   mainNode->Append(refNode);
480 }
481
482
483 //=======================================================================
484 //function : SetDimTol
485 //purpose  : 
486 //=======================================================================
487
488 TDF_Label XCAFDoc_DimTolTool::SetDimTol(const TDF_Label& L,
489                                         const Standard_Integer kind,
490                                         const Handle(TColStd_HArray1OfReal)& aVal,
491                                         const Handle(TCollection_HAsciiString)& aName,
492                                         const Handle(TCollection_HAsciiString)& aDescription) const
493 {
494   TDF_Label DimTolL = AddDimTol(kind,aVal,aName,aDescription);
495   SetDimTol(L,DimTolL);
496   return DimTolL;
497 }
498
499
500 //=======================================================================
501 //function : GetRefShapeLabel
502 //purpose  : 
503 //=======================================================================
504
505 Standard_Boolean XCAFDoc_DimTolTool::GetRefShapeLabel(const TDF_Label& theL,
506                                                       TDF_LabelSequence& theShapeLFirst,
507                                                       TDF_LabelSequence& theShapeLSecond) const
508 {
509   theShapeLFirst.Clear();
510   theShapeLSecond.Clear();
511   Handle(TDataStd_TreeNode) aNode;
512   if( !theL.FindAttribute(XCAFDoc::DimTolRefGUID(),aNode) || !aNode->HasFather() ) {
513     if( !theL.FindAttribute(XCAFDoc::DatumRefGUID(),aNode) || !aNode->HasFather() ) {
514       Handle(XCAFDoc_GraphNode) aGNode;
515       if( theL.FindAttribute(XCAFDoc::GeomToleranceRefGUID(),aGNode) && aGNode->NbFathers() > 0 ) {
516         for(Standard_Integer i = 1; i <= aGNode->NbFathers(); i++)
517         {
518           theShapeLFirst.Append(aGNode->GetFather(i)->Label());
519         }
520         return Standard_True;
521       }
522       else if (theL.FindAttribute(XCAFDoc::DatumRefGUID(), aGNode) && aGNode->NbFathers() > 0) {
523         for (Standard_Integer i = 1; i <= aGNode->NbFathers(); i++)
524         {
525           theShapeLFirst.Append(aGNode->GetFather(i)->Label());
526         }
527         return Standard_True;
528       }
529       else if( theL.FindAttribute(XCAFDoc::DimensionRefFirstGUID(),aGNode) && aGNode->NbFathers() > 0 ) {
530         for(Standard_Integer i = 1; i <= aGNode->NbFathers(); i++)
531         {
532           theShapeLFirst.Append(aGNode->GetFather(i)->Label());
533         }
534         if( theL.FindAttribute(XCAFDoc::DimensionRefSecondGUID(),aGNode) && aGNode->NbFathers() > 0 ) {
535           for(Standard_Integer i = 1; i <= aGNode->NbFathers(); i++)
536           {
537             theShapeLSecond.Append(aGNode->GetFather(i)->Label());
538           }
539         }
540         return Standard_True;
541       }
542       else
543       {
544         return Standard_False;
545       }
546     }
547   }
548
549   theShapeLFirst.Append(aNode->Father()->Label());
550   return Standard_True;
551 }
552
553 //=======================================================================
554 //function : GetRefDimensionLabels
555 //purpose  : 
556 //=======================================================================
557
558 Standard_Boolean XCAFDoc_DimTolTool::GetRefDimensionLabels(const TDF_Label& theShapeL,
559                                                      TDF_LabelSequence& theDimTols) const
560 {
561   Handle(XCAFDoc_GraphNode) aGNode;
562   Standard_Boolean aResult = Standard_False;
563   if( theShapeL.FindAttribute(XCAFDoc::DimensionRefFirstGUID(),aGNode) && aGNode->NbChildren() > 0 ) {
564     for(Standard_Integer i = 1; i <= aGNode->NbChildren(); i++)
565     {
566       theDimTols.Append(aGNode->GetChild(i)->Label());
567     }
568     aResult = Standard_True;
569   }
570   if( theShapeL.FindAttribute(XCAFDoc::DimensionRefSecondGUID(),aGNode) && aGNode->NbChildren() > 0 ) {
571     for(Standard_Integer i = 1; i <= aGNode->NbChildren(); i++)
572     {
573       theDimTols.Append(aGNode->GetChild(i)->Label());
574     }
575     aResult = Standard_True;
576   }
577   return aResult;
578 }
579
580 //=======================================================================
581 //function : GetRefGeomToleranceLabels
582 //purpose  : 
583 //=======================================================================
584
585 Standard_Boolean XCAFDoc_DimTolTool::GetRefGeomToleranceLabels(const TDF_Label& theShapeL,
586                                                      TDF_LabelSequence& theDimTols) const
587 {
588   Handle(XCAFDoc_GraphNode) aGNode;
589   if( !theShapeL.FindAttribute(XCAFDoc::GeomToleranceRefGUID(),aGNode) ||
590     aGNode->NbChildren() == 0 ) {
591     return Standard_False;
592   }
593   for(Standard_Integer i = 1; i <= aGNode->NbChildren(); i++)
594   {
595     theDimTols.Append(aGNode->GetChild(i)->Label());
596   }
597   return Standard_True;
598 }
599
600 //=======================================================================
601 //function : GetRefDatumLabel
602 //purpose  : 
603 //=======================================================================
604
605 Standard_Boolean XCAFDoc_DimTolTool::GetRefDatumLabel(const TDF_Label& theShapeL,
606                                                      TDF_LabelSequence& theDatum) const
607 {
608   Handle(XCAFDoc_GraphNode) aGNode;
609   if (!theShapeL.FindAttribute(XCAFDoc::DatumRefGUID(), aGNode)) {
610     return Standard_False;
611   }
612   for (Standard_Integer i = 1; i <= aGNode->NbChildren(); i++) {
613     theDatum.Append(aGNode->GetChild(i)->Label());
614   }
615   return Standard_True;
616 }
617
618 //=======================================================================
619 //function : GetDimTol
620 //purpose  : 
621 //=======================================================================
622
623 Standard_Boolean XCAFDoc_DimTolTool::GetDimTol(const TDF_Label& DimTolL,
624                                                Standard_Integer& kind,
625                                                Handle(TColStd_HArray1OfReal)& aVal,
626                                                Handle(TCollection_HAsciiString)& aName,
627                                                Handle(TCollection_HAsciiString)& aDescription) const
628 {
629   Handle(XCAFDoc_DimTol) DimTolAttr;
630   if(!DimTolL.FindAttribute(XCAFDoc_DimTol::GetID(),DimTolAttr)) {
631     return Standard_False;
632   }
633   kind = DimTolAttr->GetKind();
634   aVal = DimTolAttr->GetVal();
635   aName = DimTolAttr->GetName();
636   aDescription = DimTolAttr->GetDescription();
637   
638   return Standard_True;
639 }
640
641
642 //=======================================================================
643 //function : IsDatum
644 //purpose  : 
645 //=======================================================================
646
647 Standard_Boolean XCAFDoc_DimTolTool::IsDatum(const TDF_Label& theDimTolL) const
648 {
649   Handle(XCAFDoc_Datum) aDatumAttr;
650   if(theDimTolL.FindAttribute(XCAFDoc_Datum::GetID(),aDatumAttr)) {
651     return Standard_True;
652   }
653   return Standard_False;
654 }
655
656
657 //=======================================================================
658 //function : GetDatumLabels
659 //purpose  : 
660 //=======================================================================
661
662 void XCAFDoc_DimTolTool::GetDatumLabels(TDF_LabelSequence& theLabels) const
663 {
664   theLabels.Clear();
665   TDF_ChildIterator aChildIterator( Label() ); 
666   for (; aChildIterator.More(); aChildIterator.Next()) {
667     TDF_Label L = aChildIterator.Value();
668     if ( IsDatum(L)) theLabels.Append(L);
669   }
670 }
671
672 //=======================================================================
673 //function : FindDatum
674 //purpose  : 
675 //=======================================================================
676
677 Standard_Boolean XCAFDoc_DimTolTool::FindDatum(const Handle(TCollection_HAsciiString)& aName,
678                                                const Handle(TCollection_HAsciiString)& aDescription,
679                                                const Handle(TCollection_HAsciiString)& anIdentification,
680                                                TDF_Label& lab) const
681 {
682   TDF_ChildIDIterator it(Label(),XCAFDoc_Datum::GetID());
683   for(; it.More(); it.Next()) {
684     Handle(TCollection_HAsciiString) aName1, aDescription1, anIdentification1;
685     TDF_Label aLabel = it.Value()->Label();
686     if ( !GetDatum( aLabel, aName1, aDescription1, anIdentification1 ) )
687       continue;
688     if(!(aName==aName1)) continue;
689     if(!(aDescription==aDescription1)) continue;
690     if(!(anIdentification==anIdentification1)) continue;
691     lab = aLabel;
692     return Standard_True;
693   }
694   return Standard_False;
695 }
696
697
698 //=======================================================================
699 //function : AddDatum
700 //purpose  : 
701 //=======================================================================
702
703 TDF_Label XCAFDoc_DimTolTool::AddDatum(const Handle(TCollection_HAsciiString)& aName,
704                                        const Handle(TCollection_HAsciiString)& aDescription,
705                                        const Handle(TCollection_HAsciiString)& anIdentification) const
706 {
707   TDF_Label DatumL;
708   TDF_TagSource aTag;
709   DatumL = aTag.NewChild ( Label() );
710   XCAFDoc_Datum::Set(DatumL,aName,aDescription,anIdentification);
711   TDataStd_Name::Set(DatumL,"DGT:Datum");
712   return DatumL;
713 }
714
715 //=======================================================================
716 //function : AddDatum
717 //purpose  : 
718 //=======================================================================
719
720 TDF_Label XCAFDoc_DimTolTool::AddDatum()
721 {
722   TDF_Label aDatumL;
723   TDF_TagSource aTag;
724   aDatumL = aTag.NewChild ( Label() );
725   Handle(XCAFDoc_Datum) aDat = XCAFDoc_Datum::Set(aDatumL);
726   TDataStd_Name::Set(aDatumL,"DGT:Datum");
727   return aDatumL;
728 }
729
730 //=======================================================================
731 //function : SetDatum
732 //purpose  : 
733 //=======================================================================
734
735 void XCAFDoc_DimTolTool::SetDatum(const TDF_LabelSequence& theL,
736                                   const TDF_Label& theDatumL) const
737 {
738   if (!IsDatum(theDatumL))
739   {
740     return;
741   }
742
743   Handle(XCAFDoc_GraphNode) aChGNode;
744   Handle(XCAFDoc_GraphNode) aFGNode;
745
746   if (theDatumL.FindAttribute(XCAFDoc::DatumRefGUID(), aChGNode)) {
747     while (aChGNode->NbFathers() > 0) {
748       aFGNode = aChGNode->GetFather(1);
749       aFGNode->UnSetChild(aChGNode);
750       if (aFGNode->NbChildren() == 0)
751         aFGNode->ForgetAttribute(XCAFDoc::DatumRefGUID());
752     }
753     theDatumL.ForgetAttribute(XCAFDoc::DatumRefGUID());
754   }
755
756   if (!theDatumL.FindAttribute(XCAFDoc::DatumRefGUID(), aChGNode)) {
757     aChGNode = new XCAFDoc_GraphNode;
758     aChGNode = XCAFDoc_GraphNode::Set(theDatumL);
759     aChGNode->SetGraphID(XCAFDoc::DatumRefGUID());
760   }
761   for (Standard_Integer i = theL.Lower(); i <= theL.Upper(); i++)
762   {
763     if (!theL.Value(i).FindAttribute(XCAFDoc::DatumRefGUID(), aFGNode)) {
764       aFGNode = new XCAFDoc_GraphNode;
765       aFGNode = XCAFDoc_GraphNode::Set(theL.Value(i));
766     }
767     aFGNode->SetGraphID(XCAFDoc::DatumRefGUID());
768     aFGNode->SetChild(aChGNode);
769     aChGNode->SetFather(aFGNode);
770   }
771 }
772
773 //=======================================================================
774 //function : SetDatum
775 //purpose  : 
776 //=======================================================================
777
778 void XCAFDoc_DimTolTool::SetDatum(const TDF_Label& L,
779                                   const TDF_Label& TolerL,
780                                   const Handle(TCollection_HAsciiString)& aName,
781                                   const Handle(TCollection_HAsciiString)& aDescription,
782                                   const Handle(TCollection_HAsciiString)& anIdentification) const
783 {
784   TDF_Label DatumL;
785   if(!FindDatum(aName,aDescription,anIdentification,DatumL))
786     DatumL = AddDatum(aName,aDescription,anIdentification);
787   TDF_LabelSequence aLabels;
788   aLabels.Append(L);
789   SetDatum(aLabels,DatumL);
790   // set reference
791   Handle(XCAFDoc_GraphNode) FGNode;
792   Handle(XCAFDoc_GraphNode) ChGNode;
793   if (! TolerL.FindAttribute( XCAFDoc::DatumTolRefGUID(), FGNode) ) {
794     FGNode = new XCAFDoc_GraphNode;
795     FGNode = XCAFDoc_GraphNode::Set(TolerL);
796   }
797   if (! DatumL.FindAttribute( XCAFDoc::DatumTolRefGUID(), ChGNode) ) {
798     ChGNode = new XCAFDoc_GraphNode;
799     ChGNode = XCAFDoc_GraphNode::Set(DatumL);
800   }
801   FGNode->SetGraphID( XCAFDoc::DatumTolRefGUID() );
802   ChGNode->SetGraphID( XCAFDoc::DatumTolRefGUID() );
803   FGNode->SetChild(ChGNode);
804   ChGNode->SetFather(FGNode);
805 }
806
807 //=======================================================================
808 //function : SetDatumToGeomTol
809 //purpose  : 
810 //=======================================================================
811
812 void XCAFDoc_DimTolTool::SetDatumToGeomTol(const TDF_Label& theDatumL,
813                                            const TDF_Label& theTolerL) const
814 {
815   // set reference
816   Handle(XCAFDoc_GraphNode) aFGNode;
817   Handle(XCAFDoc_GraphNode) aChGNode;
818   if (! theTolerL.FindAttribute( XCAFDoc::DatumTolRefGUID(), aFGNode) ) {
819     aFGNode = new XCAFDoc_GraphNode;
820     aFGNode = XCAFDoc_GraphNode::Set(theTolerL);
821   }
822   if (! theDatumL.FindAttribute( XCAFDoc::DatumTolRefGUID(), aChGNode) ) {
823     aChGNode = new XCAFDoc_GraphNode;
824     aChGNode = XCAFDoc_GraphNode::Set(theDatumL);
825   }
826   aFGNode->SetGraphID( XCAFDoc::DatumTolRefGUID() );
827   aChGNode->SetGraphID( XCAFDoc::DatumTolRefGUID() );
828   aFGNode->SetChild(aChGNode);
829   aChGNode->SetFather(aFGNode);
830 }
831
832 //=======================================================================
833 //function : GetDatum
834 //purpose  : 
835 //=======================================================================
836
837 Standard_Boolean XCAFDoc_DimTolTool::GetDatum(const TDF_Label& theDatumL,
838                                               Handle(TCollection_HAsciiString)& theName,
839                                               Handle(TCollection_HAsciiString)& theDescription,
840                                               Handle(TCollection_HAsciiString)& theIdentification) const
841 {
842   Handle(XCAFDoc_Datum) aDatumAttr;
843   if( theDatumL.IsNull() || 
844       !theDatumL.FindAttribute(XCAFDoc_Datum::GetID(),aDatumAttr) )
845     return Standard_False;
846   
847   theName = aDatumAttr->GetName();
848   theDescription = aDatumAttr->GetDescription();
849   theIdentification = aDatumAttr->GetIdentification();
850   return Standard_True;
851 }
852
853 //=======================================================================
854 //function : GetDatumTolerLabels
855 //purpose  : 
856 //=======================================================================
857
858 Standard_Boolean XCAFDoc_DimTolTool::GetDatumOfTolerLabels(const TDF_Label& theDimTolL,
859                                                          TDF_LabelSequence& theDatums) const
860 {
861   Handle(XCAFDoc_GraphNode) aNode;
862   if( !theDimTolL.FindAttribute(XCAFDoc::DatumTolRefGUID(),aNode) )
863     return Standard_False;
864
865   for(Standard_Integer i=1; i<=aNode->NbChildren(); i++) {
866     Handle(XCAFDoc_GraphNode) aDatumNode = aNode->GetChild(i);
867     theDatums.Append(aDatumNode->Label());
868   }
869   return Standard_True;
870 }
871
872 //=======================================================================
873 //function : GetDatumWthObjectsTolerLabels
874 //purpose  : 
875 //=======================================================================
876
877 Standard_Boolean XCAFDoc_DimTolTool::GetDatumWithObjectOfTolerLabels(const TDF_Label& theDimTolL,
878                                                                      TDF_LabelSequence& theDatums) const
879 {
880   Handle(XCAFDoc_GraphNode) aNode;
881   if( !theDimTolL.FindAttribute(XCAFDoc::DatumTolRefGUID(),aNode) )
882     return Standard_False;
883
884   TColStd_MapOfAsciiString aDatumNameMap;
885   for(Standard_Integer i=1; i<=aNode->NbChildren(); i++) {
886     Handle(XCAFDoc_GraphNode) aDatumNode = aNode->GetChild(i);
887     TDF_Label aDatumL = aDatumNode->Label();
888     Handle(XCAFDoc_Datum) aDatumAttr;
889     if (!aDatumL.FindAttribute(XCAFDoc_Datum::GetID(), aDatumAttr)) 
890       continue;
891     Handle(XCAFDimTolObjects_DatumObject) aDatumObj = aDatumAttr->GetObject();
892     if (aDatumObj.IsNull())
893       continue;
894     Handle(TCollection_HAsciiString) aName = aDatumObj->GetName();
895     if (!aDatumNameMap.Add(aName->String())) {
896       // the datum has already been appended to sequence, due to one of its datum targets
897       continue;
898     }
899     theDatums.Append(aDatumNode->Label());
900   }
901   return Standard_True;
902 }
903
904 //=======================================================================
905 //function : GetTolerDatumLabels
906 //purpose  : 
907 //=======================================================================
908
909 Standard_Boolean XCAFDoc_DimTolTool::GetTolerOfDatumLabels(const TDF_Label& theDatumL,
910                                                          TDF_LabelSequence& theTols) const
911 {
912   Handle(XCAFDoc_GraphNode) aNode;
913   if( !theDatumL.FindAttribute(XCAFDoc::DatumTolRefGUID(),aNode) )
914     return Standard_False;
915   for(Standard_Integer i=1; i<=aNode->NbFathers(); i++) {
916     Handle(XCAFDoc_GraphNode) aDatumNode = aNode->GetFather(i);
917     theTols.Append(aDatumNode->Label());
918   }
919   return Standard_True;
920 }
921
922 //=======================================================================
923 //function : IsLocked
924 //purpose  : 
925 //=======================================================================
926
927 Standard_Boolean XCAFDoc_DimTolTool::IsLocked(const TDF_Label& theViewL) const
928 {
929   Handle(TDataStd_UAttribute) anAttr;
930   return theViewL.FindAttribute(XCAFDoc::LockGUID(), anAttr);
931 }
932
933 //=======================================================================
934 //function : Lock
935 //purpose  : 
936 //=======================================================================
937
938 void XCAFDoc_DimTolTool::Lock(const TDF_Label& theViewL) const
939 {
940   TDataStd_UAttribute::Set(theViewL, XCAFDoc::LockGUID());
941 }
942
943 //=======================================================================
944 //function : Unlock
945 //purpose  : 
946 //=======================================================================
947
948 void XCAFDoc_DimTolTool::Unlock(const TDF_Label& theViewL) const
949 {
950   theViewL.ForgetAttribute(XCAFDoc::LockGUID());
951 }
952
953 //=======================================================================
954 //function : ID
955 //purpose  : 
956 //=======================================================================
957
958 const Standard_GUID& XCAFDoc_DimTolTool::ID() const
959 {
960   return GetID();
961 }
962
963
964 //=======================================================================
965 //function : Restore
966 //purpose  : 
967 //=======================================================================
968
969 void XCAFDoc_DimTolTool::Restore(const Handle(TDF_Attribute)& /*with*/) 
970 {
971 }
972
973
974 //=======================================================================
975 //function : NewEmpty
976 //purpose  : 
977 //=======================================================================
978
979 Handle(TDF_Attribute) XCAFDoc_DimTolTool::NewEmpty() const
980 {
981   return new XCAFDoc_DimTolTool;
982 }
983
984
985 //=======================================================================
986 //function : Paste
987 //purpose  : 
988 //=======================================================================
989
990 void XCAFDoc_DimTolTool::Paste(const Handle(TDF_Attribute)& /*into*/,
991                                const Handle(TDF_RelocationTable)& /*RT*/) const
992 {
993 }
994