]> OCCT Git - occt-copy.git/commitdiff
0026507: Visualization - Improved presentations of dimensions CR26507_2
authoraba <aba@opencascade.com>
Fri, 11 Sep 2015 12:16:05 +0000 (15:16 +0300)
committeraba <aba@opencascade.com>
Fri, 11 Sep 2015 12:16:05 +0000 (15:16 +0300)
1) Added text alignment according to custom direction
2) Added possibility to add additional segment aligned with text
3) Added support  of alignment of special symbol with multiline 3d text
4) Added possibility to remove main dimension line from presentation of linear dimension

17 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/Font/Font_BRepFont.cxx
src/Font/Font_BRepFont.hxx
src/Prs3d/Prs3d_DimensionTextVerticalPosition.hxx
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]
tests/bugs/vis/bug26507_5 [new file with mode: 0644]
tests/bugs/vis/bug26507_6 [new file with mode: 0644]

index cf746fbf89b51db39f92f09f7aca5f7f61253000..17b2c562d1ea3f42610986bad5f58de48beb5f19 100644 (file)
@@ -597,9 +597,14 @@ 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 +1164,15 @@ 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 +1351,15 @@ 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 69f2d13b59d81d2239a1d37942f739186e30911f..3ffe16eb0dd5c1881a158c274534e97e385e70cb 100644 (file)
@@ -35,10 +35,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);
@@ -105,7 +106,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;
@@ -120,7 +122,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();
@@ -292,7 +294,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 3547b52a001957034a41473a28a584b135cb494f..ccade429e5dc9cc1d926dac08a8ae31c2c42b323 100644 (file)
@@ -59,7 +59,9 @@ public:
 
   //! Construct diameter dimension for the circle.
   //! @param theCircle [in] the circle to measure.
-  Standard_EXPORT AIS_DiameterDimension (const gp_Circ& theCircle);
+  //! @param theParameter [in] the value of parameter for parametric representation of the input circle
+  //! that defines the point where the dimension is to be attached.
+  Standard_EXPORT AIS_DiameterDimension (const gp_Circ& theCircle, const Standard_Real theParameter = 0.0);
 
   //! Construct diameter dimension for the circle and orient it correspondingly
   //! to the passed plane.
@@ -106,7 +108,9 @@ 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);
+  //! @param theParameter [in] the value of parameter for parametric representation of the input circle
+  //! that defines the point where the dimension is to be attached.
+  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 feca35f0a3fe2b970341050f40c82e9544250008..f54d0eb88d707838883ef870a4badf4f4552cdde 100755 (executable)
@@ -25,6 +25,7 @@
 #include <ElCLib.hxx>
 #include <Font_BRepFont.hxx>
 #include <Font_BRepTextBuilder.hxx>
+#include <Font_FTFont.hxx>
 #include <GC_MakeCircle.hxx>
 #include <Geom_Line.hxx>
 #include <GeomAdaptor_Curve.hxx>
@@ -82,8 +83,8 @@ namespace
   static const TCollection_AsciiString    THE_UNDEFINED_UNITS;
 
   // default text margin and resolution
-  static const Standard_Real THE_3D_TEXT_MARGIN    = 0.1;
-  static const unsigned int  THE_2D_TEXT_RESOLUTION = 72;
+  static const Standard_Real THE_3D_TEXT_MARGIN  = 0.1;
+  static const unsigned int  THE_FONT_RESOLUTION = 72;
 
   // default selection priorities
   static const Standard_Integer THE_NEUTRAL_SEL_PRIORITY = 5;
@@ -97,37 +98,104 @@ 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:
+      {
+        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  : 
@@ -141,7 +209,7 @@ const gp_Pln& AIS_Dimension::GetPlane() const
 //function : GetGeometryType
 //purpose  : 
 //=======================================================================
-const Standard_Integer AIS_Dimension::GetGeometryType () const
+const Standard_Integer AIS_Dimension::GetGeometryType() const
 {
   return myGeometryType;
 }
@@ -243,6 +311,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  :
@@ -272,73 +409,62 @@ Standard_Real AIS_Dimension::ValueToDisplayUnits() const
                              GetDisplayUnits().ToCString());
 }
 
-//=======================================================================
-//function : GetValueString
-//purpose  : 
-//=======================================================================
-TCollection_ExtendedString AIS_Dimension::GetValueString (Standard_Real& theWidth) const
+// =======================================================================
+// function : getLabelSizes
+// 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();
+  Handle(Prs3d_DimensionAspect) anAspect    = myDrawer->DimensionAspect();
+  Handle(Prs3d_TextAspect)      aTextAspect = myDrawer->DimensionAspect()->TextAspect();
+  Standard_Real                 aFontHeight = aTextAspect->Height();
 
-  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());
-  }
+  Quantity_Color aColor;
+  Standard_CString aFontName;
+  Standard_Real anExpFactor, aSpace;
+  aTextAspect->Aspect()->Values (aColor, aFontName, anExpFactor, aSpace);
 
