0026859: Export of GDT from XCAF to STEP
[occt.git] / src / XCAFDoc / XCAFDoc_DimTolTool.cxx
old mode 100755 (executable)
new mode 100644 (file)
index c1c2be0..c488fdd
@@ -1,38 +1,43 @@
-// Copyright (c) 1999-2012 OPEN CASCADE SAS
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
 //
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
 //
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
 //
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
 
-#include <XCAFDoc_DimTolTool.ixx>
 
+#include <Precision.hxx>
+#include <Standard_GUID.hxx>
+#include <Standard_Type.hxx>
+#include <TCollection_HAsciiString.hxx>
+#include <TColStd_MapOfAsciiString.hxx>
+#include <TDataStd_Name.hxx>
+#include <TDataStd_TreeNode.hxx>
+#include <TDF_Attribute.hxx>
+#include <TDF_ChildIDIterator.hxx>
+#include <TDF_Label.hxx>
+#include <TDF_RelocationTable.hxx>
+#include <XCAFDimTolObjects_DatumObject.hxx>
 #include <XCAFDoc.hxx>
-#include <XCAFDoc_DimTol.hxx>
+#include <XCAFDoc_Dimension.hxx>
+#include <XCAFDoc_GeomTolerance.hxx>
 #include <XCAFDoc_Datum.hxx>
+#include <XCAFDoc_DimTol.hxx>
+#include <XCAFDoc_DimTolTool.hxx>
 #include <XCAFDoc_DocumentTool.hxx>
 #include <XCAFDoc_GraphNode.hxx>
-#include <TDataStd_TreeNode.hxx>
-#include <TDataStd_Name.hxx>
-#include <TDF_ChildIDIterator.hxx>
-#include <Precision.hxx>
-
+#include <XCAFDoc_ShapeTool.hxx>
 
 //=======================================================================
 //function : XCAFDoc_DimTolTool
 //purpose  : 
 //=======================================================================
-
 XCAFDoc_DimTolTool::XCAFDoc_DimTolTool()
 {
 }
@@ -96,31 +101,87 @@ const Handle(XCAFDoc_ShapeTool)& XCAFDoc_DimTolTool::ShapeTool()
 //purpose  : 
 //=======================================================================
 
