13 #include "vtkMitkVolumeTextureMapper3D.h" 16 #define GPU_INFO MITK_INFO("mapper.vr") 17 #define GPU_WARN MITK_WARN("mapper.vr") 19 #include "vtkCamera.h" 20 #include "vtkColorTransferFunction.h" 21 #include "vtkDataArray.h" 22 #include "vtkImageData.h" 24 #include "vtkMatrix4x4.h" 25 #include "vtkPiecewiseFunction.h" 26 #include "vtkPointData.h" 27 #include "vtkRenderer.h" 28 #include "vtkVolume.h" 29 #include "vtkVolumeProperty.h" 38 vtkMitkVolumeTextureMapper3D::vtkMitkVolumeTextureMapper3D()
42 this->PolygonBuffer =
nullptr;
43 this->IntersectionBuffer =
nullptr;
44 this->NumberOfPolygons = 0;
48 this->SavedTextureInput =
nullptr;
51 this->SavedParametersInput =
nullptr;
53 this->SavedRGBFunction =
nullptr;
54 this->SavedGrayFunction =
nullptr;
55 this->SavedScalarOpacityFunction =
nullptr;
56 this->SavedGradientOpacityFunction =
nullptr;
57 this->SavedColorChannels = 0;
58 this->SavedSampleDistance = 0;
59 this->SavedScalarOpacityDistance = 0;
71 this->VolumeSpacing[0] = this->VolumeSpacing[1] = this->VolumeSpacing[2] = 0;
72 this->VolumeDimensions[0] = 0;
73 this->VolumeDimensions[1] = 0;
74 this->VolumeDimensions[2] = 0;
76 this->SampleDistance = 1.0;
77 this->ActualSampleDistance = 1.0;
79 this->UseCompressedTexture =
false;
80 this->SupportsNonPowerOfTwoTextures =
false;
86 vtkMitkVolumeTextureMapper3D::~vtkMitkVolumeTextureMapper3D()
90 delete[] this->PolygonBuffer;
91 delete[] this->IntersectionBuffer;
111 void vtkMitkVolumeTextureMapper3D::ComputePolygons(vtkRenderer *ren, vtkVolume *vol,
double inBounds[6])
116 double focalPoint[4], position[4];
118 vtkCamera *camera = ren->GetActiveCamera();
120 camera->GetPosition(position);
121 camera->GetFocalPoint(focalPoint);
133 vtkMatrix4x4 *matrix = vtkMatrix4x4::New();
134 vol->GetMatrix(matrix);
136 matrix->MultiplyPoint(position, position);
137 matrix->MultiplyPoint(focalPoint, focalPoint);
142 position[0] /= position[3];
143 position[1] /= position[3];
144 position[2] /= position[3];
149 focalPoint[0] /= focalPoint[3];
150 focalPoint[1] /= focalPoint[3];
151 focalPoint[2] /= focalPoint[3];
155 plane[0] = focalPoint[0] - position[0];
156 plane[1] = focalPoint[1] - position[1];
157 plane[2] = focalPoint[2] - position[2];
161 plane[3] = -(plane[0] * position[0] + plane[1] * position[1] + plane[2] * position[2]);
164 double minDistance = VTK_DOUBLE_MAX;
165 double maxDistance = VTK_DOUBLE_MIN;
171 this->GetInput()->GetBounds(volBounds);
174 bounds[0] = (inBounds[0] > volBounds[0]) ? (inBounds[0]) : (volBounds[0]);
175 bounds[1] = (inBounds[1] < volBounds[1]) ? (inBounds[1]) : (volBounds[1]);
176 bounds[2] = (inBounds[2] > volBounds[2]) ? (inBounds[2]) : (volBounds[2]);
177 bounds[3] = (inBounds[3] < volBounds[3]) ? (inBounds[3]) : (volBounds[3]);
178 bounds[4] = (inBounds[4] > volBounds[4]) ? (inBounds[4]) : (volBounds[4]);
179 bounds[5] = (inBounds[5] < volBounds[5]) ? (inBounds[5]) : (volBounds[5]);
183 double vertices[8][3];
187 for (k = 0; k < 2; k++)
189 for (j = 0; j < 2; j++)
191 for (i = 0; i < 2; i++)
193 vertices[idx][2] = bounds[4 +
k];
194 vertices[idx][1] = bounds[2 + j];
195 vertices[idx][0] = bounds[i];
197 double d = plane[0] * vertices[idx][0] + plane[1] * vertices[idx][1] + plane[2] * vertices[idx][2] + plane[3];
202 minDistance = (d < minDistance) ? (d) : (minDistance);
203 maxDistance = (d > maxDistance) ? (d) : (maxDistance);
209 this->GetVolumeDimensions(dim);
211 float tCoordOffset[3], tCoordScale[3];
213 tCoordOffset[0] = 0.5 / dim[0];
214 tCoordOffset[1] = 0.5 / dim[1];
215 tCoordOffset[2] = 0.5 / dim[2];
217 tCoordScale[0] = (dim[0] - 1) / static_cast<float>(dim[0]);
218 tCoordScale[1] = (dim[1] - 1) / static_cast<float>(dim[1]);
219 tCoordScale[2] = (dim[2] - 1) / static_cast<float>(dim[2]);
222 this->GetVolumeSpacing(spacing);
224 double offset = 0.333 * 0.5 * (spacing[0] + spacing[1] + spacing[2]);
226 minDistance += 0.1 *
offset;
227 maxDistance -= 0.1 *
offset;
229 minDistance = (minDistance <
offset) ? (offset) : (minDistance);
231 double stepSize = this->ActualSampleDistance;
234 int numPolys =
static_cast<int>((maxDistance - minDistance) / static_cast<double>(stepSize));
237 if (this->BufferSize < numPolys)
239 delete[] this->PolygonBuffer;
240 delete[] this->IntersectionBuffer;
242 this->BufferSize = numPolys;
244 this->PolygonBuffer =
new float[36 * this->BufferSize];
245 this->IntersectionBuffer =
new float[12 * this->BufferSize];
248 this->NumberOfPolygons = numPolys;
251 int lines[12][2] = {{0, 1}, {1, 3}, {2, 3}, {0, 2}, {4, 5}, {5, 7}, {6, 7}, {4, 6}, {0, 4}, {1, 5}, {3, 7}, {2, 6}};
255 for (i = 0; i < 12; i++)
259 line[0] = vertices[lines[i][1]][0] - vertices[lines[i][0]][0];
260 line[1] = vertices[lines[i][1]][1] - vertices[lines[i][0]][1];
261 line[2] = vertices[lines[i][1]][2] - vertices[lines[i][0]][2];
263 double d = maxDistance;
265 iptr = this->IntersectionBuffer + i;
267 double planeDotLineOrigin = vtkMath::Dot(plane, vertices[lines[i][0]]);
268 double planeDotLine = vtkMath::Dot(plane, line);
272 if (planeDotLine != 0.0)
274 t = (d - planeDotLineOrigin - plane[3]) / planeDotLine;
275 increment = -stepSize / planeDotLine;
283 for (j = 0; j < numPolys; j++)
285 *iptr = (t > 0.0 && t < 1.0) ? (t) : (-1.0);
293 int neighborLines[12][6] = {{1, 2, 3, 4, 8, 9},
295 {0, 1, 3, 6, 10, 11},
299 {2, 4, 5, 7, 10, 11},
304 {2, 3, 6, 7, 8, 10}};
306 float tCoord[12][4] = {{0, 0, 0, 0},
322 low[0] = (bounds[0] - volBounds[0]) / (volBounds[1] - volBounds[0]);
323 high[0] = (bounds[1] - volBounds[0]) / (volBounds[1] - volBounds[0]);
324 low[1] = (bounds[2] - volBounds[2]) / (volBounds[3] - volBounds[2]);
325 high[1] = (bounds[3] - volBounds[2]) / (volBounds[3] - volBounds[2]);
326 low[2] = (bounds[4] - volBounds[4]) / (volBounds[5] - volBounds[4]);
327 high[2] = (bounds[5] - volBounds[4]) / (volBounds[5] - volBounds[4]);
329 for (i = 0; i < 12; i++)
331 tCoord[i][0] = (tCoord[i][0]) ? (high[0]) : (low[0]);
332 tCoord[i][1] = (tCoord[i][1]) ? (high[1]) : (low[1]);
333 tCoord[i][2] = (tCoord[i][2]) ? (high[2]) : (low[2]);
336 iptr = this->IntersectionBuffer;
337 pptr = this->PolygonBuffer;
339 for (i = 0; i < numPolys; i++)
344 while (start < 12 && iptr[start] == -1.0)
361 while (idx < 6 && !errFlag && (idx == 0 || current != start))
363 double t = iptr[current];
365 *(pptr + idx * 6) = tCoord[current][0] * tCoordScale[0] + tCoordOffset[0];
366 *(pptr + idx * 6 + 1) = tCoord[current][1] * tCoordScale[1] + tCoordOffset[1];
367 *(pptr + idx * 6 + 2) = tCoord[current][2] * tCoordScale[2] + tCoordOffset[2];
369 int coord =
static_cast<int>(tCoord[current][3]);
370 *(pptr + idx * 6 + coord) =
371 (low[coord] + t * (high[coord] - low[coord])) * tCoordScale[coord] + tCoordOffset[coord];
373 *(pptr + idx * 6 + 3) = static_cast<float>(
374 vertices[lines[current][0]][0] + t * (vertices[lines[current][1]][0] - vertices[lines[current][0]][0]));
376 *(pptr + idx * 6 + 4) = static_cast<float>(
377 vertices[lines[current][0]][1] + t * (vertices[lines[current][1]][1] - vertices[lines[current][0]][1]));
379 *(pptr + idx * 6 + 5) = static_cast<float>(
380 vertices[lines[current][0]][2] + t * (vertices[lines[current][1]][2] - vertices[lines[current][0]][2]));
386 while (j < 6 && (*(this->IntersectionBuffer + i * 12 + neighborLines[current][j]) < 0 ||
387 neighborLines[current][j] == previous))
399 current = neighborLines[current][j];
405 *(pptr + idx * 6) = -1;
414 void vtkMitkVolumeTextureMapper3D::UpdateMTime()
416 this->SavedTextureMTime.Modified();
420 int vtkMitkVolumeTextureMapper3D::UpdateColorLookup(vtkVolume *vol)
424 int needToUpdate = 0;
427 vtkImageData *input = this->GetInput();
431 if (this->SavedParametersInput != input || this->SavedParametersMTime.GetMTime() < input->GetMTime())
440 this->ActualSampleDistance = this->SampleDistance;
441 if (vol->GetAllocatedRenderTime() < 1.0)
444 this->GetVolumeSpacing(spacing);
445 this->ActualSampleDistance =
446 0.333 * (
static_cast<double>(spacing[0]) + static_cast<double>(spacing[1]) +
static_cast<double>(spacing[2]));
450 int components = input->GetNumberOfScalarComponents();
453 if (this->SavedSampleDistance != this->ActualSampleDistance)
458 vtkColorTransferFunction *rgbFunc =
nullptr;
459 vtkPiecewiseFunction *grayFunc =
nullptr;
462 int colorChannels = vol->GetProperty()->GetColorChannels(0);
467 if (this->SavedColorChannels != colorChannels)
474 if (colorChannels == 3)
476 rgbFunc = vol->GetProperty()->GetRGBTransferFunction(0);
477 if (this->SavedRGBFunction != rgbFunc || this->SavedParametersMTime.GetMTime() < rgbFunc->GetMTime())
485 if (colorChannels == 1)
487 grayFunc = vol->GetProperty()->GetGrayTransferFunction(0);
488 if (this->SavedGrayFunction != grayFunc || this->SavedParametersMTime.GetMTime() < grayFunc->GetMTime())
496 vtkPiecewiseFunction *scalarOpacityFunc = vol->GetProperty()->GetScalarOpacity(0);
497 if (this->SavedScalarOpacityFunction != scalarOpacityFunc ||
498 this->SavedParametersMTime.GetMTime() < scalarOpacityFunc->GetMTime())
504 vtkPiecewiseFunction *gradientOpacityFunc = vol->GetProperty()->GetGradientOpacity(0);
505 if (this->SavedGradientOpacityFunction != gradientOpacityFunc ||
506 this->SavedParametersMTime.GetMTime() < gradientOpacityFunc->GetMTime())
511 double scalarOpacityDistance = vol->GetProperty()->GetScalarOpacityUnitDistance(0);
512 if (this->SavedScalarOpacityDistance != scalarOpacityDistance)
523 this->SavedRGBFunction = rgbFunc;
524 this->SavedGrayFunction = grayFunc;
525 this->SavedScalarOpacityFunction = scalarOpacityFunc;
526 this->SavedGradientOpacityFunction = gradientOpacityFunc;
527 this->SavedColorChannels = colorChannels;
528 this->SavedSampleDistance = this->ActualSampleDistance;
529 this->SavedScalarOpacityDistance = scalarOpacityDistance;
530 this->SavedParametersInput = input;
532 this->SavedParametersMTime.Modified();
535 double scalarRange[2];
536 input->GetPointData()->GetScalars()->GetRange(scalarRange, components - 1);
538 int arraySizeNeeded = this->ColorTableSize;
543 if (colorChannels == 1)
545 grayFunc->GetTable(scalarRange[0], scalarRange[1], arraySizeNeeded, this->TempArray1);
549 rgbFunc->GetTable(scalarRange[0], scalarRange[1], arraySizeNeeded, this->TempArray1);
553 scalarOpacityFunc->GetTable(scalarRange[0], scalarRange[1], arraySizeNeeded, this->TempArray2);
556 gradientOpacityFunc->GetTable(0, (scalarRange[1] - scalarRange[0]) * 0.25, 256, goArray);
561 float *fptr2 = this->TempArray2;
562 double factor = this->ActualSampleDistance / scalarOpacityDistance;
563 for (i = 0; i < arraySizeNeeded; i++)
567 *fptr2 = 1.0 - pow(static_cast<double>(1.0 - (*fptr2)), factor);
573 unsigned char *ptr, *rgbptr, *aptr;
580 ptr = this->ColorLookup;
581 for (goLoop = 0; goLoop < 256; goLoop++)
583 fptr1 = this->TempArray1;
584 fptr2 = this->TempArray2;
585 if (colorChannels == 1)
587 for (i = 0; i < arraySizeNeeded; i++)
589 *(ptr++) = static_cast<unsigned char>(*(fptr1)*255.0 + 0.5);
590 *(ptr++) = static_cast<unsigned char>(*(fptr1)*255.0 + 0.5);
591 *(ptr++) = static_cast<unsigned char>(*(fptr1++) * 255.0 + 0.5);
592 *(ptr++) = static_cast<unsigned char>(*(fptr2++) * goArray[goLoop] * 255.0 + 0.5);
597 for (i = 0; i < arraySizeNeeded; i++)
599 *(ptr++) = static_cast<unsigned char>(*(fptr1++) * 255.0 + 0.5);
600 *(ptr++) = static_cast<unsigned char>(*(fptr1++) * 255.0 + 0.5);
601 *(ptr++) = static_cast<unsigned char>(*(fptr1++) * 255.0 + 0.5);
602 *(ptr++) = static_cast<unsigned char>(*(fptr2++) * goArray[goLoop] * 255.0 + 0.5);
619 rgbptr = this->ColorLookup;
620 aptr = this->AlphaLookup;
622 if (colorChannels == 1)
624 for (i = 0; i < arraySizeNeeded; i++)
626 fptr1 = this->TempArray1;
627 fptr2 = this->TempArray2;
628 for (goLoop = 0; goLoop < 256; goLoop++)
630 *(rgbptr++) = static_cast<unsigned char>(*(fptr1)*255.0 + 0.5);
631 *(rgbptr++) = static_cast<unsigned char>(*(fptr1)*255.0 + 0.5);
632 *(rgbptr++) = static_cast<unsigned char>(*(fptr1++) * 255.0 + 0.5);
633 *(aptr++) = static_cast<unsigned char>(*(fptr2++) * goArray[goLoop] * 255.0 + 0.5);
639 fptr1 = this->TempArray1;
640 fptr2 = this->TempArray2;
641 for (i = 0; i < arraySizeNeeded; i++)
643 for (goLoop = 0; goLoop < 256; goLoop++)
645 *(rgbptr++) = static_cast<unsigned char>(*(fptr1)*255.0 + 0.5);
646 *(rgbptr++) = static_cast<unsigned char>(*(fptr1 + 1) * 255.0 + 0.5);
647 *(rgbptr++) = static_cast<unsigned char>(*(fptr1 + 2) * 255.0 + 0.5);
648 *(aptr++) = static_cast<unsigned char>(*(fptr2)*goArray[goLoop] * 255.0 + 0.5);
657 for (goLoop = 0; goLoop < 256; goLoop++)
670 aptr = this->AlphaLookup;
672 for (goLoop = 0; goLoop < 256; goLoop++)
674 fptr2 = this->TempArray2;
675 for (i = 0; i < arraySizeNeeded; i++)
677 *(aptr++) = static_cast<unsigned char>(*(fptr2++) * goArray[goLoop] * 255.0 + 0.5);
692 void vtkMitkVolumeTextureMapper3D::PrintSelf(ostream &os, vtkIndent indent)
694 this->Superclass::PrintSelf(os, indent);
696 os << indent <<
"Sample Distance: " << this->SampleDistance << endl;
697 os << indent <<
"NumberOfPolygons: " << this->NumberOfPolygons << endl;
698 os << indent <<
"ActualSampleDistance: " << this->ActualSampleDistance << endl;
699 os << indent <<
"VolumeDimensions: " << this->VolumeDimensions[0] <<
" " << this->VolumeDimensions[1] <<
" " 700 << this->VolumeDimensions[2] << endl;
701 os << indent <<
"VolumeSpacing: " << this->VolumeSpacing[0] <<
" " << this->VolumeSpacing[1] <<
" " 702 << this->VolumeSpacing[2] << endl;
704 os << indent <<
"UseCompressedTexture: " << this->UseCompressedTexture << endl;
static void Update(vtkPolyData *)
vtkInstantiatorNewMacro(vtkMitkVolumeTextureMapper3D)
void Normalize(itk::Image< TPixel, VImageDimension > *itkImage, mitk::Image::Pointer im2, mitk::Image::Pointer mask1, std::string output)