-  switch (myDisplaySpecialSymbol)
+  NCollection_String aText ((Standard_Utf16Char*) theLabel.ToExtString());
+  NCollection_String aSymbol;
+  if (DisplaySpecialSymbol() != AIS_DSS_No)
   {
-    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;
+    aSymbol.FromUnicode ((Standard_Utf16Char*) TCollection_ExtendedString (mySpecialSymbol).ToExtString());
   }
 
-  // Get text style parameters
-  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();
-
-  NCollection_Utf8String anUTFString = (Standard_Utf16Char* )aValueStr.ToExtString();
-
-  theWidth = 0.0;
+  Font_FTFont::Rect aTextBox;
+  Font_FTFont::Rect aSymbolBox;
 
-  if (myDrawer->DimensionAspect()->IsText3d())
+  if (!anAspect->IsText3d())
   {
-    // text width produced by BRepFont
-    Font_BRepFont aFont (aFontName, aFontAspect, aFontHeight);
-
-    for (NCollection_Utf8Iter anIter = anUTFString.Iterator(); *anIter != 0; )
+    Font_FTFont aFont;
+    aFont.Init (aFontName,
+                aTextAspect->Aspect()->GetTextFontAspect(),
+                static_cast<Standard_Integer> (aFontHeight),
+                THE_FONT_RESOLUTION);
+    aTextBox = aFont.BoundingBox (aText, Graphic3d_HTA_LEFT, Graphic3d_VTA_TOP);
+    if (!aSymbol.IsEmpty())
     {
-      Standard_Utf32Char aCurrChar = *anIter;
-      Standard_Utf32Char aNextChar = *(++anIter);
-      theWidth += aFont.AdvanceX (aCurrChar, aNextChar);
+      aSymbolBox = aFont.BoundingBox (aSymbol, Graphic3d_HTA_LEFT, Graphic3d_VTA_TOP);
     }
   }
   else
   {
-    // 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; )
+    Font_BRepFont aFont (aFontName, aTextAspect->Aspect()->GetTextFontAspect(), aFontHeight);
+    aTextBox = aFont.BoundingBox (aText);
+    if (!aSymbol.IsEmpty())
     {
-      Standard_Utf32Char aCurrChar = *anIter;
-      Standard_Utf32Char aNextChar = *(++anIter);
-      theWidth += (Standard_Real) aFont->AdvanceX (aCurrChar, aNextChar);
+      aSymbolBox = aFont.BoundingBox (aSymbol);
     }
   }
 
-  return aValueStr;
+  theWidth        = aTextBox.Width();
+  theHeight       = aTextBox.Height();
+  theSymbolWidth  = aSymbolBox.Width();
+  theSymbolHeight = aSymbolBox.Height();
 }
 
 //=======================================================================
@@ -409,97 +535,188 @@ 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();
+
+  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_Real aSymbolHOffset = 0.0;
+  Standard_Real aShapeHOffset = 0.0;
+  Standard_Real aShapeVOffset = 0.0;
+  Standard_Real aFlippingVOffset = 0.0;
+  Standard_Integer aVLabelPos = theLabelPosition & LabelPosition_VMask;
+  Standard_Integer aHLabelPos = theLabelPosition & LabelPosition_HMask;
+
   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();
 
+    const Standard_Real aHeightOfLine = aFont.LineSpacing();
     Font_BRepTextBuilder aBuilder;
     TopoDS_Shape aTextShape = aBuilder.Perform (aFont, 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 = aBuilder.Perform (aFont, anUTFSymbol);
     }
 
-    // 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;
+    // Formating text position in XOY plane
     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 + aSymbolWidth) / 2.0 + aMarginSize; break;
+      case LabelPosition_Left    : aCenterHOffset = -(aWidth + aSymbolWidth) / 2.0 - aMarginSize; break;
     }
