1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkMultiVolume.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  * @class vtkMultiVolume
17  * @brief Represents a world axis-aligned bounding-box containing a set of
18  * volumes in a rendered scene.
19  *
20  * vtkVolume instances registered in this class can be overlapping. They are
21  * intended to be all rendered simultaneously by a vtkGPUVolumeRayCastMapper
22  * (inputs should be set directly in the mapper).
23  *
24  * This class holds the full transformation of a bounding-box containing
25  * all of the registered volumes.
26  *
27  *      + TexToBBox : Texture-to-Data (scaling)
28  *      + Matrix : Data-to-World (translation)
29  *
30  * @note This class is intended to be used only by mappers supporting multiple
31  * inputs.
32  *
33  * @sa vtkVolume vtkAbstractVolumeMapper vtkGPUVolumeRayCastMapper
34  */
35 #ifndef vtkMultiVolume_h
36 #define vtkMultiVolume_h
37 #include <array>         // for std::array
38 #include <unordered_map> // For std::unordered_map
39 
40 #include "vtkMatrix4x4.h"             // For Matrix
41 #include "vtkRenderingVolumeModule.h" // For export macro
42 #include "vtkSmartPointer.h"          // For vtkSmartPointer
43 #include "vtkVolume.h"
44 
45 class vtkAbstractVolumeMapper;
46 class vtkBoundingBox;
47 class vtkMatrix4x4;
48 class vtkRenderer;
49 class vtkVolumeProperty;
50 class vtkWindow;
51 class vtkVolumeProperty;
52 class vtkAbstractVolumeMapper;
53 
54 class VTKRENDERINGVOLUME_EXPORT vtkMultiVolume : public vtkVolume
55 {
56 public:
57   static vtkMultiVolume* New();
58   vtkTypeMacro(vtkMultiVolume, vtkVolume);
59   void PrintSelf(ostream& os, vtkIndent indent) override;
60 
61   ///@{
62   /**
63    * Add / Remove a vtkVolume instance.
64    */
65   void SetVolume(vtkVolume* volume, int port = 0);
66   vtkVolume* GetVolume(int port = 0);
RemoveVolume(int port)67   void RemoveVolume(int port) { this->SetVolume(nullptr, port); }
68   ///@}
69 
70   ///@{
71   /**
72    * Given that this class represents a bounding-box only there is no property
73    * directly associated with it (a cannot be set directly).
74    * This instance will return the property of the volume registered in the 0th
75    * port (or nullptr if no volume has been set).
76    * \sa vtkVolume
77    */
78   void SetProperty(vtkVolumeProperty* property) override;
79   vtkVolumeProperty* GetProperty() override;
80   ///@}
81 
82   /**
83    * Computes the bounds of the box containing all of the vtkVolume instances.
84    * Returns the bounds (vtkVolume::Bounds) in world coordinates [xmin, xmax,
85    * ymin, ymax, zmin, zmax] but also keeps cached the bounds in data coordinates
86    * (vtkMultiVolume::DataBounds).
87    */
88   double* GetBounds() override;
89 
90   /**
91    * \sa vtkVolume
92    */
93   vtkMTimeType GetMTime() override;
94 
95   /**
96    * Checks whether the vtkProp passed is another vtkMultiVolume and tries to
97    * copy accordingly. Otherwise it falls back to vtkVolume::ShallowCopy.
98    * \sa vtkVolume
99    */
100   void ShallowCopy(vtkProp* prop) override;
101 
102   /**
103    * As with other vtkProp3D, Matrix holds the transformation from data
104    * coordinates to world coordinates.  Since this class represents an
105    * axis-aligned bounding-box, this transformation only contains a translation
106    * vector. Each registered vtkVolume contains its own transformation with
107    * respect to the world coordinate system.
108    * \sa vtkProp3D vtkVolume
109    */
110   using vtkVolume::GetMatrix;
GetMatrix()111   vtkMatrix4x4* GetMatrix() override { return this->Matrix; }
112 
113   /**
114    * Returns the transformation from texture coordinates to data cooridinates
115    * of the bounding-box. Since this class represents an axis-aligned bounding
116    * -boxThis, this transformation only contains a scaling diagonal.
117    */
GetTextureMatrix()118   vtkMatrix4x4* GetTextureMatrix() { return this->TexToBBox.GetPointer(); }
119 
120   /**
121    * Total bounds in data coordinates.
122    */
GetDataBounds()123   double* GetDataBounds() { return this->DataBounds.data(); }
124 
GetBoundsTime()125   vtkMTimeType GetBoundsTime() { return this->BoundsComputeTime.GetMTime(); }
126 
127   /**
128    * Since vtkMultiVolume acts like a proxy volume to compute the bounding box
129    * for its internal vtkVolume instances, there are no properties to be set directly
130    * in this instance. For that reason, this override ignores the vtkVolumeProperty
131    * check.
132    */
133   int RenderVolumetricGeometry(vtkViewport* vp) override;
134 
135   /**
136    * Return the eight corners of the volume
137    */
GetDataGeometry()138   double* GetDataGeometry() { return this->DataGeometry.data(); }
139 
140 protected:
141   vtkMultiVolume();
142   ~vtkMultiVolume() override;
143 
144   /**
145    * The transformation matrix of this vtkProp3D is not user-definable,
146    * (only the registered vtkVolume instances define the total bounding-box).
147    * For that reason this method does nothing.
148    * \sa vtkProp3D
149    */
ComputeMatrix()150   void ComputeMatrix() override {}
151 
152   /**
153    * Returns the vtkVolume registered in port.
154    */
155   vtkVolume* FindVolume(int port);
156 
157   /**
158    * Checks for changes in the registered vtkVolume instances which could
159    * required the bounding-box to be recomputed.
160    */
161   bool VolumesChanged();
162 
163   /**
164    * For a box defined by bounds in coordinate system X, compute its
165    * axis-aligned bounds in coordinate system Y. T defines the transformation
166    * from X to Y and bounds ([x_min, x_max, y_min, y_max, z_min, z_max])
167    * the box in X.
168    */
169   std::array<double, 6> ComputeAABounds(double bounds[6], vtkMatrix4x4* T) const;
170 
171   std::array<double, 6> DataBounds;
172   std::array<double, 24> DataGeometry;
173   std::unordered_map<int, vtkVolume*> Volumes;
174   vtkTimeStamp BoundsComputeTime;
175   vtkSmartPointer<vtkMatrix4x4> TexToBBox;
176 
177 private:
178   vtkMultiVolume(const vtkMultiVolume&) = delete;
179   void operator=(const vtkMultiVolume&) = delete;
180 };
181 #endif
182