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