vtkChartXYZ.h 12.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkChartXYZ.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.

=========================================================================*/

16 17 18 19 20 21
/**
 * @class   vtkChartXYZ
 * @brief   Factory class for drawing 3D XYZ charts.
 *
 *
*/
22

23 24
#ifndef vtkChartXYZ_h
#define vtkChartXYZ_h
25

26
#include "vtkChartsCoreModule.h" // For export macro
27
#include "vtkContextItem.h"
28
#include "vtkColor.h"        // For vtkColor4ub
29 30 31
#include "vtkRect.h"         // For vtkRectf ivars
#include "vtkNew.h"          // For ivars
#include "vtkSmartPointer.h" // For ivars
Zack Galbreath's avatar
Zack Galbreath committed
32
#include <vector>            // For ivars
33 34 35

class vtkAnnotationLink;
class vtkAxis;
Zack Galbreath's avatar
Zack Galbreath committed
36 37 38
class vtkContext3D;
class vtkContextMouseEvent;
class vtkPen;
39
class vtkPlaneCollection;
Zack Galbreath's avatar
Zack Galbreath committed
40
class vtkPlot3D;
41 42
class vtkTable;
class vtkTransform;
Zack Galbreath's avatar
Zack Galbreath committed
43
class vtkUnsignedCharArray;
44

