iMSTK
Interactive Medical Simulation Toolkit
imstkVTKTextureDelegate.cpp
1 /*
2 ** This file is part of the Interactive Medical Simulation Toolkit (iMSTK)
3 ** iMSTK is distributed under the Apache License, Version 2.0.
4 ** See accompanying NOTICE for details.
5 */
6 
7 #include "imstkVTKTextureDelegate.h"
8 #include "imstkColor.h"
9 #include "imstkGeometryUtilities.h"
10 #include "imstkLogger.h"
11 #include "imstkTexture.h"
12 
13 #include <vtkImageData.h>
14 #include <vtkImageFlip.h>
15 #include <vtkImageReader2Factory.h>
16 #include <vtkPNGReader.h>
17 #include <vtkTexture.h>
18 #include <vtksys/SystemTools.hxx>
19 
20 namespace imstk
21 {
22 VTKTextureDelegate::VTKTextureDelegate() :
23  m_vtkTexture(vtkSmartPointer<vtkTexture>::New())
24 {
25 }
26 
27 void
28 VTKTextureDelegate::initialize(std::shared_ptr<Texture> texture)
29 {
30  m_texture = texture;
31  const std::string tFileName = texture->getPath();
32 
33  // If the texture is provided by ImageData use that, otherwise load via path
34  std::shared_ptr<ImageData> imstkImgData = texture->getImageData();
35  if (imstkImgData == nullptr)
36  {
37  CHECK(vtksys::SystemTools::FileExists(tFileName.c_str()))
38  << "Error: texture file \"" << tFileName << "\" does not exist";
39 
40  // Load by file name
41  vtkNew<vtkImageReader2Factory> readerFactory;
42  if (texture->getType() == Texture::Type::Cubemap)
43  {
44  std::string sideNames[6] = { "posx", "negx", "posy", "negy", "posz", "negz" };
45  m_vtkTexture->SetCubeMap(true);
46 
47  for (int i = 0; i < 6; i++)
48  {
49  auto index = tFileName.find(".");
50  auto tempName = tFileName.substr(0, index);
51  auto extension = tFileName.substr(index);
52  auto sideName = tempName + sideNames[i] + extension;
53 
54  vtkImageReader2* imgReader = readerFactory->CreateImageReader2(sideName.c_str());
55 
56  CHECK(imgReader != nullptr) << "Error: could not find reader for "
57  << sideName;
58 
59  auto imageFlip = vtkSmartPointer<vtkImageFlip>::New();
60  imageFlip->SetFilteredAxis(1);
61  imgReader->SetFileName(sideName.c_str());
62  imgReader->Update();
63  imageFlip->SetInputConnection(imgReader->GetOutputPort());
64  m_vtkTexture->SetInputConnection(i, imageFlip->GetOutputPort());
65  }
66  }
67  else
68  {
69  vtkImageReader2* imgReader = readerFactory->CreateImageReader2(tFileName.c_str());
70 
71  CHECK(imgReader != nullptr) << "Error: could not find reader for "
72  << tFileName;
73 
74  imgReader->SetFileName(tFileName.c_str());
75  imgReader->Update();
76  m_vtkTexture->SetBlendingMode(vtkTexture::VTK_TEXTURE_BLENDING_MODE_ADD);
77  const Texture::WrapType wrapType = m_texture->getWrapType();
78  if (wrapType == Texture::WrapType::REPEAT)
79  {
80  m_vtkTexture->SetWrap(vtkTexture::Repeat);
81  }
82  else if (wrapType == Texture::WrapType::CLAMP_TO_BORDER)
83  {
84  m_vtkTexture->SetWrap(vtkTexture::ClampToBorder);
85  }
86  else if (wrapType == Texture::WrapType::CLAMP_TO_EDGE)
87  {
88  m_vtkTexture->SetWrap(vtkTexture::ClampToEdge);
89  }
90  const Color& borderColor = m_texture->getBorderColor();
91  m_vtkTexture->SetBorderColor(
92  static_cast<float>(borderColor.r),
93  static_cast<float>(borderColor.g),
94  static_cast<float>(borderColor.b),
95  static_cast<float>(borderColor.a));
96  m_vtkTexture->SetInterpolate(m_texture->getInterpolation());
97  m_vtkTexture->SetInputConnection(0, imgReader->GetOutputPort());
98 
99  if (texture->getType() == Texture::Type::Diffuse)
100  {
101  m_vtkTexture->SetUseSRGBColorSpace(true);
102  }
103  }
104  }
105  else
106  {
107  // Load by ImageData
108  vtkSmartPointer<vtkImageData> vtkImgData = GeometryUtils::coupleVtkImageData(imstkImgData);
109  m_vtkTexture->SetBlendingMode(vtkTexture::VTK_TEXTURE_BLENDING_MODE_ADD);
110  m_vtkTexture->SetInterpolate(m_texture->getInterpolation());
111 
112  const Texture::WrapType wrapType = m_texture->getWrapType();
113  if (wrapType == Texture::WrapType::REPEAT)
114  {
115  m_vtkTexture->SetWrap(vtkTexture::Repeat);
116  }
117  else if (wrapType == Texture::WrapType::CLAMP_TO_BORDER)
118  {
119  m_vtkTexture->SetWrap(vtkTexture::ClampToBorder);
120  }
121  else if (wrapType == Texture::WrapType::CLAMP_TO_EDGE)
122  {
123  m_vtkTexture->SetWrap(vtkTexture::ClampToEdge);
124  }
125  const Color& borderColor = m_texture->getBorderColor();
126  m_vtkTexture->SetBorderColor(
127  static_cast<float>(borderColor.r),
128  static_cast<float>(borderColor.g),
129  static_cast<float>(borderColor.b),
130  static_cast<float>(borderColor.a));
131  m_vtkTexture->SetInputData(vtkImgData);
132 
133  if (texture->getType() == Texture::Type::Diffuse)
134  {
135  m_vtkTexture->SetUseSRGBColorSpace(true);
136  }
137  }
138 
139  // Observe changes to the texture
140  connect<Event>(m_texture, &Texture::modified,
141  std::static_pointer_cast<VTKTextureDelegate>(shared_from_this()),
142  &VTKTextureDelegate::textureModified);
143 }
144 
145 void
146 VTKTextureDelegate::textureModified(Event* imstkNotUsed(e))
147 {
148  //m_vtkTexture->GetInputDataObject();
149  m_vtkTexture->Modified();
150 }
151 } // namespace imstk
Compound Geometry.