/*========================================================================= Program: Visualization Toolkit Module: vtkCoordinateFrameRepresentation.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 vtkCoordinateFrameRepresentation * @brief a class defining the representation for a vtkCoordinateFrameWidget * * This class is a concrete representation for the * vtkCoordinateFrameWidget. It represents a coordinate frame with an origin, 3 axis and * 3 axis lockers. Through interaction with the widget, the coordinate frame can be manipulated * by adjusting the axis normals, locking them, or moving/picking the origin point. * * The PlaceWidget() method is also used to initially position the * representation. * * @warning * This class, and vtkCoordinateFrameWidget, are next generation VTK * widgets. */ #ifndef vtkCoordinateFrameRepresentation_h #define vtkCoordinateFrameRepresentation_h #include "vtkDeprecation.h" // For VTK_DEPRECATED_IN_9_2_0 #include "vtkInteractionWidgetsModule.h" // For export macro #include "vtkNew.h" // For vtkNew command #include "vtkWidgetRepresentation.h" class vtkActor; class vtkBox; class vtkCellPicker; class vtkConeSource; class vtkFeatureEdges; class vtkGenericCell; class vtkHardwarePicker; class vtkLineSource; class vtkPlane; class vtkPolyData; class vtkPolyDataMapper; class vtkProperty; class vtkSphereSource; class vtkTransform; class VTKINTERACTIONWIDGETS_EXPORT vtkCoordinateFrameRepresentation : public vtkWidgetRepresentation { public: /** * Instantiate the class. */ static vtkCoordinateFrameRepresentation* New(); ///@{ /** * Standard methods for the class. */ vtkTypeMacro(vtkCoordinateFrameRepresentation, vtkWidgetRepresentation); void PrintSelf(ostream& os, vtkIndent indent) override; ///@} ///@{ /** * Set/Get the origin of the coordinate frame. */ void SetOrigin(double x, double y, double z); void SetOrigin(double x[3]); vtkGetVector3Macro(Origin, double); ///@} ///@{ /** * Set/Get the normal of one of the axes of the coordinate frame. * * 1) If 1 arrow tip is constrained, the corresponding normal vector is set to the picked normal. * 2) Otherwise, the axis closest to the picked normal (i.e., with the largest dot product) is * reset to the picked normal. * * In both cases, the remaining normals are re-orthogonalized using the * * Gram-Schmidt procedure. */ void SetNormal(double x, double y, double z); void SetNormal(double n[3]); void SetNormalToCamera(); vtkGetVector3Macro(XVectorNormal, double); vtkGetVector3Macro(YVectorNormal, double); vtkGetVector3Macro(ZVectorNormal, double); ///@} ///@{ /** * Set the direction of the locked (or absent a locked axis, the nearest * axis) to point from the frame's origin toward the given (x,y,z) location. */ void SetDirection(double x, double y, double z); void SetDirection(double d[3]); ///@} ///@{ /** * Force an axis to be aligned with the vector \a v, regardless of whether any axis is locked. * * This will normalize \a v and re-orthogonalize the remaining axes using the Gram-Schmidt * procedure. Passing in a degenerate (zero-length) vector will be ignored. */ void SetXAxisVector(const double v[3]); void SetXAxisVector(double x, double y, double z); void SetYAxisVector(const double v[3]); void SetYAxisVector(double x, double y, double z); void SetZAxisVector(const double v[3]); void SetZAxisVector(double x, double y, double z); ///@} ///@{ /** * If enabled, and a vtkCamera is available through the renderer, then * LockNormalToCamera will cause the normal to follow the camera's * normal. */ virtual void SetLockNormalToCamera(vtkTypeBool); vtkGetMacro(LockNormalToCamera, vtkTypeBool); vtkBooleanMacro(LockNormalToCamera, vtkTypeBool); ///@} ///@{ /** * Toggles constraint translation axis on/off. */ void SetXTranslationAxisOn() { this->TranslationAxis = Axis::XAxis; } void SetYTranslationAxisOn() { this->TranslationAxis = Axis::YAxis; } void SetZTranslationAxisOn() { this->TranslationAxis = Axis::ZAxis; } void SetTranslationAxisOff() { this->TranslationAxis = Axis::NONE; } ///@} ///@{ /** * Returns true if ContrainedAxis **/ bool IsTranslationConstrained() { return this->TranslationAxis != Axis::NONE; } ///@} /** * Satisfies the superclass API. This will change the state of the widget * to match changes that have been made to the underlying PolyDataSource */ void UpdatePlacement(); /** * Reset the origin (by calling update placement) and the axes (to be aligned * with the world coordinate X, Y, and Z axes). */ void Reset(); /** * Reset only the axis orientations (not the origin). */ void ResetAxes(); ///@{ /** * Get the properties of the origin. The properties of the origin when selected * and unselected can be manipulated. */ vtkGetObjectMacro(OriginProperty, vtkProperty); vtkGetObjectMacro(SelectedOriginProperty, vtkProperty); ///@} ///@{ /** * Get the properties on the XVector. The properties of the XVector when selected * and unselected can be manipulated. */ vtkGetObjectMacro(XVectorProperty, vtkProperty); vtkGetObjectMacro(SelectedXVectorProperty, vtkProperty); ///@} ///@{ /** * Get the properties on the LockedXVector. The properties of the LockedXVector when selected * and unselected can be manipulated. */ vtkGetObjectMacro(LockedXVectorProperty, vtkProperty); vtkGetObjectMacro(SelectedLockedXVectorProperty, vtkProperty); ///@} ///@{ /** * Get the properties on the UnlockedXVector. The properties of the UnlockedXVector when selected * and unselected can be manipulated. */ vtkGetObjectMacro(UnlockedXVectorProperty, vtkProperty); vtkGetObjectMacro(SelectedUnlockedXVectorProperty, vtkProperty); ///@} ///@{ /** * Get the properties on the YVector. The properties of the YVector when selected * and unselected can be manipulated. */ vtkGetObjectMacro(YVectorProperty, vtkProperty); vtkGetObjectMacro(SelectedYVectorProperty, vtkProperty); ///@} ///@{ /** * Get the properties on the LockedYVector. The properties of the LockedYVector when selected * and unselected can be manipulated. */ vtkGetObjectMacro(LockedYVectorProperty, vtkProperty); vtkGetObjectMacro(SelectedLockedYVectorProperty, vtkProperty); ///@} ///@{ /** * Get the properties on the UnlockedYVector. The properties of the UnlockedYVector when selected * and unselected can be manipulated. */ vtkGetObjectMacro(UnlockedYVectorProperty, vtkProperty); vtkGetObjectMacro(SelectedUnlockedYVectorProperty, vtkProperty); ///@} ///@{ /** * Get the properties on the ZVector. The properties of the ZVector when selected * and unselected can be manipulated. */ vtkGetObjectMacro(ZVectorProperty, vtkProperty); vtkGetObjectMacro(SelectedZVectorProperty, vtkProperty); ///@} ///@{ /** * Get the properties on the LockedZVector. The properties of the LockedZVector when selected * and unselected can be manipulated. */ vtkGetObjectMacro(LockedZVectorProperty, vtkProperty); vtkGetObjectMacro(SelectedLockedZVectorProperty, vtkProperty); ///@} ///@{ /** * Get the properties on the UnlockedZVector. The properties of the UnlockedZVector when selected * and unselected can be manipulated. */ vtkGetObjectMacro(UnlockedZVectorProperty, vtkProperty); vtkGetObjectMacro(SelectedUnlockedZVectorProperty, vtkProperty); ///@} ///@{ /** * Enable/Disable picking camera focal info if no result is available for PickOrigin, PickNormal * and PickDirectionPoint. The default is disabled. */ vtkGetMacro(PickCameraFocalInfo, bool); vtkSetMacro(PickCameraFocalInfo, bool); vtkBooleanMacro(PickCameraFocalInfo, bool); ///@} /** * Given the X, Y display coordinates, pick a new origin for the coordinate frame * from a point that is on the objects rendered by the renderer. * * Note: if a point from a rendered object is not picked, the camera focal point can optionally be * set. */ bool PickOrigin(int X, int Y, bool snapToMeshPoint = false); /** * Given the X, Y display coordinates, pick a new normal for the coordinate frame * from a point that is on the objects rendered by the renderer. * * Note: if a normal from a rendered object is not picked, the camera plane normal can optionally * be set. */ bool PickNormal(int X, int Y, bool snapToMeshPoint = false); /** * Given the X, Y display coordinates, pick a point and using the origin define normal for the * coordinate frame from a point that is on the objects rendered by the renderer. * * Note: if a point from a rendered object is not picked, the camera focal point can optionally be * set. */ bool PickDirectionPoint(int X, int Y, bool snapToMeshPoint = false); /** * Get/set which axis (if any) is locked. * * At most, a single axis can be locked at a time. * * The axis must be one of the following values: { -1, 0, 1, 2 }. * -1 indicates that no axis is locked; 0 corresponds to the X axis; 1 to Y; and 2 to Z. * * In terms of mouse interactions, locking an axis prevents its direction from being * modified by rotation (so only rotations about that axis are possible) and * prevents the origin from translating along it (so all translations must be in the * plane using it as a normal). * * In terms of picking interactions, locking an axis selects it as the target axis * to be modified (i.e., the locked axis will be overwritten with a normal vector * or direction vector). */ int GetLockedAxis() const; void SetLockedAxis(int axis); ///@{ /** * Methods to interface with the vtkCoordinateFrameWidget. */ int ComputeInteractionState(int X, int Y, int modify = 0) override; void PlaceWidget(double bounds[6]) override; void BuildRepresentation() override; void StartWidgetInteraction(double eventPos[2]) override; void WidgetInteraction(double newEventPos[2]) override; void EndWidgetInteraction(double newEventPos[2]) override; ///@} ///@{ /** * Methods supporting the rendering process. */ double* GetBounds() VTK_SIZEHINT(6) override; void GetActors(vtkPropCollection* pc) override; void ReleaseGraphicsResources(vtkWindow*) override; int RenderOpaqueGeometry(vtkViewport*) override; int RenderTranslucentPolygonalGeometry(vtkViewport*) override; vtkTypeBool HasTranslucentPolygonalGeometry() override; ///@} // Manage the state of the widget enum InteractionStateType { Outside = 0, Moving, MovingOrigin, RotatingXVector, RotatingYVector, RotatingZVector, ModifyingLockerXVector, ModifyingLockerYVector, ModifyingLockerZVector }; #if !defined(VTK_LEGACY_REMOVE) VTK_DEPRECATED_IN_9_2_0("because leading underscore is reserved") typedef InteractionStateType _InteractionState; #endif ///@{ /** * The interaction state may be set from a widget (e.g., * vtkCoordinateFrameWidget) or other object. This controls how the * interaction with the widget proceeds. Normally this method is used as * part of a handshaking process with the widget: First * ComputeInteractionState() is invoked that returns a state based on * geometric considerations (i.e., cursor near a widget feature), then * based on events, the widget may modify this further. */ vtkSetClampMacro(InteractionState, int, Outside, ModifyingLockerZVector); ///@} ///@{ /** * Sets the visual appearance of the representation based on the * state it is in. This state is usually the same as InteractionState. */ virtual void SetRepresentationState(int); vtkGetMacro(RepresentationState, int); ///@} ///@{ /** * Set/get the length of the axis glyphs relative to screen size. * The default is 0.04. */ vtkSetClampMacro(LengthFactor, double, 0, 1); vtkGetMacro(LengthFactor, double); ///@} protected: vtkCoordinateFrameRepresentation(); ~vtkCoordinateFrameRepresentation() override; int RepresentationState = Outside; // Keep track of event positions double LastEventPosition[3]; bool PickCameraFocalInfo = false; // Locking normal to camera vtkTypeBool LockNormalToCamera = false; int TranslationAxis = Axis::NONE; double Origin[3] = { 0, 0, 0 }; double XVectorNormal[3] = { 1, 0, 0 }; double YVectorNormal[3] = { 0, 1, 0 }; double ZVectorNormal[3] = { 0, 0, 1 }; vtkSetVector3Macro(XVectorNormal, double); vtkSetVector3Macro(YVectorNormal, double); vtkSetVector3Macro(ZVectorNormal, double); // The origin positioning handle vtkNew OriginSphereSource; vtkNew OriginSphereMapper; vtkNew OriginSphereActor; void HighlightOrigin(int highlight); // The XVector line source vtkNew XVectorLineSource; vtkNew XVectorLineMapper; vtkNew XVectorLineActor; // The XVector cone source vtkNew XVectorConeSource; vtkNew XVectorConeMapper; vtkNew XVectorConeActor; void HighlightXVector(int highlight); // The lock XVector cone source bool XVectorIsLocked = false; vtkNew LockerXVectorConeSource; vtkNew LockerXVectorConeMapper; vtkNew LockerXVectorConeActor; void HighlightLockerXVector(int highlight); // The YVector line source vtkNew YVectorLineSource; vtkNew YVectorLineMapper; vtkNew YVectorLineActor; // The YVector cone source vtkNew YVectorConeSource; vtkNew YVectorConeMapper; vtkNew YVectorConeActor; void HighlightYVector(int highlight); // The lock YVector cone source bool YVectorIsLocked = false; vtkNew LockerYVectorConeSource; vtkNew LockerYVectorConeMapper; vtkNew LockerYVectorConeActor; void HighlightLockerYVector(int highlight); // The Vector Z line source vtkNew ZVectorLineSource; vtkNew ZVectorLineMapper; vtkNew ZVectorLineActor; // The Vector Z cone source vtkNew ZVectorConeSource; vtkNew ZVectorConeMapper; vtkNew ZVectorConeActor; void HighlightZVector(int highlight); // The lock Vector Z cone source bool ZVectorIsLocked = false; vtkNew LockerZVectorConeSource; vtkNew LockerZVectorConeMapper; vtkNew LockerZVectorConeActor; void HighlightLockerZVector(int highlight); // Do the picking vtkNew HardwarePicker; // Used for picking rendered props vtkNew CellPicker; // Used for picking widget props // Compute Picker tolerance void ComputeAdaptivePickerTolerance(); // Register internal Pickers within PickingManager void RegisterPickers() override; // Transform the normal (used for rotation) vtkNew Transform; // Methods to manipulate the plane void Rotate(double X, double Y, double* p1, double* p2, double* vpn); void ModifyingLocker(int axis); void TranslateOrigin(double* p1, double* p2); void SizeHandles(); // Properties used to control the appearance of selected objects and // the manipulator in general. vtkNew OriginProperty; vtkNew SelectedOriginProperty; vtkNew XVectorProperty; vtkNew SelectedXVectorProperty; vtkNew LockedXVectorProperty; vtkNew SelectedLockedXVectorProperty; vtkNew UnlockedXVectorProperty; vtkNew SelectedUnlockedXVectorProperty; vtkNew YVectorProperty; vtkNew SelectedYVectorProperty; vtkNew LockedYVectorProperty; vtkNew SelectedLockedYVectorProperty; vtkNew UnlockedYVectorProperty; vtkNew SelectedUnlockedYVectorProperty; vtkNew ZVectorProperty; vtkNew SelectedZVectorProperty; vtkNew LockedZVectorProperty; vtkNew SelectedLockedZVectorProperty; vtkNew UnlockedZVectorProperty; vtkNew SelectedUnlockedZVectorProperty; virtual void CreateDefaultProperties(); // Support GetBounds() method vtkNew BoundingBox; vtkNew Cell; double LengthFactor = 0.04; private: vtkCoordinateFrameRepresentation(const vtkCoordinateFrameRepresentation&) = delete; void operator=(const vtkCoordinateFrameRepresentation&) = delete; }; #endif