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

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

=========================================================================*/
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
/**
 * @class   vtkUnstructuredGridVolumeZSweepMapper
 * @brief   Unstructured grid volume mapper based the ZSweep Algorithm
 *
 *
 * This is a volume mapper for unstructured grid implemented with the ZSweep
 * algorithm. This is a software projective method.
 *
 * @sa
 * vtkVolumetMapper
 *
 * @par Background:
 * The algorithm is described in the following paper:
 * Ricardo Farias, Joseph S. B. Mitchell and Claudio T. Silva.
 * ZSWEEP: An Efficient and Exact Projection Algorithm for Unstructured Volume
 * Rendering. In 2000 Volume Visualization Symposium, pages 91--99.
 * October 2000.
 * http://www.cse.ogi.edu/~csilva/papers/volvis2000.pdf
*/
34

35 36
#ifndef vtkUnstructuredGridVolumeZSweepMapper_h
#define vtkUnstructuredGridVolumeZSweepMapper_h
37

38
#include "vtkRenderingVolumeModule.h" // For export macro
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
#include "vtkUnstructuredGridVolumeMapper.h"

class vtkRenderer;
class vtkVolume;
class vtkRayCastImageDisplayHelper;
class vtkCell;
class vtkGenericCell;
class vtkIdList;
class vtkPriorityQueue;
class vtkTransform;
class vtkMatrix4x4;
class vtkVolumeProperty;
class vtkDoubleArray;
class vtkUnstructuredGridVolumeRayIntegrator;
class vtkRenderWindow;

// Internal classes
56 57 58 59 60 61 62 63 64 65 66 67
namespace vtkUnstructuredGridVolumeZSweepMapperNamespace
{
  class vtkScreenEdge;
  class vtkSpan;
  class vtkPixelListFrame;
  class vtkUseSet;
  class vtkVertices;
  class vtkSimpleScreenEdge;
  class vtkDoubleScreenEdge;
  class vtkVertexEntry;
  class vtkPixelListEntryMemory;
};
68