+
+    // Correct text direction
+    gp_Dir aTextDir = (aHLabelPos == LabelPosition_Left ? -theTextDir : theTextDir);
+
+    // Transform text to myWorkingPlane coordinate system
+    gp_Ax3 aTextCoordSystem (theTextPos, GetPlane().Axis().Direction(), aTextDir);
+    gp_Trsf aTextPlaneTrsf;
+    aTextPlaneTrsf.SetTransformation (aTextCoordSystem, gp_Ax3 (gp::XOY()));
+
+    // ALIGNMENT: Vertical
+
     switch (aVLabelPos)
     {
-      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_FirstLine:
+      {
+        if (myTypeOfLabel == TOL_Text && aHeight > aHeightOfLine)
+        {
+          aCenterVOffset = aSymbolHeight - aHeight / 2.0 - aMarginSize;
+          aSymbolVOffset = aHeight / 2.0 - aSymbolHeight / 2.0;
+          aFlippingVOffset = aHeight / 2.0 - aSymbolHeight + aMarginSize;
+        }
+        break;
+      }
+      case LabelPosition_LastLine:
+      {
+        if (myTypeOfLabel == TOL_Text && aHeight > aHeightOfLine)
+        {
+          aCenterVOffset = aHeight / 2.0 + aMarginSize - aSymbolHeight;
+          aSymbolVOffset = aHeight / 2.0 - aHeightOfLine / 2.0 - aMarginSize;
+          aFlippingVOffset = -aHeight / 2.0 + aSymbolHeight - aMarginSize;
+
+        }
+        break;
+      }
+      case LabelPosition_VCenter:
+      {
+        if (myTypeOfLabel == TOL_Text && aHeight > aHeightOfLine)
+        {
+          aSymbolVOffset = aCenterVOffset + (aHeight - aHeightOfLine) / 2.0 - aMarginSize;
+        }
+      }
+      break;
+      case LabelPosition_Above:
+      {
+        aCenterVOffset = aHeight / 2.0 + aMarginSize;
+        if (myTypeOfLabel == TOL_Text)
+        {
+          aSymbolVOffset = aCenterVOffset / 2.0;
+        }
+        break;
+      }
+      case LabelPosition_Below:
+      {
+        aCenterVOffset = - aHeight / 2.0 - aMarginSize;
+        if (myTypeOfLabel == TOL_Text)
+        {
+          aSymbolVOffset = aCenterVOffset / 2.0;
+        }
+        break;
+      }
     }
 
-    // compute shape offset transformation
-    Standard_Real aShapeHOffset = aCenterHOffset - aTextWidth / 2.0;
-    Standard_Real aShapeVOffset = aCenterVOffset - aTextHeight / 2.0;
+    // ALIGNMENT: Horisontal
 
-    // center shape in its bounding box (suppress border spacing added by FT_Font)
+    // Center shape in its bounding box (suppress border spacing added by FT_Font)
     Bnd_Box aShapeBnd;
     BRepBndLib::AddClose (aTextShape, aShapeBnd);
