]> OCCT Git - occt-copy.git/commitdiff
0026507: Visualization - Improved presentations of dimensions
authoraba <aba@opencascade.com>
Fri, 7 Aug 2015 18:46:02 +0000 (21:46 +0300)
committeraba <aba@opencascade.com>
Fri, 7 Aug 2015 18:46:02 +0000 (21:46 +0300)
13 files changed:
src/AIS/AIS_AngleDimension.cxx
src/AIS/AIS_DiameterDimension.cxx
src/AIS/AIS_DiameterDimension.hxx
src/AIS/AIS_Dimension.cxx
src/AIS/AIS_Dimension.hxx
src/AIS/AIS_RadiusDimension.cxx
src/AIS/AIS_RadiusDimension.hxx
src/Prs3d/Prs3d.cdl
src/ViewerTest/ViewerTest_RelationCommands.cxx
tests/bugs/vis/bug26507_1 [new file with mode: 0644]
tests/bugs/vis/bug26507_2 [new file with mode: 0644]
tests/bugs/vis/bug26507_3 [new file with mode: 0644]
tests/bugs/vis/bug26507_4 [new file with mode: 0644]

index 2767e031070218d3bee6add0368be704f4a7c69f..6b81661445c58730810f6c8011cd073d496866a1 100644 (file)
@@ -597,9 +597,13 @@ void AIS_AngleDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*
 
   Quantity_Length anArrowLength = aDimensionAspect->ArrowAspect()->Length();
 
-  // prepare label string and compute its geometrical width
-  Standard_Real aLabelWidth;
-  TCollection_ExtendedString aLabelString = GetValueString (aLabelWidth);
+  TCollection_ExtendedString aLabelString = GetTextLabel();
+  // Text sizes
+  Standard_Real aLabelWidth = 0.0;
+  Standard_Real aLabelHeight = 0.0;
+  Standard_Real aSymbolWidth = 0.0;
+  Standard_Real aSymbolHeight = 0.0;
+  getLabelSizes (aLabelString, aLabelWidth, aLabelHeight, aSymbolWidth, aSymbolHeight);
 
   // add margins to label width
   if (aDimensionAspect->IsText3d())
@@ -1159,8 +1163,14 @@ const gp_Pnt AIS_AngleDimension::GetTextPosition() const
   Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
 
   // Prepare label string and compute its geometrical width
-  Standard_Real aLabelWidth;
-  TCollection_ExtendedString aLabelString = GetValueString (aLabelWidth);
+  TCollection_ExtendedString aLabelString = GetTextLabel();
+  // Text sizes
+  Standard_Real aLabelWidth = 0.0;
+  Standard_Real aLabelHeight = 0.0;
+  Standard_Real aSymbolWidth = 0.0;
+  Standard_Real aSymbolHeight = 0.0;
+  getLabelSizes (aLabelString, aLabelWidth, aLabelHeight, aSymbolWidth, aSymbolHeight);
+
 
   gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, myFirstPoint).Normalized() * GetFlyout());
   gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, mySecondPoint).Normalized() * GetFlyout());
@@ -1339,8 +1349,14 @@ void AIS_AngleDimension::FitTextAlignment (const Prs3d_DimensionTextHorizontalPo
   Quantity_Length anArrowLength = aDimensionAspect->ArrowAspect()->Length();
 
   // Prepare label string and compute its geometrical width
-  Standard_Real aLabelWidth;
-  TCollection_ExtendedString aLabelString = GetValueString (aLabelWidth);
+  TCollection_ExtendedString aLabelString = GetTextLabel();
+  // Text sizes
+  Standard_Real aLabelWidth = 0.0;
+  Standard_Real aLabelHeight = 0.0;
+  Standard_Real aSymbolWidth = 0.0;
+  Standard_Real aSymbolHeight = 0.0;
+  getLabelSizes (aLabelString, aLabelWidth, aLabelHeight, aSymbolWidth, aSymbolHeight);
+
 
   // add margins to label width
   if (aDimensionAspect->IsText3d())
index 244f46e62c25f86ace2a5a2d7877d22b671bdf17..66abc06ff48c2b878985b84b93872d00bfc1c4a8 100644 (file)
@@ -37,10 +37,11 @@ namespace
 //function : Constructor
 //purpose  : 
 //=======================================================================
-AIS_DiameterDimension::AIS_DiameterDimension (const gp_Circ& theCircle)
+AIS_DiameterDimension::AIS_DiameterDimension (const gp_Circ& theCircle,
+                                              const Standard_Real theParameter)
 : AIS_Dimension (AIS_KOD_DIAMETER)
 {
-  SetMeasuredGeometry (theCircle);
+  SetMeasuredGeometry (theCircle, theParameter);
   SetSpecialSymbol (THE_DIAMETER_SYMBOL);
   SetDisplaySpecialSymbol (AIS_DSS_Before);
   SetFlyout (0.0);
@@ -107,7 +108,8 @@ gp_Pnt AIS_DiameterDimension::AnchorPoint()
 //function : SetMeasuredGeometry
 //purpose  : 
 //=======================================================================
-void AIS_DiameterDimension::SetMeasuredGeometry (const gp_Circ& theCircle)
+void AIS_DiameterDimension::SetMeasuredGeometry (const gp_Circ& theCircle, 
+                                                 const Standard_Real theParameter)
 {
   myCircle          = theCircle;
   myGeometryType    = GeometryType_Edge;
@@ -122,7 +124,7 @@ void AIS_DiameterDimension::SetMeasuredGeometry (const gp_Circ& theCircle)
   else if (!myIsPlaneCustom)
   {
     ComputePlane();
-    myAnchorPoint = ElCLib::Value (0.0, myCircle);
+    myAnchorPoint = ElCLib::Value (theParameter, myCircle);
   }
 
   SetToUpdate();
@@ -294,7 +296,7 @@ void AIS_DiameterDimension::Compute (const Handle(PrsMgr_PresentationManager3d)&
   gp_Pnt aSecondPnt (gp::Origin());
   ComputeSidePoints (myCircle, aFirstPnt, aSecondPnt);
 
-  DrawLinearDimension (thePresentation, theMode, aFirstPnt, aSecondPnt);
+  DrawLinearDimension (thePresentation, theMode, aFirstPnt, aSecondPnt, Standard_False, myToDrawDimensionLine);
 }
 
 //=======================================================================
index de17879e616c0671b07b147f27cf873778a6d221..8b12a1dc1fe074a59e041f208cb68bf5fb9debd7 100644 (file)
@@ -58,7 +58,7 @@ public:
 
   //! Construct diameter dimension for the circle.
   //! @param theCircle [in] the circle to measure.
-  Standard_EXPORT AIS_DiameterDimension (const gp_Circ& theCircle);
+  Standard_EXPORT AIS_DiameterDimension (const gp_Circ& theCircle, const Standard_Real theParameter = 0);
 
   //! Construct diameter dimension for the circle and orient it correspondingly
   //! to the passed plane.
@@ -105,7 +105,7 @@ public:
   //! The dimension will become invalid if the diameter of the circle
   //! is less than Precision::Confusion().
   //! @param theCircle [in] the circle to measure.
-  Standard_EXPORT void SetMeasuredGeometry (const gp_Circ& theCircle);
+  Standard_EXPORT void SetMeasuredGeometry (const gp_Circ& theCircle, const Standard_Real theParameter = 0);
 
   //! Measure diameter on the passed shape, if applicable.
   //! The dimension will become invalid if the passed shape is not
index a09e1a1da27cf5cae4b1fd30c3bacfe2d4967ee6..6bd087af5110cd268db47b2a2550b8b8886e9d53 100755 (executable)
@@ -24,6 +24,7 @@
 #include <Bnd_Box.hxx>
 #include <ElCLib.hxx>
 #include <Font_BRepFont.hxx>
+#include <Font_FTFont.hxx>
 #include <GC_MakeCircle.hxx>
 #include <Geom_Line.hxx>
 #include <GeomAdaptor_Curve.hxx>
@@ -98,37 +99,105 @@ namespace
 AIS_Dimension::AIS_Dimension (const AIS_KindOfDimension theType)
 : AIS_InteractiveObject  (),
   mySelToleranceForText2d(0.0),
-  myCustomValue          (0.0),
-  myIsValueCustom        (Standard_False),
+  myTypeOfLabel          (TOL_Computed),
+  myLabel                (""),
   myIsTextPositionFixed  (Standard_False), 
   mySpecialSymbol        (' '),
   myDisplaySpecialSymbol (AIS_DSS_No),
+  myToDrawDimensionLine  (Standard_True),
   myGeometryType         (GeometryType_UndefShapes),
   myIsPlaneCustom        (Standard_False),
   myFlyout               (0.0),
+  myIsTextAligned        (Standard_False),
+  myTextDir              (1.0, 0.0, 0.0),
+  myLeaderSegmentLength  (0.0),
   myIsGeometryValid      (Standard_False),
   myKindOfDimension      (theType)
 {
 }
 
+//=======================================================================
+//function : GetValue
+//purpose  : 
+//=======================================================================
+Standard_Real AIS_Dimension::GetValue() const
+{
+  switch (myTypeOfLabel)
+  {
+    case TOL_Computed:
+      return ComputeValue();
+    case TOL_Value:
+      {
+        /*Standard_PCharacter aCString;
+        myLabel.ToUTF8CString (aCString);
+        return atof (aCString);*/
+        return myCustomValue;
+      }
+    case TOL_Text:
+    default:
+      return 0.0;
+  };
+}
+
 //=======================================================================
 //function : SetCustomValue
 //purpose  : 
 //=======================================================================
 void AIS_Dimension::SetCustomValue (const Standard_Real theValue)
 {
-  if (myIsValueCustom && myCustomValue == theValue)
+  if (myTypeOfLabel == TOL_Value && GetValue() == theValue)
   {
     return;
   }
 
-  myIsValueCustom = Standard_True;
+  myTypeOfLabel = TOL_Value;
 
   myCustomValue = theValue;
 
   SetToUpdate();
 }
 
+//=======================================================================
+//function : SetTextLabel
+//purpose  : 
+//=======================================================================
+void AIS_Dimension::SetTextLabel (const TCollection_ExtendedString& theValue)
+{
+  myTypeOfLabel = TOL_Text;
+  myLabel = theValue;
+}
+
+//=======================================================================
+//function : GetTextLabel
+//purpose  : 
+//=======================================================================
+TCollection_ExtendedString AIS_Dimension::GetTextLabel() const
+{
+  if (myTypeOfLabel == TOL_Text)
+  {
+    return myLabel;
+  }
+  else
+  {
+    TCollection_ExtendedString aString;
+
+    // Format value string using "sprintf"
+    TCollection_AsciiString aFormatStr = myDrawer->DimensionAspect()->ValueStringFormat();
+
+    char aFmtBuffer[256];
+    sprintf (aFmtBuffer, aFormatStr.ToCString(), ValueToDisplayUnits());
+    aString = TCollection_ExtendedString (aFmtBuffer);
+
+    // Add units to values string
+    if (myDrawer->DimensionAspect()->IsUnitsDisplayed())
+    {
+      aString += " ";
+      aString += TCollection_ExtendedString (GetDisplayUnits());
+    }
+    return aString;
+  }
+}
+
 //=======================================================================
 //function : GetPlane
 //purpose  : 
@@ -244,6 +313,75 @@ void AIS_Dimension::SetFlyout (const Standard_Real theFlyout)
   SetToUpdate();
 }
 
+//=======================================================================
+//function : ToDrawDimensionLine
+//purpose  : 
+//=======================================================================
+const Standard_Boolean AIS_Dimension::ToDrawDimensionLine() const
+{
+  return myToDrawDimensionLine;
+}
+
+//=======================================================================
+//function : SetToDrawDimensionLine
+//purpose  : 
+//=======================================================================
+void AIS_Dimension::SetToDrawDimensionLine (const Standard_Boolean theToDraw)
+{
+  myToDrawDimensionLine = theToDraw;
+}
+
+//=======================================================================
+//function : SetToAlignText
+//purpose  : 
+//=======================================================================
+void AIS_Dimension::SetToAlignText (const Standard_Boolean theToAlign,
+                                    const gp_Dir& theAlignmentDir)
+{
+  myIsTextAligned = theToAlign;
+  myTextDir = theAlignmentDir;
+  if (theToAlign && !myTextDir.IsNormal (myPlane.Axis().Direction(), Precision::Angular() ) )
+  {
+    myIsTextAligned = Standard_False;
+  }
+}
+
+//=======================================================================
+//function : IsTextAligned
+//purpose  : 
+//=======================================================================
+const Standard_Boolean AIS_Dimension::IsTextAligned() const
+{
+  return myIsTextAligned;
+}
+
+//=======================================================================
+//function : TextAlignmentDir
+//purpose  : 
+//=======================================================================
+const gp_Dir& AIS_Dimension::TextAlignmentDir() const
+{
+  return myTextDir;
+}
+
+//=======================================================================
+//function : SetLeaderSegment
+//purpose  : 
+//=======================================================================
+void AIS_Dimension::SetLeaderSegment (const Standard_Real& theLength)
+{
+  myLeaderSegmentLength = theLength;
+}
+
+//=======================================================================
+//function : UnsetLeaderSegment
+//purpose  : 
+//=======================================================================
+void AIS_Dimension::UnsetLeaderSegment()
+{
+  myLeaderSegmentLength = 0.0;
+}
+
 //=======================================================================
 //function : GetDisplayUnits
 //purpose  :
@@ -273,73 +411,46 @@ Standard_Real AIS_Dimension::ValueToDisplayUnits() const
                              GetDisplayUnits().ToCString());
 }
 
