0031456: Visualization - move out Dimensions and Relations from package AIS to PrsDims
[occt.git] / src / ViewerTest / ViewerTest_RelationCommands.cxx
old mode 100755 (executable)
new mode 100644 (file)
index 8b47070..9fe3682
@@ -1,46 +1,54 @@
 // Created on: 1998-11-12
 // Created by: Robert COUBLANC
 // Copyright (c) 1998-1999 Matra Datavision
-// 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 <ViewerTest.hxx>
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
 
-#include <AIS_AngleDimension.hxx>
 #include <AIS_Circle.hxx>
-#include <AIS_DiameterDimension.hxx>
 #include <AIS_DisplayMode.hxx>
 #include <AIS_InteractiveContext.hxx>
-#include <AIS_LengthDimension.hxx>
 #include <AIS_ListIteratorOfListOfInteractive.hxx>
 #include <AIS_ListOfInteractive.hxx>
 #include <AIS_MapOfInteractive.hxx>
 #include <AIS_Point.hxx>
-#include <AIS_RadiusDimension.hxx>
-#include <AIS_Relation.hxx>
 #include <AIS_Shape.hxx>
-#include <BRepAdaptor_Curve.hxx>
+#include <PrsDim_AngleDimension.hxx>
+#include <PrsDim_ConcentricRelation.hxx>
+#include <PrsDim_DiameterDimension.hxx>
+#include <PrsDim_EqualDistanceRelation.hxx>
+#include <PrsDim_EqualRadiusRelation.hxx>
+#include <PrsDim_FixRelation.hxx>
+#include <PrsDim_IdenticRelation.hxx>
+#include <PrsDim_KindOfRelation.hxx>
+#include <PrsDim_LengthDimension.hxx>
+#include <PrsDim_OffsetDimension.hxx>
+#include <PrsDim_ParallelRelation.hxx>
+#include <PrsDim_PerpendicularRelation.hxx>
+#include <PrsDim_RadiusDimension.hxx>
+#include <PrsDim_Relation.hxx>
+#include <PrsDim_SymmetricRelation.hxx>
+#include <PrsDim_TangentRelation.hxx>
 #include <BRep_Builder.hxx>
 #include <BRep_Tool.hxx>
+#include <BRepAdaptor_Curve.hxx>
+#include <BRepBuilderAPI_MakeVertex.hxx>
+#include <BRepExtrema_ExtCC.hxx>
+#include <BRepExtrema_ExtPC.hxx>
+#include <BRepExtrema_ExtCF.hxx>
+#include <BRepExtrema_ExtPF.hxx>
+#include <BRepExtrema_ExtFF.hxx>
 #include <BRepTools.hxx>
 #include <Draw_Interpretor.hxx>
 #include <Draw.hxx>
 #include <Draw_Window.hxx>
 #include <DBRep.hxx>
 #include <ElSLib.hxx>
+#include <Font_FontMgr.hxx>
 #include <GC_MakePlane.hxx>
 #include <Geom_CartesianPoint.hxx>
 #include <Geom_Circle.hxx>
+#include <Geom_Line.hxx>
 #include <Geom_Plane.hxx>
+#include <GeomAPI_IntCS.hxx>
+#include <gce_MakeLin.hxx>
+#include <gce_MakePln.hxx>
 #include <gp_Circ.hxx>
 #include <gp_Pln.hxx>
 #include <IntAna_IntConicQuad.hxx>
 #include <IntAna_Quadric.hxx>
 #include <Precision.hxx>
-#include <Select3D_Projector.hxx>
 #include <StdSelect.hxx>
-#include <string.h>
 #include <TCollection_AsciiString.hxx>
 #include <TCollection_ExtendedString.hxx>
 #include <TColStd_MapOfInteger.hxx>
+#include <TColStd_SequenceOfReal.hxx>
 #include <TopAbs.hxx>
 #include <TopAbs_ShapeEnum.hxx>
 #include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Solid.hxx>
 #include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
 #include <ViewerTest_EventManager.hxx>
 
+extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
+                                           const Handle(AIS_InteractiveObject)& theAISObj,
+                                           Standard_Boolean theReplaceIfExists = Standard_True);
 extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
 extern int ViewerMainLoop(Standard_Integer argc, const char** argv);
 extern Handle(AIS_InteractiveContext)& TheAISContext ();
 
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
-
 #define VertexMask 0x01
 #define EdgeMask 0x02
 #define FaceMask 0x04
 
-static Standard_Boolean ComputeIntersection(const gp_Lin& L,const gp_Pln& ThePl, gp_Pnt& TheInter)
-{
-  static IntAna_Quadric TheQuad;
-  TheQuad.SetQuadric(ThePl);
-  static IntAna_IntConicQuad QQ;
-   QQ.Perform(L,TheQuad);
-  if(QQ.IsDone()){
-    if(QQ.NbPoints()>0){
-      TheInter = QQ.Point(1);
-      return Standard_True;
-    }
-  }
-  return Standard_False;
-}
-
 //=======================================================================
 //function : Get3DPointAtMousePosition
-//purpose  : calcul du point 3D correspondant a la position souris dans le plan de 
-// la vue...
+//purpose  : Calculates the 3D points corresponding to the mouse position
+//           in the plane of the view
 //=======================================================================
-
-static gp_Pnt Get3DPointAtMousePosition ()
+static gp_Pnt Get3DPointAtMousePosition()
 {
-  Handle(V3d_View) aview = ViewerTest::CurrentView();
-  static Select3D_Projector prj;
-  prj.SetView(aview);
-  
-  // le plan de la vue...
+  Handle(V3d_View) aView = ViewerTest::CurrentView();
+
   Standard_Real xv,yv,zv;
-  aview->Proj(xv,yv,zv);
+  aView->Proj (xv,yv,zv);
   Standard_Real xat,yat,zat;
-  aview->At(xat,yat,zat);
-  gp_Pln ThePl(gp_Pnt(xat,yat,zat),gp_Dir(xv,yv,zv));
-  Standard_Integer xpix,ypix;
-  Standard_Real x,y;
-  ViewerTest::GetMousePosition(xpix,ypix);
-  aview->Convert(xpix,ypix,x,y); // espace reel 2D de la vue...
-  gp_Lin L = prj.Shoot(x,y);
-  gp_Pnt P(0.,0.,0.);
-
-  ComputeIntersection(L,ThePl,P);
-  return P;
-}
+  aView->At(xat,yat,zat);
+  gp_Pln aPlane (gp_Pnt(xat,yat,zat), gp_Dir(xv,yv,zv));
+  
+  Standard_Integer aPixX, aPixY;
+  Standard_Real aX, aY, aZ, aDX, aDY, aDZ;
 
-//=======================================================================
-//function : ComputeNewPlaneForDim
-//purpose  : 
-//=======================================================================
+  ViewerTest::GetMousePosition (aPixX, aPixY);
+  aView->ConvertWithProj (aPixX, aPixY, aX, aY, aZ, aDX, aDY, aDZ);
+  gp_Lin aLine( gp_Pnt(aX, aY, aZ), gp_Dir(aDX, aDY, aDZ) );
 
-static void ComputeNewPlaneForDim (const Handle(AIS_Relation)& R,
-                                   gp_Pln& ,
-                                   gp_Pnt&)
-{
-// 0   COMPOUND,
-// 1   COMPSOLID,
-// 2   SOLID,
-// 3   SHELL,
-// 4   FACE,
-// 5           WIRE,
-// 6   EDGE,
-// 7   VERTEX,
-// 8   SHAPE
-  TopoDS_Shape S1 = R->FirstShape();
-  TopoDS_Shape S2 = R->SecondShape();
-  TopAbs_ShapeEnum Typ1 = S1.ShapeType();
-  TopAbs_ShapeEnum Typ2 = S2.ShapeType();
-  
-  gp_Pnt thepoint [3];
-  thepoint[0] = Get3DPointAtMousePosition();
-  
-  // on met l'objet le plus petit en 1...
-  if((Standard_Integer)Typ2>(Standard_Integer)Typ1){
-    
-    TopoDS_Shape tmpS = S1;
-    TopAbs_ShapeEnum tmpT = Typ1;
-    S1= S2;
-    Typ1 = Typ2;
-    S2= tmpS;
-    Typ2 = tmpT;
-  }
-/*  
-  switch (Typ1){
-  case TopAbs_VERTEX:{
-    thepoint[0]  = BRep_Tool::Pnt(S1);
-    if(Typ2==TopAbs_VERTEX)
-      thepoint[1] = BRep_Tool::Pnt(S2);
-    else if(Typ2==TopAbs_EDGE){
-      TopoDS_Vertex  Va,Vb;
-      TopExp::Vertices(S2,Va,Vb);
-      thepoint[1] = BRep_Tool::Pnt(Va);
-    }
-    else if(Typ2==TopAbs_FACE){
-    }
-    break;
-  }
-  case TopAbs_EDGE:
+  // Compute intersection
+  Handle(Geom_Line) aGeomLine = new Geom_Line (aLine);
+  Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
+  GeomAPI_IntCS anIntersector (aGeomLine, aGeomPlane);
+  if (!anIntersector.IsDone() || anIntersector.NbPoints() == 0)
+  {
+    return gp::Origin();
   }
-*/
+  return anIntersector.Point (1);
 }
 
 //=======================================================================
-//function : VDimBuilder
-//purpose  : Command for building dimension presentations: angle,
-//           length, radius, diameter
+//function : Get3DPointAtMousePosition
+//purpose  : Calculates the 3D points corresponding to the mouse position
+//           in the plane of the view
 //=======================================================================