45
class VTKCHARTSCORE_EXPORT vtkChartXYZ : public vtkContextItem
46 47 48
{
public:
  vtkTypeMacro(vtkChartXYZ, vtkContextItem);
49
  void PrintSelf(ostream &os, vtkIndent indent) override;
50 51 52

  static vtkChartXYZ * New();

53 54 55 56 57 58
  /**
   * Set the geometry in pixel coordinates (origin and width/height).
   * This method also sets up the end points of the axes of the chart.
   * For this reason, if you call SetAroundX(), you should call SetGeometry()
   * afterwards.
   */
Zack Galbreath's avatar
Zack Galbreath committed
59
  void SetGeometry(const vtkRectf &bounds);
60

61 62 63
  /**
   * Set the rotation angle for the chart (AutoRotate mode only).
   */
Zack Galbreath's avatar
Zack Galbreath committed
64
  void SetAngle(double angle);
65

66 67 68
  /**
   * Set whether or not we're rotating about the X axis.
   */
Zack Galbreath's avatar
Zack Galbreath committed
69
  void SetAroundX(bool isX);
70

71 72 73
  /**
   * Set the vtkAnnotationLink for the chart.
   */
74 75
  virtual void SetAnnotationLink(vtkAnnotationLink *link);

76 77 78
  /**
   * Get the x (0), y (1) or z (2) axis.
   */
79 80
  vtkAxis * GetAxis(int axis);

Peter Franz's avatar
Peter Franz committed
81 82 83 84 85 86 87

  /**
   * Set the x (0), y (1) or z (2) axis.
   */
  virtual void SetAxis(int axisIndex, vtkAxis* axis);


88 89 90 91
  //@{
  /**
   * Set the color for the axes.
   */
92 93
  void SetAxisColor(const vtkColor4ub& color);
  vtkColor4ub GetAxisColor();
94
  //@}
95

96 97 98 99
  /**
   * Set whether or not we're using this chart to rotate on a timer.
   * Default value is false.
   */
Zack Galbreath's avatar
Zack Galbreath committed
100 101
  void SetAutoRotate(bool b);

102 103 104 105
  /**
   * Set whether or not axes labels & tick marks should be drawn.
   * Default value is true.
   */
Zack Galbreath's avatar
Zack Galbreath committed
106 107
  void SetDecorateAxes(bool b);

108 109 110 111
  /**
   * Set whether or not the chart should automatically resize itself to fill
   * the scene.  Default value is true.
   */
Zack Galbreath's avatar
Zack Galbreath committed
112 113
  void SetFitToScene(bool b);

114 115 116
  /**
   * Perform any updates to the item that may be necessary before rendering.
   */
117
  void Update() override;
118

119 120 121
  /**
   * Paint event for the chart, called whenever the chart needs to be drawn.
   */
122
  bool Paint(vtkContext2D *painter) override;
Zack Galbreath's avatar
Zack Galbreath committed
123

124 125 126
  /**
   * Adds a plot to the chart.
   */
Zack Galbreath's avatar
Zack Galbreath committed
127 128
  virtual vtkIdType AddPlot(vtkPlot3D* plot);

129 130 131
  /**
   * Remove all the plots from this chart.
   */
Zack Galbreath's avatar
Zack Galbreath committed
132 133
  void ClearPlots();

134 135 136 137
  /**
   * Determine the XYZ bounds of the plots within this chart.
   * This information is then used to set the range of the axes.
   */
138 139
  void RecalculateBounds();

140 141 142 143 144
  /**
   * Use this chart's Geometry to set the endpoints of its axes.
   * This method also sets up a transformation that is used to
   * properly render the data within the chart.
   */
Zack Galbreath's avatar
Zack Galbreath committed
145
  void RecalculateTransform();
146

147 148 149
  /**
   * Returns true if the transform is interactive, false otherwise.
   */
150
  bool Hit(const vtkContextMouseEvent &mouse) override;
Zack Galbreath's avatar
Zack Galbreath committed
151

152 153 154
  /**
   * Mouse press event. Keep track of zoom anchor position.
   */
155
  bool MouseButtonPressEvent(const vtkContextMouseEvent &mouse) override;
Zack Galbreath's avatar
Zack Galbreath committed
156

157 158 159
  /**
   * Mouse move event. Perform pan or zoom as specified by the mouse bindings.
   */
160
  bool MouseMoveEvent(const vtkContextMouseEvent &mouse) override;
Zack Galbreath's avatar
Zack Galbreath committed
161

162 163 164
  /**
   * Mouse wheel event.  Zooms in or out.
   */
165
  bool MouseWheelEvent(const vtkContextMouseEvent &mouse, int delta) override;
Zack Galbreath's avatar
Zack Galbreath committed
166

167 168 169 170 171
  /**
   * Key press event.  This allows the user to snap the chart to one of three
   * different 2D views.  "x" changes the view so we're looking down the X axis.
   * Similar behavior occurs for "y" or "z".
   */
172
  bool KeyPressEvent(const vtkContextKeyEvent &key) override;
173 174 175

protected:
  vtkChartXYZ();
176
  ~vtkChartXYZ() override;
177

178 179 180 181 182
  /**
   * Calculate the transformation matrices used to draw data points and axes
   * in the scene.  This function also sets up clipping planes that determine
   * whether or not a data point is within range.
   */
Zack Galbreath's avatar
Zack Galbreath committed
183 184
  virtual void CalculateTransforms();

185 186 187 188 189 190
  /**
   * Given the x, y and z vtkAxis, and a transform, calculate the transform that
   * the points in a chart would need to be drawn within the axes. This assumes
   * that the axes have the correct start and end positions, and that they are
   * perpendicular.
   */
191 192 193
  bool CalculatePlotTransform(vtkAxis *x, vtkAxis *y, vtkAxis *z,
                              vtkTransform *transform);

194 195 196
  /**
   * Rotate the chart in response to a mouse movement.
   */
Zack Galbreath's avatar
Zack Galbreath committed
197 198
  bool Rotate(const vtkContextMouseEvent &mouse);

199 200 201
  /**
   * Pan the data within the chart in response to a mouse movement.
   */
Zack Galbreath's avatar
Zack Galbreath committed
202 203
  bool Pan(const vtkContextMouseEvent &mouse);

204 205 206
  /**
   * Zoom in or out on the data in response to a mouse movement.
   */
Zack Galbreath's avatar
Zack Galbreath committed
207
  bool Zoom(const vtkContextMouseEvent &mouse);
Zack Galbreath's avatar
Zack Galbreath committed
208

209 210 211
  /**
   * Spin the chart in response to a mouse movement.
   */
Zack Galbreath's avatar
Zack Galbreath committed
212 213
  bool Spin(const vtkContextMouseEvent &mouse);

214 215 216
  /**
   * Adjust the rotation of the chart so that we are looking down the X axis.
   */
Zack Galbreath's avatar
Zack Galbreath committed
217 218
  void LookDownX();

219 220 221
  /**
   * Adjust the rotation of the chart so that we are looking down the Y axis.
   */
Zack Galbreath's avatar
Zack Galbreath committed
222 223
  void LookDownY();

224 225 226
  /**
   * Adjust the rotation of the chart so that we are looking down the Z axis.
   */
Zack Galbreath's avatar
Zack Galbreath committed
227 228
  void LookDownZ();

229 230 231
  /**
   * Adjust the rotation of the chart so that we are looking up the X axis.
   */
Zack Galbreath's avatar
Zack Galbreath committed
232 233
  void LookUpX();

234 235 236
  /**
   * Adjust the rotation of the chart so that we are looking up the Y axis.
   */
Zack Galbreath's avatar
Zack Galbreath committed
237 238
  void LookUpY();

239 240 241
  /**
   * Adjust the rotation of the chart so that we are looking up the Z axis.
   */
Zack Galbreath's avatar
Zack Galbreath committed
242 243
  void LookUpZ();

244 245 246
  /**
   * Check to see if the scene changed size since the last render.
   */
Zack Galbreath's avatar
Zack Galbreath committed
247 248
  bool CheckForSceneResize();

249 250 251
  /**
   * Scale the axes up or down in response to a scene resize.
   */
Zack Galbreath's avatar
Zack Galbreath committed
252 253
  void RescaleAxes();

254 255 256
  /**
   * Scale up the axes when the scene gets larger.
   */
Zack Galbreath's avatar
Zack Galbreath committed
257 258
  void ScaleUpAxes();

259 260 261
  /**
   * Scale down the axes when the scene gets smaller.
   */
Zack Galbreath's avatar
Zack Galbreath committed
262 263
  void ScaleDownAxes();

264 265 266
  /**
   * Change the scaling of the axes by a specified amount.
   */
Zack Galbreath's avatar
Zack Galbreath committed
267 268
  void ZoomAxes(int delta);

269 270 271 272
  /**
   * Initialize a list of "test points".  These are used to determine whether
   * or not the chart fits completely within the bounds of the current scene.
   */
Zack Galbreath's avatar
Zack Galbreath committed
273 274
  void InitializeAxesBoundaryPoints();

275 276 277 278 279 280 281 282 283
  /**
   * Initialize the "future box" transform.  This transform is a duplicate of
   * the Box transform, which dictates how the chart's axes should be drawn.
   * In ScaleUpAxes() and ScaleDownAxes(), we incrementally change the scaling
   * of the FutureBox transform to determine how much we need to zoom in or
   * zoom out to fit the chart within the newly resized scene.  Using a
   * separate transform for this process allows us to resize the Box in a
   * single step.
   */
Zack Galbreath's avatar
Zack Galbreath committed
284 285
  void InitializeFutureBox();

286 287 288
  /**
   * Compute a bounding box for the data that is rendered within the axes.
   */
Zack Galbreath's avatar
Zack Galbreath committed
289 290
  void ComputeDataBounds();

291 292 293
  /**
   * Draw the cube axes of this chart.
   */
Zack Galbreath's avatar
Zack Galbreath committed
294 295
  void DrawAxes(vtkContext3D *context);

296 297 298 299
  /**
   * For each of the XYZ dimensions, find the axis line that is furthest
   * from the rendered data.
   */
Zack Galbreath's avatar
Zack Galbreath committed
300 301
  void DetermineWhichAxesToLabel();

302 303 304
  /**
   * Draw tick marks and tick mark labels along the axes.
   */
Zack Galbreath's avatar
Zack Galbreath committed
305 306
  void DrawTickMarks(vtkContext2D *painter);

307 308 309
  /**
   * Label the axes.
   */
Zack Galbreath's avatar
Zack Galbreath committed
310 311
  void DrawAxesLabels(vtkContext2D *painter);

312 313 314 315 316
  /**
   * Compute how some text should be offset from an axis.  The parameter
   * bounds contains the bounding box of the text to be rendered.  The
   * result is stored in the parameter offset.
   */
Zack Galbreath's avatar
Zack Galbreath committed
317 318
  void GetOffsetForAxisLabel(int axis, float *bounds, float *offset);

319 320 321 322 323
  /**
   * Calculate the next "nicest" numbers above and below the current minimum.
   * \return the "nice" spacing of the numbers.
   * This function was mostly copied from vtkAxis.
   */
Zack Galbreath's avatar
Zack Galbreath committed
324 325
  double CalculateNiceMinMax(double &min, double &max, int axis);

326 327 328
  /**
   * Get the equation for the ith face of our bounding cube.
   */
329 330
  void GetClippingPlaneEquation(int i, double *planeEquation);

331 332 333
  /**
   * The size and position of this chart.
   */
334 335
  vtkRectf Geometry;

336 337 338
  /**
   * The 3 axes of this chart.
   */
339
  std::vector< vtkSmartPointer<vtkAxis> > Axes;
Zack Galbreath's avatar
Zack Galbreath committed
340

341 342 343 344
  /**
   * This boolean indicates whether or not we're using this chart to rotate
   * on a timer.
   */
Zack Galbreath's avatar
Zack Galbreath committed
345 346
  bool AutoRotate;

347 348 349 350
  /**
   * When we're in AutoRotate mode, this boolean tells us if we should rotate
   * about the X axis or the Y axis.
   */
Zack Galbreath's avatar
Zack Galbreath committed
351 352
  bool IsX;

353 354 355 356
  /**
   * When we're in AutoRotate mode, this value tells the chart how much it
   * should be rotated.
   */
Zack Galbreath's avatar
Zack Galbreath committed
357 358
  double Angle;

359 360 361 362
  /**
   * This boolean indicates whether or not we should draw tick marks
   * and axes labels.
   */
Zack Galbreath's avatar
Zack Galbreath committed
363 364
  bool DrawAxesDecoration;

365 366 367 368
  /**
   * This boolean indicates whether or not we should automatically resize the
   * chart so that it snugly fills up the scene.
   */
Zack Galbreath's avatar
Zack Galbreath committed
369 370
  bool FitToScene;

371 372 373
  /**
   * This is the transform that is applied when rendering data from the plots.
   */
Zack Galbreath's avatar
Zack Galbreath committed
374 375
  vtkNew<vtkTransform> ContextTransform;

376 377 378 379 380
  /**
   * This transform translates and scales the plots' data points so that they
   * appear within the axes of this chart.  It is one of the factors that
   * makes up the ContextTransform.
   */
Zack Galbreath's avatar
Zack Galbreath committed
381 382
  vtkNew<vtkTransform> PlotTransform;

383 384 385
  /**
   * This is the transform that is applied when rendering data from the plots.
   */
Zack Galbreath's avatar
Zack Galbreath committed
386 387
  vtkNew<vtkTransform> Box;

388 389 390
  /**
   * This transform keeps track of how the chart has been rotated.
   */
Zack Galbreath's avatar
Zack Galbreath committed
391 392
  vtkNew<vtkTransform> Rotation;

393 394 395 396
  /**
   * This transform keeps track of how the data points have been panned within
   * the chart.
   */
Zack Galbreath's avatar
Zack Galbreath committed
397 398
  vtkNew<vtkTransform> Translation;

399 400 401 402
  /**
   * This transform keeps track of how the data points have been scaled
   * (zoomed in or zoomed out) within the chart.
   */
Zack Galbreath's avatar
Zack Galbreath committed
403 404
  vtkNew<vtkTransform> Scale;

405 406 407 408
  /**
   * This transform keeps track of how the axes have been scaled
   * (zoomed in or zoomed out).
   */
Zack Galbreath's avatar
Zack Galbreath committed
409 410
  vtkNew<vtkTransform> BoxScale;

411 412 413 414 415
  /**
   * This transform is initialized as a copy of Box.  It is used within
   * ScaleUpAxes() and ScaleDownAxes() to figure out how much we need to
   * zoom in or zoom out to fit our chart within the newly resized scene.
   */
Zack Galbreath's avatar
Zack Galbreath committed
416 417
  vtkNew<vtkTransform> FutureBox;

418 419 420
  /**
   * This transform keeps track of the Scale of the FutureBox transform.
   */
Zack Galbreath's avatar
Zack Galbreath committed
421 422
  vtkNew<vtkTransform> FutureBoxScale;

423 424 425
  /**
   * This is the pen that is used to draw data from the plots.
   */
426
  vtkNew<vtkPen> Pen;
Zack Galbreath's avatar
Zack Galbreath committed
427

428 429 430
  /**
   * This is the pen that is used to draw the axes.
   */
431
  vtkNew<vtkPen> AxisPen;
Zack Galbreath's avatar
Zack Galbreath committed
432

433 434 435
  /**
   * This link is used to share selected points with other classes.
   */
436
  vtkSmartPointer<vtkAnnotationLink> Link;
437

438 439 440
  /**
   * The plots that are drawn within this chart.
   */
441
  std::vector<vtkPlot3D *> Plots;
Zack Galbreath's avatar
Zack Galbreath committed
442

443 444 445
  /**
   * The label for the X Axis.
   */
Zack Galbreath's avatar
Zack Galbreath committed
446
  std::string XAxisLabel;
Zack Galbreath's avatar
Zack Galbreath committed
447

448 449 450
  /**
   * The label for the Y Axis.
   */
Zack Galbreath's avatar
Zack Galbreath committed
451 452
  std::string YAxisLabel;

453 454 455
  /**
   * The label for the Z Axis.
   */
Zack Galbreath's avatar
Zack Galbreath committed
456 457
  std::string ZAxisLabel;

458 459 460
  /**
   * The six planes that define the bounding cube of our 3D axes.
   */
461
  vtkNew<vtkPlaneCollection> BoundingCube;
Zack Galbreath's avatar
Zack Galbreath committed
462

463 464 465 466
  /**
   * Points used to determine whether the axes will fit within the scene as
   * currently sized, regardless of rotation.
   */
Zack Galbreath's avatar
Zack Galbreath committed
467 468
  float AxesBoundaryPoints[14][3];

469 470 471 472
  /**
   * This member variable stores the size of the tick labels for each axis.
   * It is used to determine the position of the axis labels.
   */
Zack Galbreath's avatar
Zack Galbreath committed
473 474
  float TickLabelOffset[3][2];

475 476 477
  /**
   * The height of the scene, as of the most recent call to Paint().
   */
Zack Galbreath's avatar
Zack Galbreath committed
478 479
  int SceneHeight;

480 481 482
  /**
   * The weight of the scene, as of the most recent call to Paint().
   */
Zack Galbreath's avatar
Zack Galbreath committed
483 484
  int SceneWidth;

485 486 487 488
  //@{
  /**
   * Which line to label.
   */
Zack Galbreath's avatar
Zack Galbreath committed
489 490 491
  int XAxisToLabel[3];
  int YAxisToLabel[3];
  int ZAxisToLabel[3];
492
  //@}
Zack Galbreath's avatar
Zack Galbreath committed
493

494 495 496
  /**
   * What direction the data is from each labeled axis line.
   */
Zack Galbreath's avatar
Zack Galbreath committed
497 498
  int DirectionToData[3];

499 500 501
  /**
   * A bounding box surrounding the currently rendered data points.
   */
Zack Galbreath's avatar
Zack Galbreath committed
502
  double DataBounds[4];
503

504
private:
505 506
  vtkChartXYZ(const vtkChartXYZ &) = delete;
  void operator=(const vtkChartXYZ &) = delete;
507 508 509
};

#endif