-
     Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
     aShapeBnd.Get (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
+    Standard_Real aXalign = aWidth  * 0.5 - (aXmax + aXmin) * 0.5;
+    Standard_Real aYalign = aHeight * 0.5 - (aYmax + aYmin) * 0.5;
 
-    Standard_Real aXalign = aTextWidth  * 0.5 - (aXmax + aXmin) * 0.5;
-    Standard_Real aYalign = aTextHeight * 0.5 - (aYmax + aYmin) * 0.5;
-    aShapeHOffset += aXalign;
-    aShapeVOffset += aYalign;
+    // Compute where to place main part of label (without special symbol) relative to the input text position
+    aShapeHOffset = aCenterHOffset - aWidth / 2.0 + aXalign;
+    aShapeVOffset += aCenterVOffset - aHeight / 2.0 + aYalign;
 
     gp_Trsf anOffsetTrsf;
+    if (!aSymbolShape.IsNull())
+    {
+      Bnd_Box aSymbolBnd;
+      BRepBndLib::AddClose (aSymbolShape, aSymbolBnd);
+      aSymbolBnd.Get (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
+      aXalign = aSymbolWidth * 0.5 - (aXmax + aXmin) * 0.5;
+
+      aSymbolHOffset = aCenterHOffset + aXalign;
+      aSymbolVOffset += aYalign - aHeight / 2.0;
+
+      switch (myDisplaySpecialSymbol)
+      {
+        case AIS_DSS_After:
+        {
+          aSymbolHOffset += aWidth * 0.5;
+          aShapeHOffset -= aSymbolWidth * 0.5;
+          break;
+        }
+        case AIS_DSS_Before:
+        {
+          aSymbolHOffset -= (aWidth + aSymbolWidth) * 0.5;
+          aShapeHOffset += aSymbolWidth * 0.5;
+          break;
+        }
+        case AIS_DSS_No:
+        default:
+        {
+          break;
+        }
+      }
+
+      // Modify transformation for a special symbol relative! to the main text
+      anOffsetTrsf.SetTranslation (gp::Origin(), gp_Pnt (aSymbolHOffset, aSymbolVOffset, 0.0));
+      aSymbolShape.Move (anOffsetTrsf);
+      aSymbolShape.Move (aTextPlaneTrsf);
+    }
+
     anOffsetTrsf.SetTranslation (gp::Origin(), gp_Pnt (aShapeHOffset, aShapeVOffset, 0.0));
     aTextShape.Move (anOffsetTrsf);
-
-    // transform text to myWorkingPlane coordinate system
-    gp_Ax3 aTextCoordSystem (theTextPos, GetPlane().Axis().Direction(), aTextDir);
-    gp_Trsf aTextPlaneTrsf;
-    aTextPlaneTrsf.SetTransformation (aTextCoordSystem, gp_Ax3 (gp::XOY()));
     aTextShape.Move (aTextPlaneTrsf);
 
-    // set text flipping anchors
-    gp_Trsf aCenterOffsetTrsf;
-    gp_Pnt aCenterOffset (aCenterHOffset, aCenterVOffset, 0.0);
-    aCenterOffsetTrsf.SetTranslation (gp::Origin(), aCenterOffset);
-
-    gp_Pnt aCenterOfLabel (gp::Origin());
-    aCenterOfLabel.Transform (aCenterOffsetTrsf);
-    aCenterOfLabel.Transform (aTextPlaneTrsf);
+    // Compute anchor point for flipping options
 
-    gp_Ax2 aFlippingAxes (aCenterOfLabel, GetPlane().Axis().Direction(), aTextDir);
+    gp_Trsf aFlippingTrsf;
+    aFlippingTrsf.SetTranslation (gp::Origin(), gp_Pnt(aCenterHOffset, aCenterVOffset + aFlippingVOffset, 0.0));
+    gp_Pnt aFlippingPoint = gp::Origin();
+    aFlippingPoint.Transform (aFlippingTrsf);
+    aFlippingPoint.Transform (aTextPlaneTrsf);
+    gp_Ax2 aFlippingAxes (aFlippingPoint, 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
@@ -511,33 +728,92 @@ void AIS_Dimension::DrawText (const Handle(Prs3d_Presentation)& thePresentation,
       myDrawer->ShadingAspect()->Aspect()->SetBackInteriorColor (aColor);
       myDrawer->ShadingAspect()->SetMaterial (aShadeMat);
 
-      // 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
+
       StdPrs_WFShape::Add (thePresentation, aTextShape, myDrawer);
+      StdPrs_WFShape::Add (thePresentation, aSymbolShape, myDrawer);
     }
+
     Prs3d_Root::CurrentGroup (thePresentation)->SetFlippingOptions (Standard_False, gp_Ax2());
 
+    gp_Trsf aCenterOffsetTrsf;
+    gp_Pnt aCenterOfLabel (gp::Origin());
+    gp_Pnt aCenterOffset (aCenterHOffset, aCenterVOffset, 0.0);
+    aCenterOffsetTrsf.SetTranslation (gp::Origin(), aCenterOffset);
+    aCenterOfLabel.Transform (aCenterOffsetTrsf);
+    aCenterOfLabel.Transform (aTextPlaneTrsf);
+
+
     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;
 
     return;
   }
 
-  // generate primitives for 2D text
+  // 2D text
+
   myDrawer->DimensionAspect()->TextAspect()->Aspect()->SetDisplayType (Aspect_TODT_DIMENSION);
 
-  Prs3d_Text::Draw (thePresentation,
-                    myDrawer->DimensionAspect()->TextAspect(),
-                    theText,
-                    theTextPos);
+  gp_Pnt aTextPos = theTextPos;
+
+  Font_FTFont aFont;
+  aFont.Init (aFontName,
+              anAspectText3d->GetTextFontAspect(),
+              static_cast<Standard_Integer>(aFontHeight),
+              THE_FONT_RESOLUTION);
+  const Standard_Real aHeightOfLine = aFont.LineSpacing();
+
+  switch (aVLabelPos)
+  {
+    case LabelPosition_FirstLine: break;
+    case LabelPosition_LastLine : break;
+    case LabelPosition_VCenter  : break;
+    case LabelPosition_Above:
+    {
+      if (myTypeOfLabel == TOL_Text && aHeight > aHeightOfLine)
+      {
+        aSymbolVOffset = -aHeight / 2;
+      }
+      break;
+    }
+    case LabelPosition_Below:
+    {
+      if (myTypeOfLabel == TOL_Text && aHeight > aHeightOfLine)
+      {
+        aSymbolVOffset = aHeight / 2;
+      }
+      break;
+    }
+  }
+
+  // NOTE: for 2d text that is always parallel to view plane,
+  //       multiline text alignment with special symbol does not applied.
+  TCollection_ExtendedString aText = theText;
+  switch (myDisplaySpecialSymbol)
+  {
+    case AIS_DSS_Before:
+    {
+      aText.Insert (1, mySpecialSymbol);
+      break;
+    }
+    case AIS_DSS_After:
+    {
+      aText += mySpecialSymbol;
+      break;
+    }
+    case AIS_DSS_No: break;
+  }
+
+  
+  Prs3d_Text::Draw (thePresentation, aTextAspect, aText, aTextPos);
 
   mySelectionGeom.TextPos    = theTextPos;
   mySelectionGeom.TextDir    = theTextDir;
@@ -562,11 +838,33 @@ 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;
+
+  // Compute graphical primitives and sensitives for extension line
+  gp_Pnt anExtStart = theExtensionStart;
+  gp_Pnt   anExtEnd = !hasLabel || !(theLabelPosition & LabelPosition_Above || theLabelPosition & LabelPosition_Below)
+    ? 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;
+
+    if (hasLabel && myLeaderSegmentLength > 0 && myIsTextAligned)
+    {
+      gp_Lin aSegmentLine (anExtEnd, aTextDir);
+      Standard_Real aSegmentLength = !(theLabelPosition & LabelPosition_Above || theLabelPosition & LabelPosition_Below)
+        ? myLeaderSegmentLength : theLabelWidth + myLeaderSegmentLength;
+      aSegmentPoint = ElCLib::Value (aSegmentLength, aSegmentLine);
+      aTextPos = !(theLabelPosition & LabelPosition_Above || theLabelPosition & LabelPosition_Below)
+        ? aSegmentPoint : ElCLib::Value (myLeaderSegmentLength, aSegmentLine);
+    }
 
     DrawText (thePresentation,
               aTextPos,
@@ -580,25 +878,30 @@ 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);
 
-  // add selection primitives
+  // Add selection primitives
   SelectionGeometry::Curve& aSensitiveCurve = mySelectionGeom.NewCurve();
   aSensitiveCurve.Append (anExtStart);
   aSensitiveCurve.Append (anExtEnd);
 
+  // Draw segment
+  if (hasLabel && myLeaderSegmentLength > 0 && myIsTextAligned)
+  {
+    anExtPrimitive->AddVertex (anExtEnd);
+    anExtPrimitive->AddVertex (aSegmentPoint);
+
+    // Add selection primitives
+    SelectionGeometry::Curve& aSensitiveCurve = mySelectionGeom.NewCurve();
+    aSensitiveCurve.Append (anExtEnd);
+    aSensitiveCurve.Append (aSegmentPoint);
+  }
+
+
+
   if (!myDrawer->DimensionAspect()->IsText3d() && theMode == ComputeMode_All)
   {
     Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_True);
@@ -620,7 +923,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()))
@@ -633,9 +937,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())
@@ -660,7 +969,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);
 