-static int VDimBuilder(Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgs)
+static Standard_Boolean Get3DPointAtMousePosition (const gp_Pnt& theFirstPoint,
+                                                   const gp_Pnt& theSecondPoint,
+                                                   gp_Pnt& theOutputPoint)
 {
-  if (theArgsNb < 2)
-  {
-    std::cerr << theArgs[0] << ": command argument is required. Type help for more information.\n";
-    return 1;
-  }
+  theOutputPoint = gp::Origin();
 
-  // Parse parameters
-  TCollection_AsciiString aDimType(theArgs[1]);
-  AIS_KindOfDimension aKindOfDimension;
-  if (aDimType == "length")
-  {
-    aKindOfDimension = AIS_KOD_LENGTH;
-  }
-  else if (aDimType == "angle")
-  {
-    aKindOfDimension = AIS_KOD_PLANEANGLE;
-  }
-  else if (aDimType == "radius")
-  {
-    aKindOfDimension = AIS_KOD_RADIUS;
-  }
-  else if (aDimType == "diameter" || aDimType == "diam")
+  Handle(V3d_View) aView = ViewerTest::CurrentView();
+
+  Standard_Integer aPixX, aPixY;
+  Standard_Real aX, aY, aZ, aDx, aDy, aDz, aUx, aUy, aUz;
+
+  // Get 3D point in view coordinates and projection vector from the pixel point.
+  ViewerTest::GetMousePosition (aPixX, aPixY);
+  aView->ConvertWithProj (aPixX, aPixY, aX, aY, aZ, aDx, aDy, aDz);
+  gp_Lin aProjLin (gp_Pnt(aX, aY, aZ), gp_Dir(aDx, aDy, aDz));
+
+  // Get plane
+  gp_Vec aDimVec (theFirstPoint, theSecondPoint);
+  aView->Up (aUx, aUy, aUz);
+  gp_Vec aViewUp (aUx, aUy, aUz);
+
+  if (aDimVec.IsParallel (aViewUp, Precision::Angular()))
   {
-    aKindOfDimension = AIS_KOD_DIAMETER;
+    theOutputPoint = Get3DPointAtMousePosition();
+    return Standard_True;
   }
-  else
+
+  gp_Vec aDimNormal = aDimVec ^ aViewUp;
+  gp_Pln aViewPlane= gce_MakePln (theFirstPoint, aDimNormal);
+
+  // Get intersection of view plane and projection line
+  Handle(Geom_Plane) aPlane = new Geom_Plane (aViewPlane);
+  Handle(Geom_Line) aProjLine = new Geom_Line (aProjLin);
+  GeomAPI_IntCS anIntersector (aProjLine, aPlane);
+  if (!anIntersector.IsDone() || anIntersector.NbPoints() == 0)
   {
-    std::cerr << theArgs[0] << ": wrong type of dimension. Type help for more information.\n";
-    return 1;
+    return Standard_False;
   }
-  NCollection_List<Handle(AIS_InteractiveObject)> aShapes;
-  Handle(Prs3d_DimensionAspect) anAspect = new Prs3d_DimensionAspect;
-  Standard_Boolean isPlaneCustom = Standard_False;
-  TCollection_AsciiString aName;
-  gp_Pln aWorkingPlane;
-  Standard_Boolean isCustomFlyout = Standard_False;
-  Standard_Real aCustomFlyout = 0.0;
 
-  for (Standard_Integer anIt = 2; anIt < theArgsNb; ++anIt)
+  theOutputPoint = anIntersector.Point (1);
+  return Standard_True;
+}
+
+//=======================================================================
+//function : ParseDimensionParams
+//purpose  : Auxilliary function: sets aspect parameters for
+//           length, angle, radius and diameter dimension.
+//
+//draw args: -text [3d|2d] [wf|sh|wireframe|shading] [Size]
+//           -label [left|right|hcenter|hfit] [top|bottom|vcenter|vfit]
+//           -arrow [external|internal|fit] [Length(int)]
+//           -arrowangle ArrowAngle(degrees)
+//           -plane xoy|yoz|zox
+//           -flyout FloatValue -extension FloatValue
+//           -autovalue
+//           -value CustomRealValue
+//           -textvalue CustomTextValue
+//           -dispunits DisplayUnitsString
+//           -modelunits ModelUnitsString
+//           -showunits
+//           -hideunits
+//
+// Warning! flyout is not an aspect value, it is for dimension parameter
+// likewise text position, but text position override other paramaters.
+// For text position changing use 'vmovedim'.
+//=======================================================================
+static int ParseDimensionParams (Standard_Integer  theArgNum,
+                                 const char**      theArgVec,
+                                 Standard_Integer  theStartIndex,
+                                 const Handle(Prs3d_DimensionAspect)& theAspect,
+                                 Standard_Boolean& theIsCustomPlane, gp_Pln& thePlane,
+                                 NCollection_DataMap<TCollection_AsciiString, Standard_Real>& theRealParams,
+                                 NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString>& theStringParams,
+                                 NCollection_List<Handle(AIS_InteractiveObject)>* theShapeList = NULL)
+{
+  theRealParams.Clear();
+  theStringParams.Clear();
+
+  theIsCustomPlane  = Standard_False;
+
+  // Begin from the second parameter: the first one is dimension name
+  for (Standard_Integer anIt = theStartIndex; anIt < theArgNum; ++anIt)
   {
-    TCollection_AsciiString anArgString = theArgs[anIt];
-    TCollection_AsciiString aParamName;
-    TCollection_AsciiString aParamValue;
-    if (ViewerTest::SplitParameter (anArgString, aParamName, aParamValue))
+    TCollection_AsciiString aParam (theArgVec[anIt]);
+    aParam.LowerCase();
+
+    if (aParam.Search ("-") == -1)
+    {
+      continue;
+    }
+
+    // Boolean flags
+    if (aParam.IsEqual ("-autovalue"))
     {
-      aParamName.LowerCase();
-      aParamValue.LowerCase();
+      theRealParams.Bind ("autovalue", 1);
+      continue;
+    }
 
-      if (aParamName == "text")
+    if (aParam.IsEqual ("-showunits"))
+    {
+      theAspect->MakeUnitsDisplayed (Standard_True);
+      continue;
+    }
+    else if (aParam.IsEqual ("-hideunits"))
+    {
+      theAspect->MakeUnitsDisplayed (Standard_False);
+      continue;
+    }
+    else if (aParam.IsEqual ("-selected"))
+    {
+      if (!theShapeList)
       {
-        anAspect->MakeText3d (aParamValue == "3d");
+        std::cerr << "Error: unknown parameter '" << aParam << "'\n";
+        return 1;
       }
-      else if (aParamName == "name")
+
+      for (TheAISContext()->InitSelected(); TheAISContext()->MoreSelected(); TheAISContext()->NextSelected())
       {
-        if (aParamValue.IsEmpty())
+        TopoDS_Shape aShape = TheAISContext()->SelectedShape();
+        if (!aShape.IsNull())
         {
-          std::cerr << theArgs[0] << ": no name for dimension.\n";
-          return 1;
+          theShapeList->Append (new AIS_Shape (aShape));
         }
+      }
+      continue;
+    }
+
+    // Before all non-boolean flags parsing check if a flag have at least one value.
+    if (anIt + 1 >= theArgNum)
+    {
+      std::cerr << "Error: "<< aParam <<" flag should have value.\n";
+      return 1;
+    }
 
-        aName = aParamValue;
+    // Non-boolean flags
+    if (aParam.IsEqual ("-shape")
+     || aParam.IsEqual ("-shapes"))
+    {
+      if (!theShapeList)
+      {
+        std::cerr << "Error: unknown parameter '" << aParam << "'\n";
+        return 1;
       }
-      else if (aParamName == "plane")
+
+      do
       {
-        if (aParamValue == "xoy")
-        {
-          aWorkingPlane = gp_Pln (gp_Ax3 (gp::XOY()));
-        }
-        else if (aParamValue == "zox")
-        {
-          aWorkingPlane = gp_Pln (gp_Ax3 (gp::ZOX()));
-        }
-        else if (aParamValue == "yoz")
+        anIt++;
+        TCollection_AsciiString anArgString = theArgVec[anIt];
+        Handle(AIS_InteractiveObject) anAISObject;
+        Standard_CString aStr   = anArgString.ToCString();
+        TopoDS_Shape     aShape =  DBRep::Get (aStr);
+        if (!aShape.IsNull())
         {
-          aWorkingPlane = gp_Pln (gp_Ax3 (gp::YOZ()));
+          anAISObject = new AIS_Shape (aShape);
         }
-        else
+        else if (!GetMapOfAIS().Find2 (anArgString, anAISObject)
+               || anAISObject.IsNull())
         {
-          std::cerr << theArgs[0] << ": wrong plane.\n";
+          std::cerr << "Error: shape with name '" << aStr << "' is not found.\n";
           return 1;
         }
-
-        isPlaneCustom = Standard_True;
+        theShapeList->Append (anAISObject);
       }
-      else if (aParamName == "label")
+      while (anIt + 1 < theArgNum && theArgVec[anIt + 1][0] != '-');
+    }
+    else if (aParam.IsEqual ("-text"))
+    {
+      do
       {
-        NCollection_List<TCollection_AsciiString> aListOfLabelVals;
-        while (aParamValue.Length() > 0)
-        {
-          TCollection_AsciiString aValue = aParamValue;
-
-          Standard_Integer aSeparatorPos = aParamValue.Search (",");
-          if (aSeparatorPos >= 0)
-          {
-            aValue.Trunc (aSeparatorPos - 1);
-            aParamValue.Remove (aSeparatorPos, 1);
-          }
-
-          aListOfLabelVals.Append (aValue);
-
-          aParamValue.Remove (1, aValue.Length());
-        }
-
-        NCollection_List<TCollection_AsciiString>::Iterator aLabelValueIt (aListOfLabelVals);
-        for ( ; aLabelValueIt.More(); aLabelValueIt.Next())
+        anIt++;
+        TCollection_AsciiString aValue (theArgVec[anIt]);
+        aValue.LowerCase();
+        if (aValue.IsEqual ("3d"))
         {
-          aParamValue = aLabelValueIt.Value();
-
-          if (aParamValue == "left")
-          {
-            anAspect->SetTextHorizontalPosition (Prs3d_DTHP_Left);
-          }
-          else if (aParamValue == "right")
-          {
-            anAspect->SetTextHorizontalPosition (Prs3d_DTHP_Right);
-          }
-          else if (aParamValue == "hcenter")
-          {
-            anAspect->SetTextHorizontalPosition (Prs3d_DTHP_Center);
-          }
-          else if (aParamValue == "hfit")
-          {
-            anAspect->SetTextHorizontalPosition (Prs3d_DTHP_Fit);
-          }
-          else if (aParamValue == "above")
-          {
-            anAspect->SetTextVerticalPosition (Prs3d_DTVP_Above);
-          }
-          else if (aParamValue == "below")
-          {
-            anAspect->SetTextVerticalPosition (Prs3d_DTVP_Below);
-          }
-          else if (aParamValue == "vcenter")
-          {
-            anAspect->SetTextVerticalPosition (Prs3d_DTVP_Center);
-          }
-          else
-          {
-            std::cerr << theArgs[0] << ": invalid label position: \"" << aParamValue << "\".\n";
-            return 1;
-          }
+          theAspect->MakeText3d (Standard_True);
         }
-      }
-      else if (aParamName == "flyout")
-      {
-        if (!aParamValue.IsRealValue())
+        else if (aValue.IsEqual ("2d"))
         {
-          std::cerr << theArgs[0] << ": numeric value expected for flyout.\n";
-          return 1;
+          theAspect->MakeText3d (Standard_False);
         }
-
-        aCustomFlyout = aParamValue.RealValue();
-
-        isCustomFlyout = Standard_True;
-      }
-      else if (aParamName == "arrows")
-      {
-        if (aParamValue == "external")
+        else if (aValue.IsEqual ("wf") || aValue.IsEqual ("wireframe"))
         {
-          anAspect->SetArrowOrientation (Prs3d_DAO_External);
+           theAspect->MakeTextShaded (Standard_False);
         }
-        else if (aParamValue == "internal")
+        else if ( aValue.IsEqual ("sh") || aValue.IsEqual ("shading"))
         {
-          anAspect->SetArrowOrientation (Prs3d_DAO_Internal);
+          theAspect->MakeTextShaded (Standard_True);
         }
-        else if (aParamValue == "fit")
+        else if (aValue.IsIntegerValue()) // text size
         {
-          anAspect->SetArrowOrientation (Prs3d_DAO_Fit);
+          theAspect->TextAspect()->SetHeight (Draw::Atoi (aValue.ToCString()));
         }
       }
-      else
-      {
-        std::cerr << theArgs[0] << ": unknow parameter: \"" << aParamName << "\".\n";
-        return 1;
-      }
+      while (anIt + 1 < theArgNum && theArgVec[anIt + 1][0] != '-');
     }
-    else // Shape
+    else if (aParam.IsEqual ("-font"))
     {
-      if (!GetMapOfAIS().IsBound2 (anArgString))
+      if (anIt + 1 >= theArgNum)
       {
-        std::cerr << theArgs[0] << ": wrong name of shape. May be here is a wrong parameter.\n";
+        std::cout << "Error: wrong number of values for parameter '" << aParam << "'.\n";
         return 1;
       }
 
-      Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (anArgString));
-      if (aShape.IsNull())
+      theAspect->TextAspect()->SetFont (theArgVec[++anIt]);
+    }
+    else if (aParam.IsEqual ("-label"))
+    {
+      do
       {
-        std::cerr << theArgs[0] << ": wrong name of shape. Not a shape.\n";
-        return 1;
+        anIt++;
+        TCollection_AsciiString aParamValue (theArgVec[anIt]);
+        aParamValue.LowerCase();
+
+        if (aParamValue == "left")         { theAspect->SetTextHorizontalPosition (Prs3d_DTHP_Left);  }
+        else if (aParamValue == "right")   { theAspect->SetTextHorizontalPosition (Prs3d_DTHP_Right); }
+        else if (aParamValue == "hcenter") { theAspect->SetTextHorizontalPosition (Prs3d_DTHP_Center);}
+        else if (aParamValue == "hfit")    { theAspect->SetTextHorizontalPosition (Prs3d_DTHP_Fit);   }
+        else if (aParamValue == "above")   { theAspect->SetTextVerticalPosition   (Prs3d_DTVP_Above); }
+        else if (aParamValue == "below")   { theAspect->SetTextVerticalPosition   (Prs3d_DTVP_Below); }
+        else if (aParamValue == "vcenter") { theAspect->SetTextVerticalPosition   (Prs3d_DTVP_Center);}
+        else
+        {
+          std::cerr << "Error: invalid label position: '" << aParamValue << "'.\n";
+          return 1;
+        }
       }
-
-      aShapes.Append (aShape);
+      while (anIt + 1 < theArgNum && theArgVec[anIt+1][0] != '-');
     }
-  }
-
-  if (aName.IsEmpty())
-  {
-    std::cerr << theArgs[0] << ": no name for dimension.\n";
-    return 1;
-  }
+    else if (aParam.IsEqual ("-arrow"))
+    {
+      TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
+      aLocalParam.LowerCase();
 
-  // Build dimension
-  Handle(AIS_Dimension) aDim;
-  switch (aKindOfDimension)
-  {
-    case AIS_KOD_LENGTH:
+      if (aLocalParam == "external") { theAspect->SetArrowOrientation (Prs3d_DAO_External); }
+      if (aLocalParam == "internal") { theAspect->SetArrowOrientation (Prs3d_DAO_Internal); }
+      if (aLocalParam == "fit")      { theAspect->SetArrowOrientation (Prs3d_DAO_Fit); }
+    }
+    else if (aParam.IsEqual ("-arrowlength") || aParam.IsEqual ("-arlen"))
     {
-      if (!isPlaneCustom)
+      TCollection_AsciiString aValue (theArgVec[++anIt]);
+      if (!aValue.IsRealValue())
       {
-        std::cerr << theArgs[0] << ": can not build dimension without working plane.\n";
+        std::cerr << "Error: arrow lenght should be float degree value.\n";
         return 1;
       }
-      if (aShapes.Extent() == 1)
-      {
-        if (aShapes.First()->Type() == AIS_KOI_Shape
-            && (Handle(AIS_Shape)::DownCast(aShapes.First()))->Shape().ShapeType() != TopAbs_EDGE)
-        {
-          std::cerr << theArgs[0] << ": wrong shape type.\n";
-          return 1;
-        }
-        aDim = new AIS_LengthDimension (TopoDS::Edge ((Handle(AIS_Shape)::DownCast(aShapes.First()))->Shape()), aWorkingPlane);
-      }
-      else if (aShapes.Extent() == 2)
+      theAspect->ArrowAspect()->SetLength (Draw::Atof (aValue.ToCString()));
+    }
+    else if (aParam.IsEqual ("-arrowangle") || aParam.IsEqual ("-arangle"))
+    {
+      TCollection_AsciiString aValue (theArgVec[++anIt]);
+      if (!aValue.IsRealValue())
       {
-        if (aShapes.First()->Type() == AIS_KOI_Shape && aShapes.Last()->Type() == AIS_KOI_Shape)
-          aDim = new AIS_LengthDimension ((Handle(AIS_Shape)::DownCast(aShapes.First ()))->Shape(),
-                                          (Handle(AIS_Shape)::DownCast(aShapes.Last ()))->Shape(),
-                                          aWorkingPlane);
-        else// AIS_Point
-        {
-          Handle(AIS_Point) aPoint1 = Handle(AIS_Point)::DownCast(aShapes.First ());
-          Handle(AIS_Point) aPoint2 = Handle(AIS_Point)::DownCast(aShapes.Last ());
-          aDim = new AIS_LengthDimension (aPoint1->Component()->Pnt(),
-                                          aPoint2->Component()->Pnt(),
-                                          aWorkingPlane);
-        }
+        std::cerr << "Error: arrow angle should be float degree value.\n";
+        return 1;
       }
-      else
+      theAspect->ArrowAspect()->SetAngle (Draw::Atof (aValue.ToCString()));
+    }
+    else if (aParam.IsEqual ("-color"))
+    {
+      theAspect->SetCommonColor (Quantity_Color (ViewerTest::GetColorFromName (theArgVec[++anIt])));
+    }
+    else if (aParam.IsEqual ("-extension"))
+    {
+      TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
+      if (!aLocalParam.IsRealValue())
       {
-        std::cerr << theArgs[0] << ": wrong number of shapes to build dimension.\n";
+        std::cerr << "Error: extension size for dimension should be real value.\n";
         return 1;
       }
-
-      break;
+      theAspect->SetExtensionSize (Draw::Atof (aLocalParam.ToCString()));
     }
-
-    case AIS_KOD_PLANEANGLE:
+    else if (aParam.IsEqual ("-plane"))
     {
-      if (aShapes.Extent() == 1 && aShapes.First()->Type()==AIS_KOI_Shape)
+      TCollection_AsciiString aValue (theArgVec[++anIt]);
+      aValue.LowerCase();
+      if (aValue == "xoy")
       {
-        Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(aShapes.First());
-        if (aShape->Shape().ShapeType() == TopAbs_FACE)
-          aDim = new AIS_AngleDimension (TopoDS::Face(aShape->Shape()));
+        theIsCustomPlane = Standard_True;
+        thePlane = gp_Pln (gp_Ax3 (gp::XOY()));
       }
-      if (aShapes.Extent() == 2)
+      else if (aValue == "zox")
       {
-        Handle(AIS_Shape) aShape1 = Handle(AIS_Shape)::DownCast(aShapes.First());
-        Handle(AIS_Shape) aShape2 = Handle(AIS_Shape)::DownCast(aShapes.Last());
-        if (!aShape1.IsNull() && !aShape2.IsNull()
-            && aShape1->Shape().ShapeType() == TopAbs_EDGE
-            && aShape2->Shape().ShapeType() == TopAbs_EDGE)
-          aDim = new AIS_AngleDimension (TopoDS::Edge(aShape1->Shape()),TopoDS::Edge(aShape2->Shape()));
-        else
-        {
-          std::cerr << theArgs[0] << ": wrong shapes for angle dimension.\n";
-          return 1;
-        }
+        theIsCustomPlane = Standard_True;
+        thePlane = gp_Pln (gp_Ax3 (gp::ZOX()));
       }
-      else if (aShapes.Extent() == 3)
+      else if (aValue == "yoz")
       {
-        gp_Pnt aP1, aP2, aP3;
-        Handle(AIS_Point) aPoint = Handle(AIS_Point)::DownCast (aShapes.First());
-        if (aPoint.IsNull())
-          return 1;
-        aP1 = aPoint->Component()->Pnt();
-        aShapes.RemoveFirst();
-        aPoint = Handle(AIS_Point)::DownCast (aShapes.First());
-        if (aPoint.IsNull())
-          return 1;
-        aP2 = aPoint->Component()->Pnt();
-        aShapes.RemoveFirst();
-        aPoint = Handle(AIS_Point)::DownCast (aShapes.First());
-        if (aPoint.IsNull())
-          return 1;
-        aP3 = aPoint->Component()->Pnt();
-        aDim = new AIS_AngleDimension (aP1, aP2, aP3);
+        theIsCustomPlane = Standard_True;
+        thePlane = gp_Pln (gp_Ax3 (gp::YOZ()));
       }
       else
       {
-        std::cerr << theArgs[0] << ": wrong number of shapes to build dimension.\n";
+        std::cerr << "Error: wrong plane '" << aValue << "'.\n";
         return 1;
       }
-
-      break;
     }
-
-    case AIS_KOD_RADIUS: // radius of the circle
+    else if (aParam.IsEqual ("-flyout"))
     {
-      if (aShapes.Extent() == 1)
+      TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
+      if (!aLocalParam.IsRealValue())
       {
-        Handle(AIS_Circle) aShape = Handle(AIS_Circle)::DownCast (aShapes.First());
-        gp_Circ aCircle = aShape->Circle()->Circ();
-        aDim = new AIS_RadiusDimension (aCircle);
-      }
-      else
-      {
-        std::cerr << theArgs[0] << ": wrong number of shapes to build dimension.\n";
+        std::cerr << "Error: flyout for dimension should be real value.\n";
         return 1;
       }
 
-      break;
+      theRealParams.Bind ("flyout", Draw::Atof (aLocalParam.ToCString()));
     }
-
-    case AIS_KOD_DIAMETER:
+    else if (aParam.IsEqual ("-value"))
     {
-      if (aShapes.Extent() == 1)
-      {
-        Handle(AIS_Circle) aShape = Handle(AIS_Circle)::DownCast (aShapes.First());
-        gp_Circ aCircle = aShape->Circle()->Circ();
-        aDim = new AIS_DiameterDimension (aCircle);
-      }
-      else
+      TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
+      if (!aLocalParam.IsRealValue())
       {
-        std::cerr << theArgs[0] << ": wrong number of shapes to build dimension.\n";
+        std::cerr << "Error: dimension value for dimension should be real value.\n";
         return 1;
       }
 
-      break;
+      theRealParams.Bind ("value", Draw::Atof (aLocalParam.ToCString()));
     }
+    else if (aParam.IsEqual ("-textvalue"))
+    {
+      TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
 
-    default:
+      theStringParams.Bind ("textvalue", aLocalParam);
+    }
+    else if (aParam.IsEqual ("-modelunits"))
     {
-      std::cerr << theArgs[0] << ": wrong type of dimension. Type help for more information.\n";
+      TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
+
+      theStringParams.Bind ("modelunits", aLocalParam);
+    }
+    else if (aParam.IsEqual ("-dispunits"))
+    {
+      TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
+
+      theStringParams.Bind ("dispunits", aLocalParam);
+    }
+    else
+    {
+      std::cerr << "Error: unknown parameter '" << aParam << "'.\n";
       return 1;
     }
   }
 
-  aDim->SetDimensionAspect (anAspect);
+  return 0;
+}
+
+//=======================================================================
+//function : SetDimensionParams
+//purpose  : Sets parameters for dimension
+//=======================================================================
+static void SetDimensionParams (const Handle(PrsDim_Dimension)& theDim,
+                                const NCollection_DataMap<TCollection_AsciiString, Standard_Real>& theRealParams,
+                                const NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString>& theStringParams)
+{
+  if (theRealParams.IsBound ("flyout"))
+  {
+    theDim->SetFlyout (theRealParams.Find ("flyout"));
+  }
 
-  if (isCustomFlyout)
+  if (theRealParams.IsBound ("autovalue"))
   {
-    aDim->SetFlyout (aCustomFlyout);
+    theDim->SetComputedValue();
   }
 
-  if (GetMapOfAIS().IsBound2(aName))
+  if (theRealParams.IsBound ("value"))
   {
-    theDi << theArgs[0] << ": shape with name " << aName.ToCString ()<< " already exists. It will be replaced\n";
-    Handle(AIS_InteractiveObject) anObj = 
-        Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(aName));
-    TheAISContext()->Remove(anObj, Standard_False);
-    GetMapOfAIS().UnBind2(aName);
+    theDim->SetCustomValue (theRealParams.Find ("value"));
   }
 
-  GetMapOfAIS().Bind (aDim,aName);
+  if (theStringParams.IsBound ("textvalue"))
+  {
+    theDim->SetCustomValue (theStringParams.Find ("textvalue"));
+  }
 
-  return 0;
+  if (theStringParams.IsBound ("modelunits"))
+  {
+    theDim->SetModelUnits (theStringParams.Find ("modelunits"));
+  }
+
+  if (theStringParams.IsBound ("dispunits"))
+  {
+    theDim->SetDisplayUnits (theStringParams.Find ("dispunits"));
+  }
 }
 
 //=======================================================================
-//function : VAngleDimBuilder
-//purpose  : 
+//function : ParseAngleDimensionParams
+//purpose  : Auxilliary function: sets custom parameters for angle dimension.
+//
+//draw args: -type [interior|exterior]
+//           -showarrow [first|second|both|none]
 //=======================================================================
-
-static int VAngleDimBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
+static int ParseAngleDimensionParams (Standard_Integer  theArgNum,
+                               const char**      theArgVec,
+                               Standard_Integer  theStartIndex,
+                               NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString>& theStringParams)
 {
-  Standard_Integer myCurrentIndex;
-  if (argc!=2) {di<<" vangledim error."<<"\n";return 1;}
-  TheAISContext()->CloseAllContexts();
-  TheAISContext()->OpenLocalContext();
-  myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
-  TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
-  di<<" Select two  edges coplanar or not."<<"\n";
-  Standard_Integer argcc = 5;
-  const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-  const char **argvv = (const char **) buff;
-  while (ViewerMainLoop( argcc, argvv) ) { }
-  
-  TopoDS_Shape ShapeA;
-  for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-    ShapeA = TheAISContext()->SelectedShape();
-  }
-  // Si ShapeA est un Edge.
-  if (ShapeA.ShapeType()== TopAbs_EDGE ) {
-    
-    // Boucle d'attente waitpick.
-    Standard_Integer argccc = 5;
-    const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-    const char **argvvv = (const char **) bufff;
-    while (ViewerMainLoop( argccc, argvvv) ) { }
-    // fin de la boucle
-    
-    TopoDS_Shape ShapeB;
-    for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-      ShapeB = TheAISContext()->SelectedShape();
-    }
-    // ShapeB doit etre un Edge
-    if (ShapeB.ShapeType()!= TopAbs_EDGE ) {
-      di<<" vangledim error: you shoud have selected an edge."<<"\n";return 1;
-    }
-    
-    // on recupere les vertexes de edgeA
-    TopoDS_Vertex Va,Vb;
-    TopExp::Vertices(TopoDS::Edge(ShapeA),Va ,Vb );
-    // Recuperation des points.
-    gp_Pnt A=BRep_Tool::Pnt(Va);
-    gp_Pnt B=BRep_Tool::Pnt(Vb);
-    gp_Pnt C(A.X()+5 ,A.Y()+5 ,A.Z()+5 );
-
-
-    // Construction du plane. Methode pas orthodoxe!
-    GC_MakePlane MkPlane(A ,B ,C );
-    Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
-    
-    // Construction du texte.
-    TCollection_ExtendedString TheMessage_Str(TCollection_ExtendedString("d=")+TCollection_ExtendedString( 90 ) );
-    
-    // Fermeture du context local.
-    TheAISContext()->CloseLocalContext(myCurrentIndex);
-    
-    // Construction de l'AIS dimension
-    Handle (AIS_AngleDimension) myAISDim= new AIS_AngleDimension (TopoDS::Edge(ShapeA) ,TopoDS::Edge(ShapeB) ,theGeomPlane->Pln());
-    GetMapOfAIS().Bind (myAISDim,argv[1]);
-    TheAISContext()->Display(myAISDim );
-    
-  }
-else {
-  di<<" vangledim error: you must select 2 edges."<<"\n";return 1;
-}
-  
-  
-  return 0;
-}
+  theStringParams.Clear();
 
-//==============================================================================
-//function : VDiameterDim
-//purpose  : Display the diameter dimension of a face or an edge.
-//Draw arg : vdiameterdim Name 
-//==============================================================================
+  // Begin from the second parameter: the first one is dimension name
+  for (Standard_Integer anIt = theStartIndex; anIt < theArgNum; ++anIt)
+  {
+    TCollection_AsciiString aParam (theArgVec[anIt]);
+    aParam.LowerCase();
 
-static int VDiameterDimBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
-{
-  // Declarations
-  Standard_Integer myCurrentIndex;
-  Standard_Real theRadius;
-    
-  // Verification
-  if (argc!=2) {di<<" vdiameterdim error"<<"\n";return 1;}
-  // Fermeture des contextes locaux
-  TheAISContext()->CloseAllContexts();
-  // Ouverture d'un contexte local et recuperation de son index.
-  TheAISContext()->OpenLocalContext();
-  myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
-  
-  // On active les modes de selections Edges et Faces.
-  TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
-  di<<" Select an circled edge."<<"\n";
-  
-  // Boucle d'attente waitpick.
-  Standard_Integer argcc = 5;
-  const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-  const char **argvv = (const char **) buff;
-  while (ViewerMainLoop( argcc, argvv) ) { }
-  // fin de la boucle
-  
-  TopoDS_Shape ShapeA;
-  for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-    ShapeA = TheAISContext()->SelectedShape();
-  }
-  if (ShapeA.ShapeType()==TopAbs_EDGE  ) {
-    
-    // Recuperation du rayon 
-    BRepAdaptor_Curve theCurve(TopoDS::Edge(ShapeA));
-    if (theCurve.GetType()!=GeomAbs_Circle ) {di<<"vdiameterdim error: the edge is not a circular one."<<"\n";return 1;}
-    else {
-      gp_Circ theGpCircle=theCurve.Circle();
-      theRadius=2.*theGpCircle.Radius();
+    if (aParam.Search ("-") == -1)
+    {
+      std::cerr << "Error: wrong parameter '" << aParam << "'.\n";
+      return 1;
     }
-    
-    // Construction du texte.
-    TCollection_ExtendedString TheMessage_Str(TCollection_ExtendedString("d=")+TCollection_ExtendedString(theRadius  ) );
-    // Construction de L'AIS_AngleDimension.
-    TheAISContext()->CloseLocalContext(myCurrentIndex);
-    
-    Handle (AIS_DiameterDimension) myDiamDim= new AIS_DiameterDimension(ShapeA);
-    GetMapOfAIS().Bind (myDiamDim,argv[1]);
-    TheAISContext()->Display(myDiamDim );
-    
-  }
-  
-  else {
-    di<<" vdiameterdim error: the selection of a face or an edge was expected."<<"\n";return 1;
-  }
-  
-  return 0;
-  
-}
 
+    // Before all non-boolean flags parsing check if a flag have at least one value.
+    if (anIt + 1 >= theArgNum)
+    {
+      std::cerr << "Error: "<< aParam <<" flag should have value.\n";
+      return 1;
+    }
 
-//==============================================================================
-// Fonction  vconcentric
-// -----------------  Uniquement par selection dans le viewer.
-//==============================================================================
-
-//==============================================================================
-//function : VConcentric
-//purpose  : Display the concentric relation between two surfaces.
-//Draw arg : vconcentric Name
-//==============================================================================
-#include <AIS_ConcentricRelation.hxx>
-#include <Geom_Plane.hxx>
-#include <gp_Pln.hxx>
-#include <GC_MakePlane.hxx>
-#include <BRepAdaptor_Curve.hxx>
-#include <TopExp_Explorer.hxx>
+    if (aParam.IsEqual ("-type"))
+    {
+      TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
 
+      theStringParams.Bind ("type", aLocalParam);
+    }
+    else if (aParam.IsEqual ("-showarrow"))
+    {
+      TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
 
-static int VConcentricBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
-{
-  // Declarations
-  Standard_Integer myCurrentIndex;
-  
-  // Verification
-  if (argc!=2) {di<<"vconcentric  error."<<"\n";return 1;}
-  // Fermeture des contextes locaux
-  TheAISContext()->CloseAllContexts();
-  // Ouverture d'un contexte local et recuperation de son index.
-  TheAISContext()->OpenLocalContext();
-  myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
-  
-  // On active les modes de selections Edges et Faces.
-  TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
-  di<<" Select a circled edge."<<"\n";
-  
-  // Boucle d'attente waitpick.
-  Standard_Integer argcc = 5;
-  const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-  const char **argvv = (const char **) buff;
-  while (ViewerMainLoop( argcc, argvv) ) { }
-  // fin de la boucle
-  
-  TopoDS_Shape ShapeA;
-  for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-    ShapeA = TheAISContext()->SelectedShape();
-  }
-  // ShapeA est un edge
-  // ==================
-  if (ShapeA.ShapeType()==TopAbs_EDGE  ) {
-    TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4) );
-    di<<" Select an edge."<<"\n";
-    
-    // Boucle d'attente waitpick.
-    Standard_Integer argccc = 5;
-    const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-    const char **argvvv = (const char **) bufff;
-    while (ViewerMainLoop( argccc, argvvv) ) { }
-    // fin de la boucle
-    
-    TopoDS_Shape ShapeB;
-    for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-      ShapeB = TheAISContext()->SelectedShape();
+      theStringParams.Bind ("showarrow", aLocalParam);
     }
