ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
TextureLoader.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
9 
10 #include <CVLog.h>
11 #include <CVTools.h>
12 #include <FileSystem.h>
13 #include <Utils/sm2cc.h>
14 #include <ecvMaterial.h>
15 
16 // Qt
17 #include <QImage>
18 
19 // VTK
20 #include <vtkBMPReader.h>
21 #include <vtkJPEGReader.h>
22 #include <vtkPNGReader.h>
23 #include <vtkPNMReader.h>
24 #include <vtkQImageToImageSource.h>
25 #include <vtkSmartPointer.h>
26 #include <vtkTIFFReader.h>
27 #include <vtkTexture.h>
28 
29 namespace PclUtils {
30 namespace renders {
31 
32 int TextureLoader::LoadFromPCLMaterial(const pcl::TexMaterial& tex_mat,
33  vtkTexture* vtk_tex) {
34  if (!vtk_tex) {
35  return -1;
36  }
37 
38  QImage qimage = ccMaterial::GetTexture(tex_mat.tex_file.c_str());
39  if (!qimage.isNull()) {
40  vtkSmartPointer<vtkQImageToImageSource> qimageToImageSource =
42  qimageToImageSource->SetQImage(&qimage);
43  qimageToImageSource->Update();
44  vtk_tex->SetInputConnection(qimageToImageSource->GetOutputPort());
45  return 1;
46  }
47 
48  if (tex_mat.tex_file.empty()) {
49  return -1;
50  }
51 
52  std::string full_path = tex_mat.tex_file;
54  std::string parent_dir =
56  full_path);
57  std::string upper_filename =
58  cloudViewer::utility::ToUpper(tex_mat.tex_file);
59  std::string real_name;
60 
61  try {
63  parent_dir)) {
65  "[TextureLoader::LoadFromPCLMaterial] Parent directory "
66  "'%s' doesn't exist!",
67  parent_dir.c_str());
68  return -1;
69  }
70 
73  "[TextureLoader::LoadFromPCLMaterial] Parent '%s' is "
74  "not a directory !",
75  parent_dir.c_str());
76  return -1;
77  }
78 
79  std::vector<std::string> paths_vector;
81  parent_dir, paths_vector);
82 
83  for (const auto& path : paths_vector) {
85  if (cloudViewer::utility::ToUpper(path) == upper_filename) {
86  real_name = path;
87  break;
88  }
89  }
90  }
91 
92  if (real_name.empty()) {
94  "[TextureLoader::LoadFromPCLMaterial] Can not find "
95  "texture file %s!",
96  tex_mat.tex_file.c_str());
97  return -1;
98  }
99  } catch (const std::exception& ex) {
101  "[TextureLoader::LoadFromPCLMaterial] Error %s when "
102  "looking for file %s!",
103  ex.what(), tex_mat.tex_file.c_str());
104  return -1;
105  }
106 
107  full_path = real_name;
108  }
109 
110  std::string extension =
112  full_path);
113 
114  if ((extension == "jpg") || (extension == "jpeg")) {
115  vtkSmartPointer<vtkJPEGReader> jpeg_reader =
117  jpeg_reader->SetFileName(full_path.c_str());
118  jpeg_reader->Update();
119  vtk_tex->SetInputConnection(jpeg_reader->GetOutputPort());
120  } else if (extension == "bmp") {
121  vtkSmartPointer<vtkBMPReader> bmp_reader =
123  bmp_reader->SetFileName(full_path.c_str());
124  bmp_reader->Update();
125  vtk_tex->SetInputConnection(bmp_reader->GetOutputPort());
126  } else if (extension == "pnm") {
127  vtkSmartPointer<vtkPNMReader> pnm_reader =
129  pnm_reader->SetFileName(full_path.c_str());
130  pnm_reader->Update();
131  vtk_tex->SetInputConnection(pnm_reader->GetOutputPort());
132  } else if (extension == "png") {
133  vtkSmartPointer<vtkPNGReader> png_reader =
135  png_reader->SetFileName(full_path.c_str());
136  png_reader->Update();
137  vtk_tex->SetInputConnection(png_reader->GetOutputPort());
138  } else if ((extension == "tiff") || (extension == "tif")) {
139  vtkSmartPointer<vtkTIFFReader> tiff_reader =
141  tiff_reader->SetFileName(full_path.c_str());
142  tiff_reader->Update();
143  vtk_tex->SetInputConnection(tiff_reader->GetOutputPort());
144  } else {
146  "[TextureLoader::LoadFromPCLMaterial] Unhandled image %s "
147  "(extension: '%s') for material %s!",
148  full_path.c_str(), extension.c_str(), tex_mat.tex_name.c_str());
149  return -1;
150  }
151 
152  return 1;
153 }
154 
156  vtkTexture* vtk_tex) {
157  if (!material || !vtk_tex) {
158  return -1;
159  }
160 
161  // For traditional multi-texture rendering, prioritize DIFFUSE texture
162  using TexType = ccMaterial::TextureMapType;
163  QString tex_file = material->getTextureFilename(TexType::DIFFUSE);
164  if (tex_file.isEmpty()) {
165  // Fallback to legacy texture filename (for backward compatibility)
166  tex_file = material->getTextureFilename();
167  }
168 
169  QImage qimage = ccMaterial::GetTexture(tex_file);
170  if (!qimage.isNull()) {
171  vtkSmartPointer<vtkQImageToImageSource> qimageToImageSource =
173  qimageToImageSource->SetQImage(&qimage);
174  qimageToImageSource->Update();
175  vtk_tex->SetInputConnection(qimageToImageSource->GetOutputPort());
176  return 1;
177  }
178 
179  if (tex_file.isEmpty()) {
180  return -1;
181  }
182 
183  std::string full_path = CVTools::FromQString(tex_file);
185  std::string parent_dir =
187  full_path);
188  std::string upper_filename = cloudViewer::utility::ToUpper(full_path);
189  std::string real_name;
190 
191  try {
193  parent_dir)) {
195  "[TextureLoader::LoadFromCCMaterial] Parent directory "
196  "'%s' doesn't exist!",
197  parent_dir.c_str());
198  return -1;
199  }
200 
203  "[TextureLoader::LoadFromCCMaterial] Parent '%s' is "
204  "not "
205  "a directory !",
206  parent_dir.c_str());
207  return -1;
208  }
209 
210  std::vector<std::string> paths_vector;
212  parent_dir, paths_vector);
213 
214  for (const auto& path : paths_vector) {
216  if (cloudViewer::utility::ToUpper(path) == upper_filename) {
217  real_name = path;
218  break;
219  }
220  }
221  }
222 
223  if (real_name.empty()) {
225  "[TextureLoader::LoadFromCCMaterial] Can not find "
226  "texture file %s!",
227  full_path.c_str());
228  return -1;
229  }
230  } catch (const std::exception& ex) {
232  "[TextureLoader::LoadFromCCMaterial] Error %s when "
233  "looking for file %s!",
234  ex.what(), full_path.c_str());
235  return -1;
236  }
237 
238  full_path = real_name;
239  }
240 
241  std::string extension =
243  full_path);
244 
245  if ((extension == "jpg") || (extension == "jpeg")) {
246  vtkSmartPointer<vtkJPEGReader> jpeg_reader =
248  jpeg_reader->SetFileName(full_path.c_str());
249  jpeg_reader->Update();
250  vtk_tex->SetInputConnection(jpeg_reader->GetOutputPort());
251  } else if (extension == "bmp") {
252  vtkSmartPointer<vtkBMPReader> bmp_reader =
254  bmp_reader->SetFileName(full_path.c_str());
255  bmp_reader->Update();
256  vtk_tex->SetInputConnection(bmp_reader->GetOutputPort());
257  } else if (extension == "pnm") {
258  vtkSmartPointer<vtkPNMReader> pnm_reader =
260  pnm_reader->SetFileName(full_path.c_str());
261  pnm_reader->Update();
262  vtk_tex->SetInputConnection(pnm_reader->GetOutputPort());
263  } else if (extension == "png") {
264  vtkSmartPointer<vtkPNGReader> png_reader =
266  png_reader->SetFileName(full_path.c_str());
267  png_reader->Update();
268  vtk_tex->SetInputConnection(png_reader->GetOutputPort());
269  } else if ((extension == "tiff") || (extension == "tif")) {
270  vtkSmartPointer<vtkTIFFReader> tiff_reader =
272  tiff_reader->SetFileName(full_path.c_str());
273  tiff_reader->Update();
274  vtk_tex->SetInputConnection(tiff_reader->GetOutputPort());
275  } else {
277  "[TextureLoader::LoadFromCCMaterial] Unhandled image %s "
278  "(extension: '%s') for material %s!",
279  full_path.c_str(), extension.c_str(),
280  CVTools::FromQString(material->getName()).c_str());
281  return -1;
282  }
283 
284  return 1;
285 }
286 
287 } // namespace renders
288 } // namespace PclUtils
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
Definition: CVLog.cpp:133
static std::string FromQString(const QString &qs)
Definition: CVTools.cpp:100
static int LoadFromPCLMaterial(const pcl::TexMaterial &tex_mat, vtkTexture *vtk_tex)
Load texture from pcl::TexMaterial.
static int LoadFromCCMaterial(ccMaterial::CShared material, vtkTexture *vtk_tex)
Load texture from ccMaterial.
TextureMapType
Texture map types for PBR materials.
Definition: ecvMaterial.h:176
QSharedPointer< const ccMaterial > CShared
Const + Shared type.
Definition: ecvMaterial.h:31
static QImage GetTexture(const QString &absoluteFilename)
Returns the texture image associated to a given name.
static const std::string path
Definition: PointCloud.cpp:59
bool ListFilesInDirectory(const std::string &directory, std::vector< std::string > &filenames)
Definition: FileSystem.cpp:561
bool IsDirectory(const std::string &directory)
Definition: FileSystem.cpp:454
std::string GetFileParentDirectory(const std::string &filename)
Definition: FileSystem.cpp:314
bool DirectoryExists(const std::string &directory)
Definition: FileSystem.cpp:473
std::string GetFileExtensionInLowerCase(const std::string &filename)
Definition: FileSystem.cpp:281
bool FileExists(const std::string &filename)
Definition: FileSystem.cpp:524
bool IsFile(const std::string &filename)
Definition: FileSystem.cpp:435
std::string ToUpper(const std::string &s)
Convert string to the upper case.
Definition: Helper.cpp:249