-Standard_Boolean XCAFDoc_DimTolTool::IsDimTol(const TDF_Label& DimTolL) const
+Standard_Boolean XCAFDoc_DimTolTool::IsDimTol(const TDF_Label& theDimTolL) const
 {
-  Handle(XCAFDoc_DimTol) DimTolAttr;
-  if(DimTolL.FindAttribute(XCAFDoc_DimTol::GetID(),DimTolAttr)) {
+  Handle(XCAFDoc_DimTol) aDimTolAttr;
+  if(theDimTolL.FindAttribute(XCAFDoc_DimTol::GetID(),aDimTolAttr)) {
     return Standard_True;
   }
   return Standard_False;
 }
 
+//=======================================================================
+//function : IsDimension
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean XCAFDoc_DimTolTool::IsDimension(const TDF_Label& theDimTolL) const
+{
+  Handle(XCAFDoc_Dimension) aDimTolAttr;
+  if(theDimTolL.FindAttribute(XCAFDoc_Dimension::GetID(),aDimTolAttr)) {
+    return Standard_True;
+  }
+  return Standard_False;
+}
+
+//=======================================================================
+//function : IsGeomTolerance
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean XCAFDoc_DimTolTool::IsGeomTolerance(const TDF_Label& theDimTolL) const
+{
+  Handle(XCAFDoc_GeomTolerance) aDimTolAttr;
+  if(theDimTolL.FindAttribute(XCAFDoc_GeomTolerance::GetID(),aDimTolAttr)) {
+    return Standard_True;
+  }
+  return Standard_False;
+}
 
 //=======================================================================
 //function : GetDimTolLabels
 //purpose  : 
 //=======================================================================
 
-void XCAFDoc_DimTolTool::GetDimTolLabels(TDF_LabelSequence& Labels) const
+void XCAFDoc_DimTolTool::GetDimTolLabels(TDF_LabelSequence& theLabels) const
+{
+  theLabels.Clear();
+  TDF_ChildIterator aChildIterator( Label() ); 
+  for (; aChildIterator.More(); aChildIterator.Next()) {
+    TDF_Label aL = aChildIterator.Value();
+    if ( IsDimTol(aL)) theLabels.Append(aL);
+  }
+}
+
+//=======================================================================
+//function : GetDimensionLabels
+//purpose  : 
+//=======================================================================
+
+void XCAFDoc_DimTolTool::GetDimensionLabels(TDF_LabelSequence& theLabels) const
 {
-  Labels.Clear();
-  TDF_ChildIterator ChildIterator( Label() ); 
-  for (; ChildIterator.More(); ChildIterator.Next()) {
-    TDF_Label L = ChildIterator.Value();
-    if ( IsDimTol(L)) Labels.Append(L);
+  theLabels.Clear();
+  TDF_ChildIterator aChildIterator( Label() ); 
+  for (; aChildIterator.More(); aChildIterator.Next()) {
+    TDF_Label aL = aChildIterator.Value();
+    if ( IsDimension(aL)) theLabels.Append(aL);
   }
 }
 
+//=======================================================================
+//function : GetGeomToleranceLabels
+//purpose  : 
+//=======================================================================
+
+void XCAFDoc_DimTolTool::GetGeomToleranceLabels(TDF_LabelSequence& theLabels) const
+{
+  theLabels.Clear();
+  TDF_ChildIterator aChildIterator( Label() ); 
+  for (; aChildIterator.More(); aChildIterator.Next()) {
+    TDF_Label aL = aChildIterator.Value();
+    if ( IsGeomTolerance(aL)) theLabels.Append(aL);
+  }
+}
 
 //=======================================================================
 //function : FindDimTol
@@ -202,21 +263,213 @@ TDF_Label XCAFDoc_DimTolTool::AddDimTol(const Standard_Integer kind,
   return DimTolL;
 }
 
+//=======================================================================
+//function : AddDimension
+//purpose  : 
+//=======================================================================
+
+TDF_Label XCAFDoc_DimTolTool::AddDimension()
+{
+  TDF_Label aDimTolL;
+  TDF_TagSource aTag;
+  aDimTolL = aTag.NewChild ( Label() );
+  Handle(XCAFDoc_Dimension) aDim = XCAFDoc_Dimension::Set(aDimTolL);
+  TCollection_AsciiString aStr = "DGT:Dimension";
+  TDataStd_Name::Set(aDimTolL,aStr);
+  return aDimTolL;
+}
+
+//=======================================================================
+//function : AddGeomTolerance
+//purpose  : 
+//=======================================================================
+
+TDF_Label XCAFDoc_DimTolTool::AddGeomTolerance()
+{
+  TDF_Label aDimTolL;
+  TDF_TagSource aTag;
+  aDimTolL = aTag.NewChild ( Label() );
+  Handle(XCAFDoc_GeomTolerance) aTol = XCAFDoc_GeomTolerance::Set(aDimTolL);
+  TCollection_AsciiString aStr = "DGT:Tolerance";
+  TDataStd_Name::Set(aDimTolL,aStr);
+  return aDimTolL;
+}
+
+//=======================================================================
+//function : SetDimension
+//purpose  : 
+//=======================================================================
+
+void XCAFDoc_DimTolTool::SetDimension(const TDF_Label& theL,
+                                   const TDF_Label& theDimTolL) const
+{
+  TDF_Label nullLab;
+  SetDimension(theL, nullLab, theDimTolL);
+}
+
+//=======================================================================
+//function : SetDimension
+//purpose  : 
+//=======================================================================
+
+void XCAFDoc_DimTolTool::SetDimension(const TDF_Label& theFirstL,
+                                   const TDF_Label& theSecondL,
+                                   const TDF_Label& theDimTolL) const
+{
+  TDF_LabelSequence aFirstLS, aSecondLS;
+  if(!theFirstL.IsNull())
+    aFirstLS.Append(theFirstL);
+  if(!theSecondL.IsNull())
+    aSecondLS.Append(theSecondL);
+  SetDimension(aFirstLS, aSecondLS, theDimTolL);
+}
+
+//=======================================================================
+//function : SetDimension
+//purpose  : 
+//=======================================================================
+
+void XCAFDoc_DimTolTool::SetDimension(const TDF_LabelSequence& theFirstL,
+                                   const TDF_LabelSequence& theSecondL,
+                                   const TDF_Label& theDimTolL) const
+{
+  if(!IsDimension(theDimTolL) || theFirstL.Length() == 0)
+  {
+    return;
+  }
+
+  Handle(XCAFDoc_GraphNode) aChGNode;
+  Handle(XCAFDoc_GraphNode) aFGNode;
+  Handle(XCAFDoc_GraphNode) aSecondFGNode;
+
+  if ( theDimTolL.FindAttribute (XCAFDoc::DimensionRefFirstGUID(), aChGNode) ) {
+    while (aChGNode->NbFathers() > 0) {
+      aFGNode = aChGNode->GetFather(1);
+      aFGNode->UnSetChild(aChGNode);
+      if(aFGNode->NbChildren() == 0)
+        aFGNode->ForgetAttribute( XCAFDoc::DimensionRefFirstGUID() );
+    }
+    theDimTolL.ForgetAttribute ( XCAFDoc::DimensionRefFirstGUID() );
+  }
+  if ( theDimTolL.FindAttribute (XCAFDoc::DimensionRefSecondGUID(), aChGNode) ) {
+    while (aChGNode->NbFathers() > 0) {
+      aFGNode = aChGNode->GetFather(1);
+      aFGNode->UnSetChild(aChGNode);
+      if(aFGNode->NbChildren() == 0)
+        aFGNode->ForgetAttribute( XCAFDoc::DimensionRefSecondGUID() );
+    }
+    theDimTolL.ForgetAttribute ( XCAFDoc::DimensionRefSecondGUID() );
+  }
+
+  if (!theDimTolL.FindAttribute(XCAFDoc::DimensionRefFirstGUID(), aChGNode)) {
+    aChGNode = new XCAFDoc_GraphNode;
+    aChGNode = XCAFDoc_GraphNode::Set(theDimTolL);
+    aChGNode->SetGraphID(XCAFDoc::DimensionRefFirstGUID());
+  }
+  for(Standard_Integer i = theFirstL.Lower(); i <= theFirstL.Upper(); i++)
+  {
+    if (!theFirstL.Value(i).FindAttribute(XCAFDoc::DimensionRefFirstGUID(), aFGNode) ) {
+      aFGNode = new XCAFDoc_GraphNode;
+      aFGNode = XCAFDoc_GraphNode::Set(theFirstL.Value(i));
+    }
+    aFGNode->SetGraphID(XCAFDoc::DimensionRefFirstGUID());
+    aFGNode->SetChild(aChGNode);
+    aChGNode->SetFather(aFGNode);
+  }
+
+  if (!theDimTolL.FindAttribute(XCAFDoc::DimensionRefSecondGUID(), aChGNode) && theSecondL.Length() > 0) {
+    aChGNode = new XCAFDoc_GraphNode;
+    aChGNode = XCAFDoc_GraphNode::Set(theDimTolL);
+    aChGNode->SetGraphID(XCAFDoc::DimensionRefSecondGUID());
+  }
+  for(Standard_Integer i = theSecondL.Lower(); i <= theSecondL.Upper(); i++)
+  {
+    if(!theSecondL.Value(i).FindAttribute(XCAFDoc::DimensionRefSecondGUID(), aSecondFGNode) ) {
+      aSecondFGNode = new XCAFDoc_GraphNode;
+      aSecondFGNode = XCAFDoc_GraphNode::Set(theSecondL.Value(i));
+    }
+    aSecondFGNode->SetGraphID(XCAFDoc::DimensionRefSecondGUID());
+    aSecondFGNode->SetChild(aChGNode);
+    aChGNode->SetFather(aSecondFGNode);
+  }
+}
+
+//=======================================================================
+//function : SetGeomTolerance
+//purpose  : 
+//=======================================================================
+
+void XCAFDoc_DimTolTool::SetGeomTolerance(const TDF_Label& theL,
+                                   const TDF_Label& theDimTolL) const
+{
+  TDF_LabelSequence aSeq;
+  aSeq.Append(theL);
+  SetGeomTolerance(aSeq, theDimTolL);
+}
+
+//=======================================================================
+//function : SetGeomTolerance
+//purpose  : 
+//=======================================================================
+
+void XCAFDoc_DimTolTool::SetGeomTolerance(const TDF_LabelSequence& theL,
+                                   const TDF_Label& theDimTolL) const
+{
+  //  // set reference
+  //  Handle(TDataStd_TreeNode) refNode, mainNode;
+  //  refNode = TDataStd_TreeNode::Set ( theDimTolL, XCAFDoc::GeomToleranceRefGUID() );
+  //  mainNode  = TDataStd_TreeNode::Set ( theL,       XCAFDoc::GeomToleranceRefGUID() );
+  //  refNode->Remove(); // abv: fix against bug in TreeNode::Append()
+  //  mainNode->Append(refNode);
+  
+  if(!IsGeomTolerance(theDimTolL) ||  theL.Length() == 0)
+  {
+    return;
+  }
+
+  Handle(XCAFDoc_GraphNode) aChGNode;
+  Handle(XCAFDoc_GraphNode) aFGNode;
+
+  //Handle(XCAFDoc_GraphNode) ChGNode, FGNode;
+  if ( theDimTolL.FindAttribute (XCAFDoc::GeomToleranceRefGUID(), aChGNode) ) {
+    while (aChGNode->NbFathers() > 0) {
+      aFGNode = aChGNode->GetFather(1);
+      aFGNode->UnSetChild(aChGNode);
+      if(aFGNode->NbChildren() == 0)
+        aFGNode->ForgetAttribute( XCAFDoc::GeomToleranceRefGUID() );
+    }
+    theDimTolL.ForgetAttribute ( XCAFDoc::GeomToleranceRefGUID() );
+  }
+
+  if (!theDimTolL.FindAttribute(XCAFDoc::GeomToleranceRefGUID(), aChGNode)) {
+    aChGNode = new XCAFDoc_GraphNode;
+    aChGNode = XCAFDoc_GraphNode::Set(theDimTolL);
+    aChGNode->SetGraphID(XCAFDoc::GeomToleranceRefGUID());
+  }
+  for(Standard_Integer i = theL.Lower(); i <= theL.Upper(); i++)
+  {
+    if (!theL.Value(i).FindAttribute(XCAFDoc::GeomToleranceRefGUID(), aFGNode) ) {
+      aFGNode = new XCAFDoc_GraphNode;
+      aFGNode = XCAFDoc_GraphNode::Set(theL.Value(i));
+    }
+    aFGNode->SetGraphID(XCAFDoc::GeomToleranceRefGUID());
+    aFGNode->SetChild(aChGNode);
+    aChGNode->SetFather(aFGNode);
+  }
+}
 
 //=======================================================================
 //function : SetDimTol
 //purpose  : 
 //=======================================================================
 
-void XCAFDoc_DimTolTool::SetDimTol(const TDF_Label& L,
-                                   const TDF_Label& DimTolL) const
+void XCAFDoc_DimTolTool::SetDimTol(const TDF_Label& theL,
+                                   const TDF_Label& theDimTolL) const
 {
   // set reference
   Handle(TDataStd_TreeNode) refNode, mainNode;
-//  mainNode = TDataStd_TreeNode::Set ( DimTolL, XCAFDoc::DimTolRefGUID() );
-//  refNode  = TDataStd_TreeNode::Set ( L,       XCAFDoc::DimTolRefGUID() );
-  refNode = TDataStd_TreeNode::Set ( DimTolL, XCAFDoc::DimTolRefGUID() );
-  mainNode  = TDataStd_TreeNode::Set ( L,       XCAFDoc::DimTolRefGUID() );
+  refNode = TDataStd_TreeNode::Set ( theDimTolL, XCAFDoc::DimTolRefGUID() );
+  mainNode  = TDataStd_TreeNode::Set (theL,       XCAFDoc::DimTolRefGUID() );
   refNode->Remove(); // abv: fix against bug in TreeNode::Append()
   mainNode->Append(refNode);
 }
@@ -244,42 +497,116 @@ TDF_Label XCAFDoc_DimTolTool::SetDimTol(const TDF_Label& L,
 //purpose  : 
 //=======================================================================
 
-Standard_Boolean XCAFDoc_DimTolTool::GetRefShapeLabel(const TDF_Label& L,
-                                                      TDF_Label& ShapeL) const
+Standard_Boolean XCAFDoc_DimTolTool::GetRefShapeLabel(const TDF_Label& theL,
+                                                      TDF_LabelSequence& theShapeLFirst,
+                                                      TDF_LabelSequence& theShapeLSecond) const
 {
-  Handle(TDataStd_TreeNode) Node;
-  if( !L.FindAttribute(XCAFDoc::DimTolRefGUID(),Node) || !Node->HasFather() ) {
-    if( !L.FindAttribute(XCAFDoc::DatumRefGUID(),Node) || !Node->HasFather() ) {
-      return Standard_False;
+  theShapeLFirst.Clear();
+  theShapeLSecond.Clear();
+  Handle(TDataStd_TreeNode) aNode;
+  if( !theL.FindAttribute(XCAFDoc::DimTolRefGUID(),aNode) || !aNode->HasFather() ) {
+    if( !theL.FindAttribute(XCAFDoc::DatumRefGUID(),aNode) || !aNode->HasFather() ) {
+      Handle(XCAFDoc_GraphNode) aGNode;
+      if( theL.FindAttribute(XCAFDoc::GeomToleranceRefGUID(),aGNode) && aGNode->NbFathers() > 0 ) {
+        for(Standard_Integer i = 1; i <= aGNode->NbFathers(); i++)
+        {
+          theShapeLFirst.Append(aGNode->GetFather(i)->Label());
+        }
+        return Standard_True;
+      }
+      else if( theL.FindAttribute(XCAFDoc::DimensionRefFirstGUID(),aGNode) && aGNode->NbFathers() > 0 ) {
+        for(Standard_Integer i = 1; i <= aGNode->NbFathers(); i++)
+        {
+          theShapeLFirst.Append(aGNode->GetFather(i)->Label());
+        }
+        if( theL.FindAttribute(XCAFDoc::DimensionRefSecondGUID(),aGNode) && aGNode->NbFathers() > 0 ) {
+          for(Standard_Integer i = 1; i <= aGNode->NbFathers(); i++)
+          {
+            theShapeLSecond.Append(aGNode->GetFather(i)->Label());
+          }
+        }
+        return Standard_True;
+      }
+      else
+      {
+        return Standard_False;
+      }
     }
   }
-  ShapeL = Node->Father()->Label();
+
+  theShapeLFirst.Append(aNode->Father()->Label());
   return Standard_True;
 }
 
+//=======================================================================
+//function : GetRefDimensionLabels
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean XCAFDoc_DimTolTool::GetRefDimensionLabels(const TDF_Label& theShapeL,
+                                                     TDF_LabelSequence& theDimTols) const
+{
+  Handle(XCAFDoc_GraphNode) aGNode;
+  Standard_Boolean aResult = Standard_False;
+  if( theShapeL.FindAttribute(XCAFDoc::DimensionRefFirstGUID(),aGNode) && aGNode->NbChildren() > 0 ) {
+    for(Standard_Integer i = 1; i <= aGNode->NbChildren(); i++)
+    {
+      theDimTols.Append(aGNode->GetChild(i)->Label());
+    }
+    aResult = Standard_True;
+  }
+  if( theShapeL.FindAttribute(XCAFDoc::DimensionRefSecondGUID(),aGNode) && aGNode->NbChildren() > 0 ) {
+    for(Standard_Integer i = 1; i <= aGNode->NbChildren(); i++)
+    {
+      theDimTols.Append(aGNode->GetChild(i)->Label());
+    }
+    aResult = Standard_True;
+  }
+  return aResult;
+}
 
 //=======================================================================
-//function : GetRefDGTLabels
+//function : GetRefGeomToleranceLabels
 //purpose  : 
 //=======================================================================
 
-Standard_Boolean XCAFDoc_DimTolTool::GetRefDGTLabels(const TDF_Label& ShapeL,
-                                                     TDF_LabelSequence &DimTols) const
+Standard_Boolean XCAFDoc_DimTolTool::GetRefGeomToleranceLabels(const TDF_Label& theShapeL,
+                                                     TDF_LabelSequence& theDimTols) const
 {
-  Handle(TDataStd_TreeNode) Node;
-  if( !ShapeL.FindAttribute(XCAFDoc::DimTolRefGUID(),Node) ||
-       !Node->HasFirst() ) {
+  Handle(XCAFDoc_GraphNode) aGNode;
+  if( !theShapeL.FindAttribute(XCAFDoc::GeomToleranceRefGUID(),aGNode) ||
+    aGNode->NbChildren() == 0 ) {
     return Standard_False;
   }
-  Handle(TDataStd_TreeNode) Last = Node->First();
-  DimTols.Append(Last->Label());
-  while(Last->HasNext()) {
-    Last = Last->Next();
-    DimTols.Append(Last->Label());
+  for(Standard_Integer i = 1; i <= aGNode->NbChildren(); i++)
+  {
+    theDimTols.Append(aGNode->GetChild(i)->Label());
   }
   return Standard_True;
 }
 
+//=======================================================================
+//function : GetRefDatumLabel
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean XCAFDoc_DimTolTool::GetRefDatumLabel(const TDF_Label& theShapeL,
+                                                     TDF_LabelSequence& theDatum) const
+{
+  Handle(TDataStd_TreeNode) aNode;
+  if( !theShapeL.FindAttribute(XCAFDoc::DatumRefGUID(),aNode) ||
+       !aNode->HasFirst() ) {
+    return Standard_False;
+  }
+  Handle(TDataStd_TreeNode) aFirst = aNode->First();
+  theDatum.Append(aFirst->Label());
+  for(Standard_Integer i = 1; i < aNode->NbChildren(); i++)
+  {
+    aFirst = aFirst->Next();
+    theDatum.Append(aFirst->Label());
+  }
+  return Standard_True;
+}
 
 //=======================================================================
 //function : GetDimTol
@@ -310,10 +637,10 @@ Standard_Boolean XCAFDoc_DimTolTool::GetDimTol(const TDF_Label& DimTolL,
 //purpose  : 
 //=======================================================================
 
-Standard_Boolean XCAFDoc_DimTolTool::IsDatum(const TDF_Label& DimTolL) const
+Standard_Boolean XCAFDoc_DimTolTool::IsDatum(const TDF_Label& theDimTolL) const
 {
-  Handle(XCAFDoc_Datum) DatumAttr;
-  if(DimTolL.FindAttribute(XCAFDoc_Datum::GetID(),DatumAttr)) {
+  Handle(XCAFDoc_Datum) aDatumAttr;
+  if(theDimTolL.FindAttribute(XCAFDoc_Datum::GetID(),aDatumAttr)) {
     return Standard_True;
   }
   return Standard_False;
@@ -325,17 +652,16 @@ Standard_Boolean XCAFDoc_DimTolTool::IsDatum(const TDF_Label& DimTolL) const
 //purpose  : 
 //=======================================================================
 
-void XCAFDoc_DimTolTool::GetDatumLabels(TDF_LabelSequence& Labels) const
+void XCAFDoc_DimTolTool::GetDatumLabels(TDF_LabelSequence& theLabels) const
 {
-  Labels.Clear();
-  TDF_ChildIterator ChildIterator( Label() ); 
-  for (; ChildIterator.More(); ChildIterator.Next()) {
-    TDF_Label L = ChildIterator.Value();
-    if ( IsDatum(L)) Labels.Append(L);
+  theLabels.Clear();
+  TDF_ChildIterator aChildIterator( Label() ); 
+  for (; aChildIterator.More(); aChildIterator.Next()) {
+    TDF_Label L = aChildIterator.Value();
+    if ( IsDatum(L)) theLabels.Append(L);
   }
 }
 
-
 //=======================================================================
 //function : FindDatum
 //purpose  : 
@@ -379,24 +705,37 @@ TDF_Label XCAFDoc_DimTolTool::AddDatum(const Handle(TCollection_HAsciiString)& a
   return DatumL;
 }
 
+//=======================================================================
+//function : AddDatum
+//purpose  : 
+//=======================================================================
+
+TDF_Label XCAFDoc_DimTolTool::AddDatum()
+{
+  TDF_Label aDatumL;
+  TDF_TagSource aTag;
+  aDatumL = aTag.NewChild ( Label() );
+  Handle(XCAFDoc_Datum) aDat = XCAFDoc_Datum::Set(aDatumL);
+  TDataStd_Name::Set(aDatumL,"DGT:Datum");
+  return aDatumL;
+}
 
 //=======================================================================
 //function : SetDatum
 //purpose  : 
 //=======================================================================
 
-void XCAFDoc_DimTolTool::SetDatum(const TDF_Label& L,
-                                  const TDF_Label& DatumL) const
+void XCAFDoc_DimTolTool::SetDatum(const TDF_Label& theL,
+                                  const TDF_Label& theDatumL) const
 {
   // set reference
   Handle(TDataStd_TreeNode) refNode, mainNode;
-  refNode = TDataStd_TreeNode::Set ( DatumL, XCAFDoc::DatumRefGUID() );
-  mainNode  = TDataStd_TreeNode::Set ( L, XCAFDoc::DatumRefGUID() );
+  refNode = TDataStd_TreeNode::Set ( theDatumL, XCAFDoc::DatumRefGUID() );
+  mainNode  = TDataStd_TreeNode::Set ( theL, XCAFDoc::DatumRefGUID() );
   refNode->Remove();
   mainNode->Append(refNode);
 }
 
-
 //=======================================================================
 //function : SetDatum
 //purpose  : 
@@ -429,6 +768,31 @@ void XCAFDoc_DimTolTool::SetDatum(const TDF_Label& L,
   ChGNode->SetFather(FGNode);
 }
 
+//=======================================================================
+//function : SetDatumToGeomTol
+//purpose  : 
+//=======================================================================
+
+void XCAFDoc_DimTolTool::SetDatumToGeomTol(const TDF_Label& theDatumL,
+                                           const TDF_Label& theTolerL) const
+{
+  // set reference
+  Handle(XCAFDoc_GraphNode) aFGNode;
+  Handle(XCAFDoc_GraphNode) aChGNode;
+  if (! theTolerL.FindAttribute( XCAFDoc::DatumTolRefGUID(), aFGNode) ) {
+    aFGNode = new XCAFDoc_GraphNode;
+    aFGNode = XCAFDoc_GraphNode::Set(theTolerL);
+  }
+  if (! theDatumL.FindAttribute( XCAFDoc::DatumTolRefGUID(), aChGNode) ) {
+    aChGNode = new XCAFDoc_GraphNode;
+    aChGNode = XCAFDoc_GraphNode::Set(theDatumL);
+  }
+  aFGNode->SetGraphID( XCAFDoc::DatumTolRefGUID() );
+  aChGNode->SetGraphID( XCAFDoc::DatumTolRefGUID() );
+  aFGNode->SetChild(aChGNode);
+  aChGNode->SetFather(aFGNode);
+}
+
 //=======================================================================
 //function : GetDatum
 //purpose  : 
@@ -455,15 +819,66 @@ Standard_Boolean XCAFDoc_DimTolTool::GetDatum(const TDF_Label& theDatumL,
 //purpose  : 
 //=======================================================================
 
-Standard_Boolean XCAFDoc_DimTolTool::GetDatumTolerLabels(const TDF_Label& DimTolL,
-                                                         TDF_LabelSequence &Datums) const
+Standard_Boolean XCAFDoc_DimTolTool::GetDatumOfTolerLabels(const TDF_Label& theDimTolL,
+                                                         TDF_LabelSequence& theDatums) const
+{
+  Handle(XCAFDoc_GraphNode) aNode;
+  if( !theDimTolL.FindAttribute(XCAFDoc::DatumTolRefGUID(),aNode) )
+    return Standard_False;
+
+  for(Standard_Integer i=1; i<=aNode->NbChildren(); i++) {
+    Handle(XCAFDoc_GraphNode) aDatumNode = aNode->GetChild(i);
+    theDatums.Append(aDatumNode->Label());
+  }
+  return Standard_True;
+}
+
+//=======================================================================
+//function : GetDatumWthObjectsTolerLabels
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean XCAFDoc_DimTolTool::GetDatumWithObjectOfTolerLabels(const TDF_Label& theDimTolL,
+                                                                     TDF_LabelSequence& theDatums) const
+{
+  Handle(XCAFDoc_GraphNode) aNode;
+  if( !theDimTolL.FindAttribute(XCAFDoc::DatumTolRefGUID(),aNode) )
+    return Standard_False;
+
+  TColStd_MapOfAsciiString aDatumNameMap;
+  for(Standard_Integer i=1; i<=aNode->NbChildren(); i++) {
+    Handle(XCAFDoc_GraphNode) aDatumNode = aNode->GetChild(i);
+    TDF_Label aDatumL = aDatumNode->Label();
+    Handle(XCAFDoc_Datum) aDatumAttr;
+    if (!aDatumL.FindAttribute(XCAFDoc_Datum::GetID(), aDatumAttr)) 
+      continue;
+    Handle(XCAFDimTolObjects_DatumObject) aDatumObj = aDatumAttr->GetObject();
+    if (aDatumObj.IsNull())
+      continue;
+    Handle(TCollection_HAsciiString) aName = aDatumObj->GetName();
+    if (!aDatumNameMap.Add(aName->String())) {
+      // the datum has already been appended to sequence, due to one of its datum targets
+      continue;
+    }
+    theDatums.Append(aDatumNode->Label());
+  }
+  return Standard_True;
+}
+
+//=======================================================================
+//function : GetTolerDatumLabels
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean XCAFDoc_DimTolTool::GetTolerOfDatumLabels(const TDF_Label& theDatumL,
+                                                         TDF_LabelSequence& theTols) const
 {
-  Handle(XCAFDoc_GraphNode) Node;
-  if( !DimTolL.FindAttribute(XCAFDoc::DatumTolRefGUID(),Node) )
+  Handle(XCAFDoc_GraphNode) aNode;
+  if( !theDatumL.FindAttribute(XCAFDoc::DatumTolRefGUID(),aNode) )
     return Standard_False;
-  for(Standard_Integer i=1; i<=Node->NbChildren(); i++) {
-    Handle(XCAFDoc_GraphNode) DatumNode = Node->GetChild(i);
-    Datums.Append(DatumNode->Label());
+  for(Standard_Integer i=1; i<=aNode->NbFathers(); i++) {
+    Handle(XCAFDoc_GraphNode) aDatumNode = aNode->GetFather(i);
+    theTols.Append(aDatumNode->Label());
   }
   return Standard_True;
 }