@@ -718,7 +1027,11 @@ void AIS_Dimension::DrawLinearDimension (const Handle(Prs3d_Presentation)& thePr
 
       gp_Pnt aTextPos = IsTextPositionCustom() ? myFixedTextPosition
                                               : (aCenterLineBegin.XYZ() + aCenterLineEnd.XYZ()) * 0.5;
-      gp_Dir aTextDir = aDimensionLine.Direction();
+
+      // Choose a text direction
+      gp_Dir aTextDir = myIsTextAligned
+        ? myTextDir
+        : aDimensionLine.Direction();
 
       // add text primitives
       if (theMode == ComputeMode_All || theMode == ComputeMode_Text)
@@ -726,15 +1039,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);
 
@@ -771,11 +1087,14 @@ void AIS_Dimension::DrawLinearDimension (const Handle(Prs3d_Presentation)& thePr
 
         // set text label justification
         Graphic3d_VerticalTextAlignment aTextJustificaton = Graphic3d_VTA_BOTTOM;
+
         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);
 
@@ -836,7 +1155,7 @@ void AIS_Dimension::DrawLinearDimension (const Handle(Prs3d_Presentation)& thePr
                        ? aFirstArrowEnd
                        : aFirstArrowBegin,
                      aFirstExtensionDir,
-                     aLabelString,
+                     aLabel,
                      aLabelWidth,
                      theMode,
                      aLabelPosition);
@@ -844,27 +1163,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 || abs(myFlyout) > Precision::Confusion() )
+        {
+          // 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 || (!isArrowsExternal && !theToDrawDimensionLine)))
         {
           DrawArrow (thePresentation, aSecondArrowBegin, aSecondArrowDir);
         }
@@ -877,9 +1199,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;
@@ -899,32 +1224,35 @@ 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 || abs(myFlyout) > Precision::Confusion())
+        {
+          // 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);
 
         DrawArrow (thePresentation, aSecondArrowBegin, aSecondArrowDir);
-        if (!theIsOneSide)
+        if (!theIsOneSide && (theToDrawDimensionLine || (!theToDrawDimensionLine && !isArrowsExternal)))
         {
           DrawArrow (thePresentation, aFirstArrowBegin, aFirstArrowDir);
         }
@@ -937,9 +1265,12 @@ void AIS_Dimension::DrawLinearDimension (const Handle(Prs3d_Presentation)& thePr
         // add extension lines for external arrows
         Prs3d_Root::NewGroup (thePresentation);
 
-        DrawExtension (thePresentation, aDimensionAspect->ArrowTailSize(),
-                       aFirstArrowEnd, aFirstExtensionDir,
-                       THE_EMPTY_LABEL, 0.0, theMode, LabelPosition_None);
+        if (theToDrawDimensionLine)
+        {
+          DrawExtension (thePresentation, aDimensionAspect->ArrowTailSize(),
+                         aFirstArrowEnd, aFirstExtensionDir,
+                         THE_EMPTY_LABEL, 0.0, theMode, LabelPosition_None);
+        }
       }
 
       break;
@@ -1583,8 +1914,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())
@@ -1618,7 +1956,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:
     {
@@ -1635,7 +1973,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 12de7352476b0269057162e8a6ed5d876e1dd802..1ebc2cfa7db586628b7c94ebaca9b3aa4cf8ad3a 100755 (executable)
@@ -196,10 +196,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:
@@ -225,10 +227,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,
@@ -236,6 +235,14 @@ public:
   //! @param theValue [in] the user-defined value to display.
   Standard_EXPORT void SetCustomValue (const Standard_Real theValue);
 
+  //! Sets multiline 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.
@@ -376,6 +383,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, AIS_InteractiveObject)
@@ -384,10 +411,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.
@@ -435,11 +461,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.
@@ -651,29 +681,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 b51601fb077b311d2afc339007f567d335399691..7bd1fb0d77efd629e1dbaad5ed677ac6c601269d 100644 (file)
@@ -31,15 +31,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  : 
@@ -48,10 +58,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);
 }
 
 //=======================================================================
