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