-    if (ShapeB.ShapeType()!=TopAbs_EDGE  ) {
-      di<<" vconcentric error: select an edge."<<"\n";return 1;
+    else
+    {
+      std::cerr << "Error: unknown parameter '" << aParam << "'.\n";
+      return 1;
     }
-     
-    // Construction du plane.
-    // On recupere le centre du cercle A.
-    BRepAdaptor_Curve theCurveA(TopoDS::Edge(ShapeA) );
-    gp_Circ theCircleA=theCurveA.Circle();
-    gp_Pnt theCenterA=theCircleA.Location();
-    // On recupere deux points sur le cercle A
-    gp_Pnt B= theCurveA.Value(0.25);
-    gp_Pnt C= theCurveA.Value(0.75);
-    // Construction du plane.
-    GC_MakePlane MkPlane(theCenterA ,B ,C );
-    Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
-    
-    // Fermeture du context local
-    TheAISContext()->CloseLocalContext(myCurrentIndex);
-    
-    Handle (AIS_ConcentricRelation) myConcentry= new AIS_ConcentricRelation(ShapeA, ShapeB, theGeomPlane );
-    TheAISContext()->Display(myConcentry );
-    GetMapOfAIS().Bind (myConcentry,argv[1]);
-  }
-  
-  
-  else {
-    di<<" vconcentric  error: the selection of a face or an edge was expected."<<"\n";return 1;
   }
-  
+
   return 0;
-  
-  
-  
-  
 }
 
