@@ -566,97 +566,97 @@ bool WriteTriangleMeshUsingASSIMP(const std::string& filename,
566566 ai_mat->AddProperty (&ac, 1 , AI_MATKEY_COLOR_EMISSIVE );
567567 }
568568
569- // Count texture maps...
569+ // Build a list of texture-embed actions in a single pass. Each action
570+ // is a lambda that writes one texture slot into the assimp scene; the
571+ // slot index is passed at call time. .
572+ //
570573 // NOTE: GLTF2 expects a single combined roughness/metal map. If the
571574 // model has one we just export it, otherwise if both roughness and
572575 // metal maps are available we combine them, otherwise if only one or
573576 // the other is available we just export the one map.
574577 const auto & material = w_mesh.GetMaterial ();
575- int n_textures = 0 ;
576- if (HasValidTexture (material, " albedo" )) ++n_textures;
577- if (HasValidTexture (material, " normal" )) ++n_textures;
578- if (HasValidTexture (material, " ambient_occlusion" )) ++n_textures;
578+ using TextureAction = std::function<void (int /* slot*/ )>;
579+ std::vector<TextureAction> texture_actions;
580+
581+ if (HasValidTexture (material, " albedo" )) {
582+ texture_actions.push_back ([&](int idx) {
583+ auto img = material.GetAlbedoMap ();
584+ SetTextureMaterialProperty (ai_mat, ai_scene.get (), idx,
585+ aiTextureType_DIFFUSE, img);
586+ SetTextureMaterialProperty (ai_mat, ai_scene.get (), idx,
587+ aiTextureType_BASE_COLOR, img);
588+ });
589+ }
590+ if (HasValidTexture (material, " ambient_occlusion" )) {
591+ texture_actions.push_back ([&](int idx) {
592+ auto img = material.GetAOMap ();
593+ SetTextureMaterialProperty (ai_mat, ai_scene.get (), idx,
594+ aiTextureType_LIGHTMAP, img);
595+ });
596+ }
579597 if (HasValidTexture (material, " ao_rough_metal" )) {
580- ++n_textures;
598+ texture_actions.push_back ([&](int idx) {
599+ auto img = material.GetAORoughnessMetalMap ();
600+ SetTextureMaterialProperty (ai_mat, ai_scene.get (), idx,
601+ aiTextureType_UNKNOWN, img);
602+ });
581603 } else if (HasValidTexture (material, " roughness" ) &&
582604 HasValidTexture (material, " metallic" )) {
583- ++n_textures;
605+ texture_actions.push_back ([&](int idx) {
606+ auto rough = material.GetRoughnessMap ().AsTensor ();
607+ auto metal = material.GetMetallicMap ().AsTensor ();
608+ if (rough.GetShape () != metal.GetShape ()) {
609+ utility::LogError (
610+ " RoughnessMap (shape={}) and MetallicMap "
611+ " (shape={}) must have the same shape." ,
612+ rough.GetShape (), metal.GetShape ());
613+ }
614+ auto rows = rough.GetShape (0 );
615+ auto cols = rough.GetShape (1 );
616+ auto rough_metal = core::Tensor::Full ({rows, cols, 4 }, 255 ,
617+ core::Dtype::UInt8);
618+ rough_metal.Slice (2 , 2 , 3 ) =
619+ metal.Slice (2 , 0 , 1 ); // blue channel is metal
620+ rough_metal.Slice (2 , 1 , 2 ) =
621+ rough.Slice (2 , 0 , 1 ); // green channel is roughness
622+ geometry::Image rough_metal_img (rough_metal);
623+ SetTextureMaterialProperty (ai_mat, ai_scene.get (), idx,
624+ aiTextureType_UNKNOWN,
625+ rough_metal_img);
626+ });
584627 } else {
585- if (HasValidTexture (material, " roughness" )) ++n_textures;
586- if (HasValidTexture (material, " metallic" )) ++n_textures;
628+ if (HasValidTexture (material, " roughness" )) {
629+ texture_actions.push_back ([&](int idx) {
630+ auto img = material.GetRoughnessMap ();
631+ SetTextureMaterialProperty (ai_mat, ai_scene.get (), idx,
632+ aiTextureType_UNKNOWN, img);
633+ });
634+ }
635+ if (HasValidTexture (material, " metallic" )) {
636+ texture_actions.push_back ([&](int idx) {
637+ auto img = material.GetMetallicMap ();
638+ SetTextureMaterialProperty (ai_mat, ai_scene.get (), idx,
639+ aiTextureType_UNKNOWN, img);
640+ });
641+ }
587642 }
643+ if (HasValidTexture (material, " normal" )) {
644+ texture_actions.push_back ([&](int idx) {
645+ auto img = material.GetNormalMap ();
646+ SetTextureMaterialProperty (ai_mat, ai_scene.get (), idx,
647+ aiTextureType_NORMALS, img);
648+ });
649+ }
650+
651+ int n_textures = static_cast <int >(texture_actions.size ());
588652 if (n_textures > 0 ) {
589653 ai_scene->mTextures = new aiTexture*[n_textures];
590654 for (int i = 0 ; i < n_textures; ++i) {
591655 ai_scene->mTextures [i] = new aiTexture ();
656+ texture_actions[i](i);
592657 }
593658 ai_scene->mNumTextures = n_textures;
594659 }
595-
596- // Now embed the textures that are available...
597- int current_idx = 0 ;
598- if (HasValidTexture (material, " albedo" )) {
599- auto img = material.GetAlbedoMap ();
600- SetTextureMaterialProperty (ai_mat, ai_scene.get (), current_idx,
601- aiTextureType_DIFFUSE, img);
602- SetTextureMaterialProperty (ai_mat, ai_scene.get (), current_idx,
603- aiTextureType_BASE_COLOR, img);
604- ++current_idx;
605- }
606- if (HasValidTexture (w_mesh.GetMaterial (), " ambient_occlusion" )) {
607- auto img = w_mesh.GetMaterial ().GetAOMap ();
608- SetTextureMaterialProperty (ai_mat, ai_scene.get (), current_idx,
609- aiTextureType_LIGHTMAP, img);
610- ++current_idx;
611- }
612- if (HasValidTexture (w_mesh.GetMaterial (), " ao_rough_metal" )) {
613- auto img = w_mesh.GetMaterial ().GetAORoughnessMetalMap ();
614- SetTextureMaterialProperty (ai_mat, ai_scene.get (), current_idx,
615- aiTextureType_UNKNOWN, img);
616- ++current_idx;
617- } else if (HasValidTexture (w_mesh.GetMaterial (), " roughness" ) &&
618- HasValidTexture (w_mesh.GetMaterial (), " metallic" )) {
619- auto rough = w_mesh.GetMaterial ().GetRoughnessMap ().AsTensor ();
620- auto metal = w_mesh.GetMaterial ().GetMetallicMap ().AsTensor ();
621- if (rough.GetShape () != metal.GetShape ()) {
622- utility::LogError (
623- " RoughnessMap (shape={}) and MetallicMap (shape={}) "
624- " must have the same shape." ,
625- rough.GetShape (), metal.GetShape ());
626- }
627- auto rows = rough.GetShape (0 );
628- auto cols = rough.GetShape (1 );
629- auto rough_metal = core::Tensor::Full ({rows, cols, 4 }, 255 ,
630- core::Dtype::UInt8);
631- rough_metal.Slice (2 , 2 , 3 ) =
632- metal.Slice (2 , 0 , 1 ); // blue channel is metal
633- rough_metal.Slice (2 , 1 , 2 ) =
634- rough.Slice (2 , 0 , 1 ); // green channel is roughness
635-
636- geometry::Image rough_metal_img (rough_metal);
637- SetTextureMaterialProperty (ai_mat, ai_scene.get (), current_idx,
638- aiTextureType_UNKNOWN, rough_metal_img);
639- ++current_idx;
640- } else {
641- if (HasValidTexture (material, " roughness" )) {
642- auto img = material.GetRoughnessMap ();
643- SetTextureMaterialProperty (ai_mat, ai_scene.get (), current_idx,
644- aiTextureType_UNKNOWN, img);
645- ++current_idx;
646- }
647- if (HasValidTexture (material, " metallic" )) {
648- auto img = material.GetMetallicMap ();
649- SetTextureMaterialProperty (ai_mat, ai_scene.get (), current_idx,
650- aiTextureType_UNKNOWN, img);
651- ++current_idx;
652- }
653- }
654- if (HasValidTexture (material, " normal" )) {
655- auto img = material.GetNormalMap ();
656- SetTextureMaterialProperty (ai_mat, ai_scene.get (), current_idx,
657- aiTextureType_NORMALS, img);
658- ++current_idx;
659- }
660660 }
661661 ai_scene->mMaterials [0 ] = ai_mat;
662662
0 commit comments