1 /*========================================================================= 2 3 Program: Visualization Toolkit 4 Module: vtkCurveRepresentation 5 6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 7 All rights reserved. 8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details. 9 10 This software is distributed WITHOUT ANY WARRANTY; without even 11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 12 PURPOSE. See the above copyright notice for more information. 13 14 =========================================================================*/ 15 /** 16 * @class vtkCurveRepresentation 17 * @brief vtkWidgetRepresentation 18 * base class for a widget that represents an curve that connects control 19 * points. 20 * 21 * Base class for widgets used to define curves from points, such as 22 * vtkPolyLineRepresentation and vtkSplineRepresentation. This class 23 * uses handles, the number of which can be changed, to represent the 24 * points that define the curve. The handles can be picked can be 25 * picked on the curve itself to translate or rotate it in the scene. 26 */ 27 28 #ifndef vtkCurveRepresentation_h 29 #define vtkCurveRepresentation_h 30 31 #include "vtkInteractionWidgetsModule.h" // For export macro 32 #include "vtkPolyDataAlgorithm.h" // needed for vtkPolyDataAlgorithm 33 #include "vtkWidgetRepresentation.h" 34 35 class vtkActor; 36 class vtkCellPicker; 37 class vtkDoubleArray; 38 class vtkHandleSource; 39 class vtkPlaneSource; 40 class vtkPoints; 41 class vtkPolyData; 42 class vtkProp; 43 class vtkProperty; 44 class vtkTransform; 45 46 #define VTK_PROJECTION_YZ 0 47 #define VTK_PROJECTION_XZ 1 48 #define VTK_PROJECTION_XY 2 49 #define VTK_PROJECTION_OBLIQUE 3 50 class VTKINTERACTIONWIDGETS_EXPORT vtkCurveRepresentation : public vtkWidgetRepresentation 51 { 52 public: 53 vtkTypeMacro(vtkCurveRepresentation, vtkWidgetRepresentation); 54 void PrintSelf(ostream& os, vtkIndent indent) override; 55 56 // Used to manage the InteractionState of the widget 57 enum _InteractionState 58 { 59 Outside = 0, 60 OnHandle, 61 OnLine, 62 Moving, 63 Scaling, 64 Spinning, 65 Inserting, 66 Erasing, 67 Pushing 68 }; 69 70 ///@{ 71 /** 72 * Set the interaction state 73 */ 74 vtkSetMacro(InteractionState, int); 75 ///@} 76 77 ///@{ 78 /** 79 * Force the widget to be projected onto one of the orthogonal 80 * planes. Remember that when the InteractionState changes, a 81 * ModifiedEvent is invoked. This can be used to snap the curve to 82 * the plane if it is originally not aligned. The normal in 83 * SetProjectionNormal is 0,1,2 for YZ,XZ,XY planes respectively and 84 * 3 for arbitrary oblique planes when the widget is tied to a 85 * vtkPlaneSource. 86 */ 87 vtkSetMacro(ProjectToPlane, vtkTypeBool); 88 vtkGetMacro(ProjectToPlane, vtkTypeBool); 89 vtkBooleanMacro(ProjectToPlane, vtkTypeBool); 90 ///@} 91 92 /** 93 * Set up a reference to a vtkPlaneSource that could be from another widget 94 * object, e.g. a vtkPolyDataSourceWidget. 95 */ 96 void SetPlaneSource(vtkPlaneSource* plane); 97 98 vtkSetClampMacro(ProjectionNormal, int, VTK_PROJECTION_YZ, VTK_PROJECTION_OBLIQUE); 99 vtkGetMacro(ProjectionNormal, int); SetProjectionNormalToXAxes()100 void SetProjectionNormalToXAxes() { this->SetProjectionNormal(0); } SetProjectionNormalToYAxes()101 void SetProjectionNormalToYAxes() { this->SetProjectionNormal(1); } SetProjectionNormalToZAxes()102 void SetProjectionNormalToZAxes() { this->SetProjectionNormal(2); } SetProjectionNormalToOblique()103 void SetProjectionNormalToOblique() { this->SetProjectionNormal(3); } 104 105 ///@{ 106 /** 107 * Set the position of poly line handles and points in terms of a plane's 108 * position. i.e., if ProjectionNormal is 0, all of the x-coordinate 109 * values of the points are set to position. Any value can be passed (and is 110 * ignored) to update the poly line points when Projection normal is set to 3 111 * for arbitrary plane orientations. 112 */ 113 void SetProjectionPosition(double position); 114 vtkGetMacro(ProjectionPosition, double); 115 ///@} 116 117 /** 118 * Grab the polydata (including points) that defines the 119 * interpolating curve. Points are guaranteed to be up-to-date when 120 * either the InteractionEvent or EndInteraction events are 121 * invoked. The user provides the vtkPolyData and the points and 122 * polyline are added to it. 123 */ 124 virtual void GetPolyData(vtkPolyData* pd) = 0; 125 126 ///@{ 127 /** 128 * Set/Get the handle properties (the spheres are the handles). The 129 * properties of the handles when selected and unselected can be manipulated. 130 */ 131 vtkGetObjectMacro(HandleProperty, vtkProperty); 132 vtkGetObjectMacro(SelectedHandleProperty, vtkProperty); 133 ///@} 134 135 ///@{ 136 /** 137 * Set/Get the line properties. The properties of the line when selected 138 * and unselected can be manipulated. 139 */ 140 vtkGetObjectMacro(LineProperty, vtkProperty); 141 vtkGetObjectMacro(SelectedLineProperty, vtkProperty); 142 ///@} 143 144 ///@{ 145 /** 146 * Set/Get the number of handles for this widget. 147 */ 148 virtual void SetNumberOfHandles(int npts) = 0; 149 vtkGetMacro(NumberOfHandles, int); 150 ///@} 151 152 ///@{ 153 /** 154 * @deprecated VTK 9.1. Use `GetDirectional` and `SetDirectional` instead. 155 */ 156 VTK_DEPRECATED_IN_9_1_0("renamed to SetDirectional") 157 virtual void SetDirectionalLine(bool val); 158 VTK_DEPRECATED_IN_9_1_0("renamed to GetDirectional") 159 virtual bool GetDirectionalLine(); 160 VTK_DEPRECATED_IN_9_1_0("renamed to DirectionalOn") 161 virtual void DirectionalLineOn(); 162 VTK_DEPRECATED_IN_9_1_0("renamed to DirectionalOff") 163 virtual void DirectionalLineOff(); 164 ///@} 165 166 ///@{ 167 /** 168 * Set the representation to be directional or not. 169 * The meaning of being directional depends on the representation and 170 * its handles implementations in the subclasses. 171 */ 172 virtual void SetDirectional(bool val); 173 vtkGetMacro(Directional, bool); 174 vtkBooleanMacro(Directional, bool); 175 ///@} 176 177 ///@{ 178 /** 179 * Set/Get the position of the handles. Call GetNumberOfHandles 180 * to determine the valid range of handle indices. 181 */ 182 virtual void SetHandlePosition(int handle, double x, double y, double z); 183 virtual void SetHandlePosition(int handle, double xyz[3]); 184 virtual void GetHandlePosition(int handle, double xyz[3]); 185 virtual double* GetHandlePosition(int handle); 186 virtual vtkDoubleArray* GetHandlePositions() = 0; 187 ///@} 188 189 ///@{ 190 /** 191 * Control whether the curve is open or closed. A closed forms a 192 * continuous loop: the first and last points are the same. A 193 * minimum of 3 handles are required to form a closed loop. 194 */ 195 void SetClosed(vtkTypeBool closed); 196 vtkGetMacro(Closed, vtkTypeBool); 197 vtkBooleanMacro(Closed, vtkTypeBool); 198 ///@} 199 200 /** 201 * Convenience method to determine whether the curve is 202 * closed in a geometric sense. The widget may be set "closed" but still 203 * be geometrically open (e.g., a straight line). 204 */ 205 vtkTypeBool IsClosed(); 206 207 /** 208 * Get the approximate vs. the true arc length of the curve. Calculated as 209 * the summed lengths of the individual straight line segments. Use 210 * SetResolution to control the accuracy. 211 */ 212 virtual double GetSummedLength() = 0; 213 214 /** 215 * Convenience method to allocate and set the handles from a 216 * vtkPoints instance. If the first and last points are the same, 217 * the curve sets Closed to the on InteractionState and disregards 218 * the last point, otherwise Closed remains unchanged. 219 */ 220 virtual void InitializeHandles(vtkPoints* points) = 0; 221 222 ///@{ 223 /** 224 * These are methods that satisfy vtkWidgetRepresentation 225 * API. Note that a version of place widget is available where the 226 * center and handle position are specified. 227 */ 228 void BuildRepresentation() override = 0; 229 int ComputeInteractionState(int X, int Y, int modify = 0) override; 230 void StartWidgetInteraction(double e[2]) override; 231 void WidgetInteraction(double e[2]) override; 232 void EndWidgetInteraction(double e[2]) override; 233 double* GetBounds() override; 234 ///@} 235 236 ///@{ 237 /** 238 * Methods supporting, and required by, the rendering process. 239 */ 240 void ReleaseGraphicsResources(vtkWindow*) override; 241 int RenderOpaqueGeometry(vtkViewport*) override; 242 int RenderTranslucentPolygonalGeometry(vtkViewport*) override; 243 int RenderOverlay(vtkViewport*) override; 244 vtkTypeBool HasTranslucentPolygonalGeometry() override; 245 ///@} 246 247 /** 248 * Convenience method to set the line color. 249 * Ideally one should use GetLineProperty()->SetColor(). 250 */ 251 void SetLineColor(double r, double g, double b); 252 253 /* 254 * Register internal Pickers within PickingManager 255 */ 256 void RegisterPickers() override; 257 258 ///@{ 259 /** 260 * Get/Set the current handle index. Setting the current handle index will 261 * also result in the handle being highlighted. Set to `-1` to remove the 262 * highlight. 263 */ 264 void SetCurrentHandleIndex(int index); 265 vtkGetMacro(CurrentHandleIndex, int); 266 ///@} 267 268 ///@{ 269 /** 270 * Gets/Sets the constraint axis for translations. Returns Axis::NONE 271 * if none. 272 **/ 273 vtkGetMacro(TranslationAxis, int); 274 vtkSetClampMacro(TranslationAxis, int, -1, 2); 275 ///@} 276 277 ///@{ 278 /** 279 * Toggles constraint translation axis on/off. 280 */ SetXTranslationAxisOn()281 void SetXTranslationAxisOn() { this->TranslationAxis = Axis::XAxis; } SetYTranslationAxisOn()282 void SetYTranslationAxisOn() { this->TranslationAxis = Axis::YAxis; } SetZTranslationAxisOn()283 void SetZTranslationAxisOn() { this->TranslationAxis = Axis::ZAxis; } SetTranslationAxisOff()284 void SetTranslationAxisOff() { this->TranslationAxis = Axis::NONE; } 285 ///@} 286 287 ///@{ 288 /** 289 * Returns true if ContrainedAxis 290 **/ IsTranslationConstrained()291 bool IsTranslationConstrained() { return this->TranslationAxis != Axis::NONE; } 292 ///@} 293 294 protected: 295 vtkCurveRepresentation(); 296 ~vtkCurveRepresentation() override; 297 298 double LastEventPosition[3]; 299 double Bounds[6]; 300 301 // Controlling vars 302 int ProjectionNormal; 303 double ProjectionPosition; 304 vtkTypeBool ProjectToPlane; 305 vtkPlaneSource* PlaneSource; 306 307 // Projection capabilities 308 void ProjectPointsToPlane(); 309 void ProjectPointsToOrthoPlane(); 310 void ProjectPointsToObliquePlane(); 311 312 int NumberOfHandles = 0; 313 vtkTypeBool Closed; 314 315 // The line segments 316 vtkActor* LineActor; 317 void HighlightLine(int highlight); 318 int HighlightHandle(vtkProp* prop); // returns handle index or -1 on fail 319 320 // accessors to glyphs representing hot spots (e.g., handles) 321 virtual vtkActor* GetHandleActor(int index) = 0; 322 virtual vtkHandleSource* GetHandleSource(int index) = 0; 323 324 /** 325 * returns handle index or -1 on fail 326 */ 327 virtual int GetHandleIndex(vtkProp* prop) = 0; 328 virtual void SizeHandles(); 329 330 /** 331 * Returns the position of insertion or -1 on fail. 332 */ 333 virtual int InsertHandleOnLine(double* pos) = 0; 334 335 virtual void PushHandle(double* pos); 336 virtual void EraseHandle(const int&); 337 338 // Do the picking 339 vtkCellPicker* HandlePicker; 340 vtkCellPicker* LinePicker; 341 double LastPickPosition[3]; 342 vtkActor* CurrentHandle; 343 int CurrentHandleIndex; 344 bool FirstSelected; 345 346 // Methods to manipulate the curve. 347 void MovePoint(double* p1, double* p2); 348 void Scale(double* p1, double* p2, int X, int Y); 349 void Translate(double* p1, double* p2); 350 void Spin(double* p1, double* p2, double* vpn); 351 352 // Transform the control points (used for spinning) 353 vtkTransform* Transform; 354 355 // Manage how the representation appears 356 bool Directional = false; 357 358 // Properties used to control the appearance of selected objects and 359 // the manipulator in general. 360 vtkProperty* HandleProperty; 361 vtkProperty* SelectedHandleProperty; 362 vtkProperty* LineProperty; 363 vtkProperty* SelectedLineProperty; 364 void CreateDefaultProperties(); 365 366 // For efficient spinning 367 double Centroid[3]; 368 void CalculateCentroid(); 369 370 int TranslationAxis; 371 372 private: 373 vtkCurveRepresentation(const vtkCurveRepresentation&) = delete; 374 void operator=(const vtkCurveRepresentation&) = delete; 375 }; 376 #endif 377