-//==============================================================================
-//function : VEqualDistRelation
-//purpose  : 
-//Draw arg : vdiameterdim Name DiameterValue
-//==============================================================================
-#include <AIS_EqualDistanceRelation.hxx>
-#include <BRepExtrema_ExtCC.hxx>
-#include <GC_MakePlane.hxx>
-
-
-static int VEqualDistRelation(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
+//=======================================================================
+//function : SetAngleDimensionParams
+//purpose  : Sets parameters for angle dimension
+//=======================================================================
+static void SetAngleDimensionParams (const Handle(PrsDim_Dimension)& theDim,
+                                     const NCollection_DataMap<TCollection_AsciiString,
+                                     TCollection_AsciiString>& theStringParams)
 {
-  // Declarations
-  Standard_Integer myCurrentIndex;
-  
-  // Verification
-  if (argc!=2) {di<<" vequaldistrelation error: no arguments allowed."<<"\n";return 1;}
-  
-  // Fermeture des contextes locaux
-  TheAISContext()->CloseAllContexts();
-  
-  // Ouverture d'un contexte local et recuperation de son index.
-  TheAISContext()->OpenLocalContext();
-  myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
-  
-  // On active les modes de selections Edges et Vertexes.
-  TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
-  TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1) );
-  di<<" Select an edge or a vertex"<<"\n";
-  
-  // Boucle d'attente waitpick.
-  Standard_Integer argc1 = 5;
-  const char *buf1[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-  const char **argv1 = (const char **) buf1;
-  while (ViewerMainLoop( argc1, argv1) ) { }
-  // fin de la boucle
-  
-  TopoDS_Shape ShapeA;
-  for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-    ShapeA = TheAISContext()->SelectedShape();
-  }
-  
-  di<<" Select an edge or a vertex"<<"\n";
-  // Boucle d'attente waitpick.
-  Standard_Integer argc2 = 5;
-  const char *buf2[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-  const char **argv2 = (const char **) buf2;
-  while (ViewerMainLoop( argc2, argv2) ) { }
-  // fin de la boucle
-  
-  TopoDS_Shape ShapeB;
-  for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-    ShapeB = TheAISContext()->SelectedShape();
-  }
-  
-  // Verification des resultats.
-  if (ShapeA.ShapeType()==TopAbs_EDGE && ShapeB.ShapeType()==TopAbs_EDGE  ) {
-    // A et B sont des edges ils doivent etre paralleles
-    BRepExtrema_ExtCC myDeltaEdge (TopoDS::Edge(ShapeA) ,TopoDS::Edge(ShapeB)  );
-    // on verifie qu'ils sont pas paralleles.
-    if (!myDeltaEdge.IsParallel() ) {di<<"vequaldist error: non parallel edges."<<"\n";return 1; }
-    
-  }
-  
-  
-  di<<" Select an edge or a vertex"<<"\n";
-  // Boucle d'attente waitpick.
-  Standard_Integer argc3 = 5;
-  const char *buf3[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-  const char **argv3 = (const char **) buf3;
-  while (ViewerMainLoop( argc3, argv3) ) { }
-  // fin de la boucle
-  
-  TopoDS_Shape ShapeC;
-  for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-    ShapeC = TheAISContext()->SelectedShape();
-  }
-  
-  di<<" Select an edge or a vertex"<<"\n";
-  // Boucle d'attente waitpick.
-  Standard_Integer argc4 = 5;
-  const char *buf4[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-  const char **argv4 = (const char **) buf4;
-  while (ViewerMainLoop( argc4, argv4) ) { }
-  // fin de la boucle
-  
-  TopoDS_Shape ShapeD;
-  for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-    ShapeD = TheAISContext()->SelectedShape();
-  }
-  // Verification des resultats.
-  if (ShapeC.ShapeType()==TopAbs_EDGE && ShapeD.ShapeType()==TopAbs_EDGE  ) {
-    // C et D sont des edges ils doivent etre paralleles
-    BRepExtrema_ExtCC myDeltaEdge2 (TopoDS::Edge(ShapeC) ,TopoDS::Edge(ShapeD)  );
-    // on verifie qu'ils sont pas paralleles.
-    if (!myDeltaEdge2.IsParallel() ) {di<<"vequaldist error: non parallel edges."<<"\n";return 1; }
-    
+  Handle(PrsDim_AngleDimension) anAngleDim = Handle(PrsDim_AngleDimension)::DownCast (theDim);
+  if (anAngleDim.IsNull())
+  {
+    return;
   }
-  
-  // Creation du plan porteur de la contrainte.Methode lourde!
-  gp_Pnt A,B,C;
-  if (ShapeA.ShapeType()==TopAbs_EDGE) {
-    // A est un edge
-    TopoDS_Vertex Va,Vb;
-    TopExp::Vertices (TopoDS::Edge(ShapeA) ,Va ,Vb );
-    A=BRep_Tool::Pnt(Va);
-    B=BRep_Tool::Pnt(Vb);
-    
-    if (ShapeB.ShapeType()==TopAbs_EDGE) {
-      // B est un edge aussi
-      TopoDS_Vertex Vc,Vd;
-      TopExp::Vertices (TopoDS::Edge(ShapeB) ,Vc ,Vd );
-      // besoin que de 1 point.
-      C=BRep_Tool::Pnt(Vc);
-      
+
+  if (theStringParams.IsBound ("type"))
+  {
+    PrsDim_TypeOfAngle anAngleType = PrsDim_TypeOfAngle_Interior;
+    TCollection_AsciiString anAngleTypeStr = theStringParams.Find ("type");
+    if (anAngleTypeStr.IsEqual("interior"))
+    {
+      anAngleType = PrsDim_TypeOfAngle_Interior;
+    }
+    else if (anAngleTypeStr.IsEqual("exterior"))
+    {
+      anAngleType = PrsDim_TypeOfAngle_Exterior;
     }
-    else {
-      // B est un vertex
-      C=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB) );
+    else
+    {
+      std::cerr << "Error: wrong angle type.\n";
     }
+    anAngleDim->SetType(anAngleType);
   }
-  else {
-    // A est un vertex
-    A=BRep_Tool::Pnt(TopoDS::Vertex(ShapeA) );
-    
-    if (ShapeB.ShapeType()==TopAbs_EDGE ) {
-      // B est un edge 
-      TopoDS_Vertex Vb,Vc;
-      TopExp::Vertices (TopoDS::Edge(ShapeB) ,Vb ,Vc );
-      // besoin que de 2 points.
-      B=BRep_Tool::Pnt(Vb);
-      C=BRep_Tool::Pnt(Vc);
-      
+
+  if (theStringParams.IsBound ("showarrow"))
+  {
+    PrsDim_TypeOfAngleArrowVisibility anArrowType = PrsDim_TypeOfAngleArrowVisibility_Both;
+    TCollection_AsciiString anArrowTypeStr = theStringParams.Find ("showarrow");
+    if (anArrowTypeStr.IsEqual("both"))
+    {
+      anArrowType = PrsDim_TypeOfAngleArrowVisibility_Both;
     }
-    else {
-      // B est un vertex
-      B=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB) );
-      C.SetX(B.X()+5.);
-      C.SetY(B.Y()+5.);
-      C.SetZ(B.Z()+5.);
-      
+    else if (anArrowTypeStr.IsEqual("first"))
+    {
+      anArrowType = PrsDim_TypeOfAngleArrowVisibility_First;
+    }
+    else if (anArrowTypeStr.IsEqual("second"))
+    {
+      anArrowType = PrsDim_TypeOfAngleArrowVisibility_Second;
+    }
+    else if (anArrowTypeStr.IsEqual("none"))
+    {
+      anArrowType = PrsDim_TypeOfAngleArrowVisibility_None;
     }
+    else
+    {
+      std::cerr << "Error: wrong showarrow type.\n";
+    }
+    anAngleDim->SetArrowsVisibility(anArrowType);
   }
-  
-  // Fermeture du context local.
-  TheAISContext()->CloseLocalContext(myCurrentIndex);
-  
-  // construction du plane 
-  GC_MakePlane MkPlane(A ,B ,C );
-  Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
-  
-  // Construction de l'AIS_EqualDistanceRelation
-  Handle (AIS_EqualDistanceRelation ) myRelation= new AIS_EqualDistanceRelation (ShapeA, ShapeB, ShapeC ,ShapeD , theGeomPlane );
-  TheAISContext()->Display(myRelation );
-  GetMapOfAIS().Bind (myRelation,argv[1]);
-  
-
-  
-  return 0;
-  
 }
 
-//==============================================================================
-//function : VEqualRadiusRelation
-//purpose  : 
-//Draw arg : vdiameterdim Name DiameterValue
-//==============================================================================
-#include <AIS_EqualRadiusRelation.hxx>
-#include <GC_MakePlane.hxx>
-#include <BRepAdaptor_Curve.hxx>
-
-
-static int VEqualRadiusRelation(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
+//=======================================================================
+//function : VDimBuilder
+//purpose  : Command for building dimension presentations: angle,
+//           length, radius, diameter
+//=======================================================================
+static int VDimBuilder (Draw_Interpretor& /*theDi*/,
+                        Standard_Integer  theArgsNb,
+                        const char**      theArgs)
 {
-  // Declarations
-  Standard_Integer myCurrentIndex;
-  
-  // Verification
-  if (argc!=2) {di<<" vequalrad error: no arguments allowed."<<"\n";return 1;}
-  
-  // Fermeture des contextes locaux
-  TheAISContext()->CloseAllContexts();
-  
-  // Ouverture d'un contexte local et recuperation de son index.
-  TheAISContext()->OpenLocalContext();
-  myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
-  
-  // On active les modes de selections Edges.
-  TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
-  di<<" Select an circled edge "<<"\n";
-  
-  // Boucle d'attente waitpick.
-  Standard_Integer argc1 = 5;
-  const char *buf1[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-  const char **argv1 = (const char **) buf1;
-  while (ViewerMainLoop( argc1, argv1) ) { }
-  // fin de la boucle
-  
-  TopoDS_Shape ShapeA;
-  for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-    ShapeA = TheAISContext()->SelectedShape();
-  }
-  
-  di<<" Select the last circled edge."<<"\n";
-  // Boucle d'attente waitpick.
-  Standard_Integer argc2 = 5;
-  const char *buf2[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-  const char **argv2 = (const char **) buf2;
-  while (ViewerMainLoop( argc2, argv2) ) { }
-  // fin de la boucle
-  
-  TopoDS_Shape ShapeB;
-  for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-    ShapeB = TheAISContext()->SelectedShape();
+  if (theArgsNb < 2)
+  {
+    std::cerr << "Error: wrong number of arguments.\n";
+    return 1;
   }
-  // creation du plan qui contient la contrainte.
-  TopoDS_Edge EdgeA=TopoDS::Edge(ShapeA);
-  TopoDS_Edge EdgeB=TopoDS::Edge(ShapeB);
-  BRepAdaptor_Curve theCurveA(EdgeA);
-  // On recupere 3 points A,B,C de la curve.
-  gp_Pnt A=theCurveA.Value(0.1);
-  gp_Pnt B=theCurveA.Value(0.5);
-  gp_Pnt C=theCurveA.Value(0.9);
-  
-  // fermeture du contexte local.
-  TheAISContext()->CloseLocalContext(myCurrentIndex);
-  
-  // Creation du plane.
-  GC_MakePlane MkPlane (A ,B ,C );
-  Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
-  // Construction de l'AIS_EqualRadiusRelation
-  Handle (AIS_EqualRadiusRelation ) myRelation= new AIS_EqualRadiusRelation (EdgeA,EdgeB, theGeomPlane );
-  TheAISContext()->Display(myRelation );
-  GetMapOfAIS().Bind (myRelation,argv[1]);
-  
-  return 0;
-  
-}
-
 
-//==============================================================================
-//function : VFixRelation
-//purpose  : 
-//Draw arg : vdiameterdim Name DiameterValue
-//==============================================================================
-#include <AIS_FixRelation.hxx>
-#include <GC_MakePlane.hxx>
-#include <BRepAdaptor_Curve.hxx>
-
-static int VFixRelation(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
-{
-  // Declarations
-  Standard_Integer myCurrentIndex;
-  
-  // Verification
-  if (argc!=2) {di<<" vfix  error: no arguments allowed."<<"\n";return 1;}
-  
-  // Fermeture des contextes locaux
-  TheAISContext()->CloseAllContexts();
-  
-  // Ouverture d'un contexte local et recuperation de son index.
-  TheAISContext()->OpenLocalContext();
-  myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
-  
-  // On active les modes de selections edge.
-  TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
-  di<<" Select an edge. "<<"\n";
-  
-  // Boucle d'attente waitpick.
-  Standard_Integer argc1 = 5;
-  const char *buf1[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-  const char **argv1 = (const char **) buf1;
-  while (ViewerMainLoop( argc1, argv1) ) { }
-  // fin de la boucle
-  
-  TopoDS_Shape ShapeA;
-  for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-    ShapeA = TheAISContext()->SelectedShape();
-  }
-  
-  // creation du plan qui contient la contrainte.
-  TopoDS_Edge EdgeA=TopoDS::Edge(ShapeA);
-  BRepAdaptor_Curve theCurveA(EdgeA);
-  // On recupere 3 points A,B,C de la curve.
-  gp_Pnt A=theCurveA.Value(0.1);
-  gp_Pnt B=theCurveA.Value(0.5);
-  gp_Pnt D=theCurveA.Value(0.9);
-  gp_Pnt C(B.X()+5,B.Y()+5,B.Z()+5);
-  
-  // fermeture du contexte local.
-  TheAISContext()->CloseLocalContext(myCurrentIndex);
-  
-  // Creation du plane.
-  GC_MakePlane MkPlane (A ,D ,C );
-  Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
-  // Construction de l'AIS_EqualRadiusRelation
-  Handle (AIS_FixRelation) myRelation= new AIS_FixRelation (EdgeA,theGeomPlane );
-  TheAISContext()->Display(myRelation );
-  GetMapOfAIS().Bind (myRelation,argv[1]);
-  
-  
-  return 0;
-  
-}
+  // Parse parameters
+  TCollection_AsciiString aName (theArgs[1]);
 
-//==============================================================================
-//function : VIdenticRelation
-//purpose  : 
-//Draw arg : vdiameterdim Name DiameterValue
-//==============================================================================
-#include <AIS_IdenticRelation.hxx>
-#include <BRepAdaptor_Curve.hxx>
-#include <TopExp_Explorer.hxx>
+  NCollection_List<Handle(AIS_InteractiveObject)> aShapes;
+  Handle(Prs3d_DimensionAspect) anAspect = new Prs3d_DimensionAspect;
+  Standard_Boolean isPlaneCustom = Standard_False;
+  gp_Pln aWorkingPlane;
 
+  NCollection_DataMap<TCollection_AsciiString, Standard_Real> aRealParams;
+  NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString> aStringParams;
 
-static int VIdenticRelation(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
-{
-  // Declarations
-  Standard_Integer myCurrentIndex;
-  
-  // Verification
-  if (argc!=2) {di<<" videntity error: no arguments allowed."<<"\n";return 1;}
-  
-  // Fermeture des contextes locaux
-  TheAISContext()->CloseAllContexts();
-  
-  // Ouverture d'un contexte local et recuperation de son index.
-  TheAISContext()->OpenLocalContext();
-  myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
-  
-  // On active les modes de selections  vertex et face.
-  TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
-  TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1) );
-  TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4) );
-  di<<" Select an edge, a face or a vertex. "<<"\n";
-  
-  // Boucle d'attente waitpick.
-  Standard_Integer argc1 = 5;
-  const char *buf1[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-  const char **argv1 = (const char **) buf1;
-  while (ViewerMainLoop( argc1, argv1) ) { }
-  // fin de la boucle
-  
-  TopoDS_Shape ShapeA;
-  for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-    ShapeA = TheAISContext()->SelectedShape();
+  TCollection_AsciiString aDimType(theArgs[2]);
+  aDimType.LowerCase();
+  PrsDim_KindOfDimension aKindOfDimension;
+  if (aDimType == "-length")
+  {
+    aKindOfDimension = PrsDim_KOD_LENGTH;
   }
-  
-  di<<" Select an edge, a face or a vertex. "<<"\n";
-  // Boucle d'attente waitpick.
-  Standard_Integer argc2 = 5;
-  const char *buf2[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-  const char **argv2 = (const char **) buf2;
-  while (ViewerMainLoop( argc2, argv2) ) { }
-  // fin de la boucle
-  
-  TopoDS_Shape ShapeB;
-  for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-    ShapeB = TheAISContext()->SelectedShape();
+  else if (aDimType == "-angle")
+  {
+    aKindOfDimension = PrsDim_KOD_PLANEANGLE;
   }
-  
-  // Recuperation de points pour construir le Geom_Plnae.
-  gp_Pnt A,B,C;
-  if (ShapeA.ShapeType()==TopAbs_EDGE) {
-    // A est un edge; on peut supposer qu'il sera element d'une face ou possesseur d'un vertex ou identic a un autre edge.
-    // on recupere deux points sur l'edge (il peut etre rectiligne)
-    TopoDS_Edge EdgeA=TopoDS::Edge(ShapeA);
-    BRepAdaptor_Curve theCurveA(EdgeA);
-    // Creation des 3 points.
-    A=theCurveA.Value(0.1);
-    B=theCurveA.Value(0.9);
-    C.SetX(B.X()+5.);
-    C.SetY(B.Y()+5.);
-    C.SetZ(B.Z()+5.);
+  else if (aDimType == "-radius")
+  {
+    aKindOfDimension = PrsDim_KOD_RADIUS;
   }
-  else if (ShapeA.ShapeType()==TopAbs_VERTEX ) {
-    // SahpeA est un Vertex
-    // On va utiliser ShapeB
-    if (ShapeB.ShapeType()==TopAbs_EDGE) {
-      // B est un edge 
-      TopoDS_Edge EdgeB=TopoDS::Edge(ShapeB);
-      BRepAdaptor_Curve theCurveB(EdgeB);
-      // Creation des 3 points.
-      A=theCurveB.Value(0.1);
-      B=theCurveB.Value(0.9);
-      C.SetX(B.X()+5.);
-      C.SetY(B.Y()+5.);
-      C.SetZ(B.Z()+5.);
-      
-    }
-    else if (ShapeB.ShapeType()==TopAbs_FACE ) {
-      // Shape B est une face
-      TopoDS_Face  FaceB=TopoDS::Face(ShapeB);
-      // On recupere 1 edge de FaceB(la face n'a pas forcement de vertex) (l'element A est forcement dans B).
-      TopExp_Explorer FaceExp(FaceB,TopAbs_EDGE);
-      TopoDS_Edge EdgeFromB=TopoDS::Edge(FaceExp.Current() );
-      // On recupere les 3 points de l'edge de face B
-      BRepAdaptor_Curve theCurveB(EdgeFromB);
-      // On recupere 3 points A,B,C de la curve.
-      A=theCurveB.Value(0.1);
-      B=theCurveB.Value(0.5);
-      C=theCurveB.Value(0.9);
-      
-    }
-    else {
-      // B ets un vetex aussi
-      A=BRep_Tool::Pnt(TopoDS::Vertex(ShapeA) );
-      B=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB) );
-      C.SetX(B.X()+5.);
-      C.SetY(B.Y()+5.);
-      C.SetZ(B.Z()+5.);
-      
-    }
-    
+  else if (aDimType == "-diameter" || aDimType == "-diam")
+  {
+    aKindOfDimension = PrsDim_KOD_DIAMETER;
   }
-  else {
-    // A est une face.
-    TopoDS_Face  FaceA=TopoDS::Face(ShapeA);
-    // On recupere 1 edge de FaceA
-    TopExp_Explorer FaceExp(FaceA,TopAbs_EDGE);
-    TopoDS_Edge EdgeFromA=TopoDS::Edge(FaceExp.Current() );
-    // On recupere les 3 points de l'edge
-    BRepAdaptor_Curve theCurveA(EdgeFromA);
-    // On recupere 3 points A,B,C de la curve.
-    A=theCurveA.Value(0.1);
-    B=theCurveA.Value(0.5);
-    C=theCurveA.Value(0.9);
-    
+  else
+  {
+    std::cerr << "Error: wrong type of dimension.\n";
+    return 1;
   }
-  
-  // Fermeture du context local.
-  TheAISContext()->CloseLocalContext(myCurrentIndex);
-  // On construit le plane 
-  GC_MakePlane MkPlane (A ,B ,C );
-  Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
-  
-  // Construction de l'AIS_IdenticRelation
-  Handle ( AIS_IdenticRelation ) myRelation= new AIS_IdenticRelation  (ShapeA ,ShapeB, theGeomPlane );
-  TheAISContext()->Display(myRelation );
-  GetMapOfAIS().Bind (myRelation,argv[1]);
-  
 
-  
-  return 0;
-  
-}
-//==============================================================================
-//function : VLengthDimension
-//purpose  : Display the diameter dimension of a face or an edge.
-//Draw arg : vdiameterdim Name DiameterValue
-//==============================================================================
-#include <AIS_LengthDimension.hxx>
-#include <BRepExtrema_ExtCC.hxx>
-#include <BRepExtrema_ExtPC.hxx>
-#include <BRepExtrema_ExtCF.hxx>
-#include <BRepExtrema_ExtPF.hxx>
-#include <BRepExtrema_ExtFF.hxx>
-#include <TCollection_ExtendedString.hxx>
-#include <BRepExtrema_DistShapeShape.hxx>
-#include <GC_MakePlane.hxx>
-#include <TopExp_Explorer.hxx>
-#include <BRepBuilderAPI_MakeVertex.hxx>
-static int VLenghtDimension(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
-{
-  // Declarations
-  Standard_Integer myCurrentIndex;
-  Standard_Real theDist;
-  
-  // Verification
-  if (argc!=2) {di<<" videntity error: no arguments allowed."<<"\n";return 1;}
-  
-  // Fermeture des contextes locaux
-  TheAISContext()->CloseAllContexts();
-  
-  // Ouverture d'un contexte local et recuperation de son index.
-  myCurrentIndex = TheAISContext()->OpenLocalContext();
-  TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
-  TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1) );
-  TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4) );
-  di<<" Select an edge, a face or a vertex. "<<"\n";
-  
-  // Boucle d'attente waitpick.
-  Standard_Integer argc1 = 5;
-  const char *buf1[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-  const char **argv1 = (const char **) buf1;
-  while (ViewerMainLoop( argc1, argv1) ) { }
-
-  // fin de la boucle
-  TopoDS_Shape ShapeA;
-  for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-    ShapeA = TheAISContext()->SelectedShape();
-  }
-  di<<" Select an edge, a face or a vertex. "<<"\n";
-  // Boucle d'attente waitpick.
-  Standard_Integer argc2 = 5;
-  const char *buf2[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-  const char **argv2 = (const char **) buf2;
-  while (ViewerMainLoop( argc2, argv2) ) { }
-  // fin de la boucle
-  
-  TopoDS_Shape ShapeB;
-  for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-    ShapeB = TheAISContext()->SelectedShape();
+
+  if (ParseDimensionParams (theArgsNb, theArgs, 3,
+                            anAspect,isPlaneCustom,aWorkingPlane,
+                            aRealParams, aStringParams, &aShapes))
+  {
+    return 1;
   }
-  // ShapeA est un edge.
-  // ===================
-  if (ShapeA.ShapeType()==TopAbs_EDGE ) {
-    TopoDS_Edge  EdgeA=TopoDS::Edge(ShapeA);
-    
-    // Si ShapeB est un edge
-    if (ShapeB.ShapeType()==TopAbs_EDGE ) {
-      TopoDS_Edge  EdgeB=TopoDS::Edge(ShapeB);
-      BRepExtrema_ExtCC myDeltaEdge (EdgeA ,EdgeB );
-      // on verifie qu'ils ne sont pas paralleles.
-      if (!myDeltaEdge.IsParallel() ) {di<<"vlenghtdim error: non parallel edges."<<"\n";return 1; }
-      
-      // On saisit la distance et on l'arrondit!
-      theDist=Round (sqrt(myDeltaEdge.SquareDistance(1))*10. )/10.;
-      
-      // On recupere 3 Points des edges pour construire un plane.
-      TopoDS_Vertex  Va,Vb,Vc,Vd;
-      TopExp::Vertices(EdgeA,Va,Vb);
-      TopExp::Vertices(EdgeB,Vc,Vd);
-      gp_Pnt A=BRep_Tool::Pnt(Va);
-      gp_Pnt B=BRep_Tool::Pnt(Vb);
-      gp_Pnt C=BRep_Tool::Pnt(Vc);
-      
-      // Creation du Plane contenant la relation.
-      GC_MakePlane MkPlane(A,B,C);
-      Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
-      
-      TCollection_ExtendedString TheMessage_Str(TCollection_ExtendedString("d=")+TCollection_ExtendedString(theDist ) );
-      
-      // On ferme le contexte local.
-      TheAISContext()->CloseLocalContext(myCurrentIndex);
-      
-      // on construit l'AISLenghtDimension.
-      Handle(AIS_LengthDimension ) myLenghtDim=new AIS_LengthDimension (EdgeA,EdgeB,theGeomPlane->Pln());
-      TheAISContext()->Display(myLenghtDim );
-      GetMapOfAIS().Bind (myLenghtDim ,argv[1]);
-    }
-    
-    // Si ShapeB est un vertex.
-    else if (ShapeB.ShapeType()==TopAbs_VERTEX ) {
-      
-      TopoDS_Vertex  VertexB=TopoDS::Vertex(ShapeB);
-      BRepExtrema_ExtPC myDeltaEdgeVertex  (VertexB ,EdgeA );
-      
-      // On saisit la distance et on l'arrondit!
-      theDist=Round (sqrt (myDeltaEdgeVertex.SquareDistance(1))*10. )/10.;
-      
-      // On recupere 2 Points de EdgeA pour construire un plane.
-      TopoDS_Vertex  Va,Vb;
-      TopExp::Vertices(EdgeA,Va,Vb);
-      gp_Pnt A=BRep_Tool::Pnt(Va);
-      gp_Pnt B=BRep_Tool::Pnt(Vb);
-      gp_Pnt C=BRep_Tool::Pnt(VertexB);
-      
-      GC_MakePlane MkPlane(A,B,C);
-      Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
-      
-      TCollection_ExtendedString TheMessage_Str(TCollection_ExtendedString("d=")+TCollection_ExtendedString(theDist ) );
-      TheAISContext()->CloseLocalContext(myCurrentIndex);
-      Handle(AIS_LengthDimension ) myLenghtDim=new AIS_LengthDimension (EdgeA,VertexB,theGeomPlane->Pln());
-      TheAISContext()->Display(myLenghtDim );
-      GetMapOfAIS().Bind (myLenghtDim ,argv[1]);
-      
-      
-    }
-    
-    // Si ShapeB est une Face
-    else
+
+  // Build dimension
+  Handle(PrsDim_Dimension) aDim;
+  switch (aKindOfDimension)
+  {
+    case PrsDim_KOD_LENGTH:
+    {
+      if (aShapes.Extent() == 1)
+      {
+        if (aShapes.First()->Type() == AIS_KOI_Shape
+          && (Handle(AIS_Shape)::DownCast(aShapes.First()))->Shape().ShapeType() != TopAbs_EDGE)
+        {
+          std::cerr << theArgs[0] << ": wrong shape type.\n";
+          return 1;
+        }
+        if (!isPlaneCustom)
+        {
+          std::cerr << theArgs[0] << ": can not build dimension without working plane.\n";
+          return 1;
+        }
+
+        // Adjust working plane
+        TopoDS_Edge anEdge = TopoDS::Edge ((Handle(AIS_Shape)::DownCast(aShapes.First()))->Shape());
+        TopoDS_Vertex aFirst, aSecond;
+        TopExp::Vertices (anEdge, aFirst, aSecond);
+        aDim = new PrsDim_LengthDimension (anEdge, aWorkingPlane);
+
+        // Move standard plane (XOY, YOZ or ZOX) to the first point to make it working for dimension
+        aWorkingPlane.SetLocation (Handle(PrsDim_LengthDimension)::DownCast (aDim)->FirstPoint());
+      }
+      else if (aShapes.Extent() == 2)
+      {
+        TopoDS_Shape aShape1, aShape2;
+
+        // Getting shapes
+        if (aShapes.First()->DynamicType() == STANDARD_TYPE (AIS_Point))
+        {
+          aShape1 = Handle(AIS_Point)::DownCast (aShapes.First ())->Vertex();
+        }
+        else if (aShapes.First()->Type() == AIS_KOI_Shape)
+        {
+          aShape1 = (Handle(AIS_Shape)::DownCast (aShapes.First()))->Shape();
+        }
+
+        if (aShapes.Last()->DynamicType() == STANDARD_TYPE (AIS_Point))
+        {
+          aShape2 = Handle(AIS_Point)::DownCast (aShapes.Last ())->Vertex();
+        }
+        else if (aShapes.Last()->Type() == AIS_KOI_Shape)
+        {
+          aShape2 = (Handle(AIS_Shape)::DownCast (aShapes.Last()))->Shape();
+        }
+
+        if (aShape1.IsNull() || aShape2.IsNull())
+        {
+          std::cerr << theArgs[0] << ": wrong shape type.\n";
+          return 1;
+        }
+
+        // Face-Face case
+        if (aShape1.ShapeType() == TopAbs_FACE && aShape2.ShapeType() == TopAbs_FACE)
+        {
+          aDim = new PrsDim_LengthDimension (TopoDS::Face (aShape1), TopoDS::Face (aShape2));
+        }
+        else if (aShape1.ShapeType() == TopAbs_FACE && aShape2.ShapeType() == TopAbs_EDGE)
+        {
+          aDim = new PrsDim_LengthDimension (TopoDS::Face (aShape1), TopoDS::Edge (aShape2));
+        }
+        else if (aShape1.ShapeType() == TopAbs_EDGE && aShape2.ShapeType() == TopAbs_FACE)
+        {
+          aDim = new PrsDim_LengthDimension (TopoDS::Face (aShape2), TopoDS::Edge (aShape1));
+        }
+        else
+        {
+          if (!isPlaneCustom)
+          {
+            std::cerr << theArgs[0] << ": can not build dimension without working plane.\n";
+            return 1;
+          }
+          // Vertex-Vertex case
+          if (aShape1.ShapeType() == TopAbs_VERTEX)
+          {
+            aWorkingPlane.SetLocation (BRep_Tool::Pnt (TopoDS::Vertex (aShape1)));
+          }
+          else if (aShape2.ShapeType() == TopAbs_VERTEX)
+          {
+            aWorkingPlane.SetLocation (BRep_Tool::Pnt (TopoDS::Vertex (aShape2)));
+          }
+
+          aDim = new PrsDim_LengthDimension (aShape1, aShape2, aWorkingPlane);
+        }
+      }
+      else
+      {
+        std::cerr << theArgs[0] << ": wrong number of shapes to build dimension.\n";
+        return 1;
+      }
+
+      break;
+    }
+    case PrsDim_KOD_PLANEANGLE:
+    {
+      if (aShapes.Extent() == 1 && aShapes.First()->Type()==AIS_KOI_Shape)
+      {
+        Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(aShapes.First());
+        if (aShape->Shape().ShapeType() == TopAbs_FACE)
+          aDim = new PrsDim_AngleDimension (TopoDS::Face(aShape->Shape()));
+      }
+      if (aShapes.Extent() == 2)
+      {
+        Handle(AIS_Shape) aShape1 = Handle(AIS_Shape)::DownCast(aShapes.First());
+        Handle(AIS_Shape) aShape2 = Handle(AIS_Shape)::DownCast(aShapes.Last());
+        if (!aShape1.IsNull() && !aShape2.IsNull()
+          && aShape1->Shape().ShapeType() == TopAbs_EDGE
+          && aShape2->Shape().ShapeType() == TopAbs_EDGE)
+          aDim = new PrsDim_AngleDimension (TopoDS::Edge(aShape1->Shape()),TopoDS::Edge(aShape2->Shape()));
+        else
+        {
+          std::cerr << theArgs[0] << ": wrong shapes for angle dimension.\n";
+          return 1;
+        }
+      }
+      else if (aShapes.Extent() == 3)
+      {
+        gp_Pnt aP1, aP2, aP3;
+        Handle(AIS_Point) aPoint = Handle(AIS_Point)::DownCast (aShapes.First());
+        if (aPoint.IsNull())
+          return 1;
+        aP1 = aPoint->Component()->Pnt();
+        aShapes.RemoveFirst();
+        aPoint = Handle(AIS_Point)::DownCast (aShapes.First());
+        if (aPoint.IsNull())
+          return 1;
+        aP2 = aPoint->Component()->Pnt();
+        aShapes.RemoveFirst();
+        aPoint = Handle(AIS_Point)::DownCast (aShapes.First());
+        if (aPoint.IsNull())
+          return 1;
+        aP3 = aPoint->Component()->Pnt();
+        aDim = new PrsDim_AngleDimension (aP1, aP2, aP3);
+      }
+      else
+      {
+        std::cerr << theArgs[0] << ": wrong number of shapes to build dimension.\n";
+        return 1;
+      }
+
+      break;
+    }
+    case PrsDim_KOD_RADIUS: // radius of the circle
     {
-      TopoDS_Face FaceB=TopoDS::Face(ShapeB);
-      BRepExtrema_ExtCF myDeltaEdgeFace  (EdgeA,FaceB );
-      // On verifie que l'edge est bien parallele a la face.
-      if (!myDeltaEdgeFace.IsParallel() ) {di<<"vdistdim error: the edge isn't parallel to the face;can't compute the distance. "<<"\n";return 1; }
-
-      // on construit l'AISLenghtDimension.
-      Handle(AIS_LengthDimension ) myLenghtDim=new AIS_LengthDimension (FaceB,EdgeA);
-      TheAISContext()->Display(myLenghtDim );
-      GetMapOfAIS().Bind (myLenghtDim ,argv[1]);
+      gp_Pnt anAnchor;
+      bool hasAnchor = false;
+      for (NCollection_List<Handle(AIS_InteractiveObject)>::Iterator aShapeIter (aShapes); aShapeIter.More(); aShapeIter.Next())
+      {
+        if (Handle(AIS_Point) aPoint = Handle(AIS_Point)::DownCast(aShapeIter.Value()))
+        {
+          hasAnchor = true;
+          anAnchor = aPoint->Component()->Pnt();
+          aShapes.Remove (aShapeIter);
+          break;
+        }
+      }
+      if (aShapes.Extent() != 1)
+      {
+        std::cout << "Syntax error: wrong number of shapes to build dimension.\n";
+        return 1;
+      }
+
+      if (Handle(AIS_Circle) aShapeCirc = Handle(AIS_Circle)::DownCast(aShapes.First()))
+      {
+        gp_Circ aCircle = aShapeCirc->Circle()->Circ();
+        if (hasAnchor)
+        {
+          aDim = new PrsDim_RadiusDimension (aCircle, anAnchor);
+        }
+        else
+        {
+          aDim = new PrsDim_RadiusDimension (aCircle);
+        }
+      }
+      else if (Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(aShapes.First()))
+      {
+        Handle(PrsDim_RadiusDimension) aRadDim = new PrsDim_RadiusDimension (aShape->Shape());
+        if (hasAnchor)
+        {
+          aRadDim->SetMeasuredGeometry (aShape->Shape(), anAnchor);
+        }
+        aDim = aRadDim;
+      }
+      else
+      {
+        std::cout << "Error: shape for radius has wrong type.\n";
+        return 1;
+      }
+      break;
     }
+    case PrsDim_KOD_DIAMETER:
+    {
+      if (aShapes.Extent() == 1)
+      {
+        if (aShapes.First()->DynamicType() == STANDARD_TYPE(AIS_Circle))
+        {
+          Handle(AIS_Circle) aShape = Handle(AIS_Circle)::DownCast (aShapes.First());
+          gp_Circ aCircle = aShape->Circle()->Circ();
+          aDim = new PrsDim_DiameterDimension (aCircle);
+        }
+        else
+        {
+          Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (aShapes.First());
+          if (aShape.IsNull())
+          {
+            std::cerr << "Error: shape for radius is of wrong type.\n";
+            return 1;
+          }
+          aDim = new PrsDim_DiameterDimension (aShape->Shape());
+        }
+      }
+      else
+      {
+        std::cerr << theArgs[0] << ": wrong number of shapes to build dimension.\n";
+        return 1;
+      }
+
+      break;
+    }
+    default:
+    {
+      std::cerr << theArgs[0] << ": wrong type of dimension. Type help for more information.\n";
+      return 1;
+    }
+  }
+
+  // Check dimension geometry
+  if (!aDim->IsValid())
+  {
+    std::cerr << theArgs[0] << ":dimension geometry is invalid, " << aDimType.ToCString()
+      << " dimension can't be built on input shapes.\n";
+    return 1;
+  }
+
+  aDim->SetDimensionAspect (anAspect);
+
+  SetDimensionParams (aDim, aRealParams, aStringParams);
+
+  VDisplayAISObject (aName,aDim);
+
+  return 0;
+}
+
+namespace
+{
+  //! If the given shapes are edges then check whether they are parallel else return true.
+  Standard_Boolean IsParallel (const TopoDS_Shape& theShape1,
+                               const TopoDS_Shape& theShape2)
+  {
+    if (theShape1.ShapeType() == TopAbs_EDGE
+     && theShape2.ShapeType() == TopAbs_EDGE)
+    {
+      BRepExtrema_ExtCC aDelta (TopoDS::Edge (theShape1),
+                                TopoDS::Edge (theShape2));
+      return aDelta.IsParallel();
+    }
+
+    return Standard_True;
+  }
+}
+//=======================================================================
+//function : VRelationBuilder
+//purpose  : Command for building realation presentation
+//=======================================================================
+static int VRelationBuilder (Draw_Interpretor& /*theDi*/,
+                             Standard_Integer  theArgsNb,
+                             const char**      theArgs)
+{
+  if (theArgsNb < 2)
+  {
+    std::cerr << "Error: wrong number of arguments.\n";
+    return 1;
+  }
+
+  TCollection_AsciiString aName (theArgs[1]);
+  TCollection_AsciiString aType (theArgs[2]);
+
+  PrsDim_KindOfRelation aKindOfRelation = PrsDim_KOR_NONE;
+  if (aType == "-concentric")
+  {
+    aKindOfRelation = PrsDim_KOR_CONCENTRIC;
+  }
+  else if (aType == "-equaldistance")
+  {
+    aKindOfRelation = PrsDim_KOR_EQUALDISTANCE;
   }
+  else if (aType == "-equalradius")
+  {
+    aKindOfRelation = PrsDim_KOR_EQUALRADIUS;
+  }
+  else if (aType == "-fix")
+  {
+    aKindOfRelation = PrsDim_KOR_FIX;
+  }
+  else if (aType == "-identic")
+  {
+    aKindOfRelation = PrsDim_KOR_IDENTIC;
+  }
+  else if (aType == "-offset")
+  {
+    aKindOfRelation = PrsDim_KOR_OFFSET;
+  }
+  else if (aType == "-parallel")
+  {
+    aKindOfRelation = PrsDim_KOR_PARALLEL;
+  }
+  else if (aType == "-perpendicular")
+  {
+    aKindOfRelation = PrsDim_KOR_PERPENDICULAR;
+  }
+  else if (aType == "-tangent")
+  {
+    aKindOfRelation = PrsDim_KOR_TANGENT;
+  }
+  else if (aType == "-symmetric")
+  {
+    aKindOfRelation = PrsDim_KOR_SYMMETRIC;
+  }
+
+  TopTools_ListOfShape aShapes;
+  ViewerTest::GetSelectedShapes (aShapes);
+
+  // Build relation.
+  Handle(PrsDim_Relation) aRelation;
+  switch (aKindOfRelation)
+  {
+    case PrsDim_KOR_CONCENTRIC:
+    {
+      if (aShapes.Extent() != 2)
+      {
+        std::cerr << "Error: Wrong number of selected shapes.\n";
+        return 1;
+      }
+
+      const TopoDS_Shape& aShape1 = aShapes.First();
+      const TopoDS_Shape& aShape2 = aShapes.Last();
+
+      if (!(aShape1.ShapeType() == TopAbs_EDGE
+         && aShape2.ShapeType() == TopAbs_EDGE))
+      {
+        std::cerr << "Syntax error: selected shapes are not edges.\n";
+        return 1;
+      }
+
+      BRepAdaptor_Curve aCurve1 (TopoDS::Edge (aShape1));
+      gp_Circ           aCircle1 = aCurve1.Circle();
+      gp_Pnt            aCenter1 = aCircle1.Location();
+      gp_Pnt            B = aCurve1.Value (0.25);
+      gp_Pnt            C = aCurve1.Value (0.75);
+      GC_MakePlane      aMkPlane (aCenter1, B, C);
+
+      aRelation = new PrsDim_ConcentricRelation (aShape1, aShape2, aMkPlane.Value());
+
+      break;
+    }
+    case PrsDim_KOR_EQUALDISTANCE:
+    {
+      if (aShapes.Extent() != 4)
+      {
+        std::cerr << "Error: Wrong number of selected shapes.\n";
+        return 1;
+      }
+
+      TopoDS_Shape aSelectedShapes[4];
+
+      Standard_Integer anIdx = 0;
+      TopTools_ListOfShape::Iterator anIter (aShapes);
+      for (; anIter.More(); anIter.Next(), ++anIdx)
+      {
+        aSelectedShapes[anIdx] = anIter.Value();
+      }
+
+      if (!IsParallel (aSelectedShapes[0], aSelectedShapes[1])
+       || !IsParallel (aSelectedShapes[2], aSelectedShapes[3]))
+      {
+        std::cerr << "Syntax error: non parallel edges.\n";
+        return 1;
+      }
+
+      gp_Pnt A, B, C;
+      if (aSelectedShapes[0].ShapeType() == TopAbs_EDGE)
+      {
+        TopoDS_Vertex Va, Vb;
+        TopExp::Vertices (TopoDS::Edge (aSelectedShapes[0]), Va, Vb);
+        A = BRep_Tool::Pnt (Va);
+        B = BRep_Tool::Pnt (Vb);
+
+        if (aSelectedShapes[1].ShapeType() == TopAbs_EDGE)
+        {
+          TopoDS_Vertex Vc, Vd;
+          TopExp::Vertices (TopoDS::Edge (aSelectedShapes[1]), Vc, Vd);
+          C = BRep_Tool::Pnt (Vc);
+        }
+        else
+        {
+          C = BRep_Tool::Pnt (TopoDS::Vertex (aSelectedShapes[1]));
+        }
+      }
+      else
+      {
+        A = BRep_Tool::Pnt (TopoDS::Vertex (aSelectedShapes[0]));
+
+        if (aSelectedShapes[1].ShapeType() == TopAbs_EDGE)
+        {
+          TopoDS_Vertex Vb, Vc;
+          TopExp::Vertices (TopoDS::Edge (aSelectedShapes[1]), Vb, Vc);
+          B = BRep_Tool::Pnt (Vb);
+          C = BRep_Tool::Pnt (Vc);
+
+        }
+        else
+        {
+          B = BRep_Tool::Pnt (TopoDS::Vertex (aSelectedShapes[1]));
+          C.SetX (B.X() + 5.0);
+          C.SetY (B.Y() + 5.0);
+          C.SetZ (B.Z() + 5.0);
+
+        }
+      }
+
+      GC_MakePlane aMkPlane (A, B, C);
+      aRelation = new PrsDim_EqualDistanceRelation (aSelectedShapes[0], aSelectedShapes[1], aSelectedShapes[2], aSelectedShapes[3], aMkPlane.Value());
+
+      break;
+    }
+    case PrsDim_KOR_EQUALRADIUS:
+    {
+      if (aShapes.Extent() != 2 && aShapes.Extent() != 1)
+      {
+        std::cerr << "Error: Wrong number of selected shapes.\n";
+        return 1;
+      }
+
+      const TopoDS_Shape& aShape1 = aShapes.First();
+      const TopoDS_Shape& aShape2 = (aShapes.Extent() == 2) ? aShapes.Last() : aShape1;
+      if (!(aShape1.ShapeType() == TopAbs_EDGE
+         && aShape2.ShapeType() == TopAbs_EDGE))
+      {
+        std::cerr << "Syntax error: selected shapes are not edges.\n";
+        return 1;
+      }
+
+      TopoDS_Edge       anEdge1 = TopoDS::Edge (aShape1);
+      TopoDS_Edge       anEdge2 = TopoDS::Edge (aShape2);
+      BRepAdaptor_Curve aCurve1 (anEdge1);
+      gp_Pnt            A = aCurve1.Value (0.1);
+      gp_Pnt            B = aCurve1.Value (0.5);
+      gp_Pnt            C = aCurve1.Value (0.9);
+      GC_MakePlane      aMkPlane (A, B, C);
+
+      aRelation = new PrsDim_EqualRadiusRelation (anEdge1, anEdge2, aMkPlane.Value());
+      break;
+    }
+    case PrsDim_KOR_FIX:
+    {
+      if (aShapes.Extent() != 1)
+      {
+        std::cerr << "Error: Wrong number of selected shapes.\n";
+        return 1;
+      }
+
+      const TopoDS_Shape& aShape = aShapes.First();
+      if (aShape.ShapeType() != TopAbs_EDGE)
+      {
+        std::cerr << "Syntax error: selected shapes are not edges.\n";
+        return 1;
+      }
+
+      TopoDS_Edge anEdge = TopoDS::Edge (aShape);
+      BRepAdaptor_Curve aCurve (anEdge);
+      gp_Pnt A = aCurve.Value(0.1);
+      gp_Pnt B = aCurve.Value(0.5);
+      gp_Pnt D = aCurve.Value(0.9);
+      gp_Pnt C (B.X() + 5.0, B.Y() + 5.0, B.Z() + 5.0);
+      GC_MakePlane aMkPlane (A, D, C);
+
+      aRelation = new PrsDim_FixRelation (anEdge, aMkPlane.Value());
+      break;
+    }
+    case PrsDim_KOR_IDENTIC:
+    {
+      if (aShapes.Extent() != 2)
+      {
+        std::cerr << "Error: Wrong number of selected shapes.\n";
+        return 1;
+      }
+
+      const TopoDS_Shape& aShapeA = aShapes.First();
+      const TopoDS_Shape& aShapeB = aShapes.Last();
+
+      gp_Pnt A,B,C;
+      if (aShapeA.ShapeType() == TopAbs_EDGE)
+      {
+        TopoDS_Edge anEdgeA = TopoDS::Edge (aShapeA);
+        BRepAdaptor_Curve aCurveA (anEdgeA);
+
+        A = aCurveA.Value (0.1);
+        B = aCurveA.Value (0.9);
+        C.SetX (B.X() + 5.0);
+        C.SetY (B.Y() + 5.0);
+        C.SetZ (B.Z() + 5.0);
+      }
+      else if (aShapeA.ShapeType() == TopAbs_VERTEX)
+      {
+        if (aShapeB.ShapeType() == TopAbs_EDGE)
+        {
+          TopoDS_Edge anEdgeB = TopoDS::Edge (aShapeB);
+          BRepAdaptor_Curve aCurveB (anEdgeB);
+
+          A = aCurveB.Value (0.1);
+          B = aCurveB.Value (0.9);
+          C.SetX (B.X() + 5.0);
+          C.SetY (B.Y() + 5.0);
+          C.SetZ (B.Z() + 5.0);
+        }
+        else if (aShapeB.ShapeType() == TopAbs_FACE)
+        {
+          TopoDS_Face aFaceB = TopoDS::Face (aShapeB);
+          TopExp_Explorer aFaceExp (aFaceB, TopAbs_EDGE);
+          TopoDS_Edge anEdgeFromB = TopoDS::Edge (aFaceExp.Current());
+          BRepAdaptor_Curve aCurveB (anEdgeFromB);
+          A = aCurveB.Value (0.1);
+          B = aCurveB.Value (0.5);
+          C = aCurveB.Value (0.9);
+        }
+        else
+        {
+          A = BRep_Tool::Pnt (TopoDS::Vertex (aShapeA));
+          B = BRep_Tool::Pnt (TopoDS::Vertex (aShapeB));
+          C.SetX (B.X() + 5.0);
+          C.SetY (B.Y() + 5.0);
+          C.SetZ (B.Z() + 5.0);
+        }
+      }
+      else
+      {
+        TopoDS_Face aFaceA = TopoDS::Face (aShapeA);
+        TopExp_Explorer aFaceExp (aFaceA, TopAbs_EDGE);
+        TopoDS_Edge anEdgeFromA = TopoDS::Edge (aFaceExp.Current());
+        BRepAdaptor_Curve aCurveA (anEdgeFromA);
+        A = aCurveA.Value (0.1);
+        B = aCurveA.Value (0.5);
+        C = aCurveA.Value (0.9);
+      }
 
-  // ShapeA est un vertex
-  // ====================
-  if (ShapeA.ShapeType()==TopAbs_VERTEX ) {
-    TopoDS_Vertex  VertexA=TopoDS::Vertex(ShapeA);
-    
-    // Si ShapeB est un edge.
-    if (ShapeB.ShapeType()==TopAbs_EDGE ) {
-      TopoDS_Edge  EdgeB=TopoDS::Edge(ShapeB);
-      BRepExtrema_ExtPC myDeltaEdgeVertex  (VertexA ,EdgeB );
-      // On saisit la distance et on l'arrondit!
-      theDist=Round (sqrt (myDeltaEdgeVertex.SquareDistance(1))*10. )/10.;
-      
-      // On recupere 2 Points de EdgeB pour construire un plane.
-      TopoDS_Vertex  Va,Vb;
-      TopExp::Vertices(EdgeB,Va,Vb);
-      gp_Pnt A=BRep_Tool::Pnt(Va);
-      gp_Pnt B=BRep_Tool::Pnt(Vb);
-      gp_Pnt C=BRep_Tool::Pnt(VertexA);
-      
-      // Creation du Plane contenant la relation.
-      GC_MakePlane MkPlane(A,B,C);
-      Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
-      
-      // Fermeture du contexte local.
-      TheAISContext()->CloseLocalContext(myCurrentIndex);
-      // Construction du texte.
-      TCollection_ExtendedString TheMessage_Str(TCollection_ExtendedString("d=")+TCollection_ExtendedString(theDist ) );
-      
-      // on construit l'AISLenghtDimension.
-      Handle(AIS_LengthDimension ) myLenghtDim=new AIS_LengthDimension (EdgeB,VertexA,theGeomPlane->Pln());
-      TheAISContext()->Display(myLenghtDim );
-      GetMapOfAIS().Bind (myLenghtDim ,argv[1]);
-      
+      GC_MakePlane aMkPlane (A ,B ,C);
+      aRelation = new PrsDim_IdenticRelation (aShapeA, aShapeB, aMkPlane.Value());
+      break;
     }
-    
-    // Si ShapeB est un vertex.
-    else if (ShapeB.ShapeType()==TopAbs_VERTEX ) {
-      TopoDS_Vertex  VertexB=TopoDS::Vertex(ShapeB);
-      BRepExtrema_DistShapeShape myDeltaVertexVertex  (VertexA ,VertexB );
-      // On saisit la distance et on l'arrondit!
-      theDist=Round (myDeltaVertexVertex.Value()*10. )/10.;
-      
-      // Les deux premiers points.
-      gp_Pnt A=BRep_Tool::Pnt(VertexA);
-      gp_Pnt B=BRep_Tool::Pnt(VertexB);
-      gp_Pnt C(B.X()+10,B.Y()+10,B.Z()+10);
+    case PrsDim_KOR_OFFSET:
+    {
+      if (aShapes.Extent() != 2)
+      {
+        std::cerr << "Error: Wrong number of selected shapes.\n";
+        return 1;
+      }
 
-      GC_MakePlane MkPlane(A,B,C);
-      Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
-      
-      // Fermeture du contexte local.
-      TheAISContext()->CloseLocalContext(myCurrentIndex);
-      // Construction du texte.
-      TCollection_ExtendedString TheMessage_Str(TCollection_ExtendedString("d=")+TCollection_ExtendedString(theDist ) );
-      
-      // on construit l'AISLenghtDimension.
-      Handle(AIS_LengthDimension ) myLenghtDim=new AIS_LengthDimension (VertexA,VertexB,theGeomPlane->Pln());
-      TheAISContext()->Display(myLenghtDim );
-      GetMapOfAIS().Bind (myLenghtDim ,argv[1]);
-      
-      
-      
-      
-    }
-    
-    // Si ShapeB est une Face
-    else {
-      
-      TopoDS_Face  FaceB=TopoDS::Face(ShapeB);
-      BRepExtrema_ExtPF myDeltaVertexFace  (VertexA ,FaceB );
-      // On saisit la distance et on l'arrondit!
-      theDist=Round (sqrt (myDeltaVertexFace.SquareDistance(1))*10. )/10.;
-      
-      // Premier point.
-      gp_Pnt A=BRep_Tool::Pnt(VertexA);
-      
-      // On recupere 1 edge de FaceB.
-      TopExp_Explorer FaceExp(FaceB,TopAbs_EDGE);
-      TopoDS_Edge EdFromB=TopoDS::Edge(FaceExp.Current() );
-      // On recupere les deux vertexes extremites de l'edge de face B
-      TopoDS_Vertex  Vb,Vc;
-      TopExp::Vertices(EdFromB,Vb,Vc);
-#ifdef DEB
-      gp_Pnt B=
-#endif
-               BRep_Tool::Pnt(Vb);
-      gp_Pnt C=BRep_Tool::Pnt(Vc);
-      
-      // On projette le point B sur la Face car il 
-      // n'existe pas de constructeurs AIS_LD PointFace
-      // on est donc oblige de creer un nouveau TopoDS_Vertex.
-      gp_Pnt theProjA=myDeltaVertexFace.Point(1);
-      BRepBuilderAPI_MakeVertex theVertexMaker(theProjA);
-      TopoDS_Vertex VertexAproj=theVertexMaker.Vertex();
-      // Creation du Plane contenant la relation.
-      GC_MakePlane MkPlane(A,theProjA,C);
-      Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
-      
-      // Fermeture du contexte local.
-      TheAISContext()->CloseLocalContext(myCurrentIndex);
-      // Construction du texte.
-      TCollection_ExtendedString TheMessage_Str(TCollection_ExtendedString("d=")+TCollection_ExtendedString(theDist ) );
-      
-      // on construit l'AISLenghtDimension.
-      Handle(AIS_LengthDimension ) myLenghtDim=new AIS_LengthDimension (VertexA,VertexAproj,theGeomPlane->Pln());
-      TheAISContext()->Display(myLenghtDim );
-      GetMapOfAIS().Bind (myLenghtDim ,argv[1]);
-      
-    }
-    
-    
-    
-  }
-  
-  // ShapeA est une Face
-  // ===================
-  else {
-    TopoDS_Face  FaceA=TopoDS::Face(ShapeA);
-    // Si ShapeB est un edge.
-    if (ShapeB.ShapeType()==TopAbs_EDGE ) {
-      TopoDS_Edge EdgeB=TopoDS::Edge(ShapeB);
-      BRepExtrema_ExtCF myDeltaEdgeFace  (EdgeB,FaceA );
-      // On verifie que l'edge est bien parallele a la face.
-      if (!myDeltaEdgeFace.IsParallel() ) {di<<"vdistdim error: the edge isn't parallel to the face;can't compute the distance. "<<"\n";return 1; }
-      
-      // On saisit la distance et on l'arrondit!
-      theDist=Round (sqrt (myDeltaEdgeFace.SquareDistance(1))*10. )/10.;
-      
-      // Construction du texte.
-      TCollection_ExtendedString TheMessage_Str(TCollection_ExtendedString("d=")+TCollection_ExtendedString(theDist ) );
-      
-      // on construit l'AISLenghtDimension.
-      Handle(AIS_LengthDimension ) myLenghtDim=new AIS_LengthDimension (FaceA,EdgeB);
-      TheAISContext()->Display(myLenghtDim );
-      GetMapOfAIS().Bind (myLenghtDim ,argv[1]);
-      
-    }
-    
-    // Si ShapeB est un vertex.
-    else if (ShapeB.ShapeType()==TopAbs_VERTEX ) {
-      
-      TopoDS_Vertex  VertexB=TopoDS::Vertex(ShapeB);
-      BRepExtrema_ExtPF myDeltaVertexFace  (VertexB ,FaceA );
-      // On saisit la distance et on l'arrondit!
-      theDist=Round (sqrt (myDeltaVertexFace.SquareDistance(1))*10. )/10.;
-      
-      // Premier point.
-      gp_Pnt B=BRep_Tool::Pnt(VertexB);
-      
-      // On recupere 1 edge de FaceA.
-      TopExp_Explorer FaceExp(FaceA,TopAbs_EDGE);
-      TopoDS_Edge EdFromA=TopoDS::Edge(FaceExp.Current() );
-      // On recupere les deux vertexes extremites de l'edge de face A
-      TopoDS_Vertex  Va,Vc;
-      TopExp::Vertices(EdFromA,Va,Vc);
-      gp_Pnt A=BRep_Tool::Pnt(Va);
-#ifdef DEB
-      gp_Pnt C=
-#endif
-               BRep_Tool::Pnt(Vc);
-
-      // On projette le point B sur la Face car il 
-      // n'existe pas de constructeurs AIS_LD PointFace
-      // on est donc oblige de creer un nouveau TopoDS_Vertex.
-      gp_Pnt theProjB=myDeltaVertexFace.Point(1);
-      BRepBuilderAPI_MakeVertex theVertexMaker(theProjB);
-      TopoDS_Vertex VertexBproj=theVertexMaker.Vertex();
-      // Creation du Plane contenant la relation.
-      GC_MakePlane MkPlane(A,B,theProjB);
-      Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
-      
-      // Fermeture du contexte local.
-      TheAISContext()->CloseLocalContext(myCurrentIndex);
-      // Construction du texte.
-      TCollection_ExtendedString TheMessage_Str(TCollection_ExtendedString("d=")+TCollection_ExtendedString(theDist ) );
-      
-      // on construit l'AISLenghtDimension mais en utilisant le constructeur Vertex Vertex.
-      Handle(AIS_LengthDimension ) myLenghtDim=new AIS_LengthDimension (VertexB,VertexBproj,theGeomPlane->Pln());
-      TheAISContext()->Display(myLenghtDim );
-      GetMapOfAIS().Bind (myLenghtDim ,argv[1]);
-      
+      const TopoDS_Shape& aShape1 = aShapes.First();
+      const TopoDS_Shape& aShape2 = aShapes.Last();
+      if (!(aShape1.ShapeType() == TopAbs_FACE
+         && aShape2.ShapeType() == TopAbs_FACE))
+      {
+        std::cerr << "Syntax error: selected shapes are not faces.\n";
+        return 1;
+      }
+
+      TopoDS_Face aFace1 = TopoDS::Face (aShape1);
+      TopoDS_Face aFace2 = TopoDS::Face (aShape2);
+
+      BRepExtrema_ExtFF aDelta (aFace1, aFace2);
+      if (!aDelta.IsParallel())
+      {
+        std::cerr << "Syntax error: the faces are not parallel.\n";
+        return 1;
+      }
+
+      Standard_Real aDist = Round (sqrt (aDelta.SquareDistance (1)) * 10.0) / 10.0;
+      TCollection_ExtendedString aMessage (TCollection_ExtendedString ("offset=") + TCollection_ExtendedString (aDist));
+      aRelation = new PrsDim_OffsetDimension (aFace1, aFace2, aDist, aMessage);
+      break;
     }
-    
-    // Si ShapeB est une Face
-    else {
-      
-      TopoDS_Face  FaceB=TopoDS::Face(ShapeB);
-      BRepExtrema_ExtFF myDeltaFaceFace  (FaceA ,FaceB );
-      // On verifie que les deux faces sont bien parelles.
-      if (!myDeltaFaceFace.IsParallel() ) {di<<"vdistdim error: the faces are not parallel. "<<"\n";return 1; }
-      
-      // On saisit la distance et on l'arrondit!
-      theDist=Round (sqrt (myDeltaFaceFace.SquareDistance(1))*10. )/10.;
-      // Fermeture du contexte local.
-      TheAISContext()->CloseLocalContext(myCurrentIndex);
-      // Construction du texte.
-      TCollection_ExtendedString TheMessage_Str(TCollection_ExtendedString("d=")+TCollection_ExtendedString(theDist ) );
-      
-      // on construit l'AISLenghtDimension.
-      Handle(AIS_LengthDimension ) myLenghtDim=new AIS_LengthDimension (FaceA,FaceB);
-      TheAISContext()->Display(myLenghtDim );
-      GetMapOfAIS().Bind (myLenghtDim ,argv[1]);
-      
+    case PrsDim_KOR_PARALLEL:
+    {
+      if (aShapes.Extent() != 2)
+      {
+        std::cerr << "Error: wrong number of selected shapes.\n";
+        return 1;
+      }
+
+      const TopoDS_Shape& aShapeA = aShapes.First();
+      const TopoDS_Shape& aShapeB = aShapes.Last();
+      if (aShapeA.ShapeType() == TopAbs_EDGE)
+      {
+        TopoDS_Edge anEdgeA = TopoDS::Edge (aShapeA);
+        TopoDS_Edge anEdgeB = TopoDS::Edge (aShapeB);
+        BRepExtrema_ExtCC aDeltaEdge (anEdgeA, anEdgeB);
+
+        if (!aDeltaEdge.IsParallel())
+        {
+          std::cerr << "Error: the edges are not parallel.\n";
+          return 1;
+        }
+
+        BRepAdaptor_Curve aCurveA (anEdgeA);
+        BRepAdaptor_Curve aCurveB (anEdgeB);
+
+        gp_Pnt A = aCurveA.Value (0.1);
+        gp_Pnt B = aCurveA.Value (0.9);
+        gp_Pnt C = aCurveB.Value (0.5);
+
+        GC_MakePlane aMkPlane (A, B, C);
+
+        aRelation = new PrsDim_ParallelRelation (anEdgeA, anEdgeB, aMkPlane.Value());
+      }
+      else
+      {
+        TopoDS_Face aFaceA = TopoDS::Face (aShapeA);
+        TopoDS_Face aFaceB = TopoDS::Face (aShapeB);
+
+        BRepExtrema_ExtFF aDeltaFace (aFaceA, aFaceB);
+        if (!aDeltaFace.IsParallel())
+        {
+          std::cerr << "Error: the faces are not parallel.\n";
+          return 1;
+        }
+
+        TopExp_Explorer aFaceExpA (aFaceA, TopAbs_EDGE);
+        TopExp_Explorer aFaceExpB (aFaceB, TopAbs_EDGE);
+
+        TopoDS_Edge anEdgeA = TopoDS::Edge (aFaceExpA.Current());
+        TopoDS_Edge anEdgeB = TopoDS::Edge (aFaceExpB.Current());
+
+        BRepAdaptor_Curve aCurveA (anEdgeA);
+        BRepAdaptor_Curve aCurveB (anEdgeB);
+        gp_Pnt A = aCurveA.Value (0.1);
+        gp_Pnt B = aCurveA.Value (0.9);
+        gp_Pnt C = aCurveB.Value (0.5);
+
+        GC_MakePlane aMkPlane (A, B, C);
+
+        aRelation = new PrsDim_ParallelRelation (aFaceA, aFaceB, aMkPlane.Value());
+      }
+      break;
     }
-    
-  }
-  
-  
-  
-  return 0;
-  
-}
+    case PrsDim_KOR_PERPENDICULAR:
+    {
+      if (aShapes.Extent() != 2)
+      {
+        std::cerr << "Error: Wrong number of selected shapes.\n";
+        return 1;
+      }
 
+      const TopoDS_Shape& aShapeA = aShapes.First();
+      const TopoDS_Shape& aShapeB = aShapes.Last();
 
-//==============================================================================
-//function : VRadiusDim
-//purpose  : Display the radius dimension of a face or an edge.
-//Draw arg : vradiusdim Name 
-//==============================================================================
-#include <AIS_RadiusDimension.hxx>
-#include <TCollection_ExtendedString.hxx>
-#include <BRepAdaptor_Curve.hxx>
-#include <gp_Circ.hxx>
+      if (aShapeA.ShapeType() == TopAbs_EDGE)
+      {
+        TopoDS_Edge anEdgeA = TopoDS::Edge (aShapeA);
+        TopoDS_Edge anEdgeB = TopoDS::Edge (aShapeB);
 
+        BRepAdaptor_Curve aCurveA (anEdgeA);
+        BRepAdaptor_Curve aCurveB (anEdgeB);
 
-static int VRadiusDimBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
-{
-  // Declarations
-  Standard_Integer myCurrentIndex;
-  Standard_Real theRadius;
-    
-  // Verification
-  if (argc!=2) {di<<" vradiusdim error"<<"\n";return 1;}
-  
-  // Fermeture des contextes locaux
-  TheAISContext()->CloseAllContexts();
-  
-  // Ouverture d'un contexte local et recuperation de son index.
-  TheAISContext()->OpenLocalContext();
-  myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
-  
-  // On active les modes de selections Edges et Faces.
-  TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
-  TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4) );
-  di<<" Select an circled edge or face."<<"\n";
-  
-  // Boucle d'attente waitpick.
-  Standard_Integer argcc = 5;
-  const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-  const char **argvv = (const char **) buff;
-  while (ViewerMainLoop( argcc, argvv) ) { }
-  // fin de la boucle
-  
-  TopoDS_Shape ShapeA;
-  for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-    ShapeA = TheAISContext()->SelectedShape();
-  }
-  
-  // Shape A est un edge.
-  if (ShapeA.ShapeType()==TopAbs_EDGE  ) {
-    
-    TopoDS_Edge  EdgeA=TopoDS::Edge(ShapeA);
-    // Recuperation du rayon
-    BRepAdaptor_Curve theCurve(TopoDS::Edge(ShapeA));
-    if (theCurve.GetType()!=GeomAbs_Circle ) {di<<"vradiusdim error: the edge is not a circular one."<<"\n";return 1;}
-    else {
-      gp_Circ theGpCircle=theCurve.Circle();
-      theRadius=theGpCircle.Radius();
-      // On arrondit le rayon
-      theRadius=Round (theRadius*10. )/10.;
+        gp_Pnt A = aCurveA.Value (0.1);
+        gp_Pnt B = aCurveA.Value (0.9);
+        gp_Pnt C = aCurveB.Value (0.5);
+
+        GC_MakePlane aMkPlane (A, B, C);
+
+        aRelation = new PrsDim_PerpendicularRelation (anEdgeA, anEdgeB, aMkPlane.Value());
+      }
+      else
+      {
+        TopoDS_Face aFaceA = TopoDS::Face (aShapeA);
+        TopoDS_Face aFaceB = TopoDS::Face (aShapeB);
+
+        TopExp_Explorer aFaceExpA (aFaceA, TopAbs_EDGE);
+        TopExp_Explorer aFaceExpB (aFaceB, TopAbs_EDGE);
+
+        TopoDS_Edge anEdgeA = TopoDS::Edge (aFaceExpA.Current());
+        TopoDS_Edge anEdgeB = TopoDS::Edge (aFaceExpB.Current());
+
+        BRepAdaptor_Curve aCurveA (anEdgeA);
+        BRepAdaptor_Curve aCurveB (anEdgeB);
+
+        gp_Pnt A = aCurveA.Value (0.1);
+        gp_Pnt B = aCurveA.Value (0.9);
+        gp_Pnt C = aCurveB.Value (0.5);
+
+        GC_MakePlane aMkPlane (A, B, C);
+
+        aRelation = new PrsDim_PerpendicularRelation (aFaceA, aFaceB);
+      }
+
+      break;
     }
+    case PrsDim_KOR_TANGENT:
+    {
+      if (aShapes.Extent() != 2)
+      {
+        std::cerr << "Error: Wrong number of selected shapes.\n";
+        return 1;
+      }
+
+      const TopoDS_Shape& aShapeA = aShapes.First();
+      const TopoDS_Shape& aShapeB = aShapes.Last();
+
+      if (aShapeA.ShapeType() == TopAbs_EDGE)
+      {
+        TopoDS_Edge anEdgeA = TopoDS::Edge (aShapeA);
+        TopoDS_Edge anEdgeB = TopoDS::Edge (aShapeB);
+
+        BRepAdaptor_Curve aCurveA (anEdgeA);
+        BRepAdaptor_Curve aCurveB (anEdgeB);
     
-    // Construction du texte.
-    TCollection_ExtendedString TheMessage_Str(TCollection_ExtendedString("r=")+TCollection_ExtendedString(theRadius  ) );
-    
-    // Fermeture du contexte.
-    TheAISContext()->CloseLocalContext(myCurrentIndex);
-    
-    // Construction de L'AIS_RadiusDimension.
-    Handle (AIS_RadiusDimension) myRadDim= new AIS_RadiusDimension(ShapeA);
-    GetMapOfAIS().Bind (myRadDim,argv[1]);
-    TheAISContext()->Display(myRadDim );
-    
-    
-  }
-  
-  // Shape A est une face
-  else if (ShapeA.ShapeType()==TopAbs_FACE ) {
-    
-    // on recupere un edge de la face.
-    TopoDS_Face  FaceA=TopoDS::Face(ShapeA);
-    // on explore.
-    TopExp_Explorer FaceExp(FaceA,TopAbs_EDGE);
-    TopoDS_Edge EdgeFromA=TopoDS::Edge(FaceExp.Current() );
+        gp_Pnt A = aCurveA.Value (0.1);
+        gp_Pnt B = aCurveA.Value (0.9);
+        gp_Pnt C = aCurveB.Value (0.5);
+
+        GC_MakePlane aMkPlane (A,B,C);
+
+        aRelation = new PrsDim_TangentRelation (anEdgeA, anEdgeB, aMkPlane.Value());
+      }
+      else
+      {
+        TopoDS_Face aFaceA = TopoDS::Face (aShapeA);
+        TopoDS_Face aFaceB = TopoDS::Face (aShapeB);
+
+        TopExp_Explorer aFaceExpA (aFaceA, TopAbs_EDGE);
+        TopExp_Explorer aFaceExpB (aFaceB, TopAbs_EDGE);
     
-    // Recuperation du rayon
-    BRepAdaptor_Curve theCurve(EdgeFromA );
-    if (theCurve.GetType()!=GeomAbs_Circle ) {di<<"vradiusdim error: the face is not a circular one."<<"\n";return 1;}
-    else {
-      gp_Circ theGpCircle=theCurve.Circle();
-      theRadius=theGpCircle.Radius();
-      // On arrondit le rayon
-      theRadius=Round (theRadius*10. )/10.;
+        TopoDS_Edge anEdgeA = TopoDS::Edge (aFaceExpA.Current());
+        TopoDS_Edge anEdgeB = TopoDS::Edge (aFaceExpB.Current());
+
+        BRepAdaptor_Curve aCurveA (anEdgeA);
+        BRepAdaptor_Curve aCurveB (anEdgeB);
+
+        gp_Pnt A = aCurveA.Value (0.1);
+        gp_Pnt B = aCurveA.Value (0.9);
+        gp_Pnt C = aCurveB.Value (0.5);
+
+        GC_MakePlane aMkPlane (A,B,C);
+
+        aRelation = new PrsDim_TangentRelation (aFaceA, aFaceB, aMkPlane.Value());
+      }
+      break;
     }
-    
-    // Construction du texte.
-    TCollection_ExtendedString TheMessage_Str(TCollection_ExtendedString("r=")+TCollection_ExtendedString(theRadius  ) );
-    
-    // Fermeture du contexte.
-    TheAISContext()->CloseLocalContext(myCurrentIndex);
-    
-    // Construction de L'AIS_RadiusDimension.
-    Handle (AIS_RadiusDimension) myRadDim= new AIS_RadiusDimension(ShapeA);
-    GetMapOfAIS().Bind (myRadDim,argv[1]);
-    TheAISContext()->Display(myRadDim );
-    
-    
-  }
-  
-  else {
-    di<<" vradiusdim error: the selection of a face or an edge was expected."<<"\n";return 1;
-  }
-  
-  return 0;
-  
-}
+    case PrsDim_KOR_SYMMETRIC:
+    {
+      if (aShapes.Extent() != 3)
+      {
+        std::cerr << "Error: Wrong number of selected shapes.\n";
+        return 1;
+      }
 
+      TopoDS_Shape aSelectedShapes[3];
+      Standard_Integer anIdx = 0;
+      TopTools_ListOfShape::Iterator anIter (aShapes);
+      for (; anIter.More(); anIter.Next(), ++anIdx)
+      {
+        aSelectedShapes[anIdx] = anIter.Value();
+      }
 
+      TopoDS_Edge anEdgeA = TopoDS::Edge (aSelectedShapes[0]);
+      if (aSelectedShapes[1].ShapeType() == TopAbs_EDGE)
+      {
+        // 1 - edge,  2 - edge, 3 - edge.
+        TopoDS_Edge anEdgeB = TopoDS::Edge (aSelectedShapes[1]);
+        TopoDS_Edge anEdgeC = TopoDS::Edge (aSelectedShapes[2]);
 
-//==============================================================================
-//function : VOffsetDim
-//purpose  : Display the offset dimension
-//Draw arg : voffsetdim Name 
-//==============================================================================
-#include <AIS_OffsetDimension.hxx>
-#include <TCollection_ExtendedString.hxx>
-#include <BRepExtrema_ExtFF.hxx>
+        BRepExtrema_ExtCC aDeltaEdgeAB (anEdgeA, anEdgeB);
+        BRepExtrema_ExtCC aDeltaEdgeAC (anEdgeA, anEdgeC);
 
+        if (!aDeltaEdgeAB.IsParallel())
+        {
+          std::cerr << "Syntax error: the edges are not parallel.\n";
+          return 1;
+        }
+        if (!aDeltaEdgeAC.IsParallel())
+        {
+          std::cerr << "Syntax error: the edges are not parallel.\n";
+          return 1;
+        }
 
-static int VOffsetDimBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
-{
-  // Declarations
-  Standard_Integer myCurrentIndex;
-  Standard_Real    theDist;
-  
-  // Verification
-  if (argc!=2) {di<<" voffsetdim error"<<"\n";return 1;}
-  
-  // Fermeture des contextes locaux
-  TheAISContext()->CloseAllContexts();
-  
-  // Ouverture d'un contexte local et recuperation de son index.
-  TheAISContext()->OpenLocalContext();
-  myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
-  
-  // On active les modes de selections Faces.
-  TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4) );
-  di<<" Select a face."<<"\n";
-  
-  // Boucle d'attente waitpick.
-  Standard_Integer argcc = 5;
-  const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-  const char **argvv = (const char **) buff;
-  while (ViewerMainLoop( argcc, argvv) ) { }
-  // fin de la boucle
-  
-  TopoDS_Shape ShapeA;
-  for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-    ShapeA = TheAISContext()->SelectedShape();
-  }
-  
-  di<<" Select a face."<<"\n";
-  // Boucle d'attente waitpick.
-  Standard_Integer argccc = 5;
-  const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-  const char **argvvv = (const char **) bufff;
-  while (ViewerMainLoop( argccc, argvvv) ) { }
-  // fin de la boucle
-  
-  TopoDS_Shape ShapeB;
-  for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-    ShapeB = TheAISContext()->SelectedShape();
-  }
-  
-  
-  // Shape A et B est une face
-  if (ShapeA.ShapeType()==TopAbs_FACE && ShapeB.ShapeType()==TopAbs_FACE ) {
-    
-    TopoDS_Face  FaceA=TopoDS::Face(ShapeA);
-    TopoDS_Face  FaceB=TopoDS::Face(ShapeB);
-    
-    BRepExtrema_ExtFF myDeltaFaceFace  (FaceA ,FaceB );
-    // On verifie que les deux faces sont bien parelles.
-    if (!myDeltaFaceFace.IsParallel() ) {di<<"vdistdim error: the faces are not parallel. "<<"\n";return 1; }
-    
-    // On saisit la distance et on l'arrondit!
-    theDist=Round (sqrt (myDeltaFaceFace.SquareDistance(1))*10. )/10.;
-    // Fermeture du contexte local.
-    TheAISContext()->CloseLocalContext(myCurrentIndex);
-    // Construction du texte.
-    TCollection_ExtendedString TheMessage_Str(TCollection_ExtendedString("offset=")+TCollection_ExtendedString(theDist ) );
-    
-    // on construit l'AIS_OffsetDimension
-    Handle(AIS_OffsetDimension) myOffsetDim=new AIS_OffsetDimension (FaceA,FaceB,theDist,TheMessage_Str );
-    TheAISContext()->Display(myOffsetDim );
-    GetMapOfAIS().Bind (myOffsetDim ,argv[1]);
-    
-    
-    
-  }
-  
-  else {
-    di<<" voffsetdim error: the selection of a face was expected."<<"\n";return 1;
-  }
-  
-  return 0;
-  
-}
+        TopoDS_Vertex Va, Vb, Vc, Vd;
+        TopExp::Vertices (anEdgeB, Va, Vb);
+        TopExp::Vertices (anEdgeC, Vc, Vd);
+        gp_Pnt A = BRep_Tool::Pnt (Va);
+        gp_Pnt B = BRep_Tool::Pnt (Vc);
+        gp_Pnt C = Get3DPointAtMousePosition();
 
+        GC_MakePlane aMkPlane (A, B, C);
 
+        aRelation = new PrsDim_SymmetricRelation (anEdgeA, anEdgeB, anEdgeC, aMkPlane.Value());
+      }
+      else
+      {
+        // 1 - edge, 2 - vertex, 3 - vertex
+        TopoDS_Vertex aVertexB = TopoDS::Vertex (aSelectedShapes[1]);
+        TopoDS_Vertex aVertexC = TopoDS::Vertex (aSelectedShapes[2]);
 
+        gp_Pnt B = BRep_Tool::Pnt (aVertexB);
+        gp_Pnt C = BRep_Tool::Pnt (aVertexC);
 
-//==============================================================================
-//function : VParallel
-//purpose  : Display the parallel relation 
-//Draw arg : vparallel Name 
-//==============================================================================
-#include <AIS_ParallelRelation.hxx>
-#include <TCollection_ExtendedString.hxx>
-#include <BRepExtrema_ExtFF.hxx>
-#include <BRepExtrema_ExtCC.hxx>
-#include <GC_MakePlane.hxx>
-#include <BRepAdaptor_Curve.hxx>
-#include <TopExp_Explorer.hxx>
+        TopoDS_Vertex Va, Vb;
+        TopExp::Vertices (anEdgeA, Va, Vb);
+        gp_Pnt A = BRep_Tool::Pnt (Va);
 
+        GC_MakePlane aMkPlane(A, B, C);
+        aRelation = new PrsDim_SymmetricRelation (anEdgeA, aVertexB, aVertexC, aMkPlane.Value());
+      }
 
-static int VParallelBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
-{
-  // Declarations
-  Standard_Integer myCurrentIndex;
-  // Verification
-  if (argc!=2) {di<<" vparallel error"<<"\n";return 1;}
-  
-  // Fermeture des contextes locaux
-  TheAISContext()->CloseAllContexts();
-  
-  // Ouverture d'un contexte local et recuperation de son index.
-  TheAISContext()->OpenLocalContext();
-  myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
-  
-  // On active les modes de selections Edges.
-  TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
-  TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4) );
-  di<<" Select an edge or a face "<<"\n";
-  
-  // Boucle d'attente waitpick.
-  Standard_Integer argcc = 5;
-  const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-  const char **argvv = (const char **) buff;
-  while (ViewerMainLoop( argcc, argvv) ) { }
-  // fin de la boucle
-  
-  TopoDS_Shape ShapeA;
-  for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-    ShapeA = TheAISContext()->SelectedShape();
-  }
-  
-  // SahpeA est un edge.
-  // ===================
-  if (ShapeA.ShapeType()==TopAbs_EDGE ) {
-    
-    // desactivation du mode face
-    TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4) );
-    di<<" Select a second edge"<<"\n";
-    // Boucle d'attente waitpick.
-    Standard_Integer argccc = 5;
-    const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-    const char **argvvv = (const char **) bufff;
-    while (ViewerMainLoop( argccc, argvvv) ) { }
-    // fin de la boucle
-    
-    TopoDS_Shape ShapeB;
-    for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-      ShapeB = TheAISContext()->SelectedShape();
+      break;
     }