@@ -61,22 +69,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)
@@ -128,6 +135,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  : 
@@ -228,7 +262,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 b484a0988a4a00b1db7b14fb561202c200e18458..b01a4cdf6ffae8b881f41fc81e01eb1f86a72844 100644 (file)
@@ -39,13 +39,21 @@ 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 parameters
+  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);
+  //! @param theParameter [in] the value of parameter for parametric representation of the input circle
+  //! that defines the point where the dimension is to be attached.
+  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.
@@ -62,22 +70,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:
 
@@ -85,7 +84,9 @@ 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);
+  //! @param theParameter [in] the value of parameter for parametric representation of the input circle
+  //! that defines the point where the dimension is to be attached.
+  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.
@@ -122,16 +123,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 128d2b8f3503d78cc0451a70883792de2336e850..30362d6340c55c3d0415347e3a8b1d16896b7ef7 100755 (executable)
@@ -464,3 +464,38 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
   myCache.Bind (theChar, theShape);
   return !theShape.IsNull();
 }
+
+
+// =======================================================================
+// function : BoundingBox
+// purpose  :
+// =======================================================================
+Font_FTFont::Rect Font_BRepFont::BoundingBox (const NCollection_String& theString,
+                                              const Graphic3d_HorizontalTextAlignment theHAlign,
+                                              const Graphic3d_VerticalTextAlignment   theVAlign)
+{
+  Rect aBox;
+  aBox.Left   = 0.0f;
+  aBox.Right  = 0.0f;
+  aBox.Bottom = 0.0f;
+  aBox.Top    = static_cast<float> (Ascender());
+
+  // Initialize text formatter
+  Font_TextFormatter aFormatter;
+  aFormatter.Reset();
+  aFormatter.SetupAlignment (theHAlign, theVAlign);
+  aFormatter.Append (theString, *(reinterpret_cast<Font_FTFont*> (this)));
+  aFormatter.Format();
+
+  // Get bounding box
+  aFormatter.BndBox (aBox);
+
+  // Apply BRepFont scale to box limits
+  Standard_Real aScaleUnits = Scale();
+  aBox.Left = aBox.Left * aScaleUnits;
+  aBox.Top = aBox.Top * aScaleUnits;
+  aBox.Right = aBox.Right * aScaleUnits;
+  aBox.Bottom = aBox.Bottom * aScaleUnits;
+
+  return aBox;
+}
\ No newline at end of file
index 28eac4ca5fe2464098c143e2fc8234ec47d8b8b2..4bbc180d5fd6ecbd8094ef30f3459385fe3aacd2 100755 (executable)
@@ -96,6 +96,12 @@ public:
   //! Notice that altering this flag clears currently accumulated cache!
   Standard_EXPORT void SetCompositeCurveMode (const Standard_Boolean theToConcatenate);
 
+  //! Compute bounding rectangle of resultant BRep text shape from input string
+  //! @return bounding rectangle
+  Standard_EXPORT Font_FTFont::Rect BoundingBox (const NCollection_String& theString,
+                                                 const Graphic3d_HorizontalTextAlignment theHAlign = Graphic3d_HTA_LEFT,
+                                                 const Graphic3d_VerticalTextAlignment   theVAlign = Graphic3d_VTA_BOTTOM);
+
 public:
 
   //! @return vertical distance from the horizontal baseline to the highest character coordinate.
@@ -164,6 +170,8 @@ public:
     return myMutex;
   }
 
+
+
 protected:
 
   //! Render single glyph as TopoDS_Shape. This method does not lock the mutex.
