From 6d933c0e3ac8048e8a04f2b42bcd21a667818c2e Mon Sep 17 00:00:00 2001 From: Julien Duroure Date: Sat, 15 Dec 2018 06:30:27 +0100 Subject: glTF importer: fix material import / vertex color Fixed a bug when a same material sometimes uses vertex color, sometimes doesn't --- io_scene_gltf2/blender/imp/gltf2_blender_gltf.py | 2 +- .../blender/imp/gltf2_blender_map_emissive.py | 8 ++--- .../blender/imp/gltf2_blender_map_normal.py | 8 ++--- .../blender/imp/gltf2_blender_map_occlusion.py | 6 ++-- .../blender/imp/gltf2_blender_material.py | 30 ++++++++++-------- io_scene_gltf2/blender/imp/gltf2_blender_mesh.py | 5 ++- .../blender/imp/gltf2_blender_primitive.py | 36 ++++++++++++++-------- 7 files changed, 57 insertions(+), 38 deletions(-) diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_gltf.py b/io_scene_gltf2/blender/imp/gltf2_blender_gltf.py index 9afc12de..1f708b40 100755 --- a/io_scene_gltf2/blender/imp/gltf2_blender_gltf.py +++ b/io_scene_gltf2/blender/imp/gltf2_blender_gltf.py @@ -84,7 +84,7 @@ class BlenderGlTF(): # Blender material if gltf.data.materials: for material in gltf.data.materials: - material.blender_material = None + material.blender_material = {} if material.pbr_metallic_roughness: # Init diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_map_emissive.py b/io_scene_gltf2/blender/imp/gltf2_blender_map_emissive.py index 81cfd76e..c3d0cb22 100755 --- a/io_scene_gltf2/blender/imp/gltf2_blender_map_emissive.py +++ b/io_scene_gltf2/blender/imp/gltf2_blender_map_emissive.py @@ -23,17 +23,17 @@ class BlenderEmissiveMap(): raise RuntimeError("%s should not be instantiated" % cls) @staticmethod - def create(gltf, material_idx): + def create(gltf, material_idx, vertex_color): """Create emissive map.""" engine = bpy.context.scene.render.engine if engine in ['CYCLES', 'BLENDER_EEVEE']: - BlenderEmissiveMap.create_nodetree(gltf, material_idx) + BlenderEmissiveMap.create_nodetree(gltf, material_idx, vertex_color) - def create_nodetree(gltf, material_idx): + def create_nodetree(gltf, material_idx, vertex_color): """Create node tree.""" pymaterial = gltf.data.materials[material_idx] - material = bpy.data.materials[pymaterial.blender_material] + material = bpy.data.materials[pymaterial.blender_material[vertex_color]] node_tree = material.node_tree BlenderTextureInfo.create(gltf, pymaterial.emissive_texture.index) diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_map_normal.py b/io_scene_gltf2/blender/imp/gltf2_blender_map_normal.py index ab09f24c..0f7bab81 100755 --- a/io_scene_gltf2/blender/imp/gltf2_blender_map_normal.py +++ b/io_scene_gltf2/blender/imp/gltf2_blender_map_normal.py @@ -22,17 +22,17 @@ class BlenderNormalMap(): raise RuntimeError("%s should not be instantiated" % cls) @staticmethod - def create(gltf, material_idx): + def create(gltf, material_idx, vertex_color): """Creation of Normal map.""" engine = bpy.context.scene.render.engine if engine in ['CYCLES', 'BLENDER_EEVEE']: - BlenderNormalMap.create_nodetree(gltf, material_idx) + BlenderNormalMap.create_nodetree(gltf, material_idx, vertex_color) - def create_nodetree(gltf, material_idx): + def create_nodetree(gltf, material_idx, vertex_color): """Creation of Nodetree.""" pymaterial = gltf.data.materials[material_idx] - material = bpy.data.materials[pymaterial.blender_material] + material = bpy.data.materials[pymaterial.blender_material[vertex_color]] node_tree = material.node_tree BlenderTextureInfo.create(gltf, pymaterial.normal_texture.index) diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_map_occlusion.py b/io_scene_gltf2/blender/imp/gltf2_blender_map_occlusion.py index 5c41ce9e..70e1e54a 100755 --- a/io_scene_gltf2/blender/imp/gltf2_blender_map_occlusion.py +++ b/io_scene_gltf2/blender/imp/gltf2_blender_map_occlusion.py @@ -22,13 +22,13 @@ class BlenderOcclusionMap(): raise RuntimeError("%s should not be instantiated" % cls) @staticmethod - def create(gltf, material_idx): + def create(gltf, material_idx, vertex_color): """Occlusion map creation.""" engine = bpy.context.scene.render.engine if engine in ['CYCLES', 'BLENDER_EEVEE']: - BlenderOcclusionMap.create_nodetree(gltf, material_idx) + BlenderOcclusionMap.create_nodetree(gltf, material_idx, vertex_color) - def create_nodetree(gltf, material_idx): + def create_nodetree(gltf, material_idx, vertex_color): """Nodetree creation.""" pymaterial = gltf.data.materials[material_idx] diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_material.py b/io_scene_gltf2/blender/imp/gltf2_blender_material.py index c9fa6927..c910b7f8 100755 --- a/io_scene_gltf2/blender/imp/gltf2_blender_material.py +++ b/io_scene_gltf2/blender/imp/gltf2_blender_material.py @@ -34,13 +34,19 @@ class BlenderMaterial(): """Material creation.""" pymaterial = gltf.data.materials[material_idx] - if pymaterial.name is not None: - name = pymaterial.name + if vertex_color is None: + if pymaterial.name is not None: + name = pymaterial.name + else: + name = "Material_" + str(material_idx) else: - name = "Material_" + str(material_idx) + if pymaterial.name is not None: + name = pymaterial.name + "_" + vertex_color + else: + name = "Material_" + str(material_idx) + "_" + vertex_color mat = bpy.data.materials.new(name) - pymaterial.blender_material = mat.name + pymaterial.blender_material[vertex_color] = mat.name if pymaterial.extensions is not None and 'KHR_materials_pbrSpecularGlossiness' in pymaterial.extensions.keys(): BlenderKHR_materials_pbrSpecularGlossiness.create( @@ -62,36 +68,36 @@ class BlenderMaterial(): # add emission map if needed if pymaterial.emissive_texture is not None: - BlenderEmissiveMap.create(gltf, material_idx) + BlenderEmissiveMap.create(gltf, material_idx, vertex_color) # add normal map if needed if pymaterial.normal_texture is not None: - BlenderNormalMap.create(gltf, material_idx) + BlenderNormalMap.create(gltf, material_idx, vertex_color) # add occlusion map if needed # will be pack, but not used if pymaterial.occlusion_texture is not None: - BlenderOcclusionMap.create(gltf, material_idx) + BlenderOcclusionMap.create(gltf, material_idx, vertex_color) if pymaterial.alpha_mode is not None and pymaterial.alpha_mode != 'OPAQUE': - BlenderMaterial.blender_alpha(gltf, material_idx) + BlenderMaterial.blender_alpha(gltf, material_idx, vertex_color) @staticmethod - def set_uvmap(gltf, material_idx, prim, obj): + def set_uvmap(gltf, material_idx, prim, obj, vertex_color): """Set UV Map.""" pymaterial = gltf.data.materials[material_idx] - node_tree = bpy.data.materials[pymaterial.blender_material].node_tree + node_tree = bpy.data.materials[pymaterial.blender_material[vertex_color]].node_tree uvmap_nodes = [node for node in node_tree.nodes if node.type in ['UVMAP', 'NORMAL_MAP']] for uvmap_node in uvmap_nodes: if uvmap_node["gltf2_texcoord"] in prim.blender_texcoord.keys(): uvmap_node.uv_map = prim.blender_texcoord[uvmap_node["gltf2_texcoord"]] @staticmethod - def blender_alpha(gltf, material_idx): + def blender_alpha(gltf, material_idx, vertex_color): """Set alpha.""" pymaterial = gltf.data.materials[material_idx] - material = bpy.data.materials[pymaterial.blender_material] + material = bpy.data.materials[pymaterial.blender_material[vertex_color]] node_tree = material.node_tree # Add nodes for basic transparency diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py b/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py index f0d0af2a..2d346638 100755 --- a/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py +++ b/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py @@ -79,7 +79,10 @@ class BlenderMesh(): # Object and UV are now created, we can set UVMap into material for prim in pymesh.primitives: - BlenderPrimitive.set_UV_in_mat(gltf, prim, obj) + vertex_color = None + if 'COLOR_0' in prim.attributes.keys(): + vertex_color = 'COLOR_0' + BlenderPrimitive.set_UV_in_mat(gltf, prim, obj, vertex_color) # Assign materials to mesh offset = 0 diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_primitive.py b/io_scene_gltf2/blender/imp/gltf2_blender_primitive.py index 52987383..93bab542 100755 --- a/io_scene_gltf2/blender/imp/gltf2_blender_primitive.py +++ b/io_scene_gltf2/blender/imp/gltf2_blender_primitive.py @@ -57,13 +57,18 @@ class BlenderPrimitive(): # manage material of primitive if pyprimitive.material is not None: - # Create Blender material - # TODO, a same material can have difference COLOR_0 multiplicator - if gltf.data.materials[pyprimitive.material].blender_material is None: - vertex_color = None - if 'COLOR_0' in pyprimitive.attributes.keys(): - vertex_color = pyprimitive.attributes['COLOR_0'] - BlenderMaterial.create(gltf, pyprimitive.material, vertex_color) + vertex_color = None + if 'COLOR_0' in pyprimitive.attributes.keys(): + vertex_color = 'COLOR_0' + + # Create Blender material if needed + if vertex_color is None: + if None not in gltf.data.materials[pyprimitive.material].blender_material.keys(): + BlenderMaterial.create(gltf, pyprimitive.material, vertex_color) + else: + if vertex_color not in gltf.data.materials[pyprimitive.material].blender_material.keys(): + BlenderMaterial.create(gltf, pyprimitive.material, vertex_color) + return verts, edges, faces @@ -126,7 +131,7 @@ class BlenderPrimitive(): offset = offset + pyprimitive.vertices_length return offset - def set_UV_in_mat(gltf, pyprimitive, obj): + def set_UV_in_mat(gltf, pyprimitive, obj, vertex_color): """After nodetree creation, set UVMap in nodes.""" if pyprimitive.material is None: return @@ -137,29 +142,34 @@ class BlenderPrimitive(): and gltf.data.materials[pyprimitive.material].extensions[ 'KHR_materials_pbrSpecularGlossiness' ]['diffuse_type'] in [gltf.TEXTURE, gltf.TEXTURE_FACTOR]: - BlenderMaterial.set_uvmap(gltf, pyprimitive.material, pyprimitive, obj) + BlenderMaterial.set_uvmap(gltf, pyprimitive.material, pyprimitive, obj, vertex_color) else: if pyprimitive.material is not None \ and gltf.data.materials[pyprimitive.material].extensions[ 'KHR_materials_pbrSpecularGlossiness' ]['specgloss_type'] in [gltf.TEXTURE, gltf.TEXTURE_FACTOR]: - BlenderMaterial.set_uvmap(gltf, pyprimitive.material, pyprimitive, obj) + BlenderMaterial.set_uvmap(gltf, pyprimitive.material, pyprimitive, obj, vertex_color) else: if pyprimitive.material is not None \ and gltf.data.materials[pyprimitive.material].pbr_metallic_roughness.color_type in \ [gltf.TEXTURE, gltf.TEXTURE_FACTOR]: - BlenderMaterial.set_uvmap(gltf, pyprimitive.material, pyprimitive, obj) + BlenderMaterial.set_uvmap(gltf, pyprimitive.material, pyprimitive, obj, vertex_color) else: if pyprimitive.material is not None \ and gltf.data.materials[pyprimitive.material].pbr_metallic_roughness.metallic_type in \ [gltf.TEXTURE, gltf.TEXTURE_FACTOR]: - BlenderMaterial.set_uvmap(gltf, pyprimitive.material, pyprimitive, obj) + BlenderMaterial.set_uvmap(gltf, pyprimitive.material, pyprimitive, obj, vertex_color) def assign_material(gltf, pyprimitive, obj, bm, offset, cpt_index_mat): """Assign material to faces of primitives.""" if pyprimitive.material is not None: - obj.data.materials.append(bpy.data.materials[gltf.data.materials[pyprimitive.material].blender_material]) + + vertex_color = None + if 'COLOR_0' in pyprimitive.attributes.keys(): + vertex_color = 'COLOR_0' + + obj.data.materials.append(bpy.data.materials[gltf.data.materials[pyprimitive.material].blender_material[vertex_color]]) for vert in bm.verts: if vert.index in range(offset, offset + pyprimitive.vertices_length): for loop in vert.link_loops: -- cgit v1.2.3