-    
-    // recuperation des edges.
-    TopoDS_Edge  EdgeA=TopoDS::Edge(ShapeA);
-    TopoDS_Edge  EdgeB=TopoDS::Edge(ShapeB);
-    BRepExtrema_ExtCC myDeltaEdge (EdgeA ,EdgeB );
-    // on verifie qu'ils ne sont pas paralleles.
-    if (!myDeltaEdge.IsParallel() ) {di<<"vparallel error: non parallel edges."<<"\n";return 1; }
-    
-    
-    // On recupere les  vertexes extremites des edge A et B.
-    BRepAdaptor_Curve theCurveA(EdgeA);
-    BRepAdaptor_Curve theCurveB(EdgeB);
-    // On recupere 3 points A,B,C des  curves.
-    gp_Pnt A=theCurveA.Value(0.1);
-    gp_Pnt B=theCurveA.Value(0.9);
-    gp_Pnt C=theCurveB.Value(0.5);
-    
-    // Construction du Geom_Plane
-    GC_MakePlane MkPlane(A,B,C);
-    Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
-    // Fermeture du contexte local.
-    TheAISContext()->CloseLocalContext(myCurrentIndex);
-    // Construction de l'AIS_ParallelRelation
-    Handle(AIS_ParallelRelation) myParaRelation= new AIS_ParallelRelation(EdgeA ,EdgeB ,theGeomPlane );
-    TheAISContext()->Display(myParaRelation );
-    GetMapOfAIS().Bind (myParaRelation ,argv[1]);
-    
-    
-  }
-  
-  // Shape A est une face
-  // ====================
-  else {
-    
-    // desactivation du mode edge
-    TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(2) );
-    di<<" Select a second edge"<<"\n";
-    // Boucle d'attente waitpick.
-    Standard_Integer argccc = 5;
-    const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-    const char **argvvv = (const char **) bufff;
-    while (ViewerMainLoop( argccc, argvvv) ) { }
-    // fin de la boucle
-    
-    TopoDS_Shape ShapeB;
-    for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-      ShapeB = TheAISContext()->SelectedShape();
+    case PrsDim_KOR_NONE:
+    {
+      std::cerr << "Error: Unknown type of relation!\n";
+      return 1;
     }
