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