New Addon: Import Autodesk .max #105013
@ -1331,7 +1331,7 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
|
||||
elif new_chunk.ID == MORPH_SMOOTH and tracking == 'OBJECT': # Smooth angle
|
||||
smooth_angle = read_float(new_chunk)
|
||||
if child.data is not None: # Check if child is a dummy
|
||||
child.data.set_sharp_from_angle(smooth_angle)
|
||||
child.data.set_sharp_from_angle(angle=smooth_angle)
|
||||
|
||||
elif KEYFRAME and new_chunk.ID == COL_TRACK_TAG and tracking == 'AMBIENT': # Ambient
|
||||
keyframe_data = {}
|
||||
|
@ -5,7 +5,7 @@
|
||||
bl_info = {
|
||||
'name': 'glTF 2.0 format',
|
||||
'author': 'Julien Duroure, Scurest, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors',
|
||||
"version": (4, 1, 13),
|
||||
"version": (4, 1, 17),
|
||||
'blender': (4, 1, 0),
|
||||
'location': 'File > Import-Export',
|
||||
'description': 'Import-Export as glTF 2.0',
|
||||
@ -324,8 +324,8 @@ class ExportGLTF2_Base(ConvertGLTF2_Base):
|
||||
)
|
||||
|
||||
export_colors: BoolProperty(
|
||||
name='Vertex Colors',
|
||||
description='Export vertex colors with meshes',
|
||||
name='dummy',
|
||||
description='Keep for compatibility only',
|
||||
default=True
|
||||
)
|
||||
|
||||
@ -810,7 +810,6 @@ class ExportGLTF2_Base(ConvertGLTF2_Base):
|
||||
export_settings['gltf_draco_mesh_compression'] = False
|
||||
|
||||
export_settings['gltf_materials'] = self.export_materials
|
||||
export_settings['gltf_colors'] = self.export_colors
|
||||
export_settings['gltf_attributes'] = self.export_attributes
|
||||
export_settings['gltf_cameras'] = self.export_cameras
|
||||
|
||||
@ -1097,7 +1096,6 @@ class GLTF_PT_export_data_mesh(bpy.types.Panel):
|
||||
col = layout.column()
|
||||
col.active = operator.export_normals
|
||||
col.prop(operator, 'export_tangents')
|
||||
layout.prop(operator, 'export_colors')
|
||||
layout.prop(operator, 'export_attributes')
|
||||
|
||||
col = layout.column()
|
||||
|
@ -116,7 +116,7 @@ def __fix_json(obj):
|
||||
|
||||
|
||||
def __should_include_json_value(key, value):
|
||||
allowed_empty_collections = ["KHR_materials_unlit", "KHR_materials_specular"]
|
||||
allowed_empty_collections = ["KHR_materials_unlit"]
|
||||
|
||||
if value is None:
|
||||
return False
|
||||
|
@ -55,7 +55,7 @@ def __gather_intensity(blender_lamp, export_settings) -> Optional[float]:
|
||||
if blender_lamp.type != 'SUN':
|
||||
# When using cycles, the strength should be influenced by a LightFalloff node
|
||||
result = gltf2_blender_search_node_tree.from_socket(
|
||||
emission_node.inputs.get("Strength"),
|
||||
gltf2_blender_search_node_tree.NodeSocket(emission_node.inputs.get("Strength"), blender_lamp),
|
||||
gltf2_blender_search_node_tree.FilterByType(bpy.types.ShaderNodeLightFalloff)
|
||||
)
|
||||
if result:
|
||||
@ -131,7 +131,7 @@ def __get_cycles_emission_node(blender_lamp) -> Optional[bpy.types.ShaderNodeEmi
|
||||
if not currentNode.is_active_output:
|
||||
continue
|
||||
result = gltf2_blender_search_node_tree.from_socket(
|
||||
currentNode.inputs.get("Surface"),
|
||||
gltf2_blender_search_node_tree.NodeSocket(currentNode.inputs.get("Surface"), blender_lamp),
|
||||
gltf2_blender_search_node_tree.FilterByType(bpy.types.ShaderNodeEmission)
|
||||
)
|
||||
if not result:
|
||||
|
@ -10,7 +10,7 @@ from ...io.com.gltf2_io_constants import ROUNDING_DIGIT
|
||||
from ...io.exp.gltf2_io_user_extensions import export_user_extensions
|
||||
from ...io.com import gltf2_io_constants
|
||||
from ..com import gltf2_blender_conversion
|
||||
from .material.gltf2_blender_gather_materials import get_base_material
|
||||
from .material.gltf2_blender_gather_materials import get_base_material, get_material_from_idx
|
||||
from . import gltf2_blender_gather_skins
|
||||
|
||||
|
||||
@ -24,7 +24,7 @@ def extract_primitives(materials, blender_mesh, uuid_for_skined_data, blender_ve
|
||||
primitive_creator.create_dots_data_structure()
|
||||
primitive_creator.populate_dots_data()
|
||||
primitive_creator.primitive_split()
|
||||
primitive_creator.material_uvmap_attribute_add()
|
||||
primitive_creator.manage_material_info() # UVMap & Vertex Color
|
||||
return primitive_creator.primitive_creation()
|
||||
|
||||
class PrimitiveCreator:
|
||||
@ -142,7 +142,7 @@ class PrimitiveCreator:
|
||||
self.attr_name = attr_name
|
||||
self.keep = attr_name.startswith("_")
|
||||
|
||||
# Manage attributes + COLOR_0
|
||||
# Manage attributes
|
||||
for blender_attribute_index, blender_attribute in enumerate(self.blender_mesh.attributes):
|
||||
|
||||
attr = {}
|
||||
@ -162,42 +162,27 @@ class PrimitiveCreator:
|
||||
|
||||
continue
|
||||
|
||||
if self.blender_mesh.color_attributes.find(blender_attribute.name) == self.blender_mesh.color_attributes.render_color_index \
|
||||
and self.blender_mesh.color_attributes.render_color_index != -1:
|
||||
# Custom attributes
|
||||
# Keep only attributes that starts with _
|
||||
# As Blender create lots of attributes that are internal / not needed are as duplicated of standard glTF accessors (position, uv, material_index...)
|
||||
if self.export_settings['gltf_attributes'] is False:
|
||||
continue
|
||||
# Check if there is an extension that want to keep this attribute, or change the exported name
|
||||
keep_attribute = KeepAttribute(blender_attribute.name)
|
||||
|
||||
if self.export_settings['gltf_colors'] is False:
|
||||
continue
|
||||
attr['gltf_attribute_name'] = 'COLOR_0'
|
||||
attr['get'] = self.get_function()
|
||||
export_user_extensions('gather_attribute_keep', self.export_settings, keep_attribute)
|
||||
|
||||
# Seems we sometime can have name collision about attributes
|
||||
# Avoid crash and ignoring one of duplicated attribute name
|
||||
if 'COLOR_0' in [a['gltf_attribute_name'] for a in self.blender_attributes]:
|
||||
print_console('WARNING', 'Attribute (vertex color) collision name: ' + blender_attribute.name + ", ignoring one of them")
|
||||
continue
|
||||
if keep_attribute.keep is False:
|
||||
continue
|
||||
|
||||
else:
|
||||
# Custom attributes
|
||||
# Keep only attributes that starts with _
|
||||
# As Blender create lots of attributes that are internal / not needed are as duplicated of standard glTF accessors (position, uv, material_index...)
|
||||
if self.export_settings['gltf_attributes'] is False:
|
||||
continue
|
||||
# Check if there is an extension that want to keep this attribute, or change the exported name
|
||||
keep_attribute = KeepAttribute(blender_attribute.name)
|
||||
attr['gltf_attribute_name'] = keep_attribute.attr_name.upper()
|
||||
attr['get'] = self.get_function()
|
||||
|
||||
export_user_extensions('gather_attribute_keep', self.export_settings, keep_attribute)
|
||||
|
||||
if keep_attribute.keep is False:
|
||||
continue
|
||||
|
||||
attr['gltf_attribute_name'] = keep_attribute.attr_name.upper()
|
||||
attr['get'] = self.get_function()
|
||||
|
||||
# Seems we sometime can have name collision about attributes
|
||||
# Avoid crash and ignoring one of duplicated attribute name
|
||||
if attr['gltf_attribute_name'] in [a['gltf_attribute_name'] for a in self.blender_attributes]:
|
||||
print_console('WARNING', 'Attribute collision name: ' + blender_attribute.name + ", ignoring one of them")
|
||||
continue
|
||||
# Seems we sometime can have name collision about attributes
|
||||
# Avoid crash and ignoring one of duplicated attribute name
|
||||
if attr['gltf_attribute_name'] in [a['gltf_attribute_name'] for a in self.blender_attributes]:
|
||||
print_console('WARNING', 'Attribute collision name: ' + blender_attribute.name + ", ignoring one of them")
|
||||
continue
|
||||
|
||||
self.blender_attributes.append(attr)
|
||||
|
||||
@ -388,12 +373,18 @@ class PrimitiveCreator:
|
||||
for material_idx in unique_material_idxs:
|
||||
self.prim_indices[material_idx] = loop_indices[loop_material_idxs == material_idx]
|
||||
|
||||
def material_uvmap_attribute_add(self):
|
||||
def manage_material_info(self):
|
||||
# If user defined UVMap as a custom attribute, we need to add it/them in the dots structure and populate data
|
||||
# So we need to get, for each material, what are these custom attribute
|
||||
# No choice : We need to retrieve materials here. Anyway, this will be baked, and next call will be quick
|
||||
# We also need to shuffle Vertex Color data if needed
|
||||
|
||||
materials_use_vc = None
|
||||
warning_already_displayed = False
|
||||
for material_idx in self.prim_indices.keys():
|
||||
_, material_info = get_base_material(material_idx, self.materials, self.export_settings)
|
||||
|
||||
# UVMaps
|
||||
self.uvmap_attribute_list = list(set([i['value'] for i in material_info["uv_info"].values() if 'type' in i.keys() and i['type'] == "Attribute" ]))
|
||||
|
||||
additional_fields = []
|
||||
@ -402,10 +393,11 @@ class PrimitiveCreator:
|
||||
additional_fields.append((attr + str(0), gltf2_blender_conversion.get_numpy_type('FLOAT2')))
|
||||
additional_fields.append((attr + str(1), gltf2_blender_conversion.get_numpy_type('FLOAT2')))
|
||||
|
||||
new_dt = np.dtype(self.dots.dtype.descr + additional_fields)
|
||||
dots = np.zeros(self.dots.shape, dtype=new_dt)
|
||||
for f in self.dots.dtype.names:
|
||||
dots[f] = self.dots[f]
|
||||
if len(additional_fields) > 0:
|
||||
new_dt = np.dtype(self.dots.dtype.descr + additional_fields)
|
||||
dots = np.zeros(self.dots.shape, dtype=new_dt)
|
||||
for f in self.dots.dtype.names:
|
||||
dots[f] = self.dots[f]
|
||||
|
||||
# Now we need to get data and populate
|
||||
for attr in self.uvmap_attribute_list:
|
||||
@ -424,7 +416,57 @@ class PrimitiveCreator:
|
||||
dots[attr + '1'] = data[:, 1]
|
||||
del data
|
||||
|
||||
self.dots = dots
|
||||
if len(additional_fields) > 0:
|
||||
self.dots = dots
|
||||
|
||||
# There are multiple case to take into account for VC
|
||||
|
||||
# The simplier test is when no vertex color are used
|
||||
if material_info['vc_info']['color_type'] is None and material_info['vc_info']['alpha_type'] is None:
|
||||
# Nothing to do
|
||||
continue
|
||||
|
||||
if material_info['vc_info']['color_type'] is None and material_info['vc_info']['alpha_type'] is not None:
|
||||
print_console('WARNING', 'We are not managing this case (Vertex Color alpha without color)')
|
||||
continue
|
||||
|
||||
vc_color_name = None
|
||||
vc_alpha_name = None
|
||||
if material_info['vc_info']['color_type'] == "name":
|
||||
vc_color_name = material_info['vc_info']['color']
|
||||
elif material_info['vc_info']['color_type'] == "active":
|
||||
# Get active (render) Vertex Color
|
||||
vc_color_name = self.blender_mesh.color_attributes[self.blender_mesh.color_attributes.render_color_index].name
|
||||
|
||||
if material_info['vc_info']['alpha_type'] == "name":
|
||||
vc_alpha_name = material_info['vc_info']['alpha']
|
||||
elif material_info['vc_info']['alpha_type'] == "active":
|
||||
# Get active (render) Vertex Color
|
||||
vc_alpha_name = self.blender_mesh.color_attributes[self.blender_mesh.color_attributes.render_color_index].name
|
||||
|
||||
if vc_color_name is not None:
|
||||
|
||||
vc_key = ""
|
||||
vc_key += vc_color_name if vc_color_name is not None else ""
|
||||
vc_key += vc_alpha_name if vc_alpha_name is not None else ""
|
||||
|
||||
if materials_use_vc is not None and materials_use_vc != vc_key:
|
||||
if warning_already_displayed is False:
|
||||
print_console('WARNING', 'glTF specification does not allow this case (multiple materials with different Vertex Color)')
|
||||
warning_already_displayed = True
|
||||
materials_use_vc = vc_key
|
||||
continue
|
||||
elif materials_use_vc is None:
|
||||
materials_use_vc = vc_key
|
||||
|
||||
# We need to check if we need to add alpha
|
||||
add_alpha = vc_alpha_name is not None
|
||||
mat = get_material_from_idx(material_idx, self.materials, self.export_settings)
|
||||
add_alpha = add_alpha and not (mat.blend_method is None or mat.blend_method == 'OPAQUE')
|
||||
# Manage Vertex Color (RGB and Alpha if needed)
|
||||
self.__manage_color_attribute(vc_color_name, vc_alpha_name if add_alpha else None)
|
||||
else:
|
||||
pass # Using the same Vertex Color
|
||||
|
||||
def primitive_creation(self):
|
||||
primitives = []
|
||||
@ -628,9 +670,7 @@ class PrimitiveCreator:
|
||||
def get_function(self):
|
||||
|
||||
def getting_function(attr):
|
||||
if attr['gltf_attribute_name'] == "COLOR_0":
|
||||
self.__get_color_attribute(attr)
|
||||
elif attr['gltf_attribute_name'].startswith("_"):
|
||||
if attr['gltf_attribute_name'].startswith("_"):
|
||||
self.__get_layer_attribute(attr)
|
||||
elif attr['gltf_attribute_name'].startswith("TEXCOORD_"):
|
||||
self.__get_uvs_attribute(int(attr['gltf_attribute_name'].split("_")[-1]), attr)
|
||||
@ -642,15 +682,79 @@ class PrimitiveCreator:
|
||||
return getting_function
|
||||
|
||||
|
||||
def __get_color_attribute(self, attr):
|
||||
blender_color_idx = self.blender_mesh.color_attributes.render_color_index
|
||||
def __manage_color_attribute(self, attr_name, attr_name_alpha):
|
||||
blender_color_idx = self.blender_mesh.color_attributes.find(attr_name)
|
||||
if blender_color_idx < 0:
|
||||
return None
|
||||
|
||||
if attr['blender_domain'] == "POINT":
|
||||
# Add COLOR_0 in dots data
|
||||
|
||||
attr = self.blender_mesh.color_attributes[blender_color_idx]
|
||||
|
||||
# Get data
|
||||
data_dots, data_dots_edges, data_dots_points = self.__get_color_attribute_data(attr)
|
||||
|
||||
# Get data for alpha if needed
|
||||
if attr_name_alpha is not None and attr_name_alpha != attr_name:
|
||||
blender_alpha_idx = self.blender_mesh.color_attributes.find(attr_name_alpha)
|
||||
if blender_alpha_idx >= 0:
|
||||
attr_alpha = self.blender_mesh.color_attributes[blender_alpha_idx]
|
||||
data_dots_alpha, data_dots_edges_alpha, data_dots_points_alpha = self.__get_color_attribute_data(attr_alpha)
|
||||
# Merging data
|
||||
data_dots[:, 3] = data_dots_alpha[:, 3]
|
||||
if data_dots_edges is not None:
|
||||
data_dots_edges[:, 3] = data_dots_edges_alpha[:, 3]
|
||||
if data_dots_points is not None:
|
||||
data_dots_points[:, 3] = data_dots_points_alpha[:, 3]
|
||||
|
||||
# Check if we need to get alpha (the 4th channel) here
|
||||
max_index = 4 if attr_name_alpha is not None else 3
|
||||
|
||||
# Add this data to dots structure
|
||||
additional_fields = []
|
||||
for i in range(max_index):
|
||||
# Must calculate the type of the field : FLOAT_COLOR or BYTE_COLOR
|
||||
additional_fields.append(('COLOR_0' + str(i), gltf2_blender_conversion.get_numpy_type('FLOAT_COLOR' if max_index == 3 else 'BYTE_COLOR')))
|
||||
|
||||
# Keep the existing custom attribute
|
||||
# Data will be exported twice, one for COLOR_O, one for the custom attribute
|
||||
new_dt = np.dtype(self.dots.dtype.descr + additional_fields)
|
||||
dots = np.zeros(self.dots.shape, dtype=new_dt)
|
||||
for f in self.dots.dtype.names:
|
||||
dots[f] = self.dots[f]
|
||||
|
||||
self.dots = dots
|
||||
|
||||
# colors are already linear, no need to switch color space
|
||||
for i in range(max_index):
|
||||
self.dots['COLOR_0' +str(i)] = data_dots[:, i]
|
||||
if self.export_settings['gltf_loose_edges'] and attr.domain == "POINT":
|
||||
self.dots_edges['COLOR_0' + str(i)] = data_dots_edges[:, i]
|
||||
if self.export_settings['gltf_loose_points'] and attr['blender_domain'] == "POINT":
|
||||
self.dots_points['COLOR_0' + str(i)] = data_dots_points[:, i]
|
||||
|
||||
# Add COLOR_0 in attribute list
|
||||
attr_color_0 = {}
|
||||
attr_color_0['blender_data_type'] = 'FLOAT_COLOR' if max_index == 3 else 'BYTE_COLOR'
|
||||
attr_color_0['blender_domain'] = attr.domain
|
||||
attr_color_0['gltf_attribute_name'] = 'COLOR_0'
|
||||
attr_color_0['len'] = max_index # 3 or 4, depending if we have alpha
|
||||
attr_color_0['type'] = gltf2_blender_conversion.get_numpy_type(attr_color_0['blender_data_type'])
|
||||
attr_color_0['component_type'] = gltf2_blender_conversion.get_component_type(attr_color_0['blender_data_type'])
|
||||
attr_color_0['data_type'] = gltf2_io_constants.DataType.Vec3 if max_index == 3 else gltf2_io_constants.DataType.Vec4
|
||||
|
||||
self.blender_attributes.append(attr_color_0)
|
||||
|
||||
def __get_color_attribute_data(self, attr):
|
||||
data_dots_edges = None
|
||||
data_dots_points = None
|
||||
|
||||
if attr.domain == "POINT":
|
||||
colors = np.empty(len(self.blender_mesh.vertices) * 4, dtype=np.float32)
|
||||
elif attr['blender_domain'] == "CORNER":
|
||||
elif attr.domain == "CORNER":
|
||||
colors = np.empty(len(self.blender_mesh.loops) * 4, dtype=np.float32)
|
||||
self.blender_mesh.color_attributes[blender_color_idx].data.foreach_get('color', colors)
|
||||
if attr['blender_domain'] == "POINT":
|
||||
attr.data.foreach_get('color', colors)
|
||||
if attr.domain == "POINT":
|
||||
colors = colors.reshape(-1, 4)
|
||||
data_dots = colors[self.dots['vertex_index']]
|
||||
if self.export_settings['gltf_loose_edges']:
|
||||
@ -658,18 +762,13 @@ class PrimitiveCreator:
|
||||
if self.export_settings['gltf_loose_points']:
|
||||
data_dots_points = colors[self.dots_points['vertex_index']]
|
||||
|
||||
elif attr['blender_domain'] == "CORNER":
|
||||
elif attr.domain == "CORNER":
|
||||
colors = colors.reshape(-1, 4)
|
||||
data_dots = colors
|
||||
|
||||
del colors
|
||||
# colors are already linear, no need to switch color space
|
||||
for i in range(4):
|
||||
self.dots[attr['gltf_attribute_name'] + str(i)] = data_dots[:, i]
|
||||
if self.export_settings['gltf_loose_edges'] and attr['blender_domain'] == "POINT":
|
||||
self.dots_edges[attr['gltf_attribute_name'] + str(i)] = data_dots_edges[:, i]
|
||||
if self.export_settings['gltf_loose_points'] and attr['blender_domain'] == "POINT":
|
||||
self.dots_points[attr['gltf_attribute_name'] + str(i)] = data_dots_points[:, i]
|
||||
|
||||
return data_dots, data_dots_edges, data_dots_points
|
||||
|
||||
def __get_layer_attribute(self, attr):
|
||||
if attr['blender_domain'] in ['CORNER']:
|
||||
@ -969,15 +1068,19 @@ class PrimitiveCreator:
|
||||
res[:, i] = self.prim_dots[attr['gltf_attribute_name'] + str(i)]
|
||||
self.attributes[attr['gltf_attribute_name']] = {}
|
||||
self.attributes[attr['gltf_attribute_name']]["data"] = res
|
||||
if 'gltf_attribute_name' == "NORMAL":
|
||||
if attr['gltf_attribute_name'] == "NORMAL":
|
||||
self.attributes[attr['gltf_attribute_name']]["component_type"] = gltf2_io_constants.ComponentType.Float
|
||||
self.attributes[attr['gltf_attribute_name']]["data_type"] = gltf2_io_constants.DataType.Vec3
|
||||
elif 'gltf_attribute_name' == "TANGENT":
|
||||
elif attr['gltf_attribute_name'] == "TANGENT":
|
||||
self.attributes[attr['gltf_attribute_name']]["component_type"] = gltf2_io_constants.ComponentType.Float
|
||||
self.attributes[attr['gltf_attribute_name']]["data_type"] = gltf2_io_constants.DataType.Vec4
|
||||
elif attr['gltf_attribute_name'].startswith('TEXCOORD_'):
|
||||
self.attributes[attr['gltf_attribute_name']]["component_type"] = gltf2_io_constants.ComponentType.Float
|
||||
self.attributes[attr['gltf_attribute_name']]["data_type"] = gltf2_io_constants.DataType.Vec2
|
||||
elif attr['gltf_attribute_name'].startswith('COLOR_'):
|
||||
# This is already managed, we only have to copy
|
||||
self.attributes[attr['gltf_attribute_name']]["component_type"] = attr['component_type']
|
||||
self.attributes[attr['gltf_attribute_name']]["data_type"] = attr['data_type']
|
||||
else:
|
||||
self.attributes[attr['gltf_attribute_name']]["component_type"] = gltf2_blender_conversion.get_component_type(attr['blender_data_type'])
|
||||
self.attributes[attr['gltf_attribute_name']]["data_type"] = gltf2_blender_conversion.get_data_type(attr['blender_data_type'])
|
||||
|
@ -279,7 +279,7 @@ def __get_image_data_mapping(sockets, default_sockets, results, export_settings)
|
||||
dst_chan = Channel.G
|
||||
elif socket.socket.name == 'Thickness': # For KHR_materials_volume
|
||||
dst_chan = Channel.G
|
||||
elif socket.socket.name == "Specular IOR Level": # For KHR_material_specular
|
||||
elif socket.socket.name == "Specular IOR Level": # For KHR_materials_specular
|
||||
dst_chan = Channel.A
|
||||
elif socket.socket.name == "Sheen Roughness": # For KHR_materials_sheen
|
||||
dst_chan = Channel.A
|
||||
|
@ -26,7 +26,8 @@ from .gltf2_blender_search_node_tree import \
|
||||
has_image_node_from_socket, \
|
||||
get_socket_from_gltf_material_node, \
|
||||
get_socket, \
|
||||
get_node_socket
|
||||
get_node_socket, \
|
||||
get_vertex_color_info
|
||||
|
||||
@cached
|
||||
def get_material_cache_key(blender_material, export_settings):
|
||||
@ -47,7 +48,7 @@ def gather_material(blender_material, export_settings):
|
||||
:return: a glTF material
|
||||
"""
|
||||
if not __filter_material(blender_material, export_settings):
|
||||
return None, {}
|
||||
return None, {"uv_info": {}, "vc_info": {'color': None, 'alpha': None, 'color_type': None, 'alpha_type': None}}
|
||||
|
||||
mat_unlit, uvmap_info, vc_info = __export_unlit(blender_material, export_settings)
|
||||
if mat_unlit is not None:
|
||||
@ -299,9 +300,11 @@ def __export_unlit(blender_material, export_settings):
|
||||
|
||||
info = gltf2_unlit.detect_shadeless_material(blender_material, export_settings)
|
||||
if info is None:
|
||||
return None, {}, {"color": None, "alpha": None}
|
||||
return None, {}, {"color": None, "alpha": None, "color_type": None, "alpha_type": None}
|
||||
|
||||
base_color_texture, uvmap_info, vc_info = gltf2_unlit.gather_base_color_texture(info, export_settings)
|
||||
base_color_texture, uvmap_info = gltf2_unlit.gather_base_color_texture(info, export_settings)
|
||||
|
||||
vc_info = get_vertex_color_info(info.get('rgb_socket'), info.get('alpha_socket'), export_settings)
|
||||
|
||||
material = gltf2_io.Material(
|
||||
alpha_cutoff=__gather_alpha_cutoff(blender_material, export_settings),
|
||||
@ -447,7 +450,7 @@ def get_material_from_idx(material_idx, materials, export_settings):
|
||||
def get_base_material(material_idx, materials, export_settings):
|
||||
|
||||
material = None
|
||||
material_info = {"uv_info": {}, "vc_info": {}}
|
||||
material_info = {"uv_info": {}, "vc_info": {"color": None, "alpha": None, "color_type": None, "alpha_type": None}}
|
||||
|
||||
mat = get_material_from_idx(material_idx, materials, export_settings)
|
||||
if mat is not None:
|
||||
|
@ -20,17 +20,19 @@ from .gltf2_blender_search_node_tree import \
|
||||
@cached
|
||||
def gather_material_pbr_metallic_roughness(blender_material, orm_texture, export_settings):
|
||||
if not __filter_pbr_material(blender_material, export_settings):
|
||||
return None, {}
|
||||
return None, {}, {'color': None, 'alpha': None, 'color_type': None, 'alpha_type': None}
|
||||
|
||||
uvmap_infos = {}
|
||||
|
||||
base_color_texture, uvmap_info, vc_info, _ = __gather_base_color_texture(blender_material, export_settings)
|
||||
base_color_texture, uvmap_info, _ = __gather_base_color_texture(blender_material, export_settings)
|
||||
uvmap_infos.update(uvmap_info)
|
||||
metallic_roughness_texture, uvmap_info, _ = __gather_metallic_roughness_texture(blender_material, orm_texture, export_settings)
|
||||
uvmap_infos.update(uvmap_info)
|
||||
|
||||
base_color_factor, vc_info = __gather_base_color_factor(blender_material, export_settings)
|
||||
|
||||
material = gltf2_io.MaterialPBRMetallicRoughness(
|
||||
base_color_factor=__gather_base_color_factor(blender_material, export_settings),
|
||||
base_color_factor=base_color_factor,
|
||||
base_color_texture=base_color_texture,
|
||||
extensions=__gather_extensions(blender_material, export_settings),
|
||||
extras=__gather_extras(blender_material, export_settings),
|
||||
@ -50,7 +52,7 @@ def __filter_pbr_material(blender_material, export_settings):
|
||||
|
||||
def __gather_base_color_factor(blender_material, export_settings):
|
||||
if not blender_material.use_nodes:
|
||||
return [*blender_material.diffuse_color[:3], 1.0]
|
||||
return [*blender_material.diffuse_color[:3], 1.0], {"color": None, "alpha": None, "color_type": None, "alpha_type": None}
|
||||
|
||||
rgb, alpha = None, None
|
||||
|
||||
@ -80,8 +82,10 @@ def __gather_base_color_factor(blender_material, export_settings):
|
||||
|
||||
rgba = [*rgb, alpha]
|
||||
|
||||
if rgba == [1, 1, 1, 1]: return None
|
||||
return rgba
|
||||
vc_info = get_vertex_color_info(base_color_socket, alpha_socket, export_settings)
|
||||
|
||||
if rgba == [1, 1, 1, 1]: return None, vc_info
|
||||
return rgba, vc_info
|
||||
|
||||
|
||||
def __gather_base_color_texture(blender_material, export_settings):
|
||||
@ -99,11 +103,10 @@ def __gather_base_color_texture(blender_material, export_settings):
|
||||
if socket.socket is not None and has_image_node_from_socket(socket, export_settings)
|
||||
)
|
||||
if not inputs:
|
||||
return None, {}, {"uv_info": {}, "vc_info": {}}, None
|
||||
return None, {}, None
|
||||
|
||||
tex, uvmap_info, factor = gather_texture_info(inputs[0], inputs, (), export_settings)
|
||||
vc_info = get_vertex_color_info(inputs[0], inputs, export_settings)
|
||||
return tex, {'baseColorTexture': uvmap_info}, vc_info, factor
|
||||
return tex, {'baseColorTexture': uvmap_info}, factor
|
||||
|
||||
|
||||
def __gather_extensions(blender_material, export_settings):
|
||||
|
@ -3,7 +3,6 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
from . import gltf2_blender_gather_texture_info
|
||||
from .gltf2_blender_search_node_tree import get_vertex_color_info
|
||||
from .gltf2_blender_search_node_tree import \
|
||||
get_socket, \
|
||||
NodeSocket, \
|
||||
@ -143,7 +142,5 @@ def gather_base_color_texture(info, export_settings):
|
||||
export_settings,
|
||||
)
|
||||
|
||||
vc_info = get_vertex_color_info(sockets[0], sockets, export_settings)
|
||||
|
||||
return unlit_texture, {'baseColorTexture': uvmap_info}, vc_info
|
||||
return None, {}, {"color": None, "alpha": None}
|
||||
return unlit_texture, {'baseColorTexture': uvmap_info}
|
||||
return None, {}
|
||||
|
@ -437,5 +437,58 @@ def check_if_is_linked_to_active_output(shader_socket, group_path):
|
||||
|
||||
return False
|
||||
|
||||
def get_vertex_color_info(primary_socket, sockets, export_settings):
|
||||
return {"color": None, "alpha": None} #TODO, placeholder for now
|
||||
def get_vertex_color_info(color_socket, alpha_socket, export_settings):
|
||||
|
||||
attribute_color = None
|
||||
attribute_alpha = None
|
||||
attribute_color_type = None
|
||||
attribute_alpha_type = None
|
||||
|
||||
# Retrieve Attribute used as vertex color for Color
|
||||
if color_socket is not None and color_socket.socket is not None:
|
||||
node = previous_node(color_socket)
|
||||
if node.node is not None:
|
||||
if node.node.type == 'MIX' and node.node.data_type == "RGBA" and node.node.blend_type == 'MULTIPLY':
|
||||
use_vc, attribute_color, use_active = get_attribute_name(NodeSocket(node.node.inputs[6], node.group_path), export_settings)
|
||||
if use_vc is False:
|
||||
use_vc, attribute_color, use_active = get_attribute_name(NodeSocket(node.node.inputs[7], node.group_path), export_settings)
|
||||
if use_vc is True and use_active is True:
|
||||
attribute_color_type = "active"
|
||||
elif use_vc is True and use_active is None and attribute_color is not None:
|
||||
attribute_color_type = "name"
|
||||
|
||||
if alpha_socket is not None and alpha_socket.socket is not None:
|
||||
node = previous_node(alpha_socket)
|
||||
if node.node is not None:
|
||||
if node.node.type == 'MIX' and node.node.data_type == "FLOAT" and node.node.blend_type == 'MULTIPLY':
|
||||
use_vc, attribute_alpha, use_active = get_attribute_name(NodeSocket(node.node.inputs[2], node.group_path), export_settings)
|
||||
if use_vc is False:
|
||||
use_vc, attribute_alpha, use_active = get_attribute_name(NodeSocket(node.node.inputs[3], node.group_path), export_settings)
|
||||
if use_vc is True and use_active is True:
|
||||
attribute_alpha_type = "active"
|
||||
elif use_vc is True and use_active is None and attribute_alpha is not None:
|
||||
attribute_alpha_type = "name"
|
||||
|
||||
return {"color": attribute_color, "alpha": attribute_alpha, "color_type": attribute_color_type, "alpha_type": attribute_alpha_type}
|
||||
|
||||
def get_attribute_name(socket, export_settings):
|
||||
node = previous_node(socket)
|
||||
if node.node is not None and node.node.type == "ATTRIBUTE" \
|
||||
and node.node.attribute_type == "GEOMETRY" \
|
||||
and node.node.attribute_name is not None \
|
||||
and node.node.attribute_name != "":
|
||||
return True, node.node.attribute_name, None
|
||||
elif node.node is not None and node.node.type == "ATTRIBUTE" \
|
||||
and node.node.attribute_type == "GEOMETRY" \
|
||||
and node.node.attribute_name == "":
|
||||
return True, None, True
|
||||
|
||||
if node.node is not None and node.node.type == "VERTEX_COLOR" \
|
||||
and node.node.layer_name is not None \
|
||||
and node.node.layer_name != "":
|
||||
return True, node.node.layer_name, None
|
||||
elif node.node is not None and node.node.type == "VERTEX_COLOR" \
|
||||
and node.node.layer_name == "":
|
||||
return True, None, True
|
||||
|
||||
return False, None, None
|
||||
|
@ -3013,7 +3013,7 @@ def importShape_ProcessObject(
|
||||
# solid=false, we don't support it yet.
|
||||
creaseAngle = geom.getFieldAsFloat('creaseAngle', None, ancestry)
|
||||
if creaseAngle is not None:
|
||||
bpydata.set_sharp_from_angle(creaseAngle)
|
||||
bpydata.set_sharp_from_angle(angle=creaseAngle)
|
||||
else:
|
||||
bpydata.polygons.foreach_set("use_smooth", [False] * len(bpydata.polygons))
|
||||
|
||||
|
@ -677,7 +677,7 @@ def mu_set_auto_smooth(self, angle, affect, set_smooth_shading):
|
||||
|
||||
#bpy.ops.object.shade_smooth()
|
||||
|
||||
object.data.set_sharp_from_angle(angle) # 35 degrees as radians
|
||||
object.data.set_sharp_from_angle(angle=angle) # 35 degrees as radians
|
||||
|
||||
objects_affected += 1
|
||||
|
||||
|
@ -338,7 +338,7 @@ def CreateBevel(context, CurrentObject):
|
||||
|
||||
bpy.ops.object.shade_smooth()
|
||||
|
||||
context.object.data.set_sharp_from_angle(1.0471975)
|
||||
context.object.data.set_sharp_from_angle(angle=1.0471975)
|
||||
|
||||
# Restore the active object
|
||||
context.view_layer.objects.active = SavActive
|
||||
|
@ -656,7 +656,7 @@ def pov_torus_define(context, op, ob):
|
||||
bpy.ops.object.mode_set(mode="EDIT")
|
||||
bpy.ops.mesh.hide(unselected=False)
|
||||
bpy.ops.object.mode_set(mode="OBJECT")
|
||||
ob.data.set_sharp_from_angle(0.6)
|
||||
ob.data.set_sharp_from_angle(angle=0.6)
|
||||
ob.pov.object_as = "TORUS"
|
||||
ob.update_tag() # as prop set via python not updated in depsgraph
|
||||
|
||||
|
@ -171,7 +171,7 @@ def pov_superellipsoid_define(context, op, ob):
|
||||
bpy.ops.object.mode_set(mode="EDIT")
|
||||
bpy.ops.mesh.hide(unselected=False)
|
||||
bpy.ops.object.mode_set(mode="OBJECT")
|
||||
ob.data.set_sharp_from_angle(1.3)
|
||||
ob.data.set_sharp_from_angle(angle=1.3)
|
||||
ob.pov.object_as = "SUPERELLIPSOID"
|
||||
ob.update_tag() # as prop set via python not updated in depsgraph
|
||||
|
||||
@ -1050,7 +1050,7 @@ def pov_parametric_define(context, op, ob):
|
||||
bpy.ops.object.mode_set(mode="EDIT")
|
||||
bpy.ops.mesh.hide(unselected=False)
|
||||
bpy.ops.object.mode_set(mode="OBJECT")
|
||||
ob.data.set_sharp_from_angle(0.6)
|
||||
ob.data.set_sharp_from_angle(angle=0.6)
|
||||
ob.pov.object_as = "PARAMETRIC"
|
||||
ob.update_tag() # as prop set via python not updated in depsgraph
|
||||
return{'FINISHED'}
|
||||
|
Loading…
Reference in New Issue
Block a user