glTF exporter: Manage material at object level: instances with different colors
This commit is contained in:
parent
ae500d2891
commit
42493a36ed
|
@ -15,7 +15,7 @@
|
|||
bl_info = {
|
||||
'name': 'glTF 2.0 format',
|
||||
'author': 'Julien Duroure, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors',
|
||||
"version": (0, 9, 23),
|
||||
"version": (0, 9, 24),
|
||||
'blender': (2, 80, 0),
|
||||
'location': 'File > Import-Export',
|
||||
'description': 'Import-Export as glTF 2.0',
|
||||
|
|
|
@ -423,26 +423,23 @@ def extract_primitives(glTF, blender_mesh, blender_vertex_groups, modifiers, exp
|
|||
# Directory of materials with its primitive.
|
||||
#
|
||||
no_material_primitives = {
|
||||
MATERIAL_ID: '',
|
||||
MATERIAL_ID: 0,
|
||||
INDICES_ID: [],
|
||||
ATTRIBUTES_ID: no_material_attributes
|
||||
}
|
||||
|
||||
material_name_to_primitives = {'': no_material_primitives}
|
||||
material_idx_to_primitives = {0: no_material_primitives}
|
||||
|
||||
#
|
||||
|
||||
vertex_index_to_new_indices = {}
|
||||
|
||||
material_map[''] = vertex_index_to_new_indices
|
||||
material_map[0] = vertex_index_to_new_indices
|
||||
|
||||
#
|
||||
# Create primitive for each material.
|
||||
#
|
||||
for blender_material in blender_mesh.materials:
|
||||
if blender_material is None:
|
||||
continue
|
||||
|
||||
for (mat_idx, _) in enumerate(blender_mesh.materials):
|
||||
attributes = {
|
||||
POSITION_ATTRIBUTE: [],
|
||||
NORMAL_ATTRIBUTE: []
|
||||
|
@ -452,18 +449,18 @@ def extract_primitives(glTF, blender_mesh, blender_vertex_groups, modifiers, exp
|
|||
attributes[TANGENT_ATTRIBUTE] = []
|
||||
|
||||
primitive = {
|
||||
MATERIAL_ID: blender_material.name,
|
||||
MATERIAL_ID: mat_idx,
|
||||
INDICES_ID: [],
|
||||
ATTRIBUTES_ID: attributes
|
||||
}
|
||||
|
||||
material_name_to_primitives[blender_material.name] = primitive
|
||||
material_idx_to_primitives[mat_idx] = primitive
|
||||
|
||||
#
|
||||
|
||||
vertex_index_to_new_indices = {}
|
||||
|
||||
material_map[blender_material.name] = vertex_index_to_new_indices
|
||||
material_map[mat_idx] = vertex_index_to_new_indices
|
||||
|
||||
tex_coord_max = 0
|
||||
if blender_mesh.uv_layers.active:
|
||||
|
@ -519,13 +516,12 @@ def extract_primitives(glTF, blender_mesh, blender_vertex_groups, modifiers, exp
|
|||
|
||||
#
|
||||
|
||||
if blender_polygon.material_index < 0 or blender_polygon.material_index >= len(blender_mesh.materials) or \
|
||||
blender_mesh.materials[blender_polygon.material_index] is None:
|
||||
primitive = material_name_to_primitives['']
|
||||
vertex_index_to_new_indices = material_map['']
|
||||
if not blender_polygon.material_index in material_idx_to_primitives:
|
||||
primitive = material_idx_to_primitives[0]
|
||||
vertex_index_to_new_indices = material_map[0]
|
||||
else:
|
||||
primitive = material_name_to_primitives[blender_mesh.materials[blender_polygon.material_index].name]
|
||||
vertex_index_to_new_indices = material_map[blender_mesh.materials[blender_polygon.material_index].name]
|
||||
primitive = material_idx_to_primitives[blender_polygon.material_index]
|
||||
vertex_index_to_new_indices = material_map[blender_polygon.material_index]
|
||||
#
|
||||
|
||||
attributes = primitive[ATTRIBUTES_ID]
|
||||
|
@ -920,7 +916,7 @@ def extract_primitives(glTF, blender_mesh, blender_vertex_groups, modifiers, exp
|
|||
|
||||
result_primitives = []
|
||||
|
||||
for material_name, primitive in material_name_to_primitives.items():
|
||||
for material_idx, primitive in material_idx_to_primitives.items():
|
||||
export_color = True
|
||||
|
||||
#
|
||||
|
@ -993,7 +989,7 @@ def extract_primitives(glTF, blender_mesh, blender_vertex_groups, modifiers, exp
|
|||
pending_attributes[TANGENT_ATTRIBUTE] = []
|
||||
|
||||
pending_primitive = {
|
||||
MATERIAL_ID: material_name,
|
||||
MATERIAL_ID: material_idx,
|
||||
INDICES_ID: [],
|
||||
ATTRIBUTES_ID: pending_attributes
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
# limitations under the License.
|
||||
|
||||
import bpy
|
||||
from typing import Optional, Dict, List, Any
|
||||
from typing import Optional, Dict, List, Any, Tuple
|
||||
from .gltf2_blender_export_keys import MORPH
|
||||
from io_scene_gltf2.blender.exp.gltf2_blender_gather_cache import cached
|
||||
from io_scene_gltf2.io.com import gltf2_io
|
||||
|
@ -23,21 +23,22 @@ from io_scene_gltf2.io.com.gltf2_io_debug import print_console
|
|||
|
||||
|
||||
@cached
|
||||
def gather_mesh(blender_mesh: bpy.types.Mesh,
|
||||
def gather_mesh(blender_mesh_name: str,
|
||||
vertex_groups: Optional[bpy.types.VertexGroups],
|
||||
modifiers: Optional[bpy.types.ObjectModifiers],
|
||||
skip_filter: bool,
|
||||
material_names: Tuple[str],
|
||||
export_settings
|
||||
) -> Optional[gltf2_io.Mesh]:
|
||||
if not skip_filter and not __filter_mesh(blender_mesh, vertex_groups, modifiers, export_settings):
|
||||
if not skip_filter and not __filter_mesh(blender_mesh_name, vertex_groups, modifiers, export_settings):
|
||||
return None
|
||||
|
||||
mesh = gltf2_io.Mesh(
|
||||
extensions=__gather_extensions(blender_mesh, vertex_groups, modifiers, export_settings),
|
||||
extras=__gather_extras(blender_mesh, vertex_groups, modifiers, export_settings),
|
||||
name=__gather_name(blender_mesh, vertex_groups, modifiers, export_settings),
|
||||
primitives=__gather_primitives(blender_mesh, vertex_groups, modifiers, export_settings),
|
||||
weights=__gather_weights(blender_mesh, vertex_groups, modifiers, export_settings)
|
||||
extensions=__gather_extensions(blender_mesh_name, vertex_groups, modifiers, export_settings),
|
||||
extras=__gather_extras(blender_mesh_name, vertex_groups, modifiers, export_settings),
|
||||
name=__gather_name(blender_mesh_name, vertex_groups, modifiers, export_settings),
|
||||
primitives=__gather_primitives(blender_mesh_name, vertex_groups, modifiers, material_names, export_settings),
|
||||
weights=__gather_weights(blender_mesh_name, vertex_groups, modifiers, export_settings)
|
||||
)
|
||||
|
||||
if len(mesh.primitives) == 0:
|
||||
|
@ -46,17 +47,18 @@ def gather_mesh(blender_mesh: bpy.types.Mesh,
|
|||
return mesh
|
||||
|
||||
|
||||
def __filter_mesh(blender_mesh: bpy.types.Mesh,
|
||||
def __filter_mesh(blender_mesh_name: str,
|
||||
vertex_groups: Optional[bpy.types.VertexGroups],
|
||||
modifiers: Optional[bpy.types.ObjectModifiers],
|
||||
export_settings
|
||||
) -> bool:
|
||||
blender_mesh = bpy.data.meshes[blender_mesh_name]
|
||||
if blender_mesh.users == 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def __gather_extensions(blender_mesh: bpy.types.Mesh,
|
||||
def __gather_extensions(blender_mesh_name: str,
|
||||
vertex_groups: Optional[bpy.types.VertexGroups],
|
||||
modifiers: Optional[bpy.types.ObjectModifiers],
|
||||
export_settings
|
||||
|
@ -64,11 +66,12 @@ def __gather_extensions(blender_mesh: bpy.types.Mesh,
|
|||
return None
|
||||
|
||||
|
||||
def __gather_extras(blender_mesh: bpy.types.Mesh,
|
||||
def __gather_extras(blender_mesh_name: str,
|
||||
vertex_groups: Optional[bpy.types.VertexGroups],
|
||||
modifiers: Optional[bpy.types.ObjectModifiers],
|
||||
export_settings
|
||||
) -> Optional[Dict[Any, Any]]:
|
||||
blender_mesh = bpy.data.meshes[blender_mesh_name]
|
||||
extras = {}
|
||||
|
||||
if export_settings['gltf_extras']:
|
||||
|
@ -89,28 +92,33 @@ def __gather_extras(blender_mesh: bpy.types.Mesh,
|
|||
return None
|
||||
|
||||
|
||||
def __gather_name(blender_mesh: bpy.types.Mesh,
|
||||
def __gather_name(blender_mesh_name: str,
|
||||
vertex_groups: Optional[bpy.types.VertexGroups],
|
||||
modifiers: Optional[bpy.types.ObjectModifiers],
|
||||
export_settings
|
||||
) -> str:
|
||||
return blender_mesh.name
|
||||
return blender_mesh_name
|
||||
|
||||
|
||||
def __gather_primitives(blender_mesh: bpy.types.Mesh,
|
||||
def __gather_primitives(blender_mesh_name: str,
|
||||
vertex_groups: Optional[bpy.types.VertexGroups],
|
||||
modifiers: Optional[bpy.types.ObjectModifiers],
|
||||
material_names: Tuple[str],
|
||||
export_settings
|
||||
) -> List[gltf2_io.MeshPrimitive]:
|
||||
return gltf2_blender_gather_primitives.gather_primitives(blender_mesh, vertex_groups, modifiers, export_settings)
|
||||
return gltf2_blender_gather_primitives.gather_primitives(blender_mesh_name,
|
||||
vertex_groups,
|
||||
modifiers,
|
||||
material_names,
|
||||
export_settings)
|
||||
|
||||
|
||||
def __gather_weights(blender_mesh: bpy.types.Mesh,
|
||||
def __gather_weights(blender_mesh_name: str,
|
||||
vertex_groups: Optional[bpy.types.VertexGroups],
|
||||
modifiers: Optional[bpy.types.ObjectModifiers],
|
||||
export_settings
|
||||
) -> Optional[List[float]]:
|
||||
|
||||
blender_mesh = bpy.data.meshes[blender_mesh_name]
|
||||
if not export_settings[MORPH] or not blender_mesh.shape_keys:
|
||||
return None
|
||||
|
||||
|
|
|
@ -241,7 +241,13 @@ def __gather_mesh(blender_object, export_settings):
|
|||
blender_mesh = blender_object.data
|
||||
skip_filter = False
|
||||
|
||||
result = gltf2_blender_gather_mesh.gather_mesh(blender_mesh, vertex_groups, modifiers, skip_filter, export_settings)
|
||||
material_names = tuple([ms.material.name for ms in blender_object.material_slots])
|
||||
result = gltf2_blender_gather_mesh.gather_mesh(blender_mesh.name,
|
||||
vertex_groups,
|
||||
modifiers,
|
||||
skip_filter,
|
||||
material_names,
|
||||
export_settings)
|
||||
|
||||
if export_settings[gltf2_blender_export_keys.APPLY]:
|
||||
blender_mesh_owner.to_mesh_clear()
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
# limitations under the License.
|
||||
|
||||
import bpy
|
||||
from typing import List, Optional
|
||||
from typing import List, Optional, Tuple
|
||||
|
||||
from .gltf2_blender_export_keys import NORMALS, MORPH_NORMAL, TANGENTS, MORPH_TANGENT, MORPH
|
||||
|
||||
|
@ -32,9 +32,10 @@ from io_scene_gltf2.io.com.gltf2_io_debug import print_console
|
|||
|
||||
@cached
|
||||
def gather_primitives(
|
||||
blender_mesh: bpy.types.Mesh,
|
||||
blender_mesh_name: str,
|
||||
vertex_groups: Optional[bpy.types.VertexGroups],
|
||||
modifiers: Optional[bpy.types.ObjectModifiers],
|
||||
material_names: Tuple[str],
|
||||
export_settings
|
||||
) -> List[gltf2_io.MeshPrimitive]:
|
||||
"""
|
||||
|
@ -43,33 +44,64 @@ def gather_primitives(
|
|||
:return: a list of glTF2 primitives
|
||||
"""
|
||||
primitives = []
|
||||
blender_primitives = gltf2_blender_extract.extract_primitives(
|
||||
None, blender_mesh, vertex_groups, modifiers, export_settings)
|
||||
|
||||
blender_primitives = __gather_cache_primitives(blender_mesh_name,
|
||||
vertex_groups, modifiers, export_settings)
|
||||
|
||||
for internal_primitive in blender_primitives:
|
||||
material_idx = internal_primitive['material']
|
||||
double_sided = False
|
||||
material = None
|
||||
try:
|
||||
blender_material = bpy.data.materials[material_names[material_idx]]
|
||||
double_sided = not blender_material.use_backface_culling
|
||||
material = gltf2_blender_gather_materials.gather_material(blender_material,
|
||||
double_sided,
|
||||
export_settings)
|
||||
except IndexError:
|
||||
# no material at that index
|
||||
pass
|
||||
|
||||
|
||||
primitive = gltf2_io.MeshPrimitive(
|
||||
attributes=__gather_attributes(internal_primitive, blender_mesh, modifiers, export_settings),
|
||||
attributes=internal_primitive['attributes'],
|
||||
extensions=None,
|
||||
extras=None,
|
||||
indices=__gather_indices(internal_primitive, blender_mesh, modifiers, export_settings),
|
||||
material=__gather_materials(internal_primitive, modifiers, export_settings),
|
||||
indices=internal_primitive['indices'],
|
||||
material=material,
|
||||
mode=None,
|
||||
targets=__gather_targets(internal_primitive, blender_mesh, modifiers, export_settings)
|
||||
targets=internal_primitive['targets']
|
||||
)
|
||||
primitives.append(primitive)
|
||||
|
||||
return primitives
|
||||
|
||||
@cached
|
||||
def __gather_cache_primitives(
|
||||
blender_mesh_name: str,
|
||||
vertex_groups: Optional[bpy.types.VertexGroups],
|
||||
modifiers: Optional[bpy.types.ObjectModifiers],
|
||||
export_settings
|
||||
) -> List[dict]:
|
||||
"""
|
||||
Gather parts that are identical for instances, i.e. excluding materials
|
||||
"""
|
||||
blender_mesh = bpy.data.meshes[blender_mesh_name]
|
||||
primitives = []
|
||||
|
||||
def __gather_materials(blender_primitive, modifiers, export_settings):
|
||||
if not blender_primitive['material']:
|
||||
# TODO: fix 'extract_primitives' so that the value of 'material' is None and not empty string
|
||||
return None
|
||||
material = bpy.data.materials[blender_primitive['material']]
|
||||
material_double_sided = not material.use_backface_culling
|
||||
return gltf2_blender_gather_materials.gather_material(material, material_double_sided, export_settings)
|
||||
blender_primitives = gltf2_blender_extract.extract_primitives(
|
||||
None, blender_mesh, vertex_groups, modifiers, export_settings)
|
||||
|
||||
for internal_primitive in blender_primitives:
|
||||
primitive = {
|
||||
"attributes": __gather_attributes(internal_primitive, blender_mesh, modifiers, export_settings),
|
||||
"indices": __gather_indices(internal_primitive, blender_mesh, modifiers, export_settings),
|
||||
"material": internal_primitive['material'],
|
||||
"targets": __gather_targets(internal_primitive, blender_mesh, modifiers, export_settings)
|
||||
}
|
||||
primitives.append(primitive)
|
||||
|
||||
return primitives
|
||||
|
||||
def __gather_indices(blender_primitive, blender_mesh, modifiers, export_settings):
|
||||
indices = blender_primitive['indices']
|
||||
|
|
Loading…
Reference in New Issue