```-//!  Linear dimensions:
-//!
-//!  extension
-//!   line                                     arrow
-//!       -->|------- main dimension line -------|<--
-//!          |                                   |
-//!          |flyout                       flyout|
-//!          |                                   |
-//!          +-----------------------------------+
-//! attachment                                attachment
-//!  point                                       point
-//!
-//!  Angular dimensions:
-//!
-//!                  extension
-//!                     line
-//!                        -->|+++++
-//!                     arrow |     +++
-//!                           |        90(deg) - main dimension line
-//!                    flyout |         +++
-//!                           |           +
-//!                           o---flyout---
-//!                         center         ^
-//!                         point          | extension
-//!                                          line
-//! ```
```+//!  Linear dimensions:
+//!
+//!  extension
+//!   line                                     arrow
+//!       -->|------- main dimension line -------|<--
+//!          |                                   |
+//!          |flyout                       flyout|
+//!          |                                   |
+//!          +-----------------------------------+
+//! attachment                                attachment
+//!  point                                       point
+//!
+//!  Angular dimensions:
+//!
+//!                  extension
+//!                     line
+//!                        -->|+++++
+//!                     arrow |     +++
+//!                           |        90(deg) - main dimension line
+//!                    flyout |         +++
+//!                           |           +
+//!                           o---flyout---
+//!                         center         ^
+//!                         point          | extension
+//!                                          line
+//! ```
+//! +//! Being a 2D drawings, the dimensions are created on imaginary plane, called "dimension plane", +//! which can be thought of as reference system of axes (X,Y,N) for constructing the presentation. +//! +//! The role of axes of the dimension plane is to guide you through the encapsualted automations +//! of presentation building to help you understand how is the presentation will look and how it +//! will be oriented in model space during construction. +//! +//! Orientation of dimension line in model space relatively to the base shapes is defined +//! with the flyouts. Flyouts specify length of flyout lines and their orientation relatively +//! to the attachment points on the working plane. +//! For linear dimensions: +//! Direction of flyouts is specified with direction of main dimension line +//! (vector from the first attachment to the second attachment) and the normal of the dimension plane. +//! Positive direction of flyouts is defined by vector multiplication: AttachVector * PlaneNormal. +//! For angular dimensions: +//! Flyouts are defined by vectors from the center point to the attachment points. +//! These vectors directions are supposed to be the positive directions of flyouts. +//! Negative flyouts directions means that these vectors should be reversed +//! (and dimension will be built out of the angle constructed with center and two attach points). +//! +//! The dimension plane can be constructed automatically by application (where possible, +//! it depends on the measured geometry). +//! It can be also set by user. However, if the user-defined plane does not fit the +//! geometry of the dimension (attach points do not belong to it), the dimension could not +//! be built. +//! If it is not possible to compute automatic plane (for example, in case of length between +//! two points) the user is supposed to specify the custom plane. +//! +//! Since the dimensions feature automated construction procedures from an arbitrary shapes, +//! the interfaces to check the validness are also implemented. Once the measured geometry is +//! specified, the one can inquire the validness status by calling "IsValid()" method. If the result +//! is TRUE, then all of public parameters should be pre-computed and ready. The presentation +//! should be also computable. Otherwise, the parameters may return invalid values. In this case, +//! the presentation will not be computed and displayed. +//! +//! The dimension support two local selection modes: main dimension line selection and text label +//! selection. These modes can be used to develop interactive modification of dimension presentations. +//! The component highlighting in these selection modes is provided by PrsDim_DimensionOwner class. +//! Please note that selection is unavailable until the presentation is computed. +//! +//! The specific drawing attributes are controlled through Prs3d_DimensionAspect. The one can change +//! color, arrows, text and arrow style and specify positioning of value label by setting corresponding +//! values to the aspect. +//! +//! Such set of parameters that consists of: +//! - flyout size and direction, +//! - user-defined dimension plane, +//! - horizontal and vertical text alignment +//! can be uniquely replaced with text position in 3d space. Therefore, there are methods to convert +//! this set of parameters to the text position and vice versa: +//! +//! - If the fixed text position is defined by user, called SetTextPosition (theTextPos) method converts +//! this 3d point to the set of parameters including adjusting of the dimension plane (this plane will be +//! automatic plane, NOT user-defined one). +//! If the fixed text position is set, the flag myIsFixedTextPosition is set to TRUE. +//! ATTENSION! myIsFixedTextPosition fixes all parameters of the set from recomputing inside +//! SetMeasureGeometry() methods. Parameters in dimension aspect (they are horizontal text position +//! and extension size) are adjusted on presentation computing step, user-defined values in +//! dimension aspect are not changed. +//! But plane and flyout as dimension position parameters are changed by SetTextPosition() method +//! according with user-defined text position. +//! If parameters from the set are changed by user with calls of setters, it leads to disabling of +//! fixed text position (myIsFixedTextPosition is set to FALSE). +//! If the fixed text position is set and geometry is changed by user (SetMeasureGeometry() method +//! is called) and the geometry doesn't satisfy computed dimension plane, the dimension is not valid. +//! +//! - If the set of parameters was set by user (may be without the user-defined plane or with it), +//! it can be converted to the text position by calling the method GetTextPosition(). In this case +//! the text position is NOT fixed, and SetMeasureGeometry() without user-defined plane adjusts +//! the automatic plane according input geometry (if it is possible). +class PrsDim_Dimension : public AIS_InteractiveObject +{ + DEFINE_STANDARD_RTTIEXT(PrsDim_Dimension, AIS_InteractiveObject) +protected: + + //! Geometry type defines type of shapes on which the dimension is to be built. + //! Some type of geometry allows automatic plane computing and + //! can be built without user-defined plane + //! Another types can't be built without user-defined plane. + enum GeometryType + { + GeometryType_UndefShapes, + GeometryType_Edge, + GeometryType_Face, + GeometryType_Points, + GeometryType_Edges, + GeometryType_Faces, + GeometryType_EdgeFace, + GeometryType_EdgeVertex + }; + + //! Specifies supported at base level horizontal and vertical + //! label positions for drawing extension lines and centered text. + enum LabelPosition + { + LabelPosition_None = 0x00, + + LabelPosition_Left = 0x01, + LabelPosition_Right = 0x02, + 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 + }; + + enum ValueType + { + ValueType_Computed, + ValueType_CustomReal, + ValueType_CustomText + }; + +public: + + //! Specifies supported presentation compute modes. + //! Used to compute only parts of presentation for + //! advanced highlighting. + enum ComputeMode + { + ComputeMode_All = 0, //!< "0" is reserved as neutral mode + ComputeMode_Line = 1, //!< corresponds to selection mode + ComputeMode_Text = 2 //!< corresponds to selection mode + }; + +public: + + //! Constructor with default parameters values. + //! @param theType [in] the type of dimension. + Standard_EXPORT PrsDim_Dimension (const PrsDim_KindOfDimension theType); + + //! Gets dimension measurement value. If the value to display is not + //! specified by user, then the dimension object is responsible to + //! 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 myValueType == ValueType_CustomReal ? myCustomValue : ComputeValue(); + } + + //! Sets computed dimension value. Resets custom value mode if it was set. + void SetComputedValue () + { + myValueType = ValueType_Computed; + } + + //! Sets user-defined dimension value. + //! The user-defined dimension value is specified in model space, + //! and affect by unit conversion during the display. + //! @param theValue [in] the user-defined value to display. + Standard_EXPORT void SetCustomValue (const Standard_Real theValue); + + //! Sets user-defined dimension value. + //! Unit conversion during the display is not applyed. + //! @param theValue [in] the user-defined value to display. + Standard_EXPORT void SetCustomValue (const TCollection_ExtendedString& theValue); + + //! Gets user-defined dimension value. + //! @return dimension value string. + const TCollection_ExtendedString& GetCustomValue() const { return myCustomStringValue; } + + //! 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. + //! If computed dimension geometry (points) can't be placed on the user-defined + //! plane, dimension geometry was set as invalid (validity flag is set to false) + //! and dimension presentation will not be computed. + //! If user-defined plane allow geometry placement on it, it will be used for + //! computing of the dimension presentation. + //! @return dimension plane used for presentation computing. + const gp_Pln& GetPlane() const { return myPlane; } + + //! Geometry type defines type of shapes on which the dimension is to be built. + //! @return type of geometry on which the dimension will be built. + Standard_Integer GetGeometryType () const { return myGeometryType; } + + //! Sets user-defined plane where the 2D dimension presentation will be placed. + //! Checks validity of this plane if geometry has been set already. + //! Validity of the plane is checked according to the geometry set + //! and has different criteria for different kinds of dimensions. + Standard_EXPORT virtual void SetCustomPlane (const gp_Pln& thePlane); + + //! Unsets user-defined plane. Therefore the plane for dimension will be + //! computed automatically. + void UnsetCustomPlane() { myIsPlaneCustom = Standard_False; } + + //! @return TRUE if text position is set by user with method SetTextPosition(). + Standard_Boolean IsTextPositionCustom() const + { + return myIsTextPositionFixed; + } + + //! Fixes the absolute text position and adjusts flyout, plane and text alignment + //! according to it. Updates presentation if the text position is valid. + //! ATTENTION! It does not change vertical text alignment. + //! @param theTextPos [in] the point of text position. + virtual void SetTextPosition (const gp_Pnt& /*theTextPos*/) { } + + //! Computes absolute text position from dimension parameters + //! (flyout, plane and text alignment). + virtual gp_Pnt GetTextPosition () const { return gp_Pnt(); } + +public: + + //! Gets the dimension aspect from AIS object drawer. + //! Dimension aspect contains aspects of line, text and arrows for dimension presentation. + Handle(Prs3d_DimensionAspect) DimensionAspect() const + { + return myDrawer->DimensionAspect(); + } + + //! Sets new dimension aspect for the interactive object drawer. + //! The dimension aspect provides dynamic properties which are generally + //! used during computation of dimension presentations. + Standard_EXPORT void SetDimensionAspect (const Handle(Prs3d_DimensionAspect)& theDimensionAspect); + + //! @return the kind of dimension. + PrsDim_KindOfDimension KindOfDimension() const { return myKindOfDimension; } + + //! @return the kind of interactive. + virtual AIS_KindOfInteractive Type() const Standard_OVERRIDE { return AIS_KOI_Dimension; } + + //! Returns true if the class of objects accepts the display mode theMode. + //! The interactive context can have a default mode of representation for + //! the set of Interactive Objects. This mode may not be accepted by object. + virtual Standard_Boolean AcceptDisplayMode (const Standard_Integer theMode) const Standard_OVERRIDE + { + return theMode == ComputeMode_All; + } + +public: + + //! @return dimension special symbol display options. + PrsDim_DisplaySpecialSymbol DisplaySpecialSymbol() const { return myDisplaySpecialSymbol; } + + //! Specifies whether to display special symbol or not. + Standard_EXPORT void SetDisplaySpecialSymbol (const PrsDim_DisplaySpecialSymbol theDisplaySpecSymbol); + + //! @return special symbol. + Standard_ExtCharacter SpecialSymbol() const + { + return mySpecialSymbol; + } + + //! Specifies special symbol. + Standard_EXPORT void SetSpecialSymbol (const Standard_ExtCharacter theSpecialSymbol); + + Standard_EXPORT virtual const TCollection_AsciiString& GetDisplayUnits() const; + + Standard_EXPORT virtual const TCollection_AsciiString& GetModelUnits() const; + + virtual void SetDisplayUnits (const TCollection_AsciiString& /*theUnits*/) { } + + virtual void SetModelUnits (const TCollection_AsciiString& /*theUnits*/) { } + + //! Unsets user defined text positioning and enables text positioning + //! by other parameters: text alignment, extension size, flyout and custom plane. + Standard_EXPORT void UnsetFixedTextPosition(); + +public: + + //! Returns selection tolerance for text2d: + //! For 2d text selection detection sensitive point with tolerance is used + //! Important! Only for 2d text. + Standard_Real SelToleranceForText2d() const + { + return mySelToleranceForText2d; + } + + //! Sets selection tolerance for text2d: + //! For 2d text selection detection sensitive point with tolerance is used + //! to change this tolerance use this method + //! Important! Only for 2d text. + Standard_EXPORT void SetSelToleranceForText2d (const Standard_Real theTol); + + //! @return flyout value for dimension. + Standard_Real GetFlyout() const + { + return myFlyout; + } + + //! Sets flyout value for dimension. + Standard_EXPORT void SetFlyout (const Standard_Real theFlyout); + + //! Check that the input geometry for dimension is valid and the + //! presentation can be successfully computed. + //! @return TRUE if dimension geometry is ok. + virtual Standard_Boolean IsValid() const + { + return myIsGeometryValid && CheckPlane (GetPlane()); + } + +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; + + //! Performs drawing of 2d or 3d arrows on the working plane + //! @param theLocation [in] the location of the arrow tip. + //! @param theDirection [in] the direction from the tip to the bottom of the arrow. + Standard_EXPORT void DrawArrow (const Handle(Prs3d_Presentation)& thePresentation, + const gp_Pnt& theLocation, + const gp_Dir& theDirection); + + //! Performs drawing of 2d or 3d text on the working plane + //! @param theTextPos [in] the position of the text label. + //! @param theTestDir [in] the direction of the text label. + //! @param theText [in] the text label string. + //! @param theLabelPosition [in] the text label vertical and horizontal positioning option + //! respectively to the main dimension line. + //! @return text width relative to the dimension working plane. For 2d text this value will be zero. + Standard_EXPORT void drawText (const Handle(Prs3d_Presentation)& thePresentation, + const gp_Pnt& theTextPos, + const gp_Dir& theTextDir, + const TCollection_ExtendedString& theText, + const Standard_Integer theLabelPosition); + + //! Performs computing of dimension linear extension with text + //! @param thePresentation [in] the presentation to fill with graphical primitives. + //! @param theExtensionSize [in] the size of extension line. + //! @param theExtensionStart [in] the point where extension line connects to dimension. + //! @param theExtensionDir [in] the direction of extension line. + //! @param theLabelString [in] the string with value. + //! @param theLabelWidth [in] the geometrical width computed for value string. + //! @param theMode [in] the display mode. + //! @param theLabelPosition [in] position flags for the text label. + Standard_EXPORT void DrawExtension (const Handle(Prs3d_Presentation)& thePresentation, + const Standard_Real theExtensionSize, + const gp_Pnt& theExtensionStart, + const gp_Dir& theExtensionDir, + const TCollection_ExtendedString& theLabelString, + const Standard_Real theLabelWidth, + const Standard_Integer theMode, + const Standard_Integer theLabelPosition); + + //! Performs computing of linear dimension (for length, diameter, radius and so on). + //! Please note that this method uses base dimension properties, like working plane + //! flyout length, drawer attributes. + //! @param thePresentation [in] the presentation to fill with primitives. + //! @param theMode [in] the presentation compute mode. + //! @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. + 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); + + //! Computes points bounded the flyout line for linear dimension. + //! @param theFirstPoint [in] the first attach point of linear dimension. + //! @param theSecondPoint [in] the second attach point of linear dimension. + //! @param theLineBegPoint [out] the first attach point of linear dimension. + //! @param theLineEndPoint [out] the second attach point of linear dimension. + Standard_EXPORT virtual void ComputeFlyoutLinePoints (const gp_Pnt& theFirstPoint, const gp_Pnt& theSecondPoint, + gp_Pnt& theLineBegPoint, gp_Pnt& theLineEndPoint); + + //! 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. + //! @param theSelection [in] the selection structure to fill with selection primitives. + //! @param theOwner [in] the selection entity owner. + //! @param theFirstPoint [in] the first attach point of linear dimension. + //! @param theSecondPoint [i