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