ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
FileASSIMP.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 
8 #include <FileSystem.h>
9 #include <ImageIO.h>
10 #include <Logging.h>
11 #include <ProgressReporters.h>
12 #include <ecvPointCloud.h>
13 
14 #include <fstream>
15 #include <numeric>
16 #include <vector>
17 
18 #include "assimp/Importer.hpp"
19 #include "assimp/ProgressHandler.hpp"
20 #include "assimp/pbrmaterial.h"
21 #include "assimp/postprocess.h"
22 #include "assimp/scene.h"
23 #include "io/FileFormatIO.h"
24 #include "io/ModelIO.h"
25 #include "io/TriangleMeshIO.h"
28 
29 #define AI_MATKEY_CLEARCOAT_THICKNESS "$mat.clearcoatthickness", 0, 0
30 #define AI_MATKEY_CLEARCOAT_ROUGHNESS "$mat.clearcoatroughness", 0, 0
31 #define AI_MATKEY_SHEEN "$mat.sheen", 0, 0
32 #define AI_MATKEY_ANISOTROPY "$mat.anisotropy", 0, 0
33 
34 namespace cloudViewer {
35 namespace io {
36 
37 // Ref:
38 // https://github.com/assimp/assimp/blob/master/include/assimp/postprocess.h
39 const unsigned int kPostProcessFlags_compulsory =
40  aiProcess_JoinIdenticalVertices | aiProcess_SortByPType |
41  aiProcess_PreTransformVertices;
42 
43 const unsigned int kPostProcessFlags_fast =
44  kPostProcessFlags_compulsory | aiProcess_GenNormals |
45  aiProcess_Triangulate | aiProcess_GenUVCoords |
46  aiProcess_RemoveRedundantMaterials | aiProcess_OptimizeMeshes;
47 
48 struct TextureImages {
49  std::shared_ptr<geometry::Image> albedo;
50  std::shared_ptr<geometry::Image> normal;
51  std::shared_ptr<geometry::Image> ao;
52  std::shared_ptr<geometry::Image> roughness;
53  std::shared_ptr<geometry::Image> metallic;
54  std::shared_ptr<geometry::Image> reflectance;
55  std::shared_ptr<geometry::Image> clearcoat;
56  std::shared_ptr<geometry::Image> clearcoat_roughness;
57  std::shared_ptr<geometry::Image> anisotropy;
58  std::shared_ptr<geometry::Image> gltf_rough_metal;
59 };
60 
61 void LoadTextures(const std::string& filename,
62  const aiScene* scene,
63  const aiMaterial* mat,
64  TextureImages& maps) {
65  // Retrieve textures
66  std::string base_path =
68 
69  auto texture_loader = [&base_path, &scene, &mat, &filename](
70  aiTextureType type,
71  std::shared_ptr<geometry::Image>& img) {
72  if (mat->GetTextureCount(type) > 0) {
73  aiString path;
74  mat->GetTexture(type, 0, &path);
75 
76  // If the texture is an embedded texture, use `GetEmbeddedTexture`.
77  if (auto texture = scene->GetEmbeddedTexture(path.C_Str())) {
78  if (texture->CheckFormat("png")) {
80  "png",
81  reinterpret_cast<const unsigned char*>(
82  texture->pcData),
83  texture->mWidth);
84  if (image->HasData()) {
85  img = image;
86  }
87  } else if (texture->CheckFormat("jpg")) {
89  "jpg",
90  reinterpret_cast<const unsigned char*>(
91  texture->pcData),
92  texture->mWidth);
93  if (image->HasData()) {
94  img = image;
95  }
96  } else {
98  "Unsupported texture format for texture {} for "
99  "file {}: Only jpg and "
100  "png textures are supported.",
101  path.C_Str(), filename);
102  }
103  }
104  // Else, build the path to it.
105  else {
106  std::string strpath(path.C_Str());
107  // Normalize path separators.
108  auto p_win = strpath.find("\\");
109  while (p_win != std::string::npos) {
110  strpath[p_win] = '/';
111  p_win = strpath.find("\\", p_win + 1);
112  }
113  // If absolute path convert to relative to base path.
114  if (strpath.length() > 1 &&
115  (strpath[0] == '/' || strpath[1] == ':')) {
117  strpath);
118  }
119  auto image = io::CreateImageFromFile(base_path + strpath);
120  if (image->HasData()) {
121  img = image;
122  }
123  }
124  }
125  };
126 
127  // Prefer BASE_COLOR texture as assimp now uses it for PBR workflows
128  if (mat->GetTextureCount(aiTextureType_BASE_COLOR) > 0) {
129  texture_loader(aiTextureType_BASE_COLOR, maps.albedo);
130  } else {
131  texture_loader(aiTextureType_DIFFUSE, maps.albedo);
132  }
133  texture_loader(aiTextureType_NORMALS, maps.normal);
134  // Assimp may place ambient occlusion texture in AMBIENT_OCCLUSION if
135  // format has AO support. Prefer that texture if it is preset. Otherwise,
136  // try AMBIENT where OBJ and FBX typically put AO textures.
137  if (mat->GetTextureCount(aiTextureType_AMBIENT_OCCLUSION) > 0) {
138  texture_loader(aiTextureType_AMBIENT_OCCLUSION, maps.ao);
139  } else {
140  texture_loader(aiTextureType_AMBIENT, maps.ao);
141  }
142  texture_loader(aiTextureType_METALNESS, maps.metallic);
143  if (mat->GetTextureCount(aiTextureType_DIFFUSE_ROUGHNESS) > 0) {
144  texture_loader(aiTextureType_DIFFUSE_ROUGHNESS, maps.roughness);
145  } else if (mat->GetTextureCount(aiTextureType_SHININESS) > 0) {
146  // NOTE: In some FBX files assimp puts the roughness texture in
147  // shininess slot
148  texture_loader(aiTextureType_SHININESS, maps.roughness);
149  }
150  // NOTE: Assimp doesn't have a texture type for GLTF's combined
151  // roughness/metallic texture so it puts it in the 'unknown' texture slot
152  texture_loader(aiTextureType_UNKNOWN, maps.gltf_rough_metal);
153  // NOTE: the following may be non-standard. We are using REFLECTION texture
154  // type to store OBJ map_Ps 'sheen' PBR map
155  texture_loader(aiTextureType_REFLECTION, maps.reflectance);
156 
157  // NOTE: ASSIMP doesn't appear to provide texture params for the following:
158  // clearcoat
159  // clearcoat_roughness
160  // anisotropy
161 }
162 
164  const std::string& filename,
165  ccMesh& mesh,
166  const ReadTriangleMeshOptions& params /*={}*/) {
167  Assimp::Importer importer;
168 
169  unsigned int post_process_flags = kPostProcessFlags_compulsory;
170 
171  if (params.enable_post_processing) {
172  post_process_flags = kPostProcessFlags_fast;
173  }
174 
175  const auto* scene = importer.ReadFile(filename.c_str(), post_process_flags);
176  if (!scene) {
177  utility::LogWarning("Unable to load file {} with ASSIMP: {}", filename,
178  importer.GetErrorString());
179  return false;
180  }
181 
182  mesh.clear();
183  if (scene->mNumMeshes > 0) {
184  const auto* assimp_mesh = scene->mMeshes[0];
185 
186  if (!mesh.getAssociatedCloud()) {
187  mesh.CreateInternalCloud();
188  }
189 
190  if (!mesh.reserveAssociatedCloud(assimp_mesh->mNumVertices,
191  assimp_mesh->HasVertexColors(0),
192  assimp_mesh->HasNormals())) {
193  return false;
194  }
195  } else {
196  utility::LogWarning("Must call CreateInternalCloud first!");
197  return false;
198  }
199 
200  size_t current_vidx = 0;
201  // Merge individual meshes in aiScene into a single TriangleMesh
202  for (size_t midx = 0; midx < scene->mNumMeshes; ++midx) {
203  const auto* assimp_mesh = scene->mMeshes[midx];
204  // Only process triangle meshes
205  if (assimp_mesh->mPrimitiveTypes != aiPrimitiveType_TRIANGLE) {
207  "Skipping non-triangle primitive geometry of type: "
208  "{}",
209  assimp_mesh->mPrimitiveTypes);
210  continue;
211  }
212 
213  // copy vertex data
214  for (size_t vidx = 0; vidx < assimp_mesh->mNumVertices; ++vidx) {
215  auto& vertex = assimp_mesh->mVertices[vidx];
216  mesh.addVertice({vertex.x, vertex.y, vertex.z});
217  }
218 
219  // copy face indices data
220  for (size_t fidx = 0; fidx < assimp_mesh->mNumFaces; ++fidx) {
221  auto& face = assimp_mesh->mFaces[fidx];
222  Eigen::Vector3i facet(
223  face.mIndices[0] + static_cast<int>(current_vidx),
224  face.mIndices[1] + static_cast<int>(current_vidx),
225  face.mIndices[2] + static_cast<int>(current_vidx));
226  mesh.addTriangle(facet);
227  mesh.triangle_material_ids_.push_back(assimp_mesh->mMaterialIndex);
228  }
229 
230  if (assimp_mesh->HasNormals()) {
231  for (size_t nidx = 0; nidx < assimp_mesh->mNumVertices; ++nidx) {
232  auto& normal = assimp_mesh->mNormals[nidx];
233  mesh.addVertexNormal({normal.x, normal.y, normal.z});
234  }
235  }
236 
237  // NOTE: only support a single UV channel
238  if (assimp_mesh->HasTextureCoords(0)) {
239  for (size_t fidx = 0; fidx < assimp_mesh->mNumFaces; ++fidx) {
240  auto& face = assimp_mesh->mFaces[fidx];
241  auto& uv1 = assimp_mesh->mTextureCoords[0][face.mIndices[0]];
242  auto& uv2 = assimp_mesh->mTextureCoords[0][face.mIndices[1]];
243  auto& uv3 = assimp_mesh->mTextureCoords[0][face.mIndices[2]];
244  mesh.triangle_uvs_.push_back(Eigen::Vector2d(uv1.x, uv1.y));
245  mesh.triangle_uvs_.push_back(Eigen::Vector2d(uv2.x, uv2.y));
246  mesh.triangle_uvs_.push_back(Eigen::Vector2d(uv3.x, uv3.y));
247  }
248  }
249 
250  // NOTE: only support a single per-vertex color attribute
251  if (assimp_mesh->HasVertexColors(0)) {
252  for (size_t cidx = 0; cidx < assimp_mesh->mNumVertices; ++cidx) {
253  auto& c = assimp_mesh->mColors[0][cidx];
254  mesh.addVertexColor({c.r, c.g, c.b});
255  }
256  }
257 
258  // Adjust face indices to index into combined mesh vertex array
259  current_vidx += assimp_mesh->mNumVertices;
260  }
261 
262  // Now load the materials
263  mesh.materials_.resize(scene->mNumMaterials);
264  for (size_t i = 0; i < scene->mNumMaterials; ++i) {
265  auto* mat = scene->mMaterials[i];
266 
267  // create material structure to match this name
268  auto& mesh_material = mesh.materials_[i].second;
269  mesh.materials_[i].first = mat->GetName().C_Str();
270 
271  using MaterialParameter = ccMesh::Material::MaterialParameter;
272 
273  // Retrieve base material properties
274  aiColor3D color(1.f, 1.f, 1.f);
275 
276  mat->Get(AI_MATKEY_COLOR_DIFFUSE, color);
277  mesh_material.baseColor =
278  MaterialParameter::CreateRGB(color.r, color.g, color.b);
279  mat->Get(AI_MATKEY_METALLIC_FACTOR, mesh_material.baseMetallic);
280  mat->Get(AI_MATKEY_ROUGHNESS_FACTOR, mesh_material.baseRoughness);
281  // NOTE: We prefer sheen to reflectivity so the following code works
282  // since if sheen is not present it won't modify baseReflectance
283  mat->Get(AI_MATKEY_REFLECTIVITY, mesh_material.baseReflectance);
284  mat->Get(AI_MATKEY_SHEEN, mesh_material.baseReflectance);
285 
286  mat->Get(AI_MATKEY_CLEARCOAT_THICKNESS, mesh_material.baseClearCoat);
288  mesh_material.baseClearCoatRoughness);
289  mat->Get(AI_MATKEY_ANISOTROPY, mesh_material.baseAnisotropy);
290 
291  // Retrieve textures
292  TextureImages maps;
293  LoadTextures(filename, scene, mat, maps);
294  mesh_material.albedo = maps.albedo;
295  mesh_material.normalMap = maps.normal;
296  mesh_material.ambientOcclusion = maps.ao;
297  mesh_material.metallic = maps.metallic;
298  mesh_material.roughness = maps.roughness;
299  mesh_material.reflectance = maps.reflectance;
300 
301  // For legacy visualization support
302  if (mesh_material.albedo) {
303  mesh.textures_.emplace_back(*mesh_material.albedo->FlipVertical());
304  } else {
305  mesh.textures_.emplace_back();
306  }
307  }
308 
309  return true;
310 }
311 
312 bool ReadModelUsingAssimp(const std::string& filename,
314  const ReadTriangleModelOptions& params /*={}*/) {
315  int64_t progress_total = 100; // 70: ReadFile(), 10: mesh, 20: textures
316  float readfile_total = 70.0f;
317  float mesh_total = 10.0f;
318  float textures_total = 20.0f;
319  int64_t progress = 0;
320  utility::CountingProgressReporter reporter(params.update_progress);
321  reporter.SetTotal(progress_total);
322  class AssimpProgress : public Assimp::ProgressHandler {
323  public:
324  AssimpProgress(const ReadTriangleModelOptions& params, float scaling)
325  : params_(params), scaling_(scaling) {}
326 
327  bool Update(float percentage = -1.0f) override {
328  if (params_.update_progress) {
329  params_.update_progress(
330  std::max(0.0f, 100.0f * scaling_ * percentage));
331  }
332  return true;
333  }
334 
335  private:
336  const ReadTriangleModelOptions& params_;
337  float scaling_;
338  };
339 
340  Assimp::Importer importer;
341  // The importer takes ownership of the pointer (the documentation
342  // is silent on this salient point).
343  importer.SetProgressHandler(
344  new AssimpProgress(params, readfile_total / progress_total));
345  const auto* scene =
346  importer.ReadFile(filename.c_str(), kPostProcessFlags_fast);
347  if (!scene) {
348  utility::LogWarning("Unable to load file {} with ASSIMP: {}", filename,
349  importer.GetErrorString());
350  return false;
351  }
352 
353  progress = int64_t(readfile_total);
354  reporter.Update(progress);
355 
356  // Process each Assimp mesh into a ccMesh
357  for (size_t midx = 0; midx < scene->mNumMeshes; ++midx) {
358  const auto* assimp_mesh = scene->mMeshes[midx];
359  // Only process triangle meshes
360  if (!(assimp_mesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE)) {
362  "Skipping non-triangle primitive geometry of type: "
363  "{}",
364  assimp_mesh->mPrimitiveTypes);
365  continue;
366  }
367 
368  ccPointCloud* baseVertices = new ccPointCloud("vertices");
369  assert(baseVertices);
370  auto mesh = std::make_shared<ccMesh>(baseVertices);
371 
372  if (!baseVertices->reserveThePointsTable(assimp_mesh->mNumVertices)) {
374  "[reserveThePointsTable] Not have enough memory! ");
375  return false;
376  }
377  if (assimp_mesh->mNormals) {
378  if (!baseVertices->reserveTheNormsTable()) {
380  "[reserveTheNormsTable] Not have enough memory! ");
381  return false;
382  }
383  }
384  if (assimp_mesh->HasVertexColors(0)) {
385  if (!baseVertices->reserveTheRGBTable()) {
387  "[reserveTheRGBTable] Not have enough memory! ");
388  return false;
389  }
390  }
391 
392  // copy vertex data
393  for (size_t vidx = 0; vidx < assimp_mesh->mNumVertices; ++vidx) {
394  auto& vertex = assimp_mesh->mVertices[vidx];
395  baseVertices->addEigenPoint({vertex.x, vertex.y, vertex.z});
396  }
397 
398  // copy face indices data
399  for (size_t fidx = 0; fidx < assimp_mesh->mNumFaces; ++fidx) {
400  auto& face = assimp_mesh->mFaces[fidx];
401  Eigen::Vector3i facet(face.mIndices[0], face.mIndices[1],
402  face.mIndices[2]);
403  mesh->addTriangle(facet);
404  }
405 
406  if (assimp_mesh->mNormals) {
407  for (size_t nidx = 0; nidx < assimp_mesh->mNumVertices; ++nidx) {
408  auto& normal = assimp_mesh->mNormals[nidx];
409  baseVertices->addEigenNorm({normal.x, normal.y, normal.z});
410  }
411  }
412 
413  // NOTE: only use the first UV channel
414  if (assimp_mesh->HasTextureCoords(0)) {
415  for (size_t fidx = 0; fidx < assimp_mesh->mNumFaces; ++fidx) {
416  auto& face = assimp_mesh->mFaces[fidx];
417  auto& uv1 = assimp_mesh->mTextureCoords[0][face.mIndices[0]];
418  auto& uv2 = assimp_mesh->mTextureCoords[0][face.mIndices[1]];
419  auto& uv3 = assimp_mesh->mTextureCoords[0][face.mIndices[2]];
420  mesh->triangle_uvs_.push_back(Eigen::Vector2d(uv1.x, uv1.y));
421  mesh->triangle_uvs_.push_back(Eigen::Vector2d(uv2.x, uv2.y));
422  mesh->triangle_uvs_.push_back(Eigen::Vector2d(uv3.x, uv3.y));
423  }
424  }
425 
426  // NOTE: only use the first color attribute
427  if (assimp_mesh->HasVertexColors(0)) {
428  for (size_t cidx = 0; cidx < assimp_mesh->mNumVertices; ++cidx) {
429  auto& c = assimp_mesh->mColors[0][cidx];
430  baseVertices->addEigenColor({c.r, c.g, c.b});
431  }
432  }
433 
434  // do some cleaning
435  {
436  baseVertices->shrinkToFit();
437  mesh->shrinkToFit();
438  NormsIndexesTableType* normals = mesh->getTriNormsTable();
439  if (normals) {
440  normals->shrink_to_fit();
441  }
442  }
443 
444  baseVertices->setEnabled(false);
445  // DGM: no need to lock it as it is only used by one mesh!
446  baseVertices->setLocked(false);
447  mesh->addChild(baseVertices);
448 
449  // Add the mesh to the model
450  model.meshes_.push_back({mesh, std::string(assimp_mesh->mName.C_Str()),
451  assimp_mesh->mMaterialIndex});
452  }
453 
454  progress = int64_t(readfile_total + mesh_total);
455  reporter.Update(progress);
456 
457  // Load materials
458  for (size_t i = 0; i < scene->mNumMaterials; ++i) {
459  auto* mat = scene->mMaterials[i];
460 
462 
463  cv3d_mat.name = mat->GetName().C_Str();
464 
465  // Retrieve base material properties
466  aiColor3D color(1.f, 1.f, 1.f);
467 
468  mat->Get(AI_MATKEY_COLOR_DIFFUSE, color);
469  cv3d_mat.base_color = Eigen::Vector4f(color.r, color.g, color.b, 1.f);
470  mat->Get(AI_MATKEY_METALLIC_FACTOR, cv3d_mat.base_metallic);
471  mat->Get(AI_MATKEY_ROUGHNESS_FACTOR, cv3d_mat.base_roughness);
472  mat->Get(AI_MATKEY_REFLECTIVITY, cv3d_mat.base_reflectance);
473  mat->Get(AI_MATKEY_SHEEN, cv3d_mat.base_reflectance);
474 
475  mat->Get(AI_MATKEY_CLEARCOAT_THICKNESS, cv3d_mat.base_clearcoat);
476  mat->Get(AI_MATKEY_CLEARCOAT_FACTOR, cv3d_mat.base_clearcoat);
477  mat->Get(AI_MATKEY_CLEARCOAT_ROUGHNESS_FACTOR,
478  cv3d_mat.base_clearcoat_roughness);
479  mat->Get(AI_MATKEY_ANISOTROPY, cv3d_mat.base_anisotropy);
480  mat->Get(AI_MATKEY_COLOR_EMISSIVE, color);
481  cv3d_mat.emissive_color =
482  Eigen::Vector4f(color.r, color.g, color.b, 1.f);
483  aiString alpha_mode;
484  mat->Get(AI_MATKEY_GLTF_ALPHAMODE, alpha_mode);
485  std::string alpha_mode_str(alpha_mode.C_Str());
486  if (alpha_mode_str == "BLEND" || alpha_mode_str == "MASK") {
487  cv3d_mat.has_alpha = true;
488  }
489 
490  // Retrieve textures
491  TextureImages maps;
492  LoadTextures(filename, scene, mat, maps);
493  cv3d_mat.albedo_img = maps.albedo;
494  cv3d_mat.normal_img = maps.normal;
495  cv3d_mat.ao_img = maps.ao;
496  cv3d_mat.metallic_img = maps.metallic;
497  cv3d_mat.roughness_img = maps.roughness;
498  cv3d_mat.reflectance_img = maps.reflectance;
499  cv3d_mat.ao_rough_metal_img = maps.gltf_rough_metal;
500 
501  if (cv3d_mat.has_alpha) {
502  cv3d_mat.shader = "defaultLitTransparency";
503  } else {
504  cv3d_mat.shader = "defaultLit";
505  }
506 
507  model.materials_.push_back(cv3d_mat);
508 
509  progress = int64_t(readfile_total + mesh_total +
510  textures_total * float(i + 1) /
511  float(scene->mNumMaterials));
512  reporter.Update(progress);
513  }
514 
515  reporter.Update(progress_total);
516 
517  return true;
518 }
519 
520 } // namespace io
521 } // namespace cloudViewer
std::string filename
std::shared_ptr< core::Tensor > image
double normal[3]
char type
math::float4 color
cmdLineReadable * params[]
Array of compressed 3D normals (single index)
Triangular mesh.
Definition: ecvMesh.h:35
std::vector< int > triangle_material_ids_
List of material ids.
Definition: ecvMesh.h:707
void addVertice(const Eigen::Vector3d &vertice)
std::vector< Eigen::Vector2d > triangle_uvs_
List of uv coordinates per triangle.
Definition: ecvMesh.h:625
ccGenericPointCloud * getAssociatedCloud() const override
Returns the vertices cloud.
Definition: ecvMesh.h:143
void addVertexNormal(const Eigen::Vector3d &normal)
void addTriangle(unsigned i1, unsigned i2, unsigned i3)
Adds a triangle to the mesh.
bool reserveAssociatedCloud(std::size_t n, bool init_color=false, bool init_normal=false)
void clear()
std::vector< cloudViewer::geometry::Image > textures_
Textures of the image.
Definition: ecvMesh.h:709
std::vector< std::pair< std::string, Material > > materials_
Definition: ecvMesh.h:704
void addVertexColor(const Eigen::Vector3d &color)
virtual void setLocked(bool state)
Sets the "enabled" property.
Definition: ecvObject.h:117
virtual void setEnabled(bool state)
Sets the "enabled" property.
Definition: ecvObject.h:102
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
void addEigenNorm(const Eigen::Vector3d &N)
void addEigenColor(const Eigen::Vector3d &color)
bool reserveTheNormsTable()
Reserves memory to store the compressed normals.
bool reserveTheRGBTable()
Reserves memory to store the RGB colors.
void shrinkToFit()
Removes unused capacity.
bool reserveThePointsTable(unsigned _numberOfPoints)
Reserves memory to store the points coordinates.
void addEigenPoint(const Eigen::Vector3d &point)
std::vector< unsigned int > face
double normals[3]
#define LogWarning(...)
Definition: Logging.h:72
#define LogInfo(...)
Definition: Logging.h:81
#define LogError(...)
Definition: Logging.h:60
int max(int a, int b)
Definition: cutil_math.h:48
#define AI_MATKEY_CLEARCOAT_ROUGHNESS
Definition: FileASSIMP.cpp:30
#define AI_MATKEY_SHEEN
Definition: FileASSIMP.cpp:31
#define AI_MATKEY_CLEARCOAT_THICKNESS
Definition: FileASSIMP.cpp:29
#define AI_MATKEY_ANISOTROPY
Definition: FileASSIMP.cpp:32
float scaling
Definition: Window.cpp:78
std::shared_ptr< geometry::Image > CreateImageFromMemory(const std::string &image_format, const unsigned char *image_data_ptr, size_t image_data_size)
Factory function to create an image from memory.
const unsigned int kPostProcessFlags_compulsory
Definition: FileASSIMP.cpp:39
bool ReadModelUsingAssimp(const std::string &filename, visualization::rendering::TriangleMeshModel &model, const ReadTriangleModelOptions &params)
Definition: FileASSIMP.cpp:312
std::shared_ptr< geometry::Image > CreateImageFromFile(const std::string &filename)
const unsigned int kPostProcessFlags_fast
Definition: FileASSIMP.cpp:43
bool ReadTriangleMeshUsingASSIMP(const std::string &filename, ccMesh &mesh, const ReadTriangleMeshOptions &params)
Definition: FileASSIMP.cpp:163
void LoadTextures(const std::string &filename, const aiScene *scene, const aiMaterial *mat, TextureImages &maps)
Definition: FileASSIMP.cpp:61
static const std::string path
Definition: PointCloud.cpp:59
std::string GetFileParentDirectory(const std::string &filename)
Definition: FileSystem.cpp:314
std::string GetFileNameWithoutDirectory(const std::string &filename)
Definition: FileSystem.cpp:301
Generic file read and write utility for python interface.
Eigen::Matrix< Index, 3, 1 > Vector3i
Definition: knncpp.h:30
std::shared_ptr< geometry::Image > anisotropy
Definition: FileASSIMP.cpp:57
std::shared_ptr< geometry::Image > clearcoat
Definition: FileASSIMP.cpp:55
std::shared_ptr< geometry::Image > roughness
Definition: FileASSIMP.cpp:52
std::shared_ptr< geometry::Image > reflectance
Definition: FileASSIMP.cpp:54
std::shared_ptr< geometry::Image > clearcoat_roughness
Definition: FileASSIMP.cpp:56
std::shared_ptr< geometry::Image > normal
Definition: FileASSIMP.cpp:50
std::shared_ptr< geometry::Image > metallic
Definition: FileASSIMP.cpp:53
std::shared_ptr< geometry::Image > albedo
Definition: FileASSIMP.cpp:49
std::shared_ptr< geometry::Image > gltf_rough_metal
Definition: FileASSIMP.cpp:58
std::shared_ptr< geometry::Image > ao
Definition: FileASSIMP.cpp:51
std::shared_ptr< geometry::Image > normal_img
std::shared_ptr< geometry::Image > albedo_img
std::shared_ptr< geometry::Image > ao_rough_metal_img
std::shared_ptr< geometry::Image > metallic_img
std::shared_ptr< geometry::Image > roughness_img
std::shared_ptr< geometry::Image > reflectance_img
std::vector< visualization::rendering::MaterialRecord > materials_
Definition: Model.h:26