-//=======================================================================
-//function : GetValueString
-//purpose  : 
-//=======================================================================
-TCollection_ExtendedString AIS_Dimension::GetValueString (Standard_Real& theWidth) const
+// =======================================================================
+// function : getWidthAndHeight
+// purpose  :
+// =======================================================================
+void  AIS_Dimension::getLabelSizes (const TCollection_ExtendedString& theLabel,
+                                    Standard_Real& theWidth, Standard_Real& theHeight,
+                                    Standard_Real& theSymbolWidth, Standard_Real& theSymbolHeight
+                                    ) const
 {
-  // format value string using "sprintf"
-  TCollection_AsciiString aFormatStr = myDrawer->DimensionAspect()->ValueStringFormat();
+  theWidth = 0;
+  theHeight = 0;
+  theSymbolWidth = 0;
+  theSymbolHeight = 0;
 
-  char aFmtBuffer[256];
-  sprintf (aFmtBuffer, aFormatStr.ToCString(), ValueToDisplayUnits());
-  TCollection_ExtendedString aValueStr = TCollection_ExtendedString (aFmtBuffer);
 
-  // add units to values string
-  if (myDrawer->DimensionAspect()->IsUnitsDisplayed())
-  {
-    aValueStr += " ";
-    aValueStr += TCollection_ExtendedString (GetDisplayUnits());
-  }
-
-  switch (myDisplaySpecialSymbol)
-  {
-    case AIS_DSS_Before : aValueStr.Insert (1, mySpecialSymbol); break;
-    case AIS_DSS_After  : aValueStr.Insert (aValueStr.Length() + 1, mySpecialSymbol); break;
-    case AIS_DSS_No     : break;
-  }
-
-  // Get text style parameters
-  Quantity_Color aColor; 
+  Handle(Graphic3d_AspectText3d) anAspectText = myDrawer->TextAspect()->Aspect();
+  Quantity_Color aColor;
   Standard_CString aFontName;
-  Standard_Real aFactor;
-  Standard_Real aSpace;
-  myDrawer->DimensionAspect()->TextAspect()->Aspect()->Values (aColor, aFontName, aFactor, aSpace);
-  Font_FontAspect aFontAspect = myDrawer->DimensionAspect()->TextAspect()->Aspect()->GetTextFontAspect();
-  Standard_Real   aFontHeight = myDrawer->DimensionAspect()->TextAspect()->Height();
+  Standard_Real anExpFactor, aSpace;
+  anAspectText->Values (aColor, aFontName, anExpFactor, aSpace);
 
-  NCollection_Utf8String anUTFString = (Standard_Utf16Char* )aValueStr.ToExtString();
+  // Initialize font with specific settings.
+  Font_FTFont aFont;
+  aFont.Init (aFontName, anAspectText->GetTextFontAspect(), myDrawer->TextAspect()->Height(), 96);
 
-  theWidth = 0.0;
+  Font_FTFont::Rect aBndBox;
 
-  if (myDrawer->DimensionAspect()->IsText3d())
-  {
-    // text width produced by BRepFont
-    Font_BRepFont aFont (aFontName, aFontAspect, aFontHeight);
-
-    for (NCollection_Utf8Iter anIter = anUTFString.Iterator(); *anIter != 0; )
-    {
-      Standard_Utf32Char aCurrChar = *anIter;
-      Standard_Utf32Char aNextChar = *(++anIter);
-      theWidth += aFont.AdvanceX (aCurrChar, aNextChar);
-    }
-  }
-  else
+  if (myDisplaySpecialSymbol != AIS_DSS_No)
   {
-    // Text width for 1:1 scale 2D case
-    Handle(Font_FTFont) aFont = new Font_FTFont();
-    aFont->Init (aFontName, aFontAspect, (const unsigned int)aFontHeight, THE_2D_TEXT_RESOLUTION);
-
-    for (NCollection_Utf8Iter anIter = anUTFString.Iterator(); *anIter != 0; )
-    {
-      Standard_Utf32Char aCurrChar = *anIter;
-      Standard_Utf32Char aNextChar = *(++anIter);
-      theWidth += (Standard_Real) aFont->AdvanceX (aCurrChar, aNextChar);
-    }
+    const NCollection_String aString ((Standard_Utf16Char*) TCollection_ExtendedString (mySpecialSymbol).ToExtString());
+    aBndBox = aFont.BoundingBox (aString.ToCString(), Graphic3d_HTA_LEFT, Graphic3d_VTA_TOP);
+    theSymbolWidth = aBndBox.Width();
+    theSymbolHeight = aBndBox.Height();
   }
 
-  return aValueStr;
+  // Compute bounding box for the main text of label
+  const NCollection_String aString ((Standard_Utf16Char*) theLabel.ToExtString());
+  aBndBox = aFont.BoundingBox (aString.ToCString(), Graphic3d_HTA_LEFT, Graphic3d_VTA_TOP);
+  theWidth = aBndBox.Width();
+  theHeight = aBndBox.Height();
 }
 
 //=======================================================================
