0024133: Development of improvement of dimensions implementation; new length, radius...
authoraba <aba@opencascade.com>
Thu, 31 Oct 2013 12:49:38 +0000 (16:49 +0400)
committerbugmaster <bugmaster@opencascade.com>
Thu, 31 Oct 2013 14:02:17 +0000 (18:02 +0400)
Some corrections; test cases were added; coding standards in MFC samples & presentations
Request stencil buffer for Linux.
correct test cases; correct compilation errors
compilation warnings (gcc/Linux)

137 files changed:
samples/mfc/standard/04_Viewer3d/res/AIS_TB.bmp
samples/mfc/standard/04_Viewer3d/src/Viewer3d.rc
samples/mfc/standard/04_Viewer3d/src/Viewer3dDoc.cpp
samples/mfc/standard/05_ImportExport/res/ImportExport.aps
samples/mfc/standard/Common/AngleParamsVerticesPage.cpp [new file with mode: 0644]
samples/mfc/standard/Common/AngleParamsVerticesPage.h [new file with mode: 0644]
samples/mfc/standard/Common/DimensionDlg.cpp [new file with mode: 0644]
samples/mfc/standard/Common/DimensionDlg.h [new file with mode: 0644]
samples/mfc/standard/Common/LengthParamsEdgePage.cpp [new file with mode: 0644]
samples/mfc/standard/Common/LengthParamsEdgePage.h [new file with mode: 0644]
samples/mfc/standard/Common/LengthParamsEdgesPage.cpp [new file with mode: 0644]
samples/mfc/standard/Common/LengthParamsEdgesPage.h [new file with mode: 0644]
samples/mfc/standard/Common/LengthParamsVerticesPage.cpp [new file with mode: 0644]
samples/mfc/standard/Common/LengthParamsVerticesPage.h [new file with mode: 0644]
samples/mfc/standard/Common/OCC_3dBaseDoc.cpp
samples/mfc/standard/Common/OCC_3dBaseDoc.h
samples/mfc/standard/Common/RadiusParamsPage.cpp [new file with mode: 0644]
samples/mfc/standard/Common/RadiusParamsPage.h [new file with mode: 0644]
samples/mfc/standard/Common/res/AIS_TB.bmp
samples/mfc/standard/Common/res/OCC_Resource.aps
samples/mfc/standard/Common/res/OCC_Resource.h
samples/mfc/standard/Common/res/OCC_Resource.rc
samples/mfc/standard/mfcsample/adm/win/vc10/mfcsample.vcxproj
samples/mfc/standard/mfcsample/adm/win/vc10/mfcsample.vcxproj.filters
samples/mfc/standard/mfcsample/adm/win/vc11/mfcsample.vcxproj
samples/mfc/standard/mfcsample/adm/win/vc11/mfcsample.vcxproj.filters
samples/mfc/standard/mfcsample/adm/win/vc8/mfcsample.vcproj
samples/mfc/standard/mfcsample/adm/win/vc9/mfcsample.vcproj
src/AIS/AIS.cdl
src/AIS/AIS.cxx
src/AIS/AIS_AngleDimension.cdl [deleted file]
src/AIS/AIS_AngleDimension.cxx
src/AIS/AIS_AngleDimension.hxx [new file with mode: 0644]
src/AIS/AIS_AngleDimension.lxx [deleted file]
src/AIS/AIS_Chamf2dDimension.cxx
src/AIS/AIS_Chamf3dDimension.cxx
src/AIS/AIS_DiameterDimension.cdl [deleted file]
src/AIS/AIS_DiameterDimension.cxx
src/AIS/AIS_DiameterDimension.hxx [new file with mode: 0644]
src/AIS/AIS_DiameterDimension.lxx [deleted file]
src/AIS/AIS_Dimension.cxx [new file with mode: 0644]
src/AIS/AIS_Dimension.hxx [new file with mode: 0644]
src/AIS/AIS_DimensionOwner.cdl
src/AIS/AIS_DimensionOwner.cxx
src/AIS/AIS_Drawer.cdl
src/AIS/AIS_Drawer.cxx
src/AIS/AIS_Drawer.lxx
src/AIS/AIS_EqualDistanceRelation.cxx
src/AIS/AIS_EqualRadiusRelation.cxx
src/AIS/AIS_GraphicTool.cxx
src/AIS/AIS_LengthDimension.cdl [deleted file]
src/AIS/AIS_LengthDimension.cxx
src/AIS/AIS_LengthDimension.hxx [new file with mode: 0644]
src/AIS/AIS_LengthDimension.lxx [deleted file]
src/AIS/AIS_MaxRadiusDimension.cxx
src/AIS/AIS_MidPointRelation.cxx
src/AIS/AIS_MinRadiusDimension.cxx
src/AIS/AIS_OffsetDimension.cxx
src/AIS/AIS_ParallelRelation.cxx
src/AIS/AIS_RadiusDimension.cdl [deleted file]
src/AIS/AIS_RadiusDimension.cxx
src/AIS/AIS_RadiusDimension.hxx [new file with mode: 0644]
src/AIS/AIS_RadiusDimension.lxx [deleted file]
src/AIS/AIS_Relation.cdl
src/AIS/AIS_Relation.cxx
src/AIS/AIS_SymmetricRelation.cxx
src/AIS/FILES
src/Aspect/Aspect.cdl
src/DsgPrs/DsgPrs.cdl
src/DsgPrs/DsgPrs.cxx
src/DsgPrs/DsgPrs_AnglePresentation.cxx
src/DsgPrs/DsgPrs_Chamf2dPresentation.cxx
src/DsgPrs/DsgPrs_ConcentricPresentation.cxx
src/DsgPrs/DsgPrs_DiameterPresentation.cxx
src/DsgPrs/DsgPrs_EllipseRadiusPresentation.cxx
src/DsgPrs/DsgPrs_EqualDistancePresentation.cxx
src/DsgPrs/DsgPrs_EqualRadiusPresentation.cxx
src/DsgPrs/DsgPrs_FilletRadiusPresentation.cxx
src/DsgPrs/DsgPrs_FixPresentation.cxx
src/DsgPrs/DsgPrs_IdenticPresentation.cxx
src/DsgPrs/DsgPrs_LengthPresentation.cxx
src/DsgPrs/DsgPrs_MidPointPresentation.cxx
src/DsgPrs/DsgPrs_OffsetPresentation.cxx
src/DsgPrs/DsgPrs_ParalPresentation.cxx
src/DsgPrs/DsgPrs_PerpenPresentation.cxx
src/DsgPrs/DsgPrs_RadiusPresentation.cxx
src/DsgPrs/DsgPrs_SymbPresentation.cxx
src/DsgPrs/DsgPrs_SymmetricPresentation.cxx
src/DsgPrs/DsgPrs_TangentPresentation.cxx
src/Graphic3d/Graphic3d_AspectText3d.cdl
src/Graphic3d/Graphic3d_GraphicDriver.cdl
src/Graphic3d/Graphic3d_Group.cdl
src/Graphic3d/Graphic3d_Group_13.cxx
src/OpenGl/FILES
src/OpenGl/OpenGl_GraphicDriver.cxx
src/OpenGl/OpenGl_GraphicDriver.hxx
src/OpenGl/OpenGl_StencilTest.cxx [new file with mode: 0644]
src/OpenGl/OpenGl_StencilTest.hxx [moved from src/AIS/AIS_DimensionOwner.lxx with 56% similarity, mode: 0644]
src/OpenGl/OpenGl_Text.cxx
src/OpenGl/OpenGl_Window.cxx
src/Prs3d/Prs3d.cdl
src/Prs3d/Prs3d_AngleAspect.cdl [deleted file]
src/Prs3d/Prs3d_AngleAspect.cxx [deleted file]
src/Prs3d/Prs3d_AnglePresentation.cdl [deleted file]
src/Prs3d/Prs3d_AnglePresentation.cxx [deleted file]
src/Prs3d/Prs3d_ArrowAspect.cdl
src/Prs3d/Prs3d_CompositeAspect.cdl [deleted file]
src/Prs3d/Prs3d_CompositeAspect.cxx [deleted file]
src/Prs3d/Prs3d_DatumAspect.cdl
src/Prs3d/Prs3d_DimensionAspect.cdl [new file with mode: 0644]
src/Prs3d/Prs3d_DimensionAspect.cxx [new file with mode: 0644]
src/Prs3d/Prs3d_Drawer.cdl
src/Prs3d/Prs3d_Drawer.cxx
src/Prs3d/Prs3d_LengthAspect.cdl [deleted file]
src/Prs3d/Prs3d_LengthAspect.cxx [deleted file]
src/Prs3d/Prs3d_LengthPresentation.cdl [deleted file]
src/Prs3d/Prs3d_LengthPresentation.cxx [deleted file]
src/Prs3d/Prs3d_PlaneAspect.cdl
src/Prs3d/Prs3d_RadiusAspect.cdl [deleted file]
src/Prs3d/Prs3d_RadiusAspect.cxx [deleted file]
src/QABugs/QABugs_16.cxx
src/QABugs/QABugs_17.cxx
src/QABugs/QABugs_3.cxx
src/TKV3d/EXTERNLIB
src/TPrsStd/TPrsStd_ConstraintTools.cxx
src/ViewerTest/ViewerTest_ObjectCommands.cxx
src/ViewerTest/ViewerTest_RelationCommands.cxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx
src/XCAFPrs/XCAFPrs_AISObject.cxx
src/Xw/Xw_Window.cxx
tests/bugs/vis/buc60632_1
tests/bugs/vis/buc60632_2
tests/bugs/vis/bug24133_1 [new file with mode: 0644]
tests/bugs/vis/bug24133_2 [new file with mode: 0644]
tests/bugs/vis/bug24133_3 [new file with mode: 0644]
tests/bugs/vis/bug24133_4 [new file with mode: 0644]
tests/bugs/vis/bug301

index ccf7af1..d99e3ae 100755 (executable)
Binary files a/samples/mfc/standard/04_Viewer3d/res/AIS_TB.bmp and b/samples/mfc/standard/04_Viewer3d/res/AIS_TB.bmp differ
index f8012b0..94113f4 100755 (executable)
@@ -303,6 +303,7 @@ BEGIN
     BUTTON      ID_OBJECT_DISPLAYALL
     SEPARATOR
     BUTTON      ID_OBJECT_REMOVE
+    BUTTON      ID_OBJECT_DIM
 END
 
 
@@ -371,10 +372,6 @@ BEGIN
     BEGIN
         MENUITEM "Background Color...",         ID_Modify_ChangeBackground
     END
-    POPUP "User cylinder"
-    BEGIN
-        MENUITEM "Change face color",           ID_USERCYLINDER_CHANGEFACECOLOR
-    END
     POPUP "Object(s)"
     BEGIN
         MENUITEM "Erase",                       ID_OBJECT_ERASE
@@ -408,6 +405,10 @@ BEGIN
         END
         MENUITEM "Transparency...",             ID_OBJECT_TRANSPARENCY
     END
+    POPUP "User cylinder"
+    BEGIN
+        MENUITEM "Change face color",           ID_USERCYLINDER_CHANGEFACECOLOR
+    END
 END
 
 
@@ -514,6 +515,12 @@ BEGIN
     ID_TEXTURE_ON           "Run texture example\nRun texture example"
 END
 
+STRINGTABLE 
+BEGIN
+    ID_OBJECT_DIMENSIONS    "Add dimensions"
+    ID_LOCALCONTEXT_ADDDIMENSION "Add new dimension for selected objetcs"
+END
+
 #endif    // English (U.S.) resources
 /////////////////////////////////////////////////////////////////////////////
 
index afb33e7..a535dbd 100755 (executable)
@@ -77,6 +77,7 @@ END_MESSAGE_MAP()
 // CViewer3dDoc construction/destruction
 
 CViewer3dDoc::CViewer3dDoc()
+:OCC_3dDoc()
 {
        myCylinder.Nullify();
        mySphere.Nullify();
@@ -86,21 +87,9 @@ CViewer3dDoc::CViewer3dDoc()
        myOverlappedBox.Nullify();
        myOffsetDlg = NULL;
        myStaticTrihedronAxisIsDisplayed = FALSE;
-
        myState = -1;
 
        isTextureSampleStarted = FALSE;
-/*
-       // TODO: add one-time construction code here
-       Handle(Graphic3d_WNTGraphicDevice) theGraphicDevice = 
-               ((CViewer3dApp*)AfxGetApp())->GetGraphicDevice();
-
-       myViewer = new V3d_Viewer(theGraphicDevice,(short *) "Visu3D");
-       myViewer->SetDefaultLights();
-       myViewer->SetLightOn();
-*/
-
-//     myViewer->SetDefaultBackgroundColor(Quantity_TOC_RGB, 0.,0.,0.);
 
        myPresentation = OCCDemo_Presentation::Current;
        myPresentation->SetDocument(this);
@@ -702,39 +691,22 @@ void CViewer3dDoc::OnUpdateOptionsTrihedronStaticTrihedron(CCmdUI* pCmdUI)
        
 }
 
-void  CViewer3dDoc::Popup( const Standard_Integer  x,
-                                                  const Standard_Integer  y ,
-                           const Handle(V3d_View)& aView   ) 
+void  CViewer3dDoc::Popup (const Standard_Integer  x,
+                           const Standard_Integer  y ,
+                           const Handle(V3d_View)& aView)
 {
-  Standard_Integer PopupMenuNumber=0;
- myAISContext->InitCurrent();
-  if (myAISContext->MoreCurrent()) {
-               if (myAISContext->Current()->IsKind(STANDARD_TYPE(User_Cylinder)))
-                       return;
-               else 
-                       PopupMenuNumber = 1;
-       }
-
-  CMenu menu;
-  VERIFY(menu.LoadMenu(IDR_Popup3D));
-  CMenu* pPopup = menu.GetSubMenu(PopupMenuNumber);
-
-  ASSERT(pPopup != NULL);
-   if (PopupMenuNumber == 1) // more than 1 object.
+  myPopupMenuNumber=0;
+  // Specified check for context menu number to call
+  myAISContext->InitCurrent();
+  if (myAISContext->MoreCurrent())
   {
-    bool OneOrMoreInShading = false;
-       for (myAISContext->InitCurrent();myAISContext->MoreCurrent ();myAISContext->NextCurrent ())
-    if (myAISContext->IsDisplayed(myAISContext->Current(),1)) OneOrMoreInShading=true;
-       if(!OneOrMoreInShading)
-       pPopup->EnableMenuItem(5, MF_BYPOSITION | MF_DISABLED | MF_GRAYED);
-   }
-
-  POINT winCoord = { x , y };
-  Handle(WNT_Window) aWNTWindow=
-  Handle(WNT_Window)::DownCast(aView->Window());
-  ClientToScreen ( (HWND)(aWNTWindow->HWindow()),&winCoord);
-  pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON , winCoord.x, winCoord.y , 
-                         AfxGetMainWnd());
+    if (myAISContext->Current()->IsKind(STANDARD_TYPE(User_Cylinder)))
+    {
+      myPopupMenuNumber = 2;
+      //return;
+    }
+  }
+  OCC_3dBaseDoc::Popup(x,y, aView);
 }
 
 //Set faces selection mode
index be2896c..56f8a48 100755 (executable)
Binary files a/samples/mfc/standard/05_ImportExport/res/ImportExport.aps and b/samples/mfc/standard/05_ImportExport/res/ImportExport.aps differ
diff --git a/samples/mfc/standard/Common/AngleParamsVerticesPage.cpp b/samples/mfc/standard/Common/AngleParamsVerticesPage.cpp
new file mode 100644 (file)
index 0000000..62f6c30
--- /dev/null
@@ -0,0 +1,163 @@
+// AngleParamsVerticesPage.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "AngleParamsVerticesPage.h"
+#include "DimensionDlg.h"
+
+#include <AIS_InteractiveContext.hxx>
+#include <AIS_LocalContext.hxx>
+#include <AIS_LengthDimension.hxx>
+#include <AIS_AngleDimension.hxx>
+#include <BRep_Tool.hxx>
+#include <GC_MakePlane.hxx>
+#include <Prs3d_DimensionAspect.hxx>
+
+// CAngleParamsVerticesPage dialog
+
+IMPLEMENT_DYNAMIC(CAngleParamsVerticesPage, CDialog)
+
+//=======================================================================
+//function : CAngleParamsVerticesPage
+//purpose  :
+//=======================================================================
+
+CAngleParamsVerticesPage::CAngleParamsVerticesPage (Handle(AIS_InteractiveContext) theAISContext,
+                                                    CWnd* pParent /*=NULL*/)
+: CDialog(CAngleParamsVerticesPage::IDD, pParent)
+{
+  myAISContext = theAISContext;
+}
+
+//=======================================================================
+//function : ~CAngleParamsVerticesPage
+//purpose  :
+//=======================================================================
+
+CAngleParamsVerticesPage::~CAngleParamsVerticesPage()
+{
+}
+
+//=======================================================================
+//function : DoDataExchange
+//purpose  :
+//=======================================================================
+
+void CAngleParamsVerticesPage::DoDataExchange (CDataExchange* pDX)
+{
+  CDialog::DoDataExchange (pDX);
+}
+
+
+BEGIN_MESSAGE_MAP(CAngleParamsVerticesPage, CDialog)
+  ON_BN_CLICKED(IDC_BUTTON1, &CAngleParamsVerticesPage::OnBnClickedVertex1Btn)
+  ON_BN_CLICKED(IDC_BUTTON3, &CAngleParamsVerticesPage::OnBnClickedVertex2Btn)
+  ON_BN_CLICKED(IDC_BUTTON4, &CAngleParamsVerticesPage::OnBnClickedVertex3Btn)
+END_MESSAGE_MAP()
+
+
+//=======================================================================
+//function : OnBnClickedVertex1Btn
+//purpose  :
+//=======================================================================
+
+void CAngleParamsVerticesPage::OnBnClickedVertex1Btn()
+{
+  // Open local context and choose the vertex for angle dimensions
+  if (!myAISContext->HasOpenedContext())
+  {
+    myAISContext->OpenLocalContext();
+    myAISContext->ActivateStandardMode(TopAbs_VERTEX);
+    AfxMessageBox (_T ("Local context was not opened. Choose the edge and press the button again"),
+                       MB_ICONINFORMATION | MB_OK);
+    return;
+  }
+
+  // Now it's ok, local context is opened and edge selection mode is activated
+  // Check if some vertex is selected
+  myAISContext->LocalContext()->InitSelected();
+  if (!myAISContext->LocalContext()->MoreSelected())
+  {
+    AfxMessageBox (_T ("Choose the vertex and press the button again"),
+                       MB_ICONINFORMATION | MB_OK);
+    return;
+  }
+
+  myFirstVertex = TopoDS::Vertex (myAISContext->LocalContext()->SelectedShape());
+  myAISContext->LocalContext()->ClearSelected();
+}
+
+//=======================================================================
+//function : OnBnClickedVertex2Btn
+//purpose  :
+//=======================================================================
+
+void CAngleParamsVerticesPage::OnBnClickedVertex2Btn()
+{
+  myAISContext->LocalContext()->InitSelected();
+  if (!myAISContext->LocalContext()->MoreSelected())
+  {
+    AfxMessageBox ( _T("Choose the vertex and press the button again"), MB_ICONINFORMATION | MB_OK);
+    return;
+  }
+
+  mySecondVertex = TopoDS::Vertex (myAISContext->LocalContext()->SelectedShape());
+
+  myAISContext->LocalContext()->ClearSelected();
+}
+
+//=======================================================================
+//function : OnBnClickedVertex3Btn
+//purpose  :
+//=======================================================================
+
+void CAngleParamsVerticesPage::OnBnClickedVertex3Btn()
+{
+  myAISContext->LocalContext()->InitSelected();
+  if (!myAISContext->LocalContext()->MoreSelected())
+  {
+    AfxMessageBox (_T ("Choose the vertex and press the button again"), MB_ICONINFORMATION | MB_OK);
+    return;
+  }
+
+  myThirdVertex = TopoDS::Vertex (myAISContext->LocalContext()->SelectedShape());
+  myAISContext->LocalContext()->ClearSelected();
+
+  //Build dimension here
+  TopoDS_Edge anEdge12 = BRepBuilderAPI_MakeEdge (myFirstVertex, mySecondVertex);
+  TopoDS_Edge anEdge23 = BRepBuilderAPI_MakeEdge (mySecondVertex, myThirdVertex);
+
+  CDimensionDlg *aDimDlg = (CDimensionDlg*)(GetParentOwner());
+
+  gp_Pnt aP1 = BRep_Tool::Pnt (myFirstVertex),
+         aP2 = BRep_Tool::Pnt (mySecondVertex),
+         aP3 = BRep_Tool::Pnt (myThirdVertex);
+  GC_MakePlane aPlaneBuilder (aP1,aP2,aP3);
+
+  Handle(Geom_Plane) aPlane = aPlaneBuilder.Value();
+  Handle(AIS_AngleDimension) anAngleDim = new AIS_AngleDimension (aP1,aP2,aP3);
+  Handle(Prs3d_DimensionAspect) anAspect = new Prs3d_DimensionAspect();
+  anAspect->MakeArrows3d (Standard_False);
+  anAspect->MakeText3d (aDimDlg->GetTextType());
+  anAspect->TextAspect()->SetHeight (aDimDlg->GetFontHeight());
+  anAspect->MakeTextShaded (aDimDlg->IsText3dShaded());
+  anAspect->SetCommonColor (aDimDlg->GetDimensionColor());
+  anAngleDim->MakeUnitsDisplayed (aDimDlg->IsUnitsDisplayed());
+  if (anAngleDim->IsUnitsDisplayed())
+  {
+    anAngleDim->SetDisplayUnits (aDimDlg->GetUnits());
+    if ((anAngleDim->DisplayUnits().IsEqual (TCollection_AsciiString ("deg"))))
+    {
+      anAngleDim->MakeUnitsDisplayed (Standard_False);
+    }
+    else
+    {
+      anAngleDim->SetDisplaySpecialSymbol (AIS_DSS_No);
+    }
+  }
+  anAngleDim->SetDimensionAspect (anAspect);
+  myAISContext->CloseAllContexts();
+  myAISContext->Display (anAngleDim);
+  myAISContext->OpenLocalContext();
+  myAISContext->ActivateStandardMode (TopAbs_VERTEX);
+}
diff --git a/samples/mfc/standard/Common/AngleParamsVerticesPage.h b/samples/mfc/standard/Common/AngleParamsVerticesPage.h
new file mode 100644 (file)
index 0000000..88edc13
--- /dev/null
@@ -0,0 +1,31 @@
+#pragma once
+
+#include "res\OCC_Resource.h"
+
+// CAngleParamsVerticesPage dialog
+
+class CAngleParamsVerticesPage : public CDialog
+{
+  DECLARE_DYNAMIC(CAngleParamsVerticesPage)
+private:
+  Handle(AIS_InteractiveContext) myAISContext;
+  TopoDS_Vertex myFirstVertex;
+  TopoDS_Vertex mySecondVertex;
+  TopoDS_Vertex myThirdVertex;
+public:
+  CAngleParamsVerticesPage(Handle (AIS_InteractiveContext) theAISContext,
+                                   CWnd* pParent = NULL);   // standard constructor
+  virtual ~CAngleParamsVerticesPage();
+
+// Dialog Data
+  enum { IDD = IDD_AngleParamsVerticesPage };
+
+protected:
+  virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
+
+  DECLARE_MESSAGE_MAP()
+public:
+  afx_msg void OnBnClickedVertex1Btn();
+  afx_msg void OnBnClickedVertex2Btn();
+  afx_msg void OnBnClickedVertex3Btn();
+};
diff --git a/samples/mfc/standard/Common/DimensionDlg.cpp b/samples/mfc/standard/Common/DimensionDlg.cpp
new file mode 100644 (file)
index 0000000..1ae8cf7
--- /dev/null
@@ -0,0 +1,686 @@
+// CDimensionDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+
+#include "DimensionDlg.h"
+#include "LengthParamsEdgePage.h"
+#include "LengthParamsVerticesPage.h"
+#include "LengthParamsEdgesPage.h"
+#include "AngleParamsVerticesPage.h"
+#include "RadiusParamsPage.h"
+#include <Standard_Macro.hxx>
+#include <AIS_InteractiveContext.hxx>
+#include <TColStd_ListIteratorOfListOfInteger.hxx>
+#include <TColStd_ListOfInteger.hxx>
+#include <AIS_LocalContext.hxx>
+#include <Quantity_Color.hxx>
+
+BEGIN_MESSAGE_MAP(CDimensionDlg, CDialog)
+  ON_BN_CLICKED(IDOK, &CDimensionDlg::OnBnClickedOk)
+  ON_BN_CLICKED(IDC_DimLength, &CDimensionDlg::OnBnClickedDimLength)
+  ON_BN_CLICKED(IDC_DimAngle, &CDimensionDlg::OnBnClickedDimAngle)
+  ON_BN_CLICKED(IDC_DimRadius, &CDimensionDlg::OnBnClickedDimRadius)
+  ON_NOTIFY(TCN_SELCHANGE, IDC_LengthTab, &CDimensionDlg::OnTcnSelChangeLengthTab)
+  ON_NOTIFY(TCN_SELCHANGING, IDC_LengthTab, &CDimensionDlg::OnTcnSelChangingLengthTab)
+  ON_WM_DESTROY()
+  ON_NOTIFY(TCN_SELCHANGE, IDC_AngleTab, &CDimensionDlg::OnTcnSelChangeAngleTab)
+  ON_NOTIFY(TCN_SELCHANGING, IDC_AngleTab, &CDimensionDlg::OnTcnSelChangingAngleTab)
+  ON_BN_CLICKED(IDC_DimDiameter, &CDimensionDlg::OnBnClickedDimDiameter)
+  ON_BN_CLICKED(IDC_2DText, &CDimensionDlg::OnBnClicked2dText)
+  ON_BN_CLICKED(IDC_3DText, &CDimensionDlg::OnBnClicked3dText)
+  ON_BN_CLICKED(IDC_DimensionColor, &CDimensionDlg::OnBnClickedDimensionColor)
+END_MESSAGE_MAP()
+
+//=======================================================================
+//function : CDimensionDlg
+//purpose  :
+//=======================================================================
+
+CDimensionDlg::CDimensionDlg(CWnd* pParent /*=NULL*/)
+  : CDialog(CDimensionDlg::IDD, pParent),
+  mySelectedDimType(0),
+  myFontSize (10),
+  myDimensionColor (Quantity_NOC_LAWNGREEN)
+{
+}
+
+//=======================================================================
+//function : CDimensionDlg
+//purpose  :
+//=======================================================================
+
+CDimensionDlg::CDimensionDlg (Handle(AIS_InteractiveContext) &theAISContext,
+               CWnd* pParent)
+: CDialog(CDimensionDlg::IDD, pParent),
+  mySelectedDimType(0),
+  myFontSize (10),
+  myDimensionColor (Quantity_NOC_LAWNGREEN)
+{
+  myAISContext = theAISContext;
+}
+
+//=======================================================================
+//function : ~CDimensionDlg
+//purpose  :
+//=======================================================================
+
+CDimensionDlg::~CDimensionDlg()
+{
+}
+
+//=======================================================================
+//function : SetContext
+//purpose  :
+//=======================================================================
+
+void CDimensionDlg::SetContext (const Handle(AIS_InteractiveContext) theContext)
+{
+  myAISContext = theContext;
+}
+
+//=======================================================================
+//function : OnInitDialog
+//purpose  : Initialization of dialog fields and parameters
+//=======================================================================
+
+BOOL CDimensionDlg::OnInitDialog()
+{
+  CDialog::OnInitDialog();
+
+  myLengthParams = (CTabCtrl*) GetDlgItem (IDC_LengthTab);
+  myAngleParams = (CTabCtrl*) GetDlgItem (IDC_AngleTab);
+  myRadiusParams = (CTabCtrl*) GetDlgItem (IDC_RadiusTab);
+  myDiameterParams = (CTabCtrl*) GetDlgItem (IDC_DiameterTab);
+
+  CreateLengthParamsTab();
+  CreateAngleParamsTab();
+  CreateRadiusParamsTab();
+  CreateDiameterParamsTab( );
+
+  myLengthParams->ShowWindow (SW_SHOW);
+  myAngleParams->ShowWindow (SW_HIDE);
+  myRadiusParams->ShowWindow (SW_HIDE);
+  myDiameterParams->ShowWindow (SW_HIDE);
+
+  // Setting default values
+  ((CSliderCtrl*)GetDlgItem(IDC_Flyout))->SetRange (-30,30,true);
+  ((CSliderCtrl*)GetDlgItem(IDC_Flyout))->SetPos (15);
+  UpdateUnitsListForLength ();
+  ((CComboBox*)GetDlgItem (IDC_DisplayUnits))->SetCurSel (1);
+  CheckRadioButton (IDC_2DText, IDC_3DText, IDC_2DText);
+  SetTextModeControlsVisible (false);
+  CComboBox* aCombo =(CComboBox* )GetDlgItem (IDC_FontSize);
+  aCombo->SelectString (0,"10");
+
+  UpdateData (FALSE);
+
+  return TRUE;  // return TRUE unless you set the focus to a control
+  // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+//=======================================================================
+//function : DoDataExchange
+//purpose  : Updating of dialog data if it's needed
+//=======================================================================
+
+void CDimensionDlg::DoDataExchange (CDataExchange* pDX)
+{
+  CDialog::DoDataExchange (pDX);
+
+  DDX_Radio (pDX, IDC_DimLength, mySelectedDimType);
+}
+
+//=======================================================================
+//function : OnBnClickedOk
+//purpose  : Reset all local contexts and close the dimension dialog
+//=======================================================================
+
+void CDimensionDlg::OnBnClickedOk()
+{
+ if (myAISContext->HasOpenedContext())
+ {
+   myAISContext->CloseAllContexts();
+ }
+
+ OnOK();
+}
+
+//=======================================================================
+//function : GetFlyout
+//purpose  : Only for length dimensions! Gets flyout value
+//=======================================================================
+
+const Standard_Real CDimensionDlg::GetFlyout() const 
+{
+  return ((CSliderCtrl*)GetDlgItem(IDC_Flyout))->GetPos();
+}
+
+//=======================================================================
+//function : CreateLengthParamsTab
+//purpose  : Fill tab control for length dimensions
+//=======================================================================
+
+void CDimensionDlg::CreateLengthParamsTab()
+{
+  TC_ITEM aTabItem;
+  aTabItem.mask = TCIF_TEXT;
+  aTabItem.pszText = "Edge";
+  myLengthParams->InsertItem (0, &aTabItem);
+  aTabItem.pszText = "Vertices";
+  myLengthParams->InsertItem (1, &aTabItem);
+  aTabItem.pszText = "Parallel edges";
+  myLengthParams->InsertItem (2, &aTabItem);
+
+  CLengthParamsEdgePage *aPage1 = new CLengthParamsEdgePage (myAISContext);
+  aTabItem.mask = TCIF_PARAM;
+  aTabItem.lParam = (LPARAM)aPage1;
+  myLengthParams->SetItem (0, &aTabItem);
+  VERIFY (aPage1->Create (CLengthParamsEdgePage::IDD,myLengthParams));
+  aPage1->SetWindowPos (NULL,10,30,0,0,SWP_NOSIZE | SWP_NOZORDER);
+  aPage1->ShowWindow (SW_SHOW);
+
+  CLengthParamsVerticesPage *aPage2 = new CLengthParamsVerticesPage (myAISContext);
+  aTabItem.mask = TCIF_PARAM;
+  aTabItem.lParam = (LPARAM)aPage2;
+  myLengthParams->SetItem (1, &aTabItem);
+  VERIFY (aPage2->Create (CLengthParamsVerticesPage::IDD,myLengthParams));
+  aPage2->SetWindowPos (NULL,10,30,0,0,SWP_NOSIZE | SWP_NOZORDER);
+
+  CLengthParamsEdgesPage *aPage3 = new CLengthParamsEdgesPage (myAISContext);
+  aTabItem.mask = TCIF_PARAM;
+  aTabItem.lParam = (LPARAM)aPage3;
+  myLengthParams->SetItem (2, &aTabItem);
+  VERIFY (aPage3->Create (CLengthParamsEdgesPage::IDD,myLengthParams));
+  aPage3->SetWindowPos (NULL,10,30,0,0,SWP_NOSIZE | SWP_NOZORDER);
+}
+
+//=======================================================================
+//function : CreateAngleParamsTab
+//purpose  : Fill tab control for angle dimensions
+//=======================================================================
+
+void CDimensionDlg::CreateAngleParamsTab()
+{
+  TC_ITEM aTabItem;
+  aTabItem.mask = TCIF_TEXT;
+  aTabItem.pszText = "Two edges";
+  myAngleParams->InsertItem (0, &aTabItem);
+  aTabItem.pszText = "Three vertices";
+  myAngleParams->InsertItem (1, &aTabItem);
+
+  CLengthParamsEdgesPage *aPage1 = new CLengthParamsEdgesPage (myAISContext, true);
+  aTabItem.mask = TCIF_PARAM;
+  aTabItem.lParam = (LPARAM)aPage1;
+  myAngleParams->SetItem (0, &aTabItem);
+  VERIFY (aPage1->Create (CLengthParamsEdgesPage::IDD,myAngleParams));
+  aPage1->SetWindowPos (NULL,10,30,0,0,SWP_NOSIZE | SWP_NOZORDER);
+  aPage1->ShowWindow (SW_SHOW);
+
+  CAngleParamsVerticesPage *aPage2 = new CAngleParamsVerticesPage (myAISContext);
+  aTabItem.mask = TCIF_PARAM;
+  aTabItem.lParam = (LPARAM)aPage2;
+  myAngleParams->SetItem (1, &aTabItem);
+  VERIFY (aPage2->Create (CAngleParamsVerticesPage::IDD,myAngleParams));
+  aPage2->SetWindowPos (NULL,10,30,0,0,SWP_NOSIZE | SWP_NOZORDER);
+}
+
+//=======================================================================
+//function : CreateRadiusParamsTab
+//purpose  : Fill tab control for radius dimensions
+//=======================================================================
+
+void CDimensionDlg::CreateRadiusParamsTab()
+{
+  TC_ITEM aTabItem;
+  aTabItem.mask = TCIF_TEXT;
+  aTabItem.pszText = "Circle or arc";
+  myRadiusParams->InsertItem (0, &aTabItem);
+  CRadiusParamsPage *aPage1 = new CRadiusParamsPage (myAISContext);
+  aTabItem.mask = TCIF_PARAM;
+  aTabItem.lParam = (LPARAM)aPage1;
+  myRadiusParams->SetItem (0, &aTabItem);
+  VERIFY (aPage1->Create (CRadiusParamsPage::IDD,myRadiusParams));
+  aPage1->SetWindowPos (NULL,10,30,0,0,SWP_NOSIZE | SWP_NOZORDER);
+  aPage1->ShowWindow (SW_SHOW);
+}
+
+//=======================================================================
+//function : CreateDiameterParamsTab
+//purpose  : Fill tab control for diameter dimensions
+//=======================================================================
+
+void CDimensionDlg::CreateDiameterParamsTab()
+{
+  TC_ITEM aTabItem;
+  aTabItem.mask = TCIF_TEXT;
+  aTabItem.pszText = "Circle or arc";
+  myDiameterParams->InsertItem (0, &aTabItem);
+  CRadiusParamsPage *aPage1 = new CRadiusParamsPage (myAISContext,Standard_True);
+  aTabItem.mask = TCIF_PARAM;
+  aTabItem.lParam = (LPARAM)aPage1;
+  myRadiusParams->SetItem (0, &aTabItem);
+  VERIFY (aPage1->Create (CRadiusParamsPage::IDD,myDiameterParams));
+  aPage1->SetWindowPos (NULL,10,30,0,0,SWP_NOSIZE | SWP_NOZORDER);
+  aPage1->ShowWindow (SW_SHOW);
+}
+
+//=======================================================================
+//function : UpdateStandardModeForAngle
+//purpose  : 
+//=======================================================================
+
+void CDimensionDlg::UpdateStandardModeForAngle()
+{
+  int aTabNum = ((CTabCtrl*) GetDlgItem (IDC_AngleTab))->GetCurSel();
+  myAISContext->CloseAllContexts();
+  myAISContext->OpenLocalContext();
+  myAISContext->ActivateStandardMode (aTabNum == 1 ? TopAbs_VERTEX : TopAbs_EDGE);
+}
+
+//=======================================================================
+//function : UpdateStandardModeForLength
+//purpose  : 
+//=======================================================================
+
+void CDimensionDlg::UpdateStandardModeForLength()
+{
+  int aTabNum = ((CTabCtrl*) GetDlgItem (IDC_LengthTab))->GetCurSel();
+  myAISContext->CloseAllContexts();
+  myAISContext->OpenLocalContext();
+  myAISContext->ActivateStandardMode (aTabNum == 1 ? TopAbs_VERTEX : TopAbs_EDGE);
+}
+
+//=======================================================================
+//function : UpdateStandardModeForLength
+//purpose  : 
+//=======================================================================
+
+void CDimensionDlg::UpdateStandardMode()
+{
+  int aCurIndex = GetCheckedRadioButton (IDC_DimLength, IDC_DimDiameter);
+  switch (aCurIndex)
+  {
+  case IDC_DimLength:
+    UpdateStandardModeForLength();
+    break;
+  case IDC_DimAngle:
+    UpdateStandardModeForAngle();
+    break;
+  case IDC_DimRadius:
+  case IDC_DimDiameter:
+    {
+      myAISContext->OpenLocalContext();
+      myAISContext->ActivateStandardMode (TopAbs_EDGE);
+    }
+    break;
+  }
+}
+
+//=======================================================================
+//function : OnBnClickedDimLength
+//purpose  : it is called when <Length> radio button is chosen
+//=======================================================================
+
+void CDimensionDlg::OnBnClickedDimLength()
+{
+  // Update parameters
+  UpdateStandardModeForLength ();
+  (CTabCtrl*) GetDlgItem (IDC_LengthTab)->ShowWindow (SW_SHOW);
+  (CTabCtrl*) GetDlgItem (IDC_AngleTab)->ShowWindow (SW_HIDE);
+  (CTabCtrl*) GetDlgItem (IDC_RadiusTab)->ShowWindow (SW_HIDE);
+  (CTabCtrl*) GetDlgItem (IDC_DiameterTab)->ShowWindow (SW_HIDE);
+
+  UpdateUnitsListForLength ();
+  ((CSliderCtrl*)GetDlgItem(IDC_Flyout))->SetPos (15);
+}
+
+//=======================================================================
+//function : OnBnClickedDimAngle
+//purpose  : it is called when <Angle> radio button is chosen
+//=======================================================================
+
+void CDimensionDlg::OnBnClickedDimAngle()
+{
+  // Update parameters
+  UpdateStandardModeForAngle();
+  (CTabCtrl*) GetDlgItem (IDC_LengthTab)->ShowWindow (SW_HIDE);
+  (CTabCtrl*) GetDlgItem (IDC_AngleTab)->ShowWindow (SW_SHOW);
+  (CTabCtrl*) GetDlgItem (IDC_RadiusTab)->ShowWindow (SW_HIDE);
+  (CTabCtrl*) GetDlgItem (IDC_DiameterTab)->ShowWindow (SW_HIDE);
+
+  UpdateUnitsListForAngle();
+  ((CSliderCtrl*)GetDlgItem(IDC_Flyout))->SetPos (15);
+}
+
+//=======================================================================
+//function : OnBnClickedDimDiameter
+//purpose  : it is called when <Diameter> radio button is chosen
+//=======================================================================
+
+void CDimensionDlg::OnBnClickedDimDiameter()
+{
+  // Update parameters
+  myAISContext->CloseAllContexts();
+  myAISContext->OpenLocalContext();
+  myAISContext->ActivateStandardMode (TopAbs_EDGE);
+
+  (CTabCtrl*) GetDlgItem (IDC_LengthTab)->ShowWindow (SW_HIDE);
+  (CTabCtrl*) GetDlgItem (IDC_AngleTab)->ShowWindow (SW_HIDE);
+  (CTabCtrl*) GetDlgItem (IDC_RadiusTab)->ShowWindow (SW_HIDE);
+  (CTabCtrl*) GetDlgItem (IDC_DiameterTab)->ShowWindow (SW_SHOW);
+
+  UpdateUnitsListForLength();
+  ((CSliderCtrl*)GetDlgItem(IDC_Flyout))->SetPos (0);
+}
+
+//=======================================================================
+//function : OnBnClickedDimRadius
+//purpose  : it is called when <Radius> radio button is chosen
+//=======================================================================
+
+void CDimensionDlg::OnBnClickedDimRadius()
+{
+  // Update parameters
+  myAISContext->CloseAllContexts();
+  myAISContext->OpenLocalContext();
+  myAISContext->ActivateStandardMode (TopAbs_EDGE);
+  (CTabCtrl*) GetDlgItem (IDC_LengthTab)->ShowWindow (SW_HIDE);
+  (CTabCtrl*) GetDlgItem (IDC_AngleTab)->ShowWindow (SW_HIDE);
+  (CTabCtrl*) GetDlgItem (IDC_RadiusTab)->ShowWindow (SW_SHOW);
+  (CTabCtrl*) GetDlgItem (IDC_DiameterTab)->ShowWindow (SW_HIDE);
+
+  UpdateUnitsListForLength();
+  ((CSliderCtrl*)GetDlgItem(IDC_Flyout))->SetPos (0);
+}
+
+//=======================================================================
+//function : OnTcnSelChangeLengthTab
+//purpose  : it is called when in Length tab control current tab was changed
+//=======================================================================
+
+void CDimensionDlg::OnTcnSelChangeLengthTab (NMHDR *pNMHDR, LRESULT *pResult)
+{
+  // Show this chosen tab page
+  int aTabNum = ((CTabCtrl*) GetDlgItem (IDC_LengthTab))->GetCurSel();
+  TC_ITEM anItem;
+  anItem.mask = TCIF_PARAM;
+  ((CTabCtrl*) GetDlgItem (IDC_LengthTab))->GetItem (aTabNum, &anItem);
+  ASSERT(anItem.lParam);
+  CWnd *aWnd = (CWnd*)anItem.lParam;
+  aWnd->ShowWindow (SW_SHOW);
+  UpdateStandardModeForLength();
+  *pResult = 0;
+}
+
+//=======================================================================
+//function : OnTcnSelChangingLengthTab
+//purpose  : it is called when in Length tab control current tab
+//           is changing
+//           It is used to hide the current tab here to prevent collisions.
+//=======================================================================
+
+void CDimensionDlg::OnTcnSelChangingLengthTab (NMHDR *pNMHDR, LRESULT *pResult)
+{
+  // Hide current tab page
+  int aTabNum =  ((CTabCtrl*) GetDlgItem (IDC_LengthTab))->GetCurSel();
+  TC_ITEM anItem;
+  anItem.mask = TCIF_PARAM;
+   ((CTabCtrl*) GetDlgItem (IDC_LengthTab))->GetItem (aTabNum, &anItem);
+  ASSERT (anItem.lParam);
+  CWnd *aWnd = (CWnd*)anItem.lParam;
+  aWnd->ShowWindow (SW_HIDE);
+  *pResult = 0;
+}
+
+//=======================================================================
+//function : OnTcnSelChangeAngleTab
+//purpose  : it is called when in Angle tab control current tab was changed
+//=======================================================================
+
+void CDimensionDlg::OnTcnSelChangeAngleTab (NMHDR *pNMHDR, LRESULT *pResult)
+{
+  int aTabNum = ((CTabCtrl*) GetDlgItem (IDC_AngleTab))->GetCurSel();
+  TC_ITEM anItem;
+  anItem.mask = TCIF_PARAM;
+  ((CTabCtrl*) GetDlgItem (IDC_AngleTab))->GetItem (aTabNum, &anItem);
+  ASSERT (anItem.lParam);
+  CWnd *aWnd = (CWnd*)anItem.lParam;
+  aWnd->ShowWindow (SW_SHOW);
+  UpdateStandardModeForAngle();
+  *pResult = 0;
+}
+
+//=======================================================================
+//function : OnTcnSelChangingAngleTab
+//purpose  : it is called when in Angle tab control current tab
+//           is changing
+//           It is used to hide the current tab here to prevent collisions.
+//=======================================================================
+
+void CDimensionDlg::OnTcnSelChangingAngleTab (NMHDR *pNMHDR, LRESULT *pResult)
+{
+  int aTabNum = ((CTabCtrl*) GetDlgItem (IDC_AngleTab))->GetCurSel();
+  TC_ITEM anItem;
+  anItem.mask = TCIF_PARAM;
+  ((CTabCtrl*) GetDlgItem (IDC_AngleTab))->GetItem (aTabNum, &anItem);
+  ASSERT (anItem.lParam);
+  CWnd *aWnd = (CWnd*)anItem.lParam;
+  aWnd->ShowWindow (SW_HIDE);
+  *pResult = 0;
+}
+
+//=======================================================================
+//function : DeactivateAllStandardModes
+//purpose  : 
+//=======================================================================
+
+void CDimensionDlg::DeactivateAllStandardModes()
+{
+  if (myAISContext->HasOpenedContext())
+  {
+    myAISContext->CloseAllContexts();
+    for (TColStd_ListIteratorOfListOfInteger anIt (myAISContext->LocalContext()->StandardModes());
+      anIt.More();
+      anIt.Next())
+    {
+      myAISContext->LocalContext()->DeactivateStandardMode ((TopAbs_ShapeEnum)anIt.Value());
+    }
+  }
+}
+
+//=======================================================================
+//function : OnDestroy
+//purpose  : 
+//=======================================================================
+
+void CDimensionDlg::OnDestroy()
+{
+  if (myAISContext->HasOpenedContext())
+  {
+    myAISContext->CloseAllContexts();
+  }
+  // Destroy length tab
+  CWnd *aWnd;
+  TC_ITEM anItem;
+  anItem.mask = TCIF_PARAM;
+  for (int i = 2; i >= 0; --i)
+  {
+    ((CTabCtrl*) GetDlgItem (IDC_LengthTab))->GetItem (i, &anItem);
+    ASSERT (anItem.lParam);
+    aWnd  = (CWnd*) anItem.lParam;
+    aWnd->DestroyWindow();
+    delete aWnd;
+  }
+  // Destroy angle tab
+  for (int i = 1; i >= 0; --i)
+  {
+    ((CTabCtrl*) GetDlgItem (IDC_AngleTab))->GetItem (i, &anItem);
+    ASSERT(anItem.lParam);
+    aWnd  = (CWnd*) anItem.lParam;
+    aWnd->DestroyWindow();
+    delete aWnd;
+  }
+
+  CDialog::OnDestroy();
+}
+
+//=======================================================================
+//function : GetTextType
+//purpose  : Returns true if 3d text is to be used
+//           and false in the case of 2d text.
+//=======================================================================
+
+const Standard_Boolean CDimensionDlg::GetTextType() const
+{
+  CButton* a3DButton = (CButton*)GetDlgItem (IDC_3DText);
+  return a3DButton->GetCheck();
+}
+
+//=======================================================================
+//function : GetFontHeight
+//purpose  : Returns font height
+//=======================================================================
+
+const Standard_Real CDimensionDlg::GetFontHeight() const
+{
+  CComboBox *aComboBox = (CComboBox*)GetDlgItem (IDC_FontSize);
+  CString aStr;
+  aComboBox->GetWindowTextA (aStr);
+  return (Standard_Real)atof (aStr);
+}
+
+//=======================================================================
+//function : IsText3dShaded
+//purpose  : Only for 3d text; returns true if shaded 3d text is to be used
+//=======================================================================
+
+const Standard_Boolean CDimensionDlg::IsText3dShaded() const
+{
+  CComboBox *aComboBox = (CComboBox*)GetDlgItem (IDC_TextDisplayMode);
+  int aCurIndex = aComboBox->GetCurSel();
+  return aCurIndex == 0 ? Standard_False : Standard_True;
+}
+
+//=======================================================================
+//function : SetTextModeControlsVisible
+//purpose  : for the dialog updating
+//=======================================================================
+
+void CDimensionDlg::SetTextModeControlsVisible (bool isVisible)
+{
+  GetDlgItem (IDC_TextDisplayMode)->ShowWindow (isVisible ? SW_SHOW : SW_HIDE);
+  GetDlgItem (IDC_TextDisplayModeStatic)->ShowWindow (isVisible ? SW_SHOW : SW_HIDE);
+}
+
+//=======================================================================
+//function : OnBnClicked2dText
+//purpose  : for the dialog updating when 2d text radio button was chosen
+//=======================================================================
+
+void CDimensionDlg::OnBnClicked2dText()
+{
+  SetTextModeControlsVisible (false);
+}
+
+//=======================================================================
+//function : OnBnClicked3dText
+//purpose  : for the dialog updating when 3d text radio button was chosen
+//=======================================================================
+
+void CDimensionDlg::OnBnClicked3dText()
+{
+  SetTextModeControlsVisible (true);
+}
+
+//=======================================================================
+//function : UpdateUnitsListForLength
+//purpose  : for the dialog updating when 3d text radio button was chosen
+//=======================================================================
+
+void CDimensionDlg::UpdateUnitsListForLength()
+{
+  CComboBox *aCombo = (CComboBox*)GetDlgItem (IDC_DisplayUnits);
+  aCombo->ResetContent();
+  aCombo->AddString ("No");
+  aCombo->AddString ("m");
+  aCombo->AddString ("mm");
+  aCombo->AddString ("in");
+  aCombo->SetCurSel (1);
+}
+
+//=======================================================================
+//function : UpdateUnitsListForAngle
+//purpose  : for the dialog updating when 3d text radio button was chosen
+//=======================================================================
+
+void CDimensionDlg::UpdateUnitsListForAngle()
+{
+  CComboBox *aCombo = (CComboBox*)GetDlgItem (IDC_DisplayUnits);
+  aCombo->ResetContent();
+  aCombo->AddString ("No");
+  aCombo->AddString ("deg");
+  aCombo->AddString ("rad");
+  aCombo->SetCurSel (1);
+}
+
+//=======================================================================
+//function : IsUnitsDisplayed
+//purpose  : returns true if the units is to be displayed
+//=======================================================================
+
+const Standard_Boolean CDimensionDlg::IsUnitsDisplayed() const
+{
+  CString aStr;
+  GetDlgItem (IDC_DisplayUnits)->GetWindowTextA (aStr);
+  return !aStr.IsEmpty() && aStr != "No";
+}
+
+//=======================================================================
+//function : GetUnits
+//purpose  : returns display quantity units for current dimension
+//=======================================================================
+
+const TCollection_AsciiString CDimensionDlg::GetUnits() const
+{
+  if (!IsUnitsDisplayed())
+    return TCollection_AsciiString();
+  CString aStr;
+  GetDlgItem (IDC_DisplayUnits)->GetWindowTextA (aStr);
+  Standard_CString aChars = (LPCSTR)aStr;
+  return TCollection_AsciiString (aChars);
+}
+
+//=======================================================================
+//function : OnBnClickedDimensionColor
+//purpose  : returns display quantity units for current dimension
+//=======================================================================
+
+void CDimensionDlg::OnBnClickedDimensionColor()
+{
+  Standard_Real aR;
+  Standard_Real aG;
+  Standard_Real aB;
+  myDimensionColor.Values (aR,aG,aB, Quantity_TOC_RGB);
+  COLORREF aColor = RGB (aR*255, aG*255, aB*255);
+
+  CColorDialog aDlgColor (aColor);
+  if (aDlgColor.DoModal() == IDOK)
+  {
+    aColor = aDlgColor.GetColor();
+    aR = GetRValue(aColor) / 255.0;
+    aG = GetGValue(aColor) / 255.0;
+    aB = GetBValue(aColor) / 255.0;
+    myDimensionColor = Quantity_Color (aR, aG, aB, Quantity_TOC_RGB);
+  }
+}
+
+//=======================================================================
+//function : GetDimensionColor
+//purpose  : returns current dimension color
+//=======================================================================
+
+const Quantity_Color CDimensionDlg::GetDimensionColor() const
+{
+  return myDimensionColor;
+}
diff --git a/samples/mfc/standard/Common/DimensionDlg.h b/samples/mfc/standard/Common/DimensionDlg.h
new file mode 100644 (file)
index 0000000..5a5e479
--- /dev/null
@@ -0,0 +1,79 @@
+#pragma once
+
+// DimensionDlg dialog
+
+#include <stdafx.h>
+
+#include "res\OCC_Resource.h"
+#include <Standard_Macro.hxx>
+#include <AIS_InteractiveContext.hxx>
+#include <TCollection_AsciiString.hxx>
+#include <Quantity_Color.hxx>
+
+class CDimensionDlg : public CDialog
+{
+public:
+  /// Construction & termination
+  CDimensionDlg (CWnd* pParent = NULL);  // standard constructor
+  CDimensionDlg (Handle(AIS_InteractiveContext) &theAISContext,
+                 CWnd* pParent = NULL);
+  virtual ~CDimensionDlg();
+
+  // Methods for data operation
+  void SetContext (const Handle(AIS_InteractiveContext) theContext);
+  void SetTextModeControlsVisible (bool isVisible);
+  void UpdateUnitsListForLength();
+  void UpdateUnitsListForAngle();
+  void Empty();
+  void DeactivateAllStandardModes();
+  void UpdateStandardModeForAngle ();
+  void UpdateStandardModeForLength ();
+  void UpdateStandardMode ();
+  const Standard_Real GetFlyout () const;
+  const Standard_Boolean GetTextType() const;
+  const Standard_Real GetFontHeight() const;
+  const Standard_Boolean IsText3dShaded() const;
+  const Standard_Boolean IsUnitsDisplayed() const;
+  const TCollection_AsciiString GetUnits() const;
+  const Quantity_Color GetDimensionColor() const;
+
+  // Dialog Data
+  enum { IDD = IDD_Dimension };
+  // Initialization of dialog
+protected:
+  virtual BOOL OnInitDialog();
+  virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
+
+  DECLARE_MESSAGE_MAP()
+
+  //Attributes
+private:
+  Handle (AIS_InteractiveContext) myAISContext;
+  int mySelectedDimType;
+  int myFontSize;
+  Quantity_Color myDimensionColor;
+  CTabCtrl *myLengthParams;
+  CTabCtrl *myAngleParams;
+  CTabCtrl *myRadiusParams;
+  CTabCtrl *myDiameterParams;
+
+  void CreateLengthParamsTab();
+  void CreateAngleParamsTab();
+  void CreateRadiusParamsTab();
+  void CreateDiameterParamsTab();
+
+public:
+  afx_msg void OnBnClickedOk();
+  afx_msg void OnBnClickedDimLength();
+  afx_msg void OnBnClickedDimAngle();
+  afx_msg void OnBnClickedDimRadius();
+  afx_msg void OnTcnSelChangeLengthTab(NMHDR *pNMHDR, LRESULT *pResult);
+  afx_msg void OnTcnSelChangingLengthTab(NMHDR *pNMHDR, LRESULT *pResult);
+  afx_msg void OnDestroy();
+  afx_msg void OnTcnSelChangeAngleTab(NMHDR *pNMHDR, LRESULT *pResult);
+  afx_msg void OnTcnSelChangingAngleTab(NMHDR *pNMHDR, LRESULT *pResult);
+  afx_msg void OnBnClickedDimDiameter();
+  afx_msg void OnBnClicked2dText();
+  afx_msg void OnBnClicked3dText();
+  afx_msg void OnBnClickedDimensionColor();
+};
diff --git a/samples/mfc/standard/Common/LengthParamsEdgePage.cpp b/samples/mfc/standard/Common/LengthParamsEdgePage.cpp
new file mode 100644 (file)
index 0000000..1fac26f
--- /dev/null
@@ -0,0 +1,112 @@
+// LengthParamsEdgePage.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "LengthParamsEdgePage.h"
+#include "DimensionDlg.h"
+
+#include <Standard_Macro.hxx>
+#include <AIS_InteractiveContext.hxx>
+#include <AIS_LocalContext.hxx>
+#include <AIS_LengthDimension.hxx>
+#include <GC_MakePlane.hxx>
+#include <TopExp.hxx>
+
+// CLengthParamsEdgePage dialog
+
+IMPLEMENT_DYNAMIC(CLengthParamsEdgePage, CDialog)
+
+//=======================================================================
+//function : CLengthParamsEdgePage
+//purpose  :
+//=======================================================================
+
+CLengthParamsEdgePage::CLengthParamsEdgePage (Handle(AIS_InteractiveContext) theContext,CWnd* pParent /*=NULL*/)
+: CDialog (CLengthParamsEdgePage::IDD, pParent)
+{
+  myAISContext = theContext;
+}
+
+//=======================================================================
+//function : ~CLengthParamsEdgePage
+//purpose  :
+//=======================================================================
+
+CLengthParamsEdgePage::~CLengthParamsEdgePage()
+{
+}
+
+//=======================================================================
+//function : DoDataExchange
+//purpose  :
+//=======================================================================
+
+void CLengthParamsEdgePage::DoDataExchange (CDataExchange* pDX)
+{
+  CDialog::DoDataExchange(pDX);
+}
+
+BEGIN_MESSAGE_MAP (CLengthParamsEdgePage, CDialog)
+  ON_BN_CLICKED (IDC_ChooseEdgeBtn, &CLengthParamsEdgePage::OnBnClickedChooseEdgeBtn)
+END_MESSAGE_MAP()
+
+//=======================================================================
+//function : GetButton
+//purpose  :
+//=======================================================================
+
+CButton* CLengthParamsEdgePage::GetButton()
+{
+  return (CButton*)GetDlgItem (IDC_ChooseEdgeBtn);
+}
+
+//=======================================================================
+//function : OnBnClickedChooseEdgeBtn
+//purpose  :
+//=======================================================================
+
+void CLengthParamsEdgePage::OnBnClickedChooseEdgeBtn()
+{
+  myAISContext->LocalContext()->InitSelected();
+
+  if (!myAISContext->LocalContext()->MoreSelected())
+  {
+    AfxMessageBox ( _T("Choose the vertex and press the button again"), MB_ICONINFORMATION | MB_OK);
+    return;
+  }
+
+  TopoDS_Edge anEdge = TopoDS::Edge(myAISContext->LocalContext()->SelectedShape());
+  myAISContext->LocalContext()->ClearSelected();
+  TopoDS_Vertex aFirstVertex, aSecondVertex;
+  TopExp::Vertices (anEdge, aFirstVertex, aSecondVertex);
+
+  gp_Pnt aP1=BRep_Tool::Pnt (aFirstVertex);
+  gp_Pnt aP2=BRep_Tool::Pnt (aSecondVertex);
+  gp_Pnt aP3(aP2.X()+10, aP2.Y()+10, aP2.Z()+10);
+
+  GC_MakePlane aMkPlane (aP1,aP2,aP3);
+  Handle(Geom_Plane) aPlane = aMkPlane.Value ();
+
+  CDimensionDlg *aDimDlg = (CDimensionDlg*)(GetParentOwner());
+
+  Handle(AIS_LengthDimension) aLenDim = new AIS_LengthDimension (anEdge, aPlane->Pln());
+  Handle(Prs3d_DimensionAspect) anAspect = new Prs3d_DimensionAspect();
+  anAspect->MakeArrows3d (Standard_False);
+  anAspect->MakeText3d (aDimDlg->GetTextType());
+  anAspect->TextAspect()->SetHeight (aDimDlg->GetFontHeight());
+  anAspect->MakeTextShaded (aDimDlg->IsText3dShaded());
+  anAspect->SetCommonColor (aDimDlg->GetDimensionColor());
+  aLenDim->MakeUnitsDisplayed (aDimDlg->IsUnitsDisplayed());
+  if (aLenDim->IsUnitsDisplayed())
+  {
+    aLenDim->SetDisplayUnits (aDimDlg->GetUnits());
+  }
+
+  aLenDim->SetDimensionAspect (anAspect);
+  aLenDim->SetFlyout (aDimDlg->GetFlyout());
+
+  myAISContext->CloseAllContexts();
+  myAISContext->Display (aLenDim);
+  myAISContext->OpenLocalContext();
+  myAISContext->ActivateStandardMode(TopAbs_EDGE);
+}
diff --git a/samples/mfc/standard/Common/LengthParamsEdgePage.h b/samples/mfc/standard/Common/LengthParamsEdgePage.h
new file mode 100644 (file)
index 0000000..1594ba5
--- /dev/null
@@ -0,0 +1,29 @@
+#pragma once
+
+#include "res\OCC_Resource.h"
+#include <Standard_Macro.hxx>
+#include <AIS_InteractiveContext.hxx>
+
+// CLengthParamsEdgePage dialog
+
+class CLengthParamsEdgePage : public CDialog
+{
+  DECLARE_DYNAMIC(CLengthParamsEdgePage)
+
+public:
+  CLengthParamsEdgePage(Handle(AIS_InteractiveContext) theAISContext,CWnd* pParent = NULL);   // standard constructor
+  virtual ~CLengthParamsEdgePage();
+  CButton* GetButton();
+
+// Dialog Data
+  enum { IDD = IDD_LengthParamsEdgePage };
+
+protected:
+  virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
+
+  DECLARE_MESSAGE_MAP()
+private:
+  Handle(AIS_InteractiveContext) myAISContext;
+public:
+  afx_msg void OnBnClickedChooseEdgeBtn();
+};
diff --git a/samples/mfc/standard/Common/LengthParamsEdgesPage.cpp b/samples/mfc/standard/Common/LengthParamsEdgesPage.cpp
new file mode 100644 (file)
index 0000000..1c126b0
--- /dev/null
@@ -0,0 +1,163 @@
+// LenghtParamsEdgesPage.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "LengthParamsEdgesPage.h"
+#include "DimensionDlg.h"
+#include <AIS_InteractiveContext.hxx>
+#include <AIS_LocalContext.hxx>
+#include <AIS_LengthDimension.hxx>
+#include <AIS_AngleDimension.hxx>
+#include <GC_MakePlane.hxx>
+// CLengthParamsEdgesPage dialog
+
+//=======================================================================
+//function : CLengthParamsEdgesPage
+//purpose  :
+//=======================================================================
+
+CLengthParamsEdgesPage::CLengthParamsEdgesPage (Handle(AIS_InteractiveContext) theAISContext,
+                                                bool isAngleDimension /*= false*/,
+                                                CWnd* pParent /*=NULL*/)
+: CDialog(CLengthParamsEdgesPage::IDD, pParent)
+{
+  myAISContext = theAISContext;
+  myIsAngleDimension = isAngleDimension;
+}
+
+//=======================================================================
+//function : ~CLengthParamsEdgesPage
+//purpose  :
+//=======================================================================
+
+CLengthParamsEdgesPage::~CLengthParamsEdgesPage()
+{
+}
+
+//=======================================================================
+//function : DoDataExchange
+//purpose  :
+//=======================================================================
+
+void CLengthParamsEdgesPage::DoDataExchange(CDataExchange* pDX)
+{
+  CDialog::DoDataExchange(pDX);
+}
+
+
+BEGIN_MESSAGE_MAP(CLengthParamsEdgesPage, CDialog)
+  ON_BN_CLICKED(IDC_BUTTON1, &CLengthParamsEdgesPage::OnBnClickedEdge1Btn)
+  ON_BN_CLICKED(IDC_BUTTON3, &CLengthParamsEdgesPage::OnBnClickedEdge2Btn)
+END_MESSAGE_MAP()
+
+
+//=======================================================================
+//function : OnBnClickedEdge1Btn
+//purpose  :
+//=======================================================================
+
+void CLengthParamsEdgesPage::OnBnClickedEdge1Btn()
+{
+  // Open local context and choose the edge for length dimensions
+  if (!myAISContext->HasOpenedContext())
+  {
+    myAISContext->OpenLocalContext();
+    myAISContext->ActivateStandardMode (TopAbs_EDGE);
+    AfxMessageBox (_T("Local context was not opened. Choose the edge and press the button again"),
+                     MB_ICONINFORMATION | MB_OK);
+    return;
+  }
+
+  // Now it's ok, local context is opened and edge selection mode is activated
+  // Check if some edge is selected
+  myAISContext->LocalContext()->InitSelected();
+  if (!myAISContext->LocalContext()->MoreSelected())
+  {
+    AfxMessageBox(_T("Choose the edge and press the button again"),
+                    MB_ICONINFORMATION | MB_OK);
+    return;
+  }
+
+  myFirstEdge = TopoDS::Edge (myAISContext->LocalContext()->SelectedShape());
+  myAISContext->LocalContext()->ClearSelected();
+}
+
+//=======================================================================
+//function : OnBnClickedEdge2Btn
+//purpose  :
+//=======================================================================
+
+void CLengthParamsEdgesPage::OnBnClickedEdge2Btn()
+{
+  myAISContext->LocalContext()->InitSelected();
+  if (!myAISContext->LocalContext()->MoreSelected())
+  {
+    AfxMessageBox (_T("Choose the edge and press the button again"),
+       MB_ICONINFORMATION | MB_OK);
+    return;
+  }
+
+  mySecondEdge = TopoDS::Edge (myAISContext->LocalContext()->SelectedShape());
+  myAISContext->LocalContext()->ClearSelected();
+
+  // Build plane through three points
+  BRepAdaptor_Curve aCurve1 (myFirstEdge);
+  BRepAdaptor_Curve aCurve2 (mySecondEdge);
+
+  gp_Pnt aP1=aCurve1.Value (0.1);
+  gp_Pnt aP2=aCurve1.Value (0.9);
+  gp_Pnt aP3=aCurve2.Value (0.5);
+
+  GC_MakePlane aMkPlane (aP1,aP2,aP3);
+
+  Handle(Geom_Plane) aPlane = aMkPlane.Value();
+
+  CDimensionDlg *aDimDlg = (CDimensionDlg*)(GetParentOwner());
+
+  myAISContext->CloseAllContexts();
+
+  Handle(Prs3d_DimensionAspect) anAspect = new Prs3d_DimensionAspect();
+  anAspect->MakeArrows3d (Standard_False);
+  anAspect->MakeText3d (aDimDlg->GetTextType());
+  anAspect->TextAspect()->SetHeight (aDimDlg->GetFontHeight());
+  anAspect->MakeTextShaded (aDimDlg->IsText3dShaded());
+  anAspect->SetCommonColor (aDimDlg->GetDimensionColor());
+  if (myIsAngleDimension)
+  {
+    // Build an angle dimension between two non-parallel edges
+    Handle(AIS_AngleDimension) anAngleDim = new AIS_AngleDimension (myFirstEdge, mySecondEdge);
+    anAngleDim->SetDimensionAspect (anAspect);
+    anAngleDim->MakeUnitsDisplayed (aDimDlg->IsUnitsDisplayed());
+    if (anAngleDim->IsUnitsDisplayed())
+    {
+      anAngleDim->SetDisplayUnits (aDimDlg->GetUnits ());
+      if ((anAngleDim->DisplayUnits().IsEqual (TCollection_AsciiString ("deg"))))
+      {
+        anAngleDim->MakeUnitsDisplayed (Standard_False);
+      }
+      else
+      {
+        anAngleDim->SetDisplaySpecialSymbol (AIS_DSS_No);
+      }
+    }
+
+    anAngleDim->SetFlyout (aDimDlg->GetFlyout());
+    myAISContext->Display (anAngleDim);
+  }
+  else
+  {
+    Handle(AIS_LengthDimension) aLenDim = new AIS_LengthDimension (myFirstEdge, mySecondEdge, aPlane->Pln());
+    aLenDim->SetDimensionAspect (anAspect);
+    aLenDim->MakeUnitsDisplayed (aDimDlg->IsUnitsDisplayed());
+    if (aLenDim->IsUnitsDisplayed())
+    {
+      aLenDim->SetFlyout (aDimDlg->GetFlyout());
+      aLenDim->SetDisplayUnits (aDimDlg->GetUnits());
+    }
+
+    myAISContext->Display (aLenDim);
+  }
+
+  myAISContext->OpenLocalContext();
+  myAISContext->ActivateStandardMode (TopAbs_EDGE);
+}
diff --git a/samples/mfc/standard/Common/LengthParamsEdgesPage.h b/samples/mfc/standard/Common/LengthParamsEdgesPage.h
new file mode 100644 (file)
index 0000000..aa9b37b
--- /dev/null
@@ -0,0 +1,30 @@
+#pragma once
+
+#include "res\OCC_Resource.h"
+
+// CLenghtParamsEdgesPage dialog
+
+class CLengthParamsEdgesPage : public CDialog
+{
+private:
+  Handle(AIS_InteractiveContext) myAISContext;
+  bool myIsAngleDimension;
+  TopoDS_Edge myFirstEdge;
+  TopoDS_Edge mySecondEdge;
+public:
+  CLengthParamsEdgesPage (Handle(AIS_InteractiveContext) theAISContext,
+                          bool isAngleDimension = false,
+                          CWnd* pParent = NULL);   // standard constructor
+  virtual ~CLengthParamsEdgesPage();
+
+// Dialog Data
+  enum { IDD = IDD_LengthParamsEdgesPage };
+
+protected:
+  virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
+
+  DECLARE_MESSAGE_MAP()
+public:
+  afx_msg void OnBnClickedEdge1Btn();
+  afx_msg void OnBnClickedEdge2Btn();
+};
diff --git a/samples/mfc/standard/Common/LengthParamsVerticesPage.cpp b/samples/mfc/standard/Common/LengthParamsVerticesPage.cpp
new file mode 100644 (file)
index 0000000..ca51dd7
--- /dev/null
@@ -0,0 +1,153 @@
+// LengthParamsVerticesPage.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "LengthParamsVerticesPage.h"
+#include "DimensionDlg.h"
+#include <Standard_Macro.hxx>
+#include <AIS_InteractiveContext.hxx>
+#include <AIS_LocalContext.hxx>
+#include <AIS_LengthDimension.hxx>
+#include <GC_MakePlane.hxx>
+
+
+// CLengthParamsVerticesPage dialog
+
+IMPLEMENT_DYNAMIC(CLengthParamsVerticesPage, CDialog)
+
+//=======================================================================
+//function : CLengthParamsVerticesPage
+//purpose  :
+//=======================================================================
+
+CLengthParamsVerticesPage::CLengthParamsVerticesPage (Handle(AIS_InteractiveContext) theAISContext, CWnd* pParent /*=NULL*/)
+: CDialog (CLengthParamsVerticesPage::IDD, pParent)
+{
+ myAISContext = theAISContext;
+}
+
+//=======================================================================
+//function : ~CLengthParamsVerticesPage
+//purpose  :
+//=======================================================================
+
+CLengthParamsVerticesPage::~CLengthParamsVerticesPage()
+{
+}
+
+//=======================================================================
+//function : DoDataExchange
+//purpose  :
+//=======================================================================
+
+void CLengthParamsVerticesPage::DoDataExchange (CDataExchange* pDX)
+{
+  CDialog::DoDataExchange (pDX);
+}
+
+
+BEGIN_MESSAGE_MAP(CLengthParamsVerticesPage, CDialog)
+  ON_BN_CLICKED(IDC_BUTTON1, &CLengthParamsVerticesPage::OnBnClickedVertex1Btn)
+  ON_BN_CLICKED(IDC_BUTTON2, &CLengthParamsVerticesPage::OnBnClickedVertex2Btn)
+END_MESSAGE_MAP()
+
+
+//=======================================================================
+//function : OnBnClickedVertex1Btn
+//purpose  :
+//=======================================================================
+
+void CLengthParamsVerticesPage::OnBnClickedVertex1Btn()
+{
+   // Open local context and choose the edge for length dimensions
+  if (!myAISContext->HasOpenedContext())
+  {
+    myAISContext->OpenLocalContext();
+    myAISContext->ActivateStandardMode(TopAbs_VERTEX);
+    AfxMessageBox(_T("Local context was not opened. Choose the vertices and press the button again"),
+                    MB_ICONINFORMATION | MB_OK);
+    return;
+  }
+
+  // Now it's ok, local context is opened and edge selection mode is activated
+  // Check if some edge is selected
+  myAISContext->LocalContext()->InitSelected();
+  if (!myAISContext->LocalContext()->MoreSelected())
+  {
+    AfxMessageBox (_T ("Choose the vertex and press the button again"), MB_ICONINFORMATION | MB_OK);
+    return;
+  }
+
+  myFirstVertex = TopoDS::Vertex (myAISContext->LocalContext()->SelectedShape());
+
+  myAISContext->LocalContext()->ClearSelected();
+}
+
+//=======================================================================
+//function : OnBnClickedVertex2Btn
+//purpose  :
+//=======================================================================
+
+void CLengthParamsVerticesPage::OnBnClickedVertex2Btn()
+{
+  myAISContext->LocalContext()->InitSelected();
+  if (!myAISContext->LocalContext()->MoreSelected())
+  {
+    AfxMessageBox (_T ("Choose the vertex and press the button again"), MB_ICONINFORMATION | MB_OK);
+    return;
+  }
+
+  mySecondVertex = TopoDS::Vertex (myAISContext->LocalContext()->SelectedShape());
+  myAISContext->LocalContext()->ClearSelected();
+
+  //Build dimension here
+  gp_Pnt aP1=BRep_Tool::Pnt (myFirstVertex);
+  gp_Pnt aP2=BRep_Tool::Pnt (mySecondVertex);
+  gp_Pnt aP3 (aP2.X() + 10, aP2.Y() + 10, aP2.Z() + 10);
+
+  GC_MakePlane aMkPlane (aP1,aP2,aP3);
+  Handle(Geom_Plane) aPlane = aMkPlane.Value();
+
+  CDimensionDlg *aDimDlg = (CDimensionDlg*)(this->GetParentOwner());
+
+  Handle(AIS_LengthDimension) aLenDim = new AIS_LengthDimension (aP1, aP2, aPlane->Pln());
+
+  Handle(Prs3d_DimensionAspect) anAspect = new Prs3d_DimensionAspect();
+  anAspect->MakeArrows3d (Standard_False);
+  anAspect->MakeText3d (aDimDlg->GetTextType());
+  anAspect->TextAspect()->SetHeight (aDimDlg->GetFontHeight());
+  anAspect->MakeTextShaded (aDimDlg->IsText3dShaded());
+  aLenDim->MakeUnitsDisplayed (aDimDlg->IsUnitsDisplayed());
+  if (aLenDim->IsUnitsDisplayed ())
+  {
+    aLenDim->SetDisplayUnits (aDimDlg->GetUnits ());
+  }
+
+  aLenDim->SetDimensionAspect (anAspect);
+  aLenDim->SetFlyout (aDimDlg->GetFlyout());
+
+  myAISContext->CloseAllContexts();
+  myAISContext->Display (aLenDim);
+  myAISContext->OpenLocalContext();
+  myAISContext->ActivateStandardMode (TopAbs_VERTEX);
+}
+
+//=======================================================================
+//function : getFirstVertex
+//purpose  :
+//=======================================================================
+
+const TopoDS_Vertex& CLengthParamsVerticesPage::getFirstVertex() const
+{
+  return myFirstVertex;
+}
+
+//=======================================================================
+//function : getSecondVertex
+//purpose  :
+//=======================================================================
+
+const TopoDS_Vertex& CLengthParamsVerticesPage::getSecondVertex() const
+{
+  return mySecondVertex;
+}
diff --git a/samples/mfc/standard/Common/LengthParamsVerticesPage.h b/samples/mfc/standard/Common/LengthParamsVerticesPage.h
new file mode 100644 (file)
index 0000000..315dc32
--- /dev/null
@@ -0,0 +1,29 @@
+#pragma once
+
+#include "res\OCC_Resource.h"
+
+// CLengthParamsVerticesPage dialog
+
+class CLengthParamsVerticesPage : public CDialog
+{
+  DECLARE_DYNAMIC(CLengthParamsVerticesPage)
+
+public:
+  CLengthParamsVerticesPage(Handle(AIS_InteractiveContext) theAISContext,CWnd* pParent = NULL);   // standard constructor
+  virtual ~CLengthParamsVerticesPage();
+  const TopoDS_Vertex& getFirstVertex() const;
+  const TopoDS_Vertex& getSecondVertex() const;
+// Dialog Data
+  enum { IDD = IDD_LengthParamsVerticesPage };
+private:
+  Handle(AIS_InteractiveContext) myAISContext;
+  TopoDS_Vertex myFirstVertex;
+  TopoDS_Vertex mySecondVertex;
+protected:
+  virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
+
+  DECLARE_MESSAGE_MAP()
+public:
+  afx_msg void OnBnClickedVertex1Btn();
+  afx_msg void OnBnClickedVertex2Btn();
+};
index e7246c9..b66e3e7 100755 (executable)
 #include <res\OCC_Resource.h>
 #include "ImportExport/ImportExport.h"
 #include "AISDialogs.h"
+#include <AIS_LocalContext.hxx>
 #include <AIS_ListOfInteractive.hxx>
 #include <AIS_ListIteratorOfListOfInteractive.hxx>
+#include <TColStd_ListIteratorOfListOfInteger.hxx>
+#include <TColStd_ListOfInteger.hxx>
+#include <TopoDS_Shape.hxx>
 
 BEGIN_MESSAGE_MAP(OCC_3dBaseDoc, OCC_BaseDoc)
   //{{AFX_MSG_MAP(OCC_3dBaseDoc)
@@ -34,6 +38,9 @@ BEGIN_MESSAGE_MAP(OCC_3dBaseDoc, OCC_BaseDoc)
   ON_UPDATE_COMMAND_UI(ID_OBJECT_DISPLAYALL, OnUpdateObjectDisplayall)
   ON_COMMAND(ID_OBJECT_REMOVE, OnObjectRemove)
   ON_UPDATE_COMMAND_UI(ID_OBJECT_REMOVE, OnUpdateObjectRemove)
+  ON_COMMAND(ID_OBJECT_DIM, OnObjectAddDimensions)
+  ON_UPDATE_COMMAND_UI(ID_OBJECT_DIM, OnUpdateObjectAddDimensions)
+
   //}}AFX_MSG_MAP
   ON_COMMAND_EX_RANGE(ID_OBJECT_MATERIAL_BRASS,ID_OBJECT_MATERIAL_DEFAULT, OnObjectMaterialRange)
   ON_UPDATE_COMMAND_UI_RANGE(ID_OBJECT_MATERIAL_BRASS,ID_OBJECT_MATERIAL_DEFAULT, OnUpdateObjectMaterialRange)
@@ -45,6 +52,8 @@ END_MESSAGE_MAP()
 //////////////////////////////////////////////////////////////////////
 
 OCC_3dBaseDoc::OCC_3dBaseDoc()
+:myPopupMenuNumber(0),
+ myDimensionDlg()
 {
   AfxInitRichEdit();
 
@@ -55,6 +64,8 @@ OCC_3dBaseDoc::OCC_3dBaseDoc()
   myViewer->SetDefaultLights();
   myViewer->SetLightOn();
   myAISContext = new AIS_InteractiveContext (myViewer);
+  myDimensionDlg.SetContext (myAISContext);
+  myDimensionDlg.Create(CDimensionDlg::IDD, NULL);
 }
 
 //-----------------------------------------------------------------------------------------
@@ -167,17 +178,20 @@ void  OCC_3dBaseDoc::Popup (const Standard_Integer theMouseX,
                             const Standard_Integer theMouseY,
                             const Handle(V3d_View)& theView)
 {
-  Standard_Integer PopupMenuNumber=0;
-  myAISContext->InitCurrent();
-  if (myAISContext->MoreCurrent())
-    PopupMenuNumber=1;
+  // Base check which context menu to call
+  if (!myPopupMenuNumber)
+  {
+    myAISContext->InitCurrent();
+    if (myAISContext->MoreCurrent())
+      myPopupMenuNumber=1;
+  }
 
   CMenu menu;
   VERIFY(menu.LoadMenu(IDR_Popup3D));
-  CMenu* pPopup = menu.GetSubMenu(PopupMenuNumber);
+  CMenu* pPopup = menu.GetSubMenu(myPopupMenuNumber);
 
   ASSERT(pPopup != NULL);
-   if (PopupMenuNumber == 1) // more than 1 object.
+   if (myPopupMenuNumber == 1) // more than 1 object.
   {
     bool OneOrMoreInShading = false;
        for (myAISContext->InitCurrent();myAISContext->MoreCurrent ();myAISContext->NextCurrent ())
@@ -190,8 +204,10 @@ void  OCC_3dBaseDoc::Popup (const Standard_Integer theMouseX,
   Handle(WNT_Window) aWNTWindow=
   Handle(WNT_Window)::DownCast(theView->Window());
   ClientToScreen ( (HWND)(aWNTWindow->HWindow()),&winCoord);
-  pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON , winCoord.x, winCoord.y , 
-                         AfxGetMainWnd());
+  pPopup->TrackPopupMenu (TPM_LEFTALIGN | TPM_RIGHTBUTTON,
+                          winCoord.x,
+                          winCoord.y,
+                          AfxGetMainWnd());
 }
 
 void OCC_3dBaseDoc::Fit()
@@ -392,7 +408,7 @@ void OCC_3dBaseDoc::OnUpdateObjectRemove(CCmdUI* pCmdUI)
   bool OneOrMoreIsDisplayed = false;
   for (myAISContext->InitCurrent();myAISContext->MoreCurrent ();myAISContext->NextCurrent ())
     if (myAISContext->IsDisplayed(myAISContext->Current())) OneOrMoreIsDisplayed=true;
-  pCmdUI->Enable (OneOrMoreIsDisplayed);       
+  pCmdUI->Enable (OneOrMoreIsDisplayed);
 }
 
 void OCC_3dBaseDoc::SetMaterial(Graphic3d_NameOfMaterial Material) 
@@ -401,3 +417,18 @@ void OCC_3dBaseDoc::SetMaterial(Graphic3d_NameOfMaterial Material)
     myAISContext->SetMaterial (myAISContext->Current(),
     (Graphic3d_NameOfMaterial)(Material));
 }
+
+void OCC_3dBaseDoc::OnObjectAddDimensions() 
+{
+  //Add dimentions dialog is opened here
+  myDimensionDlg.ShowWindow(SW_SHOW);
+  myDimensionDlg.UpdateStandardMode ();
+}
+
+void OCC_3dBaseDoc::OnUpdateObjectAddDimensions(CCmdUI* pCmdUI) 
+{
+  // Check if local context is opened
+  //pCmdUI->Enable (myAISContext->HasOpenedContext());
+}
+
+
index 283d8b5..2434cb6 100755 (executable)
 #endif // _MSC_VER > 1000
 
 #include "OCC_BaseDoc.h"
+#include "DimensionDlg.h"
 #include <Standard_Macro.hxx>
 
 class AFX_EXT_CLASS OCC_3dBaseDoc : public OCC_BaseDoc  
 {
+protected:
+  CDimensionDlg myDimensionDlg;
+  int myPopupMenuNumber;
 public:
 
   OCC_3dBaseDoc();
@@ -78,6 +82,9 @@ protected:
   afx_msg void OnUpdateObjectDisplayall(CCmdUI* pCmdUI);
   afx_msg void OnObjectRemove();
   afx_msg void OnUpdateObjectRemove(CCmdUI* pCmdUI);
+  afx_msg void OnObjectAddDimensions();
+  afx_msg void OnUpdateObjectAddDimensions(CCmdUI* pCmdUI);
+
   //}}AFX_MSG
   DECLARE_MESSAGE_MAP()
 };
diff --git a/samples/mfc/standard/Common/RadiusParamsPage.cpp b/samples/mfc/standard/Common/RadiusParamsPage.cpp
new file mode 100644 (file)
index 0000000..c810a16
--- /dev/null
@@ -0,0 +1,133 @@
+
+#include "stdafx.h"
+#include "RadiusParamsPage.h"
+#include "DimensionDlg.h"
+
+#include <AIS_InteractiveContext.hxx>
+#include <AIS_LocalContext.hxx>
+#include <AIS_RadiusDimension.hxx>
+#include <AIS_DiameterDimension.hxx>
+#include <ElCLib.hxx>
+#include <TopoDS_Shape.hxx>
+
+IMPLEMENT_DYNAMIC(CRadiusParamsPage, CDialog)
+
+//=======================================================================
+//function : CRadiusParamsPage
+//purpose  :
+//=======================================================================
+
+CRadiusParamsPage::CRadiusParamsPage (const Handle(AIS_InteractiveContext)& theAISContext,
+                                      const Standard_Boolean isDiameterDimension /* =Standard_False*/,
+                                      CWnd* pParent /*=NULL*/)
+ : CDialog (CRadiusParamsPage::IDD, pParent)
+{
+  myAISContext = theAISContext;
+  myIsDiameterDimension = isDiameterDimension;
+}
+
+//=======================================================================
+//function : ~CRadiusParamsPage
+//purpose  :
+//=======================================================================
+
+CRadiusParamsPage::~CRadiusParamsPage()
+{
+}
+
+//=======================================================================
+//function : DoDataExchange
+//purpose  :
+//=======================================================================
+
+void CRadiusParamsPage::DoDataExchange(CDataExchange* pDX)
+{
+  CDialog::DoDataExchange(pDX);
+}
+
+
+BEGIN_MESSAGE_MAP(CRadiusParamsPage, CDialog)
+  ON_BN_CLICKED(IDC_BUTTON1, &CRadiusParamsPage::OnBnClickedObjectBtn)
+END_MESSAGE_MAP()
+
+//=======================================================================
+//function : OnBnClickedObjectBtn
+//purpose  :
+//=======================================================================
+
+void CRadiusParamsPage::OnBnClickedObjectBtn()
+{
+  //Build dimension here
+  myAISContext->LocalContext()->InitSelected();
+  if (!myAISContext->LocalContext()->MoreSelected())
+  {
+    AfxMessageBox (_T ("Choose the edge and press the button again"), MB_ICONINFORMATION | MB_OK);
+    return;
+  }
+
+  gp_Circ aCircle;
+  Standard_Boolean isAttachPoint = Standard_False;
+  Standard_Real aFirstPar = 0, aLastPar = 0;
+
+  TopoDS_Shape aSelShape = myAISContext->LocalContext()->SelectedShape();
+  if (aSelShape.ShapeType() != TopAbs_EDGE &&
+      aSelShape.ShapeType() != TopAbs_FACE &&
+      aSelShape.ShapeType() != TopAbs_WIRE)
+    return;
+
+  if (aSelShape.ShapeType() == TopAbs_EDGE)
+  {
+    BRepAdaptor_Curve aCurve (TopoDS::Edge (aSelShape));
+    if (aCurve.GetType() != GeomAbs_Circle)
+    {
+      return;
+    }
+
+    aCircle = aCurve.Circle();
+    if (aCurve.FirstParameter() != 0 && aCurve.LastParameter() != M_PI * 2)
+    {
+      isAttachPoint = Standard_True;
+      aFirstPar = aCurve.FirstParameter();
+      aLastPar = aCurve.LastParameter();
+    }
+  }
+
+  myAISContext->LocalContext()->ClearSelected();
+  CDimensionDlg *aDimDlg = (CDimensionDlg*)(this->GetParentOwner());
+  // Try to create dimension if it is possible
+  Handle(AIS_Dimension) aDim;
+  if (myIsDiameterDimension)
+  {
+    aDim = isAttachPoint ? new AIS_DiameterDimension (aCircle, ElCLib::Value ((aFirstPar + aLastPar) / 2.0, aCircle))
+                         : new AIS_DiameterDimension (aCircle);
+    Handle(AIS_DiameterDimension)::DownCast(aDim)->SetFlyout (aDimDlg->GetFlyout());
+  }
+  else
+  {
+    aDim = isAttachPoint ? new AIS_RadiusDimension (aCircle, ElCLib::Value ((aFirstPar + aLastPar) / 2.0, aCircle))
+                         : new AIS_RadiusDimension (aCircle);
+    Handle(AIS_RadiusDimension)::DownCast(aDim)->SetFlyout (aDimDlg->GetFlyout());
+  }
+
+  Handle(Prs3d_DimensionAspect) anAspect = new Prs3d_DimensionAspect();
+  anAspect->MakeArrows3d (Standard_False);
+  anAspect->MakeText3d (aDimDlg->GetTextType());
+  anAspect->TextAspect()->SetHeight (aDimDlg->GetFontHeight());
+  anAspect->MakeTextShaded (aDimDlg->IsText3dShaded());
+  anAspect->SetCommonColor (aDimDlg->GetDimensionColor());
+  aDim->MakeUnitsDisplayed (aDimDlg->IsUnitsDisplayed());
+  if (aDim->IsUnitsDisplayed())
+  {
+    aDim->SetDisplayUnits (aDimDlg->GetUnits());
+  }
+
+  aDim->SetDimensionAspect (anAspect);
+
+  // Display dimension in the neutral point
+  myAISContext->CloseAllContexts();
+
+  myAISContext->Display (aDim);
+
+  myAISContext->OpenLocalContext();
+  myAISContext->ActivateStandardMode (TopAbs_EDGE);
+}
diff --git a/samples/mfc/standard/Common/RadiusParamsPage.h b/samples/mfc/standard/Common/RadiusParamsPage.h
new file mode 100644 (file)
index 0000000..0c28f42
--- /dev/null
@@ -0,0 +1,27 @@
+#pragma once
+
+#include "res\OCC_Resource.h"
+// CRadiusParamsPage dialog
+
+class CRadiusParamsPage : public CDialog
+{
+  DECLARE_DYNAMIC(CRadiusParamsPage)
+private:
+  Handle(AIS_InteractiveContext) myAISContext;
+  Standard_Boolean myIsDiameterDimension;
+public:
+  CRadiusParamsPage(const Handle(AIS_InteractiveContext)& theAISContext,
+                    const Standard_Boolean isDiameterDimension = Standard_False,
+                    CWnd* pParent = NULL);   // standard constructor
+  virtual ~CRadiusParamsPage();
+
+// Dialog Data
+  enum { IDD = IDD_RadiusParamsPage };
+
+protected:
+  virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
+
+  DECLARE_MESSAGE_MAP()
+public:
+  afx_msg void OnBnClickedObjectBtn();
+};
index e509bd0..edb1f37 100755 (executable)
Binary files a/samples/mfc/standard/Common/res/AIS_TB.bmp and b/samples/mfc/standard/Common/res/AIS_TB.bmp differ
index 82b47ae..f404b32 100755 (executable)
Binary files a/samples/mfc/standard/Common/res/OCC_Resource.aps and b/samples/mfc/standard/Common/res/OCC_Resource.aps differ
index 8d82a08..3e31ed7 100755 (executable)
@@ -3,7 +3,13 @@
 // Used by OCC_Resource.rc
 //
 #define IDR_POPUP                       116
+#define IDD_Dimension                   119
+#define IDD_LengthParamsEdgePage        122
+#define IDD_LengthParamsVerticesPage    123
+#define IDD_LengthParamsEdgesPage       125
+#define IDD_AngleParamsVerticesPage     126
 #define IDR_MAINFRAME                   128
+#define IDD_RadiusParamsPage            128
 #define IDR_2DTYPE                      129
 #define IDR_3DTYPE                      131
 #define ID_FILE_EXPORT_IMAGE            132
 #define IDD_COLORMESH                   552
 #define IDB_coloredmesh                 554
 #define IDC_RICHEDIT_ResultDialog       1001
-#define IDC_EDIT1                       1004
-#define IDC_README                      1005
+#define IDC_ResultNameEdit              1003
+#define IDC_README                      1004
+#define IDC_DimensionGroupbox           1005
+#define IDD_DIMENSIONDLG                1006
+#define IDC_TextParamGroupbox           1007
+#define IDC_DimensionParametersGroupbox 1010
+#define IDC_TAB1                        1011
+#define IDC_LengthTab                   1014
+#define IDC_AngleTab                    1015
+#define IDC_BUTTON1                     1016
+#define IDC_XPOS                        1017
+#define IDC_BUTTON2                     1018
+#define IDC_BUTTON3                     1019
+#define IDC_YPOS                        1020
+#define IDC_BUTTON4                     1021
+#define IDC_RadiusTab                   1022
+#define IDC_ZPOS                        1023
+#define IDC_ChooseEdgeBtn               1025
+#define IDC_ChooseEdgeEdit              1026
+#define IDC_Flyout                      1028
+#define IDC_DiameterTab                 1031
+#define IDC_DimLength                   1032
+#define IDC_DimAngle                    1033
+#define IDC_DimRadius                   1034
+#define IDC_DimDiameter                 1035
+#define IDC_2DText                      1036
+#define IDC_3DText                      1037
+#define IDC_FontSize                    1038
+#define IDC_FontSizeStatic              1039
+#define IDC_FlyoutStatic                1044
+#define IDC_DisplayUnits                1045
+#define IDC_DisplayUnitsStatic          1046
+#define IDC_TextDisplayMode             1047
+#define IDC_TextDisplayModeStatic       1048
+#define IDC_DimensionColor              1049
 #define ID_WINDOW_NEW3D                 1151
 #define ID_OBJECT_DISPLAYALL            1201
 #define ID_OBJECT_MATERIAL              1205
 #define ID_BUTTONTop                    40016
 #define ID_BUTTON40017                  40017
 #define ID_BUTTON40033                  40033
+#define ID_OBJECT_DIMENSIONS            40035
+#define ID_OBJECT_DIM                   40036
+#define ID_LOCALCONTEXT_ADDDIMENSION    40037
 #define ID_FILE_IMPORT_CSFDB            40100
 #define ID_FILE_IMPORT_BREP             40101
 #define ID_FILE_IMPORT_STEP             40102
 // 
 #ifdef APSTUDIO_INVOKED
 #ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE        119
-#define _APS_NEXT_COMMAND_VALUE         40034
-#define _APS_NEXT_CONTROL_VALUE         1006
+#define _APS_NEXT_RESOURCE_VALUE        131
+#define _APS_NEXT_COMMAND_VALUE         40038
+#define _APS_NEXT_CONTROL_VALUE         1052
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif
index 04fe07f..c6951ea 100755 (executable)
@@ -73,6 +73,52 @@ IDB_coloredmesh         BITMAP                  "coloredm.bmp"
 // Dialog
 //
 
+IDD_RadiusParamsPage DIALOGEX 0, 0, 121, 46
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+    PUSHBUTTON      "Click to set up selected circle or arc",IDC_BUTTON1,26,10,70,25,BS_MULTILINE
+END
+
+IDD_AngleParamsVerticesPage DIALOGEX 0, 0, 126, 69
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+    PUSHBUTTON      "Set up selected vertex",IDC_BUTTON1,39,7,83,18,BS_MULTILINE
+    LTEXT           "Vertex1",IDC_STATIC,10,12,26,8
+    PUSHBUTTON      "Set up selected vertex",IDC_BUTTON3,39,26,83,17
+    LTEXT           "Vertex2",IDC_STATIC,9,30,26,8
+    PUSHBUTTON      "Set up selected vertex",IDC_BUTTON4,39,44,83,18
+    LTEXT           "Vertex3",IDC_STATIC,9,47,26,8
+END
+
+IDD_LengthParamsEdgePage DIALOGEX 0, 0, 70, 35
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+    PUSHBUTTON      "Click to set up selected edge",IDC_ChooseEdgeBtn,1,1,66,30,BS_MULTILINE
+END
+
+IDD_LengthParamsVerticesPage DIALOGEX 0, 0, 135, 55
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+    LTEXT           "Vertex1",IDC_STATIC,7,11,26,8
+    LTEXT           "Vertex2",IDC_STATIC,7,35,26,8
+    PUSHBUTTON      "Click to set up selected vertex",IDC_BUTTON1,39,4,74,21,BS_MULTILINE
+    PUSHBUTTON      "Click to set up selected vertex",IDC_BUTTON2,39,31,74,20,BS_MULTILINE
+END
+
+IDD_LengthParamsEdgesPage DIALOGEX 0, 0, 128, 60
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+    PUSHBUTTON      "Click to set up selected edge",IDC_BUTTON1,33,1,82,26,BS_MULTILINE
+    PUSHBUTTON      "Click to set up selected edge",IDC_BUTTON3,34,30,81,26,BS_MULTILINE
+    LTEXT           "Edge1",IDC_STATIC,6,12,21,8
+    LTEXT           "Edge2",IDC_STATIC,6,33,21,8
+END
+
 IDD_OCC_ABOUTBOX DIALOGEX 34, 22, 284, 257
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "About"
@@ -90,7 +136,7 @@ IDD_ResultDialog DIALOG  0, 0, 212, 202
 STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
 FONT 8, "MS Sans Serif"
 BEGIN
-    CONTROL         "",IDC_RICHEDIT_ResultDialog,"RICHEDIT",TCS_HOTTRACK | TCS_VERTICAL | TCS_RAGGEDRIGHT | TCS_MULTISELECT | WS_BORDER | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP,0,10,210,160
+    CONTROL         "",IDC_RICHEDIT_ResultDialog,"RICHEDIT",TCS_HOTTRACK | TCS_VERTICAL | TCS_RAGGEDRIGHT | TCS_MULTISELECT | WS_BORDER | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP,2,9,207,162
     PUSHBUTTON      "Copy selection to clipboard",IDC_CopySelectionToClipboard,5,176,100,15
     PUSHBUTTON      "Copy all to clipboard",IDC_CopyAllToClipboard,107,176,100,15
 END
@@ -204,6 +250,37 @@ BEGIN
     GROUPBOX        "",IDC_STATIC,115,86,8,73
 END
 
+IDD_Dimension DIALOGEX 0, 0, 236, 337
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Add dimension"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+    DEFPUSHBUTTON   "OK",IDOK,97,311,50,14
+    GROUPBOX        "Dimension",IDC_DimensionGroupbox,8,9,64,85
+    CONTROL         "",IDC_LengthTab,"SysTabControl32",0x0,11,205,194,95
+    CONTROL         "",IDC_AngleTab,"SysTabControl32",NOT WS_VISIBLE,10,205,193,94
+    CONTROL         "",IDC_RadiusTab,"SysTabControl32",0x0,10,205,193,93
+    GROUPBOX        "Dimension parameters",IDC_DimensionParametersGroupbox,9,103,209,84,WS_GROUP
+    CONTROL         "",IDC_DiameterTab,"SysTabControl32",0x0,10,205,194,92
+    CONTROL         "Length",IDC_DimLength,"Button",BS_AUTORADIOBUTTON | WS_GROUP,20,26,38,10
+    CONTROL         "Angle",IDC_DimAngle,"Button",BS_AUTORADIOBUTTON,20,38,34,10
+    CONTROL         "Radius",IDC_DimRadius,"Button",BS_AUTORADIOBUTTON,20,50,37,10
+    CONTROL         "Diameter",IDC_DimDiameter,"Button",BS_AUTORADIOBUTTON,20,63,45,10
+    GROUPBOX        "Text parameters",IDC_TextParamGroupbox,80,9,139,84
+    CONTROL         "2D Text",IDC_2DText,"Button",BS_AUTORADIOBUTTON | WS_GROUP,162,20,41,10
+    CONTROL         "3D Text",IDC_3DText,"Button",BS_AUTORADIOBUTTON,162,33,41,10
+    LTEXT           "Text type:",IDC_STATIC,86,22,47,8
+    LTEXT           "Font Size:",IDC_FontSizeStatic,87,51,33,8
+    COMBOBOX        IDC_FontSize,157,51,48,57,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    LTEXT           "Flyout value",IDC_FlyoutStatic,25,117,40,8
+    LTEXT           "Display units",IDC_DisplayUnitsStatic,25,138,41,8
+    COMBOBOX        IDC_DisplayUnits,105,138,64,59,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
+    LTEXT           "Text display mode:",IDC_TextDisplayModeStatic,86,74,62,8
+    COMBOBOX        IDC_TextDisplayMode,157,71,48,58,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    PUSHBUTTON      "Change dimension color",IDC_DimensionColor,105,156,63,24,BS_MULTILINE
+    CONTROL         "",IDC_Flyout,"msctls_trackbar32",TBS_TOP | TBS_TOOLTIPS | WS_TABSTOP,73,112,100,20
+END
+
 
 /////////////////////////////////////////////////////////////////////////////
 //
@@ -275,6 +352,7 @@ BEGIN
     BUTTON      ID_OBJECT_DISPLAYALL
     SEPARATOR
     BUTTON      ID_OBJECT_REMOVE
+    BUTTON      ID_OBJECT_DIM
 END
 
 
@@ -352,6 +430,29 @@ END
 #ifdef APSTUDIO_INVOKED
 GUIDELINES DESIGNINFO 
 BEGIN
+    IDD_RadiusParamsPage, DIALOG
+    BEGIN
+        RIGHTMARGIN, 120
+        BOTTOMMARGIN, 45
+    END
+
+    IDD_AngleParamsVerticesPage, DIALOG
+    BEGIN
+        RIGHTMARGIN, 80
+        BOTTOMMARGIN, 66
+    END
+
+    IDD_LengthParamsVerticesPage, DIALOG
+    BEGIN
+        BOTTOMMARGIN, 51
+    END
+
+    IDD_LengthParamsEdgesPage, DIALOG
+    BEGIN
+        RIGHTMARGIN, 115
+        BOTTOMMARGIN, 58
+    END
+
     IDD_OCC_ABOUTBOX, DIALOG
     BEGIN
         BOTTOMMARGIN, 256
@@ -367,12 +468,50 @@ BEGIN
         RIGHTMARGIN, 67
         BOTTOMMARGIN, 219
     END
+
+    IDD_Dimension, DIALOG
+    BEGIN
+        RIGHTMARGIN, 235
+        BOTTOMMARGIN, 336
+        HORZGUIDE, 336
+    END
 END
 #endif    // APSTUDIO_INVOKED
 
 
 /////////////////////////////////////////////////////////////////////////////
 //
+// Dialog Info
+//
+
+IDD_Dimension DLGINIT
+BEGIN
+    IDC_FontSize, 0x403, 2, 0
+0x0037, 
+    IDC_FontSize, 0x403, 2, 0
+0x0038, 
+    IDC_FontSize, 0x403, 2, 0
+0x0039, 
+    IDC_FontSize, 0x403, 3, 0
+0x3031, "\000" 
+    IDC_FontSize, 0x403, 3, 0
+0x3131, "\000" 
+    IDC_FontSize, 0x403, 3, 0
+0x3231, "\000" 
+    IDC_FontSize, 0x403, 3, 0
+0x3331, "\000" 
+    IDC_FontSize, 0x403, 3, 0
+0x3431, "\000" 
+    IDC_TextDisplayMode, 0x403, 10, 0
+0x6957, 0x6572, 0x7266, 0x6d61, 0x0065, 
+    IDC_TextDisplayMode, 0x403, 9, 0
+0x5320, 0x6168, 0x6964, 0x676e, "\000" 
+    0
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
 // String Table
 //
 
@@ -494,6 +633,12 @@ BEGIN
     ID_OBJECT_WIREFRAME     "Put selection in wireframe\nWireframe"
 END
 
+STRINGTABLE 
+BEGIN
+    ID_OBJECT_DIMENSIONS    "Add dimensions"
+    ID_LOCALCONTEXT_ADDDIMENSION "Add new dimension for selected objetcs"
+END
+
 #endif    // English (U.S.) resources
 /////////////////////////////////////////////////////////////////////////////
 
index 2fe42c8..1b3fc73 100644 (file)
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ClCompile>
+    <ClCompile Include="..\..\..\..\Common\AngleParamsVerticesPage.cpp" />
+    <ClCompile Include="..\..\..\..\Common\DimensionDlg.cpp" />
     <ClCompile Include="..\..\..\..\Common\ImportExport\ImportExport.cpp">
       <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ClCompile>
+    <ClCompile Include="..\..\..\..\Common\LengthParamsEdgePage.cpp" />
+    <ClCompile Include="..\..\..\..\Common\LengthParamsEdgesPage.cpp" />
+    <ClCompile Include="..\..\..\..\Common\LengthParamsVerticesPage.cpp" />
+    <ClCompile Include="..\..\..\..\Common\RadiusParamsPage.cpp" />
     <ClCompile Include="..\..\..\src\mfcsample.cpp">
       <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\..\..\Common\AISDialogs.h" />
+    <ClInclude Include="..\..\..\..\Common\AngleParamsVerticesPage.h" />
+    <ClInclude Include="..\..\..\..\Common\DimensionDlg.h" />
     <ClInclude Include="..\..\..\..\Common\ImportExport\ImportExport.h" />
+    <ClInclude Include="..\..\..\..\Common\LengthParamsEdgePage.h" />
+    <ClInclude Include="..\..\..\..\Common\LengthParamsEdgesPage.h" />
+    <ClInclude Include="..\..\..\..\Common\LengthParamsVerticesPage.h" />
     <ClInclude Include="..\..\..\..\Common\OCC_2dChildFrame.h" />
     <ClInclude Include="..\..\..\..\Common\OCC_2dDoc.h" />
     <ClInclude Include="..\..\..\..\Common\OCC_2dView.h" />
     <ClInclude Include="..\..\..\..\Common\OCC_BaseDoc.h" />
     <ClInclude Include="..\..\..\..\Common\OCC_BaseView.h" />
     <ClInclude Include="..\..\..\..\Common\OCC_MainFrame.h" />
+    <ClInclude Include="..\..\..\..\Common\RadiusParamsPage.h" />
     <ClInclude Include="..\..\..\..\Common\res\OCC_Resource.h" />
     <ClInclude Include="..\..\..\..\Common\ResultDialog.h" />
     <ClInclude Include="..\..\..\..\Common\ImportExport\SaveCSFDBDlg.h" />
index ab0406a..2163d8a 100644 (file)
     <ClCompile Include="..\..\..\..\Common\ISession2D\ISession2D_Shape.cpp">
       <Filter>Source Files\ISession2D-src</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\..\..\Common\DimensionDlg.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\Common\AngleParamsVerticesPage.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\Common\LengthParamsEdgePage.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\Common\LengthParamsEdgesPage.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\Common\LengthParamsVerticesPage.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\Common\RadiusParamsPage.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="..\..\..\..\Common\res\OCC_Resource.rc">
     <ClInclude Include="..\..\..\..\Common\ISession2D\ISession2D_Shape.h">
       <Filter>Header Files\ISession2D-headers</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\..\..\Common\DimensionDlg.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\Common\AngleParamsVerticesPage.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\Common\LengthParamsEdgePage.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\Common\LengthParamsEdgesPage.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\Common\LengthParamsVerticesPage.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\Common\RadiusParamsPage.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\..\..\..\Common\res\2dChildFrameTB.bmp">
index e1d17fe..7bf98fc 100644 (file)
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ClCompile>
+    <ClCompile Include="..\..\..\..\Common\AngleParamsVerticesPage.cpp" />
+    <ClCompile Include="..\..\..\..\Common\DimensionDlg.cpp" />
     <ClCompile Include="..\..\..\..\Common\ImportExport\ImportExport.cpp">
       <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ClCompile>
+    <ClCompile Include="..\..\..\..\Common\LengthParamsEdgePage.cpp" />
+    <ClCompile Include="..\..\..\..\Common\LengthParamsEdgesPage.cpp" />
+    <ClCompile Include="..\..\..\..\Common\LengthParamsVerticesPage.cpp" />
+    <ClCompile Include="..\..\..\..\Common\RadiusParamsPage.cpp" />
     <ClCompile Include="..\..\..\src\mfcsample.cpp">
       <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\..\..\Common\AISDialogs.h" />
+    <ClInclude Include="..\..\..\..\Common\AngleParamsVerticesPage.h" />
+    <ClInclude Include="..\..\..\..\Common\DimensionDlg.h" />
     <ClInclude Include="..\..\..\..\Common\ImportExport\ImportExport.h" />
+    <ClInclude Include="..\..\..\..\Common\LengthParamsEdgePage.h" />
+    <ClInclude Include="..\..\..\..\Common\LengthParamsEdgesPage.h" />
+    <ClInclude Include="..\..\..\..\Common\LengthParamsVerticesPage.h" />
     <ClInclude Include="..\..\..\..\Common\OCC_2dChildFrame.h" />
     <ClInclude Include="..\..\..\..\Common\OCC_2dDoc.h" />
     <ClInclude Include="..\..\..\..\Common\OCC_2dView.h" />
     <ClInclude Include="..\..\..\..\Common\OCC_BaseDoc.h" />
     <ClInclude Include="..\..\..\..\Common\OCC_BaseView.h" />
     <ClInclude Include="..\..\..\..\Common\OCC_MainFrame.h" />
+    <ClInclude Include="..\..\..\..\Common\RadiusParamsPage.h" />
     <ClInclude Include="..\..\..\..\Common\res\OCC_Resource.h" />
     <ClInclude Include="..\..\..\..\Common\ResultDialog.h" />
     <ClInclude Include="..\..\..\..\Common\ImportExport\SaveCSFDBDlg.h" />
index ab0406a..2163d8a 100644 (file)
     <ClCompile Include="..\..\..\..\Common\ISession2D\ISession2D_Shape.cpp">
       <Filter>Source Files\ISession2D-src</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\..\..\Common\DimensionDlg.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\Common\AngleParamsVerticesPage.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\Common\LengthParamsEdgePage.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\Common\LengthParamsEdgesPage.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\Common\LengthParamsVerticesPage.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\Common\RadiusParamsPage.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="..\..\..\..\Common\res\OCC_Resource.rc">
     <ClInclude Include="..\..\..\..\Common\ISession2D\ISession2D_Shape.h">
       <Filter>Header Files\ISession2D-headers</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\..\..\Common\DimensionDlg.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\Common\AngleParamsVerticesPage.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\Common\LengthParamsEdgePage.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\Common\LengthParamsEdgesPage.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\Common\LengthParamsVerticesPage.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\Common\RadiusParamsPage.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\..\..\..\Common\res\2dChildFrameTB.bmp">
index 9dcd89d..5a68460 100644 (file)
                                </FileConfiguration>
                        </File>
                        <File
+                               RelativePath="..\..\..\..\Common\AngleParamsVerticesPage.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\..\..\Common\DimensionDlg.cpp"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\..\..\..\Common\ImportExport\ImportExport.cpp"
                                >
                                <FileConfiguration
                                </FileConfiguration>
                        </File>
                        <File
+                               RelativePath="..\..\..\..\Common\LengthParamsEdgePage.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\..\..\Common\LengthParamsEdgesPage.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\..\..\Common\LengthParamsVerticesPage.cpp"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\..\..\src\mfcsample.cpp"
                                >
                                <FileConfiguration
                                </FileConfiguration>
                        </File>
                        <File
+                               RelativePath="..\..\..\..\Common\RadiusParamsPage.cpp"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\..\..\..\Common\ResultDialog.cpp"
                                >
                                <FileConfiguration
                                >
                        </File>
                        <File
+                               RelativePath="..\..\..\..\Common\AngleParamsVerticesPage.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\..\..\Common\DimensionDlg.h"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\..\..\..\Common\ImportExport\ImportExport.h"
                                >
                        </File>
                        <File
+                               RelativePath="..\..\..\..\Common\LengthParamsEdgePage.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\..\..\Common\LengthParamsEdgesPage.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\..\..\Common\LengthParamsVerticesPage.h"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\..\..\..\Common\OCC_2dChildFrame.h"
                                >
                        </File>
                                >
                        </File>
                        <File
+                               RelativePath="..\..\..\..\Common\RadiusParamsPage.h"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\..\..\..\Common\ResultDialog.h"
                                >
                        </File>
index 9dfd4f5..5936919 100644 (file)
                                </FileConfiguration>
                        </File>
                        <File
+                               RelativePath="..\..\..\..\Common\AngleParamsVerticesPage.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\..\..\Common\DimensionDlg.cpp"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\..\..\..\Common\ImportExport\ImportExport.cpp"
                                >
                                <FileConfiguration
                                </FileConfiguration>
                        </File>
                        <File
+                               RelativePath="..\..\..\..\Common\LengthParamsEdgePage.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\..\..\Common\LengthParamsEdgesPage.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\..\..\Common\LengthParamsVerticesPage.cpp"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\..\..\src\mfcsample.cpp"
                                >
                                <FileConfiguration
                                </FileConfiguration>
                        </File>
                        <File
+                               RelativePath="..\..\..\..\Common\RadiusParamsPage.cpp"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\..\..\..\Common\ResultDialog.cpp"
                                >
                                <FileConfiguration
                                >
                        </File>
                        <File
+                               RelativePath="..\..\..\..\Common\AngleParamsVerticesPage.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\..\..\Common\DimensionDlg.h"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\..\..\..\Common\ImportExport\ImportExport.h"
                                >
                        </File>
                        <File
+                               RelativePath="..\..\..\..\Common\LengthParamsEdgePage.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\..\..\Common\LengthParamsEdgesPage.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\..\..\Common\LengthParamsVerticesPage.h"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\..\..\..\Common\OCC_2dChildFrame.h"
                                >
                        </File>
                                >
                        </File>
                        <File
+                               RelativePath="..\..\..\..\Common\RadiusParamsPage.h"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\..\..\..\Common\ResultDialog.h"
                                >
                        </File>
index 66cfab9..318badf 100755 (executable)
@@ -275,7 +275,7 @@ is
         -- for example, are only created for the selection
         -- process. By means of these enumerations, they can
         -- be cleared from local context.
-        
+
     enumeration KindOfUnit is 
     TOU_LENGTH,
     TOU_SURFACE,
@@ -285,19 +285,19 @@ is
     TOU_MASS,
     TOU_FORCE,
     TOU_TIME;
-        ---Purpose: Declares the type of Interactive Object unit.
-        
+    ---Purpose: Declares the type of Interactive Object unit.
+
     enumeration TypeOfAxis is TOAX_Unknown,TOAX_XAxis,TOAX_YAxis,TOAX_ZAxis;
-        ---Purpose: Declares the type of axis.
-        
+    ---Purpose: Declares the type of axis.
+
     enumeration TypeOfPlane is TOPL_Unknown,TOPL_XYPlane,TOPL_XZPlane,TOPL_YZPlane;
-        ---Purpose: Declares the type of plane.
+     ---Purpose: Declares the type of plane.
     enumeration TypeOfDist is TOD_Unknown,TOD_Horizontal,TOD_Vertical;
----Purpose: To declare the type of distance.
-    
+    ---Purpose: To declare the type of distance.
+
     enumeration TypeOfAttribute is 
     TOA_Line,
-    TOA_Angle,
+    TOA_Dimension,
     TOA_Wire,
     TOA_Plane,
     TOA_Vector,
@@ -311,16 +311,21 @@ is
     TOA_FirstAxis,
     TOA_SecondAxis,
     TOA_ThirdAxis;
-    
-    enumeration StandardDatum is SD_None,SD_Point,SD_Axis,SD_Trihedron,SD_PlaneTrihedron,SD_Line,SD_Circle,SD_Plane;
-       --- Purpose: Declares the type of standard datum of an Interactive Object. 
 
--- New ------------------------------------------------
+    enumeration StandardDatum is SD_None,SD_Point,SD_Axis,SD_Trihedron,SD_PlaneTrihedron,SD_Line,SD_Circle,SD_Plane;
+    --- Purpose: Declares the type of standard datum of an Interactive Object. 
 
     enumeration KindOfSurface is KOS_Plane, KOS_Cylinder, KOS_Cone, KOS_Sphere, KOS_Torus,
-               KOS_Revolution, KOS_Extrusion, KOS_OtherSurface;
--------------------------------------------------------    
-   
+                                 KOS_Revolution, KOS_Extrusion, KOS_OtherSurface;
+
+-- Enumerations for dimensions management --
+
+    enumeration DisplaySpecialSymbol is DSS_No, DSS_Before, DSS_After;
+    ---Purpose: Specifies dimension special symbol display options
+
+    enumeration DimensionDisplayMode is DDM_All, DDM_Line, DDM_Text;
+    ---Purpose: Specifies dimension display modes for advanced highlighting and selection.
+
     class Triangulation;
 
     class TexturedShape;
@@ -374,10 +379,10 @@ is
     deferred class EllipseRadiusDimension; 
     class MaxRadiusDimension; 
     class MinRadiusDimension; 
-    class LengthDimension;
-    class AngleDimension;
-    class RadiusDimension;
-    class DiameterDimension;
+    imported LengthDimension;
+    imported AngleDimension;
+    imported RadiusDimension;
+    imported DiameterDimension;
     class Chamf2dDimension;
     class Chamf3dDimension;
     class OffsetDimension;
index 0c7e02f..68b04f4 100755 (executable)
@@ -384,10 +384,10 @@ Standard_Boolean AIS::ComputeGeometry(const TopoDS_Edge& anEdge1,
 //=======================================================================
 //function : ComputeGeometry
 //purpose  : Computes the geometry of the 2 edges in the current wp
-//           and the 'rigth' geometry of the edges if one doesn't
-//           belong to the currentworkingplane.
+//           and the 'right' geometry of the edges if one doesn't
+//           belong to the current working plane.
 //           There may be only one curve that can't belong to the
-//           current workingplane ( attachement constraint)
+//           current working plane ( attachement constraint)
 //           if the 2 edges belong to the current WP, <WhatProj> = 0
 //
 //           indexExt = 0 2 edges are in the current wp
@@ -397,19 +397,19 @@ Standard_Boolean AIS::ComputeGeometry(const TopoDS_Edge& anEdge1,
 //           it returns Standard_False
 //=======================================================================
 
-Standard_Boolean AIS::ComputeGeometry(const TopoDS_Edge& anEdge1, 
-                                     const TopoDS_Edge& anEdge2, 
-                                     Standard_Integer& indexExt, 
-                                     Handle(Geom_Curve)& aCurve1, 
-                                     Handle(Geom_Curve)& aCurve2, 
-                                     gp_Pnt& FirstPnt1, 
-                                     gp_Pnt& LastPnt1, 
-                                     gp_Pnt& FirstPnt2, 
-                                     gp_Pnt& LastPnt2, 
-                                     Handle(Geom_Curve)& extCurve,
-                                     Standard_Boolean& isInfinite1,
-                                     Standard_Boolean& isInfinite2,                                  
-                                     const Handle(Geom_Plane)& aPlane)
+Standard_Boolean AIS::ComputeGeometry (const TopoDS_Edge& anEdge1,
+                                       const TopoDS_Edge& anEdge2,
+                                       Standard_Integer& indexExt,
+                                       Handle(Geom_Curve)& aCurve1,
+                                       Handle(Geom_Curve)& aCurve2,
+                                       gp_Pnt& FirstPnt1,
+                                       gp_Pnt& LastPnt1,
+                                       gp_Pnt& FirstPnt2,
+                                       gp_Pnt& LastPnt2,
+                                       Handle(Geom_Curve)& extCurve,
+                                       Standard_Boolean& isInfinite1,
+                                       Standard_Boolean& isInfinite2,
+                                       const Handle(Geom_Plane)& aPlane)
 {
   if (aPlane.IsNull()) return Standard_False;
   extCurve.Nullify();
diff --git a/src/AIS/AIS_AngleDimension.cdl b/src/AIS/AIS_AngleDimension.cdl
deleted file mode 100755 (executable)
index c0be9ef..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
--- Created on: 1996-12-03
--- Created by: Arnaud BOUZY/Odile Olivier
--- Copyright (c) 1996-1999 Matra Datavision
--- Copyright (c) 1999-2012 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.
---
--- 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.
---
--- 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.
-
-
-
-class AngleDimension from AIS inherits Relation from AIS
-
-      
-        ---Purpose: A framework to define display of angles.
-        -- These displays are particularly useful in viewing draft prisms.
-        -- The angle displayed may define an intersection
-        -- can be between two edges or two faces of a shape
-        -- or a plane. The display consists of arrows and text.
-
-uses Shape                 from TopoDS,
-     Presentation          from Prs3d,
-     PresentationManager3d from PrsMgr,
-     Selection             from SelectMgr,
-     Pnt                   from gp,
-     Dir                   from gp,
-     Circ                  from gp,
-     Line                  from Geom,
-     Ax1                   from gp,
-     Projector             from Prs3d,
-     Transformation        from Geom,
-     Plane                 from Geom,
-     Surface               from Geom,
-     ExtendedString        from TCollection,
-     ArrowSide             from DsgPrs,
-     KindOfDimension       from AIS,   
-     Edge                  from TopoDS,    
-     Face                  from TopoDS   
-is
-
-    Create (aFirstEdge       : Edge           from TopoDS;
-           aSecondEdge      : Edge           from TopoDS;
-           aPlane           : Plane          from Geom;
-           aVal             : Real           from Standard;
-           aText            : ExtendedString from TCollection)    
-        ---Purpose:  Constructs the angle display object defined by the
-        -- shapes aFShape, aSShape, the plane aPlane, the
-        -- value aVal and the text aText.
-        -- aFShape and aSShape are edges.
-    returns mutable AngleDimension from AIS;
-    
-    Create (aFirstEdge       : Edge           from TopoDS;
-           aSecondEdge      : Edge           from TopoDS;
-           aPlane           : Plane          from Geom;
-           aVal             : Real           from Standard;
-           aText            : ExtendedString from TCollection;    
-           aPosition        : Pnt            from gp;
-           aSymbolPrs       : ArrowSide      from DsgPrs;    
-           anArrowSize      : Real           from Standard = 0.0)
-        ---Purpose: Constructs the angle display object defined by the
-        -- shapes aFShape, aSShape, the plane aPlane, the
-        -- value aVal, the text aText, the point aPosition, the
-        -- type of arrow aSymbolPrs, and the arrow length anArrowSize.
-        -- aFShape and aSShape are edges.
-    returns mutable AngleDimension from AIS;
-
-    Create (aCone       : Face           from TopoDS;
-           aVal        : Real           from Standard;
-           aText       : ExtendedString from TCollection)    
-        ---Purpose:  Angle of cone  
-    returns mutable AngleDimension from AIS;
-    
-   
-    Create (aCone            : Face           from TopoDS;
-           aVal             : Real           from Standard;
-           aText            : ExtendedString from TCollection;
-            aPosition        : Pnt            from gp;
-           aSymbolPrs       : ArrowSide      from DsgPrs;    
-           anArrowSize      : Real           from Standard = 0.01 )    
-        ---Purpose:  Angle of cone  
-    returns mutable AngleDimension from AIS;
- --===================================================================       
-    
-    Create (aFirstFace  : Face           from TopoDS;
-           aSecondFace : Face           from TopoDS;
-           anAxis      : Ax1            from gp;
-           aVal        : Real           from Standard;
-           aText       : ExtendedString from TCollection)    
-         ---Purpose:  TwoPlanarFaceAngle dimension
-    returns mutable AngleDimension from AIS;
-
-    Create (aFirstFace  : Face           from TopoDS;
-           aSecondFace : Face           from TopoDS;
-           anAxis      : Ax1            from gp;
-           aVal        : Real           from Standard;
-           aText       : ExtendedString from TCollection;          
-           aPosition   : Pnt            from gp;
-           aSymbolPrs  : ArrowSide      from DsgPrs;    
-           anArrowSize : Real           from Standard = 0.0)
-         ---Purpose: TwoPlanarFacesAngle dimension  with   position
-         --           and text Face  can be Plane or Extrusion of line
-         --           or Offset of  those
-    returns mutable AngleDimension from AIS;
-
-
-    Create (aFFace      : Face           from TopoDS;
-           aSFace      : Face           from TopoDS;
-           aVal        : Real           from Standard;
-           aText       : ExtendedString from TCollection)    
-         ---Purpose:  Angle dimension between two curvilinear faces
-         --           Warning:
-         --           Requaired 0 <= aVal < PI,
-         --                     aVal must be defined exactly.
-    returns mutable AngleDimension from AIS;
-
-    Create (aFFace      : Face           from TopoDS;
-           aSFace      : Face           from TopoDS;
-           aVal        : Real           from Standard;
-           aText       : ExtendedString from TCollection;          
-           aPosition   : Pnt            from gp;
-           aSymbolPrs  : ArrowSide      from DsgPrs;    
-           anArrowSize : Real           from Standard = 0.001)
-        ---Purpose:  Angle dimension between two curvilinear faces
-        --           with position and text. Face can be Cone, Cylinder
-        --           Offset of Cone, Offset of Cylinder 
-    returns mutable AngleDimension from AIS;
-
-
-    Axis (me) 
-        ---Purpose:
-        -- Returns the axis set by the SetAxis method, which
-        -- serves to locate the angle between two faces.
-        ---C++: return const &
-        ---C++: inline 
-    returns Ax1 from gp 
-    is static;
-
-    SetAxis(me: mutable;anAxis : Ax1 from gp)
-        ---C++: inline
-        ---Purpose:
-        -- Sets the axis, anAxis, which serves to locate the
-        -- angle between two faces.
-    is static;
-
-    SetConeFace( me: mutable; aConeFace : Face from TopoDS )
-    is  static;
-
-    SetFirstShape( me: mutable; aFShape : Shape from TopoDS )
-    is redefined static;
-
-    SetSecondShape( me: mutable; aSShape : Shape from TopoDS )
-    is redefined static;
-
-
-    KindOfDimension(me) 
-        ---Purpose: Returns PLANEANGLE as the kind of dimension.
-        ---C++: inline
-    returns KindOfDimension from AIS 
-    is redefined;
-
-    IsMovable(me) returns Boolean from Standard 
-        ---C++: inline    
-        ---Purpose: Returns true if the angle dimension is movable.
-        
-    is redefined;
-    
-  -- Methods from PresentableObject
-
-    Compute(me            : mutable;
-            aPresentationManager: PresentationManager3d from PrsMgr;
-           aPresentation : mutable Presentation from Prs3d;
-           aMode         : Integer from Standard= 0) 
-    is redefined static private;
-    
-    Compute(me:mutable;
-               aProjector: Projector from Prs3d;
-                aPresentation: mutable Presentation from Prs3d)
-    is redefined static private;     
-
-    Compute(me            : mutable;
-           aProjector    : Projector from Prs3d;
-           aTrsf         : Transformation from Geom;
-           aPresentation : mutable Presentation from Prs3d)
-    is redefined;
-        ---Purpose: Computes the presentation according to a point of view
-        --          given by <aProjector>. 
-        --          This method should be used when the associated degenerated Presentations 
-        --          have been transformed by <aTrsf> which is not a Pure
-        --          Translation. The HLR Prs can't be deducted automatically
-        --          WARNING :<aTrsf> must be applied
-        --           to the object to display before computation  !!!
-
--- Methods from SelectableObject
-
-    ComputeSelection(me         : mutable;
-                    aSelection : mutable Selection from SelectMgr;
-                    aMode      : Integer from Standard)
-    is redefined private;
-
-    
---
---     Computation private methods
---
-
-    ComputeConeAngle(me: mutable; 
-                        aPresentation : mutable Presentation from Prs3d)
-    is private;
-
-    ComputeTwoFacesAngle(me: mutable;
-                         aPresentation : mutable Presentation from Prs3d)
-    is private;
-    
-    ComputeTwoPlanarFacesAngle(me: mutable;
-                         aPresentation : mutable Presentation from Prs3d)
-    is private;
-    
-    ComputeTwoCurvilinearFacesAngle(me: mutable;
-                         aPresentation : mutable Presentation from Prs3d)
-    is private;
-    
-    ComputeTwoEdgesAngle(me: mutable;
-                         aPresentation : mutable Presentation from Prs3d)
-    is private;
-    ComputeTwoEdgesNullAngle(me: mutable;
-                           aPresentation : mutable Presentation from Prs3d;  
-                           l1    : Line from Geom;
-                           l2    : Line from Geom;
-                           ptat11 : Pnt from gp;
-                           ptat12 : Pnt from gp;
-                            ptat21 : Pnt from gp;
-                           ptat22 : Pnt from gp;
-                           isInf1 : Boolean from Standard;
-                           isInf2 : Boolean from Standard )                        
-    is private;
-    
-    ComputeTwoEdgesNotNullAngle(me: mutable;
-                           aPresentation : mutable Presentation from Prs3d;  
-                           l1    : Line from Geom;
-                           l2    : Line from Geom;
-                           ptat11 : Pnt from gp;
-                           ptat12 : Pnt from gp;
-                            ptat21 : Pnt from gp;
-                           ptat22 : Pnt from gp;
-                           isInf1 : Boolean from Standard;
-                           isInf2 : Boolean from Standard )                        
-    is private;
-
-    Compute3DSelection(me         : mutable;
-                      aSelection : mutable Selection from SelectMgr)
-    is private;
-    
-    Compute2DSelection(me         : mutable;
-                      aSelection : mutable Selection from SelectMgr)
-    is private;
-    ComputeNull2DSelection(me         : mutable;
-                          aSelection : mutable Selection from SelectMgr; 
-                          distFS     : Real from Standard)
-    is private;
-
-    ComputeConeAngleSelection(me         : mutable;
-                             aSelection : mutable Selection from SelectMgr)
-    is private;    
-
-fields
-
-    myNbShape  : Integer from Standard;
-    myCenter   : Pnt     from gp;
-    myFAttach  : Pnt     from gp;
-    mySAttach  : Pnt     from gp;
-    myFDir     : Dir     from gp;
-    mySDir     : Dir     from gp;
-    myAxis     : Ax1     from gp;
-    myCone     : Face    from TopoDS;
-   
-end AngleDimension;
index 9736e2c..9327a58 100755 (executable)
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
-
-#define BUC60655       //GG 22/03/00 Enable to compute correctly
-//                     the arrow size at object creation time.
-
-#define BUC60915        //GG 05/06/01 Enable to compute the requested arrow size
-//                      if any in all dimensions.
-
-#include <Standard_NotImplemented.hxx>
-
-#include <AIS_AngleDimension.ixx>
+#include <AIS_AngleDimension.hxx>
 
 #include <AIS.hxx>
+#include <AIS_Dimension.hxx>
 #include <AIS_DimensionOwner.hxx>
 #include <AIS_Drawer.hxx>
-
+#include <BRep_Tool.hxx>
 #include <BRepBuilderAPI_MakeFace.hxx>
 #include <BRepAdaptor_Curve.hxx>
 #include <BRepAdaptor_Surface.hxx>
-#include <BRep_Tool.hxx>
+#include <BRepLib_MakeVertex.hxx>
 
 #include <DsgPrs.hxx>
 #include <DsgPrs_AnglePresentation.hxx>
 #include <ElCLib.hxx>
 #include <ElSLib.hxx>
 
+#include <GC_MakeCircle.hxx>
+#include <GC_MakeConicalSurface.hxx>
+#include <gce_MakeLin.hxx>
+#include <gce_MakeLin2d.hxx>
+#include <gce_MakePln.hxx>
+#include <gce_MakeCirc.hxx>
+#include <gce_MakeCone.hxx>
 #include <Geom2d_Circle.hxx>
 #include <Geom2d_Curve.hxx>
 #include <Geom2d_Line.hxx>
+#include <Geom2dAPI_ExtremaCurveCurve.hxx>
 #include <GeomAPI.hxx>
 #include <Geom_Circle.hxx>
 #include <Geom_Line.hxx>
 #include <Geom_SurfaceOfRevolution.hxx>
 #include <Geom_SurfaceOfLinearExtrusion.hxx>
 #include <Geom_OffsetSurface.hxx>
+#include <GeomAPI_ExtremaCurveCurve.hxx>
+#include <Graphic3d_ArrayOfSegments.hxx>
+#include <Graphic3d_AspectLine3d.hxx>
+#include <gp.hxx>
+#include <gp_Ax1.hxx>
+#include <gp_Lin.hxx>
+#include <gp_Cone.hxx>
+#include <gp_Pln.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Pnt2d.hxx>
+#include <gp_Vec.hxx> 
+#include <gp_XYZ.hxx>
+#include <Graphic3d_Group.hxx>
+#include <Graphic3d_ArrayOfPrimitives.hxx>
+#include <Graphic3d_ArrayOfPolylines.hxx>
 
 #include <IntAna2d_AnaIntersection.hxx>
 #include <IntAna2d_IntPoint.hxx>
 #include <IntAna_QuadQuadGeo.hxx>
 #include <IntAna_ResultType.hxx>
-
+#include <Poly_Polygon3D.hxx>
 #include <Precision.hxx>
-
 #include <ProjLib.hxx>
-
-#include <Prs3d_AngleAspect.hxx>
 #include <Prs3d_ArrowAspect.hxx>
+#include <Prs3d_DimensionAspect.hxx>
 #include <Prs3d_Drawer.hxx>
-
+#include <Prs3d_Root.hxx>
+#include <PrsMgr_PresentationManager3d.hxx>
 #include <Select3D_SensitiveCurve.hxx>
 #include <Select3D_SensitiveSegment.hxx>
 #include <Select3D_SensitiveBox.hxx>
 #include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_Selection.hxx>
+#include <Standard_NotImplemented.hxx>
+#include <Standard_Type.hxx>
+#include <Standard_Macro.hxx>
+#include <Standard_DefineHandle.hxx>
 
 #include <TColStd_Array1OfReal.hxx>
-
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Shape.hxx>
 #include <TopoDS_Vertex.hxx>
-
 #include <UnitsAPI.hxx>
 
-#include <gp.hxx>
-#include <gp_Ax1.hxx>
-#include <gp_Lin.hxx>
-#include <gp_Cone.hxx>
-#include <gp_Pln.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_Pnt2d.hxx>
-#include <gp_Vec.hxx> 
-#include <gp_XYZ.hxx>
-
-#include <GC_MakeCircle.hxx>
-#include <GC_MakeConicalSurface.hxx>
-#include <gce_MakePln.hxx>
-#include <gce_MakeCone.hxx>
-
+IMPLEMENT_STANDARD_HANDLE (AIS_AngleDimension, AIS_Dimension)
+IMPLEMENT_STANDARD_RTTIEXT (AIS_AngleDimension, AIS_Dimension)
 
 //=======================================================================
-//function : Constructor
-//purpose  : ConeAngle dimension 
+//function : init
+//purpose  : Private constructor for default initialization
 //=======================================================================
 
-AIS_AngleDimension::AIS_AngleDimension( const TopoDS_Face& aCone, 
-                                       const Standard_Real aVal,
-                                       const TCollection_ExtendedString& aText,
-                                       const gp_Pnt& aPosition,
-                                       const DsgPrs_ArrowSide /*aSymbolPrs*/,
-                                       const Standard_Real anArrowSize):
-myNbShape(1)
+void AIS_AngleDimension::init()
 {
-  myCone = aCone;
-  myVal = aVal;
-  myText = aText;
-  myPosition = aPosition; 
-  mySymbolPrs = DsgPrs_AS_BOTHAR;
-  myAutomaticPosition = Standard_True;
-#ifdef BUC60915
-  SetArrowSize( anArrowSize );
-#else
-  myArrowSize = anArrowSize;
-#endif
+  // Default values of units
+  UnitsAPI::SetLocalSystem (UnitsAPI_SI);
+  SetUnitsQuantity ("PLANE ANGLE");
+  SetModelUnits ("rad");
+  SetDisplayUnits ("deg");
+  SetSpecialSymbol (0x00B0);
+  SetDisplaySpecialSymbol (AIS_DSS_After);
+  MakeUnitsDisplayed (Standard_False);
 }
 
 //=======================================================================
 //function : Constructor
-//purpose  : ConeAngle dimension 
+//purpose  : Two edges dimension
 //=======================================================================
 
-AIS_AngleDimension::AIS_AngleDimension( const TopoDS_Face& aCone, 
-                                       const Standard_Real aVal,
-                                       const TCollection_ExtendedString& aText):
-myNbShape(1)
+AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Edge& theFirstEdge,
+                                        const TopoDS_Edge& theSecondEdge)
+: AIS_Dimension(),
+  myIsFlyoutLines (Standard_True),
+  myFlyout (15.0)
 {
-//#ifdef DEB
-  cout << "Call new AngleDimension for cone's angle" << endl;
-//#endif
-
-  gp_Pnt tmpPnt(0., 0., 0.); 
-
-  myCone = aCone;
-  myVal = aVal;
-  myText = aText;
-  myPosition = tmpPnt; 
-  mySymbolPrs = DsgPrs_AS_BOTHAR;
-  myAutomaticPosition = Standard_True;
-  myArrowSize = 0.0;
-
+  init();
+  myShapesNumber = 2;
+  SetKindOfDimension (AIS_KOD_PLANEANGLE);
+  myFirstShape  = theFirstEdge;
+  mySecondShape = theSecondEdge;
 }
 
-
 //=======================================================================
 //function : Constructor
-//purpose  : TwoEdgesAngle dimension 
+//purpose  : Two edges dimension
+//           <thePlane> is used in case of Angle=PI
 //=======================================================================
 
-
-AIS_AngleDimension::AIS_AngleDimension(const TopoDS_Edge& aFirstEdge,
-                                      const TopoDS_Edge& aSecondEdge,
-                                      const Handle (Geom_Plane)& aPlane, 
-                                      const Standard_Real aVal, 
-                                      const TCollection_ExtendedString& aText)
-:AIS_Relation(),
- myNbShape(2)
+AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Edge& theFirstEdge,
+                                        const TopoDS_Edge& theSecondEdge,
+                                        const gp_Pln& thePlane)
+: AIS_Dimension(),
+  myIsFlyoutLines (Standard_True),
+  myFlyout (15.0)
 {
-#ifdef DEB
-  cout << endl << "Call new AngleDimension for edges, default" << endl;
-#endif
-
-  myFShape = aFirstEdge;
-  mySShape = aSecondEdge;
-  myVal = aVal;
-  myPlane = aPlane;
-  myText = aText;
-  mySymbolPrs = DsgPrs_AS_BOTHAR;
-  myAutomaticPosition = Standard_True;
-
-  myArrowSize = myVal / 100.;
+  init();
+  myShapesNumber = 2;
+  SetKindOfDimension (AIS_KOD_PLANEANGLE);
+  myFirstShape  = theFirstEdge;
+  mySecondShape = theSecondEdge;
+  SetWorkingPlane (thePlane);
 }
 
 //=======================================================================
 //function : Constructor
-//purpose  : TwoEdgesAngle dimension (avec position et texte)
+//purpose  : Two edges dimension with aspect
+//           <thePlane> is used in case of Angle=PI
 //=======================================================================
 
-AIS_AngleDimension::AIS_AngleDimension( const TopoDS_Edge& aFirstEdge, 
-                                       const TopoDS_Edge& aSecondEdge, 
-                                       const Handle (Geom_Plane)& aPlane,  
-                                       const Standard_Real aVal, 
-                                       const TCollection_ExtendedString& aText, 
-                                       const gp_Pnt& aPosition,
-                                       const DsgPrs_ArrowSide aSymbolPrs,
-                                       const Standard_Real anArrowSize):
-myNbShape(2)
+AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Edge& theFirstEdge,
+                                        const TopoDS_Edge& theSecondEdge,
+                                        const gp_Pln& thePlane,
+                                        const Handle(Prs3d_DimensionAspect)& theDimensionAspect,
+                                        const Standard_Real theExtensionSize)
+: AIS_Dimension (theDimensionAspect,theExtensionSize),
+  myIsFlyoutLines (Standard_True),
+  myFlyout (15.0)
 {
-#ifdef DEB
-  cout << endl << "Call new AngleDimension for edges" << endl;
-#endif
-
-  myFShape = aFirstEdge;
-  mySShape = aSecondEdge;
-  myVal = aVal;
-  myPlane = aPlane;
-  myText = aText;
-  mySymbolPrs = aSymbolPrs;
-  myAutomaticPosition = Standard_False;
-#ifdef BUC60915
-  SetArrowSize( anArrowSize );
-#else
-  myArrowSize = anArrowSize;
-#endif
-  myPosition = aPosition;
-
+  myShapesNumber = 2;
+  SetKindOfDimension (AIS_KOD_PLANEANGLE);
+  myFirstShape  = theFirstEdge;
+  mySecondShape = theSecondEdge;
+  SetWorkingPlane (thePlane);
 }
 
 //=======================================================================
 //function : Constructor
-//purpose  : TwoPlanarFacesAngle dimension 
+//purpose  : Three points dimension
 //=======================================================================
 
-AIS_AngleDimension::AIS_AngleDimension( const TopoDS_Face& aFirstFace, 
-                                       const TopoDS_Face& aSecondFace, 
-                                       const gp_Ax1& anAxis, 
-                                       const Standard_Real aVal,
-                                       const TCollection_ExtendedString& aText):
-myNbShape(2),
-myAxis(anAxis)
+AIS_AngleDimension::AIS_AngleDimension (const gp_Pnt& theFirstPoint,
+                                        const gp_Pnt& theSecondPoint,
+                                        const gp_Pnt& theThirdPoint)
+: AIS_Dimension(),
+  myIsFlyoutLines (Standard_True),
+  myFlyout (15.0)
 {
-#ifdef DEB
-  cout << endl << "Call new AngleDimension for planar faces, default" << endl;
-#endif
-
-  myFShape = aFirstFace;
-  mySShape = aSecondFace;
-
-  AIS::GetPlaneFromFace( aFirstFace, myFirstPlane, myFirstBasisSurf, myFirstSurfType, myFirstOffset );
-  AIS::GetPlaneFromFace( aSecondFace, mySecondPlane, mySecondBasisSurf, mySecondSurfType, mySecondOffset );
-
-//POP init champ myPlane
-  myPlane = new Geom_Plane(myFirstPlane);
-
-  myVal = aVal;
-  myText = aText;
-  mySymbolPrs = DsgPrs_AS_BOTHAR;
-  myAutomaticPosition = Standard_True;
-
-  myArrowSize = myVal / 100.;
+  init();
+  myIsInitialized = Standard_True;
+  SetKindOfDimension (AIS_KOD_PLANEANGLE);
+  myFirstPoint   = theFirstPoint;
+  myCenter       = theSecondPoint;
+  mySecondPoint  = theThirdPoint;
+  myShapesNumber = 3;
 }
 
 //=======================================================================
 //function : Constructor
-//purpose  : TwoPlanarFacesAngle dimension  (avec position et texte)
+//purpose  : Three points dimension
 //=======================================================================
 
-AIS_AngleDimension::AIS_AngleDimension( const TopoDS_Face& aFirstFace, 
-                                       const TopoDS_Face& aSecondFace, 
-                                       const gp_Ax1& anAxis, 
-                                       const Standard_Real aVal, 
-                                       const TCollection_ExtendedString& aText, 
-                                       const gp_Pnt& aPosition, 
-                                       const DsgPrs_ArrowSide aSymbolPrs,
-                                       const Standard_Real anArrowSize):
-myNbShape(2),
-myAxis(anAxis)
+AIS_AngleDimension::AIS_AngleDimension (const gp_Pnt& theFirstPoint,
+                                        const gp_Pnt& theSecondPoint,
+                                        const gp_Pnt& theThirdPoint,
+                                        const Handle(Prs3d_DimensionAspect)& theDimensionAspect,
+                                        const Standard_Real theExtensionSize)
+: AIS_Dimension (theDimensionAspect,theExtensionSize),
+  myIsFlyoutLines (Standard_True),
+  myFlyout (15.0)
 {
-#ifdef DEB
-  cout << endl << "Call new AngleDimension for planar faces" << endl;
-#endif
-
-  myFShape = aFirstFace;
-  mySShape = aSecondFace;
-
-  AIS::GetPlaneFromFace( aFirstFace, myFirstPlane, myFirstBasisSurf, myFirstSurfType, myFirstOffset );
-  AIS::GetPlaneFromFace( aSecondFace, mySecondPlane, mySecondBasisSurf, mySecondSurfType, mySecondOffset );
-
-//POP init champ myPlane
-  myPlane = new Geom_Plane(myFirstPlane);
-
-  myVal = aVal;
-  myText = aText;
-  mySymbolPrs = aSymbolPrs;
-  myAutomaticPosition = Standard_False;
-#ifdef BUC60915
-  SetArrowSize( anArrowSize );
-#else
-  myArrowSize = anArrowSize;
-#endif
-  myPosition = aPosition;
+  myIsInitialized = Standard_True;
+  SetKindOfDimension (AIS_KOD_PLANEANGLE);
+  myFirstPoint   = theFirstPoint;
+  myCenter       = theSecondPoint;
+  mySecondPoint  = theThirdPoint;
+  myShapesNumber =3;
 }
 
-
 //=======================================================================
-//function : AIS_AngleDimension
-//purpose  : Two curvilinear faces dimension
+//function : Constructor
+//purpose  : Cone dimension
 //=======================================================================
 
-AIS_AngleDimension::AIS_AngleDimension( const TopoDS_Face& aFFace, 
-                                       const TopoDS_Face& aSFace, 
-                                       const Standard_Real aVal,
-                                       const TCollection_ExtendedString& aText ):
-myNbShape(2)
+AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Face& theCone)
+: AIS_Dimension(),
+  myIsFlyoutLines (Standard_True),
+  myFlyout (15.0)
 {
-#ifdef DEB
-  cout << endl << "Call new AngleDimension for curvilinear faces, default" << endl;
-#endif
-
-  SetFirstShape( aFFace );
-  SetSecondShape( aSFace );
-  myVal = aVal;
-
-  myText = aText;
-  mySymbolPrs = DsgPrs_AS_BOTHAR;
-  myAutomaticPosition = Standard_True;
-
-  myArrowSize = myVal / 100.;
+  init();
+  myIsInitialized = Standard_False;
+  SetKindOfDimension (AIS_KOD_PLANEANGLE);
+  myFirstShape   = theCone;
+  myShapesNumber = 1;
 }
 
 //=======================================================================
-//function : AIS_AngleDimension
-//purpose  : 
+//function : Constructor
+//purpose  : Two faces dimension
 //=======================================================================
 
-AIS_AngleDimension::AIS_AngleDimension( const TopoDS_Face& aFFace, 
-                                       const TopoDS_Face& aSFace, 
-                                       const Standard_Real aVal,
-                                       const TCollection_ExtendedString& aText,
-                                       const gp_Pnt& aPosition, 
-                                       const DsgPrs_ArrowSide aSymbolPrs,
-                                       const Standard_Real anArrowSize):
-myNbShape(2)
+AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Face& theFirstFace,
+                                        const TopoDS_Face& theSecondFace,
+                                        const gp_Ax1& theAxis)
+: AIS_Dimension(),
+  myIsFlyoutLines (Standard_True),
+  myFlyout (15.0)
 {
-#ifdef DEB
-  cout << endl << "Call new AngleDimension for curvilinear faces" << endl;
-#endif
-
-  SetFirstShape( aFFace );
-  SetSecondShape( aSFace );
-  myVal = aVal;
-
-  myText = aText;
-  mySymbolPrs = DsgPrs_AS_BOTHAR;
-  myAutomaticPosition = Standard_True;
-
-  mySymbolPrs = aSymbolPrs;
-  myAutomaticPosition = Standard_False;
-#ifdef BUC60915
-  SetArrowSize( anArrowSize );
-#else
-  myArrowSize = anArrowSize;
-#endif
-  myPosition = aPosition;
+  init();
+  myIsInitialized = Standard_False;
+  SetKindOfDimension (AIS_KOD_PLANEANGLE);
+  myFirstShape   = theFirstFace;
+  mySecondShape  = theSecondFace;
+  myShapesNumber = 2;
+  gp_Pln aPlane;
+  aPlane.SetAxis (theAxis);
+  SetWorkingPlane (aPlane);
 }
 
-
 //=======================================================================
-//function : SetConeFace
+//function : SetFirstShape
 //purpose  : 
 //=======================================================================
 
-void AIS_AngleDimension::SetConeFace( const TopoDS_Face& aConeFace )
+void AIS_AngleDimension::SetFirstShape (const TopoDS_Shape& theShape,
+                                        const Standard_Boolean isSingleShape /*= Standard_False*/)
 {
-  myCone = aConeFace;
-  myAutomaticPosition = Standard_True;
+  AIS_Dimension::SetFirstShape (theShape);
+  if (isSingleShape)
+    myShapesNumber = 1;
 }
 
-
 //=======================================================================
-//function : SetFirstShape
-//purpose  : 
+//function : aboveInBelowCone
+//purpose  : Returns 1 if <theC> center is above of <theCMin> center;
+//                   0 if <theC> center is between <theCMin> and
+//                        <theCMax> centers;
+//                  -1 if <theC> center is below <theCMax> center.
 //=======================================================================
 
-void AIS_AngleDimension::SetFirstShape( const TopoDS_Shape& aFShape )
+Standard_Integer AIS_AngleDimension::aboveInBelowCone (const gp_Circ &theCMax,
+                                                       const gp_Circ &theCMin,
+                                                       const gp_Circ &theC)
 {
-  myFShape = aFShape;
-
-  if (myFShape.ShapeType() == TopAbs_FACE)
-    {
-      AIS::GetPlaneFromFace( TopoDS::Face( myFShape ),
-                            myFirstPlane,
-                            myFirstBasisSurf,
-                            myFirstSurfType,
-                            myFirstOffset );
-
-      if (myFirstSurfType == AIS_KOS_Cylinder)
-       myAxis = (Handle( Geom_CylindricalSurface )::DownCast( myFirstBasisSurf ))->Cylinder().Axis();
-      else if (myFirstSurfType == AIS_KOS_Cone)
-       myAxis = (Handle( Geom_ConicalSurface )::DownCast( myFirstBasisSurf ))->Cone().Axis();
-      else if (myFirstSurfType == AIS_KOS_Revolution)
-       myAxis = (Handle( Geom_SurfaceOfRevolution )::DownCast( myFirstBasisSurf ))->Axis();
-      else if (myFirstSurfType == AIS_KOS_Extrusion)
-       {
-         myAxis.SetDirection((Handle( Geom_SurfaceOfLinearExtrusion )::DownCast( myFirstBasisSurf ))
-                             ->Direction() );
-         //myAxis.SetLocation( ??? );
-       }
-    }
+  const Standard_Real aD  = theCMax.Location().Distance (theCMin.Location());
+  const Standard_Real aD1 = theCMax.Location().Distance (theC.Location());
+  const Standard_Real aD2 = theCMin.Location().Distance (theC.Location());
+
+  if (aD >= aD1 && aD >= aD2) return  0;
+  if (aD  < aD2 && aD1 < aD2) return -1;
+  if (aD  < aD1 && aD2 < aD1) return  1;
+  return 0;
 }
 
 //=======================================================================
-//function : SetSecondShape
-//purpose  : 
+//function : initConeAngle
+//purpose  : initialization of the cone angle
 //=======================================================================
 
-void AIS_AngleDimension::SetSecondShape( const TopoDS_Shape& aSShape )
+Standard_Boolean AIS_AngleDimension::initConeAngle (const TopoDS_Face& theCone)
 {
-  mySShape = aSShape;
-
-  if (myFShape.ShapeType() == TopAbs_FACE)
-    AIS::GetPlaneFromFace( TopoDS::Face( mySShape ),
-                          mySecondPlane,
-                          mySecondBasisSurf,
-                          mySecondSurfType,
-                          mySecondOffset );
-}
-
-
+  if (theCone.IsNull ())
+    return Standard_False;
 
+  gp_Pln aPln;
+  gp_Cone aCone;
+  gp_Circ aCircle;
+  // A surface from the Face
+  Handle(Geom_Surface) aSurf;
+  Handle(Geom_OffsetSurface) aOffsetSurf; 
+  Handle(Geom_ConicalSurface) aConicalSurf;
+  Handle(Geom_SurfaceOfRevolution) aRevSurf;
+  Handle(Geom_Line) aLine;
+  BRepAdaptor_Surface aConeAdaptor (theCone);
+  TopoDS_Face aFace;
+  AIS_KindOfSurface aSurfType;
+  Standard_Real anOffset = 0.;
+  Handle(Standard_Type) aType;
 
-///=======================================================================
-//function : Compute
-//purpose  : 
-//=======================================================================
+  Standard_Real aMaxV = aConeAdaptor.FirstVParameter();
+  Standard_Real aMinV = aConeAdaptor.LastVParameter();
 
-void AIS_AngleDimension::Compute(const Handle(PrsMgr_PresentationManager3d)&, 
-                                const Handle(Prs3d_Presentation)& aPresentation, 
-                                const Standard_Integer)
-{
-  aPresentation->Clear();
+  AIS::GetPlaneFromFace(theCone, aPln, aSurf, aSurfType, anOffset);
 
-  if( myNbShape == 1 ) 
-    {
-     //  cout << "Computing for cone' angle "   << endl;
-     ComputeConeAngle(aPresentation);
-     return;
-    }
-  switch (myFShape.ShapeType()) {
-  case TopAbs_FACE :
-    {
-      // cas angle entre deux faces
-      ComputeTwoFacesAngle(aPresentation);
-    }
-    break;
-  case TopAbs_EDGE :
+  if (aSurfType == AIS_KOS_Revolution)
+  {
+    // Surface of revolution
+    aRevSurf = Handle(Geom_SurfaceOfRevolution)::DownCast(aSurf);
+    gp_Lin aLin (aRevSurf->Axis());
+    Handle(Geom_Curve) aBasisCurve = aRevSurf->BasisCurve();
+    //Must be a part of line (basis curve should be linear)
+    if (aBasisCurve ->DynamicType() != STANDARD_TYPE(Geom_Line))
+      return Standard_False;
+
+    gp_Pnt aFirst1 = aConeAdaptor.Value (0., aMinV);
+    gp_Pnt aLast1 = aConeAdaptor.Value (0., aMaxV);
+    gp_Vec aVec1 (aFirst1, aLast1);
+
+    //Projection <aFirst> on <aLin>
+    gp_Pnt aFirst2 = ElCLib::Value (ElCLib::Parameter (aLin, aFirst1), aLin);
+    // Projection <aLast> on <aLin>
+    gp_Pnt aLast2 = ElCLib::Value (ElCLib::Parameter (aLin, aLast1), aLin);
+
+    gp_Vec aVec2 (aFirst2, aLast2);
+
+    // Check if two parts of revolution are parallel (it's a cylinder) or normal (it's a circle).
+    if (aVec1.IsParallel (aVec2, Precision::Angular())
+        || aVec1.IsNormal (aVec2,Precision::Angular()))
+      return Standard_False;
+
+    gce_MakeCone aMkCone (aRevSurf->Axis(), aFirst1, aLast1);
+    aCone =  aMkCone.Value();
+    myCenter = aCone.Apex();
+  }
+  else
+  {
+    aType = aSurf->DynamicType();
+    if (aType == STANDARD_TYPE(Geom_OffsetSurface) || anOffset > 0.01)
     {
-      // cas angle entre deux edges
-      ComputeTwoEdgesAngle(aPresentation);
+      // Offset surface
+      aOffsetSurf = new Geom_OffsetSurface (aSurf, anOffset);
+      aSurf = aOffsetSurf->Surface();
+      BRepBuilderAPI_MakeFace aMkFace(aSurf, Precision::Confusion());
+      aMkFace.Build();
+      if (!aMkFace.IsDone())
+        return Standard_False;
+      aConeAdaptor.Initialize (aMkFace.Face());
     }
-    break;
-  default:
-    break;
+    aCone = aConeAdaptor.Cone();
+    aConicalSurf = Handle(Geom_ConicalSurface)::DownCast (aSurf);
+    myCenter =  aConicalSurf->Apex();
   }
-  
-}
-
-//=======================================================================
-//function : Compute
-//purpose  : : to avoid warning
-//=======================================================================
 
-void AIS_AngleDimension::Compute(const Handle(Prs3d_Projector)& aProjector, 
-                                const Handle(Prs3d_Presentation)& aPresentation)
-{
-// Standard_NotImplemented::Raise("AIS_AngleDimension::Compute(const Handle(Prs3d_Projector)&,const Handle(Prs3d_Presentation)&)");
- PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
-}
+  // A circle where the angle is drawn
+  Handle(Geom_Curve) aCurve;
+  Standard_Real aMidV = ( aMinV + aMaxV ) / 2.5;
+  aCurve = aSurf->VIso (aMidV);
+  aCircle = Handle(Geom_Circle)::DownCast (aCurve)->Circ();
 
-void AIS_AngleDimension::Compute(const Handle_Prs3d_Projector& aProjector, const Handle_Geom_Transformation& aTransformation, const Handle_Prs3d_Presentation& aPresentation)
-{
-// Standard_NotImplemented::Raise("AIS_AngleDimension::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
- PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
-}
+  aCurve = aSurf->VIso(aMaxV);
+  gp_Circ aCircVmax = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
+  aCurve = aSurf->VIso(aMinV);
+  gp_Circ aCircVmin = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
 
-//=======================================================================
-//function : ComputeSelection
-//purpose  : 
-//=======================================================================
-
-void AIS_AngleDimension::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection, 
-                                         const Standard_Integer)
-{
 
-  if ( myNbShape == 1 ) 
-    {
-    // cout << "Computing selection for cone's angle "   << endl;
-     ComputeConeAngleSelection(aSelection);
-     return;
-    }
-
-
-  if (myFShape.IsNull()) return;
+  if (aCircVmax.Radius() < aCircVmin.Radius())
+  {
+   gp_Circ aTmpCirc = aCircVmax;
+   aCircVmax = aCircVmin;
+   aCircVmin = aTmpCirc;
+  }
 
-  if (myFShape.ShapeType() == TopAbs_FACE )
-    Compute3DSelection(aSelection);
-  else
-    Compute2DSelection(aSelection);
-
-  // Text
-  Handle( SelectMgr_EntityOwner ) own = new SelectMgr_EntityOwner( this, 7 );
-  Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
-  Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( own,
-                                                                  myPosition.X(),
-                                                                  myPosition.Y(),
-                                                                  myPosition.Z(),
-                                                                  myPosition.X() + size,
-                                                                  myPosition.Y() + size,
-                                                                  myPosition.Z() + size);
-  aSelection->Add(box);
+  myFirstPoint  = ElCLib::Value (0, aCircle);
+  mySecondPoint = ElCLib::Value (M_PI, aCircle);
+  return Standard_True;
 }
 
 //=======================================================================
-//function : ComputeConeAngle
-//purpose  : 
+//function : initTwoFacesAngle
+//purpose  : initialization of angle dimension between two faces
 //=======================================================================
 
-void AIS_AngleDimension::ComputeConeAngle(const Handle(Prs3d_Presentation)& aPresentation)
+Standard_Boolean AIS_AngleDimension::initTwoFacesAngle ()
 {
-  if( myCone.IsNull() ) return;
+  TopoDS_Face aFirstFace = TopoDS::Face (myFirstShape);
+  TopoDS_Face aSecondFace = TopoDS::Face (mySecondShape);
+  gp_Dir aFirstDir, aSecondDir;
+  gp_Pln aFirstPlane, aSecondPlane;
+  Handle(Geom_Surface) aFirstBasisSurf, aSecondBasisSurf;
+  AIS_KindOfSurface aFirstSurfType, aSecondSurfType;
+  Standard_Real aFirstOffset, aSecondOffset;
   
-  gp_Pln aPln;
-  gp_Cone aCone;
-  gp_Circ myCircle;
-  gp_Pnt Apex;
-  Handle( Geom_Surface ) aSurf;         //a surface from the Face
-  Handle( Geom_OffsetSurface ) aOffsetSurf; 
-  Handle( Geom_ConicalSurface ) aConicalSurf;
-  Handle( Geom_SurfaceOfRevolution ) aRevSurf; 
-  Handle( Geom_Line ) aLine;
-  BRepAdaptor_Surface tmpSurf(myCone);  
-  TopoDS_Face aFace;
-  AIS_KindOfSurface aSurfType;
-  Standard_Real Offset = 0. ;
-  Handle( Standard_Type ) aType;
-
-  Standard_Real maxV = tmpSurf.FirstVParameter();
-  Standard_Real minV = tmpSurf.LastVParameter();
-
-
- AIS::GetPlaneFromFace( myCone, aPln, aSurf, aSurfType, Offset );
-
- if ( aSurfType == AIS_KOS_Revolution ) {                                    //surface of revolution
-
-   aRevSurf = Handle( Geom_SurfaceOfRevolution )::DownCast( aSurf ); 
-   gp_Lin ln( aRevSurf->Axis() );
-   Handle( Geom_Curve ) tmpCrv = aRevSurf->BasisCurve();
-   if ( tmpCrv ->DynamicType() != STANDARD_TYPE(Geom_Line) )  return;        //Must be a part of line
-
-   Standard_Real par;
-   gp_Pnt fst = tmpSurf.Value(0., minV);
-   gp_Pnt lst = tmpSurf.Value(0., maxV);
-   gp_Vec vec1(fst, lst);
-   
-   par = ElCLib::Parameter( ln, fst );
-   gp_Pnt fst2 = ElCLib::Value( par, ln );                         //projection fst on ln
-   par = ElCLib::Parameter( ln, lst );
-   gp_Pnt lst2 = ElCLib::Value( par, ln );                         //projection lst on ln
-
-   gp_Vec vec2(fst2, lst2);
-
-   // Check if two parts of revolution are parallel ( it's a cylinder ) or normal (it's a circle ) 
-  if( vec1.IsParallel( vec2,Precision::Angular() ) || vec1.IsNormal( vec2,Precision::Angular() ) ) return; 
-  gce_MakeCone mkCone(aRevSurf->Axis(), fst, lst);
-  aCone =  mkCone.Value();
-  Apex = aCone.Apex();
- }
- else {  
-   aType = aSurf->DynamicType();
-   if ( aType == STANDARD_TYPE(Geom_OffsetSurface) || Offset > 0.01 ) {            //offset surface
-     aOffsetSurf = new Geom_OffsetSurface (aSurf, Offset);
-     aSurf = aOffsetSurf->Surface();
-     BRepBuilderAPI_MakeFace mkFace(aSurf, Precision::Confusion());
-     mkFace.Build();
-     if( !mkFace.IsDone() ) return;
-     tmpSurf.Initialize( mkFace.Face() );
-   }  
-   aCone = tmpSurf.Cone();
-   aConicalSurf = Handle( Geom_ConicalSurface)::DownCast( aSurf );
-   Apex =  aConicalSurf->Apex();
- }
-   Handle(Geom_Curve) aCurve;                 //A circle where the angle is drawn
-   if ( myAutomaticPosition ) {
-    Standard_Real midV = ( minV + maxV ) / 2.5; 
-
-    aCurve =   aSurf->VIso(midV);
-    myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
-
-    myPosition = ElCLib::Value(M_PI / 2.0, myCircle);
-    myAutomaticPosition = Standard_False;
-  }
-  else {
-    Standard_Real U, V;
-    ElSLib::Parameters(aCone, myPosition, U, V);
-    aCurve = aSurf->VIso(V); 
-    myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
+  AIS::GetPlaneFromFace (aFirstFace, aFirstPlane,
+                         aFirstBasisSurf,aFirstSurfType,aFirstOffset);
+  AIS::GetPlaneFromFace (aSecondFace, aSecondPlane,
+                         aSecondBasisSurf, aSecondSurfType, aSecondOffset);
+
+  if (aFirstSurfType == AIS_KOS_Plane)
+  {
+    //Planar faces angle
+    AIS::ComputeAngleBetweenPlanarFaces (aFirstFace,
+                                        aSecondFace,
+                                        aSecondBasisSurf,
+                                        GetWorkingPlane().Axis(),
+                                        myValue,
+                                        Standard_True,
+                                        myGeom.myTextPosition,
+                                        myCenter,
+                                        myFirstPoint,
+                                        mySecondPoint,
+                                        aFirstDir,
+                                        aSecondDir);
   }
-  
- //__________________________________________________________________
-  aCurve = aSurf->VIso(maxV);
-  gp_Circ CircVmax = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
-  aCurve = aSurf->VIso(minV);
-  gp_Circ CircVmin = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
- //__________________________________________________________________
-
-  if( CircVmax.Radius() < CircVmin.Radius() ) {
-   gp_Circ tmpCirc = CircVmax;
-   CircVmax = CircVmin;
-   CircVmin = tmpCirc;
+  else
+  {
+        // Curvilinear faces angle
+    Handle(Geom_Plane) aPlane = new Geom_Plane (GetWorkingPlane());
+    AIS::ComputeAngleBetweenCurvilinearFaces (aFirstFace,
+                                             aSecondFace,
+                                             aFirstBasisSurf,
+                                             aSecondBasisSurf,
+                                             aFirstSurfType,
+                                             aSecondSurfType,
+                                             GetWorkingPlane().Axis(),
+                                             myValue,
+                                             Standard_True,
+                                             myGeom.myTextPosition,
+                                             myCenter,
+                                             myFirstPoint,
+                                             mySecondPoint,
+                                             aFirstDir,
+                                             aSecondDir,
+                                             aPlane);
+    SetWorkingPlane (aPlane->Pln());
   }
-
-  DsgPrs_AnglePresentation::Add(aPresentation, myDrawer, myVal, 
-                               myText, myCircle, myPosition, Apex, CircVmin, CircVmax, myArrowSize);
-// cout << "ComputeConeAngle is over"   << endl;                               
+  return Standard_True;
 }
 
-
 //=======================================================================
-//function : ComputeTwoFacesAngle
+//function : SetFlyout
 //purpose  : 
 //=======================================================================
 
-void AIS_AngleDimension::ComputeTwoFacesAngle(const Handle(Prs3d_Presentation)& aPresentation)
+void AIS_AngleDimension::SetFlyout (const Standard_Real theFlyout)
 {
-  if (myFirstSurfType == AIS_KOS_Plane)
-    ComputeTwoPlanarFacesAngle( aPresentation );
-  else
-    ComputeTwoCurvilinearFacesAngle( aPresentation );
+  myFlyout = theFlyout;
 }
 
 //=======================================================================
-//function : ComputeTwoCurvilinearFacesAngle
+//function : GetFlyout
 //purpose  : 
 //=======================================================================
 
-void AIS_AngleDimension::ComputeTwoCurvilinearFacesAngle(const Handle(Prs3d_Presentation)& aPresentation) 
+Standard_Real AIS_AngleDimension::GetFlyout () const
 {
-  AIS::ComputeAngleBetweenCurvilinearFaces( TopoDS::Face( myFShape ),
-                                           TopoDS::Face( mySShape ),
-                                           myFirstBasisSurf,
-                                           mySecondBasisSurf,
-                                           myFirstSurfType,
-                                           mySecondSurfType,
-                                           myAxis,
-                                           myVal,
-                                           myAutomaticPosition,
-                                           myPosition,
-                                           myCenter,
-                                           myFAttach,
-                                           mySAttach,
-                                           myFDir,
-                                           mySDir,
-                                           myPlane );
-  if (myAutomaticPosition && myIsSetBndBox)
-    myPosition = AIS::TranslatePointToBound( myPosition, gp_Dir( gp_Vec( myCenter, myPosition ) ), myBndBox );
-
-  Handle(Prs3d_AngleAspect) la = myDrawer->AngleAspect();
-  Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();
-#ifdef BUC60915
-  if( !myArrowSizeIsDefined ) {
-#endif
-    Standard_Real arrsize = myCenter.Distance( myPosition );
-      
-    if ( (myArrowSize-arrsize) < 0.1 ) arrsize = myArrowSize;
-    if (arrsize == 0.) arrsize = 1.;
-#ifdef BUC60915
-    myArrowSize = arrsize;
-  }
-  arr->SetLength( myArrowSize );
-#else
-  arr->SetLength(arrsize);
-#endif
-      
-
-  if (myVal <= Precision::Angular() || Abs( M_PI-myVal ) <= Precision::Angular())
-    DsgPrs_AnglePresentation::Add(aPresentation,
-                                 myDrawer,
-                                 myVal,
-                                 myText,
-                                 myCenter,
-                                 myFAttach,
-                                 mySAttach,
-                                 myFDir,
-                                 mySDir,
-                                 myPlane->Pln().Axis().Direction(),
-                                 Standard_False, // not plane
-                                 myAxis,
-                                 myPosition,
-                                 mySymbolPrs);
-  else
-    DsgPrs_AnglePresentation::Add(aPresentation,
-                                 myDrawer,
-                                 myVal,
-                                 myText,
-                                 myCenter,
-                                 myFAttach,
-                                 mySAttach,
-                                 myFDir,
-                                 mySDir,
-                                 myFDir ^ mySDir,
-                                 Standard_False, // not plane
-                                 myAxis,
-                                 myPosition,
-                                 mySymbolPrs);
+  return myFlyout;
 }
 
 //=======================================================================
-//function : ComputeTwoPlanarFacesAngle
+//function : countDefaultPlane
 //purpose  : 
 //=======================================================================
 
-void AIS_AngleDimension::ComputeTwoPlanarFacesAngle( const Handle( Prs3d_Presentation )& aPresentation )
+void AIS_AngleDimension::countDefaultPlane ()
 {
-  AIS::ComputeAngleBetweenPlanarFaces( TopoDS::Face( myFShape ),
-                                      TopoDS::Face( mySShape ),
-                                      mySecondBasisSurf,
-                                      myAxis,
-                                      myVal,
-                                      myAutomaticPosition,
-                                      myPosition,
-                                      myCenter,
-                                      myFAttach,
-                                      mySAttach,
-                                      myFDir,
-                                      mySDir );
-  if (myAutomaticPosition && myIsSetBndBox)
-    myPosition = AIS::TranslatePointToBound( myPosition, gp_Dir( gp_Vec( myCenter, myPosition ) ), myBndBox );
-
-  Handle(Prs3d_AngleAspect) la = myDrawer->AngleAspect();
-  Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();
-#ifdef BUC60915
-  if( !myArrowSizeIsDefined ) {
-#endif
-    Standard_Real arrsize = myCenter.Distance( myPosition );
-      
-    if ( (myArrowSize-arrsize) < 0.1 ) arrsize = myArrowSize;
-    if (arrsize == 0.) arrsize = 1.;
-#ifdef BUC60915
-    myArrowSize = arrsize;
-  }
-  arr->SetLength( myArrowSize );
-#else
-  arr->SetLength(arrsize);
-#endif
-      
-
-  DsgPrs_AnglePresentation::Add(aPresentation,
-                               myDrawer,
-                               myVal,
-                               myText,
-                               myCenter,
-                               myFAttach,
-                               mySAttach,
-                               myFDir,
-                               mySDir,
-                               myAxis.Direction(),
-                               Standard_True,
-                               myAxis,
-                               myPosition,
-                               mySymbolPrs);
-     
+  if (!myIsInitialized)
+    return;
+  // Compute normal of the default plane.
+  gp_Vec aVec1(myCenter, myFirstPoint),
+         aVec2(myCenter, mySecondPoint);
+  myDefaultPlane = gp_Pln(myCenter, aVec1^aVec2);
+  // Set computed value to <myWorkingPlane>
+  ResetWorkingPlane ();
 }
 
 //=======================================================================
-//function : ComputeTwoEdgesAngle
+//function : computeValue
 //purpose  : 
 //=======================================================================
 
-void AIS_AngleDimension::ComputeTwoEdgesAngle(const Handle(Prs3d_Presentation)& aPresentation)
+void AIS_AngleDimension::computeValue ()
 {
-  BRepAdaptor_Curve cu1(TopoDS::Edge(myFShape));
-  BRepAdaptor_Curve cu2(TopoDS::Edge(mySShape));
-  if ((cu1.GetType() != GeomAbs_Line) || (cu2.GetType() != GeomAbs_Line)) return;
-
-  // current face
-  BRepBuilderAPI_MakeFace makeface(myPlane->Pln());
-  TopoDS_Face face(makeface.Face());  
-  BRepAdaptor_Surface adp(makeface.Face());
-    
-  // 3d lines
-  Handle(Geom_Line) geom_lin1,geom_lin2;
-  gp_Pnt ptat11,ptat12,ptat21,ptat22;//,pint3d;
-  Standard_Boolean isInfinite1,isInfinite2;
-  Handle(Geom_Curve) extCurv;
-  Standard_Integer copyOfMyExtShape = myExtShape;
-  if (!AIS::ComputeGeometry(TopoDS::Edge(myFShape),
-                           TopoDS::Edge(mySShape),
-                           myExtShape,
-                           geom_lin1,
-                           geom_lin2,
-                           ptat11,
-                           ptat12,
-                           ptat21,
-                           ptat22,
-                           extCurv,
-                           isInfinite1,
-                           isInfinite2,
-                           myPlane)) {
-    return;
-  }
-  // Temporary: computation of myVal
-  //  myVal = Abs(geom_lin1->Lin().Angle( geom_lin2->Lin())); // Pb with angles JPR
-
-  if (copyOfMyExtShape != 0) myExtShape = copyOfMyExtShape;  
-
-  // 2d lines => projection of 3d on current plane
-
-//POP pour NT
-  Handle(Geom2d_Curve) geoC1 = GeomAPI::To2d(geom_lin1,myPlane->Pln());
-  Handle(Geom2d_Line) lin1_2d = *((Handle(Geom2d_Line)*)& geoC1);
-  Handle(Geom2d_Curve) geoC2 = GeomAPI::To2d(geom_lin2,myPlane->Pln());
-  Handle(Geom2d_Line) lin2_2d = *((Handle(Geom2d_Line)*)& geoC2);
-
-#ifdef BUC60915
-  if( !myArrowSizeIsDefined ) {
-#endif
-    Standard_Real arrSize1(myArrowSize),arrSize2(myArrowSize);
-    if (!isInfinite1) arrSize1 = ptat11.Distance(ptat12)/100.;
-    if (!isInfinite2) arrSize2 = ptat21.Distance(ptat22)/100.;
-#ifdef BUC60655
-    myArrowSize = Min(myArrowSize,Max(arrSize1,arrSize2));
-#else
-    myArrowSize = Min(myArrowSize,Min(arrSize1,arrSize2));
-#endif
-#ifdef BUC60915
-  }
-#endif
-
-
-  // Processing in  case of 2 parallel straight lines
-  if (lin1_2d->Lin2d().Direction()
-      .IsParallel(lin2_2d->Lin2d().Direction(),Precision::Angular())) {    
-    ComputeTwoEdgesNullAngle(aPresentation,
-                            geom_lin1,
-                            geom_lin2,
-                            ptat11,ptat12,
-                            ptat21,ptat22,
-                            isInfinite1,isInfinite2);
-  }
-  
-  // Processing in case of 2 non-parallel straight lines
-  else {
-    ComputeTwoEdgesNotNullAngle(aPresentation,
-                               geom_lin1,
-                               geom_lin2,
-                               ptat11,
-                               ptat12,
-                               ptat21,
-                               ptat22,
-                               isInfinite1,isInfinite2);
-  }
-  if ( (myExtShape != 0) &&  !extCurv.IsNull()) {
-    gp_Pnt pf, pl;
-    if ( myExtShape == 1 ) {
-      if (!isInfinite1) {
-       pf = ptat11; 
-       pl = ptat12;
-      }
-      aPresentation->SetInfiniteState(isInfinite1);
-      ComputeProjEdgePresentation(aPresentation,TopoDS::Edge(myFShape),geom_lin1,pf,pl);
-    }
-    else {
-      if (!isInfinite2) {
-       pf = ptat21; 
-       pl = ptat22;
-      }
-      aPresentation->SetInfiniteState(isInfinite2);
-      ComputeProjEdgePresentation(aPresentation,TopoDS::Edge(mySShape),geom_lin2,pf,pl);
-    }
-  }
+  gp_Vec aVec1 (myCenter, myFirstPoint),
+         aVec2 (myCenter, mySecondPoint);
+  myValue = aVec1.Angle (aVec2);
+  // To model units
+  AIS_Dimension::computeValue();
 }
 
-
 //=======================================================================
-//function : ComputeTwoEdgesNotNullAngle
-//purpose  : 
+//function : initTwoEdgesAngle
+//purpose  : Fill gp_Pnt fields for further presentation computation
+//           If intersection between two edges doesn't exist
+//           <myIsInitialized> is set to false
 //=======================================================================
 
-void AIS_AngleDimension::ComputeTwoEdgesNotNullAngle(const Handle(Prs3d_Presentation)& aPresentation,
-                                                    const Handle(Geom_Line)& l1,
-                                                    const Handle(Geom_Line)& l2,
-                                                    const gp_Pnt& ptat11,
-                                                    const gp_Pnt& ptat12,
-                                                    const gp_Pnt& ptat21,
-                                                    const gp_Pnt& ptat22,
-                                                    const Standard_Boolean isInfinite1,
-                                                    const Standard_Boolean isInfinite2)
+Standard_Boolean AIS_AngleDimension::initTwoEdgesAngle ()
 {
-  // current face
-  BRepBuilderAPI_MakeFace makeface(myPlane->Pln());
-  TopoDS_Face face(makeface.Face());  
-  BRepAdaptor_Surface adp(makeface.Face());
-  // 2d lines => projection of 3d on current plane
-  Handle(Geom2d_Curve) geoC1 = GeomAPI::To2d(l1,myPlane->Pln());
-  const Handle(Geom2d_Line)& l1_2d = *((Handle(Geom2d_Line)*)& geoC1);
-  Handle(Geom2d_Curve) geoC2 = GeomAPI::To2d(l2,myPlane->Pln());
-  const Handle(Geom2d_Line)& l2_2d = *((Handle(Geom2d_Line)*)& geoC2);
-
-  //----------------------------------------------------------
-  //          Computation of myCenter
-  //----------------------------------------------------------
-  IntAna2d_AnaIntersection inter(l1_2d->Lin2d(),l2_2d->Lin2d());
-  if (!inter.IsDone()) return;
-  if (!inter.NbPoints()) return;
-  
-  gp_Pnt2d pint(inter.Point(1).Value());
-  myCenter = adp.Value(pint.X(),pint.Y());
-
-  //----------------------------------------------------------
-  //         Computation of the 2 directions
-  //----------------------------------------------------------
-  gp_Dir d1,d2;
-  if (!isInfinite1) {
-    if (myCenter.SquareDistance(ptat11) > myCenter.SquareDistance(ptat12)) d1 = gp_Dir(gp_Vec(myCenter,ptat11));
-    else d1 = gp_Dir(gp_Vec(myCenter,ptat12));  
-  }
-  else d1 = l1->Lin().Direction();
-
-  if (!isInfinite2) {
-    if (myCenter.SquareDistance(ptat21) > myCenter.SquareDistance(ptat22)) d2 = gp_Dir(gp_Vec(myCenter,ptat21));
-    else d2 = gp_Dir(gp_Vec(myCenter,ptat22));
-  }
-  else d2 = l2->Lin().Direction();
-  if (!isInfinite1) {
-    Standard_Boolean In1(Standard_False);
-    Standard_Boolean In2(Standard_False);
-    if ( !(Abs(d1.Angle(d2) - Abs(myVal)) <= Precision::Confusion())
-        &&  (Abs(myVal) <  M_PI) ) {
-      Standard_Real parcent1 = ElCLib::Parameter(l1->Lin(), myCenter);
-      Standard_Real par11 = ElCLib::Parameter(l1->Lin(), ptat11);
-      Standard_Real par12 = ElCLib::Parameter(l1->Lin(), ptat12);
-      if ( par11 < par12) {
-       if ( ( parcent1> par11) && (parcent1< par12)) {
-         In1 = Standard_True;
-         d1.Reverse();
-       }
-      }
-      else {
-      if ( ( parcent1> par12) && (parcent1< par11)) {
-       In1 = Standard_True;
-       d1.Reverse();
-      }
-      }
-      if ( !In1) {
-       In2 = Standard_True;
-       d2.Reverse();
-      }
-    }
-  }
-
-  myFDir = d1;
-  mySDir = d2;
-  gp_Lin theaxis;
-  gp_Lin gpl1 = l1->Lin();
-  gp_Lin gpl2 = l2->Lin();
-  theaxis = gp_Lin(myCenter,myFDir^mySDir);
+  // Data initialization
+  TopoDS_Edge aFirstEdge = TopoDS::Edge (myFirstShape);
+  TopoDS_Edge aSecondEdge = TopoDS::Edge (mySecondShape);
+  BRepAdaptor_Curve aMakeFirstLine (aFirstEdge);
+  BRepAdaptor_Curve aMakeSecondLine (aSecondEdge);
 
-  if (myVal >  M_PI) {
-    theaxis.Reverse();
-  }
-  
-  gp_Pnt curpos;  
-  TColStd_Array1OfReal tabdist(1,4);
-  if (!isInfinite1) { 
-    tabdist(1) = theaxis.Distance(ptat11);
-    tabdist(2) = theaxis.Distance(ptat12);
-  }
-  else {
-    tabdist(1) = tabdist(2) = 0.;
-  }
-
-  if (!isInfinite2) { 
-    tabdist(3) = theaxis.Distance(ptat21);
-    tabdist(4) = theaxis.Distance(ptat22);
-  }
-  else {
-    tabdist(3) = tabdist(4) = 0.;
+  if (aMakeFirstLine.GetType() != GeomAbs_Line || aMakeSecondLine.GetType() != GeomAbs_Line)
+  {
+    return  Standard_False;
   }
 
-  if (myAutomaticPosition) {
-    Standard_Real length_1(RealLast());
-    if (!isInfinite1) length_1 = .75*Abs(tabdist(2)-tabdist(1))+Min(tabdist(1),tabdist(2));
-
-    Standard_Real length_2(RealLast());
-    if (!isInfinite2) length_2 = .75*Abs(tabdist(4)-tabdist(3))+Min(tabdist(3),tabdist(4));
-    Standard_Real theLength(Min(length_1,length_2));
-    if (Precision::IsInfinite(theLength)) theLength = 50.;
-
-    myFAttach = myCenter.Translated(gp_Vec(d1)*theLength);
-    mySAttach = myCenter.Translated(gp_Vec(d2)*theLength);
-       
-    if (!isInfinite1) {
-      Standard_Real par_p1_attach(ElCLib::Parameter(gpl1,myFAttach));
-      Standard_Real par11 = ElCLib::Parameter(gpl1,ptat11);
-      Standard_Real par12 = ElCLib::Parameter(gpl1,ptat12);
-      if (par_p1_attach > par11 && par_p1_attach > par12) {
-       par_p1_attach = Max(par11,par12);
-       myFAttach = ElCLib::Value(par_p1_attach,gpl1);
-      }
-      else if (par_p1_attach < par11 && par_p1_attach < par12) {
-       par_p1_attach = Min(par11,par12);
-       myFAttach = ElCLib::Value(par_p1_attach,gpl1);
-      }
-    }
-
-    if (!isInfinite2) {
-      Standard_Real par_p2_attach(ElCLib::Parameter(gpl2,mySAttach));
-      Standard_Real par21 = ElCLib::Parameter(gpl2,ptat21);
-      Standard_Real par22 = ElCLib::Parameter(gpl2,ptat22);
-      if (par_p2_attach > par21 && par_p2_attach > par22) {
-       par_p2_attach = Max(par21,par22);
-       mySAttach = ElCLib::Value(par_p2_attach,gpl2);
-      }
-      else if (par_p2_attach < par21 && par_p2_attach < par22) {
-       par_p2_attach = Min(par21,par22);
-       mySAttach = ElCLib::Value(par_p2_attach,gpl2);
-      }
-    }
-    if ( myVal < M_PI) curpos.SetXYZ(.5*(myFAttach.XYZ()+mySAttach.XYZ())); 
-    else {
-      curpos.SetXYZ(.5*(myFAttach.XYZ()+mySAttach.XYZ())); 
-      gp_Vec transl(curpos, myCenter);
-      transl*= 2;
-      curpos.Translate(transl);
-    }
+  Handle(Geom_Line) aFirstLine  = new Geom_Line (aMakeFirstLine.Line());
+  Handle(Geom_Line) aSecondLine = new Geom_Line (aMakeSecondLine.Line());
 
-    gp_Ax2 ax(myCenter,myFDir.Crossed(mySDir),myFDir);
-    gp_Circ circle(ax,theLength);
-    Standard_Real par = ElCLib::Parameter(circle,curpos);
-    curpos = ElCLib::Value(par,circle);    
-
-    // small offset like in LengthDimension
-    gp_Vec transl(myCenter, curpos);
-    transl*= 0.3;
-    curpos.Translate(transl);
-    
-    if (myIsSetBndBox)
-      curpos = AIS::TranslatePointToBound( curpos, gp_Dir( gp_Vec( myCenter, curpos ) ), myBndBox );
-
-    myPosition = curpos;
-    myAutomaticPosition = Standard_True;      
+  gp_Lin aFirstLin  = aFirstLine->Lin ();
+  gp_Lin aSecondLin = aSecondLine->Lin ();
+  gp_Lin2d aFirstLin2d, aSecondLin2d;
+  Standard_Boolean isParallelLines = aFirstLin.Direction().IsParallel (aSecondLin.Direction(), Precision::Angular());
+  Standard_Boolean isSameLines = isParallelLines && aFirstLin.Distance (aSecondLin.Location()) <= Precision::Confusion();
+  // In case where we can't compute plane automatically
+  if ((isParallelLines || isSameLines) && !myIsWorkingPlaneCustom)
+  {
+    return Standard_False;
   }
 
-  else {
-  // point is projected on the plane
-    gp_Pnt2d pointOnPln(ProjLib::Project(myPlane->Pln(),myPosition));
-    myPosition = BRepAdaptor_Surface(BRepBuilderAPI_MakeFace(myPlane->Pln()).Face()).Value(pointOnPln.X(),pointOnPln.Y());
-    curpos = myPosition;
-    Standard_Real dist(curpos.Distance(myCenter));    
-    if (dist<=Precision::Confusion()) {
-      gp_XYZ delta(1.,1.,1.);
-      curpos.SetXYZ(curpos.XYZ()+delta);
-      dist = curpos.Distance(myCenter);
-    }
-    // To learn if it is necessary to take distance -dist or not
-    // it is necessary to know if we are in the sector opposite to the angle
-    // if not : we are in the opposite sector if the coordinates
-    // of curpos in point (d1,d2) are negative
-    gp_Ax2 ax(myCenter,myFDir.Crossed(mySDir),myFDir);
-    gp_Circ circle(ax,dist);
-#ifdef DEB
-//    gp_Pnt p1(myCenter.Translated(gp_Vec(d1)*dist));
-#endif
-    gp_Pnt p2(myCenter.Translated(gp_Vec(d2)*dist));
-    Standard_Real uc1 = 0;
-    Standard_Real uc2 = ElCLib::Parameter(circle, p2 );
-    Standard_Real uco = ElCLib::Parameter(circle, curpos );
-    Standard_Real udeb = uc1;
-    Standard_Real ufin = uc2;
-    if (uco > ufin) {
-      if (Abs(myVal)<M_PI) {
-       // test if uco is in the opposite sector 
-       if (uco > udeb+M_PI && uco < ufin+M_PI){
-         dist = -dist;
-       }
-      }
-    }
-
-     gp_Pnt p1_attach(myCenter.Translated(gp_Vec(d1)*dist));
-     gp_Pnt p2_attach(myCenter.Translated(gp_Vec(d2)*dist));
-    
-     if (!isInfinite1) {
-       Standard_Real par_p1_attach(ElCLib::Parameter(gpl1,p1_attach));
-       Standard_Real par11 = ElCLib::Parameter(gpl1,ptat11);
-       Standard_Real par12 = ElCLib::Parameter(gpl1,ptat12);
-       if (par_p1_attach > par11 && par_p1_attach > par12) {
-        par_p1_attach = Max(par11,par12);
-        p1_attach = ElCLib::Value(par_p1_attach,gpl1);
-       }
-       else if (par_p1_attach < par11 && par_p1_attach < par12) {
-        par_p1_attach = Min(par11,par12);
-        p1_attach = ElCLib::Value(par_p1_attach,gpl1);
-       }
-     }
-     myFAttach = p1_attach;
-           
-     if (!isInfinite2) {
-       Standard_Real par_p2_attach(ElCLib::Parameter(gpl2,p2_attach));
-       Standard_Real par21 = ElCLib::Parameter(gpl2,ptat21);
-       Standard_Real par22 = ElCLib::Parameter(gpl2,ptat22);
-       if (par_p2_attach > par21 && par_p2_attach > par22) {
-        par_p2_attach = Max(par21,par22);
-        p2_attach = ElCLib::Value(par_p2_attach,gpl2);
-       }
-       else if (par_p2_attach < par21 && par_p2_attach < par22) {
-        par_p2_attach = Min(par21,par22);
-        p2_attach = ElCLib::Value(par_p2_attach,gpl2);
-       }
-     }
-     mySAttach = p2_attach;
-  }  
-  myAxis = theaxis.Position();
-
-  //--------------------------------------------------------
-  //    Computation of the presentation
-  //--------------------------------------------------------
-  Handle(Prs3d_AngleAspect) la = myDrawer->AngleAspect();
-  Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();
-
-  arr->SetLength(myArrowSize);
-
-  DsgPrs_AnglePresentation::Add(aPresentation,
-                               myDrawer,
-                               myVal,
-                               myText,
-                               myCenter,
-                               myFAttach,
-                               mySAttach,
-                               myFDir,
-                               mySDir,
-                               curpos,
-                               mySymbolPrs);
-}
-
-
-
-//=======================================================================
-//function : ComputeTwoEdgesNullAngle
-//purpose  : compute the presentation of a angle dimension if it's null.
-//             -> the aim of the computation is to have a constant radius 
-//                during the dimension moving : the radius is independant
-//                of the cursor position, it's equal to a arbitrary value
-//=======================================================================
+  gp_Pln aPlane;
 
-void AIS_AngleDimension::ComputeTwoEdgesNullAngle(const Handle(Prs3d_Presentation)& aPresentation,
-                                                 const Handle(Geom_Line)& l1,
-                                                 const Handle(Geom_Line)& l2,
-                                                 const gp_Pnt& ptat11,
-                                                 const gp_Pnt& ptat12,
-                                                 const gp_Pnt& ptat21,
-                                                 const gp_Pnt& ptat22,
-                                                 const Standard_Boolean isInfinite1,
-                                                 const Standard_Boolean isInfinite2)
-{
-  // current face
-  BRepBuilderAPI_MakeFace makeface(myPlane->Pln());
-  TopoDS_Face face(makeface.Face());  
-  BRepAdaptor_Surface adp(makeface.Face());
-  // 2d lines => projection of 3d on current plane
-  Handle(Geom2d_Curve) geoC1 = GeomAPI::To2d(l1,myPlane->Pln());
-  Handle(Geom2d_Line) l1_2d = *((Handle(Geom2d_Line)*)& geoC1);
-  Handle(Geom2d_Curve) geoC2 = GeomAPI::To2d(l2,myPlane->Pln());
-  Handle(Geom2d_Line) l2_2d = *((Handle(Geom2d_Line)*)& geoC2);
-
-  gp_Lin gpl1 = l1->Lin();
-  gp_Lin gpl2 = l2->Lin();
-
-  //------------------------------------------------------------
-  //                Computation of myCenter
-  // -> Point located on the median of 2 straight lines,
-  //    is calculated as located between 2 closest points 
-  //    of each straight line.
-  //-----------------------------------------------------------
-     //   theLength : radius of the future circle
-  Standard_Real theLength = gpl1.Distance(gpl2.Location());
-  // processing of the particular case when 2 straight lines are coincident
-  Standard_Boolean SameLines(Standard_False);
-  if ( theLength <= Precision::Confusion()) {
-    SameLines = Standard_True;
-    if (!isInfinite1) {
-      if (!isInfinite2) theLength = 0.75 * Max( ptat11.Distance(ptat12), ptat21.Distance(ptat22));
-      else theLength = 0.75*ptat11.Distance(ptat12);
-    }
-    else {
-      if (!isInfinite2) theLength = 0.75*ptat21.Distance(ptat22);
-      else theLength = 50.;
-    }
-  }
-  else theLength = theLength*8/10;
-
-  gp_Pnt pmin1 ,pmin2;
-  if (!isInfinite1 && !isInfinite2) {
-    pmin1 = ptat11; pmin2 = ptat21;
-    Standard_Real dis = ptat11.Distance(ptat21);
-    Standard_Real dis2 = ptat11.Distance(ptat22);
-    if ( dis2 < dis)  {
-      pmin1 = ptat11;
-      pmin2 = ptat22;
-      dis = dis2;
-    }
-    dis2 = ptat12.Distance(ptat22);
-    if ( dis2 < dis)  {
-      pmin1 = ptat12;
-      pmin2 = ptat22;
-      dis = dis2;
-    }
-    dis2 = ptat12.Distance(ptat21);
-    if ( dis2 < dis)  {
-      pmin1 = ptat12;
-      pmin2 = ptat21;
-      dis = dis2;
-    }
-    myCenter.SetXYZ( (pmin1.XYZ() + pmin2.XYZ()) / 2. );
+  /// PART 1 is for automatic plane computation from two edges if it is possible
+  // Build plane
+  if (!myIsWorkingPlaneCustom)
+  {
+    gp_Pnt aPoint = aFirstLine->Value (0.);
+    gp_Dir aNormal = isParallelLines
+                     ? gp_Vec(aSecondLin.Normal (aPoint).Direction()) ^ gp_Vec (aSecondLin.Direction())
+                     : gp_Vec (aFirstLin.Direction()) ^ gp_Vec (aSecondLin.Direction());
+    aPlane = gp_Pln (aPoint, aNormal);
+    resetWorkingPlane (aPlane);
   }
-  else {
-    gp_Pnt pntOnl1 = gpl1.Location();
-    gp_Pnt pntOnl2 = ElCLib::Value(ElCLib::Parameter(gpl1,pntOnl1),gpl2);
-    myCenter.SetXYZ( (pntOnl1.XYZ() + pntOnl2.XYZ()) / 2. );
+  else
+  {
+    aPlane = GetWorkingPlane();
   }
 
-  
-  // directions 
-  gp_Dir d1,d2;
-  if (!isInfinite1) {
-    if (myCenter.SquareDistance(ptat11) > myCenter.SquareDistance(ptat12)) d1 = gp_Dir(gp_Vec(myCenter,ptat11));
-    else d1 = gp_Dir(gp_Vec(myCenter,ptat12));  
-  }
-  else d1 = gpl1.Direction();
-  
-  if (!isInfinite2) {
-    if (myCenter.SquareDistance(ptat21) > myCenter.SquareDistance(ptat22)) d2 = gp_Dir(gp_Vec(myCenter,ptat21));
-    else d2 = gp_Dir(gp_Vec(myCenter,ptat22));
-  }
-  else d2 = gpl2.Direction();  
-
-  gp_Dir theaxis;
-  if ( SameLines ) theaxis = myPlane->Pln().Axis().Direction();
-  else {
-    theaxis = gp_Dir(d1^d2);
-    gp_Vec V1(d1); gp_Vec V2(d2);
-    if ( V1.CrossMagnitude(V2) < 0 ) theaxis.Reverse();
+  // Compute geometry for this plane and edges
+  Standard_Boolean isInfinite1,isInfinite2;
+  gp_Pnt aFirstPoint1, aLastPoint1, aFirstPoint2, aLastPoint2;
+  Standard_Integer anExtIndex = -1;
+  Handle(Geom_Curve) anExtCurve;
+  Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
+  if (!AIS::ComputeGeometry (aFirstEdge, aSecondEdge,
+                             anExtIndex,
+                             aFirstLine, aSecondLine,
+                             aFirstPoint1, aLastPoint1,
+                             aFirstPoint2, aLastPoint2,
+                             anExtCurve,
+                             isInfinite1, isInfinite2,
+                             aGeomPlane))
+  {
+    return Standard_False;
   }
 
-  gp_Pnt curpos; // cursor position
-  TColStd_Array1OfReal tabdist(1,4);
-  gp_Pnt P1, P2; // points at intersection of the circle with 2 straight lines
-  if (myAutomaticPosition) {
-    if (!isInfinite1) {
-      tabdist(1) = myCenter.Distance(ptat11);
-      tabdist(2) = myCenter.Distance(ptat12);
-    }
-    else {
-      tabdist(1) = tabdist(2) = 0.;
-    }
-    if (!isInfinite2) { 
-      tabdist(3) = myCenter.Distance(ptat21);
-      tabdist(4) = myCenter.Distance(ptat22);
-    }
-    else {
-      tabdist(3) = tabdist(4) = 0.;
-    }
-    if ( SameLines ) {
-      Standard_Real dist1(RealLast());
-      if (!isInfinite1) dist1 = Max(tabdist(1),tabdist(2));
-      Standard_Real dist2(RealLast());
-      if (!isInfinite2) dist2 = Max(tabdist(3),tabdist(4));      
-      
-      myFAttach = myCenter;
-      mySAttach = myCenter;
-      P1 = myFAttach;
-      P2 = mySAttach;
-
-      myCenter.Translate(gp_Vec(d1)*theLength);
-
-      // calculate attachments of the face 
-      //  -> they are points of intersection if  
-      //     intersection is outside of the edges
-      Standard_Real pparam = ElCLib::Parameter(gpl1,myFAttach);
-      Standard_Real pparam1 = ElCLib::Parameter(gpl1,ptat11);
-      Standard_Real pparam2 = ElCLib::Parameter(gpl1,ptat12);
-      if (!isInfinite1) {
-       if ( pparam1 < pparam2 ) {
-         if ( pparam < pparam1 ) myFAttach = ptat11;
-         else if ( pparam > pparam2) myFAttach = ptat12;
-       }
-       else {
-         if ( pparam < pparam2) myFAttach = ptat12;
-         else if ( pparam > pparam1) myFAttach = ptat11;
-       }
-      }
-      if (!isInfinite2) {
-       pparam = ElCLib::Parameter(gpl2,myFAttach);
-       pparam1 = ElCLib::Parameter(gpl2,ptat21);
-       pparam2 = ElCLib::Parameter(gpl2,ptat22);
-       if ( pparam1 < pparam2 ) {
-         if ( pparam < pparam1 ) mySAttach = ptat21;
-         else if ( pparam > pparam2) mySAttach = ptat22;
-       }
-       else {
-         if ( pparam < pparam2) mySAttach = ptat22;
-         else if ( pparam > pparam1) mySAttach = ptat21;
-       }
-      }
-    }
-    // Case of disconneted lines
-    else {
-      gp_Ax2 AX(myCenter,theaxis,d1);
-      Handle(Geom_Circle)  circle = new Geom_Circle(AX,theLength);
-      Handle(Geom2d_Curve) geoCurve = GeomAPI::To2d(circle,myPlane->Pln());
-      Handle(Geom2d_Circle) c2d = *((Handle(Geom2d_Circle)*)& geoCurve);
-      // calculate the intersection of circle with l1
-      Standard_Real pparam; // parameter of the point of intersection on l1
-      IntAna2d_AnaIntersection inter(l1_2d->Lin2d(),c2d->Circ2d());
-      gp_Pnt2d pint1(inter.Point(1).Value());
-      gp_Pnt2d pint2(inter.Point(2).Value());
-      
-      gp_Pnt Int1 = adp.Value(pint1.X(),pint1.Y());
-      gp_Pnt Int2 = adp.Value(pint2.X(),pint2.Y());
-      gp_Dir I1I2(gp_Vec(Int1,Int2));
-      if ( d1*I1I2 > 0 ) {
-       myFAttach = Int2;
-       pparam = inter.Point(2).ParamOnFirst();
-      }
-      else {
-       myFAttach = Int1;
-       pparam = inter.Point(1).ParamOnFirst();
-      }
-      P1 = myFAttach;
-
-      Standard_Real pparam1;
-      Standard_Real pparam2; 
-      if (!isInfinite1) {
-       pparam1 = ElCLib::Parameter(gpl1,ptat11);
-       pparam2 = ElCLib::Parameter(gpl1,ptat12);       
-       if ( pparam1 < pparam2 ) {
-         if ( pparam < pparam1 ) myFAttach = ptat11;
-         else if ( pparam > pparam2) myFAttach = ptat12;
-       }
-       else {
-         if ( pparam < pparam2) myFAttach = ptat12;
-         else if ( pparam > pparam1) myFAttach = ptat11;
-       }
+  // Check if both edges are on this plane
+  if (!anExtCurve.IsNull())
+  {
+    if (anExtIndex == 1) // First curve is out of the plane
+    {
+      // Project curve on the plane
+      if (myIsWorkingPlaneCustom)
+      {
+        aFirstLin2d = ProjLib::Project (aPlane, aFirstLin);
+        aFirstLin = ElCLib::To3d (aPlane.Position().Ax2(), aFirstLin2d);
       }
-      pparam = ElCLib::Parameter(gpl2,P1);
-      mySAttach = ElCLib::Value(pparam, gpl2);
-      P2 = mySAttach;
-
-      if (!isInfinite2) {
-       pparam1 = ElCLib::Parameter(gpl2,ptat21);
-       pparam2 = ElCLib::Parameter(gpl2,ptat22);
-       if ( pparam1 < pparam2 ) {
-         if ( pparam < pparam1 ) mySAttach = ptat21;
-         else if ( pparam > pparam2) mySAttach = ptat22;
-       }
-       else {
-         if ( pparam < pparam2) mySAttach = ptat22;
-         else if ( pparam > pparam1) mySAttach = ptat21;
-       }
+      else
+      {
+        aFirstLin.Translate (gp_Vec (aFirstLin.Location(), aSecondLin.Location()));
       }
-    }
-    curpos.SetXYZ(.5*(P1.XYZ()+P2.XYZ()));
-
-    gp_Ax2 ax(myCenter,theaxis,d1);
-    gp_Circ circle(ax,theLength);
-    Standard_Real par = ElCLib::Parameter(circle,curpos);
-    curpos = ElCLib::Value(par,circle);
 
-    if (myIsSetBndBox)
-      curpos = AIS::TranslatePointToBound( curpos, gp_Dir( gp_Vec( myCenter, curpos ) ), myBndBox );
-    myPosition =curpos;
-    myAutomaticPosition = Standard_True;      
-  }
-  else {
-    curpos = myPosition;
-    gp_Lin Media(myCenter, gpl1.Direction());
-    Standard_Real pcurpos = ElCLib::Parameter(Media, curpos);
-    myCenter =  ElCLib::Value(pcurpos, Media);
-    // the centre is translated to avoid a constant radius!
-    myCenter.Translate(-theLength*gp_Vec(gpl1.Direction()));
-    gp_Ax2 AX(myCenter,theaxis,gpl1.Direction());
-    Handle(Geom_Circle)  circle = new Geom_Circle(AX,theLength);
-
-    // re-update curpos
-    pcurpos = ElCLib::Parameter(circle->Circ(), curpos);
-    curpos = ElCLib::Value(pcurpos, circle->Circ());
-
-    Handle(Geom2d_Curve) geoCurve = GeomAPI::To2d(circle,myPlane->Pln());
-    Handle(Geom2d_Circle) c2d = *((Handle(Geom2d_Circle)*)& geoCurve);
-    // calculate the point of intersection of circle with l1
-    IntAna2d_AnaIntersection inter(l1_2d->Lin2d(),c2d->Circ2d());
-    gp_Pnt2d pint1(inter.Point(1).Value());
-    gp_Pnt2d pint2(inter.Point(2).Value());
-    gp_Pnt Int1 = adp.Value(pint1.X(),pint1.Y());
-    gp_Pnt Int2 = adp.Value(pint2.X(),pint2.Y());
-    if ( curpos.SquareDistance(Int1) < curpos.SquareDistance(Int2)) myFAttach = Int1;
-    else myFAttach = Int2;
-    P1 = myFAttach;
-    
-    // calculate the point of intersection of circle with l2
-    // -> this is the projection because the centre of circle
-    //    is in the middle of l1 and l2
-    Standard_Real pparam = ElCLib::Parameter(gpl2,myFAttach);
-    mySAttach = ElCLib::Value(pparam, gpl2);
-
-    P2 = mySAttach;
-
-    Standard_Real par_attach(ElCLib::Parameter(gpl1,myFAttach));
-    Standard_Real par1,par2; 
-    if (!isInfinite1) {
-      par1 = ElCLib::Parameter(gpl1,ptat11);
-      par2 = ElCLib::Parameter(gpl1,ptat12);
-      if (par1 < par2) {
-       if ( par_attach < par1 ) myFAttach = ptat11;
-       else if ( par_attach > par2) myFAttach = ptat12;
-      }
-      else {
-       if ( par_attach < par2 ) myFAttach = ptat12;
-       else if ( par_attach > par1) myFAttach = ptat11;
-      }
+      aFirstLine = new Geom_Line (aFirstLin);
     }
-    par_attach = ElCLib::Parameter(gpl2,mySAttach);
-    if (!isInfinite2) {
-      par1 = ElCLib::Parameter(gpl2,ptat21);
-      par2 = ElCLib::Parameter(gpl2,ptat22);
-      if (par1 < par2) {
-       if ( par_attach < par1 ) mySAttach = ptat21;
-       else if ( par_attach > par2) mySAttach = ptat22;
+    else if (anExtIndex == 2) // Second curve is out of the plane
+    {
+      if (myIsWorkingPlaneCustom)
+      {
+        aSecondLin2d = ProjLib::Project (aPlane, aSecondLin);
+        aSecondLin = ElCLib::To3d (aPlane.Position().Ax2(), aSecondLin2d);
       }
-      else {
-       if ( par_attach < par2 ) mySAttach = ptat22;
-       else if ( par_attach > par1) mySAttach = ptat21;
+      else
+      {
+        aSecondLin.Translate (gp_Vec (aSecondLin.Location(), aFirstLin.Location()));
       }
+
+      aSecondLine = new Geom_Line (aSecondLin);
     }
   }
 
-  myFDir = gp_Dir(gp_Vec(myCenter,P1));
-  mySDir = gp_Dir(gp_Vec(myCenter,P2));
-
-  //--------------------------------------------------------
-  //    Computation of the presentation
-  //--------------------------------------------------------
-  Handle(Prs3d_AngleAspect) la = myDrawer->AngleAspect();
-  Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();
-
-  arr->SetLength(myArrowSize);
-
-  if (SameLines)
-    DsgPrs_AnglePresentation::Add(aPresentation,
-                                 myDrawer,
-                                 myVal,
-                                 myText,
-                                 myCenter,
-                                 myFAttach,
-                                 mySAttach,
-                                 myFDir,
-                                 mySDir,
-                                 theaxis,
-                                 Standard_True,
-                                 myAxis,
-                                 curpos,
-                                 DsgPrs_AS_NONE);
-  else
-    DsgPrs_AnglePresentation::Add(aPresentation,
-                                 myDrawer,
-                                 myVal,
-                                 myText,
-                                 myCenter,
-                                 myFAttach,
-                                 mySAttach,
-                                 myFDir,
-                                 mySDir,
-                                 curpos,
-                                 mySymbolPrs);
-}
-
+  /// PART 2 is for dimension computation using the working plane
 
-//=======================================================================
-//function : Compute3DSelection
-// purpose  : compute the zones of selection for an angle dimension
-//            between 2 faces
-//=======================================================================
-
-void AIS_AngleDimension::Compute3DSelection( const Handle( SelectMgr_Selection )& aSelection )
-{
-  gp_Circ AngleCirc, AttachCirc;
-  Standard_Real FirstParAngleCirc, LastParAngleCirc, FirstParAttachCirc, LastParAttachCirc;
-  gp_Pnt EndOfArrow1, EndOfArrow2, ProjAttachPoint2;
-  gp_Dir DirOfArrow1, DirOfArrow2;
-  gp_Dir axisdir = (myVal <= Precision::Angular() || Abs( M_PI-myVal ) <= Precision::Angular())?
-                    myPlane->Pln().Axis().Direction() : (myFDir ^ mySDir);
-  Standard_Boolean isPlane = (myFirstSurfType == AIS_KOS_Plane)? Standard_True : Standard_False;
-
-  Standard_Real ArrowLength = myDrawer->AngleAspect()->ArrowAspect()->Length();
-  DsgPrs::ComputeFacesAnglePresentation( ArrowLength,
-                                        myVal,
-                                        myCenter,
-                                        myFAttach,
-                                        mySAttach,
-                                        myFDir,
-                                        mySDir,
-                                        axisdir,
-                                        isPlane,
-                                        myAxis,
-                                        myPosition,
-                                        AngleCirc,
-                                        FirstParAngleCirc,
-                                        LastParAngleCirc,
-                                        EndOfArrow1,
-                                        EndOfArrow2,
-                                        DirOfArrow1,
-                                        DirOfArrow2,
-                                        ProjAttachPoint2,
-                                        AttachCirc,
-                                        FirstParAttachCirc,
-                                        LastParAttachCirc );
-  
-  Handle( SelectMgr_EntityOwner ) own = new SelectMgr_EntityOwner( this, 7 );
-  Handle( Select3D_SensitiveSegment ) seg;
-  Handle( Geom_TrimmedCurve ) curve; 
-  Handle( Select3D_SensitiveCurve ) SensCurve;
+  if (aFirstLin.Direction ().IsParallel (aSecondLin.Direction (), Precision::Angular ()))
+  {
+    // Parallel lines
+    isSameLines = aFirstLin.Distance(aSecondLin.Location()) <= Precision::Confusion();
+    if (!isSameLines)
+      return Standard_False;
+
+     myFirstPoint = aFirstLin.Location();
+     mySecondPoint = ElCLib::Value (ElCLib::Parameter (aFirstLin, myFirstPoint), aSecondLin);
+     if (mySecondPoint.Distance (mySecondPoint) <= Precision::Confusion ())
+       mySecondPoint.Translate (gp_Vec (aSecondLin.Direction ())*Abs(GetFlyout()));
+     myCenter.SetXYZ( (myFirstPoint.XYZ() + mySecondPoint.XYZ()) / 2. );
+  }
+  else
+  {
+    // Find intersection
+    aFirstLin2d = ProjLib::Project (aPlane, aFirstLin);
+    aSecondLin2d = ProjLib::Project (aPlane, aSecondLin);
 
-  // Angle's arc or line
-  if (myVal > Precision::Angular() && Abs( M_PI-myVal ) > Precision::Angular())
+    IntAna2d_AnaIntersection anInt2d (aFirstLin2d, aSecondLin2d);
+    gp_Pnt2d anIntersectPoint;
+    if (!anInt2d.IsDone() || anInt2d.IsEmpty())
     {
-      curve = new Geom_TrimmedCurve( new Geom_Circle( AngleCirc ), FirstParAngleCirc, LastParAngleCirc );
-      SensCurve = new Select3D_SensitiveCurve( own, curve );
-      aSelection->Add( SensCurve );
-    }
-  else // angle's line
-    {
-      gp_Vec ArrowVec( DirOfArrow1 );
-      ArrowVec *= ArrowLength;
-      gp_Pnt FirstPoint, LastPoint;
-
-      if (myPosition.Distance( EndOfArrow1 ) > ArrowLength)
-       {
-         FirstPoint = myPosition;
-         LastPoint = EndOfArrow1.Translated( ArrowVec );
-         if (myPosition.SquareDistance( LastPoint ) < myPosition.SquareDistance( EndOfArrow1 ))
-           LastPoint = EndOfArrow1.Translated( -ArrowVec );
-       }
-      else
-       {
-         FirstPoint = EndOfArrow1.Translated( ArrowVec );
-         LastPoint = EndOfArrow1.Translated( -ArrowVec );
-       }
-      seg = new Select3D_SensitiveSegment( own, FirstPoint, LastPoint );
-      aSelection->Add( seg );
+      return Standard_False;
     }
 
-  if (! myFAttach.IsEqual( EndOfArrow1, Precision::Confusion() ))
-    {
-      seg = new Select3D_SensitiveSegment( own, myFAttach, EndOfArrow1 );
-      aSelection->Add( seg );
-    }
-  if (! ProjAttachPoint2.IsEqual( EndOfArrow2, Precision::Confusion() ))
-    {
-      seg = new Select3D_SensitiveSegment( own, ProjAttachPoint2, EndOfArrow2 );
-      aSelection->Add( seg );
-    }
+    anIntersectPoint = gp_Pnt2d (anInt2d.Point(1).Value());
+    myCenter = ElCLib::To3d(aPlane.Position().Ax2(), anIntersectPoint);
 
-  // Line or arc from mySAttach to its "projection"
-  if (! mySAttach.IsEqual( ProjAttachPoint2, Precision::Confusion() ))
+    if (isInfinite1 || isInfinite2)
     {
-      if (isPlane)
-       {
-         seg = new Select3D_SensitiveSegment( own, mySAttach, ProjAttachPoint2 );
-         aSelection->Add( seg );
-       }
-      else
-       {
-         curve = new Geom_TrimmedCurve( new Geom_Circle( AttachCirc ),
-                                        FirstParAttachCirc,
-                                        LastParAttachCirc );
-         SensCurve = new Select3D_SensitiveCurve( own, curve );
-         aSelection->Add( SensCurve );
-       }
+      myFirstPoint  = myCenter.Translated (gp_Vec (aFirstLin.Direction())*Abs (GetFlyout()));
+      mySecondPoint = myCenter.Translated (gp_Vec (aSecondLin.Direction())*Abs (GetFlyout()));
+      return Standard_True;
     }
 
-  // Text
-  Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
-  Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( own,
-                                                                  myPosition.X(),
-                                                                  myPosition.Y(),
-                                                                  myPosition.Z(),
-                                                                  myPosition.X() + size,
-                                                                  myPosition.Y() + size,
-                                                                  myPosition.Z() + size);  
-  aSelection->Add(box);
+    // |
+    // | <- dimension should be here
+    // *----
+    myFirstPoint  = myCenter.Distance (aFirstPoint1) > myCenter.Distance (aLastPoint1) ? aFirstPoint1 : aLastPoint1;
+    mySecondPoint = myCenter.Distance (aFirstPoint2) > myCenter.Distance (aLastPoint2) ? aFirstPoint2 : aLastPoint2;
+  }
+  return Standard_True;
 }
 
 //=======================================================================
-//function : Compute2DSelection
-//purpose  : compute zones of selection on a side of angle between 2 edges
-//           Special processing of zero angles!
+//function : canTextBeInCenter
+//purpose  : Auxiliary method to arrange text and arrows
 //=======================================================================
 
-void AIS_AngleDimension::Compute2DSelection(const Handle(SelectMgr_Selection)& aSelection)
+Standard_Boolean AIS_AngleDimension::canTextBeInCenter (const gp_Pnt& theFirstAttach,
+                                                        const gp_Pnt& theSecondAttach,
+                                                        const Quantity_Length& theTextLength,
+                                                        const Quantity_Length& theArrowLength)
 {
-  BRepAdaptor_Curve cu1(TopoDS::Edge(myFShape));
-  BRepAdaptor_Curve cu2(TopoDS::Edge(mySShape));
-
-  gp_Lin l1(cu1.Line());
-  gp_Lin l2(cu2.Line());
-
-  // it is patch!
-  if (Abs( myVal ) <= Precision::Angular() || Abs( M_PI - myVal ) <= Precision::Angular())
-/*
-  //---------------------------------------------------------
-  //    Cas de droites paralleles ( <=> angle nul a M_PI pres)
-  if ((Abs(l1.Angle(l2)) < Precision::Angular()) ||
-      (Abs((l1.Angle(l2) - M_PI)) < Precision::Angular()) )
-*/
-    {
-       
-    Standard_Real distLL= l1.Distance(l2);
-    if ( Abs(distLL) <= Precision::Confusion() ) {
-      gp_Pnt ptat11 = cu1.Value(cu1.FirstParameter());
-      gp_Pnt ptat12 = cu1.Value(cu1.LastParameter());
-      gp_Pnt ptat21 = cu2.Value(cu2.FirstParameter());
-      gp_Pnt ptat22 = cu2.Value(cu2.LastParameter());
-      distLL =  0.75 * Max( ptat11.Distance(ptat12), ptat21.Distance(ptat22));
-      ComputeNull2DSelection(aSelection, distLL);
-    }
-    else {
-      ComputeNull2DSelection(aSelection, distLL*8/10);
-    }
-  }
-  
-  //----------------------------------------------------------
-  //  Classic case  ( angle != 0 )
-  else {
-
-    if (myFDir.IsParallel(mySDir,Precision::Angular())) {
-      Standard_Real distLL= l1.Distance(l2);
-      if ( Abs(distLL) <= Precision::Confusion() ) {
-       gp_Pnt ptat11 = cu1.Value(cu1.FirstParameter());
-       gp_Pnt ptat12 = cu1.Value(cu1.LastParameter());
-       gp_Pnt ptat21 = cu2.Value(cu2.FirstParameter());
-       gp_Pnt ptat22 = cu2.Value(cu2.LastParameter());
-       distLL =  0.75 * Max( ptat11.Distance(ptat12), ptat21.Distance(ptat22));
-       ComputeNull2DSelection(aSelection, distLL*8/10);
-      }
-    }
-    else {
-      gp_Dir Norm = myFDir.Crossed(mySDir);
-      
-      gp_Ax2 ax(myCenter,Norm,myFDir);
-      gp_Circ cer(ax,myCenter.Distance(myPosition));
-      gp_Vec vec1(myFDir);
-      
-      Standard_Boolean nullrad(Standard_False);
-      if (cer.Radius() == 0.) {
-       cer.SetRadius(1.);
-       nullrad = Standard_True;
-      }
-      vec1 *= cer.Radius();
-      gp_Pnt p1 = myCenter.Translated(vec1);
-      gp_Vec vec2(mySDir);
-      vec2 *= cer.Radius();
-      gp_Pnt p2 = myCenter.Translated(vec2);
-      
-      Standard_Real uc1 = 0.;
-      Standard_Real uc2 = ElCLib::Parameter(cer,p2);
-      Standard_Real uco;
-      if (nullrad) uco = ElCLib::Parameter(cer,p1);
-      else uco = ElCLib::Parameter(cer,myPosition);
-      
-      Standard_Real udeb = uc1;
-      Standard_Real ufin = uc2;
-      
-      if (uco > ufin) {
-       if (Abs(myVal)<M_PI) {
-         // test if uco is in the opposing sector 
-         if (uco > udeb+M_PI && uco < ufin+M_PI){
-           udeb = udeb + M_PI;
-         ufin = ufin + M_PI;
-           uc1  = udeb;
-           uc2  = ufin;
-         }
-      }
-      }  
-      if (uco > ufin) {
-       if ((uco-uc2) < (uc1-uco+(2*M_PI))) ufin = uco;
-       else udeb = uco - 2*M_PI;
-      }
-      p1   = ElCLib::Value(udeb,cer);
-      p2   = ElCLib::Value(ufin,cer);
-      
-      //Create 2 owners for each part of the arrow
-      Handle(AIS_DimensionOwner) own1 = new AIS_DimensionOwner(this,7);
-      Handle(AIS_DimensionOwner) own2 = new AIS_DimensionOwner(this,7);
-      if (myExtShape != 0) {
-       if (myExtShape == 1) {
-         own1->SetShape(mySShape);
-         own2->SetShape(mySShape);
-       }
-       else {
-         own1->SetShape(myFShape);
-         own2->SetShape(myFShape);
-       }
-      }
-      else {
-       own1->SetShape(myFShape);
-       own2->SetShape(mySShape);
-      }
-      
-      Handle(Geom_Circle) thecirc = new Geom_Circle(cer);
-      
-      Handle(Geom_TrimmedCurve) thecu1 = new Geom_TrimmedCurve(thecirc,udeb,(udeb+ufin)/2);
-      Handle(Geom_TrimmedCurve) thecu2 = new Geom_TrimmedCurve(thecirc,(udeb+ufin)/2,ufin);
-      
-      Handle(Select3D_SensitiveCurve) scurv = new Select3D_SensitiveCurve(own1,thecu1);
-      aSelection->Add(scurv);
-      scurv = new Select3D_SensitiveCurve(own2,thecu2);
-      aSelection->Add(scurv);
-      
-      Handle(Select3D_SensitiveSegment) seg;
-      if (!myFAttach.IsEqual(p1,Precision::Confusion())) {
-       seg = new Select3D_SensitiveSegment(own1,myFAttach,p1);
-       aSelection->Add(seg);
-      }
-      if (!mySAttach.IsEqual(p2,Precision::Confusion())) {
-       seg = new Select3D_SensitiveSegment(own2,mySAttach,p2);
-       aSelection->Add(seg);
-      }
-    }
-  }
+  gp_Vec anAttachVector (theFirstAttach, theSecondAttach);
+  Standard_Real aValue = anAttachVector.Magnitude();
+  return (aValue < theTextLength + 2.*theArrowLength) ? Standard_False : Standard_True;
+}
 
+//=======================================================================
+//function: getCenterOnArc
+//purpose :
+//=======================================================================
+gp_Pnt AIS_AngleDimension::getCenterOnArc (const gp_Pnt& theFirstAttach,
+                                           const gp_Pnt& theSecondAttach)
+{
+  gp_Pnt2d aCenter2d       = ProjLib::Project (GetWorkingPlane(), myCenter),
+           aFirstAttach2d  = ProjLib::Project (GetWorkingPlane(), theFirstAttach),
+           aSecondAttach2d = ProjLib::Project (GetWorkingPlane(), theSecondAttach);
+  gp_Lin2d anAttachLine2d = gce_MakeLin2d (aFirstAttach2d, aSecondAttach2d);
+
+  // Getting text center
+  gp_Pnt2d aTextCenterPnt = ElCLib::Value ((ElCLib::Parameter (anAttachLine2d, aFirstAttach2d) + ElCLib::Parameter (anAttachLine2d, aSecondAttach2d)) / 2., anAttachLine2d);
+  gp_Lin2d aCenterToTextCenterLin = gce_MakeLin2d (aCenter2d, aTextCenterPnt);
+
+  // Drawing circle
+  Standard_Real aRadius = theFirstAttach.Distance (myCenter);
+  gp_Circ2d aCircle (gp_Ax22d (aCenter2d, gp_Dir2d (1, 0)), aRadius);
+
+  // Getting text position in the center of arc
+  IntAna2d_AnaIntersection anInt2d (aCenterToTextCenterLin, aCircle);
+  gp_Pnt2d aTextCenterOnArc2d;
+  if (anInt2d.IsDone())
+    if (!anInt2d.IsEmpty())
+      aTextCenterOnArc2d = gp_Pnt2d (anInt2d.Point (1).Value());
+  gp_Pnt aCenterOnArc = ElCLib::To3d (GetWorkingPlane().Position().Ax2(), aTextCenterOnArc2d);
+  return aCenterOnArc;
 }
+
 //=======================================================================
-//function : Compute2DNullSelection
-//purpose  : for dimension of null angle
+//function: drawArcWithText
+//purpose :
 //=======================================================================
 
-void AIS_AngleDimension::ComputeNull2DSelection(
-                        const Handle(SelectMgr_Selection)& aSelection,
-                        const Standard_Real distLL)
+void AIS_AngleDimension::drawArcWithText (const Handle(Prs3d_Presentation)& thePresentation,
+                                          const gp_Pnt& theFirstAttach,
+                                          const gp_Pnt& theSecondAttach,
+                                          const TCollection_ExtendedString& theText,
+                                          const AIS_DimensionDisplayMode theMode)
 {
-  gp_Dir Norm; 
-  if ( myFDir.IsParallel(mySDir, Precision::Angular()) ) {
-    Norm = myPlane->Pln().Axis().Direction();
+  gp_Pnt2d aCenter2d       = ProjLib::Project (GetWorkingPlane(), myCenter),
+           aFirstAttach2d  = ProjLib::Project (GetWorkingPlane(), theFirstAttach),
+           aSecondAttach2d = ProjLib::Project (GetWorkingPlane(), theSecondAttach);
+  gp_Lin2d anAttachLine2d = gce_MakeLin2d (aFirstAttach2d, aSecondAttach2d);
+
+  // Getting text center
+  gp_Pnt2d aTextCenterPnt = ElCLib::Value ((ElCLib::Parameter (anAttachLine2d, aFirstAttach2d) + ElCLib::Parameter (anAttachLine2d, aSecondAttach2d)) / 2., anAttachLine2d);
+  gp_Lin2d aCenterToTextCenterLin = gce_MakeLin2d (aCenter2d, aTextCenterPnt);
+
+  // Drawing circle
+  Standard_Real aRadius = theFirstAttach.Distance (myCenter);
+  gp_Circ2d aCircle (gp_Ax22d (aCenter2d, gp_Dir2d (1, 0)), aRadius);
+
+  // Getting text position in the center of arc
+  IntAna2d_AnaIntersection anInt2d (aCenterToTextCenterLin, aCircle);
+  gp_Pnt2d aTextCenterOnArc2d;
+  if (anInt2d.IsDone())
+    if (!anInt2d.IsEmpty())
+      aTextCenterOnArc2d = gp_Pnt2d (anInt2d.Point (1).Value());
+  myGeom.myTextPosition = ElCLib::To3d (GetWorkingPlane().Position().Ax2(), aTextCenterOnArc2d);
+
+  // Drawing text
+  gp_Vec aVec (theFirstAttach, theSecondAttach);
+  Standard_Real aTextWidth = drawText (thePresentation,
+                                       myIsTextReversed ? aVec.Reversed() : aVec,
+                                       theText,theMode);
+
+  // Getting text begin and end points
+  gp_Pnt2d aTextBeginPnt = ElCLib::Value ((ElCLib::Parameter (anAttachLine2d, aFirstAttach2d) +
+                                           ElCLib::Parameter (anAttachLine2d, aSecondAttach2d) -
+                                           aTextWidth) / 2., anAttachLine2d),
+           aTextEndPnt   = ElCLib::Value (ElCLib::Parameter (anAttachLine2d,aTextBeginPnt) + aTextWidth, anAttachLine2d);
+
+
+  gp_Lin2d aCenterToTextBeginLin = gce_MakeLin2d (aCenter2d, aTextBeginPnt),
+           aCenterToTextEndLin   = gce_MakeLin2d (aCenter2d, aTextEndPnt);
+
+  // Text begin and end on the dimension arc
+  gp_Pnt2d aTextBeginOnArc2d, aTextEndOnArc2d;
+  anInt2d.Perform (aCenterToTextBeginLin, aCircle);
+  if (anInt2d.IsDone())
+    if (!anInt2d.IsEmpty())
+      aTextBeginOnArc2d = gp_Pnt2d (anInt2d.Point (1).Value());
+
+  anInt2d.Perform (aCenterToTextEndLin, aCircle);
+  if (anInt2d.IsDone())
+    if (!anInt2d.IsEmpty())
+      aTextEndOnArc2d = gp_Pnt2d (anInt2d.Point (1).Value());
+
+  gp_Pnt aTextBeginOnArc = ElCLib::To3d (GetWorkingPlane().Position().Ax2(), aTextBeginOnArc2d);
+  gp_Pnt aTextEndOnArc   = ElCLib::To3d (GetWorkingPlane().Position().Ax2(), aTextEndOnArc2d);
+
+  // Drawing arcs
+  if (theMode != AIS_DDM_Text)
+  {
+    drawArc (thePresentation, theFirstAttach, aTextBeginOnArc, myCenter, aRadius, theMode);
+    drawArc (thePresentation, aTextEndOnArc, theSecondAttach, myCenter, aRadius, theMode);
   }
-  else
-    Norm = myFDir.Crossed(mySDir);
 
-  gp_Ax2 ax(myCenter,Norm,myFDir);
-  gp_Circ cer(ax,distLL);
-  
-  gp_Vec vec1(myFDir);
-  vec1 *= cer.Radius();
-  gp_Pnt p1 = myCenter.Translated(vec1);
-  gp_Vec vec2(mySDir);
-  vec2 *= cer.Radius();
-  gp_Pnt p2 = myCenter.Translated(vec2);
-
-  // calcul de parametres de debut et de fin des extremites de l'arc
-  Standard_Real uc1 = 0.;
-  Standard_Real uc2 = ElCLib::Parameter(cer,p2);
-  Standard_Real uco = ElCLib::Parameter(cer,myPosition);
-
-  Standard_Real udeb = uc1;
-  Standard_Real ufin = uc2;
-
-  if (uco > ufin) {
-    if (Abs(myVal)<M_PI) {
-      // test if uco is in the opposing sector 
-      if (uco > udeb+M_PI && uco < ufin+M_PI){
-       udeb = udeb + M_PI;
-       ufin = ufin + M_PI;
-       uc1  = udeb;
-       uc2  = ufin;
-      }
-    }
-  }
+}
 
-  if (uco > ufin) {
-    if ((uco-uc2) < (uc1-uco+(2*M_PI))) {
-      ufin = uco;
-    }
-    else {
-      udeb = uco - 2*M_PI;
-    }
-  }
+//=======================================================================
+//function : drawArc
+//purpose  : draws the arc between two attach points
+//=======================================================================
 
-  //Create 2 owners for each part of the arrow
-  Handle(AIS_DimensionOwner) own1 = new AIS_DimensionOwner(this,7);
-  Handle(AIS_DimensionOwner) own2 = new AIS_DimensionOwner(this,7);
-  if (myExtShape != 0) {
-    if (myExtShape == 1) {
-      own1->SetShape(mySShape);
-      own2->SetShape(mySShape);
-    }
-    else {
-      own1->SetShape(myFShape);
-      own2->SetShape(myFShape);
-    }
-  }
-  else {
-    own1->SetShape(myFShape);
-    own2->SetShape(mySShape);
+void AIS_AngleDimension::drawArc (const Handle(Prs3d_Presentation)& thePresentation,
+                                  const gp_Pnt& theFirstAttach,
+                                  const gp_Pnt& theSecondAttach,
+                                  const gp_Pnt& theCenter,
+                                  const Standard_Real theRadius,
+                                  const AIS_DimensionDisplayMode theMode)
+{
+  Handle(SelectMgr_EntityOwner) anEmptyOwner;
+  Prs3d_Root::CurrentGroup (thePresentation)->
+    SetPrimitivesAspect(myDrawer->DimensionAspect()->LineAspect()->Aspect());
+
+  gp_Vec aCenterToFirstVec (theCenter,theFirstAttach);
+  gp_Vec aCenterToSecondVec (theCenter,theSecondAttach);
+  gp_Dir aCenterToFirstDir (aCenterToFirstVec);
+  gp_Dir aPlaneNormal = GetWorkingPlane().Axis().Direction();
+  gp_Dir aCenterToSecondDir = aPlaneNormal.Crossed (aCenterToFirstDir);
+
+  const Standard_Real anAngle = aCenterToFirstVec.Angle(aCenterToSecondVec);
+  const Standard_Integer aPointsOnArc = Max (4 , Standard_Integer (50. * anAngle / M_PI));
+  const Standard_Real anAngleStep = anAngle / (aPointsOnArc - 1);
+  TColgp_Array1OfPnt aPointArray (0,aPointsOnArc-1);
+  Handle(Graphic3d_ArrayOfPolylines) aPrimSegments = new Graphic3d_ArrayOfPolylines (aPointsOnArc,2);
+  aPrimSegments->AddVertex (theFirstAttach);
+  aPointArray.SetValue(0, theFirstAttach);
+  gp_Pnt aPoint = theFirstAttach;
+  gp_Vec aVector;
+
+  for (Standard_Integer anI = 1; anI < aPointsOnArc - 1; ++anI)
+  {
+    aVector = (gp_Vec(aCenterToFirstDir) * Cos ( (anI - 1) * anAngleStep) + gp_Vec(aCenterToSecondDir) * Sin ( (anI - 1) * anAngleStep)) * theRadius;
+    aPoint = theCenter.Translated(aVector);
+    aPrimSegments->AddVertex(aPoint);
+    aPointArray.SetValue (anI,aPoint);
   }
-  
-  Handle(Geom_Circle) thecirc = new Geom_Circle(cer);
-
-  if ( udeb != ufin ) {
-    Handle(Geom_TrimmedCurve) thecu1 = new Geom_TrimmedCurve(thecirc,udeb,(udeb+ufin)/2);
-    Handle(Geom_TrimmedCurve) thecu2 = new Geom_TrimmedCurve(thecirc,(udeb+ufin)/2,ufin);
+  aPrimSegments->AddVertex (theSecondAttach);
+  aPointArray.SetValue (aPointsOnArc - 1,theSecondAttach);
 
-    Handle(Select3D_SensitiveCurve) scurv = new Select3D_SensitiveCurve(own1,thecu1);
-    aSelection->Add(scurv);
-    scurv = new Select3D_SensitiveCurve(own2,thecu2);
-    aSelection->Add(scurv);
-  }
-  else {
-    // find end of segment to allow selection
-    gp_Vec VTrans(myFDir.Crossed(Norm));
-    Handle(Select3D_SensitiveSegment) seg1;
-    seg1 = new Select3D_SensitiveSegment(own1, 
-                                        p1, 
-                                        p1.Translated( VTrans*distLL/10 ) );
-    aSelection->Add(seg1);
-    seg1 = new Select3D_SensitiveSegment(own2, 
-                                        p2, 
-                                        p2.Translated(-VTrans*distLL/10 ) );
-    aSelection->Add(seg1);
-  }
+  // Fill sensitive list
+  myGeom.mySensitiveSegments.Append(new Select3D_SensitiveCurve(anEmptyOwner,aPointArray));
 
-  Handle(Select3D_SensitiveSegment) seg;
-  if (!myFAttach.IsEqual(p1,Precision::Confusion())) {
-    seg = new Select3D_SensitiveSegment(own1,myFAttach,p1);
-    aSelection->Add(seg);
+  // Fill display presentation
+  if (!myDrawer->DimensionAspect()->IsText3d() && theMode == AIS_DDM_All)
+  {
+    Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_True);
   }
-    
-  if (!mySAttach.IsEqual(p2,Precision::Confusion())) {
-    seg = new Select3D_SensitiveSegment(own2,mySAttach,p2);
-    aSelection->Add(seg);
+  Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
+  if (!myDrawer->DimensionAspect()->IsText3d() && theMode == AIS_DDM_All)
+  {
+    Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_False);
   }
 }
 
-
 //=======================================================================
-//function : ComputeConeAngleSelection
-//purpose  : for cone angle
+//function : Compute
+//purpose  : Having three gp_Pnt points compute presentation
 //=======================================================================
-void AIS_AngleDimension::ComputeConeAngleSelection(const Handle(SelectMgr_Selection)& aSelection)
-{
-  if( myCone.IsNull() ) return;
-
 
-  Handle( SelectMgr_EntityOwner ) owner = new SelectMgr_EntityOwner( this, 7 );
-  Handle( Select3D_SensitiveSegment ) seg;
-  
-  gp_Pln aPln;
-  gp_Cone aCone;
-  gp_Circ myCircle;
-  gp_Pnt Apex;
-  Handle( Geom_Surface ) aSurf;         //a surface from the Face
-  Handle( Geom_OffsetSurface ) aOffsetSurf; 
-  Handle( Geom_ConicalSurface ) aConicalSurf;
-  Handle( Geom_SurfaceOfRevolution ) aRevSurf; 
-  Handle( Geom_Line ) aLine;
-  BRepAdaptor_Surface tmpSurf(myCone);  
-  TopoDS_Face aFace;
-  AIS_KindOfSurface aSurfType;
-  Standard_Real Offset = 0. ;
-  Handle( Standard_Type ) aType;
-
-  Standard_Real maxV = tmpSurf.FirstVParameter();
-  Standard_Real minV = tmpSurf.LastVParameter();
+void AIS_AngleDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePM*/,
+                                  const Handle(Prs3d_Presentation)& thePresentation,
+                                  const Standard_Integer theMode)
+{
+  thePresentation->Clear();
+  myGeom.mySensitiveSegments.Clear();
+  Handle(SelectMgr_EntityOwner) anEmptyOwner;
 
-  AIS::GetPlaneFromFace( myCone, aPln, aSurf, aSurfType, Offset );
-  
-  if ( aSurfType == AIS_KOS_Revolution ) {                                    //surface of revolution
-
-    aRevSurf = Handle( Geom_SurfaceOfRevolution )::DownCast( aSurf ); 
-    gp_Lin ln( aRevSurf->Axis() );
-    Handle( Geom_Curve ) tmpCrv = aRevSurf->BasisCurve();
-    if ( tmpCrv ->DynamicType() != STANDARD_TYPE(Geom_Line) )  return;        //Must be a part of line
-
-    Standard_Real par;
-    gp_Pnt fst = tmpSurf.Value(0., minV);
-    gp_Pnt lst = tmpSurf.Value(0., maxV);
-    gp_Vec vec1(fst, lst);
-   
-    par = ElCLib::Parameter( ln, fst );
-    gp_Pnt fst2 = ElCLib::Value( par, ln );                         //projection fst on ln
-    par = ElCLib::Parameter( ln, lst );
-    gp_Pnt lst2 = ElCLib::Value( par, ln );                         //projection lst on ln
-
-    gp_Vec vec2(fst2, lst2);
-
-   // Check if two parts of revolution are parallel ( it's a cylinder ) or normal (it's a circle ) 
-    if( vec1.IsParallel( vec2,Precision::Angular() ) || vec1.IsNormal( vec2,Precision::Angular() ) ) return; 
-    gce_MakeCone mkCone(aRevSurf->Axis(), fst, lst);
-    aCone =  mkCone.Value();
-    Apex = aCone.Apex();
-  }
-  else {  
-    aType = aSurf->DynamicType();
-    if ( aType == STANDARD_TYPE(Geom_OffsetSurface) || Offset > 0.01 ) {            //offset surface
-      aOffsetSurf = new Geom_OffsetSurface (aSurf, Offset);
-      aSurf = aOffsetSurf->Surface();
-      BRepBuilderAPI_MakeFace mkFace(aSurf, Precision::Confusion());
-      mkFace.Build();
-      if( !mkFace.IsDone() ) return;
-      tmpSurf.Initialize( mkFace.Face() );
-    }  
-    aCone = tmpSurf.Cone();
-    aConicalSurf = Handle( Geom_ConicalSurface)::DownCast( aSurf );
-    Apex =  aConicalSurf->Apex();
+  if (!myIsInitialized)
+  {
+    if (myShapesNumber == 1)
+    {
+      myIsInitialized = initConeAngle (TopoDS::Face (myFirstShape));
+    }
+    else if (myShapesNumber == 2)
+    {
+      switch (myFirstShape.ShapeType())
+      {
+      case TopAbs_FACE:
+        {
+          myIsInitialized = initTwoFacesAngle ();
+        }
+        break;
+      case TopAbs_EDGE:
+        {
+          myIsInitialized = initTwoEdgesAngle ();
+        }
+        break;
+      default:
+        return;
+      }
+    }
+    else
+      return;
   }
 
-  Handle(Geom_Curve) aCurve;                 //A circle where the angle is drawn
-  
-  if ( myAutomaticPosition ) {
-    Standard_Real midV = ( minV + maxV ) / 2.5; 
+  // If initialization failed
+  if (!myIsInitialized)
+    return;
 
-    aCurve =   aSurf->VIso(midV);
-    myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
+  // Parameters for presentation
+  Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
+  Prs3d_Root::CurrentGroup(thePresentation)->
+    SetPrimitivesAspect(aDimensionAspect->LineAspect()->Aspect());
+  Quantity_Length anArrowLength = aDimensionAspect->ArrowAspect()->Length();
+  if (!myIsValueCustom)
+    computeValue ();
+  TCollection_ExtendedString aValueString;
+  Standard_Real aTextLength;
+  getTextWidthAndString (aTextLength, aValueString);
+  if (!myIsWorkingPlaneCustom)
+    countDefaultPlane();
+  gp_Pnt aFirstAttach = myCenter.Translated (gp_Vec(myCenter, myFirstPoint).Normalized() * GetFlyout());
+  gp_Pnt aSecondAttach = myCenter.Translated (gp_Vec(myCenter, mySecondPoint).Normalized() * GetFlyout());
+  // Attach points and radius
+  if (aDimensionAspect->HorizontalTextAlignment () == Prs3d_HTA_Center)
+  {
+    aDimensionAspect->SetArrowOrientation (Prs3d_DAO_Internal);
 
-    myPosition = ElCLib::Value(M_PI / 2.0, myCircle);
-    myAutomaticPosition = Standard_False;
-  }
-  else {
-    Standard_Real U, V;
-    ElSLib::Parameters(aCone, myPosition, U, V);
-    aCurve = aSurf->VIso(V); 
-    myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
-  }
- //__________________________________________________________________
-  aCurve = aSurf->VIso(maxV);
-  gp_Circ CircVmax = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
-  aCurve = aSurf->VIso(minV);
-  gp_Circ CircVmin = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
- //__________________________________________________________________
-
-  if( CircVmax.Radius() < CircVmin.Radius() ) {
-   gp_Circ tmpCirc = CircVmax;
-   CircVmax = CircVmin;
-   CircVmin = tmpCirc;
+    if (!canTextBeInCenter (aFirstAttach, aSecondAttach, aTextLength, anArrowLength))
+    {
+      aDimensionAspect->SetArrowOrientation (Prs3d_DAO_External);
+      aDimensionAspect->SetHorizontalTextAlignment (Prs3d_HTA_Left);
+    }
   }
-  Standard_Boolean IsArrowOut = Standard_True;    //Is arrows inside or outside of the cone
-  //Standard_Real PntOnMainAxis = 0;   //Is projection of aPosition inside of the cone = 0, above = 1, or below = -1
-  Standard_Boolean IsConeTrimmed = Standard_False; 
-
-  if( CircVmin.Radius() > 0.01 ) IsConeTrimmed = Standard_True;
-
-  gp_Pnt AttachmentPnt;
-  gp_Pnt OppositePnt;
-
-  Standard_Real param = ElCLib::Parameter(myCircle, myPosition);
+  else
+    aDimensionAspect->SetArrowOrientation (Prs3d_DAO_External);
 
-  gp_Pnt aPnt = Apex;
-  gp_Pnt P1 = ElCLib::Value(0., myCircle);
-  gp_Pnt P2 = ElCLib::Value(M_PI, myCircle);
+  //Arrows positions and directions
+  gp_Vec aFirstArrowVec = (gp_Vec(myCenter, aFirstAttach)^gp_Vec(GetWorkingPlane().Axis().Direction())).Normalized().Reversed()*anArrowLength;
+  gp_Vec aSecondArrowVec = (gp_Vec(myCenter, aSecondAttach)^gp_Vec(GetWorkingPlane().Axis().Direction())).Normalized()*anArrowLength;
 
-  gce_MakePln mkPln(P1, P2, aPnt);   // create a plane whitch defines plane for projection aPosition on it
+  gp_Pnt aFirstArrowBegin,
+         aFirstArrowEnd,
+         aSecondArrowBegin,
+         aSecondArrowEnd;
 
-  aPnt = AIS::ProjectPointOnPlane(myPosition, mkPln.Value()); 
-  gp_Pnt tmpPnt = aPnt;
+  if (aDimensionAspect->GetArrowOrientation() == Prs3d_DAO_External)
+  {
+    aFirstArrowVec.Reverse();
+    aSecondArrowVec.Reverse();
 
-  if( aPnt.Distance(P1) <  aPnt.Distance(P2) ){
-    AttachmentPnt = P1; 
-    OppositePnt = P2; 
+    aFirstArrowBegin = aFirstAttach.Translated (aFirstArrowVec);
+    aFirstArrowEnd = aFirstAttach;
+    aSecondArrowBegin = aSecondAttach;
+    aSecondArrowEnd = aSecondAttach.Translated (aSecondArrowVec);
   }
-  else {
-    AttachmentPnt = P2; 
-    OppositePnt = P1;
+  else
+  {
+    aFirstArrowBegin = aFirstAttach;
+    aFirstArrowEnd = aFirstAttach.Translated (aFirstArrowVec);
+    aSecondArrowBegin = aSecondAttach.Translated (aSecondArrowVec);
+    aSecondArrowEnd = aSecondAttach;
   }
-  
-  aPnt = AttachmentPnt ;                          // Creating of circle whitch defines a plane for a dimension arc
-  gp_Vec Vec(AttachmentPnt, Apex);                // Dimension arc is a part of the circle 
-  Vec.Scale(2);
-  aPnt.Translate(Vec);
-  GC_MakeCircle mkCirc(AttachmentPnt, OppositePnt,  aPnt); 
-  gp_Circ  aCircle2 = mkCirc.Value()->Circ();
-
-  
-  Standard_Integer i;
-  Standard_Real AttParam = ElCLib::Parameter(aCircle2, AttachmentPnt);
-  Standard_Real OppParam = ElCLib::Parameter(aCircle2, OppositePnt);
-  
-  while ( AttParam >= 2 * M_PI ) AttParam -= 2 * M_PI;
-  while ( OppParam >= 2 * M_PI ) OppParam -= 2 * M_PI;
-
-  if( myPosition.Distance( myCircle.Location() ) <= myCircle.Radius() )
-    if( 2 * myCircle.Radius() > aCircle2.Radius() * 0.4 ) IsArrowOut = Standard_False;  //four times more than an arrow size
-
-  param = AttParam;
-  Standard_Real angle = OppParam - AttParam;
 
-  if(IsArrowOut)
+  // Fill presentation
+  Handle(Graphic3d_ArrayOfSegments) aPrimSegments;
+  Standard_Boolean isTextInCenter = aDimensionAspect->VerticalTextAlignment() == Prs3d_VTA_Center;
+  if (aDimensionAspect->HorizontalTextAlignment() == Prs3d_HTA_Center)
   {
-    angle += M_PI / 6; //An angle between AttParam and OppParam + 30 degrees
-    param -= M_PI / 12;      //out parts of dimension line are 15 degrees
+    // Important! Current implementation doesn't draw the extensions here
+    aPrimSegments = new Graphic3d_ArrayOfSegments (4);
+    // Get text begin and end positions (text is positioned in the center between two attach points)
+    gp_Pnt aTextBeginOnArc, aTextEndOnArc, anArcCenter;
+    if (isTextInCenter && aDimensionAspect->IsText3d())
+    {
+      drawArcWithText (thePresentation, aFirstAttach, aSecondAttach, aValueString, (AIS_DimensionDisplayMode)theMode);
+    }
+    else
+    {
+      gp_Vec aTextDir (aFirstArrowEnd, aSecondArrowBegin);
+      myGeom.myTextPosition = getCenterOnArc (aFirstArrowEnd, aSecondArrowBegin);
+      drawText (thePresentation,
+                myIsTextReversed ? aTextDir.Reversed() : aTextDir,
+                aValueString, (AIS_DimensionDisplayMode)theMode);
+      if (theMode != AIS_DDM_Text)
+        drawArc (thePresentation, aFirstArrowEnd, aSecondArrowBegin, myCenter, Abs (GetFlyout()), (AIS_DimensionDisplayMode)theMode);
+    }
   }
+  else
+  {
+    // Lines for extensions
+    gp_Lin aLeftExtension (aFirstAttach,gp_Dir(aFirstArrowVec));
+    gp_Lin aRightExtension (aSecondAttach, gp_Dir(aSecondArrowVec));
+    aPrimSegments = new Graphic3d_ArrayOfSegments (6);
+    gp_Pnt aStartPoint;
+    if (aDimensionAspect->HorizontalTextAlignment() == Prs3d_HTA_Left)
+    {
+       aStartPoint = aFirstArrowBegin;
+       // Short extension
+       aPrimSegments->AddVertex (aSecondArrowEnd);
+       aPrimSegments->AddVertex (aSecondArrowEnd.Translated(gp_Vec(aRightExtension.Direction())*anArrowLength));
+       myGeom.mySensitiveSegments.Append (new Select3D_SensitiveSegment(anEmptyOwner,
+                                          aSecondArrowEnd,
+                                          aSecondArrowEnd.Translated(gp_Vec(aRightExtension.Direction())*anArrowLength)));
+
+       // Long extension
+       drawExtensionWithText (thePresentation, aStartPoint, aLeftExtension, aValueString, (AIS_DimensionDisplayMode)theMode);
+    }
+    else // Prs3d_HTA_Right
+    {
+       aStartPoint = aSecondArrowEnd;
+       // Short extension
+       aPrimSegments->AddVertex (aFirstArrowBegin);
+       aPrimSegments->AddVertex (aFirstArrowBegin.Translated (gp_Vec (aLeftExtension.Direction()) * anArrowLength));
+       myGeom.mySensitiveSegments.Append (new Select3D_SensitiveSegment(anEmptyOwner,
+                                          aFirstArrowBegin,
+                                          aFirstArrowBegin.Translated (gp_Vec (aLeftExtension.Direction()) * anArrowLength)));
+
+       // Long extension
+       drawExtensionWithText (thePresentation, aStartPoint, aRightExtension, aValueString, (AIS_DimensionDisplayMode)theMode);
+    }
 
-  while ( angle > 2. * M_PI ) angle -= 2. * M_PI;
+    if (theMode != AIS_DDM_Text)
+    {
+      // Draw main arc
+      drawArc (thePresentation, aFirstArrowEnd, aSecondArrowBegin, myCenter, Abs(GetFlyout ()), (AIS_DimensionDisplayMode)theMode);
+    }
+  }
 
-  gp_Pnt Vprev = ElCLib::Value(param, aCircle2);
-  for( i = 1; i <= 11; i++ ) //calculating of arc
+  // Draw flyout lines and arrows in new group.
+  Prs3d_Root::NewGroup (thePresentation)
+    ->SetPrimitivesAspect (myDrawer->DimensionAspect()->LineAspect()->Aspect());
+  if (theMode == AIS_DDM_All && myIsFlyoutLines)
+  {
+    aPrimSegments->AddVertex (myCenter);
+    aPrimSegments->AddVertex (aFirstAttach);
+    aPrimSegments->AddVertex (myCenter);
+    aPrimSegments->AddVertex (aSecondAttach);
+  }
+  if (theMode != AIS_DDM_Text)
   {
-    gp_Pnt Vcur = ElCLib::Value(param + angle/11 * i, aCircle2);
-    seg = new Select3D_SensitiveSegment(owner, Vprev, Vcur);
-    aSelection->Add(seg);
-    Vprev = Vcur;
+    Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
+    drawArrow (thePresentation, aFirstAttach, gp_Dir (aFirstArrowVec));
+    drawArrow (thePresentation, aSecondAttach, gp_Dir (aSecondArrowVec));
   }
 
-  tmpPnt = tmpPnt.Translated(gp_Vec(0, 0, -2));
-
-  const Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
-  Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( owner,
-                                                                  tmpPnt.X(),
-                                                                  tmpPnt.Y(),
-                                                                  tmpPnt.Z(),
-                                                                  tmpPnt.X() + size,
-                                                                  tmpPnt.Y() + size,
-                                                                  tmpPnt.Z() + size);
-  aSelection->Add(box);
+  setComputed (Standard_True);
 }
diff --git a/src/AIS/AIS_AngleDimension.hxx b/src/AIS/AIS_AngleDimension.hxx
new file mode 100644 (file)
index 0000000..d783959
--- /dev/null
@@ -0,0 +1,177 @@
+// Copyright (c) 1995-1999 Matra Datavision
+// Copyright (c) 1999-2013 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.
+//
+// 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.
+//
+// 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.
+
+//! A framework to define display of angles. <br>
+//! These displays are particularly useful in viewing draft prisms. <br>
+//! The angle displayed may define an intersection <br>
+//! can be between two edges or two faces of a shape <br>
+//! or a plane. The display consists of arrows and text. <br>
+
+#ifndef _AIS_AngleDimension_HeaderFile
+#define _AIS_AngleDimension_HeaderFile
+
+#include <AIS_Dimension.hxx>
+#include <Geom_Plane.hxx>
+#include <Geom_Line.hxx>
+#include <Geom_Transformation.hxx>
+#include <gp.hxx>
+#include <gp_Ax1.hxx>
+#include <gp_Dir.hxx>
+#include <gp_Pnt.hxx>
+#include <Prs3d_DimensionAspect.hxx>
+#include <Prs3d_Projector.hxx>
+#include <Prs3d_Presentation.hxx>
+#include <Standard.hxx>
+#include <Standard_Macro.hxx>
+#include <Standard_DefineHandle.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+
+DEFINE_STANDARD_HANDLE (AIS_AngleDimension, AIS_Dimension)
+
+class AIS_AngleDimension : public AIS_Dimension
+{
+public:
+  //! Constructs angle dimension between two edges
+  //! with automatic working plane computing
+  //! if it is possible. In case of PI angle please
+  //! set custom working plane or use constructor with 3 parameters.
+  Standard_EXPORT  AIS_AngleDimension (const TopoDS_Edge& theFirstEdge,
+                                       const TopoDS_Edge& theSecondEdge);
+  //!  Constructs the angle display object defined by the <br>
+  //! two edges and custom working plane.
+  //! ATTENTION :In case if the working plane is custom and one edge is out of the
+  //!            working plane it tries to project this edge line on the plane.
+  //!            To avoid this case you can reset the working plane
+  //!            using <ResetWorkingPlane ()> method.
+  Standard_EXPORT  AIS_AngleDimension (const TopoDS_Edge& theFirstEdge,
+                                       const TopoDS_Edge& theSecondEdge,
+                                       const gp_Pln& thePlane);
+  
+  //!  Constructs the angle display object defined by the <br>
+  //! two edges and custom working plane and dimension aspect.
+  Standard_EXPORT  AIS_AngleDimension (const TopoDS_Edge& theFirstEdge,
+                                       const TopoDS_Edge& theSecondEdge,
+                                       const gp_Pln& thePlane,
+                                       const Handle(Prs3d_DimensionAspect)& theDimensionAspect,
+                                       const Standard_Real theExtensionSize = 1.0);
+
+  //! Constructs the angle display object defined by three points.
+  Standard_EXPORT  AIS_AngleDimension (const gp_Pnt& theFirstPoint,
+                                       const gp_Pnt& theSecondPoint,
+                                       const gp_Pnt& theThirdPoint);
+
+   //! Constructs the angle display object defined by three points
+  //! and dimension aspect that defines line, arrow and text aspect.
+  Standard_EXPORT  AIS_AngleDimension (const gp_Pnt& theFirstPoint,
+                                       const gp_Pnt& theSecondPoint,
+                                       const gp_Pnt& theThirdPoint,
+                                       const Handle(Prs3d_DimensionAspect)& theDimensionAspect,
+                                       const Standard_Real theExtensionSize = 1.0);
+
+  //! Angle of cone
+  Standard_EXPORT  AIS_AngleDimension (const TopoDS_Face& theCone);
+
+  //! TwoPlanarFaceAngle dimension
+  Standard_EXPORT  AIS_AngleDimension (const TopoDS_Face& theFirstFace,
+                                       const TopoDS_Face& theSecondFace,
+                                       const gp_Ax1& theAxis);
+
+  //! Sets the flyout.
+  Standard_EXPORT void SetFlyout (const Standard_Real theFlyout);
+
+  //! Returns flyout value. If value > 0 the dimension is to be displayed inside the angle.
+  //! Otherwise it is displayed outside one.
+  Standard_EXPORT Standard_Real GetFlyout() const;
+
+  //! Sets first shape
+  Standard_EXPORT  void SetFirstShape (const TopoDS_Shape& theShape,
+                                       const Standard_Boolean isSingleShape = Standard_False);
+
+  DEFINE_STANDARD_RTTI(AIS_AngleDimension)
+
+protected:
+
+  //! Computes dimension value in display units
+  Standard_EXPORT virtual void computeValue();
+
+  Standard_EXPORT  void init();
+
+  Standard_EXPORT  gp_Pnt getCenterOnArc (const gp_Pnt& theFirstAttach,
+                                          const gp_Pnt& theSecondAttach);
+
+  Standard_EXPORT  void drawArc (const Handle(Prs3d_Presentation)& thePresentation,
+                                 const gp_Pnt& theFirstAttach,
+                                 const gp_Pnt& theSecondAttach,
+                                 const gp_Pnt& theCenter,
+                                 const Standard_Real theRadius,
+                                 const AIS_DimensionDisplayMode theMode);
+
+  Standard_EXPORT  void drawArcWithText (const Handle(Prs3d_Presentation)& thePresentation,
+                                         const gp_Pnt& theFirstAttach,
+                                         const gp_Pnt& theSecondAttach,
+                                         const TCollection_ExtendedString& theText,
+                                         const AIS_DimensionDisplayMode theMode);
+
+  Standard_EXPORT  virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& thePM,
+                                         const Handle(Prs3d_Presentation)& thePresentation,
+                                         const Standard_Integer theMode = 0);
+
+  Standard_EXPORT  Standard_Boolean initConeAngle (const TopoDS_Face& theCone);
+
+  Standard_EXPORT  Standard_Boolean initTwoFacesAngle();
+
+  Standard_EXPORT  Standard_Boolean initTwoEdgesAngle();
+
+  //! Auxiliary method to get position of the angle dimension
+  //! if the cone is trimmed
+  //! Returns 1 if <theC> center is above of <theCMin> center;
+  //!         0 if <theC> center is between <theCMin> and <theCMax> centers;
+  //!        -1 if <theC> center is below <theCMax> center.
+  Standard_EXPORT Standard_Integer aboveInBelowCone (const gp_Circ &theCMax,
+                                                     const gp_Circ &theCMin,
+                                                     const gp_Circ &theC);
+
+  //! Auxiliary method to arrange text and arrows
+  Standard_EXPORT Standard_Boolean canTextBeInCenter (const gp_Pnt& theFirstAttach,
+                                                      const gp_Pnt& theSecondAttach,
+                                                      const Quantity_Length& theTextLength,
+                                                      const Quantity_Length& theArrowLength);
+
+  //! Fills default plane object if it is possible to count plane automatically.
+  Standard_EXPORT virtual void countDefaultPlane ();
+
+protected:
+
+  //! Shows if there is necessarily to draw extensions on angle dimension
+  //! It is set to the true value if the attachment point are out of the edges.
+  Standard_Boolean myIsFlyoutLines;
+
+  //! The center of dimension arc
+  gp_Pnt myCenter;
+
+  //! Defines flyout lines and direction
+  //! Flyout direction in the working plane (stored in the base AIS_Dimension).
+  //! can be negative , or positive and is defined by the sign of <myFlyout> value.
+  //! The direction vector is counting using the working plane.
+  //! <myFlyout> value defined the size of flyout (radius of angle).
+  Standard_Real myFlyout;
+};
+
+#endif
diff --git a/src/AIS/AIS_AngleDimension.lxx b/src/AIS/AIS_AngleDimension.lxx
deleted file mode 100755 (executable)
index 06fc371..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-// Created on: 1997-02-28
-// Created by: Jean-Pierre COMBE
-// Copyright (c) 1997-1999 Matra Datavision
-// Copyright (c) 1999-2012 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.
-//
-// 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.
-//
-// 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.
-
-//=======================================================================
-//function : KindOfDimension
-//purpose  : 
-//=======================================================================
-inline AIS_KindOfDimension AIS_AngleDimension::KindOfDimension() const 
-{
-  return AIS_KOD_PLANEANGLE;
-}
-
-//=======================================================================
-//function : IsMovable
-//purpose  : 
-//=======================================================================
-inline Standard_Boolean AIS_AngleDimension::IsMovable() const 
-{
-  return Standard_True;
-}
-
-//=======================================================================
-//function : Axis
-//purpose  : 
-//=======================================================================
-inline const gp_Ax1& AIS_AngleDimension::Axis() const 
-{
-  return myAxis;
-}
-
-//=======================================================================
-//function : SetAxis
-//purpose  : 
-//=======================================================================
-inline void AIS_AngleDimension::SetAxis(const gp_Ax1& anAxis)
-{
-  myAxis = anAxis;
-}
index 043d72a..946eff0 100755 (executable)
@@ -29,7 +29,7 @@
 #include <DsgPrs_Chamf2dPresentation.hxx>
 
 #include <Prs3d_ArrowAspect.hxx>
-#include <Prs3d_LengthAspect.hxx>
+#include <Prs3d_DimensionAspect.hxx>
 #include <Prs3d_Drawer.hxx>
 
 #include <SelectMgr_EntityOwner.hxx>
@@ -194,8 +194,8 @@ void AIS_Chamf2dDimension::Compute(const Handle(PrsMgr_PresentationManager3d)& ,
       myPosition = curpos;
     }
     
-    Handle(Prs3d_LengthAspect) la = myDrawer->LengthAspect();
-    Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();
+    Handle(Prs3d_DimensionAspect) la = myDrawer->DimensionAspect();
+    Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();
     
     //-------------------------------------------------
     //Calcul de la boite englobante du component pour
index 0b3bfd7..aea7224 100755 (executable)
@@ -29,7 +29,7 @@
 #include <DsgPrs_Chamf2dPresentation.hxx>
 
 #include <Prs3d_ArrowAspect.hxx>
-#include <Prs3d_LengthAspect.hxx>
+#include <Prs3d_DimensionAspect.hxx>
 #include <Prs3d_Drawer.hxx>
 
 #include <SelectMgr_EntityOwner.hxx>
@@ -170,8 +170,8 @@ void AIS_Chamf3dDimension::Compute(const Handle(PrsMgr_PresentationManager3d)& ,
     myPosition = curpos;
   }
     
-  Handle(Prs3d_LengthAspect) la = myDrawer->LengthAspect();
-  Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();
+  Handle(Prs3d_DimensionAspect) la = myDrawer->DimensionAspect();
+  Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();
     
   //-------------------------------------------------
   //Calcul de la boite englobante du component pour
diff --git a/src/AIS/AIS_DiameterDimension.cdl b/src/AIS/AIS_DiameterDimension.cdl
deleted file mode 100755 (executable)
index 7dae78c..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
--- Created on: 1996-12-05
--- Created by: Jacques MINOT/Odile Olivier/Serguei ZARITCHNY
--- Copyright (c) 1996-1999 Matra Datavision
--- Copyright (c) 1999-2012 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.
---
--- 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.
---
--- 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.
-
--- Modified     Mon 12-january-98
---             <odl@sacadox.paris1.matra-dtv.fr>, 
-
-
-class DiameterDimension from AIS inherits Relation from AIS
-
-
-       ---Purpose: A framework to display diameter dimensions.
-       -- A diameter is displayed with arrows and text. The
-       -- text gives the length of the diameter.
-       -- The algorithm takes a length along a face and
-       -- analyzes it as an arc. It then reconstructs the circle
-       -- corresponding to the arc and calculates the
-       -- diameter of this circle. This diameter serves as a
-       -- relational reference in 3d presentations of the surface.
-       
-uses
-
-     Shape                 from TopoDS,
-     Circ                  from gp,
-     Pnt                   from gp, 
-     Pln                   from gp, 
-     Plane                 from Geom, 
-     Surface               from Geom,
-     Presentation          from Prs3d,
-     PresentationManager3d from PrsMgr,
-     Selection             from SelectMgr,
-     Projector             from Prs3d,
-     Transformation        from Geom,
-     ExtendedString        from TCollection,    
-     ArrowSide             from DsgPrs, 
-     KindOfSurface         from AIS,
-     KindOfDimension       from AIS 
-
-raises ConstructionError from Standard     
-      
-is
-    Create (aShape      : Shape          from TopoDS;
-           aVal        : Real           from Standard;
-           aText       : ExtendedString from TCollection)    
-       ---Purpose: Constructs a diameter display object defined by the
-       -- shape aFShape, the dimension aVal and the text aText.
-    returns mutable DiameterDimension from AIS;
-
-    Create (aShape      : Shape          from TopoDS;
-           aVal        : Real           from Standard;
-           aText       : ExtendedString from TCollection;          
-           aPosition   : Pnt            from gp;
-           aSymbolPrs  : ArrowSide      from DsgPrs;    
-           aDiamSymbol : Boolean        from Standard;    
-           anArrowSize : Real           from Standard = 0.0)
-       ---Purpose: Constructs a diameter display object defined by the
-       -- shape aFShape, the dimension aVal and the text
-       -- aText, the point of origin of the diameter aPosition,
-       -- and the type of arrow aSymbolPrs with the size anArrowSize.
-       -- If the Boolean aDiamSymbol is true.
-    returns mutable DiameterDimension from AIS;
-
-    KindOfDimension(me) returns KindOfDimension from AIS 
-        ---C++: inline
-       ---Purpose:
-       -- Indicates that we are concerned with a length.
-    is redefined;
-
-    IsMovable(me) returns Boolean from Standard 
-        ---C++: inline    
-       ---Purpose:
-       -- Returns true if the diameter dimension is movable
-    is redefined;        
-
-    DiamSymbol(me: mutable) returns Boolean from Standard 
-       ---C++: inline
-       ---Purpose:
-       -- Returns the symbol for diameter dimension. This will
-       -- be either arrow, text, or a combination of both.
-    is static;
-
-    SetDiamSymbol(me: mutable;aDiamSymbol: Boolean from Standard) 
-        ---C++: inline
-       ---Purpose:
-       -- Sets the symbol for diameter dimension aDiamSymbol.
-       -- This can be an arrow, a text or both.
-    is static;
---    SetPlane(me: mutable; aPlane : Plane from Geom)
---    is static;
---    ---C++: inline
-    
---    Plane(me) returns any Plane  from Geom 
---    is static;
---    ---C++: inline
---    ---C++: return  const  & 
-
-          
--- Methods from PresentableObject
-
-    Compute(me                  : mutable;
-           aPresentationManager: PresentationManager3d from PrsMgr;
-           aPresentation       : mutable Presentation from Prs3d;
-           aMode               : Integer from Standard= 0) 
-    is redefined private;
-    
-    Compute(me:mutable;
-               aProjector: Projector from Prs3d;
-                aPresentation: mutable Presentation from Prs3d)
-    is redefined static private;     
-    
-    Compute(me            : mutable;
-           aProjector    : Projector from Prs3d;
-           aTrsf         : Transformation from Geom;
-           aPresentation : mutable Presentation from Prs3d)
-    is redefined;
-    ---Purpose: computes the presentation according to a point of view
-    --          given by <aProjector>. 
-    --          To be Used when the associated degenerated Presentations 
-    --          have been transformed by <aTrsf> which is not a Pure
-    --          Translation. The HLR Prs can't be deducted automatically
-    --          WARNING :<aTrsf> must be applied
-    --           to the object to display before computation  !!!
-
--- Methods from SelectableObject
-
-    ComputeSelection(me         : mutable;
-                    aSelection : mutable Selection from SelectMgr;
-                    aMode      : Integer from Standard)
-    is redefined private;
-
---
---     Computation private methods
---
-
-    ComputeOneFaceDiameter(me: mutable;
-                       aPresentation : mutable Presentation from Prs3d)
-    is private; 
-     
-    ComputeOneCylFaceDiameter(me: mutable;
-                       aPresentation : mutable Presentation from Prs3d; 
-                       aSurfType     : KindOfSurface  from  AIS; 
-                       aSurf         : Surface  from  Geom  )
-    is private; 
-     
-    ComputeOnePlanarFaceDiameter(me: mutable;
-                       aPresentation : mutable Presentation from Prs3d  )
-    is private; 
-    
-    ComputeOneEdgeDiameter(me: mutable;
-                       aPresentation : mutable Presentation from Prs3d)
-    is private;
-    
-    ComputeCircleDiameter(me: mutable;
-                         aPresentation : mutable Presentation from Prs3d)
-    is private;
-    
-    ComputeArcDiameter(me: mutable;
-                      aPresentation : mutable Presentation from Prs3d; 
-                      ptFirst : Pnt from gp;
-                      ptend   : Pnt from gp)
-    is private;
-    
-    ComputeArcSelection(me      : mutable;
-                    aSelection : mutable Selection from SelectMgr)
-    is private;
-    
-fields
-     
-    myCircle       : Circ    from gp;
-    myIsAnArc      : Boolean from Standard;
-    myDiamSymbol   : Boolean from Standard; 
-    myFirstPar     : Real    from Standard;      
-    myLastPar      : Real    from Standard;   
-
-end DiameterDimension;
index a51fa6b..8070b19 100755 (executable)
 
 #define BUC60915        //GG 05/06/01 Enable to compute the requested arrow size
 //                      if any in all dimensions.
+#include <AIS_DiameterDimension.hxx>
 
-#include <Standard_NotImplemented.hxx>
-
-#include <AIS_DiameterDimension.ixx>
+#include <Adaptor3d_HCurve.hxx>
+#include <AIS.hxx>
+#include <AIS_Drawer.hxx>
 #include <AIS_DimensionOwner.hxx>
 #include <DsgPrs_DiameterPresentation.hxx>
 #include <DsgPrs_RadiusPresentation.hxx>
-
-#include <TCollection_ExtendedString.hxx>
-
-#include <Prs3d_LengthAspect.hxx>
-#include <Prs3d_ArrowAspect.hxx>
-#include <Prs3d_Drawer.hxx>
-#include <Prs3d_TextAspect.hxx>
-#include <Prs3d_Text.hxx>
-
-#include <Select3D_SensitiveSegment.hxx>
-#include <Select3D_SensitiveBox.hxx>
-#include <SelectMgr_EntityOwner.hxx>
-
 #include <ElCLib.hxx>
 #include <ElSLib.hxx>
-
-#include <TopoDS.hxx>
-
-#include <BRepAdaptor_Surface.hxx>
-#include <BRepAdaptor_Curve.hxx>
-#include <Adaptor3d_HCurve.hxx>
-
-#include <Geom_Circle.hxx>
-#include <Geom_TrimmedCurve.hxx>
+#include <GC_MakeCircle.hxx>
+#include <gce_MakeDir.hxx>
 #include <Geom_Plane.hxx>
-#include <Geom_Surface.hxx>
-#include <Geom_CylindricalSurface.hxx>
-#include <Geom_SurfaceOfRevolution.hxx>
-#include <Geom_CylindricalSurface.hxx>
-#include <Geom_SurfaceOfLinearExtrusion.hxx>
-
 #include <gp_Pln.hxx>
 #include <gp_Pnt.hxx>
 #include <gp_Lin.hxx>
 #include <gp_Ax1.hxx>
 #include <gp_Dir.hxx>
 #include <gp_Vec.hxx>
-
-#include <AIS.hxx>
-#include <AIS_Drawer.hxx>
-
-#include <GC_MakeCircle.hxx>
-
+#include <Graphic3d_ArrayOfSegments.hxx>
+#include <Graphic3d_Group.hxx>
+#include <PrsMgr_PresentationManager3d.hxx>
+#include <Prs3d_DimensionAspect.hxx>
+#include <Prs3d_ArrowAspect.hxx>
+#include <Prs3d_Drawer.hxx>
+#include <Prs3d_TextAspect.hxx>
+#include <Prs3d_Text.hxx>
+#include <Prs3d_Root.hxx>
 #include <Precision.hxx>
+#include <Select3D_SensitiveSegment.hxx>
+#include <Select3D_SensitiveBox.hxx>
+#include <SelectMgr_EntityOwner.hxx>
+#include <Standard_Macro.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TCollection_ExtendedString.hxx>
 
-#include <TopExp_Explorer.hxx>
+IMPLEMENT_STANDARD_HANDLE(AIS_DiameterDimension, AIS_Dimension)
+IMPLEMENT_STANDARD_RTTIEXT(AIS_DiameterDimension, AIS_Dimension)
 
 //=======================================================================
 //function : Constructor
 //purpose  : 
 //=======================================================================
 
-AIS_DiameterDimension::AIS_DiameterDimension(const TopoDS_Shape& aShape, 
-                                            const Standard_Real aVal, 
-                                            const TCollection_ExtendedString& aText)
-:AIS_Relation(),
- myDiamSymbol(Standard_True)
+AIS_DiameterDimension::AIS_DiameterDimension(const gp_Circ& theCircle)
+: AIS_Dimension(),
+  myFlyout (0.0),
+  myCircle (theCircle)
 {
-  myPosition  = gp_Pnt(0.,0.,0.);
-  myFShape = aShape;
-  myVal = aVal;
-  myText = aText;
-  mySymbolPrs = DsgPrs_AS_LASTAR;
-  myAutomaticPosition = Standard_True;
-  myArrowSize = myVal / 100.;
+  SetKindOfDimension(AIS_KOD_DIAMETER);
+  myIsInitialized = Standard_True;
+  SetSpecialSymbol (0x00D8);
+  SetDisplaySpecialSymbol (AIS_DSS_Before);
+  // Count attach points
+  myFirstPoint = ElCLib::Value (0, myCircle);
+  mySecondPoint = myFirstPoint.Translated (gp_Vec(myFirstPoint, theCircle.Location())*2);
 }
 
 //=======================================================================
@@ -103,618 +88,162 @@ AIS_DiameterDimension::AIS_DiameterDimension(const TopoDS_Shape& aShape,
 //purpose  : 
 //=======================================================================
 
-AIS_DiameterDimension::AIS_DiameterDimension(const TopoDS_Shape& aShape, 
-                                            const Standard_Real aVal, 
-                                            const TCollection_ExtendedString& aText, 
-                                            const gp_Pnt& aPosition, 
-                                            const DsgPrs_ArrowSide aSymbolPrs,
-                                            const Standard_Boolean aDiamSymbol,
-                                            const Standard_Real anArrowSize)
-:AIS_Relation(),
- myDiamSymbol(aDiamSymbol)
+AIS_DiameterDimension::AIS_DiameterDimension(const gp_Circ& theCircle, const gp_Pnt& theAttachPoint)
+: AIS_Dimension(),
+  myFlyout (0.0),
+  myCircle (theCircle)
 {
-  myFShape = aShape;
-  myVal = aVal;
-  myText = aText;
-  mySymbolPrs = aSymbolPrs;
-  myPosition = aPosition;
-  myAutomaticPosition = Standard_False;
-#ifdef BUC60915
-  SetArrowSize( anArrowSize );
-#else
-  myArrowSize = anArrowSize;
-#endif
+  SetKindOfDimension(AIS_KOD_DIAMETER);
+  SetSpecialSymbol (0x00D8);
+  SetDisplaySpecialSymbol (AIS_DSS_Before);
+  myFirstPoint = theAttachPoint;
+  // Count the second point
+  if (Abs(myFirstPoint.Distance (theCircle.Location()) - theCircle.Radius()) < Precision::Confusion())
+  {
+    mySecondPoint = myFirstPoint.Translated(gp_Vec(myFirstPoint, theCircle.Location())*2);
+  }
+  else
+  {
+    myFirstPoint = ElCLib::Value(0, myCircle);
+    mySecondPoint = myFirstPoint.Translated(gp_Vec(myFirstPoint, theCircle.Location())*2);
+  }
+  myIsInitialized = Standard_True;
 }
 
 //=======================================================================
-//function : Compute
+//function : Constructor
 //purpose  : 
 //=======================================================================
 
-void AIS_DiameterDimension::Compute(
-       const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
-       const Handle(Prs3d_Presentation)& aPresentation, 
-       const Standard_Integer /*aMode*/)
+AIS_DiameterDimension::AIS_DiameterDimension (const gp_Circ& theCircle,
+                                              const Handle(Prs3d_DimensionAspect)& theDimensionStyle,
+                                              const Standard_Real theExtensionSize /*= 1.0*/)
+: AIS_Dimension (theExtensionSize),
+  myFlyout (0.0),
+  myCircle (theCircle)
 {
-  aPresentation->Clear();
-
-  switch (myFShape.ShapeType()) {
-  case TopAbs_FACE :
-    {
-      // compute one face case
-      ComputeOneFaceDiameter (aPresentation);
-      break;
-    }
-  case TopAbs_EDGE:
-    {
-      ComputeOneEdgeDiameter (aPresentation);
-      break;
-    }
-  default:
-    break;
-  }
-
+  SetKindOfDimension(AIS_KOD_DIAMETER);
+  SetSpecialSymbol (0x00D8);
+  SetDisplaySpecialSymbol(AIS_DSS_Before);
+  myDrawer->SetDimensionAspect(theDimensionStyle);
+  myIsInitialized = Standard_True;
 }
 
 //=======================================================================
-//function : Compute
-//purpose  : to avoid warning
+//function : Constructor
+//purpose  : Universal constructor for diameter dimension of shape
 //=======================================================================
 
-void AIS_DiameterDimension::Compute(const Handle(Prs3d_Projector)& aProjector,
-                                    const Handle(Prs3d_Presentation)& aPresentation)
-{
-// Standard_NotImplemented::Raise("AIS_DiameterDimension::Compute(const Handle(Prs3d_Projector)& aProjector, const Handle(Prs3d_Presentation)& aPresentation)");
- PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
-}
-
-void AIS_DiameterDimension::Compute(const Handle_Prs3d_Projector& aProjector, const Handle_Geom_Transformation& aTransformation, const Handle_Prs3d_Presentation& aPresentation)
+AIS_DiameterDimension::AIS_DiameterDimension (const TopoDS_Shape& theShape)
+: AIS_Dimension (),
+  myFlyout (0.)
 {
-// Standard_NotImplemented::Raise("AIS_DiameterDimension::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
-  PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
+  SetKindOfDimension(AIS_KOD_DIAMETER);
+  SetSpecialSymbol (0x00D8);
+  SetDisplaySpecialSymbol(AIS_DSS_Before);
+  myFirstShape = theShape;
+  myIsInitialized = Standard_False;
 }
 
 //=======================================================================
-//function : ComputeSelection
+//function : Compute
 //purpose  : 
 //=======================================================================
 
-void AIS_DiameterDimension::ComputeSelection(
-       const Handle(SelectMgr_Selection)& aSelection, 
-        const Standard_Integer /*aMode*/)
+void AIS_DiameterDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePM*/,
+                                     const Handle(Prs3d_Presentation)& thePresentation, 
+                                     const Standard_Integer theMode)
 {
-  Handle(AIS_DimensionOwner) own = new AIS_DimensionOwner(this,7);
-  own->SetShape(myFShape);
-
-  if (!myIsAnArc) {
-    gp_Pnt        AttachmentPoint = myPosition;
-    Standard_Real parat    = ElCLib::Parameter(myCircle,AttachmentPoint);
-    gp_Pnt        ptoncirc = ElCLib::Value    (parat,myCircle);
-    
-    // ligne de cote
-    
-    gp_Pnt        center  = myCircle.Location();
-    gp_Vec        vecrap  (ptoncirc,center);
-    
-    Standard_Real dist    = center.Distance(AttachmentPoint);
-    Standard_Real aRadius = myCircle.Radius();
-    Standard_Real inside  = Standard_False;
-    
-    gp_Pnt pt1 = AttachmentPoint;
-    if (dist < aRadius) {
-      pt1 = ptoncirc;
-      dist = aRadius;
-      inside = Standard_True;
-    }
-    vecrap.Normalize();
-    vecrap *= (dist+aRadius);
-    gp_Pnt        OppositePoint = pt1.Translated(vecrap);
-    
-    if ( pt1.Distance(OppositePoint)>=Precision::Confusion()) {
-      Handle(Select3D_SensitiveSegment) 
-       seg = new Select3D_SensitiveSegment(own,pt1 ,OppositePoint);
-      aSelection->Add(seg);
-    }
+  thePresentation->Clear();
+
+  Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
+  Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect());
+
+  if (!myIsInitialized)
+  {
+    if (!initCircularDimension (myFirstShape, myCircle,
+                               myFirstPoint, mySecondPoint))
+      return;
+    else
+      myIsInitialized = Standard_True;
   }
-  else
-    ComputeArcSelection(aSelection);
-
-  // Text
-  Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
-  Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( own,
-                                                                  myPosition.X(),
-                                                                  myPosition.Y(),
-                                                                  myPosition.Z(),
-                                                                  myPosition.X() + size,
-                                                                  myPosition.Y() + size,
-                                                                  myPosition.Z() + size);
-  aSelection->Add(box);
-}
-//==========================================================================
-// function : ComputeArcSelection
-// purpose  : 
-//           
-//==========================================================================
+  if (!myIsWorkingPlaneCustom)
+   countDefaultPlane();
 
-void AIS_DiameterDimension::ComputeArcSelection(const Handle(SelectMgr_Selection)& aSelection)
-{
+  //Count flyout direction
+  gp_Ax1 aWorkingPlaneNormal = GetWorkingPlane().Axis();
+  gp_Dir aTargetPointsVector = gce_MakeDir (myFirstPoint, mySecondPoint);
+  // Count a flyout direction vector.
+  gp_Dir aFlyoutVector = aWorkingPlaneNormal.Direction()^aTargetPointsVector;
+  gp_Ax3 aLocalSystem (myFirstPoint, aTargetPointsVector, aFlyoutVector);
 
-  Standard_Real fpara; 
-  Standard_Real lpara; 
-  fpara = myFirstPar;
-  lpara = myLastPar;
+  // Create lines for layouts
+  gp_Lin aLine1 (myFirstPoint, aFlyoutVector);
+  gp_Lin aLine2 (mySecondPoint, aFlyoutVector);
 
-  Handle(SelectMgr_EntityOwner) own = new SelectMgr_EntityOwner(this,7);
-  gp_Pnt theCenter = myCircle.Location();
-  while (lpara > 2*M_PI) {
-    fpara -= 2*M_PI;
-    lpara -= 2*M_PI;
-  }
-  Standard_Real parat = ElCLib::Parameter(myCircle,myPosition);
-  Standard_Boolean otherside(Standard_False);
-  gp_Pnt attpoint = myPosition;
-
-  if (!AIS::InDomain(fpara,lpara,parat)) {
-    Standard_Real otherpar = parat + M_PI;
-    if (otherpar > 2*M_PI) otherpar -= 2*M_PI;
-    if (AIS::InDomain(fpara,lpara,otherpar)) {
-      parat = otherpar;
-      otherside = Standard_True;
-    }
-    else {
-      Standard_Real ecartpar = Min(Abs(fpara-parat),
-                                  Abs(lpara-parat));
-      Standard_Real ecartoth = Min(Abs(fpara-otherpar),
-                                  Abs(lpara-otherpar));
-      if (ecartpar <= ecartoth) {
-       if (parat < fpara) parat = fpara;
-       else parat = lpara;
-      }
-      else {
-       otherside = Standard_True;
-       if (otherpar < fpara) parat = fpara;
-       else parat = lpara;
-      }
-      gp_Pnt ptdir = ElCLib::Value(parat,myCircle);
-      gp_Lin lsup(theCenter,
-                 gp_Dir(ptdir.XYZ()-theCenter.XYZ()));
-      Standard_Real parpos = ElCLib::Parameter(lsup,myPosition);
-      attpoint = ElCLib::Value(parpos,lsup);
-    }
-  }
-  gp_Pnt ptoncirc = ElCLib::Value(parat,myCircle);
-  gp_Lin L (theCenter,gp_Dir(attpoint.XYZ()-theCenter.XYZ()));
-  gp_Pnt firstpoint = attpoint;
-  gp_Pnt drawtopoint = ptoncirc;
-
-  if (!otherside) {
-    Standard_Real uatt = ElCLib::Parameter(L,attpoint);
-    Standard_Real uptc = ElCLib::Parameter(L,ptoncirc);
-    if (Abs(uatt) > Abs(uptc)) {
-      drawtopoint = theCenter;
-    }
-    else {
-      firstpoint = theCenter;
-    }
+  // Get flyout end points
+  gp_Pnt aFlyoutEnd1 = ElCLib::Value (ElCLib::Parameter (aLine1, myFirstPoint) + GetFlyout(), aLine1);
+  gp_Pnt aFlyoutEnd2 = ElCLib::Value (ElCLib::Parameter (aLine2, mySecondPoint) + GetFlyout(), aLine2);
+
+    // Add layout lines to graphic group
+  // Common to all type of dimension placement.
+  if (theMode == 0)
+  {
+    Handle(Graphic3d_ArrayOfSegments) aPrimSegments = new Graphic3d_ArrayOfSegments(4);
+    aPrimSegments->AddVertex (myFirstPoint);
+    aPrimSegments->AddVertex (aFlyoutEnd1);
+
+    aPrimSegments->AddVertex (mySecondPoint);
+    aPrimSegments->AddVertex (aFlyoutEnd2);
+
+    Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
   }
 
-  Handle(Select3D_SensitiveSegment) seg = new Select3D_SensitiveSegment(own,firstpoint,drawtopoint);
-  aSelection->Add(seg);
+  drawLinearDimension (thePresentation, aFlyoutEnd1, aFlyoutEnd2, (AIS_DimensionDisplayMode)theMode);
 }
 
 //=======================================================================
-//function : ComputeOneFaceDiameter
+//function : computeValue
 //purpose  : 
 //=======================================================================
 
-void AIS_DiameterDimension::ComputeOneFaceDiameter(
-       const Handle(Prs3d_Presentation)& aPresentation)
+void AIS_DiameterDimension::computeValue ()
 {
-  //cout<<"AIS_DiameterDimension::ComputeOneFaceDiameter"<<endl;
-
-  gp_Pln aPln;
-  Handle( Geom_Surface ) aBasisSurf;
-  AIS_KindOfSurface aSurfType = AIS_KOS_OtherSurface;
-  Standard_Real Offset;
-  if( myAutomaticPosition )
-    AIS::GetPlaneFromFace( TopoDS::Face(  myFShape),
-                         aPln,
-                         aBasisSurf,
-                         aSurfType,
-                         Offset ) ;
-  
-  if ( aSurfType == AIS_KOS_Plane )
-    ComputeOnePlanarFaceDiameter( aPresentation );
-  else 
-    ComputeOneCylFaceDiameter( aPresentation, aSurfType, aBasisSurf );
-
+  myValue = myFirstPoint.Distance (mySecondPoint);
+  AIS_Dimension::computeValue();
 }
 
-
 //=======================================================================
-//function : ComputeOneCylFaceDiameter
+//function : countDefaultPlane
 //purpose  : 
 //=======================================================================
 
-void AIS_DiameterDimension::ComputeOneCylFaceDiameter
-  (const Handle(Prs3d_Presentation)& aPresentation,
-   const AIS_KindOfSurface  aSurfType,
-   const Handle( Geom_Surface )&  aBasisSurf )
+void AIS_DiameterDimension::countDefaultPlane ()
 {
-  gp_Pnt curPos;
-  if( myAutomaticPosition )
-    {
-      BRepAdaptor_Surface surf1(TopoDS::Face(myFShape));
-      Standard_Real uFirst, uLast, vFirst, vLast;
-      uFirst = surf1.FirstUParameter();
-      uLast  = surf1.LastUParameter();
-      vFirst = surf1.FirstVParameter();
-      vLast  = surf1.LastVParameter();
-      Standard_Real uMid = (uFirst + uLast)*0.5;
-      Standard_Real vMid = (vFirst + vLast)*0.5;
-      surf1.D0(uMid, vMid, curPos);
-      Handle( Adaptor3d_HCurve ) BasisCurve;
-      //Standard_Real Param;
-      Standard_Boolean ExpectedType = Standard_False;
-      if (aSurfType == AIS_KOS_Cylinder)
-       {
-         ExpectedType = Standard_True;
-       }
-      else 
-       if (aSurfType == AIS_KOS_Revolution)
-       {
-         BasisCurve = surf1.BasisCurve();
-         if (BasisCurve->GetType() == GeomAbs_Line) 
-           ExpectedType = Standard_True;
-       }
-      else if (aSurfType == AIS_KOS_Extrusion)
-       {
-         BasisCurve = surf1.BasisCurve();
-         if ( BasisCurve->GetType() == GeomAbs_Circle )
-           ExpectedType = Standard_True;
-       }
-      if(!ExpectedType) {
-       Standard_ConstructionError::Raise("AIS:: Not expected type of surface") ;
-         return;
-       }
-      //      
-      Handle(Geom_Curve) aCurve;
-      aCurve =   aBasisSurf->VIso(vMid);
-      if (aCurve->DynamicType() == STANDARD_TYPE(Geom_Circle)) 
-       {
-         myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();//gp_Circ
-       }
-      else if (aCurve->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
-       Handle(Geom_TrimmedCurve) tCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve); 
-       aCurve = tCurve->BasisCurve();
-       uFirst = tCurve->FirstParameter();
-       uLast  = tCurve->LastParameter();
-       if (aCurve->DynamicType() == STANDARD_TYPE(Geom_Circle))
-         myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();//gp_Circ
-      }
-      else {
-       // compute a circle from 3 points on "aCurve"
-       gp_Pnt P1, P2;
-       surf1.D0(uFirst, vMid, P1);
-       surf1.D0(uLast, vMid, P2);
-       GC_MakeCircle mkCirc(P1, curPos, P2);
-       myCircle = mkCirc.Value()->Circ();
-      } 
-      myCircle.SetRadius(myVal/2.);
-      myPlane = new Geom_Plane(gp_Pln(gp_Ax3(myCircle.Position())));//gp_Circ
-      gp_Vec v1(myCircle.Location(), curPos);
-      v1.Normalize();
-      v1 = v1 * myVal*1.2;
-      myPosition = myCircle.Location().Translated(v1); 
-//    IsArc ?
-      gp_Pnt p1, p2;
-      p1 = ElCLib::Value (uFirst, myCircle);
-      p2 = ElCLib::Value (uLast,  myCircle);
-      if ( p1.IsEqual(p2, Precision::Confusion()) ) 
-       myIsAnArc = Standard_False;
-      else myIsAnArc = Standard_True;
-      myFirstPar =  uFirst;
-      myLastPar  =  uLast;
-//    myPosition = curPos;
-      myAutomaticPosition = Standard_True;   
-      if ( myIsSetBndBox )
-       myPosition = AIS::TranslatePointToBound( myPosition, gp_Dir( gp_Vec( myCircle.Location(),
-                                                                           myPosition ) ), myBndBox );
-    }
-  else { // !AutomaticPosition
-    curPos = myPosition;
-    curPos = AIS::ProjectPointOnPlane( curPos, myPlane->Pln() );
-    myPosition = curPos;
-  }
-  Handle(Prs3d_LengthAspect) la = myDrawer->LengthAspect();
-  Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();
-  
-  // size
-#ifdef BUC60915
-  if( !myArrowSizeIsDefined ) {
-    myArrowSize = Min(myArrowSize,myCircle.Radius()/5.);
-  }
-  arr->SetLength(myArrowSize);
-#else
-  if (myCircle.Radius()/5. > myArrowSize) {
-    arr->SetLength(myArrowSize);
-  }
-  else {
-    arr->SetLength(myCircle.Radius()/5.);
-  }
-#endif
-  
-  //cout<<"AIS_DiameterDimension:: add Prs"<<endl;
-  if( myIsAnArc ) 
-    DsgPrs_DiameterPresentation::Add(aPresentation, myDrawer, myText, myPosition,
-                                    myCircle, myFirstPar, myLastPar, mySymbolPrs, myDiamSymbol);
-  else
-    DsgPrs_DiameterPresentation::Add(aPresentation, myDrawer, myText, myPosition,
-                                    myCircle, DsgPrs_AS_BOTHAR, myDiamSymbol);
-
-
+  // Compute normal of the default plane.
+  //gp_Vec aVec1(mySecondPoint, myFirstPoint),
+  //       aVec2(mySecondPoint, ElCLib::Value(M_PI_2, myCircle));
+  myDefaultPlane = gp_Pln(gp_Ax3(myCircle.Position()));
+  // Set computed value to <myWorkingPlane>
+  ResetWorkingPlane ();
 }
 
-
 //=======================================================================
-//function : ComputeCircleDiameter
+//function : SetFlyout
 //purpose  : 
 //=======================================================================
 
-void AIS_DiameterDimension::ComputeCircleDiameter(const Handle(Prs3d_Presentation)& aPresentation)
+void AIS_DiameterDimension::SetFlyout (const Standard_Real theFlyout)
 {
-  gp_Pnt center = myCircle.Location();
-  Standard_Real rad = myCircle.Radius();
-  gp_Pnt curpos;
-
-  if (myAutomaticPosition) {
-// we compute 1 point on the circle
-    myPlane = new Geom_Plane(gp_Pln(gp_Ax3(myCircle.Position())));//gp_Circ
-    gp_Dir xdir = myCircle.XAxis().Direction();
-    Standard_Real deport = rad *1.2;
-    curpos = center.Translated( gp_Vec(xdir)*deport );
-    SetPosition (curpos);// myPosition = curpos
-    myAutomaticPosition = Standard_True; 
-    if (myIsSetBndBox)
-      myPosition = AIS::TranslatePointToBound( myPosition, gp_Dir( gp_Vec( myCircle.Location(),
-                                                                         myPosition ) ), myBndBox );
-  }
-  else {
-    curpos = myPosition;
-       // VRO (2007-05-17) inserted this IF.
-       if (myPlane.IsNull())
-               myPlane = new Geom_Plane(gp_Pln(gp_Ax3(myCircle.Position())));
-    myPosition = AIS::ProjectPointOnPlane( curpos, myPlane->Pln() );
-  }
-
-  // size
-  Handle(Prs3d_LengthAspect) LA = myDrawer->LengthAspect();
-  Handle(Prs3d_ArrowAspect) arr = LA->Arrow1Aspect();
-
-#ifdef BUC60915
-  if( !myArrowSizeIsDefined ) {
-    myArrowSize = Min(myArrowSize,myCircle.Radius()/5.);
-  }
-  arr->SetLength(myArrowSize);
-#else
-  if (myCircle.Radius()/5. > myArrowSize) {
-    arr->SetLength(myArrowSize);
-  }
-  else {
-    arr->SetLength(myCircle.Radius()/5.);
-  }
-#endif
-  
-  DsgPrs_DiameterPresentation::Add(aPresentation, myDrawer, myText, myPosition, myCircle,
-                                  DsgPrs_AS_BOTHAR, myDiamSymbol );
-
+  myFlyout = theFlyout;
 }
 
-//==========================================================================
-// function : ComputeArcDiameter
-// purpose  : 
-//           
-//==========================================================================
-
-void AIS_DiameterDimension::ComputeArcDiameter(
-                        const Handle(Prs3d_Presentation)& aPresentation,
-                       const gp_Pnt& pfirst,
-                        const gp_Pnt& pend)
-{
-
-  gp_Pnt center = myCircle.Location();
-  Standard_Real rad = myCircle.Radius();
-
-  gp_Pnt curpos;
-  Standard_Real parfirst, parend;
-
-  parfirst = ElCLib::Parameter(myCircle, pfirst);
-  parend   = ElCLib::Parameter(myCircle, pend);
-  myFirstPar = parfirst;
-  myLastPar  = parend;
-  if ( parfirst > parend) {
-    parfirst -= 2*M_PI;
-  }
-  if (myAutomaticPosition) {
-    Standard_Real pcurpos = (parfirst + parend)/2.;
-    curpos = ElCLib::Value(pcurpos, myCircle);
-    myPlane = new Geom_Plane(gp_Pln(gp_Ax3(myCircle.Position())));//gp_Circ
-    gp_Dir vdir(gp_Vec(myCircle.Location(),curpos));
-    Standard_Real deport = rad * 1.2;
-    curpos = center.Translated( gp_Vec(vdir)*deport );
-
-    SetPosition (curpos);
-    myAutomaticPosition = Standard_True; 
-  
-    if ( myIsSetBndBox )
-      myPosition = AIS::TranslatePointToBound( myPosition, gp_Dir( gp_Vec( myCircle.Location(),
-                                                                         myPosition ) ), myBndBox );
-  }
-  else {
-    curpos = myPosition;
-    myPosition = AIS::ProjectPointOnPlane( curpos, myPlane->Pln() );
-  }
-  
-  // size
-
-  Handle(Prs3d_LengthAspect) LA = myDrawer->LengthAspect();
-  Handle(Prs3d_ArrowAspect) arr = LA->Arrow1Aspect();
-
-#ifdef BUC60915
-  if( !myArrowSizeIsDefined ) {
-    myArrowSize = Min(myArrowSize,myCircle.Radius()/5.);
-  }
-  arr->SetLength(myArrowSize);
-#else
-  if (myCircle.Radius()/5. > myArrowSize) {
-    arr->SetLength(myArrowSize);
-  }
-  else {
-    arr->SetLength(myCircle.Radius()/5.);
-  }
-#endif
-    
-  // Display
-  DsgPrs_DiameterPresentation::Add (aPresentation, myDrawer, myText, myPosition, myCircle, 
-                                 parfirst, parend, mySymbolPrs, myDiamSymbol);
-}
-
-
-//==========================================================================
-// function : ComputeOneEdgeDiameter
-// purpose  : 
-//           
-//==========================================================================
-
-void AIS_DiameterDimension::ComputeOneEdgeDiameter(const Handle(Prs3d_Presentation)& aPresentation)
-{
-  gp_Pnt ptfirst,ptend;
-  Handle(Geom_Curve) curv;
-  if (!AIS::ComputeGeometry(TopoDS::Edge(myFShape),curv,ptfirst,ptend)) return;
-
-  Handle(Geom_Circle) circ = Handle(Geom_Circle)::DownCast(curv);
-  if ( circ.IsNull()) return;
-  
-  myCircle = circ->Circ();
-  myCircle.SetRadius(myVal/2.);
-  if ( ptfirst.IsEqual(ptend, Precision::Confusion()) ) {
-    myIsAnArc = Standard_False;
-    ComputeCircleDiameter(aPresentation);
-  }
-  else {
-    myIsAnArc = Standard_True;
-    ComputeArcDiameter(aPresentation,ptfirst,ptend );
-  }
-}
-
-//===================================================================
-//function : CircleFromPlanarFace
-//purpose  : if possible computes circle from planar face
 //=======================================================================
-static Standard_Boolean CircleFromPlanarFace(const TopoDS_Face& aFace,
-                                             Handle(Geom_Curve)& aCurve, 
-                                             gp_Pnt & ptfirst,  gp_Pnt & ptend)
-{
-  TopExp_Explorer ExploEd( aFace, TopAbs_EDGE );
-  for ( ; ExploEd.More(); ExploEd.Next())
-    {
-      TopoDS_Edge curedge =  TopoDS::Edge( ExploEd.Current() );
-      if (AIS::ComputeGeometry(curedge, aCurve, ptfirst, ptend))
-       if(aCurve->IsInstance(STANDARD_TYPE(Geom_Circle))  && 
-          !Handle(Geom_Circle)::DownCast(aCurve).IsNull())
-         return Standard_True;
-    } 
-  return Standard_False;
-}
-
-//=======================================================================
-//function : ComputeOnePlanarFaceDiameter
+//function : GetFlyout
 //purpose  : 
 //=======================================================================
 
-void AIS_DiameterDimension::ComputeOnePlanarFaceDiameter(const Handle(Prs3d_Presentation)& aPresentation)
+Standard_Real AIS_DiameterDimension::GetFlyout () const
 {
-  gp_Pnt curPos ;
-  Standard_Real parfirst =0., parend =0.; 
-  if (myAutomaticPosition) {
-    Handle(Geom_Curve) curv;
-    gp_Pnt ptfirst,ptend;
-
-    if( !CircleFromPlanarFace( TopoDS::Face( myFShape ), curv, ptfirst, ptend) )  {
-      Standard_ConstructionError::Raise("AIS:: Curve is not a circle or is Null") ;
-       return;
-      }
-
-    myCircle = Handle(Geom_Circle)::DownCast(curv)->Circ();
-    if ( ptfirst.IsEqual(ptend, Precision::Confusion()) )
-      myIsAnArc = Standard_False;
-    else
-      myIsAnArc = Standard_True;
-    myCircle.SetRadius(myVal/2.);//
-    BRepAdaptor_Surface surfAlgo (TopoDS::Face(myFShape));
-    myPlane = new Geom_Plane(gp_Pln(gp_Ax3(myCircle.Position())));//gp_Circ
-    gp_Pnt center = myCircle.Location();
-    Standard_Real rad = myCircle.Radius();
-    Standard_Real deport = rad * 1.2;
-    if(! myIsAnArc ) { // Circle
-      gp_Dir xdir = myCircle.XAxis().Direction();
-      curPos = center.Translated( gp_Vec(xdir)*deport );
-    }
-    else { // Arc
-      parfirst = ElCLib::Parameter(myCircle, ptfirst);
-      parend   = ElCLib::Parameter(myCircle, ptend);
-      if ( parfirst > parend) {
-       parfirst -= 2*M_PI;
-      }
-      Standard_Real parcurPos = (parfirst + parend) * 0.5;
-      curPos = ElCLib::Value(parcurPos, myCircle);
-      gp_Vec v1( center, curPos );
-      v1.Normalize();
-      curPos = center.Translated( v1 * deport );
-    }
-    myFirstPar = parfirst;
-    myLastPar  = parend;
-    myPosition = curPos;
-    myAutomaticPosition = Standard_True;    
-    if ( myIsSetBndBox )
-      myPosition = AIS::TranslatePointToBound( myPosition, gp_Dir( gp_Vec( myCircle.Location(),
-                                                                         myPosition ) ), myBndBox );
-  } else 
-    {
-      // !myAutomaticPosition
-      // Project point on the plane of face
-      curPos = myPosition;
-      curPos = AIS::ProjectPointOnPlane( curPos, myPlane->Pln() );
-      myPosition = curPos;
-    }
-
-  
-  Handle(Prs3d_LengthAspect) la = myDrawer->LengthAspect();
-  Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();
-
-  // size
-#ifdef BUC60915
-  if( !myArrowSizeIsDefined ) {
-    myArrowSize = Min(myArrowSize,myCircle.Radius()/5.);
-  }
-  arr->SetLength(myArrowSize);
-#else
-  if (myCircle.Radius()/5. > myArrowSize) {
-    arr->SetLength(myArrowSize);
-  }
-  else {
-    arr->SetLength(myCircle.Radius()/5.);
-  }
-#endif
-       
-  if(! myIsAnArc )
-    DsgPrs_DiameterPresentation::Add(aPresentation, myDrawer, myText, myPosition,
-                                    myCircle, DsgPrs_AS_BOTHAR, myDiamSymbol);
-  else 
-    DsgPrs_DiameterPresentation::Add(aPresentation, myDrawer, myText, myPosition,
-                                    myCircle, myFirstPar, myLastPar, mySymbolPrs, myDiamSymbol );
+  return myFlyout;
 }
-
diff --git a/src/AIS/AIS_DiameterDimension.hxx b/src/AIS/AIS_DiameterDimension.hxx
new file mode 100644 (file)
index 0000000..e2efbc1
--- /dev/null
@@ -0,0 +1,85 @@
+// Copyright (c) 1995-1999 Matra Datavision
+// Copyright (c) 1999-2012 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.
+//
+// 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.
+//
+// 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.
+#ifndef _AIS_DiameterDimension_HeaderFile
+#define _AIS_DiameterDimension_HeaderFile
+
+#include <AIS.hxx>
+#include <AIS_Dimension.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Circ.hxx>
+#include <Standard.hxx>
+#include <Standard_Macro.hxx>
+#include <Standard_DefineHandle.hxx>
+
+DEFINE_STANDARD_HANDLE(AIS_DiameterDimension,AIS_Dimension)
+
+//! A framework to display diameter dimensions. <br>
+//! A diameter is displayed with arrows and text. The <br>
+//! text gives the length of the diameter. <br>
+//! The algorithm takes a length along a face and <br>
+//! analyzes it as an arc. It then reconstructs the circle <br>
+//! corresponding to the arc and calculates the <br>
+//! diameter of this circle. This diameter serves as a <br>
+//! relational reference in 3d presentations of the surface. <br>
+class AIS_DiameterDimension : public AIS_Dimension
+{
+public:
+  //! Constructs a diameter display object defined by the <br>
+  //! circle <theCircle>
+  Standard_EXPORT  AIS_DiameterDimension(const gp_Circ& theCircle);
+  //! Consctructor that allows to set a attach point <br>
+  //! on the circle <theCircle> where to attach dimension
+  Standard_EXPORT  AIS_DiameterDimension (const gp_Circ& theCircle,
+                                          const gp_Pnt& theAttachPoint);
+
+  Standard_EXPORT   AIS_DiameterDimension (const gp_Circ& theCircle,
+                                           const Handle(Prs3d_DimensionAspect)& theDimensionStyle,
+                                           const Standard_Real theExtensionSize = 1.0);
+
+  Standard_EXPORT  AIS_DiameterDimension (const TopoDS_Shape& theShape);
+
+
+  Standard_EXPORT void SetFlyout(const Standard_Real theFlyout);
+
+  Standard_EXPORT Standard_Real GetFlyout () const;
+
+  DEFINE_STANDARD_RTTI(AIS_DiameterDimension)
+
+protected:
+
+  Standard_EXPORT  virtual void computeValue ();
+    //! Fills default plane object if it is possible to count plane automatically.
+  Standard_EXPORT  virtual void countDefaultPlane ();
+
+private: 
+
+  virtual  void Compute (const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
+                         const Handle(Prs3d_Presentation)& thePresentation,
+                         const Standard_Integer theMode = 0);
+
+// Fields
+
+  //! Defines flyout lines and direction
+  //! Flyout direction in the working plane (stored in the base AIS_Dimension).
+  //! can be negative , or positive and is defined by the sign of <myFlyout> value.
+  //! The direction vector is counting using the working plane.
+  //! <myFlyout> value defined the size of flyout.
+  Standard_Real myFlyout;
+  gp_Circ myCircle;
+};
+#endif
diff --git a/src/AIS/AIS_DiameterDimension.lxx b/src/AIS/AIS_DiameterDimension.lxx
deleted file mode 100755 (executable)
index 9c36461..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-// Created on: 1997-02-28
-// Created by: Jean-Pierre COMBE, Serguei ZARITCHNY
-// Copyright (c) 1997-1999 Matra Datavision
-// Copyright (c) 1999-2012 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.
-//
-// 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.
-//
-// 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.
-
-// Modified     Mon 12-january-98
-//             <jpr>              <szy>
-
-//=======================================================================
-//function : KindOfDimension
-//purpose  : 
-//=======================================================================
-inline AIS_KindOfDimension AIS_DiameterDimension::KindOfDimension() const 
-{
-  return AIS_KOD_DIAMETER;
-}
-
-//=======================================================================
-//function : IsMovable
-//purpose  : 
-//=======================================================================
-inline Standard_Boolean AIS_DiameterDimension::IsMovable() const 
-{
-  return Standard_True;
-}
-
-//=======================================================================
-//function : DiamSymbol
-//purpose  : 
-//=======================================================================
-
-inline Standard_Boolean AIS_DiameterDimension::DiamSymbol()
-{
-  return myDiamSymbol;
-}
-
-
-//=======================================================================
-//function : SetDiamSymbol
-//purpose  : 
-//=======================================================================
-
-inline void AIS_DiameterDimension::SetDiamSymbol(const Standard_Boolean aDiamSymbol)
-{
-  myDiamSymbol = aDiamSymbol;
-}
diff --git a/src/AIS/AIS_Dimension.cxx b/src/AIS/AIS_Dimension.cxx
new file mode 100644 (file)
index 0000000..c4be695
--- /dev/null
@@ -0,0 +1,1344 @@
+// Copyright (c) 1999-2013 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.
+//
+// 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.
+//
+// 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.
+
+#include <AIS.hxx>
+#include <AIS_Dimension.hxx>
+#include <AIS_DimensionDisplayMode.hxx>
+#include <AIS_DimensionOwner.hxx>
+#include <AIS_Drawer.hxx>
+#include <Adaptor3d_HCurve.hxx>
+#include <BRepAdaptor_Curve.hxx>
+#include <BRepAdaptor_Surface.hxx>
+#include <BRepBuilderAPI_MakeEdge.hxx>
+#include <BRepLib_MakeVertex.hxx>
+#include <BRepBndLib.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <ElCLib.hxx>
+#include <Font_BRepFont.hxx>
+#include <GC_MakeCircle.hxx>
+#include <Geom_Circle.hxx>
+#include <Geom_Plane.hxx>
+#include <Geom_TrimmedCurve.hxx>
+#include <gce_MakeDir.hxx>
+#include <gce_MakeLin.hxx>
+#include <Graphic3d_ArrayOfSegments.hxx>
+#include <Graphic3d_ArrayOfTriangles.hxx>
+#include <Graphic3d_AspectLine3d.hxx>
+#include <Graphic3d_AspectFillArea3d.hxx>
+#include <Graphic3d_AspectText3d.hxx>
+#include <Graphic3d_Group.hxx>
+#include <PrsMgr_PresentationManager3d.hxx>
+#include <Prs3d_Arrow.hxx>
+#include <Prs3d_ArrowAspect.hxx>
+#include <Prs3d_Drawer.hxx>
+#include <Prs3d_LineAspect.hxx>
+#include <Prs3d_Presentation.hxx>
+#include <Prs3d_Root.hxx>
+#include <Prs3d_ShadingAspect.hxx>
+#include <Prs3d_Text.hxx>
+#include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_Selection.hxx>
+#include <SelectMgr_SequenceOfOwner.hxx>
+#include <Select3D_ListIteratorOfListOfSensitive.hxx>
+#include <Select3D_ListOfSensitive.hxx>
+#include <Select3D_SensitiveBox.hxx>
+#include <Select3D_SensitiveCircle.hxx>
+#include <Select3D_SensitiveGroup.hxx>
+#include <Select3D_SensitiveSegment.hxx>
+#include <Standard_CString.hxx>
+#include <StdPrs_ShadedShape.hxx>
+#include <StdPrs_WFShape.hxx>
+#include <TCollection_AsciiString.hxx>
+#include <TCollection_ExtendedString.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <Units.hxx>
+#include <Units_UnitsDictionary.hxx>
+#include <UnitsAPI.hxx>
+#include <UnitsAPI_SystemUnits.hxx>
+
+IMPLEMENT_STANDARD_HANDLE(AIS_Dimension, AIS_InteractiveObject)
+IMPLEMENT_STANDARD_RTTIEXT(AIS_Dimension, AIS_InteractiveObject)
+
+//=======================================================================
+//function : Constructor
+//purpose  : 
+//=======================================================================
+
+AIS_Dimension::AIS_Dimension (const Standard_Real theExtensionSize /*= 1.0*/)
+: AIS_InteractiveObject(),
+  myDefaultPlane (gp_Pln (gp::XOY())),
+  myIsWorkingPlaneCustom (Standard_False),
+  myValue (0.0),
+  myIsValueCustom (Standard_False),
+  myUnitsQuantity (TCollection_AsciiString("LENGTH")),
+  myToDisplayUnits (Standard_False),
+  mySpecialSymbol (' '),
+  myDisplaySpecialSymbol (AIS_DSS_No),
+  myIsTextReversed (Standard_False),
+  myTextOffset (DimensionAspect()->ArrowAspect()->Length()),
+  myIsInitialized (Standard_False),
+  myKindOfDimension (AIS_KOD_NONE),
+  myExtensionSize (theExtensionSize)
+{
+  ResetWorkingPlane();
+  // Units default settings
+  UnitsAPI::SetLocalSystem (UnitsAPI_SI);
+  myModelUnits = Units::DictionaryOfUnits()->ActiveUnit (myUnitsQuantity.ToCString());
+  myDisplayUnits = Units::DictionaryOfUnits()->ActiveUnit (myUnitsQuantity.ToCString());
+}
+
+//=======================================================================
+//function : Constructor
+//purpose  : 
+//=======================================================================
+
+AIS_Dimension::AIS_Dimension (const Handle(Prs3d_DimensionAspect)& theAspect,
+                              const Standard_Real theExtensionSize /*= 1.0*/)
+: AIS_InteractiveObject(),
+  myDefaultPlane (gp_Pln (gp::XOY())),
+  myIsWorkingPlaneCustom (Standard_False),
+  myValue (0.0),
+  myIsValueCustom (Standard_False),
+  myUnitsQuantity (TCollection_AsciiString("LENGTH")),
+  myToDisplayUnits (Standard_False),
+  mySpecialSymbol (' '),
+  myDisplaySpecialSymbol (AIS_DSS_No),
+  myIsTextReversed (Standard_False),
+  myTextOffset (DimensionAspect()->ArrowAspect()->Length()),
+  myIsInitialized (Standard_False),
+  myKindOfDimension (AIS_KOD_NONE),
+  myExtensionSize (theExtensionSize)
+{
+  ResetWorkingPlane();
+  // Units default settings
+  UnitsAPI::SetLocalSystem (UnitsAPI_SI);
+  myModelUnits = Units::DictionaryOfUnits()->ActiveUnit (myUnitsQuantity.ToCString());
+  myDisplayUnits = Units::DictionaryOfUnits()->ActiveUnit (myUnitsQuantity.ToCString());
+  SetDimensionAspect (theAspect);
+}
+
+//=======================================================================
+//function : AcceptDisplayMode
+//purpose  : Checks if display mode <theMode> is allowed to display object.
+//=======================================================================
+
+Standard_Boolean AIS_Dimension::AcceptDisplayMode (const Standard_Integer theMode) const
+{
+  return theMode == 0 ? Standard_True : Standard_False;
+}
+
+//=======================================================================
+//function : computeValue
+//purpose  : Computes dimension value in display units.
+//=======================================================================
+
+void AIS_Dimension::computeValue()
+{
+  UnitsAPI::SetCurrentUnit (myUnitsQuantity.ToCString(), myModelUnits.ToCString());
+  myValue = UnitsAPI::CurrentFromLS (myValue, myUnitsQuantity.ToCString());
+  myValue = valueToDisplayUnits();
+}
+
+//=======================================================================
+//function : countDefaultPlane
+//purpose  : 
+//=======================================================================
+
+void AIS_Dimension::countDefaultPlane()
+{
+}
+
+//=======================================================================
+//function : GetWorkingPlane
+//purpose  : 
+//=======================================================================
+
+const gp_Pln& AIS_Dimension::GetWorkingPlane() const
+{
+  return myWorkingPlane;
+}
+
+//=======================================================================
+//function : SetWorkingPlane
+//purpose  : 
+//=======================================================================
+
+void AIS_Dimension::SetWorkingPlane (const gp_Pln& thePlane)
+{
+  myWorkingPlane = thePlane;
+  myIsWorkingPlaneCustom = Standard_True;
+}
+
+//=======================================================================
+//function : ResetWorkingPlane
+//purpose  : Set default value of working plane
+//=======================================================================
+
+void AIS_Dimension::ResetWorkingPlane()
+{
+  myWorkingPlane = myDefaultPlane;
+  myIsWorkingPlaneCustom = Standard_False;
+}
+
+//=======================================================================
+//function : resetWorkingPlane
+//purpose  : Set default value of working plane
+//           Only for internal use.
+//=======================================================================
+
+void AIS_Dimension::resetWorkingPlane (const gp_Pln& theNewDefaultPlane)
+{
+  myDefaultPlane = theNewDefaultPlane;
+  ResetWorkingPlane();
+}
+
+//=======================================================================
+//function : valueInDisplayUnits
+//purpose  :
+//=======================================================================
+
+Standard_Real AIS_Dimension::valueToDisplayUnits()
+{
+  return  UnitsAPI::AnyToAny (myValue,
+                              myModelUnits.ToCString(),
+                              myDisplayUnits.ToCString());
+}
+
+//=======================================================================
+//function : KindOfDimension
+//purpose  : 
+//=======================================================================
+
+AIS_KindOfDimension AIS_Dimension::KindOfDimension() const 
+{
+  return myKindOfDimension;
+}
+
+//=======================================================================
+//function : SetKindOfDimension
+//purpose  : 
+//=======================================================================
+
+void AIS_Dimension::SetKindOfDimension (const AIS_KindOfDimension theKindOfDimension)
+{
+  myKindOfDimension = theKindOfDimension;
+}
+
+//=======================================================================
+//function : SetExtensionSize
+//purpose  : 
+//=======================================================================
+
+void AIS_Dimension::SetExtensionSize (const Standard_Real theExtensionSize)
+{
+  myExtensionSize = theExtensionSize;
+}
+   
+//=======================================================================
+//function : GetExtensionSize
+//purpose  : 
+//=======================================================================
+
+Standard_Real AIS_Dimension::GetExtensionSize() const
+{
+  return myExtensionSize;
+}
+
+//=======================================================================
+//function : GetValue
+//purpose  : 
+//=======================================================================
+
+Standard_Real AIS_Dimension::GetValue() const
+ {
+  return myValue;
+ }
+
+//=======================================================================
+//function : SetCustomValue
+//purpose  : 
+//=======================================================================
+
+void AIS_Dimension::SetCustomValue (const Standard_Real theValue)
+{
+  myValue = theValue;
+  myIsValueCustom = Standard_True;
+}
+
+//=======================================================================
+//function : SetFirstShape
+//purpose  : 
+//=======================================================================
+
+void AIS_Dimension::SetFirstShape (const TopoDS_Shape& theShape)
+{
+  myFirstShape = theShape;
+  myIsInitialized = Standard_False;
+  resetGeom();
+}
+
+//=======================================================================
+//function : SetSecondShape
+//purpose  : 
+//=======================================================================
+
+void AIS_Dimension::SetSecondShape (const TopoDS_Shape& theShape)
+{
+  mySecondShape = theShape;
+  myIsInitialized = Standard_False;
+  resetGeom();
+}
+
+//=======================================================================
+//function : getTextWidthAndString
+//purpose  : 
+//=======================================================================
+
+void AIS_Dimension::getTextWidthAndString (Quantity_Length& theWidth,
+                                           TCollection_ExtendedString& theString) const
+{
+  char aValueSimpleStr[25];
+  sprintf (aValueSimpleStr, "%g", GetValue());
+  theString = TCollection_ExtendedString (aValueSimpleStr);
+
+  if (IsUnitsDisplayed())
+  {
+    theString += " ";
+    theString += TCollection_ExtendedString (myDisplayUnits);
+  }
+
+  if (myDisplaySpecialSymbol == AIS_DSS_Before)
+  {
+    theString = TCollection_ExtendedString (mySpecialSymbol) + theString;
+  }
+  else if (myDisplaySpecialSymbol == AIS_DSS_After)
+  {
+    theString += TCollection_ExtendedString (mySpecialSymbol);
+  }
+
+  // Get font length
+  // Get expansion ratio for getting a width of symbols
+  Quantity_Color aColor; 
+  Standard_CString aFont;
+  Standard_Real aFactor;
+  Standard_Real aSpace;
+  myDrawer->DimensionAspect()->TextAspect()->Aspect()->Values (aColor, aFont, aFactor, aSpace);
+  theWidth = (myDrawer->DimensionAspect()->TextAspect()->Height() / aFactor) * theString.Length();
+}
+
+//=======================================================================
+//function : drawArrow
+//purpose  : 
+//=======================================================================
+
+void AIS_Dimension::drawArrow (const Handle(Prs3d_Presentation)& thePresentation,
+                               const gp_Pnt& theLocation,
+                               const gp_Dir& theDirection)
+{
+  Prs3d_Root::NewGroup (thePresentation);
+  Quantity_Length anArrowLength = myDrawer->DimensionAspect()->ArrowAspect()->Length();
+
+  if (myDrawer->DimensionAspect()->IsArrows3d())
+  {
+    Prs3d_Arrow::Draw (thePresentation,
+                       theLocation,
+                       theDirection.Reversed(),
+                       myDrawer->DimensionAspect()->ArrowAspect()->Angle(),
+                       anArrowLength);
+  }
+  else
+  {
+    gp_Vec anArrowDir (theDirection);
+    Quantity_Length theCathetusLength = anArrowLength / Cos (M_PI / 9.0);
+    Handle(Graphic3d_ArrayOfTriangles) anArrow = new Graphic3d_ArrayOfTriangles(3);
+    gp_Pnt aLeftPoint (theLocation.Translated (anArrowDir.Rotated (myWorkingPlane.Axis(), M_PI / 9.0) * theCathetusLength));
+    gp_Pnt aRightPoint (theLocation.Translated (anArrowDir.Rotated (myWorkingPlane.Axis(), M_PI * 17.0 / 9.0) * theCathetusLength));
+
+    anArrow->AddVertex (aLeftPoint);
+    anArrow->AddVertex (theLocation);
+    anArrow->AddVertex (aRightPoint);
+
+    // Set aspect for arrow triangles
+    Quantity_Color aColor;
+    Aspect_TypeOfLine aTOL;
+    Standard_Real aWidth;
+    myDrawer->DimensionAspect()->ArrowAspect()->Aspect()->Values (aColor, aTOL, aWidth);
+    Graphic3d_MaterialAspect aShadeMat (Graphic3d_NOM_DEFAULT);
+    aShadeMat.SetReflectionModeOff (Graphic3d_TOR_AMBIENT);
+    aShadeMat.SetReflectionModeOff (Graphic3d_TOR_DIFFUSE);
+    aShadeMat.SetReflectionModeOff (Graphic3d_TOR_SPECULAR);
+    myDrawer->ShadingAspect()->Aspect()->SetInteriorColor (aColor);
+    myDrawer->ShadingAspect()->Aspect()->SetBackInteriorColor (aColor);
+    myDrawer->ShadingAspect()->SetMaterial (aShadeMat);
+    Prs3d_Root::CurrentGroup(thePresentation)->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
+    Prs3d_Root::CurrentGroup(thePresentation)->AddPrimitiveArray (anArrow);
+  }
+}
+
+//=======================================================================
+//function : drawText
+//purpose  : 
+//=======================================================================
+
+Standard_Real AIS_Dimension::drawText (const Handle(Prs3d_Presentation)& thePresentation,
+                                       const gp_Dir& theTextDir,
+                                       const TCollection_ExtendedString theText,
+                                       const AIS_DimensionDisplayMode theMode)
+{
+  Standard_Real aTextWidth (0.0), aTextHeight (0.0);
+  if (theMode == AIS_DDM_Line)
+    return aTextWidth;
+  // Creating new group for text
+  Prs3d_Root::NewGroup (thePresentation);
+
+  if (myDrawer->DimensionAspect()->IsText3d())
+  {
+    // Getting font parameters
+    Quantity_Color aColor;
+    Standard_CString aFontName;
+    Standard_Real anExpansionFactor;
+    Standard_Real aSpace;
+    myDrawer->DimensionAspect()->TextAspect()->Aspect()->Values (aColor, aFontName, anExpansionFactor, aSpace);
+    Font_FontAspect aFontAspect = myDrawer->DimensionAspect()->TextAspect()->Aspect()->GetTextFontAspect();
+    Standard_Real aHeight = myDrawer->DimensionAspect()->TextAspect()->Height();
+
+    // Creating TopoDS_Shape for text
+    Font_BRepFont aFont (aFontName, aFontAspect, aHeight);
+    NCollection_String aText = (Standard_Utf16Char* )theText.ToExtString();
+    TopoDS_Shape aTextShape = aFont.RenderText (aText);
+
+    // Formating text position in XOY plane
+    Bnd_Box aTextBndBox;
+    BRepBndLib::AddClose (aTextShape, aTextBndBox);
+    Standard_Real aXMin, anYMin, aZMin, aXMax, anYMax, aZMax;
+    aTextBndBox.Get (aXMin, anYMin, aZMin, aXMax, anYMax, aZMax);
+    aTextWidth  = aXMax  - aXMin;
+    aTextHeight = anYMax - anYMin;
+    gp_Dir aTextDir (theTextDir);
+    Standard_Real aHorizontalOffset (0.0), aVerticalOffset (0.0);
+    switch (myDrawer->DimensionAspect()->HorizontalTextAlignment())
+    {
+      case Prs3d_HTA_Left:
+        aTextDir.Reverse();
+        aHorizontalOffset = -aTextWidth;
+        break;
+      case Prs3d_HTA_Center:
+        aHorizontalOffset = -(aTextWidth / 2.0);
+        break;
+      case Prs3d_HTA_Right:
+        aHorizontalOffset = 0.0;
+        break;
+    }
+    switch (myDrawer->DimensionAspect()->VerticalTextAlignment())
+    {
+      case Prs3d_VTA_Top:
+        aVerticalOffset = 0.0;
+        break;
+      case Prs3d_VTA_Center:
+        aVerticalOffset = -(aTextHeight / 2.0);
+        break;
+      case Prs3d_VTA_Bottom:
+        aVerticalOffset = -aTextHeight;
+        break;
+    }
+    gp_Trsf aTrsf;
+    aTrsf.SetTranslation (gp_Pnt (), gp_Pnt (aHorizontalOffset, aVerticalOffset, 0.0));
+    aTextShape.Move (aTrsf);
+
+    // Transform text to myWorkingPlane coordinate system
+    gp_Ax3 aPenAx3 (myGeom.myTextPosition, myWorkingPlane.Axis().Direction(), aTextDir);
+    aTrsf.SetTransformation (aPenAx3, gp_Ax3 (gp::XOY()));
+    aTextShape.Move (aTrsf);
+
+    // Set display parameters for advanced selection
+    BRepBndLib::AddClose (aTextShape, myGeom.myTextBndBox);
+    // Drawing text
+    if (myDrawer->DimensionAspect()->IsTextShaded())
+    {
+      // Setting text shading and color parameters
+      Graphic3d_MaterialAspect aShadeMat (Graphic3d_NOM_DEFAULT);
+      aShadeMat.SetReflectionModeOff (Graphic3d_TOR_AMBIENT);
+      aShadeMat.SetReflectionModeOff (Graphic3d_TOR_DIFFUSE);
+      aShadeMat.SetReflectionModeOff (Graphic3d_TOR_SPECULAR);
+      myDrawer->ShadingAspect()->Aspect()->SetInteriorColor (aColor);
+      myDrawer->ShadingAspect()->Aspect()->SetBackInteriorColor (aColor);
+      myDrawer->ShadingAspect()->SetMaterial (aShadeMat);
+
+      // Drawing text
+      StdPrs_ShadedShape::Add (thePresentation, aTextShape, myDrawer);
+    }
+    else
+    {
+      // Setting color for text
+      myDrawer->FreeBoundaryAspect()->Aspect()->SetColor (aColor);
+      // Drawing text
+      StdPrs_WFShape::Add (thePresentation, aTextShape, myDrawer);
+    }
+    // Creating new group for lines
+    Prs3d_Root::NewGroup (thePresentation);
+  }
+  else
+  {
+    myDrawer->DimensionAspect()->TextAspect()->Aspect()->SetDisplayType (Aspect_TODT_DIMENSION);
+    Prs3d_Text::Draw (thePresentation,
+                      myDrawer->DimensionAspect()->TextAspect(),
+                      theText,
+                      myGeom.myTextPosition);
+
+    // For 2d text we don not create new group for lines and draw them in the same group with text
+    // for the proper handling of stencil test buffer.
+  }
+
+  return aTextWidth;
+}
+
+  //=======================================================================
+//function : drawExtensionWithText
+//purpose  : 
+//=======================================================================
+
+void AIS_Dimension::drawExtensionWithText (const Handle(Prs3d_Presentation)& thePresentation,
+                                           const gp_Pnt& theStartPoint,
+                                           const gp_Lin& theDimensionLine,
+                                           const TCollection_ExtendedString& theValueString,
+                                           const AIS_DimensionDisplayMode theMode)
+{
+  Handle(SelectMgr_EntityOwner) anEmptyOwner;
+  Standard_Boolean isGapInCenter = (myDrawer->DimensionAspect()->VerticalTextAlignment() == Prs3d_VTA_Center
+                                    && myDrawer->DimensionAspect()->IsText3d());
+
+  Handle(Graphic3d_ArrayOfSegments) aPrimSegments = new Graphic3d_ArrayOfSegments (isGapInCenter ? 4 : 2);
+
+  gp_Dir anAttachPointsVector = myWorkingPlane.Axis().Direction() ^ gce_MakeDir (myFirstPoint, mySecondPoint);
+  Standard_Real aGap = 1.;
+  Standard_Real aStartParam = ElCLib::Parameter (theDimensionLine, theStartPoint);
+
+  // Text
+  Standard_Real aTextParam = isGapInCenter ? aStartParam + myTextOffset + aGap : aStartParam + myTextOffset;
+  myGeom.myTextPosition = ElCLib::Value (aTextParam, theDimensionLine);
+  Standard_Real aTextWidth = drawText (thePresentation,
+                                       myIsTextReversed ? theDimensionLine.Direction().Reversed()
+                                                        : theDimensionLine.Direction(),
+                                       theValueString,
+                                       theMode);
+  gp_Pnt aFirstPoint, aLastPoint;
+  aFirstPoint = theStartPoint;
+  Standard_Real aParam = isGapInCenter ? aTextParam + aTextWidth + aGap : aTextParam + aTextWidth;
+
+  // If text separates dimension line into two parts (4 points)
+  if (isGapInCenter)
+  {
+    aLastPoint = ElCLib::Value (aStartParam + myTextOffset, theDimensionLine);
+    aPrimSegments->AddVertex (aFirstPoint);
+    aPrimSegments->AddVertex (aLastPoint);
+    myGeom.mySensitiveSegments.Append (new Select3D_SensitiveSegment (anEmptyOwner, aFirstPoint, aLastPoint));
+    aFirstPoint = ElCLib::Value (aParam, theDimensionLine);
+  }
+
+  // Draw additional line segment only after 3D text
+  if (myDrawer->DimensionAspect()->IsText3d())
+  {
+    aParam += myTextOffset;
+  }
+
+  aLastPoint = ElCLib::Value (aParam, theDimensionLine);
+  aPrimSegments->AddVertex (aFirstPoint);
+  aPrimSegments->AddVertex (aLastPoint);
+  myGeom.mySensitiveSegments.Append (new Select3D_SensitiveSegment (anEmptyOwner, aFirstPoint, aLastPoint));
+
+  // Extension line in the same group
+  if (theMode != AIS_DDM_Text)
+  {
+    if (!myDrawer->DimensionAspect()->IsText3d() && theMode == AIS_DDM_All)
+    {
+      Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_True);
+    }
+    Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (myDrawer->DimensionAspect()->LineAspect()->Aspect());
+    Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
+    if (!myDrawer->DimensionAspect()->IsText3d() && theMode == AIS_DDM_All)
+    {
+      Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_False);
+    }
+  }
+}
+
+//=======================================================================
+//function : SetDimensionAspect
+//purpose  : 
+//=======================================================================
+
+void AIS_Dimension::SetDimensionAspect (const Handle(Prs3d_DimensionAspect)& theDimensionAspect)
+{
+  myDrawer->SetDimensionAspect (theDimensionAspect);
+}
+
+//=======================================================================
+//function : DimensionAspect
+//purpose  : 
+//=======================================================================
+
+Handle(Prs3d_DimensionAspect) AIS_Dimension::DimensionAspect() const
+{
+  return myDrawer->DimensionAspect();
+}
+
+//=======================================================================
+//function : SetTextOffset
+//purpose  : 
+//=======================================================================
+
+void AIS_Dimension::SetTextOffset (const Standard_Real theOffset)
+{
+  myTextOffset = theOffset;
+}
+
+//=======================================================================
+//function : TextOffset
+//purpose  : 
+//=======================================================================
+
+Standard_Real AIS_Dimension::TextOffset() const
+{
+  return myTextOffset;
+}
+
+//=======================================================================
+//function : drawLinearDimension
+//purpose  : 
+//=======================================================================
+
+void AIS_Dimension::drawLinearDimension (const Handle(Prs3d_Presentation)& thePresentation,
+                                         const gp_Pnt& theFirstAttach,
+                                         const gp_Pnt& theSecondAttach,
+                                         const AIS_DimensionDisplayMode theMode,
+                                         const Standard_Boolean isOneSideDimension/* = Standard_False*/)
+{
+  // Don't build any dimension for equal points
+  if (myFirstPoint.IsEqual (mySecondPoint, Precision::Confusion()))
+  {
+    setComputed (Standard_False);
+    return;
+  }
+  Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
+  Handle(SelectMgr_EntityOwner) anEmptyOwner;
+  myGeom.mySensitiveSegments.Clear();
+
+  gp_Dir aAttachPointsVector = GetWorkingPlane().Axis().Direction()^gce_MakeDir (myFirstPoint, mySecondPoint);
+  // Get line of the dimension
+  gp_Lin aDimensionLine = gce_MakeLin (theFirstAttach, theSecondAttach);
+
+  // Get parameters on dimension line of two layout points
+  Standard_Real aParam1 = ElCLib::Parameter (aDimensionLine, theFirstAttach);
+  Standard_Real aParam2 = ElCLib::Parameter (aDimensionLine, theSecondAttach);
+
+  // For extensions we need to know arrow size and text size, get it from aspect
+  Quantity_Length anArrowLength = aDimensionAspect->ArrowAspect()->Length();
+  // Set line parameters
+  Standard_Real aGap = 0.; // gap between line and text if AIS_VTA_Center
+  if (!myIsValueCustom)
+  {
+   computeValue();
+  }
+
+  TCollection_ExtendedString aValueString;
+  Standard_Real aTextLength;
+  getTextWidthAndString (aTextLength, aValueString);
+
+  // Automatical text and arrow placement
+  Standard_Real aValue = myFirstPoint.Distance (mySecondPoint);
+  if (aDimensionAspect->HorizontalTextAlignment() == Prs3d_HTA_Center)
+  {
+    aDimensionAspect->SetArrowOrientation (Prs3d_DAO_Internal);
+    if (aValue < aTextLength + (isOneSideDimension ? anArrowLength : 2.0 * anArrowLength))
+    {
+      aDimensionAspect->SetArrowOrientation (Prs3d_DAO_External);
+      aDimensionAspect->SetHorizontalTextAlignment (Prs3d_HTA_Left);
+    }
+  }
+  else
+  {
+    aDimensionAspect->SetArrowOrientation (Prs3d_DAO_External);
+  }
+
+  // Arrows positions and directions
+  gp_Pnt aFirstArrowPosition = ElCLib::Value (aParam1, aDimensionLine);
+  gp_Pnt aSecondArrowPosition = ElCLib::Value (aParam2, aDimensionLine);
+  gp_Dir aFirstArrowDir = aDimensionLine.Direction();
+  gp_Dir aSecondArrowDir = aDimensionLine.Direction().Reversed();
+  Standard_Real aFirstArrowBegin, aFirstArrowEnd, aSecondArrowBegin, aSecondArrowEnd;
+
+  if (aDimensionAspect->GetArrowOrientation() == Prs3d_DAO_External)
+  {
+    aFirstArrowDir.Reverse();
+    aSecondArrowDir.Reverse();
+
+    aFirstArrowBegin  = aParam1 - anArrowLength;
+    aFirstArrowEnd    = aParam1;
+    aSecondArrowBegin = aParam2;
+    aSecondArrowEnd   = aParam2 + anArrowLength;
+  }
+  else
+  {
+    aFirstArrowBegin  = aParam1;
+    aFirstArrowEnd    = aParam1 + anArrowLength;
+    aSecondArrowBegin = aParam2 - anArrowLength;
+    aSecondArrowEnd   = aParam2;
+  }
+
+  Handle(Graphic3d_ArrayOfSegments) aPrimSegments;
+  gp_Pnt aFirstPoint, aLastPoint;
+  // Take into account vertical text alignment:
+  // only for 3D text! subtract the text length if it is in the center.
+  Standard_Boolean isGapInCenter = (aDimensionAspect->VerticalTextAlignment() == Prs3d_VTA_Center
+                                     && aDimensionAspect->IsText3d());
+  if (isGapInCenter)
+  {
+    aGap = 1.0;
+  }
+
+  switch (aDimensionAspect->HorizontalTextAlignment())
+  {
+    // Default case - text is to be in the center of length dimension line
+    case Prs3d_HTA_Center:
+    {
+      // Group1: arrows
+      if (theMode != AIS_DDM_Text)
+      {
+        drawArrow (thePresentation, aFirstArrowPosition, aFirstArrowDir);
+        if (!isOneSideDimension)
+        {
+          drawArrow (thePresentation, aSecondArrowPosition, aSecondArrowDir);
+        }
+      }
+
+      // Group 2: Text and dimension line
+      aPrimSegments = new Graphic3d_ArrayOfSegments (isGapInCenter ? 4 : 2);
+      myGeom.myTextPosition = ElCLib::Value ((aParam1 + aParam2) / 2.0, aDimensionLine);
+
+      gp_Vec aTextDir (myFirstPoint, mySecondPoint);
+      Standard_Real aTextWidth = drawText (thePresentation,
+                                           myIsTextReversed ? aTextDir.Reversed() : aTextDir,
+                                           aValueString,
+                                           theMode);
+
+      aFirstPoint = ElCLib::Value (aFirstArrowEnd, aDimensionLine);
+      if (isGapInCenter)
+      {
+        aLastPoint = ElCLib::Value (ElCLib::Parameter (aDimensionLine,myGeom.myTextPosition) - aGap - (aTextWidth / 2.0), aDimensionLine);
+        aPrimSegments->AddVertex (aFirstPoint);
+        aPrimSegments->AddVertex (aLastPoint);
+        myGeom.mySensitiveSegments.Append (new Select3D_SensitiveSegment (anEmptyOwner,aFirstPoint,aLastPoint));
+        aFirstPoint = ElCLib::Value (ElCLib::Parameter(aDimensionLine,myGeom.myTextPosition) + (aTextWidth / 2.0) + aGap, aDimensionLine);
+      }
+      else if (aDimensionAspect->VerticalTextAlignment() == Prs3d_VTA_Top)
+      {
+        aDimensionAspect->TextAspect()->SetVerticalJustification (Graphic3d_VTA_BOTTOM);
+      }
+      else if (aDimensionAspect->VerticalTextAlignment() == Prs3d_VTA_Bottom)
+      {
+        aDimensionAspect->TextAspect()->SetVerticalJustification(Graphic3d_VTA_TOP);
+      }
+
+      aLastPoint = isOneSideDimension ? theSecondAttach : ElCLib::Value (aSecondArrowBegin, aDimensionLine);
+
+      aPrimSegments->AddVertex (aFirstPoint);
+      aPrimSegments->AddVertex (aLastPoint);
+      myGeom.mySensitiveSegments.Append (new Select3D_SensitiveSegment (anEmptyOwner, aFirstPoint, aLastPoint));
+
+      // Main dimension line, short extension
+      if (theMode != AIS_DDM_Text)
+      {
+        if (!aDimensionAspect->IsText3d() && theMode == AIS_DDM_All)
+        {
+          Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_True);
+        }
+        Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect());
+        Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
+        if (!aDimensionAspect->IsText3d() && theMode == AIS_DDM_All)
+        {
+          Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_False);
+        }
+      }
+      break;
+    }
+    // Text is disposed from the left side of length dimension (after the left flyout line)
+    // Needs to create extensions: left for text and right for proper view of dimensions.
+    case Prs3d_HTA_Left:
+    {
+      aPrimSegments = new Graphic3d_ArrayOfSegments (4);
+
+      gp_Pnt aFirstArrowBeginPnt = ElCLib::Value (aFirstArrowBegin, aDimensionLine);
+      gp_Lin aLongExtLine (aDimensionLine.Location(), aDimensionLine.Direction().Reversed());
+      gp_Pnt aStartPoint = ElCLib::Value (aFirstArrowBegin, aDimensionLine);
+      // Left extension with the text
+      drawExtensionWithText (thePresentation, aStartPoint, aLongExtLine, aValueString, theMode);
+
+      // Central(main) dimension line
+      aFirstPoint = ElCLib::Value (aFirstArrowEnd, aDimensionLine);
+      aLastPoint = isOneSideDimension ? theSecondAttach : ElCLib::Value (aSecondArrowBegin, aDimensionLine);
+      aPrimSegments->AddVertex (aFirstPoint);
+      aPrimSegments->AddVertex (aLastPoint);
+      myGeom.mySensitiveSegments.Append (new Select3D_SensitiveSegment (anEmptyOwner, aFirstPoint, aLastPoint));
+
+      // Right extension
+      if (!isOneSideDimension)
+      {
+        aFirstPoint = ElCLib::Value (aSecondArrowEnd, aDimensionLine);
+        aLastPoint = ElCLib::Value (aSecondArrowEnd + anArrowLength, aDimensionLine);
+        aPrimSegments->AddVertex (aFirstPoint);
+        aPrimSegments->AddVertex (aLastPoint);
+        myGeom.mySensitiveSegments.Append(new Select3D_SensitiveSegment (anEmptyOwner, aFirstPoint, aLastPoint));
+      }
+      if (theMode != AIS_DDM_Text)
+      {
+        // Main dimension line, short extension
+        Prs3d_Root::NewGroup (thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect());
+        Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
+        // Group1: Add arrows to a group
+        drawArrow (thePresentation, aFirstArrowPosition, aFirstArrowDir);
+        if (!isOneSideDimension)
+        {
+          drawArrow (thePresentation, aSecondArrowPosition, aSecondArrowDir);
+        }
+      }
+      break;
+    }
+    case Prs3d_HTA_Right:
+    {
+      aPrimSegments = new Graphic3d_ArrayOfSegments (4);
+      // Left extension
+      if (!isOneSideDimension)
+      {
+        aFirstPoint = ElCLib::Value (aFirstArrowBegin - anArrowLength, aDimensionLine);
+        aLastPoint = ElCLib::Value (aFirstArrowEnd, aDimensionLine);
+        aPrimSegments->AddVertex (aFirstPoint);
+        aPrimSegments->AddVertex (aLastPoint);
+        myGeom.mySensitiveSegments.Append (new Select3D_SensitiveSegment (anEmptyOwner, aFirstPoint, aLastPoint));
+      }
+
+      // Central(main) dimension line
+      aFirstPoint = isOneSideDimension ? theFirstAttach :  ElCLib::Value (aFirstArrowEnd, aDimensionLine);
+      aLastPoint = ElCLib::Value (aSecondArrowBegin, aDimensionLine);
+      aPrimSegments->AddVertex (aFirstPoint);
+      aPrimSegments->AddVertex (aLastPoint);
+      myGeom.mySensitiveSegments.Append (new Select3D_SensitiveSegment (anEmptyOwner, aFirstPoint, aLastPoint));
+
+      // Right extension with text
+      aFirstPoint = ElCLib::Value (aSecondArrowEnd, aDimensionLine);
+      drawExtensionWithText (thePresentation, aFirstPoint, aDimensionLine, aValueString, theMode);
+
+      if (theMode != AIS_DDM_Text)
+      {
+        // Main dimension line, short extension
+        Prs3d_Root::NewGroup(thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect());
+        Prs3d_Root::CurrentGroup(thePresentation)->AddPrimitiveArray (aPrimSegments);
+        // Group1, 2: Add arrows to a group
+        if (!isOneSideDimension)
+        {
+          drawArrow (thePresentation, aFirstArrowPosition, aFirstArrowDir);
+        }
+
+        drawArrow (thePresentation, aSecondArrowPosition, aSecondArrowDir);
+      }
+      break;
+    }
+  }
+
+  setComputed (Standard_True);
+}
+
+//=======================================================================
+//function : SetFirstPoint
+//purpose  : 
+//=======================================================================
+
+void AIS_Dimension::SetFirstPoint (const gp_Pnt& thePoint)
+{
+  myFirstPoint = thePoint;
+}
+
+//=======================================================================
+//function : SetSecondPoint
+//purpose  : 
+//=======================================================================
+
+void AIS_Dimension::SetSecondPoint (const gp_Pnt& thePoint)
+{
+  mySecondPoint = thePoint;
+}
+
+//=======================================================================
+//function : Type
+//purpose  :
+//=======================================================================
+
+AIS_KindOfInteractive AIS_Dimension::Type() const
+{
+  return AIS_KOI_Relation;
+}
+
+//=======================================================================
+//function : circleFromPlanarFace
+//purpose  : if possible computes circle from planar face
+//=======================================================================
+
+Standard_Boolean AIS_Dimension::circleFromPlanarFace (const TopoDS_Face& theFace,
+                                                      Handle(Geom_Curve)& theCurve,
+                                                      gp_Pnt & theFirstPoint,
+                                                      gp_Pnt & theLastPoint)
+{
+  TopExp_Explorer anIt (theFace, TopAbs_EDGE);
+  for ( ; anIt.More(); anIt.Next())
+  {
+    TopoDS_Edge aCurEdge =  TopoDS::Edge (anIt.Current());
+    if (AIS::ComputeGeometry (aCurEdge, theCurve, theFirstPoint, theLastPoint))
+    {
+      if (theCurve->IsInstance (STANDARD_TYPE(Geom_Circle)))
+      {
+        return Standard_True;
+      }
+    }
+  }
+  return Standard_False;
+}
+
+//=======================================================================
+//function : initCircularDimension
+//purpose  : if it's possible computes circle from planar face
+//=======================================================================
+
+Standard_Boolean AIS_Dimension::initCircularDimension (const TopoDS_Shape& theShape,
+                                                       gp_Circ& theCircle,
+                                                       gp_Pnt& theMiddleArcPoint,
+                                                       gp_Pnt& theOppositeDiameterPoint)
+{
+  gp_Pln aPln;
+  Handle(Geom_Surface) aBasisSurf;
+  AIS_KindOfSurface aSurfType = AIS_KOS_OtherSurface;
+  gp_Pnt aFirstPoint, aLastPoint;
+  Standard_Real anOffset    = 0.0;
+  Standard_Real aFirstParam = 0.0;
+  Standard_Real aLastParam  = 0.0;