index c51f89c7a139461c239a8e438204c56ef7c5c2cb..f7fdface8fe9195c3a1769138115ea0947b71fca 100644 (file)
@@ -25,7 +25,9 @@
 enum Prs3d_DimensionTextVerticalPosition
 {
 Prs3d_DTVP_Above,
+Prs3d_DTVP_FirstLine,
 Prs3d_DTVP_Below,
+Prs3d_DTVP_LastLine,
 Prs3d_DTVP_Center
 };
 
index 8569d07233915e9eed725c16b9d4b7f9a51fd8fe..129f59ef2681e21ac80061f07c92d57c72ed144e 100644 (file)
@@ -38,6 +38,7 @@
 #include <Draw_Appli.hxx>
 #include <Draw_Window.hxx>
 #include <DBRep.hxx>
+#include <ElCLib.hxx>
 #include <ElSLib.hxx>
 #include <Font_FontMgr.hxx>
 #include <GC_MakePlane.hxx>
@@ -169,16 +170,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.
@@ -191,6 +197,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();
@@ -209,7 +217,7 @@ static int ParseDimensionParams (Standard_Integer  theArgNum,
       continue;
     }
 
-    // Boolean flags
+    // BOOLEAN flags
     if (aParam.IsEqual ("-showunits"))
     {
       theAspect->MakeUnitsDisplayed (Standard_True);
@@ -221,14 +229,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"))
     {
@@ -316,13 +335,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";
@@ -345,7 +366,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()));
@@ -399,6 +420,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]);
@@ -413,13 +448,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"))
     {
@@ -449,7 +514,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"))
   {
@@ -460,6 +526,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"))
   {
@@ -470,6 +540,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"));
+  }
 }
 
 //=======================================================================
@@ -494,9 +574,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();
@@ -526,7 +609,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;
   }
@@ -667,7 +750,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
         {
@@ -696,7 +787,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
         {
@@ -724,6 +824,11 @@ static int VDimBuilder (Draw_Interpretor& /*theDi*/,
     }
   }
 
+  if (isTextAligned)
+  {
+    aDim->SetToAlignText (isTextAligned, aTextDir);
+  }
+
   // Check dimension geometry
   if (!aDim->IsValid())
   {
@@ -734,7 +839,7 @@ static int VDimBuilder (Draw_Interpretor& /*theDi*/,
 
   aDim->SetDimensionAspect (anAspect);
 
-  SetDimensionParams (aDim, aRealParams, aStringParams);
+  SetDimensionParams (aDim, aRealParams, aStringParams, aBoolParams);
 
   VDisplayAISObject (aName,aDim);
 
@@ -2546,10 +2651,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))
   {
@@ -2560,7 +2668,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;
   }
 
@@ -2569,7 +2677,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;
   }
@@ -2579,7 +2687,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())
   {
@@ -2774,16 +2887,20 @@ void ViewerTest::RelationCommands(Draw_Interpretor& theCommands)
       "vdimension name {-angle|-length|-radius|-diameter} -shapes shape1 [shape2 [shape3]]\n"
       "[-text 3d|2d wf|sh|wireframe|shading IntegerSize]\n"
       "[-font FontName]\n"
-      "[-label left|right|hcenter|hfit top|bottom|vcenter|vfit]\n"
+      "[-label left|right|hcenter|hfit above|below|vcenter|vfit]\n"
       "[-arrow external|internal|fit]\n"
       "[{-arrowlength|-arlen} RealArrowLength]\n"
       "[{-arrowangle|-arangle} ArrowAngle(degrees)]\n"
       "[-plane xoy|yoz|zox]\n"
       "[-flyout FloatValue -extension FloatValue]\n"
-      "[-value CustomNumberValue]\n"
+      "[-value CustomNumberValue] OR [-valuetext CustomMultilineLabel]\n"
       "[-dispunits DisplayUnitsString]\n"
       "[-modelunits ModelUnitsString]\n"
       "[-showunits | -hideunits]\n"
+      "[-drawdimline] <- dimension line is displayed by default\n"
+      "[-hidedimline]/n"
+      "[-aligntext DirX DirY DirZ]\n"
+      "[-segment Length\n"
       " -Builds angle, length, radius and diameter dimensions.\n"
       " -See also: vdimparam, vmovedim.\n",
       __FILE__,VDimBuilder,group);
@@ -2802,6 +2919,11 @@ void ViewerTest::RelationCommands(Draw_Interpretor& theCommands)
     "[-dispunits DisplayUnitsString]\n"
     "[-modelunits ModelUnitsString]\n"
     "[-showunits | -hideunits]\n"
+    "[-drawdimline] <- dimension line is displayed by default\n"
+    "[-hidedimline]/n"
+    "[-aligntext DirX DirY DirZ]\n"
+    "[-segment Length\n"
+    " -Builds angle, length, radius and diameter dimensions.\n"
     " -Sets parameters for angle, length, radius and diameter dimensions.\n"
     " -See also: vmovedim, vdimension.\n",
     __FILE__,VDimParam,group);