-    
-    TopoDS_Face  FaceA=TopoDS::Face(ShapeA);
-    TopoDS_Face  FaceB=TopoDS::Face(ShapeB);
-    
-    BRepExtrema_ExtFF myDeltaFaceFace  (FaceA ,FaceB );
-    // On verifie que les deux faces sont bien parelles.
-    if (!myDeltaFaceFace.IsParallel() ) {di<<"vdistdim error: the faces are not parallel. "<<"\n";return 1; }
-    
-    // recuperation des edges des faces.
-    TopExp_Explorer FaceExpA(FaceA,TopAbs_EDGE);
-    TopExp_Explorer FaceExpB(FaceB,TopAbs_EDGE);
-    
-    TopoDS_Edge EdgeA=TopoDS::Edge(FaceExpA.Current() );
-    TopoDS_Edge EdgeB=TopoDS::Edge(FaceExpB.Current() );
-    
-    // On recupere les  vertexes extremites des edge A et B.
-    BRepAdaptor_Curve theCurveA(EdgeA);
-    BRepAdaptor_Curve theCurveB(EdgeB);
-    // On recupere 3 points A,B,C des  curves.
-    gp_Pnt A=theCurveA.Value(0.1);
-    gp_Pnt B=theCurveA.Value(0.9);
-    gp_Pnt C=theCurveB.Value(0.5);
-    
-    // Construction du Geom_Plane
-    GC_MakePlane MkPlane(A,B,C);
-    Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
-    // Fermeture du contexte local.
-    TheAISContext()->CloseLocalContext(myCurrentIndex);
-    // Construction de l'AIS_ParallelRelation
-    Handle(AIS_ParallelRelation) myParaRelation= new AIS_ParallelRelation(FaceA ,FaceB ,theGeomPlane );
-    TheAISContext()->Display(myParaRelation );
-    GetMapOfAIS().Bind (myParaRelation ,argv[1]);
-    
-    
-    
   }