69
class VTKRENDERINGVOLUME_EXPORT vtkUnstructuredGridVolumeZSweepMapper : public vtkUnstructuredGridVolumeMapper
70 71
{
public:
72
  vtkTypeMacro(vtkUnstructuredGridVolumeZSweepMapper,vtkUnstructuredGridVolumeMapper);
73
  void PrintSelf( ostream& os, vtkIndent indent ) override;
74

75 76 77
  /**
   * Set MaxPixelListSize to 32.
   */
78
  static vtkUnstructuredGridVolumeZSweepMapper *New();
79

80 81 82 83 84 85
  //@{
  /**
   * Sampling distance in the XY image dimensions. Default value of 1 meaning
   * 1 ray cast per pixel. If set to 0.5, 4 rays will be cast per pixel. If
   * set to 2.0, 1 ray will be cast for every 4 (2 by 2) pixels.
   */
86 87
  vtkSetClampMacro( ImageSampleDistance, float, 0.1f, 100.0f );
  vtkGetMacro( ImageSampleDistance, float );
88
  //@}
89

90 91 92 93 94
  //@{
  /**
   * This is the minimum image sample distance allow when the image
   * sample distance is being automatically adjusted
   */
95 96
  vtkSetClampMacro( MinimumImageSampleDistance, float, 0.1f, 100.0f );
  vtkGetMacro( MinimumImageSampleDistance, float );
97
  //@}
98

99 100 101 102 103
  //@{
  /**
   * This is the maximum image sample distance allow when the image
   * sample distance is being automatically adjusted
   */
104 105
  vtkSetClampMacro( MaximumImageSampleDistance, float, 0.1f, 100.0f );
  vtkGetMacro( MaximumImageSampleDistance, float );
106 107 108 109
  //@}

  //@{
  /**
luz.paz's avatar
luz.paz committed
110
   * If AutoAdjustSampleDistances is on, the ImageSampleDistance
111 112 113 114
   * will be varied to achieve the allocated render time of this
   * prop (controlled by the desired update rate and any culling in
   * use).
   */
115 116 117
  vtkSetClampMacro( AutoAdjustSampleDistances, vtkTypeBool, 0, 1 );
  vtkGetMacro( AutoAdjustSampleDistances, vtkTypeBool );
  vtkBooleanMacro( AutoAdjustSampleDistances, vtkTypeBool );
118
  //@}
119

120 121 122 123 124
  //@{
  /**
   * If IntermixIntersectingGeometry is turned on, the zbuffer will be
   * captured and used to limit the traversal of the rays.
   */
125 126 127
  vtkSetClampMacro( IntermixIntersectingGeometry, vtkTypeBool, 0, 1 );
  vtkGetMacro( IntermixIntersectingGeometry, vtkTypeBool );
  vtkBooleanMacro( IntermixIntersectingGeometry, vtkTypeBool );
128 129 130 131 132 133 134 135
  //@}

  /**
   * Maximum size allowed for a pixel list. Default is 32.
   * During the rendering, if a list of pixel is full, incremental compositing
   * is performed. Even if it is a user setting, it is an advanced parameter.
   * You have to understand how the algorithm works to change this value.
   */
136
  int GetMaxPixelListSize();
137

138 139 140 141 142
  /**
   * Change the maximum size allowed for a pixel list. It is an advanced
   * parameter.
   * \pre positive_size: size>1
   */
143
  void SetMaxPixelListSize(int size);
144

145 146 147 148 149
  //@{
  /**
   * Set/Get the helper class for integrating rays.  If set to NULL, a
   * default integrator will be assigned.
   */
150 151
  virtual void SetRayIntegrator(vtkUnstructuredGridVolumeRayIntegrator *ri);
  vtkGetObjectMacro(RayIntegrator, vtkUnstructuredGridVolumeRayIntegrator);
152
  //@}
153

154 155 156 157 158
  /**
   * WARNING: INTERNAL METHOD - NOT INTENDED FOR GENERAL USE
   * DO NOT USE THIS METHOD OUTSIDE OF THE RENDERING PROCESS
   * Render the volume
   */
159
  void Render(vtkRenderer *ren,
160
              vtkVolume *vol) override;
161

162 163 164
  vtkGetVectorMacro( ImageInUseSize, int, 2 );
  vtkGetVectorMacro( ImageOrigin, int, 2 );
  vtkGetVectorMacro( ImageViewportSize, int , 2 );
165

166 167
protected:
  vtkUnstructuredGridVolumeZSweepMapper();
168
  ~vtkUnstructuredGridVolumeZSweepMapper() override;
169

170 171 172
  /**
   * For each vertex, find the list of incident faces.
   */
173
  void BuildUseSets();
174

175 176 177 178
  /**
   * Reorder vertices `v' in increasing order in `w'. Return if the orientation
   * has changed.
   */
179 180
  int ReorderTriangle(vtkIdType v[3],
                      vtkIdType w[3]);
181

182 183 184 185 186
  /**
   * Project and sort the vertices by z-coordinates in view space in the
   * "event list" (an heap).
   * \pre empty_list: this->EventList->GetNumberOfItems()==0
   */
187 188
  void ProjectAndSortVertices(vtkRenderer *ren,
                              vtkVolume *vol);
189

190 191 192
  /**
   * Create an empty "pixel list" for each pixel of the screen.
   */
193
  void CreateAndCleanPixelList();
194

195 196 197 198
  /**
   * MainLoop of the Zsweep algorithm.
   * \post empty_list: this->EventList->GetNumberOfItems()==0
   */
199
  void MainLoop(vtkRenderWindow *renWin);
200

201 202 203 204
  /**
   * Do delayed compositing from back to front, stopping at zTarget for each
   * pixel inside the bounding box.
   */
205
  void CompositeFunction(double zTarget);
206

207 208 209
  /**
   * Convert and clamp a float color component into a unsigned char.
   */
210
  unsigned char ColorComponentRealToByte(float color);
211

212 213 214
  /**
   * Perform scan conversion of a triangle face.
   */
215
  void RasterizeFace(vtkIdType faceIds[3], int externalSide);
216

217 218 219 220 221 222
  /**
   * Perform scan conversion of a triangle defined by its vertices.
   * \pre ve0_exists: ve0!=0
   * \pre ve1_exists: ve1!=0
   * \pre ve2_exists: ve2!=0
   */
223
  void RasterizeTriangle(
224 225 226 227
            vtkUnstructuredGridVolumeZSweepMapperNamespace::vtkVertexEntry *ve0,
            vtkUnstructuredGridVolumeZSweepMapperNamespace::vtkVertexEntry *ve1,
            vtkUnstructuredGridVolumeZSweepMapperNamespace::vtkVertexEntry *ve2,
            bool exitFace);
228

229 230 231 232 233 234
  /**
   * Perform scan conversion of an horizontal span from left ro right at line
   * y.
   * \pre left_exists: left!=0
   * \pre right_exists: right!=0
   */
235
  void RasterizeSpan(int y,
236 237 238
           vtkUnstructuredGridVolumeZSweepMapperNamespace::vtkScreenEdge *left,
           vtkUnstructuredGridVolumeZSweepMapperNamespace::vtkScreenEdge *right,
           bool exitFace);
239

240 241 242 243 244 245
  /**
   * Scan conversion of a straight line defined by endpoints v0 and v1.
   * \pre v0_exists: v0!=0
   * \pre v1_exists: v1!=0
   * \pre y_ordered v0->GetScreenY()<=v1->GetScreenY()
   */
246
  void RasterizeLine(
247 248 249
             vtkUnstructuredGridVolumeZSweepMapperNamespace::vtkVertexEntry *v0,
             vtkUnstructuredGridVolumeZSweepMapperNamespace::vtkVertexEntry *v1,
             bool exitFace);
250

251 252 253
  void StoreRenderTime(vtkRenderer *ren,
                       vtkVolume *vol,
                       float t);
254

255 256
  float RetrieveRenderTime(vtkRenderer *ren,
                           vtkVolume *vol);
257

258 259 260
  /**
   * Return the value of the z-buffer at screen coordinates (x,y).
   */
261 262
  double GetZBufferValue(int x,
                         int y);
263

264 265
  double GetMinimumBoundsDepth(vtkRenderer *ren,
                               vtkVolume *vol);
266

267 268 269 270
  /**
   * Allocate an array of usesets of size `size' only if the current one is not
   * large enough. Otherwise clear each use set of each vertex.
   */
271
  void AllocateUseSet(vtkIdType size);
272

273 274 275 276
  /**
   * Allocate a vertex array of size `size' only if the current one is not
   * large enough.
   */
277
  void AllocateVertices(vtkIdType size);
278

279 280 281
  /**
   * For debugging purpose, save the pixel list frame as a dataset.
   */
282
  void SavePixelListFrame();
283

284
  int MaxPixelListSize;
285

286 287 288
  float ImageSampleDistance;
  float MinimumImageSampleDistance;
  float MaximumImageSampleDistance;
289
  vtkTypeBool AutoAdjustSampleDistances;
290

291
  vtkRayCastImageDisplayHelper *ImageDisplayHelper;
292

293 294
  // This is how big the image would be if it covered the entire viewport
  int ImageViewportSize[2];
295

296
  // This is how big the allocated memory for image is. This may be bigger
297
  // or smaller than ImageFullSize - it will be bigger if necessary to
298 299 300
  // ensure a power of 2, it will be smaller if the volume only covers a
  // small region of the viewport
  int ImageMemorySize[2];
301

302 303 304 305 306
  // This is the size of subregion in ImageSize image that we are using for
  // the current image. Since ImageSize is a power of 2, there is likely
  // wasted space in it. This number will be used for things such as clearing
  // the image if necessary.
  int ImageInUseSize[2];
307

308 309 310
  // This is the location in ImageFullSize image where our ImageSize image
  // is located.
  int ImageOrigin[2];
311

312 313
  // This is the allocated image
  unsigned char *Image;
314

315 316
  // This is the accumulating double RGBA image
  float *RealRGBAImage;
317

318 319 320 321 322
  float *RenderTimeTable;
  vtkVolume **RenderVolumeTable;
  vtkRenderer **RenderRendererTable;
  int RenderTableSize;
  int RenderTableEntries;
323

324
  vtkTypeBool IntermixIntersectingGeometry;
325 326 327 328

  float *ZBuffer;
  int ZBufferSize[2];
  int ZBufferOrigin[2];
329

330 331
  vtkDataArray *Scalars;
  int CellScalars;
332

333 334 335 336 337
  // if use CellScalars, we need to keep track of the
  // values on each side of the face and figure out
  // if the face is used by two cells (twosided) or one cell.
  double FaceScalars[2];
  int FaceSide;
338 339 340

  vtkUnstructuredGridVolumeZSweepMapperNamespace::vtkSpan *Span;
  vtkUnstructuredGridVolumeZSweepMapperNamespace::vtkPixelListFrame *PixelListFrame;
341

342 343
  // Used by BuildUseSets().
  vtkGenericCell *Cell;
344

345
  vtkUnstructuredGridVolumeZSweepMapperNamespace::vtkUseSet *UseSet;
346

347
  vtkPriorityQueue *EventList;
348
  vtkUnstructuredGridVolumeZSweepMapperNamespace::vtkVertices *Vertices;
349

350 351
  vtkTransform *PerspectiveTransform;
  vtkMatrix4x4 *PerspectiveMatrix;
352

353 354 355 356
  // Used by the main loop
  int MaxPixelListSizeReached;
  int XBounds[2];
  int YBounds[2];
357

358 359
  vtkUnstructuredGridVolumeZSweepMapperNamespace::vtkSimpleScreenEdge *SimpleEdge;
  vtkUnstructuredGridVolumeZSweepMapperNamespace::vtkDoubleScreenEdge *DoubleEdge;
360

361 362
  vtkUnstructuredGridVolumeRayIntegrator *RayIntegrator;
  vtkUnstructuredGridVolumeRayIntegrator *RealRayIntegrator;
363

364
  vtkTimeStamp SavedTriangleListMTime;
365

366 367 368 369
  // Used during compositing
  vtkDoubleArray *IntersectionLengths;
  vtkDoubleArray *NearIntersections;
  vtkDoubleArray *FarIntersections;
370

371 372
  // Benchmark
  vtkIdType MaxRecordedPixelListSize;
373

374

375
  vtkUnstructuredGridVolumeZSweepMapperNamespace::vtkPixelListEntryMemory *MemoryManager;
376

377
private:
378 379
  vtkUnstructuredGridVolumeZSweepMapper(const vtkUnstructuredGridVolumeZSweepMapper&) = delete;
  void operator=(const vtkUnstructuredGridVolumeZSweepMapper&) = delete;
380 381 382
};

#endif