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