-  
-  
+
+  VDisplayAISObject (aName, aRelation);
   return 0;
-  
 }
 
+//=======================================================================
+//function : VDimParam
+//purpose  : Sets aspect parameters to dimension.
+//=======================================================================
+static int VDimParam (Draw_Interpretor& theDi, Standard_Integer theArgNum, const char** theArgVec)
+{
+  if (theArgNum < 3)
+  {
+    theDi << theArgVec[0] << " error: the wrong number of input parameters.\n";
+    return 1;
+  }
 
 
+  TCollection_AsciiString aName (theArgVec[1]);
+  gp_Pln aWorkingPlane;
+  Standard_Boolean isCustomPlane = Standard_False;
+  Standard_Boolean toUpdate = Standard_True;
 
-//==============================================================================
-//function : VPerpendicularRelation
-//purpose  : Display the Perpendicular Relation
-//Draw arg : vperpendicular Name 
-//==============================================================================
-#include <AIS_PerpendicularRelation.hxx>
-#include <TCollection_ExtendedString.hxx>
-#include <GC_MakePlane.hxx>
-#include <BRepAdaptor_Curve.hxx>
-#include <TopExp_Explorer.hxx>
+  NCollection_DataMap<TCollection_AsciiString, Standard_Real> aRealParams;
+  NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString> aStringParams;
 
+  Handle(AIS_InteractiveObject) anObject;
+  if (!GetMapOfAIS().Find2 (aName, anObject))
+  {
+    theDi << theArgVec[0] << "error: no object with this name.\n";
+    return 1;
+  }
+  Handle(PrsDim_Dimension) aDim = Handle(PrsDim_Dimension)::DownCast (anObject);
+  if (aDim.IsNull())
+  {
+    theDi << theArgVec[0] << "error: no dimension with this name.\n";
+    return 1;
+  }
 
+  Handle(Prs3d_DimensionAspect) anAspect = aDim->DimensionAspect();
 
-static int VPerpendicularBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
-{
-  // Declarations
-  Standard_Integer myCurrentIndex;
-  // Verification
-  if (argc!=2) {di<<" vortho error"<<"\n";return 1;}
-  
-  // Fermeture des contextes locaux
-  TheAISContext()->CloseAllContexts();
-  
-  // Ouverture d'un contexte local et recuperation de son index.
-  TheAISContext()->OpenLocalContext();
-  myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
-  
-  // On active les modes de selections Edges.
-  TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
-  TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4) );
-  di<<" Select an edge or a face "<<"\n";
-  
-  // Boucle d'attente waitpick.
-  Standard_Integer argcc = 5;
-  const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-  const char **argvv = (const char **) buff;
-  while (ViewerMainLoop( argcc, argvv) ) { }
-  // fin de la boucle
-  
-  TopoDS_Shape ShapeA;
-  for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-    ShapeA = TheAISContext()->SelectedShape();
+  if (ParseDimensionParams (theArgNum, theArgVec, 2, anAspect,
+                            isCustomPlane, aWorkingPlane,
+                            aRealParams, aStringParams))
+  {
+    return 1;
   }
-  
-  // ShapeA est un edge.
-  // ===================
-  if (ShapeA.ShapeType()==TopAbs_EDGE ) {
-    
-    // desactivation du mode face
-    TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4) );
-    di<<" Select a second edge"<<"\n";
-    // Boucle d'attente waitpick.
-    Standard_Integer argccc = 5;
-    const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-    const char **argvvv = (const char **) bufff;
-    while (ViewerMainLoop( argccc, argvvv) ) { }
-    // fin de la boucle
-    
-    TopoDS_Shape ShapeB;
-    for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-      ShapeB = TheAISContext()->SelectedShape();
-    }
-    
-    // recuperation des edges.
-    TopoDS_Edge  EdgeA=TopoDS::Edge(ShapeA);
-    TopoDS_Edge  EdgeB=TopoDS::Edge(ShapeB);
-    
-    // On recupere les  curves
-    BRepAdaptor_Curve theCurveA(EdgeA);
-    BRepAdaptor_Curve theCurveB(EdgeB);
-    // on verifie si les edges sont orthogonaux.
-    //gp_Lin theLineA=theCurveA.Line();
-    //gp_Lin theLineB=theCurveB.Line();
-    //if (abs(theLineA.Angle(theLineB) ) != M_PI/2 ) {cout<<"vperpendicular error: Edges are not  othogonals."<<endl;return 1;}
-    
-    // On recupere 3 points A,B,C des  curves.
-    gp_Pnt A=theCurveA.Value(0.1);
-    gp_Pnt B=theCurveA.Value(0.9);
-    gp_Pnt C=theCurveB.Value(0.5);
-    // Construction du Geom_Plane
-    GC_MakePlane MkPlane(A,B,C);
-    Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
-    // Fermeture du contexte local.
-    TheAISContext()->CloseLocalContext(myCurrentIndex);
-    // Construction de l'AIS_ParallelRelation
-    Handle(AIS_PerpendicularRelation) myOrthoRelation= new AIS_PerpendicularRelation (EdgeA ,EdgeB ,theGeomPlane );
-    TheAISContext()->Display(myOrthoRelation );
-    GetMapOfAIS().Bind (myOrthoRelation ,argv[1]);
-    
-    
+
+  if (isCustomPlane)
+  {
+    aDim->SetCustomPlane (aWorkingPlane);
   }
-  
-  // Shape A est une face
-  // ====================
-  else {
-    
-    // desactivation du mode edge
-    TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(2) );
-    di<<" Select a second edge"<<"\n";
-    // Boucle d'attente waitpick.
-    Standard_Integer argccc = 5;
-    const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-    const char **argvvv = (const char **) bufff;
-    while (ViewerMainLoop( argccc, argvvv) ) { }
-    // fin de la boucle
-    
-    TopoDS_Shape ShapeB;
-    for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-      ShapeB = TheAISContext()->SelectedShape();
-    }
-    
-    // pas de verification d'orthogonalite.
-    TopoDS_Face  FaceA=TopoDS::Face(ShapeA);
-    TopoDS_Face  FaceB=TopoDS::Face(ShapeB);
-    
-    // recuperation des edges des faces.
-    TopExp_Explorer FaceExpA(FaceA,TopAbs_EDGE);
-    TopExp_Explorer FaceExpB(FaceB,TopAbs_EDGE);
-    
-    TopoDS_Edge EdgeA=TopoDS::Edge(FaceExpA.Current() );
-    TopoDS_Edge EdgeB=TopoDS::Edge(FaceExpB.Current() );
-    
-    // On recupere les  vertexes extremites des edge A et B.
-    BRepAdaptor_Curve theCurveA(EdgeA);
-    BRepAdaptor_Curve theCurveB(EdgeB);
-    // On recupere 3 points A,B,C des  curves.
-    gp_Pnt A=theCurveA.Value(0.1);
-    gp_Pnt B=theCurveA.Value(0.9);
-    gp_Pnt C=theCurveB.Value(0.5);
-    // Construction du Geom_Plane
-    GC_MakePlane MkPlane(A,B,C);
-    Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
-    // Fermeture du contexte local.
-    TheAISContext()->CloseLocalContext(myCurrentIndex);
-    // Construction de l'AIS_PerpendicularRelation
-    Handle(AIS_PerpendicularRelation) myOrthoRelation= new AIS_PerpendicularRelation(FaceA ,FaceB );
-    TheAISContext()->Display(myOrthoRelation );
-    GetMapOfAIS().Bind (myOrthoRelation  ,argv[1]);
-    
-    
-    
+
+  SetDimensionParams (aDim, aRealParams, aStringParams);
+
+  if (!aDim->IsValid())
+  {
+    std::cerr << "Error: Dimension geometry or plane is not valid.\n";
+    return 1;
   }
-  
-  
+
+  // Redisplay a dimension after parameter changing.
+  if (ViewerTest::GetAISContext()->IsDisplayed (aDim))
+  {
+    ViewerTest::GetAISContext()->Redisplay (aDim, toUpdate);
+  }
+
   return 0;
-  
 }
 
+//=======================================================================
+//function : VLengthParam
+//purpose  : Sets parameters to length dimension.
+//=======================================================================
+static int VLengthParam (Draw_Interpretor&, Standard_Integer theArgNum, const char** theArgVec)
+{
+  if (theArgNum < 3)
+  {
+    std::cout << theArgVec[0] << " error: the wrong number of input parameters.\n";
+    return 1;
+  }
 
-//==============================================================================
-//function : VTangentRelation
-//purpose  : Display the tangent Relation
-//Draw arg : vtangent Name 
-//==============================================================================
-#include <AIS_TangentRelation.hxx>
-
+  TCollection_AsciiString aName (theArgVec[1]);
+  Handle(AIS_InteractiveObject) anObject;
+  if (!GetMapOfAIS().Find2 (aName, anObject))
+  {
+    std::cout << theArgVec[0] << "error: no object with this name.\n";
+    return 1;
+  }
 
-static int VTangentBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
-{
-  // Declarations
-  Standard_Integer myCurrentIndex;
-  // Verification
-  if (argc!=2) {di<<" vtangent error"<<"\n";return 1;}
-  
-  // Fermeture des contextes locaux
-  TheAISContext()->CloseAllContexts();
-  
-  // Ouverture d'un contexte local et recuperation de son index.
-  TheAISContext()->OpenLocalContext();
-  myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
-  
-  // On active les modes de selections Edges.
-  TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
-  TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4) );
-  di<<" Select two coplanar edges(First the circular edge then the tangent edge) or two faces "<<"\n";
-  
-  // Boucle d'attente waitpick.
-  Standard_Integer argcc = 5;
-  const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-  const char **argvv = (const char **) buff;
-  while (ViewerMainLoop( argcc, argvv) ) { }
-  // fin de la boucle
-  
-  TopoDS_Shape ShapeA;
-  for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-    ShapeA = TheAISContext()->SelectedShape();
+  Handle(PrsDim_LengthDimension) aLengthDim = Handle(PrsDim_LengthDimension)::DownCast (anObject);
+  if (aLengthDim.IsNull())
+  {
+    std::cout << theArgVec[0] << "error: no length dimension with this name.\n";
+    return 1;
   }
-  
-  // ShapeA est un edge.
-  // ===================
-  if (ShapeA.ShapeType()==TopAbs_EDGE ) {
-    
-    // desactivation du mode face
-    TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4) );
-    di<<" Select a second edge"<<"\n";
-    // Boucle d'attente waitpick.
-    Standard_Integer argccc = 5;
-    const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-    const char **argvvv = (const char **) bufff;
-    while (ViewerMainLoop( argccc, argvvv) ) { }
-    // fin de la boucle
-    
-    TopoDS_Shape ShapeB;
-    for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-      ShapeB = TheAISContext()->SelectedShape();
+
+  // parse direction value
+  gp_Dir aDirection;
+  int anArgumentIt = 2;
+  TCollection_AsciiString aParam (theArgVec[anArgumentIt]);
+  aParam.LowerCase();
+
+  bool isCustomDirection = false;
+  if (aParam.IsEqual ("-direction"))
+  {
+    if (anArgumentIt + 1 >= theArgNum)
+    {
+      std::cout << "Error: "<< aParam <<" direction should have value.\n";
+      return 1;
     }
-    
-    // recuperation des edges.
-    TopoDS_Edge  EdgeA=TopoDS::Edge(ShapeA);
-    TopoDS_Edge  EdgeB=TopoDS::Edge(ShapeB);
-    
-    // On recupere les  curves
-    BRepAdaptor_Curve theCurveA(EdgeA);
-    BRepAdaptor_Curve theCurveB(EdgeB);
-    
-    // On recupere 3 points A,B,C des  curves.
-    gp_Pnt A=theCurveA.Value(0.1);
-    gp_Pnt B=theCurveA.Value(0.9);
-    gp_Pnt C=theCurveB.Value(0.5);
-
-    // Construction du Geom_Plane
-    GC_MakePlane MkPlane(A,B,C);
-    Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
-    // Fermeture du contexte local.
-    TheAISContext()->CloseLocalContext(myCurrentIndex);
-    // Construction de l'AIS_TangentRelation
-    Handle(AIS_TangentRelation) myTanRelation= new AIS_TangentRelation  (EdgeA ,EdgeB ,theGeomPlane );
-    TheAISContext()->Display(myTanRelation );
-    GetMapOfAIS().Bind (myTanRelation ,argv[1]);
-    
-    
-  }
-  
-  // Shape A est une face
-  // ====================
-  else {
-    
-    // desactivation du mode edge
-    TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(2) );
-    di<<" Select a second edge"<<"\n";
-    // Boucle d'attente waitpick.
-    Standard_Integer argccc = 5;
-    const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-    const char **argvvv = (const char **) bufff;
-    while (ViewerMainLoop( argccc, argvvv) ) { }
-    // fin de la boucle
-    
-    TopoDS_Shape ShapeB;
-    for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-      ShapeB = TheAISContext()->SelectedShape();
+    anArgumentIt++;
+    isCustomDirection = Standard_True;
+    TCollection_AsciiString aValue = theArgVec[anArgumentIt];
+    aValue.LowerCase();
+    if (aValue == "ox")
+      aDirection = gp::DX();
+    else if (aValue == "oy")
+      aDirection = gp::DY();
+    else if (aValue == "oz")
+      aDirection = gp::DZ();
+    else if (aValue == "autodirection")
+      isCustomDirection = false;
+    else
+    {
+      if (anArgumentIt + 2 >= theArgNum)
+      {
+        std::cout << "Error: wrong number of values for parameter '" << aParam << "'.\n";
+        return 1;
+      }
+      // access coordinate arguments
+      TColStd_SequenceOfReal aCoords;
+      for (; anArgumentIt < theArgNum; ++anArgumentIt)
+      {
+        TCollection_AsciiString anArg (theArgVec[anArgumentIt]);
+        if (!anArg.IsRealValue())
+        {
+          break;
+        }
+        aCoords.Append (anArg.RealValue());
+      }
+      // non-numeric argument too early
+      if (aCoords.IsEmpty() || aCoords.Size() != 3)
+      {
+        std::cout << "Error: wrong number of direction arguments.\n";
+        return 1;
+      }
+      aDirection = gp_Dir (aCoords.Value (1), aCoords.Value (2), aCoords.Value (3));
     }
-    
-    TopoDS_Face  FaceA=TopoDS::Face(ShapeA);
-    TopoDS_Face  FaceB=TopoDS::Face(ShapeB);
-    
-    // recuperation des edges des faces.
-    TopExp_Explorer FaceExpA(FaceA,TopAbs_EDGE);
-    TopExp_Explorer FaceExpB(FaceB,TopAbs_EDGE);
-    
-    TopoDS_Edge EdgeA=TopoDS::Edge(FaceExpA.Current() );
-    TopoDS_Edge EdgeB=TopoDS::Edge(FaceExpB.Current() );
-    
-    // On recupere les  vertexes extremites des edge A et B.
-    BRepAdaptor_Curve theCurveA(EdgeA);
-    BRepAdaptor_Curve theCurveB(EdgeB);
-    // On recupere 3 points A,B,C des  curves.
-    gp_Pnt A=theCurveA.Value(0.1);
-    gp_Pnt B=theCurveA.Value(0.9);
-    gp_Pnt C=theCurveB.Value(0.5);
-
-    // Construction du Geom_Plane
-    GC_MakePlane MkPlane(A,B,C);
-    Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
-    // Fermeture du contexte local.
-    TheAISContext()->CloseLocalContext(myCurrentIndex);
-    // Construction de l'AIS_PerpendicularRelation
-    Handle(AIS_TangentRelation) myTanRelation= new AIS_TangentRelation(FaceA ,FaceB,theGeomPlane );
-    TheAISContext()->Display(myTanRelation );
-    GetMapOfAIS().Bind (myTanRelation  ,argv[1]);
-    
-    
-    
   }
-  
-  
+
+  aLengthDim->SetDirection (aDirection, isCustomDirection);
+  if (!aLengthDim->IsValid())
+  {
+    std::cout << "Error: Dimension geometry or plane is not valid.\n";
+    return 1;
+  }
+
+  // Redisplay a dimension after parameter changing.
+  if (ViewerTest::GetAISContext()->IsDisplayed (aLengthDim))
+  {
+    ViewerTest::GetAISContext()->Redisplay (aLengthDim, true);
+  }
+
   return 0;
-  
 }
 
-//==============================================================================
-//function : VSymetricalRelation
-//purpose  : Display the Symetrical Relation
-//Draw arg : vsymetric Name 
-//==============================================================================
-#include <AIS_SymmetricRelation.hxx>
+//=======================================================================
+//function : VAngleParam
+//purpose  : Sets aspect parameters to angle dimension.
+//=======================================================================
+static int VAngleParam (Draw_Interpretor& theDi, Standard_Integer theArgNum, const char** theArgVec)
+{
+  if (theArgNum < 3)
+  {
+    theDi << theArgVec[0] << " error: the wrong number of input parameters.\n";
+    return 1;
+  }
+
 
+  TCollection_AsciiString aName (theArgVec[1]);
+  gp_Pln aWorkingPlane;
+  Standard_Boolean toUpdate = Standard_True;
 
-static int VSymmetricBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
-{
-  // Declarations
-  Standard_Integer myCurrentIndex;
-  // Verification
-  if (argc!=2) {di<<" vSymmetric error"<<"\n";return 1;}
-  
-  // Fermeture des contextes locaux
-  TheAISContext()->CloseAllContexts();
-  
-  // Ouverture d'un contexte local et recuperation de son index.
-  TheAISContext()->OpenLocalContext();
-  myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
-  
-  // On active les modes de selections
-  TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
-  di<<" Select an edge:the axis of symetry "<<"\n";
-  
-  // Boucle d'attente waitpick.
-  Standard_Integer argcc = 5;
-  const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-  const char **argvv = (const char **) buff;
-  while (ViewerMainLoop( argcc, argvv) ) { }
-  // fin de la boucle
-  
-  TopoDS_Shape ShapeA;
-  for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-    ShapeA = TheAISContext()->SelectedShape();
+  NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString> aStringParams;
+  Handle(AIS_InteractiveObject) anObject;
+  if (!GetMapOfAIS().Find2 (aName, anObject))
+  {
+    theDi << theArgVec[0] << "error: no object with this name.\n";
+    return 1;
   }
-  // recuperation des edges.
-  TopoDS_Edge  EdgeA=TopoDS::Edge(ShapeA);
-  
-  // On active les modes de selections
-  TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
-  TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1) );
-  di<<" Select two edges or two vertices. "<<"\n";
-  
-  // Boucle d'attente waitpick.
-  Standard_Integer argcc2 = 5;
-//  const char *buff2[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-  const char **argvv2 = (const char **) buff;
-  while (ViewerMainLoop( argcc2, argvv2) ) { }
-  // fin de la boucle
-  
-  TopoDS_Shape ShapeB;
-  for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-    ShapeB = TheAISContext()->SelectedShape();
+
+  Handle(PrsDim_Dimension) aDim = Handle(PrsDim_Dimension)::DownCast (anObject);
+  if (aDim.IsNull())
+  {
+    theDi << theArgVec[0] << "error: no dimension with this name.\n";
+    return 1;
   }
