text: /*=========================================================================
  
    Program:   Visualization Toolkit
    Module:    vtkAffineRepresentation2D.h
  
    Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
    All rights reserved.
    See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
  
       This software is distributed WITHOUT ANY WARRANTY; without even
       the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
       PURPOSE.  See the above copyright notice for more information.
  
  =========================================================================*/
  /**
   * @class   vtkAffineRepresentation2D
   * @brief   represent 2D affine transformations
   *
   * This class is used to represent a vtkAffineWidget. This representation
   * consists of three parts: a box, a circle, and a cross. The box is used for
   * scaling and shearing, the circle for rotation, and the cross for
   * translation. These parts are drawn in the overlay plane and maintain a
   * constant size (width and height) specified in terms of normalized viewport
   * coordinates.
   *
   * The representation maintains an internal transformation matrix (see
   * superclass' GetTransform() method). The transformations generated by this
   * widget assume that the representation lies in the x-y plane. If this is
   * not the case, the user is responsible for transforming this
   * representation's matrix into the correct coordinate space (by judicious
   * matrix multiplication). Note that the transformation matrix returned by
   * GetTransform() is relative to the last PlaceWidget() invocation. (The
   * PlaceWidget() sets the origin around which rotation and scaling occurs;
   * the origin is the center point of the bounding box provided.)
   *
   *
   * @sa
   * vtkAffineRepresentation vtkAffineWidget
   */
  
  #ifndef vtkAffineRepresentation2D_h
  #define vtkAffineRepresentation2D_h
  
  #include "vtkAffineRepresentation.h"
  #include "vtkInteractionWidgetsModule.h" // For export macro
  
  class vtkProperty2D;
  class vtkActor2D;
  class vtkPolyDataMapper2D;
  class vtkPolyData;
  class vtkPoints;
  class vtkCellArray;
  class vtkTextProperty;
  class vtkLeaderActor2D;
  class vtkTextMapper;
  class vtkActor2D;
  
  class VTKINTERACTIONWIDGETS_EXPORT vtkAffineRepresentation2D : public vtkAffineRepresentation
  {
  public:
    /**
     * Instantiate this class.
     */
    static vtkAffineRepresentation2D* New();
  
    //@{
    /**
     * Standard methods for instances of this class.
     */
    vtkTypeMacro(vtkAffineRepresentation2D, vtkAffineRepresentation);
    void PrintSelf(ostream& os, vtkIndent indent) override;
    //@}
  
    //@{
    /**
     * Specify the width of the various parts of the representation (in
     * pixels).  The three parts are of the representation are the translation
     * axes, the rotation circle, and the scale/shear box. Note that since the
     * widget resizes itself so that the width and height are always the
     * same, only the width needs to be specified.
     */
    vtkSetClampMacro(BoxWidth, int, 10, VTK_INT_MAX);
    vtkGetMacro(BoxWidth, int);
    vtkSetClampMacro(CircleWidth, int, 10, VTK_INT_MAX);
    vtkGetMacro(CircleWidth, int);
    vtkSetClampMacro(AxesWidth, int, 10, VTK_INT_MAX);
    vtkGetMacro(AxesWidth, int);
    //@}
  
    //@{
    /**
     * Specify the origin of the widget (in world coordinates). The origin
     * is the point where the widget places itself. Note that rotations and
     * scaling occurs around the origin.
     */
    void SetOrigin(const double o[3]) { this->SetOrigin(o[0], o[1], o[2]); }
    void SetOrigin(double ox, double oy, double oz);
    vtkGetVector3Macro(Origin, double);
    //@}
  
    /**
     * Retrieve a linear transform characterizing the affine transformation
     * generated by this widget. This method copies its internal transform into
     * the transform provided. Note that the PlaceWidget() method initializes
     * the internal matrix to identity. All subsequent widget operations (i.e.,
     * scale, translate, rotate, shear) are concatenated with the internal
     * transform.
     */
    void GetTransform(vtkTransform* t) override;
  
    //@{
    /**
     * Set/Get the properties when unselected and selected.
     */
    void SetProperty(vtkProperty2D*);
    void SetSelectedProperty(vtkProperty2D*);
    void SetTextProperty(vtkTextProperty*);
    vtkGetObjectMacro(Property, vtkProperty2D);
    vtkGetObjectMacro(SelectedProperty, vtkProperty2D);
    vtkGetObjectMacro(TextProperty, vtkTextProperty);
    //@}
  
    //@{
    /**
     * Enable the display of text with numeric values characterizing the
     * transformation. Rotation and shear are expressed in degrees; translation
     * the distance in world coordinates; and scale normalized (sx,sy) values.
     */
    vtkSetMacro(DisplayText, vtkTypeBool);
    vtkGetMacro(DisplayText, vtkTypeBool);
    vtkBooleanMacro(DisplayText, vtkTypeBool);
    //@}
  
    //@{
    /**
     * Subclasses of vtkAffineRepresentation2D must implement these methods. These
     * are the methods that the widget and its representation use to
     * communicate with each other. Note: PlaceWidget() reinitializes the
     * transformation matrix (i.e., sets it to identity). It also sets the
     * origin for scaling and rotation.
     */
    void PlaceWidget(double bounds[6]) override;
    void StartWidgetInteraction(double eventPos[2]) override;
    void WidgetInteraction(double eventPos[2]) override;
    void EndWidgetInteraction(double eventPos[2]) override;
    int ComputeInteractionState(int X, int Y, int modify = 0) override;
    void BuildRepresentation() override;
    //@}
  
    //@{
    /**
     * Methods to make this class behave as a vtkProp.
     */
    void ShallowCopy(vtkProp* prop) override;
    void GetActors2D(vtkPropCollection*) override;
    void ReleaseGraphicsResources(vtkWindow*) override;
    int RenderOverlay(vtkViewport* viewport) override;
    //@}
  
  protected:
    vtkAffineRepresentation2D();
    ~vtkAffineRepresentation2D() override;
  
    // Methods to manipulate the cursor
    void Translate(double eventPos[2]);
    void Scale(double eventPos[2]);
    void Rotate(double eventPos[2]);
    void Shear(double eventPos[2]);
    void Highlight(int highlight) override;
    void UpdateText(const char* text, double eventPos[2]);
  
    // The width of the widget in normalized viewport coordinates.
    int BoxWidth;
    int CircleWidth;
    int AxesWidth;
  
    // Display text
    vtkTypeBool DisplayText;
  
    // Internal variables for bookkeeping (in display coordinates unless noted)
    double CurrentWidth;
    double CurrentRadius;
    double CurrentAxesWidth;
  
    // The internal transformation matrix
    vtkTransform* CurrentTransform;
    vtkTransform* TotalTransform;
    double Origin[4];             // the current origin in world coordinates
    double DisplayOrigin[3];      // the current origin in display coordinates
    double CurrentTranslation[3]; // translation this movement
    double StartWorldPosition[4]; // Start event position converted to world
    double StartAngle;            // The starting angle (always positive)
    double CurrentAngle;
    double CurrentScale[2];
    double CurrentShear[2];
    void ApplyShear(); // helper method to apply shear to matrix
  
    // Properties used to control the appearance of selected objects and
    // the manipulator in general.
    vtkProperty2D* Property;
    vtkProperty2D* SelectedProperty;
    vtkTextProperty* TextProperty;
    void CreateDefaultProperties();
    double Opacity;
    double SelectedOpacity;
  
    // Support picking
    double LastEventPosition[2];
  
    // These are the classes that form the geometric representation -----------
    // The label
    vtkTextMapper* TextMapper;
    vtkActor2D* TextActor;
  
    // The outer box
    vtkPoints* BoxPoints;
    vtkCellArray* BoxCellArray;
    vtkPolyData* Box;
    vtkPolyDataMapper2D* BoxMapper;
    vtkActor2D* BoxActor;
  
    vtkPoints* HBoxPoints;
    vtkCellArray* HBoxCellArray;
    vtkPolyData* HBox;
    vtkPolyDataMapper2D* HBoxMapper;
    vtkActor2D* HBoxActor;
  
    // The circle
    vtkPoints* CirclePoints;
    vtkCellArray* CircleCellArray;
    vtkPolyData* Circle;
    vtkPolyDataMapper2D* CircleMapper;
    vtkActor2D* CircleActor;
  
    vtkPoints* HCirclePoints;
    vtkCellArray* HCircleCellArray;
    vtkPolyData* HCircle;
    vtkPolyDataMapper2D* HCircleMapper;
    vtkActor2D* HCircleActor;
  
    // The translation axes
    vtkLeaderActor2D* XAxis;
    vtkLeaderActor2D* YAxis;
    vtkLeaderActor2D* HXAxis;
    vtkLeaderActor2D* HYAxis;
  
  private:
    vtkAffineRepresentation2D(const vtkAffineRepresentation2D&) = delete;
    void operator=(const vtkAffineRepresentation2D&) = delete;
  };
  
  #endif
  