@@ -410,59 +521,105 @@ void AIS_Dimension::DrawText (const Handle(Prs3d_Presentation)& thePresentation,
                               const TCollection_ExtendedString& theText,
                               const Standard_Integer theLabelPosition)
 {
+  // Prepare font
+  const Handle(Prs3d_TextAspect)& aTextAspect = myDrawer->DimensionAspect()->TextAspect();
+  Handle(Graphic3d_AspectText3d) anAspectText3d = aTextAspect->Aspect();
+  Quantity_Color aColor;
+  Standard_CString aFontName;
+  Standard_Real anExpFactor, aSpace;
+  anAspectText3d->Values (aColor, aFontName, anExpFactor, aSpace);
+  Font_FontAspect aFontAspect = anAspectText3d->GetTextFontAspect();
+  const Standard_Real aFontHeight = aTextAspect->Height();
+
+  Font_FTFont aFont;
+  aFont.Init (aFontName, anAspectText3d->GetTextFontAspect(), myDrawer->TextAspect()->Height(), 96);
+
+  const Standard_Real aHeightOfLine = aFont.LineSpacing();
+
+  // Text sizes
+  Standard_Real aWidth = 0.0;
+  Standard_Real aHeight = 0.0;
+  Standard_Real aSymbolWidth = 0.0;
+  Standard_Real aSymbolHeight = 0.0;
+  getLabelSizes (theText, aWidth, aHeight, aSymbolWidth, aSymbolHeight);
+
+    // Compute label offsets
+  Standard_Real aMarginSize    = aFontHeight * THE_3D_TEXT_MARGIN;
+  Standard_Real aCenterHOffset = 0.0;
+  Standard_Real aCenterVOffset = 0.0;
+  Standard_Real aSymbolVOffset = 0.0; //< Offset of symbol relative to the main text
+
+  Standard_Integer aVLabelPos = theLabelPosition & LabelPosition_VMask;
+
   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 aFontHeight = myDrawer->DimensionAspect()->TextAspect()->Height();
-
-    // creating TopoDS_Shape for text
+    // Creating TopoDS_Shape for text
     Font_BRepFont aFont (aFontName, aFontAspect, aFontHeight);
     NCollection_Utf8String anUTFString = (Standard_Utf16Char* )theText.ToExtString();
     TopoDS_Shape aTextShape = aFont.RenderText (anUTFString);
 
-    // compute text width with kerning
-    Standard_Real aTextWidth  = 0.0;
-    Standard_Real aTextHeight = aFont.Ascender() + aFont.Descender();
-
-    for (NCollection_Utf8Iter anIter = anUTFString.Iterator(); *anIter != 0; )
+    // Add special symbol
+    TopoDS_Shape aSymbolShape;
+    if (myDisplaySpecialSymbol != AIS_DSS_No)
     {
-      Standard_Utf32Char aCurrChar = *anIter;
-      Standard_Utf32Char aNextChar = *(++anIter);
-      aTextWidth += aFont.AdvanceX (aCurrChar, aNextChar);
+      NCollection_Utf8String anUTFSymbol = (Standard_Utf16Char* )TCollection_ExtendedString (mySpecialSymbol).ToExtString();
+      aSymbolShape = aFont.RenderText (anUTFSymbol);
     }
 
-    // formating text position in XOY plane
+    // Formating text position in XOY plane
     Standard_Integer aHLabelPos = theLabelPosition & LabelPosition_HMask;
-    Standard_Integer aVLabelPos = theLabelPosition & LabelPosition_VMask;
-
-    gp_Dir aTextDir (aHLabelPos == LabelPosition_Left ? -theTextDir : theTextDir);
-
-    // compute label offsets
-    Standard_Real aMarginSize    = aFontHeight * THE_3D_TEXT_MARGIN;
-    Standard_Real aCenterHOffset = 0.0;
-    Standard_Real aCenterVOffset = 0.0;
     switch (aHLabelPos)
     {
       case LabelPosition_HCenter : aCenterHOffset =  0.0; break;
-      case LabelPosition_Right   : aCenterHOffset =  aTextWidth / 2.0 + aMarginSize; break;
-      case LabelPosition_Left    : aCenterHOffset = -aTextWidth / 2.0 - aMarginSize; break;
+      case LabelPosition_Right   : aCenterHOffset = aWidth / 2.0 + aMarginSize; break;
+      case LabelPosition_Left    : aCenterHOffset = -aWidth / 2.0 - aMarginSize; break;
     }
     switch (aVLabelPos)
     {
+      case LabelPosition_FirstLine:
+      {
+        if (myTypeOfLabel == TOL_Text && aHeight > aHeightOfLine)
+        {
+          aCenterVOffset = aHeight / 2.0 - aHeightOfLine;
+        }
+        break;
+      }
+      case LabelPosition_LastLine:
+      {
+        if (myTypeOfLabel == TOL_Text && aHeight > aHeightOfLine)
+        {
+          aCenterVOffset = aHeightOfLine - aHeight / 2.0 ;
+        }
+        break;
+      }
       case LabelPosition_VCenter : aCenterVOffset =  0.0; break;
-      case LabelPosition_Above   : aCenterVOffset =  aTextHeight / 2.0 + aMarginSize; break;
-      case LabelPosition_Below   : aCenterVOffset = -aTextHeight / 2.0 - aMarginSize; break;
+      case LabelPosition_Above:
+      {
+        aCenterVOffset =  aHeight / 2.0 + aMarginSize;
+        if (myTypeOfLabel == TOL_Text)
+        {
+          aSymbolVOffset = aCenterVOffset / 2;
+        }
+        break;
+      }
+      case LabelPosition_Below:
+      {
+        aCenterVOffset = -aHeight / 2.0 - aMarginSize;
+        if (myTypeOfLabel == TOL_Text)
+        {
+          aSymbolVOffset = aCenterVOffset / 2;
+        }
+        break;
+      }
     }
 
-    // compute shape offset transformation
-    Standard_Real aShapeHOffset = aCenterHOffset - aTextWidth / 2.0;
-    Standard_Real aShapeVOffset = aCenterVOffset - aTextHeight / 2.0;
+    // Correct text direction
+    gp_Dir aTextDir  = (aHLabelPos == LabelPosition_Left ? -theTextDir : theTextDir);
+
+    // Compute shape offset transformation
+    Standard_Real aShapeHOffset = aCenterHOffset - aWidth / 2.0 /*+ aSymbolWidth*/;
+    Standard_Real aShapeVOffset = aCenterVOffset - aHeight / 2.0;
 
     // center shape in its bounding box (suppress border spacing added by FT_Font)
     Bnd_Box aShapeBnd;
@@ -471,8 +628,8 @@ void AIS_Dimension::DrawText (const Handle(Prs3d_Presentation)& thePresentation,
     Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
     aShapeBnd.Get (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
 
-    Standard_Real aXalign = aTextWidth  * 0.5 - (aXmax + aXmin) * 0.5;
-    Standard_Real aYalign = aTextHeight * 0.5 - (aYmax + aYmin) * 0.5;
+    Standard_Real aXalign = aWidth  * 0.5 - (aXmax + aXmin) * 0.5;
+    Standard_Real aYalign = aHeight * 0.5 - (aYmax + aYmin) * 0.5;
     aShapeHOffset += aXalign;
     aShapeVOffset += aYalign;
 
@@ -486,6 +643,14 @@ void AIS_Dimension::DrawText (const Handle(Prs3d_Presentation)& thePresentation,
     aTextPlaneTrsf.SetTransformation (aTextCoordSystem, gp_Ax3 (gp::XOY()));
     aTextShape.Move (aTextPlaneTrsf);
 
+    if (!aSymbolShape.IsNull())
+    {
+      // Modify transformation for a special symbol relative! to the main text
+      anOffsetTrsf.SetTranslation (gp::Origin(), gp_Pnt (aShapeHOffset - aSymbolWidth, aSymbolVOffset - aHeight / 2.0 + aYalign, 0.0));
+      aSymbolShape.Move (anOffsetTrsf);
+      aSymbolShape.Move (aTextPlaneTrsf);
+    }
+
     // set text flipping anchors
     gp_Trsf aCenterOffsetTrsf;
     gp_Pnt aCenterOffset (aCenterHOffset, aCenterVOffset, 0.0);
@@ -498,7 +663,7 @@ void AIS_Dimension::DrawText (const Handle(Prs3d_Presentation)& thePresentation,
     gp_Ax2 aFlippingAxes (aCenterOfLabel, GetPlane().Axis().Direction(), aTextDir);
     Prs3d_Root::CurrentGroup (thePresentation)->SetFlippingOptions (Standard_True, aFlippingAxes);
 
-    // draw text
+    // Draw text
     if (myDrawer->DimensionAspect()->IsTextShaded())
     {
       // Setting text shading and color parameters
@@ -510,33 +675,92 @@ void AIS_Dimension::DrawText (const Handle(Prs3d_Presentation)& thePresentation,
       myDrawer->ShadingAspect()->Aspect()->SetBackInteriorColor (aColor);
       myDrawer->ShadingAspect()->SetMaterial (aShadeMat);
 
-      // drawing text
+      // Drawing text
       StdPrs_ShadedShape::Add (thePresentation, aTextShape, myDrawer);
+      StdPrs_ShadedShape::Add (thePresentation, aSymbolShape, myDrawer);
     }
     else
     {
-      // setting color for text
+      // Setting color for text
       myDrawer->FreeBoundaryAspect()->Aspect()->SetColor (aColor);
-      // drawing text
+      
+      // Drawing text
       StdPrs_WFShape::Add (thePresentation, aTextShape, myDrawer);
+      StdPrs_WFShape::Add (thePresentation, aSymbolShape, myDrawer);
     }
     Prs3d_Root::CurrentGroup (thePresentation)->SetFlippingOptions (Standard_False, gp_Ax2());
 
     mySelectionGeom.TextPos    = aCenterOfLabel;
     mySelectionGeom.TextDir    = aTextDir;
-    mySelectionGeom.TextWidth  = aTextWidth + aMarginSize * 2.0;
-    mySelectionGeom.TextHeight = aTextHeight;
+    mySelectionGeom.TextWidth  = aWidth + aSymbolWidth + aMarginSize * 2.0;
+    mySelectionGeom.TextHeight = aHeight + aSymbolHeight;
 
     return;
   }
 
-  // generate primitives for 2D text
+  // Generate primitives for 2D text
   myDrawer->DimensionAspect()->TextAspect()->Aspect()->SetDisplayType (Aspect_TODT_DIMENSION);
 
-  Prs3d_Text::Draw (thePresentation,
-                    myDrawer->DimensionAspect()->TextAspect(),
-                    theText,
-                    theTextPos);
+  gp_Pnt aTextPos = theTextPos;
+
+  switch (aVLabelPos)
+  {
+    case LabelPosition_FirstLine:
+    {
+      if (myTypeOfLabel == TOL_Text && aHeight > aHeightOfLine)
+      {
+        //aTextPos.SetY (aTextPos.Y() + aHeight / 2.0 - aHeightOfLine);
+      }
+      break;
+    }
+    case LabelPosition_LastLine:
+    {
+      if (myTypeOfLabel == TOL_Text && aHeight > aHeightOfLine)
+      {
+        //aTextPos.SetY (aTextPos.Y() + aHeightOfLine - aHeight / 2.0);
+      }
+      break;
+    }
+    case LabelPosition_VCenter : break;
+    case LabelPosition_Above:
+    {
+      if (myTypeOfLabel == TOL_Text && aHeight > aHeightOfLine)
+      {
+        aSymbolVOffset = -aWidth / 2;
+      }
+      break;
+    }
+    case LabelPosition_Below:
+    {
+      if (myTypeOfLabel == TOL_Text && aHeight > aHeightOfLine)
+      {
+        aSymbolVOffset = aWidth / 2;
+      }
+      break;
+    }
+  }
+
+  Prs3d_Text::Draw (thePresentation, myDrawer->DimensionAspect()->TextAspect(),
+                    theText, aTextPos);
+
+  switch (myDisplaySpecialSymbol)
+  {
+    case AIS_DSS_Before:
+    {
+      gp_Pnt aSymbolPos (theTextPos.X(), theTextPos.Y() + aSymbolVOffset, theTextPos.Z());
+      Prs3d_Text::Draw (thePresentation, myDrawer->DimensionAspect()->TextAspect(),
+                        TCollection_ExtendedString (mySpecialSymbol), aSymbolPos);
+      break;
+    }
+    case AIS_DSS_After:
+    {
+       gp_Pnt aSymbolPos (theTextPos.X() + aWidth, theTextPos.Y() + aSymbolVOffset, theTextPos.Z());
+       Prs3d_Text::Draw (thePresentation, myDrawer->DimensionAspect()->TextAspect(),
+         TCollection_ExtendedString (mySpecialSymbol), aSymbolPos);
+       break;
+    }
+    case AIS_DSS_No: break;
+  }
 
   mySelectionGeom.TextPos    = theTextPos;
   mySelectionGeom.TextDir    = theTextDir;
@@ -561,17 +785,48 @@ void AIS_Dimension::DrawExtension (const Handle(Prs3d_Presentation)& thePresenta
   gp_Lin anExtensionLine (theExtensionStart, theExtensionDir);
 
   Standard_Boolean hasLabel = theLabelString.Length() > 0;
+
+  gp_Dir aTextDir = myIsTextAligned
+    ? (myTextDir*theExtensionDir < 0 ? -myTextDir : myTextDir)
+    : theExtensionDir;
+
+  Standard_Boolean isShortLine =  !myDrawer->DimensionAspect()->IsText3d()
+                               || theLabelPosition & LabelPosition_VCenter;
+
+  // Compute graphical primitives and sensitives for extension line
+  gp_Pnt anExtStart = theExtensionStart;
+  gp_Pnt   anExtEnd = !hasLabel || isShortLine
+    ? ElCLib::Value (theExtensionSize, anExtensionLine)
+    : ElCLib::Value (theExtensionSize + theLabelWidth, anExtensionLine);
+
+  gp_Pnt aSegmentPoint;
+
   if (hasLabel && (theMode == ComputeMode_All || theMode == ComputeMode_Text))
   {
     // compute text primitives; get its model width
     gp_Pnt aTextPos = ElCLib::Value (theExtensionSize, anExtensionLine);
-    gp_Dir aTextDir = theExtensionDir;
 
-    DrawText (thePresentation,
-              aTextPos,
-              aTextDir,
-              theLabelString,
-              theLabelPosition);
+    if (hasLabel && myLeaderSegmentLength > 0 && myIsTextAligned)
+    {
+      gp_Lin aSegmentLine (anExtEnd, aTextDir);
+      Standard_Real aSegmentLength = isShortLine ? myLeaderSegmentLength : theLabelWidth + myLeaderSegmentLength;
+      aSegmentPoint  = ElCLib::Value (aSegmentLength, aSegmentLine);
+      DrawText (thePresentation,
+                aSegmentPoint,
+                aTextDir,
+                theLabelString,
+                theLabelPosition);
+    }
+    else
+    {
+      DrawText (thePresentation,
+                aTextPos,
+                aTextDir,
+                theLabelString,
+                theLabelPosition);
+    }
+
+
   }
 
   if (theMode != ComputeMode_All && theMode != ComputeMode_Line)
@@ -579,21 +834,22 @@ void AIS_Dimension::DrawExtension (const Handle(Prs3d_Presentation)& thePresenta
     return;
   }
 
-  Standard_Boolean isShortLine =  !myDrawer->DimensionAspect()->IsText3d()
-                               || theLabelPosition & LabelPosition_VCenter;
-
-  // compute graphical primitives and sensitives for extension line
-  gp_Pnt anExtStart = theExtensionStart;
-  gp_Pnt anExtEnd   = !hasLabel || isShortLine
-    ? ElCLib::Value (theExtensionSize, anExtensionLine)
-    : ElCLib::Value (theExtensionSize + theLabelWidth, anExtensionLine);
 
-  // add graphical primitives
-  Handle(Graphic3d_ArrayOfSegments) anExtPrimitive = new Graphic3d_ArrayOfSegments (2);
+  // Add graphical primitives
+  Handle(Graphic3d_ArrayOfSegments) anExtPrimitive = new Graphic3d_ArrayOfSegments ((hasLabel && myLeaderSegmentLength > 0 && myIsTextAligned) ? 4 : 2);
   anExtPrimitive->AddVertex (anExtStart);
   anExtPrimitive->AddVertex (anExtEnd);
+  // Draw segment
+  if (hasLabel && myLeaderSegmentLength > 0 && myIsTextAligned)
+  {
+    anExtPrimitive->AddVertex (anExtEnd);
+    anExtPrimitive->AddVertex (aSegmentPoint);
+  }
+
 
-  // add selection primitives
+
+
+  // Add selection primitives
   SelectionGeometry::Curve& aSensitiveCurve = mySelectionGeom.NewCurve();
   aSensitiveCurve.Append (anExtStart);
   aSensitiveCurve.Append (anExtEnd);
@@ -619,7 +875,8 @@ void AIS_Dimension::DrawLinearDimension (const Handle(Prs3d_Presentation)& thePr
                                          const Standard_Integer theMode,
                                          const gp_Pnt& theFirstPoint,
                                          const gp_Pnt& theSecondPoint,
-                                         const Standard_Boolean theIsOneSide)
+                                         const Standard_Boolean theIsOneSide,
+                                         const Standard_Boolean theToDrawDimensionLine)
 {
   // do not build any dimension for equal points
   if (theFirstPoint.IsEqual (theSecondPoint, Precision::Confusion()))
@@ -632,9 +889,14 @@ void AIS_Dimension::DrawLinearDimension (const Handle(Prs3d_Presentation)& thePr
   // For extensions we need to know arrow size, text size and extension size: get it from aspect
   Quantity_Length anArrowLength   = aDimensionAspect->ArrowAspect()->Length();
   Standard_Real   anExtensionSize = aDimensionAspect->ExtensionSize();
-  // prepare label string and compute its geometrical width
-  Standard_Real aLabelWidth;
-  TCollection_ExtendedString aLabelString = GetValueString (aLabelWidth);
+
+  // Prepare label string and compute its geometrical sizes
+  Standard_Real aLabelWidth, aLabelHeight;
+  Standard_Real aSymbolWidth, aSymbolHeight;
+  TCollection_ExtendedString aLabel = GetTextLabel();
+  getLabelSizes (aLabel, aLabelWidth, aLabelHeight, aSymbolWidth, aSymbolHeight);
+  aLabelHeight += aSymbolHeight;
+  aLabelWidth += aSymbolWidth;
 
   // add margins to cut dimension lines for 3d text
   if (aDimensionAspect->IsText3d())
@@ -659,7 +921,7 @@ void AIS_Dimension::DrawLinearDimension (const Handle(Prs3d_Presentation)& thePr
   FitTextAlignmentForLinear (theFirstPoint, theSecondPoint, theIsOneSide, aHorisontalTextPos,
                              aLabelPosition, isArrowsExternal);
 
-    // compute dimension line points
+  // compute dimension line points
   gp_Ax1 aPlaneNormal = GetPlane().Axis();
   gp_Dir aTargetPointsVector = gce_MakeDir (theFirstPoint, theSecondPoint);
 
@@ -717,6 +979,8 @@ void AIS_Dimension::DrawLinearDimension (const Handle(Prs3d_Presentation)& thePr
 
       gp_Pnt aTextPos = IsTextPositionCustom() ? myFixedTextPosition
                                               : (aCenterLineBegin.XYZ() + aCenterLineEnd.XYZ()) * 0.5;
+
+      // Choose a text direction
       gp_Dir aTextDir = aDimensionLine.Direction();
 
       // add text primitives
@@ -725,15 +989,18 @@ void AIS_Dimension::DrawLinearDimension (const Handle(Prs3d_Presentation)& thePr
         DrawText (thePresentation,
                   aTextPos,
                   aTextDir,
-                  aLabelString,
+                  aLabel,
                   aLabelPosition);
       }
 
       // add dimension line primitives
       if (theMode == ComputeMode_All || theMode == ComputeMode_Line)
       {
-        Standard_Boolean isLineBreak = aDimensionAspect->TextVerticalPosition() == Prs3d_DTVP_Center
-                                    && aDimensionAspect->IsText3d();
+        // Line break is made only for 3d text (for 2d text it is managed with stensil test)
+        // and for special alignment for multi-line text
+        Standard_Boolean isLineBreak = aDimensionAspect->IsText3d() &&
+         (aDimensionAspect->TextVerticalPosition() == Prs3d_DTVP_Center || (myTypeOfLabel == TOL_Text &&
+           (aDimensionAspect->TextVerticalPosition() == Prs3d_DTVP_FirstLine || aDimensionAspect->TextVerticalPosition() == Prs3d_DTVP_LastLine) ) );
 
         Handle(Graphic3d_ArrayOfSegments) aPrimSegments = new Graphic3d_ArrayOfSegments (isLineBreak ? 4 : 2);
 
@@ -770,11 +1037,15 @@ void AIS_Dimension::DrawLinearDimension (const Handle(Prs3d_Presentation)& thePr
 
         // set text label justification
         Graphic3d_VerticalTextAlignment aTextJustificaton = Graphic3d_VTA_BOTTOM;
+
+        // TODO check it!
         switch (aLabelPosition & LabelPosition_VMask)
         {
-          case LabelPosition_Above   :
-          case LabelPosition_VCenter : aTextJustificaton = Graphic3d_VTA_BOTTOM; break;
-          case LabelPosition_Below   : aTextJustificaton = Graphic3d_VTA_TOP;    break;
+          case LabelPosition_Above     :
+          case LabelPosition_LastLine  :
+          case LabelPosition_VCenter   : aTextJustificaton = Graphic3d_VTA_BOTTOM; break;
+          case LabelPosition_FirstLine :
+          case LabelPosition_Below     : aTextJustificaton = Graphic3d_VTA_TOP;    break;
         }
         aDimensionAspect->TextAspect()->SetVerticalJustification (aTextJustificaton);
 
@@ -835,7 +1106,7 @@ void AIS_Dimension::DrawLinearDimension (const Handle(Prs3d_Presentation)& thePr
                        ? aFirstArrowEnd
                        : aFirstArrowBegin,
                      aFirstExtensionDir,
-                     aLabelString,
+                     aLabel,
                      aLabelWidth,
                      theMode,
                      aLabelPosition);
@@ -843,27 +1114,30 @@ void AIS_Dimension::DrawLinearDimension (const Handle(Prs3d_Presentation)& thePr
       // add dimension line primitives
       if (theMode == ComputeMode_All || theMode == ComputeMode_Line)
       {
-        // add central dimension line
-        Prs3d_Root::NewGroup (thePresentation);
+        if (theToDrawDimensionLine || !isArrowsExternal)
+        {
+          // add central dimension line
+          Prs3d_Root::NewGroup (thePresentation);
 
-        // add graphical primitives
-        Handle(Graphic3d_ArrayOfSegments) aPrimSegments = new Graphic3d_ArrayOfSegments (2);
-        aPrimSegments->AddVertex (aCenterLineBegin);
-        aPrimSegments->AddVertex (aCenterLineEnd);
+          // add graphical primitives
+          Handle(Graphic3d_ArrayOfSegments) aPrimSegments = new Graphic3d_ArrayOfSegments (2);
+          aPrimSegments->AddVertex (aCenterLineBegin);
+          aPrimSegments->AddVertex (aCenterLineEnd);
 
-        Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect());
-        Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
+          Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect());
+          Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
 
-        // add selection primitives
-        SelectionGeometry::Curve& aSensitiveCurve = mySelectionGeom.NewCurve();
-        aSensitiveCurve.Append (aCenterLineBegin);
-        aSensitiveCurve.Append (aCenterLineEnd);
+          // add selection primitives
+          SelectionGeometry::Curve& aSensitiveCurve = mySelectionGeom.NewCurve();
+          aSensitiveCurve.Append (aCenterLineBegin);
+          aSensitiveCurve.Append (aCenterLineEnd);
+        }
 
         // add arrows to presentation
         Prs3d_Root::NewGroup (thePresentation);
 
         DrawArrow (thePresentation, aFirstArrowBegin, aFirstArrowDir);
-        if (!theIsOneSide)
+        if (!theIsOneSide && theToDrawDimensionLine)
         {
           DrawArrow (thePresentation, aSecondArrowBegin, aSecondArrowDir);
         }
@@ -876,9 +1150,12 @@ void AIS_Dimension::DrawLinearDimension (const Handle(Prs3d_Presentation)& thePr
         // add extension lines for external arrows
         Prs3d_Root::NewGroup (thePresentation);
 
-        DrawExtension (thePresentation, aDimensionAspect->ArrowTailSize(),
-                       aSecondArrowEnd, aSecondExtensionDir,
-                       THE_EMPTY_LABEL, 0.0, theMode, LabelPosition_None);
+        if (theToDrawDimensionLine)
+        {
+          DrawExtension (thePresentation, aDimensionAspect->ArrowTailSize(),
+            aSecondArrowEnd, aSecondExtensionDir,
+            THE_EMPTY_LABEL, 0.0, theMode, LabelPosition_None);
+        }
       }
 
       break;
@@ -898,26 +1175,29 @@ void AIS_Dimension::DrawLinearDimension (const Handle(Prs3d_Presentation)& thePr
                        ? aSecondArrowEnd
                        : aSecondArrowBegin,
                      aSecondExtensionDir,
-                     aLabelString, aLabelWidth,
+                     aLabel, aLabelWidth,
                      theMode,
                      aLabelPosition);
 
       if (theMode == ComputeMode_All || theMode == ComputeMode_Line)
       {
-        // add central dimension line
-        Prs3d_Root::NewGroup (thePresentation);
+        if (theToDrawDimensionLine || !isArrowsExternal)
+        {
+          // add central dimension line
+          Prs3d_Root::NewGroup (thePresentation);
 
-        // add graphical primitives
-        Handle(Graphic3d_ArrayOfSegments) aPrimSegments = new Graphic3d_ArrayOfSegments (2);
-        aPrimSegments->AddVertex (aCenterLineBegin);
-        aPrimSegments->AddVertex (aCenterLineEnd);
-        Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect());
-        Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
+          // add graphical primitives
+          Handle(Graphic3d_ArrayOfSegments) aPrimSegments = new Graphic3d_ArrayOfSegments (2);
+          aPrimSegments->AddVertex (aCenterLineBegin);
+          aPrimSegments->AddVertex (aCenterLineEnd);
+          Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect());
+          Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
 
-        // add selection primitives
-        SelectionGeometry::Curve& aSensitiveCurve = mySelectionGeom.NewCurve();
-        aSensitiveCurve.Append (aCenterLineBegin);
-        aSensitiveCurve.Append (aCenterLineEnd);
+          // add selection primitives
+          SelectionGeometry::Curve& aSensitiveCurve = mySelectionGeom.NewCurve();
+          aSensitiveCurve.Append (aCenterLineBegin);
+          aSensitiveCurve.Append (aCenterLineEnd);
+        }
 
         // add arrows to presentation
         Prs3d_Root::NewGroup (thePresentation);
@@ -1582,8 +1862,15 @@ void AIS_Dimension::FitTextAlignmentForLinear (const gp_Pnt& theFirstPoint,
   Quantity_Length anArrowLength = aDimensionAspect->ArrowAspect()->Length();
 
   // prepare label string and compute its geometrical width
-  Standard_Real aLabelWidth;
-  TCollection_ExtendedString aLabelString = GetValueString (aLabelWidth);
+  TCollection_ExtendedString aLabelString = GetTextLabel();
+
+  // Text sizes
+  Standard_Real aLabelWidth = 0.0;
+  Standard_Real aLabelHeight = 0.0;
+  Standard_Real aSymbolWidth = 0.0;
+  Standard_Real aSymbolHeight = 0.0;
+  getLabelSizes (aLabelString, aLabelWidth, aLabelHeight, aSymbolWidth, aSymbolHeight);
+
 
   // Add margins to cut dimension lines for 3d text
   if (aDimensionAspect->IsText3d())
@@ -1617,7 +1904,7 @@ void AIS_Dimension::FitTextAlignmentForLinear (const gp_Pnt& theFirstPoint,
   switch (theHorizontalTextPos)
   {
     case Prs3d_DTHP_Left  : theLabelPosition |= LabelPosition_Left; break;
-    case Prs3d_DTHP_Right : theLabelPosition |= LabelPosition_Right; break;
+    case Prs3d_DTHP_Right : theLabelPosition |= theIsOneSide ? LabelPosition_Left : LabelPosition_Right; break;
     case Prs3d_DTHP_Center: theLabelPosition |= LabelPosition_HCenter; break;
     case Prs3d_DTHP_Fit:
     {
@@ -1634,7 +1921,9 @@ void AIS_Dimension::FitTextAlignmentForLinear (const gp_Pnt& theFirstPoint,
   switch (aDimensionAspect->TextVerticalPosition())
   {
     case Prs3d_DTVP_Above  : theLabelPosition |= LabelPosition_Above; break;
+    case Prs3d_DTVP_FirstLine : theLabelPosition |= LabelPosition_FirstLine; break;
     case Prs3d_DTVP_Below  : theLabelPosition |= LabelPosition_Below; break;
+    case Prs3d_DTVP_LastLine : theLabelPosition |= LabelPosition_LastLine; break;
     case Prs3d_DTVP_Center : theLabelPosition |= LabelPosition_VCenter; break;
   }
 }
index 6992339ff9a56765f4e209d271ee71144740c96c..3b8c32e1e1d9d7078d08111bf5fcc4107d2ea0ff 100755 (executable)
@@ -195,10 +195,12 @@ protected:
     LabelPosition_HCenter = 0x04,
     LabelPosition_HMask   = LabelPosition_Left | LabelPosition_Right | LabelPosition_HCenter,
 
-    LabelPosition_Above   = 0x10,
-    LabelPosition_Below   = 0x20,
-    LabelPosition_VCenter = 0x40,
-    LabelPosition_VMask   = LabelPosition_Above | LabelPosition_Below | LabelPosition_VCenter
+    LabelPosition_Above     = 0x0010,
+    LabelPosition_FirstLine = 0x0020,
+    LabelPosition_Below     = 0x0040,
+    LabelPosition_LastLine  = 0x0080,
+    LabelPosition_VCenter   = 0x0100,
+    LabelPosition_VMask     = LabelPosition_Above | LabelPosition_Below | LabelPosition_VCenter | LabelPosition_FirstLine | LabelPosition_LastLine
   };
 
 public:
@@ -224,10 +226,7 @@ public:
   //! compute it on its own in model space coordinates.
   //! @return the dimension value (in model units) which is used
   //! during display of the presentation.
-  Standard_Real GetValue() const
-  {
-    return myIsValueCustom ? myCustomValue : ComputeValue();
-  }
+  Standard_EXPORT Standard_Real GetValue() const;
 
   //! Sets user-defined dimension value.
   //! The user-defined dimension value is specified in model space,
@@ -235,6 +234,14 @@ public:
   //! @param theValue [in] the user-defined value to display.
   Standard_EXPORT void SetCustomValue (const Standard_Real theValue);
 
+  //! Sets nultiline text for dimension label.
+  //! @param theValue [in] multiline string of Unicode symbols.
+  //! Can be used along with spectial symbol (like radius and diameter symbol)
+  Standard_EXPORT void SetTextLabel (const TCollection_ExtendedString& theValue);
+
+  //! @return the text for text label.
+  Standard_EXPORT TCollection_ExtendedString GetTextLabel() const;
+
   //! Get the dimension plane in which the 2D dimension presentation is computed.
   //! By default, if plane is not defined by user, it is computed automatically
   //! after dimension geometry is computed.
@@ -375,6 +382,26 @@ public:
     return myIsGeometryValid && CheckPlane (GetPlane());
   }
 
+  //! @return state that shows if the radius inner segment
+  //! is to be displayed.
+  Standard_EXPORT const Standard_Boolean ToDrawDimensionLine() const;
+
+  //! Sets the flag that defines whether the dimenion line segment is displayed
+  //! @warning Dimension line won't be displayed only if arrows and label are moved
+  //! outside on dimension line extensions
+  Standard_EXPORT void SetToDrawDimensionLine (const Standard_Boolean theToDrawInnerSegment);
+
+  Standard_EXPORT void SetToAlignText (const Standard_Boolean theToAlign,
+                                       const gp_Dir& theAlignmentDir = gp_Dir (1.0, 0.0, 0.0));
+
+  Standard_EXPORT const Standard_Boolean IsTextAligned() const;
+
+  Standard_EXPORT const gp_Dir& TextAlignmentDir() const;
+
+  Standard_EXPORT void SetLeaderSegment (const Standard_Real& theLength);
+
+  Standard_EXPORT void UnsetLeaderSegment();
+
 public:
 
   DEFINE_STANDARD_RTTI(AIS_Dimension)
@@ -383,10 +410,9 @@ protected:
 
   Standard_EXPORT Standard_Real ValueToDisplayUnits() const;
 
-  //! Get formatted value string and its model space width.
-  //! @param theWidth [out] the model space with of the string.
-  //! @return formatted dimension value string.
-  Standard_EXPORT TCollection_ExtendedString GetValueString (Standard_Real& theWidth) const;
+  Standard_EXPORT void getLabelSizes (const TCollection_ExtendedString& theLabel,
+                                      Standard_Real& theWidth, Standard_Real& theHeight,
+                                      Standard_Real& theSymbolWidth, Standard_Real& theSymbolHeight) const;
 
   //! Performs drawing of 2d or 3d arrows on the working plane
   //! @param theLocation [in] the location of the arrow tip.
@@ -434,11 +460,15 @@ protected:
   //! @param theFirstPoint [in] the first attach point of linear dimension.
   //! @param theSecondPoint [in] the second attach point of linear dimension.
   //! @param theIsOneSide [in] specifies whether the dimension has only one flyout line.
+  //! @param theToDrawDimensionLine [in] specifies whether the dimension line is to be displayed.
+  //! @warning Dimension line won't be displayed only if arrows and label are moved
+  //! outside on dimension line extensions
   Standard_EXPORT void DrawLinearDimension (const Handle(Prs3d_Presentation)& thePresentation,
                                             const Standard_Integer theMode,
                                             const gp_Pnt& theFirstPoint,
                                             const gp_Pnt& theSecondPoint,
-                                            const Standard_Boolean theIsOneSide = Standard_False);
+                                            const Standard_Boolean theIsOneSide = Standard_False,
+                                            const Standard_Boolean theToDrawDimensionLine = Standard_True);
 
   //! Compute selection sensitives for linear dimension flyout lines (length, diameter, radius).
   //! Please note that this method uses base dimension properties: working plane and flyout length.
@@ -650,29 +680,57 @@ protected: //! @name Selection geometry
 
   Standard_Real mySelToleranceForText2d; //!< Sensitive point tolerance for 2d text selection.
 
-protected: //! @name Value properties
+protected:
+
+  enum TypeOfLabel
+  {
+    TOL_Computed = 0, //< is default
+    TOL_Value    = 1,
+    TOL_Text 
+  };
+
+protected: //! @name Label properties
+
+  TypeOfLabel myTypeOfLabel;
 
-  Standard_Real    myCustomValue;   //!< Value of the dimension (computed or user-defined).
-  Standard_Boolean myIsValueCustom; //!< Is user-defined value.
+  Standard_Real              myCustomValue; //!< Value of the dimension (computed or user-defined).
+  TCollection_ExtendedString myLabel;        //!< Label text. Sets the user defined multiline text
 
 protected: //! @name Fixed text position properties
 
-  gp_Pnt                  myFixedTextPosition;   //!< Stores text position fixed by user.
-  Standard_Boolean        myIsTextPositionFixed; //!< Is the text label position fixed by user.
+  gp_Pnt                   myFixedTextPosition;   //!< Stores text position fixed by user.
+  Standard_Boolean         myIsTextPositionFixed; //!< Is the text label position fixed by user.
 
 protected: //! @name Units properties
 
   Standard_ExtCharacter    mySpecialSymbol;        //!< Special symbol.
   AIS_DisplaySpecialSymbol myDisplaySpecialSymbol; //!< Special symbol display options.
 
+protected:
+
+  //! Shows if the dimension line is to be drawn
+  //! It is used only if the text is placed on the one of the dimension line extensions.
+  //! By default it is TRUE
+  //! @warning Dimension line won't be displayed only if arrows and label are moved
+  //! outside on dimension line extensions
+  Standard_Boolean myToDrawDimensionLine;
+
 protected: //! @name Geometrical properties
 
   GeometryType myGeometryType;  //!< defines type of shapes on which the dimension is to be built. 
 
-  gp_Pln           myPlane;           //!< Plane where dimension will be built (computed or user defined).
-  Standard_Boolean myIsPlaneCustom;   //!< Is plane defined by user (otherwise it will be computed automatically).
-  Standard_Real    myFlyout;          //!< Flyout distance.
-  Standard_Boolean myIsGeometryValid; //!< Is dimension geometry properly defined.
+  gp_Pln           myPlane;               //!< Plane where dimension will be built (computed or user defined).
+  Standard_Boolean myIsPlaneCustom;       //!< Is plane defined by user (otherwise it will be computed automatically).
+  Standard_Real    myFlyout;              //!< Flyout distance.
+  
+  //! Shows if the text label is aligned to user-defined direction myTextDir
+  //! Otherwise it is alligned to the dimension line extension direction
+  //! @warning Only for text placed outside of the dimension line
+  Standard_Boolean myIsTextAligned;       
+  gp_Dir           myTextDir;             //!< Alignment direction for the text
+  Standard_Real    myLeaderSegmentLength; //!< Length of leader line segment aligned with text to myTextDir direction
+  
+  Standard_Boolean myIsGeometryValid;     //!< Is dimension geometry properly defined.
 
 private:
 
index 265201117fc3353d731c087b8d79aa8e74bd3abd..0319b5696171ff4565489e78692d52ea63c6810e 100644 (file)
@@ -33,15 +33,25 @@ namespace
 //function : Constructor
 //purpose  : 
 //=======================================================================
-AIS_RadiusDimension::AIS_RadiusDimension (const gp_Circ& theCircle)
-: AIS_Dimension (AIS_KOD_RADIUS)
+void AIS_RadiusDimension::init()
 {
-  SetMeasuredGeometry (theCircle);
   SetSpecialSymbol (THE_RADIUS_SYMBOL);
   SetDisplaySpecialSymbol (AIS_DSS_Before);
   SetFlyout (0.0);
 }
 
+//=======================================================================
+//function : Constructor
+//purpose  : 
+//=======================================================================
+AIS_RadiusDimension::AIS_RadiusDimension (const gp_Circ& theCircle,
+                                          const Standard_Real theParameter)
+: AIS_Dimension (AIS_KOD_RADIUS)
+{
+  init();
+  SetMeasuredGeometry (theCircle, theParameter);
+}
+
 //=======================================================================
 //function : Constructor
 //purpose  : 
@@ -50,10 +60,8 @@ AIS_RadiusDimension::AIS_RadiusDimension (const gp_Circ& theCircle,
                                           const gp_Pnt& theAttachPoint)
 : AIS_Dimension (AIS_KOD_RADIUS)
 {
+  init();
   SetMeasuredGeometry (theCircle, theAttachPoint);
-  SetSpecialSymbol (THE_RADIUS_SYMBOL);
-  SetDisplaySpecialSymbol (AIS_DSS_Before);
-  SetFlyout (0.0);
 }
 
 //=======================================================================
@@ -63,22 +71,21 @@ AIS_RadiusDimension::AIS_RadiusDimension (const gp_Circ& theCircle,
 AIS_RadiusDimension::AIS_RadiusDimension (const TopoDS_Shape& theShape)
 : AIS_Dimension (AIS_KOD_RADIUS)
 {
+  init();
   SetMeasuredGeometry (theShape);
-  SetSpecialSymbol (THE_RADIUS_SYMBOL);
-  SetDisplaySpecialSymbol (AIS_DSS_Before);
-  SetFlyout (0.0);
 }
 
 //=======================================================================
 //function : SetMeasuredGeometry
 //purpose  : 
 //=======================================================================
-void AIS_RadiusDimension::SetMeasuredGeometry (const gp_Circ& theCircle)
+void AIS_RadiusDimension::SetMeasuredGeometry (const gp_Circ& theCircle,
+                                               const Standard_Real theParameter)
 {
   myCircle          = theCircle;
   myGeometryType    = GeometryType_Edge;
   myShape           = BRepLib_MakeEdge (theCircle);
-  myAnchorPoint     = ElCLib::Value (0, myCircle);
+  myAnchorPoint     = ElCLib::Value (theParameter, myCircle);
   myIsGeometryValid = IsValidCircle (myCircle);
 
   if (myIsGeometryValid)
@@ -130,6 +137,33 @@ void AIS_RadiusDimension::SetMeasuredGeometry (const TopoDS_Shape& theShape)
   SetToUpdate();
 }
 
+//=======================================================================
+//function : Circle
+//purpose  : 
+//=======================================================================
+const gp_Circ& AIS_RadiusDimension::Circle() const
+{
+  return myCircle;
+}
+
+//=======================================================================
+//function : AnchorPoint
+//purpose  : 
+//=======================================================================
+const gp_Pnt& AIS_RadiusDimension::AnchorPoint() const
+{
+  return myAnchorPoint;
+}
+
+//=======================================================================
+//function : Shape
+//purpose  : 
+//=======================================================================
+const TopoDS_Shape& AIS_RadiusDimension::Shape() const
+{
+  return myShape;
+}
+
 //=======================================================================
 //function : CheckPlane
 //purpose  : 
@@ -230,7 +264,7 @@ void AIS_RadiusDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /
     return;
   }
 
-  DrawLinearDimension (thePresentation, theMode, myAnchorPoint, myCircle.Location(), Standard_True);
+  DrawLinearDimension (thePresentation, theMode, myAnchorPoint, myCircle.Location(), Standard_True, myToDrawDimensionLine);
 }
 
 //=======================================================================
index 991c4a28aa15912acc70ab6e73d744a12c5527f6..e9b896193d9e0e69cc7c5e30e33dcc9ac6263a28 100644 (file)
@@ -38,13 +38,19 @@ DEFINE_STANDARD_HANDLE (AIS_RadiusDimension,AIS_Dimension)
 //! In case if the dimension is built on the arbitrary shape,
 //! it can be considered as invalid if the shape does not contain
 //! circle geometry.
+//! Use IsValid() method to check that created dimension is valid.
 class AIS_RadiusDimension : public AIS_Dimension
 {
+protected:
+  
+  //! Setting of default construction paramters
+  void init();
+
 public:
 
   //! Create radius dimension for the circle geometry.
   //! @param theCircle [in] the circle to measure.
-  Standard_EXPORT AIS_RadiusDimension (const gp_Circ& theCircle);
+  Standard_EXPORT AIS_RadiusDimension (const gp_Circ& theCircle, const Standard_Real theParameter = 0);
 
   //! Create radius dimension for the circle geometry and define its
   //! orientation by location of the first point on that circle.
@@ -61,22 +67,13 @@ public:
 public:
 
   //! @return measured geometry circle.
-  const gp_Circ& Circle() const
-  {
-    return myCircle;
-  }
+  Standard_EXPORT const gp_Circ& Circle() const;
 
   //! @return anchor point on circle for radius dimension.
-  const gp_Pnt& AnchorPoint() const
-  {
-    return myAnchorPoint;
-  }
+  Standard_EXPORT const gp_Pnt& AnchorPoint() const;
 
   //! @return the measured shape.
-  const TopoDS_Shape& Shape() const
-  {
-    return myShape;
-  }
+  Standard_EXPORT const TopoDS_Shape& Shape() const;
 
 public:
 
@@ -84,7 +81,7 @@ public:
   //! The dimension will become invalid if the radius of the circle
   //! is less than Precision::Confusion().
   //! @param theCircle [in] the circle to measure.
-  Standard_EXPORT void SetMeasuredGeometry (const gp_Circ& theCircle);
+  Standard_EXPORT void SetMeasuredGeometry (const gp_Circ& theCircle, const Standard_Real theParameter = 0);
 
   //! Measure radius of the circle and orient the dimension so
   //! the dimension lines attaches to anchor point on the circle.
@@ -121,16 +118,16 @@ public:
 
 protected:
 
-  Standard_EXPORT virtual void ComputePlane();
+  Standard_EXPORT virtual void ComputePlane() Standard_OVERRIDE;
 
   //! Checks if anchor point and the center of the circle are on the plane.
-  Standard_EXPORT virtual Standard_Boolean CheckPlane (const gp_Pln& thePlane) const;
+  Standard_EXPORT virtual Standard_Boolean CheckPlane (const gp_Pln& thePlane) const Standard_OVERRIDE;
 
-  Standard_EXPORT virtual Standard_Real ComputeValue() const;
+  Standard_EXPORT virtual Standard_Real ComputeValue() const Standard_OVERRIDE;
 
   Standard_EXPORT virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
                                         const Handle(Prs3d_Presentation)& thePresentation,
-                                        const Standard_Integer theMode = 0);
+                                        const Standard_Integer theMode = 0) Standard_OVERRIDE;
 
 protected:
 
index da879ef8e32f8cc03740284a5dba510f95b0a6a5..2ebe681816742c13dba56d2565863daaa33142e8 100644 (file)
@@ -78,11 +78,13 @@ is
   -- DTHP_Fit    - value label located automatically at left side if does not fits
   --               the dimension space, otherwise the value label is placed at center.
 
-  enumeration DimensionTextVerticalPosition is DTVP_Above, DTVP_Below, DTVP_Center;
+  enumeration DimensionTextVerticalPosition is DTVP_Above, DTVP_FirstLine, DTVP_Below, DTVP_LastLine, DTVP_Center;
   ---Purpose: Specifies options for positioning dimension value label in vertical direction
   -- with respect to dimension (extension) line.
   -- DTVP_Above - text label is located above the dimension or extension line.
+  -- DTVP_FirstLine - for multi-line text: first line alignment (is by default for multi-line label)
   -- DTVP_Below - text label is located below the dimension or extension line.
+  -- DTVP_LastLine - for multi-line text: last line alignment (is by default for multi-line label)
   -- DTVP_Center - the text label middle-point is in line with dimension or extension line.
 
   enumeration DimensionArrowOrientation is DAO_Internal, DAO_External, DAO_Fit;
index d15dafe84fc50bc2e7bc1cff42cab44212107e24..37094bd17046692f9ff107e3f4218c1fcd30a9b0 100644 (file)
@@ -38,6 +38,7 @@
 #include <Draw_Appli.hxx>
 #include <Draw_Window.hxx>
 #include <DBRep.hxx>
+#include <ElCLib.hxx>
 #include <ElSLib.hxx>
 #include <GC_MakePlane.hxx>
 #include <Geom_CartesianPoint.hxx>
@@ -168,16 +169,21 @@ static Standard_Boolean Get3DPointAtMousePosition (const gp_Pnt& theFirstPoint,
 //           length, angle, radius and diameter dimension.
 //
 //draw args: -text [3d|2d] [wf|sh|wireframe|shading] [Size]
-//           -label [left|right|hcenter|hfit] [top|bottom|vcenter|vfit]
+//           -label [left|right|hcenter|hfit] [top|bottom|vcenter|firstline|lastline|vfit]
 //           -arrow [external|internal|fit] [Length(int)]
 //           -arrowangle ArrowAngle(degrees)
 //           -plane xoy|yoz|zox
 //           -flyout FloatValue -extension FloatValue
 //           -value CustomNumberValue
+//           -valuetext CustomText
 //           -dispunits DisplayUnitsString
 //           -modelunits ModelUnitsString
-//           -showunits
+//           -showunits (DEFAULT)
 //           -hideunits
+//           -drawdimline (DEFAULT)
+//           -hidedimline
+//           -aligntext DirX DirY DirZ
+//           -segment Length
 //
 // Warning! flyout is not an aspect value, it is for dimension parameter
 // likewise text position, but text position override other paramaters.
@@ -190,6 +196,8 @@ static int ParseDimensionParams (Standard_Integer  theArgNum,
                                  Standard_Boolean& theIsCustomPlane, gp_Pln& thePlane,
                                  NCollection_DataMap<TCollection_AsciiString, Standard_Real>& theRealParams,
                                  NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString>& theStringParams,
+                                 NCollection_DataMap<TCollection_AsciiString, Standard_Boolean>& theBooleanParams,
+                                 Standard_Boolean& theIsTextAligned, gp_Dir& theTextDir,
                                  NCollection_List<Handle(AIS_InteractiveObject)>* theShapeList = NULL)
 {
   theRealParams.Clear();
@@ -208,7 +216,7 @@ static int ParseDimensionParams (Standard_Integer  theArgNum,
       continue;
     }
 
-    // Boolean flags
+    // BOOLEAN flags
     if (aParam.IsEqual ("-showunits"))
     {
       theAspect->MakeUnitsDisplayed (Standard_True);
@@ -220,14 +228,25 @@ static int ParseDimensionParams (Standard_Integer  theArgNum,
       continue;
     }
 
-    // Before all non-boolean flags parsing check if a flag have at least one value.
+    if (aParam.IsEqual ("-drawdimline"))
+    {
+      theBooleanParams.Bind ("drawdimline", Standard_True);
+      continue;
+    }
+    else if (aParam.IsEqual ("-hidedimline"))
+    {
+      theBooleanParams.Bind ("drawdimline", Standard_False);
+      continue;
+    }
+
+    // Before all NON-BOOLEAN flags parsing check if a flag have at least one value.
     if (anIt + 1 >= theArgNum)
     {
       std::cerr << "Error: "<< aParam <<" flag should have value.\n";
       return 1;
     }
 
-    // Non-boolean flags
+    // NON-BOOLEAN flags
     if (aParam.IsEqual ("-shape")
      || aParam.IsEqual ("-shapes"))
     {
@@ -305,13 +324,15 @@ static int ParseDimensionParams (Standard_Integer  theArgNum,
         TCollection_AsciiString aParamValue (theArgVec[anIt]);
         aParamValue.LowerCase();
 
-        if (aParamValue == "left")         { theAspect->SetTextHorizontalPosition (Prs3d_DTHP_Left);  }
-        else if (aParamValue == "right")   { theAspect->SetTextHorizontalPosition (Prs3d_DTHP_Right); }
-        else if (aParamValue == "hcenter") { theAspect->SetTextHorizontalPosition (Prs3d_DTHP_Center);}
-        else if (aParamValue == "hfit")    { theAspect->SetTextHorizontalPosition (Prs3d_DTHP_Fit);   }
-        else if (aParamValue == "above")   { theAspect->SetTextVerticalPosition   (Prs3d_DTVP_Above); }
-        else if (aParamValue == "below")   { theAspect->SetTextVerticalPosition   (Prs3d_DTVP_Below); }
-        else if (aParamValue == "vcenter") { theAspect->SetTextVerticalPosition   (Prs3d_DTVP_Center);}
+        if      (aParamValue == "left")      { theAspect->SetTextHorizontalPosition (Prs3d_DTHP_Left);      }
+        else if (aParamValue == "right")     { theAspect->SetTextHorizontalPosition (Prs3d_DTHP_Right);     }
+        else if (aParamValue == "hcenter")   { theAspect->SetTextHorizontalPosition (Prs3d_DTHP_Center);    }
+        else if (aParamValue == "hfit")      { theAspect->SetTextHorizontalPosition (Prs3d_DTHP_Fit);       }
+        else if (aParamValue == "above")     { theAspect->SetTextVerticalPosition   (Prs3d_DTVP_Above);     }
+        else if (aParamValue == "below")     { theAspect->SetTextVerticalPosition   (Prs3d_DTVP_Below);     }
+        else if (aParamValue == "vcenter")   { theAspect->SetTextVerticalPosition   (Prs3d_DTVP_Center);    }
+        else if (aParamValue == "firstline") { theAspect->SetTextVerticalPosition   (Prs3d_DTVP_FirstLine); }
+        else if (aParamValue == "lastline")  { theAspect->SetTextVerticalPosition   (Prs3d_DTVP_LastLine);  }
         else
         {
           std::cerr << "Error: invalid label position: '" << aParamValue << "'.\n";
@@ -334,7 +355,7 @@ static int ParseDimensionParams (Standard_Integer  theArgNum,
       TCollection_AsciiString aValue (theArgVec[++anIt]);
       if (!aValue.IsRealValue())
       {
-        std::cerr << "Error: arrow lenght should be float degree value.\n";
+        std::cerr << "Error: arrow length should be float degree value.\n";
         return 1;
       }
       theAspect->ArrowAspect()->SetLength (Draw::Atof (aValue.ToCString()));
@@ -388,6 +409,20 @@ static int ParseDimensionParams (Standard_Integer  theArgNum,
         return 1;
       }
     }
+    else if (aParam.IsEqual ("-aligntext"))
+    {
+      theIsTextAligned = Standard_True;
+      TCollection_AsciiString aParam1 (theArgVec[++anIt]);
+      TCollection_AsciiString aParam2 (theArgVec[++anIt]);
+      TCollection_AsciiString aParam3 (theArgVec[++anIt]);
+      if (!aParam1.IsRealValue() || !aParam2.IsRealValue() || !aParam3.IsRealValue())
+      {
+        std::cerr << "Error: direction coordinate should be real value.\n";
+        return 1;
+      }
+      theTextDir.SetCoord (aParam1.RealValue(), aParam2.RealValue(), aParam3.RealValue());
+    }
+    // REAL parameters
     else if (aParam.IsEqual ("-flyout"))
     {
       TCollection_AsciiString aParam (theArgVec[++anIt]);
@@ -402,13 +437,43 @@ static int ParseDimensionParams (Standard_Integer  theArgNum,
     else if (aParam.IsEqual ("-value"))
     {
       TCollection_AsciiString aParam (theArgVec[++anIt]);
+
+      // Custom real value
       if (!aParam.IsRealValue())
       {
-        std::cerr << "Error: dimension value for dimension should be real value.\n";
+        std::cerr << "Error: custom value should be real value.\n";
         return 1;
       }
-
       theRealParams.Bind ("value", Draw::Atof (aParam.ToCString()));
+
+    }
+    else if (aParam.IsEqual ("-circleparam"))
+    {
+      TCollection_AsciiString aParam (theArgVec[++anIt]);
+      if (!aParam.IsRealValue())
+      {
+        std::cerr << "Error: circle parameter should be real value.\n";
+        return 1;
+      }
+
+      theRealParams.Bind ("circleparam", aParam.RealValue());
+    }
+    else if (aParam.IsEqual ("-segment"))
+    {
+       TCollection_AsciiString aParam (theArgVec[++anIt]);
+      if (!aParam.IsRealValue() || aParam.RealValue() < 0.0)
+      {
+        std::cerr << "Error: segment length should be positive real value.\n";
+        return 1;
+      }
+
+      theRealParams.Bind ("segment", aParam.RealValue());
+    }
+    // STRING parameters
+    else if (aParam.IsEqual ("-valuetext"))
+    {
+      TCollection_AsciiString aParam (theArgVec[++anIt]);
+      theStringParams.Bind ("valuetext", aParam);
     }
     else if (aParam.IsEqual ("-modelunits"))
     {
@@ -438,7 +503,8 @@ static int ParseDimensionParams (Standard_Integer  theArgNum,
 //=======================================================================
 static void SetDimensionParams (const Handle(AIS_Dimension)& theDim,
                                 const NCollection_DataMap<TCollection_AsciiString, Standard_Real>& theRealParams,
-                                const NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString>& theStringParams)
+                                const NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString>& theStringParams,
+                                const NCollection_DataMap<TCollection_AsciiString, Standard_Boolean>& theBooleanParams)
 {
   if (theRealParams.IsBound ("flyout"))
   {
@@ -449,6 +515,10 @@ static void SetDimensionParams (const Handle(AIS_Dimension)& theDim,
   {
     theDim->SetCustomValue (theRealParams.Find ("value"));
   }
+  else if (theStringParams.IsBound ("valuetext"))
+  {
+    theDim->SetTextLabel (theStringParams.Find ("valuetext"));
+  }
 
   if (theStringParams.IsBound ("modelunits"))
   {
@@ -459,6 +529,16 @@ static void SetDimensionParams (const Handle(AIS_Dimension)& theDim,
   {
     theDim->SetDisplayUnits (theStringParams.Find ("dispunits"));
   }
+
+  if (theBooleanParams.IsBound ("drawdimline"))
+  {
+    theDim->SetToDrawDimensionLine (theBooleanParams.Find ("drawdimline"));
+  }
+
+  if (theRealParams.IsBound ("segment"))
+  {
+    theDim->SetLeaderSegment (theRealParams.Find ("segment"));
+  }
 }
 
 //=======================================================================
@@ -483,9 +563,12 @@ static int VDimBuilder (Draw_Interpretor& /*theDi*/,
   Handle(Prs3d_DimensionAspect) anAspect = new Prs3d_DimensionAspect;
   Standard_Boolean isPlaneCustom = Standard_False;
   gp_Pln aWorkingPlane;
+  Standard_Boolean isTextAligned = Standard_False;
+  gp_Dir aTextDir (1.0, 0.0, 0.0);
 
   NCollection_DataMap<TCollection_AsciiString, Standard_Real> aRealParams;
   NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString> aStringParams;
+  NCollection_DataMap<TCollection_AsciiString, Standard_Boolean> aBoolParams;
 
   TCollection_AsciiString aDimType(theArgs[2]);
   aDimType.LowerCase();
@@ -515,7 +598,7 @@ static int VDimBuilder (Draw_Interpretor& /*theDi*/,
 
   if (ParseDimensionParams (theArgsNb, theArgs, 3,
                             anAspect,isPlaneCustom,aWorkingPlane,
-                            aRealParams, aStringParams, &aShapes))
+                            aRealParams, aStringParams, aBoolParams, isTextAligned, aTextDir, &aShapes))
   {
     return 1;
   }
@@ -656,7 +739,15 @@ static int VDimBuilder (Draw_Interpretor& /*theDi*/,
         {
           Handle(AIS_Circle) aShape = Handle(AIS_Circle)::DownCast (aShapes.First());
           gp_Circ aCircle = aShape->Circle()->Circ();
-          aDim = new AIS_RadiusDimension (aCircle);
+          Standard_Real aParam = 0;
+
+          // Check if circle parameter is set
+          if (aRealParams.IsBound ("circleparam"))
+          {
+            aParam = aRealParams.Find ("circleparam");
+          }
+
+          aDim = new AIS_RadiusDimension (aCircle, aParam);
         }
         else
         {
@@ -685,7 +776,16 @@ static int VDimBuilder (Draw_Interpretor& /*theDi*/,
         {
           Handle(AIS_Circle) aShape = Handle(AIS_Circle)::DownCast (aShapes.First());
           gp_Circ aCircle = aShape->Circle()->Circ();
-          aDim = new AIS_DiameterDimension (aCircle);
+
+          Standard_Real aParam = 0;
+
+          // Check if circle parameter is set
+          if (aRealParams.IsBound ("circleparam"))
+          {
+            aParam = aRealParams.Find ("circleparam");
+          }
+
+          aDim = new AIS_DiameterDimension (aCircle, aParam);
         }
         else
         {
@@ -713,6 +813,11 @@ static int VDimBuilder (Draw_Interpretor& /*theDi*/,
     }
   }
 
+  if (isTextAligned)
+  {
+    aDim->SetToAlignText (isTextAligned, aTextDir);
+  }
+
   // Check dimension geometry
   if (!aDim->IsValid())
   {
@@ -723,7 +828,7 @@ static int VDimBuilder (Draw_Interpretor& /*theDi*/,
 
   aDim->SetDimensionAspect (anAspect);
 
-  SetDimensionParams (aDim, aRealParams, aStringParams);
+  SetDimensionParams (aDim, aRealParams, aStringParams, aBoolParams);
 
   VDisplayAISObject (aName,aDim);
 
@@ -2544,10 +2649,13 @@ static int VDimParam (Draw_Interpretor& theDi, Standard_Integer theArgNum, const
   TCollection_AsciiString aName (theArgVec[1]);
   gp_Pln aWorkingPlane;
   Standard_Boolean isCustomPlane = Standard_False;
+  Standard_Boolean isTextAligned = Standard_False;
+  gp_Dir aTextDir (1.0, 0.0, 0.0);
   Standard_Boolean toUpdate = Standard_True;
 
   NCollection_DataMap<TCollection_AsciiString, Standard_Real> aRealParams;
   NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString> aStringParams;
+  NCollection_DataMap<TCollection_AsciiString, Standard_Boolean> aBoolParams;
 
   if (!GetMapOfAIS().IsBound2 (aName))
   {
@@ -2558,7 +2666,7 @@ static int VDimParam (Draw_Interpretor& theDi, Standard_Integer theArgNum, const
   Handle(AIS_InteractiveObject) anObject = Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2 (aName));
   if (anObject->Type() != AIS_KOI_Dimension)
   {
-    theDi << theArgVec[0] << "error: no dimension with this name.\n";
+    theDi << theArgVec[0] << "error: no dimension with the name: " << aName.ToCString() << ".\n";
     return 1;
   }
 
@@ -2567,7 +2675,7 @@ static int VDimParam (Draw_Interpretor& theDi, Standard_Integer theArgNum, const
 
   if (ParseDimensionParams (theArgNum, theArgVec, 2, anAspect,
                             isCustomPlane, aWorkingPlane,
-                            aRealParams, aStringParams))
+                            aRealParams, aStringParams, aBoolParams, isTextAligned, aTextDir))
   {
     return 1;
   }
@@ -2577,7 +2685,12 @@ static int VDimParam (Draw_Interpretor& theDi, Standard_Integer theArgNum, const
     aDim->SetCustomPlane (aWorkingPlane);
   }
 
-  SetDimensionParams (aDim, aRealParams, aStringParams);
+  if (isTextAligned)
+  {
+    aDim->SetToAlignText (isTextAligned, aTextDir);
+  }
+
+  SetDimensionParams (aDim, aRealParams, aStringParams, aBoolParams);
 
   if (!aDim->IsValid())
   {
diff --git a/tests/bugs/vis/bug26507_1 b/tests/bugs/vis/bug26507_1
new file mode 100644 (file)
index 0000000..0d87269
--- /dev/null
@@ -0,0 +1,26 @@
+puts "================================================================"
+puts "CR26507"
+puts "Visualization - Improved presentations of dimensions"
+puts "================================================================"
+puts ""
+puts "Radius dimension line not continued to the center of a circle"
+
+#set anImage1 $imagedir/${casename}_1.png
+
+vinit Viewer1/View
+vright
+
+vpoint aCircleP1 0 0 60
+vpoint aCircleP2 60 0 0
+vpoint aCircleP3 120 0 60
+vcircle aCircle aCircleP1 aCircleP2 aCircleP3 0
+
+#Check all text and arrow positions
+vdimension aDim1 -radius -shapes aCircle -text 3d -plane zox -label hfit -arrow external -hidedimline
+vdimension aDim2 -radius -shapes aCircle -circleparam 20 -text 3d -plane zox -label vcenter -arrow external -hidedimline
+vdimension aDim3 -radius -shapes aCircle -circleparam 40 -text 3d -plane zox -label vcenter -arrow internal -hidedimline
+vdimension aDim3 -radius -shapes aCircle -circleparam 40 -text 3d -plane zox -label hfit -arrow internal -hidedimline
+vfit
+
+#finalize and dump
+set only_screen 1
diff --git a/tests/bugs/vis/bug26507_2 b/tests/bugs/vis/bug26507_2
new file mode 100644 (file)
index 0000000..fade599
--- /dev/null
@@ -0,0 +1,29 @@
+puts "================================================================"
+puts "CR26507"
+puts "Visualization - Improved presentations of dimensions"
+puts "================================================================"
+puts ""
+puts "User-defined orientation of text label"
+puts "Line segment aligned with text"
+
+#set anImage1 $imagedir/${casename}_1.png
+
+vinit Viewer1/View
+vbottom
+
+vpoint lengthP1 0 0 0
+vpoint lengthP2 50 100 0
+vpoint lengthP3 -50 100 0
+# Text in center - custom aligment does not taken into account
+vdimension dim1 -length -plane xoy -shapes lengthP1 lengthP2 -text 3d -aligntext 1.0 0.0 0.0 -flyout -10
+
+# Text on the right side - it is aligned
+vdimension dim2 -length -plane xoy -shapes lengthP1 lengthP3 -text 3d -aligntext 1.0 0.0 0.0 -segment 15 -label right
+
+# Text on the left side - it is aligned
+vdimension dim3 -length -plane xoy -shapes lengthP2 lengthP3 -text 3d -flyout -10 -aligntext 1.0 0.0 0.0 -segment 10 -label left
+
+
+vfit
+#finalize and dump
+set only_screen 1
\ No newline at end of file
diff --git a/tests/bugs/vis/bug26507_3 b/tests/bugs/vis/bug26507_3
new file mode 100644 (file)
index 0000000..82cde88
--- /dev/null
@@ -0,0 +1,28 @@
+puts "================================================================"
+puts "CR26507"
+puts "Visualization - Improved presentations of dimensions"
+puts "================================================================"
+puts ""
+puts "Multi-line custom text label"
+
+#set anImage1 $imagedir/${casename}_1.png
+
+vinit Viewer1/View
+vbottom
+
+vpoint lengthP1 0 0 0
+vpoint lengthP2 50 100 0
+vpoint lengthP3 -50 100 0
+# Text in center - custom aligment does not taken into account
+vdimension dim1 -length -plane xoy -shapes lengthP1 lengthP2 -valuetext "+2.0\n-3.0\nThickness" -text 2d -aligntext 1.0 0.0 0.0 -segment 15 -flyout -10 -label left firstline
+
+# Text on the right side - it is aligned
+vdimension dim2 -length -plane xoy -shapes lengthP1 lengthP3 -valuetext "+3.0\n-15.0\nThickness" -text 2d -aligntext 1.0 0.0 0.0 -segment 15 -label right
+
+# Text on the left side - it is aligned
+vdimension dim3 -length -plane xoy -shapes lengthP2 lengthP3 -text 2d -valuetext "+3.0\n-15.0" -flyout -10 -aligntext 1.0 0.0 0.0 -segment 10
+
+
+vfit
+#finalize and dump
+set only_screen 1
\ No newline at end of file
diff --git a/tests/bugs/vis/bug26507_4 b/tests/bugs/vis/bug26507_4
new file mode 100644 (file)
index 0000000..aa342c1
--- /dev/null
@@ -0,0 +1,25 @@
+puts "================================================================"
+puts "CR26507"
+puts "Visualization - Improved presentations of dimensions"
+puts "================================================================"
+puts ""
+puts "Radius dimension with multiline custom text"
+
+#set anImage1 $imagedir/${casename}_1.png
+
+vinit Viewer1/View
+vright
+
+vpoint aCircleP1 0 0 60
+vpoint aCircleP2 60 0 0
+vpoint aCircleP3 120 0 60
+vcircle aCircle aCircleP1 aCircleP2 aCircleP3 0
+
+#Check all text and arrow positions
+vdimension aDim1 -radius -shapes aCircle -circleparam 20 -text 3d -label right -arrow external -hidedimline -valuetext "+2.0\n-3.0\nThickness" -aligntext 1.0 0.0 0.0 -segment 15 -label left firstline
+vdimension aDim2 -diameter -shapes aCircle -circleparam 5 -text 3d -label right -arrow external -hidedimline -valuetext "+2.0\n-3.0" -aligntext 1.0 0.0 0.0 -segment 15 -label left firstline
+
+vfit
+
+#finalize and dump
+set only_screen 1