23 #include <pcl/TextureMesh.h>
25 #include <Eigen/Dense>
28 #include <vtkDataObject.h>
29 #include <vtkFloatArray.h>
30 #include <vtkLODActor.h>
31 #include <vtkMatrix4x4.h>
32 #include <vtkOpenGLRenderWindow.h>
33 #include <vtkPointData.h>
34 #include <vtkPolyData.h>
35 #include <vtkPolyDataMapper.h>
36 #include <vtkProperty.h>
37 #include <vtkRenderWindow.h>
38 #include <vtkRenderer.h>
39 #include <vtkSmartPointer.h>
40 #include <vtkTexture.h>
41 #include <vtkTextureUnitManager.h>
50 vtkPolyData* polydata,
52 vtkRenderer* renderer) {
53 if (!actor || !mesh || !render_manager) {
58 if (!materials || materials->empty()) {
60 "[MeshTextureApplier::ApplyTexturesFromCCMesh] No materials "
72 "[MeshTextureApplier::ApplyTexturesFromCCMesh] Failed to get "
73 "point cloud from mesh!");
80 std::vector<std::vector<Eigen::Vector2f>> tex_coordinates;
85 "[MeshTextureApplier::ApplyTexturesFromCCMesh] Failed to "
86 "convert mesh to VTK with textures!");
91 if (polydata && new_polydata) {
92 polydata->ShallowCopy(new_polydata);
93 }
else if (new_polydata) {
94 polydata = new_polydata.Get();
101 "[MeshTextureApplier::ApplyTexturesFromCCMesh] Successfully "
102 "converted mesh using getVtkPolyDataWithTextures with %zu texture "
104 tex_coordinates.size());
108 polydata, render_manager, renderer);
114 const std::vector<std::vector<Eigen::Vector2f>>& tex_coordinates,
115 vtkPolyData* polydata,
117 vtkRenderer* renderer) {
118 if (!actor || !materials || !render_manager) {
151 vtkIdType numPoints = polydata->GetNumberOfPoints();
157 size_t texture_index = 0;
159 for (
size_t mat_idx = 0;
160 mat_idx < materials->size() && mat_idx < tex_coordinates.size();
162 if (tex_coordinates[mat_idx].empty()) {
166 auto material = materials->at(mat_idx);
167 if (!material)
continue;
171 std::vector<QString> diffuseTextures =
172 material->getTextureFilenames(TexType::DIFFUSE);
177 for (
size_t tex_in_mat = 0; tex_in_mat < diffuseTextures.size();
179 if (diffuseTextures[tex_in_mat].isEmpty()) {
187 coordinates->SetNumberOfComponents(2);
188 std::stringstream ss;
189 ss <<
"TCoords" << texture_index;
190 std::string coords_name = ss.str();
191 coordinates->SetName(coords_name.c_str());
196 for (
const auto& tc : tex_coordinates[mat_idx]) {
197 coordinates->InsertNextTuple2(tc[0], tc[1]);
203 vtkIdType currentSize = coordinates->GetNumberOfTuples();
204 if (currentSize < numPoints) {
206 "[MeshTextureApplier::ApplyTexturesFromMaterialSet]"
208 "Material %zu texture coordinate count (%ld) < "
210 "(%ld), padding with default coordinates",
211 mat_idx, currentSize, numPoints);
212 for (vtkIdType i = currentSize; i < numPoints; ++i) {
213 coordinates->InsertNextTuple2(0.0f, 0.0f);
215 }
else if (currentSize > numPoints) {
217 "[MeshTextureApplier::ApplyTexturesFromMaterialSet]"
219 "Material %zu texture coordinate count (%ld) > "
222 mat_idx, currentSize, numPoints);
228 polydata->GetPointData()->AddArray(coordinates);
231 if (texture_index == 0) {
232 polydata->GetPointData()->SetTCoords(coordinates);
240 "[MeshTextureApplier::ApplyTexturesFromMaterialSet] Created "
242 "texture coordinate arrays for %zu points",
243 texture_index, numPoints);
247 return render_manager->
Apply(actor, materials, polydata, renderer);
251 const pcl::TextureMesh& mesh,
252 vtkPolyData* polydata,
254 vtkRenderer* renderer) {
255 if (!actor || !render_manager) {
260 "[MeshTextureApplier::ApplyPBRTextures] DEPRECATED: This method "
261 "uses pcl::TexMaterial encoding. Consider using "
262 "ApplyTexturesFromCCMesh instead.");
266 for (
const auto& pcl_mat : mesh.tex_materials) {
274 std::vector<std::vector<Eigen::Vector2f>> tex_coordinates;
275 tex_coordinates.reserve(mesh.tex_coordinates.size());
276 for (
const auto& coords : mesh.tex_coordinates) {
277 std::vector<Eigen::Vector2f> coord_vec;
278 coord_vec.reserve(coords.size());
279 for (
const auto& coord : coords) {
280 coord_vec.push_back(Eigen::Vector2f(coord[0], coord[1]));
282 tex_coordinates.push_back(coord_vec);
287 tex_coordinates, polydata,
288 render_manager, renderer);
290 delete temp_material_set;
296 const pcl::TextureMesh& mesh,
297 vtkPolyData* polydata,
298 vtkRenderWindow* render_window) {
299 if (!actor || !polydata || !render_window) {
306 "[MeshTextureApplier::ApplyTraditionalTextures] This function is "
307 "deprecated. Use TextureRenderManager instead.");
310 vtkOpenGLRenderWindow* gl_window = vtkOpenGLRenderWindow::SafeDownCast(
311 static_cast<vtkObjectBase*
>(render_window));
315 vtkTextureUnitManager* tex_manager = gl_window->GetTextureUnitManager();
321 int texture_units = tex_manager->GetNumberOfTextureUnits();
322 if (
static_cast<size_t>(texture_units) < mesh.tex_materials.size()) {
324 "[MeshTextureApplier::ApplyTraditionalTextures] GPU texture "
325 "units %d < mesh textures %zu!",
326 texture_units, mesh.tex_materials.size());
329 vtkPolyDataMapper* mapper =
330 vtkPolyDataMapper::SafeDownCast(actor->GetMapper());
337 size_t last_tex_id = std::min(mesh.tex_materials.size(),
338 static_cast<size_t>(texture_units));
340 for (
size_t tex_id = 0; tex_id < last_tex_id; ++tex_id) {
341 #if (VTK_MAJOR_VERSION == 8 && VTK_MINOR_VERSION >= 2) || VTK_MAJOR_VERSION > 8
342 const char* tu = mesh.tex_materials[tex_id].tex_name.c_str();
344 int tu = vtkProperty::VTK_TEXTURE_UNIT_0 + tex_id;
350 coordinates->SetNumberOfComponents(2);
351 std::stringstream ss;
352 if (mesh.tex_coordinates.size() == 1) {
355 ss <<
"TCoords" << tex_id;
357 std::string coords_name = ss.str();
358 coordinates->SetName(coords_name.c_str());
361 for (
size_t t = 0; t < mesh.tex_coordinates.size(); ++t) {
363 for (
const auto& tc : mesh.tex_coordinates[t]) {
364 coordinates->InsertNextTuple2(tc[0], tc[1]);
367 for (
size_t tc = 0; tc < mesh.tex_coordinates[t].size(); ++tc) {
368 coordinates->InsertNextTuple2(-1.0, -1.0);
373 mapper->MapDataArrayToMultiTextureAttribute(
374 tu, coords_name.c_str(),
375 vtkDataObject::FIELD_ASSOCIATION_POINTS);
376 polydata->GetPointData()->AddArray(coordinates);
static bool PrintDebug(const char *format,...)
Same as Print, but works only in Debug mode.
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
static bool Print(const char *format,...)
Prints out a formatted message in console.
static bool Error(const char *format,...)
Display an error dialog with formatted message.
static bool ApplyTexturesFromCCMesh(vtkLODActor *actor, ccGenericMesh *mesh, vtkPolyData *polydata, TextureRenderManager *render_manager, vtkRenderer *renderer)
Apply textures from ccGenericMesh (preferred method)
static bool ApplyPBRTextures(vtkLODActor *actor, const pcl::TextureMesh &mesh, vtkPolyData *polydata, TextureRenderManager *render_manager, vtkRenderer *renderer)
Apply PBR textures from PCLTextureMesh (deprecated)
static bool ApplyTraditionalTextures(vtkLODActor *actor, const pcl::TextureMesh &mesh, vtkPolyData *polydata, vtkRenderWindow *render_window)
Apply textures from PCLTextureMesh to actor (traditional path)
static bool ApplyTexturesFromMaterialSet(vtkLODActor *actor, const ccMaterialSet *materials, const std::vector< std::vector< Eigen::Vector2f >> &tex_coordinates, vtkPolyData *polydata, TextureRenderManager *render_manager, vtkRenderer *renderer)
Apply textures from ccMaterialSet with texture coordinates.
Texture rendering manager.
bool Apply(vtkLODActor *actor, const ccMaterialSet *materials, vtkPolyData *polydata, vtkRenderer *renderer)
Apply rendering to actor.
CC to PCL cloud converter.
bool getVtkPolyDataWithTextures(ccGenericMesh *mesh, vtkSmartPointer< vtkPolyData > &polydata, vtkSmartPointer< vtkMatrix4x4 > &transformation, std::vector< std::vector< Eigen::Vector2f >> &tex_coordinates)
Convert ccGenericMesh to vtkPolyData with texture coordinates Reuses getPclTextureMesh logic to ensur...
virtual const ccMaterialSet * getMaterialSet() const =0
virtual ccGenericPointCloud * getAssociatedCloud() const =0
Returns the vertices cloud.
static ccPointCloud * ToPointCloud(ccHObject *obj, bool *isLockedVertices=nullptr)
Converts current object to 'equivalent' ccPointCloud.
Mesh (triangle) material.
int addMaterial(ccMaterial::CShared mat, bool allowDuplicateNames=false)
Adds a material.
Mesh (triangle) material.
TextureMapType
Texture map types for PBR materials.
QSharedPointer< ccMaterial > Shared
Shared type.
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
static void FromPCLMaterial(const PCLMaterial &inMaterial, ccMaterial::Shared &outMaterial)