diff --git a/tests/bugs/vis/bug26507_1 b/tests/bugs/vis/bug26507_1
new file mode 100644 (file)
index 0000000..10d50d5
--- /dev/null
@@ -0,0 +1,28 @@
+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 right -arrow external -hidedimline
+vdimension aDim3 -radius -shapes aCircle -circleparam 40 -text 3d -plane zox -label hfit -arrow internal -hidedimline
+
+vdimension aDim4 -radius -shapes aCircle -circleparam 60 -text 2d -flyout -30 -plane zox -label right -arrow external -hidedimline
+vdimparam aDim4 -text 20
+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..d3e464b
--- /dev/null
@@ -0,0 +1,34 @@
+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
+vpoint lengthP4 0 200 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 0 -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 5 -label left
+
+# Text on the left side - it is aligned
+vdimension dim4 -length -plane xoy -shapes lengthP2 lengthP4 -text 3d -flyout -10 -aligntext 1.0 0.0 0.0 -segment 25 -label right
+
+# Text on the left side - it is aligned
+vdimension dim5 -length -plane xoy -shapes lengthP4 lengthP3 -text 3d -flyout -10 -aligntext 1.0 0.0 0.0 -label left above -segment 10 
+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..bc66fbf
--- /dev/null
@@ -0,0 +1,32 @@
+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 10 -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 left -arrow external -hidedimline -valuetext "+4.0\n -6.0" -aligntext 1.0 0.0 0.0 -segment 15 -label left firstline
+vdimension aDim3 -radius -shapes aCircle -circleparam 20 -text 3d -plane zox -label right -arrow external -hidedimline
+vdimension aDim4 -radius -shapes aCircle -circleparam 30 -text 3d -plane zox -label vcenter -arrow internal -hidedimline
+
+vdimension aDim5 -radius -shapes aCircle -circleparam 40 -text 2d -label right -arrow external -hidedimline -valuetext "+2.0\n -3.0\nThickness" -aligntext 1.0 0.0 0.0 -segment 15 -label left firstline
+
+vdimparam aDim1 -text 6
+vdimparam aDim3 -text 6
+
+vfit
+
+#finalize and dump
+set only_screen 1
diff --git a/tests/bugs/vis/bug26507_5 b/tests/bugs/vis/bug26507_5
new file mode 100644 (file)
index 0000000..ab823f3
--- /dev/null
@@ -0,0 +1,34 @@
+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 100 0 0
+vpoint lengthP3 100 100 0
+vpoint lengthP4 0 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 0 -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 5 -label left
+
+# Text on the left side - it is aligned
+vdimension dim4 -length -plane xoy -shapes lengthP4 lengthP1 -text 3d -valuetext "0.6\n1.58\nTHICKNESS" -flyout -10 -aligntext 1.0 0.0 0.0 -segment 10 -label right vcenter
+
+# Text on the left side - it is aligned
+vdimension dim5 -length -plane xoy -shapes lengthP4 lengthP3 -text 3d -flyout -10 -aligntext 1.0 0.0 0.0 -label left above -segment 10 
+vfit
+#finalize and dump
+set only_screen 1
\ No newline at end of file
diff --git a/tests/bugs/vis/bug26507_6 b/tests/bugs/vis/bug26507_6
new file mode 100644 (file)
index 0000000..ae0404b
--- /dev/null
@@ -0,0 +1,27 @@
+puts "================================================================"
+puts "CR26507"
+puts "Visualization - Improved presentations of dimensions"
+puts "================================================================"
+puts ""
+puts "Radius dimension vertical alignment with multiline custom text"
+
+#set anImage1 $imagedir/${casename}_1.png
+
+vinit Viewer1/View
+vright
+
+vpoint aCircleP1 0 0 100
+vpoint aCircleP2 100 0 0
+vpoint aCircleP3 200 0 100
+vcircle aCircle aCircleP1 aCircleP2 aCircleP3 0
+
+#Check all text and arrow positions
+vdimension aDim1 -radius -shapes aCircle -circleparam 10 -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 -radius -shapes aCircle -circleparam 20 -text 3d -label right -arrow external -hidedimline -valuetext "Thickness\n+3.0\n -4.0" -aligntext 1.0 0.0 0.0 -segment 15 -label left lastline
+vdimension aDim3 -radius -shapes aCircle -circleparam 30 -text 3d -label right -arrow external -hidedimline -valuetext "+4.0\n -5.0\nThickness" -aligntext 1.0 0.0 0.0 -flyout -70 -segment 15 -label left vcenter
+vdimension aDim4 -radius -shapes aCircle -circleparam 15 -text 3d -label right -arrow external -hidedimline -valuetext "+0.5\n -0.5" -aligntext 1.0 0.0 0.0 -segment 15 -label left lastline
+
+vfit
+
+#finalize and dump
+set only_screen 1