1 /*========================================================================= 2 3 Program: Visualization Toolkit 4 Module: vtkChartXYZ.h 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 // .NAME vtkChartXYZ - Factory class for drawing 3D XYZ charts. 17 // 18 // .SECTION Description 19 20 #ifndef vtkChartXYZ_h 21 #define vtkChartXYZ_h 22 23 #include "vtkChartsCoreModule.h" // For export macro 24 #include "vtkContextItem.h" 25 #include "vtkColor.h" // For vtkColor4ub 26 #include "vtkRect.h" // For vtkRectf ivars 27 #include "vtkNew.h" // For ivars 28 #include "vtkSmartPointer.h" // For ivars 29 #include <vector> // For ivars 30 31 class vtkAnnotationLink; 32 class vtkAxis; 33 class vtkContext3D; 34 class vtkContextMouseEvent; 35 class vtkPen; 36 class vtkPlaneCollection; 37 class vtkPlot3D; 38 class vtkTable; 39 class vtkTransform; 40 class vtkUnsignedCharArray; 41 42 class VTKCHARTSCORE_EXPORT vtkChartXYZ : public vtkContextItem 43 { 44 public: 45 vtkTypeMacro(vtkChartXYZ, vtkContextItem); 46 virtual void PrintSelf(ostream &os, vtkIndent indent); 47 48 static vtkChartXYZ * New(); 49 50 // Description: 51 // Set the geometry in pixel coordinates (origin and width/height). 52 // This method also sets up the end points of the axes of the chart. 53 // For this reason, if you call SetAroundX(), you should call SetGeometry() 54 // afterwards. 55 void SetGeometry(const vtkRectf &bounds); 56 57 // Description: 58 // Set the rotation angle for the chart (AutoRotate mode only). 59 void SetAngle(double angle); 60 61 // Description: 62 // Set whether or not we're rotating about the X axis. 63 void SetAroundX(bool isX); 64 65 // Description: 66 // Set the vtkAnnotationLink for the chart. 67 virtual void SetAnnotationLink(vtkAnnotationLink *link); 68 69 // Description: 70 // Get the x (0), y (1) or z (2) axis. 71 vtkAxis * GetAxis(int axis); 72 73 // Description: 74 // Set the color for the axes. 75 void SetAxisColor(const vtkColor4ub& color); 76 vtkColor4ub GetAxisColor(); 77 78 // Description: 79 // Set whether or not we're using this chart to rotate on a timer. 80 // Default value is false. 81 void SetAutoRotate(bool b); 82 83 // Description: 84 // Set whether or not axes labels & tick marks should be drawn. 85 // Default value is true. 86 void SetDecorateAxes(bool b); 87 88 // Description: 89 // Set whether or not the chart should automatically resize itself to fill 90 // the scene. Default value is true. 91 void SetFitToScene(bool b); 92 93 // Description: 94 // Perform any updates to the item that may be necessary before rendering. 95 virtual void Update(); 96 97 // Description: 98 // Paint event for the chart, called whenever the chart needs to be drawn. 99 virtual bool Paint(vtkContext2D *painter); 100 101 // Description: 102 // Adds a plot to the chart. 103 virtual vtkIdType AddPlot(vtkPlot3D* plot); 104 105 // Description: 106 // Remove all the plots from this chart. 107 void ClearPlots(); 108 109 // Description: 110 // Determine the XYZ bounds of the plots within this chart. 111 // This information is then used to set the range of the axes. 112 void RecalculateBounds(); 113 114 // Description: 115 // Use this chart's Geometry to set the endpoints of its axes. 116 // This method also sets up a transformation that is used to 117 // properly render the data within the chart. 118 void RecalculateTransform(); 119 120 //BTX 121 // Description: 122 // Returns true if the transform is interactive, false otherwise. 123 virtual bool Hit(const vtkContextMouseEvent &mouse); 124 125 // Description: 126 // Mouse press event. Keep track of zoom anchor position. 127 virtual bool MouseButtonPressEvent(const vtkContextMouseEvent &mouse); 128 129 // Description: 130 // Mouse move event. Perform pan or zoom as specified by the mouse bindings. 131 virtual bool MouseMoveEvent(const vtkContextMouseEvent &mouse); 132 133 // Description: 134 // Mouse wheel event. Zooms in or out. 135 virtual bool MouseWheelEvent(const vtkContextMouseEvent &mouse, int delta); 136 137 // Description: 138 // Key press event. This allows the user to snap the chart to one of three 139 // different 2D views. "x" changes the view so we're looking down the X axis. 140 // Similar behavior occurs for "y" or "z". 141 virtual bool KeyPressEvent(const vtkContextKeyEvent &key); 142 //ETX 143 144 protected: 145 vtkChartXYZ(); 146 ~vtkChartXYZ(); 147 148 // Description: 149 // Calculate the transformation matrices used to draw data points and axes 150 // in the scene. This function also sets up clipping planes that determine 151 // whether or not a data point is within range. 152 virtual void CalculateTransforms(); 153 154 // Description: 155 // Given the x, y and z vtkAxis, and a transform, calculate the transform that 156 // the points in a chart would need to be drawn within the axes. This assumes 157 // that the axes have the correct start and end positions, and that they are 158 // perpendicular. 159 bool CalculatePlotTransform(vtkAxis *x, vtkAxis *y, vtkAxis *z, 160 vtkTransform *transform); 161 162 // Description: 163 // Rotate the chart in response to a mouse movement. 164 bool Rotate(const vtkContextMouseEvent &mouse); 165 166 // Description: 167 // Pan the data within the chart in response to a mouse movement. 168 bool Pan(const vtkContextMouseEvent &mouse); 169 170 // Description: 171 // Zoom in or out on the data in response to a mouse movement. 172 bool Zoom(const vtkContextMouseEvent &mouse); 173 174 // Description: 175 // Spin the chart in response to a mouse movement. 176 bool Spin(const vtkContextMouseEvent &mouse); 177 178 // Description: 179 // Adjust the rotation of the chart so that we are looking down the X axis. 180 void LookDownX(); 181 182 // Description: 183 // Adjust the rotation of the chart so that we are looking down the Y axis. 184 void LookDownY(); 185 186 // Description: 187 // Adjust the rotation of the chart so that we are looking down the Z axis. 188 void LookDownZ(); 189 190 // Description: 191 // Adjust the rotation of the chart so that we are looking up the X axis. 192 void LookUpX(); 193 194 // Description: 195 // Adjust the rotation of the chart so that we are looking up the Y axis. 196 void LookUpY(); 197 198 // Description: 199 // Adjust the rotation of the chart so that we are looking up the Z axis. 200 void LookUpZ(); 201 202 // Description: 203 // Check to see if the scene changed size since the last render. 204 bool CheckForSceneResize(); 205 206 // Description: 207 // Scale the axes up or down in response to a scene resize. 208 void RescaleAxes(); 209 210 // Description: 211 // Scale up the axes when the scene gets larger. 212 void ScaleUpAxes(); 213 214 // Description: 215 // Scale down the axes when the scene gets smaller. 216 void ScaleDownAxes(); 217 218 // Description: 219 // Change the scaling of the axes by a specified amount. 220 void ZoomAxes(int delta); 221 222 // Description: 223 // Initialize a list of "test points". These are used to determine whether 224 // or not the chart fits completely within the bounds of the current scene. 225 void InitializeAxesBoundaryPoints(); 226 227 // Description: 228 // Initialize the "future box" transform. This transform is a duplicate of 229 // the Box transform, which dictates how the chart's axes should be drawn. 230 // In ScaleUpAxes() and ScaleDownAxes(), we incrementally change the scaling 231 // of the FutureBox transform to determine how much we need to zoom in or 232 // zoom out to fit the chart within the newly resized scene. Using a 233 // separate transform for this process allows us to resize the Box in a 234 // single step. 235 void InitializeFutureBox(); 236 237 // Description: 238 // Compute a bounding box for the data that is rendered within the axes. 239 void ComputeDataBounds(); 240 241 // Description: 242 // Draw the cube axes of this chart. 243 void DrawAxes(vtkContext3D *context); 244 245 // Description: 246 // For each of the XYZ dimensions, find the axis line that is furthest 247 // from the rendered data. 248 void DetermineWhichAxesToLabel(); 249 250 // Description: 251 // Draw tick marks and tick mark labels along the axes. 252 void DrawTickMarks(vtkContext2D *painter); 253 254 // Description: 255 // Label the axes. 256 void DrawAxesLabels(vtkContext2D *painter); 257 258 // Description: 259 // Compute how some text should be offset from an axis. The parameter 260 // bounds contains the bounding box of the text to be rendered. The 261 // result is stored in the parameter offset. 262 void GetOffsetForAxisLabel(int axis, float *bounds, float *offset); 263 264 // Description: 265 // Calculate the next "nicest" numbers above and below the current minimum. 266 // \return the "nice" spacing of the numbers. 267 // This function was mostly copied from vtkAxis. 268 double CalculateNiceMinMax(double &min, double &max, int axis); 269 270 // Description: 271 // Get the equation for the ith face of our bounding cube. 272 void GetClippingPlaneEquation(int i, double *planeEquation); 273 274 // Description: 275 // The size and position of this chart. 276 vtkRectf Geometry; 277 278 // Description: 279 // The 3 axes of this chart. 280 std::vector< vtkSmartPointer<vtkAxis> > Axes; 281 282 // Description: 283 // This boolean indicates whether or not we're using this chart to rotate 284 // on a timer. 285 bool AutoRotate; 286 287 // Description: 288 // When we're in AutoRotate mode, this boolean tells us if we should rotate 289 // about the X axis or the Y axis. 290 bool IsX; 291 292 // Description: 293 // When we're in AutoRotate mode, this value tells the chart how much it 294 // should be rotated. 295 double Angle; 296 297 // Description: 298 // This boolean indicates whether or not we should draw tick marks 299 // and axes labels. 300 bool DrawAxesDecoration; 301 302 // Description: 303 // This boolean indicates whether or not we should automatically resize the 304 // chart so that it snugly fills up the scene. 305 bool FitToScene; 306 307 // Description: 308 // This is the transform that is applied when rendering data from the plots. 309 vtkNew<vtkTransform> ContextTransform; 310 311 // Description: 312 // This transform translates and scales the plots' data points so that they 313 // appear within the axes of this chart. It is one of the factors that 314 // makes up the ContextTransform. 315 vtkNew<vtkTransform> PlotTransform; 316 317 // Description: 318 // This is the transform that is applied when rendering data from the plots. 319 vtkNew<vtkTransform> Box; 320 321 // Description: 322 // This transform keeps track of how the chart has been rotated. 323 vtkNew<vtkTransform> Rotation; 324 325 // Description: 326 // This transform keeps track of how the data points have been panned within 327 // the chart. 328 vtkNew<vtkTransform> Translation; 329 330 // Description: 331 // This transform keeps track of how the data points have been scaled 332 // (zoomed in or zoomed out) within the chart. 333 vtkNew<vtkTransform> Scale; 334 335 // Description: 336 // This transform keeps track of how the axes have been scaled 337 // (zoomed in or zoomed out). 338 vtkNew<vtkTransform> BoxScale; 339 340 // Description: 341 // This transform is initialized as a copy of Box. It is used within 342 // ScaleUpAxes() and ScaleDownAxes() to figure out how much we need to 343 // zoom in or zoom out to fit our chart within the newly resized scene. 344 vtkNew<vtkTransform> FutureBox; 345 346 // Description: 347 // This transform keeps track of the Scale of the FutureBox transform. 348 vtkNew<vtkTransform> FutureBoxScale; 349 350 // Description: 351 // This is the pen that is used to draw data from the plots. 352 vtkNew<vtkPen> Pen; 353 354 // Description: 355 // This is the pen that is used to draw the axes. 356 vtkNew<vtkPen> AxisPen; 357 358 // Description: 359 // This link is used to share selected points with other classes. 360 vtkSmartPointer<vtkAnnotationLink> Link; 361 362 // Description: 363 // The plots that are drawn within this chart. 364 std::vector<vtkPlot3D *> Plots; 365 366 // Description: 367 // The label for the X Axis. 368 std::string XAxisLabel; 369 370 // Description: 371 // The label for the Y Axis. 372 std::string YAxisLabel; 373 374 // Description: 375 // The label for the Z Axis. 376 std::string ZAxisLabel; 377 378 // Description: 379 // The six planes that define the bounding cube of our 3D axes. 380 vtkNew<vtkPlaneCollection> BoundingCube; 381 382 // Description: 383 // Points used to determine whether the axes will fit within the scene as 384 // currently sized, regardless of rotation. 385 float AxesBoundaryPoints[14][3]; 386 387 // Description: 388 // This member variable stores the size of the tick labels for each axis. 389 // It is used to determine the position of the axis labels. 390 float TickLabelOffset[3][2]; 391 392 // Description: 393 // The height of the scene, as of the most recent call to Paint(). 394 int SceneHeight; 395 396 // Description: 397 // The weight of the scene, as of the most recent call to Paint(). 398 int SceneWidth; 399 400 // Description: 401 // Which line to label. 402 int XAxisToLabel[3]; 403 int YAxisToLabel[3]; 404 int ZAxisToLabel[3]; 405 406 // Description: 407 // What direction the data is from each labeled axis line. 408 int DirectionToData[3]; 409 410 // Description: 411 // A bounding box surrounding the currently rendered data points. 412 double DataBounds[4]; 413 414 private: 415 vtkChartXYZ(const vtkChartXYZ &); // Not implemented. 416 void operator=(const vtkChartXYZ &); // Not implemented. 417 }; 418 419 #endif 420