15 #include <pcl/io/obj_io.h>
26 "[MaterialConverter::FromCCMaterial] ccMaterial is null");
37 if (diffuse_textures.size() > 1) {
40 "[MaterialConverter::FromCCMaterial] Detected %zu map_Kd "
41 "textures for material '%s', will use traditional "
44 diffuse_textures.size(), pbr.
name.c_str());
48 if (!diffuse_path.isEmpty()) {
53 if (!ao_path.isEmpty()) {
58 if (!normal_path.isEmpty()) {
63 if (!metallic_path.isEmpty()) {
68 if (!roughness_path.isEmpty()) {
73 if (!emissive_path.isEmpty()) {
79 if (!sheen_path.isEmpty()) {
84 if (!clearcoat_path.isEmpty()) {
88 QString clearcoat_roughness_path =
90 if (!clearcoat_roughness_path.isEmpty()) {
95 if (!anisotropy_path.isEmpty()) {
106 pbr.
baseColor[0] = std::max(0.0f, std::min(1.0f, diffuse.
r));
107 pbr.
baseColor[1] = std::max(0.0f, std::min(1.0f, diffuse.
g));
108 pbr.
baseColor[2] = std::max(0.0f, std::min(1.0f, diffuse.
b));
110 pbr.
ambientColor[0] = std::max(0.0f, std::min(1.0f, ambient.
r));
111 pbr.
ambientColor[1] = std::max(0.0f, std::min(1.0f, ambient.
g));
112 pbr.
ambientColor[2] = std::max(0.0f, std::min(1.0f, ambient.
b));
114 pbr.
diffuseColor[0] = std::max(0.0f, std::min(1.0f, diffuse.
r));
115 pbr.
diffuseColor[1] = std::max(0.0f, std::min(1.0f, diffuse.
g));
116 pbr.
diffuseColor[2] = std::max(0.0f, std::min(1.0f, diffuse.
b));
135 bool hasExplicitShininess =
141 if (hasExplicitShininess) {
143 pbr.
shininess = std::max(0.0f, std::min(128.0f, baseShininess));
144 }
else if (hasPBRParams) {
147 float roughnessFactor = 1.0f - pbr.
roughness;
150 float sheenFactor = 1.0f + ccMat->
getSheen() * 0.5f;
154 float clearcoatFactor =
160 float effectiveShininess =
161 50.0f * roughnessFactor * sheenFactor * clearcoatFactor;
162 pbr.
shininess = std::max(0.0f, std::min(128.0f, effectiveShininess));
165 "[MaterialConverter::FromCCMaterial] Calculated shininess from "
167 "base=50.00, roughness=%.2f (factor=%.2f), sheen=%.2f "
169 "clearcoat=%.2f (factor=%.2f) -> shininess=%.2f",
174 pbr.
shininess = std::max(0.0f, std::min(128.0f, baseShininess));
180 if (!opacity_path.isEmpty()) {
183 pbr.
opacity = std::max(0.0f, std::min(1.0f, ambient.
a));
186 pbr.
opacity = std::max(0.0f, std::min(1.0f, ambient.
a));
188 pbr.
opacity = std::max(0.0f, std::min(1.0f, diffuse.
a));
193 pbr.
sheen = std::max(0.0f, std::min(1.0f, ccMat->
getSheen()));
200 pbr.
emissive[0] = std::max(0.0f, std::min(1.0f, emission.
r));
201 pbr.
emissive[1] = std::max(0.0f, std::min(1.0f, emission.
g));
202 pbr.
emissive[2] = std::max(0.0f, std::min(1.0f, emission.
b));
205 "[MaterialConverter::FromCCMaterial] Converted material '%s': "
206 "ambient=(%.2f,%.2f,%.2f), diffuse=(%.2f,%.2f,%.2f), "
207 "specular=(%.2f,%.2f,%.2f), shininess=%.2f, opacity=%.2f",
219 "[MaterialConverter::FromPCLMaterial] ENTRY: tex_name=%s, "
221 pclMat.tex_name.c_str(), pclMat.tex_file.c_str());
225 pbr.
name = pclMat.tex_name;
233 std::string tex_name = pclMat.tex_name;
234 size_t pbr_pos = tex_name.find(
"_PBR_MULTITEX");
236 if (pbr_pos != std::string::npos) {
238 size_t start = pbr_pos + 13;
239 int diffuse_count = 0;
240 while (start < tex_name.length() && tex_name[start] ==
'|') {
241 size_t colon = tex_name.find(
':', start + 1);
242 size_t next_pipe = tex_name.find(
'|', colon);
243 if (colon == std::string::npos)
break;
245 std::string type_str =
246 tex_name.substr(start + 1, colon - start - 1);
248 (next_pipe != std::string::npos)
249 ? tex_name.substr(colon + 1, next_pipe - colon - 1)
250 : tex_name.substr(colon + 1);
252 int type = std::stoi(type_str);
275 start = (next_pipe != std::string::npos) ? next_pipe
279 if (diffuse_count > 1) {
282 "[MaterialConverter::FromPCLMaterial] Detected %d map_Kd "
283 "textures for material '%s', will use traditional "
284 "multi-texture rendering",
285 diffuse_count, pbr.
name.c_str());
289 pbr.
name = tex_name.substr(0, pbr_pos);
292 if (!pclMat.tex_file.empty()) {
314 pbr.
shininess = std::max(0.0f, std::min(128.0f, pclMat.tex_Ns));
315 pbr.
opacity = std::max(0.0f, std::min(1.0f, pclMat.tex_d));
328 "[MaterialConverter::FromPCLMaterial] Converted material '%s': "
329 "ambient=(%.2f,%.2f,%.2f), diffuse=(%.2f,%.2f,%.2f), "
330 "specular=(%.2f,%.2f,%.2f), shininess=%.2f, opacity=%.2f",
341 if (!materials || materials->empty()) {
343 "[MaterialConverter::FromMaterialSet] No materials provided");
348 auto firstMaterial = materials->at(0);
349 if (!firstMaterial) {
351 "[MaterialConverter::FromMaterialSet] First material is null!");
365 bool found_pbr_in_other_materials =
false;
368 for (
size_t i = 0; i < materials->size(); ++i) {
369 auto mat = materials->at(i);
370 if (!mat || mat == firstMaterial)
continue;
373 if (mat->hasTextureMap(TexType::NORMAL) ||
374 mat->hasTextureMap(TexType::METALLIC) ||
375 mat->hasTextureMap(TexType::ROUGHNESS) ||
376 mat->hasTextureMap(TexType::AMBIENT)) {
377 found_pbr_in_other_materials =
true;
382 auto diffuse_textures = mat->getTextureFilenames(TexType::DIFFUSE);
383 if (!diffuse_textures.empty()) {
384 found_pbr_in_other_materials =
true;
394 firstMaterial->getTextureFilenames(TexType::DIFFUSE);
398 "[MaterialConverter::FromMaterialSet] Found PBR textures "
400 "other materials, ensuring first material's "
402 "is set for accurate detection");
410 if (!material)
return false;
416 if (mat_name.find(
"_PBR_MULTITEX") != std::string::npos) {
435 if (!materials || materials->empty())
return false;
439 for (
size_t i = 0; i < materials->size(); ++i) {
440 auto mat = materials->at(i);
442 auto diffuse_textures = mat->getTextureFilenames(TexType::DIFFUSE);
443 count += diffuse_textures.size();
451 if (!materials || materials->empty())
return 0;
455 for (
size_t i = 0; i < materials->size(); ++i) {
456 auto mat = materials->at(i);
458 auto diffuse_textures = mat->getTextureFilenames(TexType::DIFFUSE);
459 count +=
static_cast<int>(diffuse_textures.size());
464 "[MaterialConverter::CountMapKd] Counted %d map_Kd textures",
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 VtkUtils::VtkMultiTextureRenderer::PBRMaterial FromCCMaterial(const ccMaterial *ccMat)
Convert ccMaterial to PBRMaterial.
static bool HasPBREncoding(const ccMaterial *material)
Detect if material has PBR encoding.
static int CountMapKd(const ccMaterialSet *materials)
Count map_Kd textures in material set.
static VtkUtils::VtkMultiTextureRenderer::PBRMaterial FromPCLMaterial(const ::pcl::TexMaterial &pclMat)
Convert pcl::TexMaterial to PBRMaterial (deprecated)
static bool HasMultipleMapKd(const ccMaterialSet *materials)
Detect if material set has multiple map_Kd textures.
static VtkUtils::VtkMultiTextureRenderer::PBRMaterial FromMaterialSet(const ccMaterialSet *materials)
Convert first material from ccMaterialSet to PBRMaterial.
Mesh (triangle) material.
Mesh (triangle) material.
float getClearcoatRoughness() const
Returns clearcoat roughness.
TextureMapType
Texture map types for PBR materials.
float getRoughness() const
Returns roughness factor.
float getSheen() const
Returns sheen factor.
float getAmbientOcclusion() const
Returns ambient occlusion factor.
float getMetallic() const
Returns metallic factor.
float getShininessFront() const
Returns front shininess.
const ecvColor::Rgbaf & getEmission() const
Returns emission color.
const ecvColor::Rgbaf & getSpecular() const
Returns specular color.
std::vector< QString > getTextureFilenames(TextureMapType type) const
Get all texture filenames for a specific map type.
const ecvColor::Rgbaf & getDiffuseFront() const
Returns front diffuse color.
bool hasTextureMap(TextureMapType type) const
Check if a specific texture map type exists.
const QString & getTextureFilename() const
Returns the texture filename (if any)
float getClearcoat() const
Returns clearcoat factor.
const ecvColor::Rgbaf & getAmbient() const
Returns ambient color.
float getAnisotropy() const
Returns anisotropy factor.
const QString & getName() const
Returns the material name.
static const std::string path
constexpr ColorCompType OPACITY
Generic PBR material structure (supports multi-texture)
std::string clearcoatTexture
std::string anisotropyTexture
std::string clearcoatRoughnessTexture
std::string emissiveTexture
std::string roughnessTexture
std::string normalTexture
std::string metallicTexture
bool hasPBRTextures() const
std::string baseColorTexture