-  
-  
-  
-  
-  
-  // ShapeB est un edge.
-  // ===================
-  if (ShapeB.ShapeType()==TopAbs_EDGE ) {
-    
-    // desactivation du mode vertex
-    TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(1) );
-    di<<" Select a second edge"<<"\n";
-    // Boucle d'attente waitpick.
-    Standard_Integer argccc = 5;
-    const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-    const char **argvvv = (const char **) bufff;
-    while (ViewerMainLoop( argccc, argvvv) ) { }
-    // fin de la boucle
-    
-    TopoDS_Shape ShapeC;
-    for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-      ShapeC = TheAISContext()->SelectedShape();
-    }
-    
-    // recuperation des edges.
-    TopoDS_Edge  EdgeB=TopoDS::Edge(ShapeB);
-    TopoDS_Edge  EdgeC=TopoDS::Edge(ShapeC);
-    // on verifie que les edges sont paralleles
-    BRepExtrema_ExtCC myDeltaEdgeAB (EdgeA ,EdgeB );
-    BRepExtrema_ExtCC myDeltaEdgeAC (EdgeA ,EdgeC );
-    // on verifie qu'ils  sont paralleles.
-    if (!myDeltaEdgeAB.IsParallel() ) {di<<"vsymetric error: non parallel edges."<<"\n";return 1; }
-    if (!myDeltaEdgeAC.IsParallel() ) {di<<"vsymetric error: non parallel edges."<<"\n";return 1; }
-    // on recupere les vertexs
-    TopoDS_Vertex  Va,Vb,Vc,Vd;
-    TopExp::Vertices(EdgeB,Va,Vb );
-    TopExp::Vertices(EdgeC,Vc,Vd );
-    gp_Pnt A=BRep_Tool::Pnt(Va);
-    gp_Pnt B=BRep_Tool::Pnt(Vc);
-    gp_Pnt C = Get3DPointAtMousePosition();
-    
-    //    gp_Pnt C=BRep_Tool::Pnt(Vc);
-    // Construction du Geom_Plane
-    GC_MakePlane MkPlane(A,B,C);
-    Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
-    // Fermeture du contexte local.
-    TheAISContext()->CloseLocalContext(myCurrentIndex);
-    // Construction de l'AIS_SymmetricRelation
-    Handle(AIS_SymmetricRelation) mySymRelation= new AIS_SymmetricRelation (EdgeA ,EdgeB ,EdgeC, theGeomPlane );
-    TheAISContext()->Display(mySymRelation );
-    GetMapOfAIS().Bind (mySymRelation ,argv[1]);
-    
-    
+
+  Handle(Prs3d_DimensionAspect) anAspect = aDim->DimensionAspect();
+  if (ParseAngleDimensionParams (theArgNum, theArgVec, 2, aStringParams))
+  {
+    return 1;
   }
-  
-  // Shape B est un vertex
-  // =====================
-  else {
-    
-    // desactivation du mode edge
-    TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(2) );
-    di<<" Select a second edge"<<"\n";
-    // Boucle d'attente waitpick.
-    Standard_Integer argccc = 5;
-    const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-    const char **argvvv = (const char **) bufff;
-    while (ViewerMainLoop( argccc, argvvv) ) { }
-    // fin de la boucle
-    
-    TopoDS_Shape ShapeC;
-    for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
-      ShapeC = TheAISContext()->SelectedShape();
-    }
-    
-    // recuperation des Vertex
-    TopoDS_Vertex  VertexB=TopoDS::Vertex(ShapeB);
-    TopoDS_Vertex  VertexC=TopoDS::Vertex(ShapeC);
-    // transfo en gp_Pnt
-    gp_Pnt B=BRep_Tool::Pnt(VertexB);
-    gp_Pnt C=BRep_Tool::Pnt(VertexC);
-    
-    // on recupere les vertexes de l'axe de sym
-    TopoDS_Vertex  Va,Vb;
-    TopExp::Vertices(EdgeA,Va,Vb );
-    gp_Pnt A=BRep_Tool::Pnt(Va);
-    // Construction du Geom_Plane
-    GC_MakePlane MkPlane(A,B,C);
-    Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
-    // Fermeture du contexte local.
-    TheAISContext()->CloseLocalContext(myCurrentIndex);
-    // Construction de l'AIS_SymmetricRelation
-    Handle(AIS_SymmetricRelation) mySymRelation= new AIS_SymmetricRelation (EdgeA ,VertexB ,VertexC, theGeomPlane );
-    TheAISContext()->Display(mySymRelation );
-    GetMapOfAIS().Bind (mySymRelation ,argv[1]);
-    
-    
-    
+
+  SetAngleDimensionParams (aDim, aStringParams);
+
+  if (!aDim->IsValid())
+  {
+    std::cerr << "Error: Dimension geometry or plane is not valid.\n";
+    return 1;
+  }
+
+  // Redisplay a dimension after parameter changing.
+  if (ViewerTest::GetAISContext()->IsDisplayed (aDim))
+  {
+    ViewerTest::GetAISContext()->Redisplay (aDim, toUpdate);
   }
-  
-  
   return 0;
-  
 }
+
 //=======================================================================
 //function : VMoveDim
-//purpose  : 
+//purpose  : Moves dimension or relation text label to defined or picked
+//           position and updates the object.
+//draw args: vmovedim [name] [x y z]
 //=======================================================================
-static int VMoveDim(Draw_Interpretor& di, Standard_Integer argc, const char** argv
+static int VMoveDim (Draw_Interpretor& theDi, Standard_Integer theArgNum, const char** theArgVec
 {
-  if(argc>2) return 1;
-  
-  const Handle(V3d_View) aview = ViewerTest::CurrentView();
-  Handle(AIS_InteractiveObject) pickedobj;
-  if(argc==1){
-    pickedobj = TheAISContext()->FirstCurrentObject();
-    if(pickedobj.IsNull() || pickedobj->Type()!=AIS_KOI_Relation)
-      pickedobj = ViewerTest::PickObject(AIS_KOI_Relation);
+  if (theArgNum > 5)
+  {
+    theDi << theArgVec[0] << " error: the wrong number of parameters.\n";
+    return 1;
   }
-  else{
-    // reperage dans le viewer...
-    if(!strcasecmp(argv[1],".")){
-      pickedobj = ViewerTest::PickObject(AIS_KOI_Relation);
-      
+
+  // Parameters parsing
+  Standard_Boolean isNameSet = (theArgNum ==2 || theArgNum == 5);
+  Standard_Boolean isPointSet = (theArgNum == 4 || theArgNum == 5);
+
+  Handle(AIS_InteractiveObject) aPickedObj;
+  gp_Pnt aPoint (gp::Origin());
+  Standard_Integer aMaxPickNum = 5;
+
+  // Find object
+  if (isNameSet)
+  {
+     TCollection_AsciiString aName (theArgVec[1]);
+     if (!GetMapOfAIS().Find2 (aName, aPickedObj)
+       || aPickedObj.IsNull())
+     {
+       theDi << theArgVec[0] << " error: no object with this name.\n";
+       return 1;
+     }
+
+     if (aPickedObj->Type() != AIS_KOI_Dimension && aPickedObj->Type() != AIS_KOI_Relation)
+     {
+       theDi << theArgVec[0] << " error: no dimension or relation with this name.\n";
+       return 1;
+     }
+  }
+  else // Pick dimension or relation
+  {
+    // Loop that will be handle picking.
+    Standard_Integer anArgNum = 5;
+    const char *aBuffer[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
+    const char **anArgVec = (const char **) aBuffer;
+
+    Standard_Boolean isPicked = Standard_False;
+    Standard_Integer aPickNum = 0;
+    while (!isPicked && aPickNum < aMaxPickNum)
+    {
+      while (ViewerMainLoop (anArgNum, anArgVec)) { }
+
+      for (TheAISContext()->InitSelected(); TheAISContext()->MoreSelected(); TheAISContext()->NextSelected())
+      {
+        aPickedObj = TheAISContext()->SelectedInteractive();
+      }
+
+      isPicked = (!aPickedObj.IsNull() && (aPickedObj->Type() == AIS_KOI_Dimension || aPickedObj->Type() == AIS_KOI_Relation));
+
+      if (isPicked)
+      {
+        break;
+      }
+      aPickNum++;
+    }
+    if (!isPicked)
+    {
+      theDi << theArgVec[0] << ": no dimension or relation is selected.\n";
+      return 1;
     }
-    else if(GetMapOfAIS().IsBound2(argv[1]))
-      pickedobj = Handle(AIS_InteractiveObject)::DownCast
-        (GetMapOfAIS().Find2(argv[1]));
   }
-  
-  if(pickedobj.IsNull()){
-    di<<"Bad Type Object"<<"\n";
-    return 1 ;}
-  
-  if(pickedobj->Type() != AIS_KOI_Relation)
-    return 1;
-  Standard_Integer argccc = 5;
-  
-  const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
-  const char **argvvv = (const char **) bufff;
-
-  Handle(AIS_Relation) R = *((Handle(AIS_Relation)*)&pickedobj);
-  Handle(Geom_Plane) ThePl;
-//  Standard_Real x,y,z,xv,yv,zv;
-  Standard_Real x,y,xv,yv,zv;
-  static Standard_Real last_xv(0),last_yv(0),last_zv(0);
-  Standard_Integer xpix,ypix;
-//  Standard_Boolean SameAsLast(Standard_False);
-  Select3D_Projector prj(aview);
-  
-  
-  while (ViewerMainLoop( argccc, argvvv) ) {
-    //....... la ligne de tir
-    ViewerTest::GetMousePosition(xpix,ypix);
-    aview->Convert(xpix,ypix,x,y); // espace reel 2D de la vue...
-    gp_Lin L = prj.Shoot(x,y);
 
-    
-    
-    // ....... le plan de la vue...
-    aview->Proj(xv,yv,zv);
-    static Standard_Boolean haschanged(Standard_False);
-    if(Abs(last_xv-xv)>Precision::Confusion() ||
-       Abs(last_yv-yv)>Precision::Confusion() ||
-       Abs(last_zv-zv)>Precision::Confusion() ){
-      last_xv = xv;
-      last_yv = yv;
-      last_zv = zv;
-      Standard_Real xat,yat,zat;
-      aview->At(xat,yat,zat);
-      ThePl = new Geom_Plane(gp_Pnt(xat,yat,zat),gp_Dir(xv,yv,zv));
-      haschanged = Standard_True;
-      di <<"changement de plan"<<"\n";
-    }
-    
-    //  
-//    Standard_Integer xpix,ypix;
-//    Standard_Real x,y;
-    gp_Pnt GoodPoint;
-    if(haschanged){
-      gp_Pln NewPlane;;
-      ComputeNewPlaneForDim(R,NewPlane,GoodPoint);
-      haschanged = Standard_False;
+  // Find point
+  if (isPointSet)
+  {
+    aPoint = theArgNum == 4 ? gp_Pnt (atoi (theArgVec[1]), atoi (theArgVec[2]), atoi (theArgVec[3]))
+                            : gp_Pnt (atoi (theArgVec[2]), atoi (theArgVec[3]), atoi (theArgVec[4]));
+  }
+  else // Pick the point
+  {
+    Standard_Integer aPickArgNum = 5;
+    const char *aPickBuff[] = {"VPick", "X", "VPickY", "VPickZ", "VPickShape"};
+    const char **aPickArgVec = (const char **) aPickBuff;
+
+    while (ViewerMainLoop (aPickArgNum, aPickArgVec)) { }
+
+    // Set text position, update relation or dimension.
+    if (aPickedObj->Type() == AIS_KOI_Relation)
+    {
+      Handle(PrsDim_Relation) aRelation = Handle(PrsDim_Relation)::DownCast (aPickedObj);
+      aPoint = Get3DPointAtMousePosition();
+      aRelation->SetPosition (aPoint);
+      TheAISContext()->Redisplay (aRelation, Standard_True);
     }
-    else{
-      if(ComputeIntersection(L,ThePl->Pln(),GoodPoint)){
-       R->SetPosition(GoodPoint);
+    else
+    {
+      Handle(PrsDim_Dimension) aDim = Handle(PrsDim_Dimension)::DownCast (aPickedObj);
+      gp_Pnt aFirstPoint, aSecondPoint;
+      if (aDim->KindOfDimension() == PrsDim_KOD_PLANEANGLE)
+      {
+        Handle(PrsDim_AngleDimension) anAngleDim = Handle(PrsDim_AngleDimension)::DownCast (aDim);
+        aFirstPoint = anAngleDim->FirstPoint();
+        aSecondPoint = anAngleDim->SecondPoint();
+      }
+      else if (aDim->KindOfDimension() == PrsDim_KOD_LENGTH)
+      {
+        Handle(PrsDim_LengthDimension) aLengthDim = Handle(PrsDim_LengthDimension)::DownCast (aDim);
+        aFirstPoint = aLengthDim->FirstPoint();
+        aSecondPoint = aLengthDim->SecondPoint();
       }
-      TheAISContext()->Redisplay(R);
+      else if (aDim->KindOfDimension() == PrsDim_KOD_RADIUS)
+      {
+        Handle(PrsDim_RadiusDimension) aRadiusDim = Handle(PrsDim_RadiusDimension)::DownCast (aDim);
+        aFirstPoint = aRadiusDim->AnchorPoint();
+        aSecondPoint = aRadiusDim->Circle().Location();
+      }
+      else if (aDim->KindOfDimension() == PrsDim_KOD_DIAMETER)
+      {
+        Handle(PrsDim_DiameterDimension) aDiameterDim = Handle(PrsDim_DiameterDimension)::DownCast (aDim);
+        aFirstPoint = aDiameterDim->AnchorPoint();
+        aSecondPoint = aDiameterDim->Circle().Location();
+      }
+
+      if (!Get3DPointAtMousePosition (aFirstPoint, aSecondPoint, aPoint))
+      {
+        return 1;
+      }
+
+      aDim->SetTextPosition (aPoint);
+      TheAISContext()->Redisplay (aDim, Standard_True);
     }
+
   }
-  
+
+  // Set text position, update relation or dimension.
+  if (aPickedObj->Type() == AIS_KOI_Relation)
+  {
+    Handle(PrsDim_Relation) aRelation = Handle(PrsDim_Relation)::DownCast (aPickedObj);
+    aRelation->SetPosition (aPoint);
+    TheAISContext()->Redisplay (aRelation, Standard_True);
+  }
+  else
+  {
+    Handle(PrsDim_Dimension) aDim = Handle(PrsDim_Dimension)::DownCast (aPickedObj);
+    aDim->SetTextPosition (aPoint);
+    TheAISContext()->Redisplay (aDim, Standard_True);
+  }
+
   return 0;
 }
 
@@ -2510,72 +1908,81 @@ void ViewerTest::RelationCommands(Draw_Interpretor& theCommands)
   const char *group = "AISRelations";
 
   theCommands.Add("vdimension",
-      "vdimension {angle|length|radius|diameter} name={Dim_Name} shape1 [shape2 [shape3]]\n"
-      " [text={2d|3d}] [plane={xoy|yoz|zox}]\n"
-      " [label={left|right|hcenter|hfit},{above|below|vcenter}]\n"
-      " [flyout=value] [arrows={external|internal|fit}]\n"
+      "vdimension name {-angle|-length|-radius|-diameter}"
+      "[-shapes shape1 [shape2 [shape3]]\n"
+      "[-selected]\n"
+      "[-text 3d|2d wf|sh|wireframe|shading IntegerSize]\n"
+      "[-font FontName]\n"
+      "[-label left|right|hcenter|hfit top|bottom|vcenter|vfit]\n"
+      "[-arrow external|internal|fit]\n"
+      "[{-arrowlength|-arlen} RealArrowLength]\n"
+      "[{-arrowangle|-arangle} ArrowAngle(degrees)]\n"
+      "[-plane xoy|yoz|zox]\n"
+      "[-flyout FloatValue -extension FloatValue]\n"
+      "[-autovalue]\n"
+      "[-value CustomRealValue]\n"
+      "[-textvalue CustomTextValue]\n"
+      "[-dispunits DisplayUnitsString]\n"
+      "[-modelunits ModelUnitsString]\n"
+      "[-showunits | -hideunits]\n"
       " -Builds angle, length, radius and diameter dimensions.\n"
+      " -See also: vdimparam, vmovedim.\n",
       __FILE__,VDimBuilder,group);
 
-  theCommands.Add("vangledim",
-                 "vangledim Name:Selection in the viewer only ",
-                 __FILE__,VAngleDimBuilder,group);
-  
-  theCommands.Add("vdiameterdim",
-                 "vdiameterdim Name : Selection in the viewer only ",
-                 __FILE__,VDiameterDimBuilder,group);
-  
-  theCommands.Add("vconcentric",
-                 "vconcentric Name : Selection in the viewer only ",
-                 __FILE__,VConcentricBuilder,group);
-
-  theCommands.Add("vequaldist",
-                 "vequaldist Name Selection in the viewer only ",
-                 __FILE__,VEqualDistRelation ,group);
-  
-  theCommands.Add("vequalrad",
-                 "vequalrad Name Selection in the viewer only ",
-                 __FILE__,VEqualRadiusRelation  ,group);
-  
-  theCommands.Add("vfix",  
-                 "vfix Name Selection in the viewer only ",
-                 __FILE__,VFixRelation  ,group);
-  
-  theCommands.Add("videntity",
-                 "videntity Name Selection in the viewer only ",
-                 __FILE__,VIdenticRelation  ,group);
-  
-  theCommands.Add("vdistdim",
-                 "vdistdim Name Selection in the viewer only ",
-                 __FILE__,VLenghtDimension ,group);
-  
-  theCommands.Add("vradiusdim",
-                 "vradiusdim Name Selection in the viewer only ",
-                 __FILE__,VRadiusDimBuilder ,group);
-  
-  theCommands.Add("voffsetdim",
-                 "voffsetdim Name Selection in the viewer only ",
-                 __FILE__,VOffsetDimBuilder ,group);
-  
-  theCommands.Add("vparallel",
-                 "vparallel Name Selection in the viewer only ",
-                 __FILE__,VParallelBuilder ,group);
-  
-  theCommands.Add("vortho",
-                 "vortho Name Selection in the viewer only ",
-                 __FILE__,VPerpendicularBuilder ,group);
-  
-  theCommands.Add("vtangent",  
-                 "vtangent Name Selection in the viewer only ",
-                 __FILE__,VTangentBuilder ,group);
-  
-  
-  theCommands.Add("vsymetric",
-                 "vsymetric Name Selection in the viewer only ",
-                 __FILE__,VSymmetricBuilder ,group);
+  theCommands.Add ("vrelation",
+      "vrelation name {-concentric|-equaldistance|-equalradius|-fix|-identic|-offset|-parallel|-perpendicular|-tangent|-symmetric}"
+      "\n\t\t: concentric - 2 circled edges."
+      "\n\t\t: equaldistance - 4 vertex/edges."
+      "\n\t\t: equalradius - 1 or 2 circled edges."
+      "\n\t\t: fix - 1 edge."
+      "\n\t\t: identic - 2 faces, edges or vertices."
+      "\n\t\t: offset - 2 faces."
+      "\n\t\t: parallel - 2 faces or 2 edges."
+      "\n\t\t: perpendicular - 2 faces or 2 edges."
+      "\n\t\t: tangent - two coplanar edges (first the circular edge then the tangent edge) or two faces."
+      "\n\t\t: symmetric - 3 edges or 1 edge and 2 vertices."
+      "-Builds specific relation from selected objects.",
+      __FILE__, VRelationBuilder, group);
+
+  theCommands.Add("vdimparam",
+    "vdimparam name"
+    "[-text 3d|2d wf|sh|wireframe|shading IntegerSize]\n"
+    "[-font FontName]\n"
+    "[-label left|right|hcenter|hfit top|bottom|vcenter|vfit]\n"
+    "[-arrow external|internal|fit]\n"
+    "[{-arrowlength|-arlen} RealArrowLength]\n"
+    "[{-arrowangle|-arangle} ArrowAngle(degrees)]\n"
+    "[-plane xoy|yoz|zox]\n"
+    "[-flyout FloatValue -extension FloatValue]\n"
+    "[-value CustomNumberValue]\n"
+    "[-textvalue CustomTextValue]\n"
+    "[-dispunits DisplayUnitsString]\n"
+    "[-modelunits ModelUnitsString]\n"
+    "[-showunits | -hideunits]\n"
+    " -Sets parameters for angle, length, radius and diameter dimensions.\n"
+    " -See also: vmovedim, vdimension.\n",
+    __FILE__,VDimParam,group);
+
+  theCommands.Add("vlengthparam",
+    "vlengthparam name"
+    "[-direction {ox|oy|oz|x y z|autodirection}]\n"
+    " -Sets parameters for length dimension.\n"
+    " -See also: vdimparam, vdimension.\n",
+    __FILE__,VLengthParam,group);
+
+  theCommands.Add("vangleparam",
+    "vangleparam name"
+    "[-type interior|exterior]\n"
+    "[-showarrow first|second|both|none]\n"
+    " -Sets parameters for angle dimension.\n"
+    " -See also: vdimparam, vdimension.\n",
+    __FILE__,VAngleParam,group);
 
   theCommands.Add("vmovedim",
-                 "vmovedim [name] : move Mouse in the viewer; click MB1 to stop motion...",
+      "vmovedim : vmovedim [name] [x y z]"
+      "\n\t\t: Moves picked or named (if name defined)"
+      "\n\t\t: dimension to picked mouse position or input point."
+      "\n\t\t: Text label of dimension 'name' is moved to position, another parts of dimensionare adjusted.",
                  __FILE__,VMoveDim,group);
 
 }