diff --git a/addons/io_scene_gltf2/__init__.py b/addons/io_scene_gltf2/__init__.py index f6e455a24..48cea35af 100644 --- a/addons/io_scene_gltf2/__init__.py +++ b/addons/io_scene_gltf2/__init__.py @@ -334,8 +334,8 @@ def __init__(self): ) export_colors: BoolProperty( - name='Vertex Colors', - description='Export vertex colors with meshes', + name='dummy', + description='Keep for compatibility only', default=True ) @@ -820,7 +820,6 @@ def execute(self, context): 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 @@ -1107,7 +1106,6 @@ def draw(self, context): 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() diff --git a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives_extract.py b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives_extract.py index 7459c2c28..b9265dc21 100644 --- a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives_extract.py +++ b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives_extract.py @@ -20,7 +20,7 @@ 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 @@ -34,7 +34,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: @@ -152,7 +152,7 @@ def __init__(self, attr_name): 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 = {} @@ -172,42 +172,27 @@ def __init__(self, attr_name): 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: - - if self.export_settings['gltf_colors'] is False: - continue - attr['gltf_attribute_name'] = 'COLOR_0' - attr['get'] = self.get_function() - - # 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 - - 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) + # 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) - export_user_extensions('gather_attribute_keep', self.export_settings, keep_attribute) + export_user_extensions('gather_attribute_keep', self.export_settings, keep_attribute) - if keep_attribute.keep is False: - continue + if keep_attribute.keep is False: + continue - attr['gltf_attribute_name'] = keep_attribute.attr_name.upper() - attr['get'] = self.get_function() + 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) @@ -398,12 +383,18 @@ def primitive_split(self): 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 = [] @@ -412,10 +403,11 @@ def material_uvmap_attribute_add(self): 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: @@ -434,7 +426,57 @@ def material_uvmap_attribute_add(self): 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 = [] @@ -638,9 +680,7 @@ def __get_positions(self): 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) @@ -652,15 +692,79 @@ def getting_function(attr): 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 + + # 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 - if attr['blender_domain'] == "POINT": + # 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']: @@ -668,18 +772,13 @@ def __get_color_attribute(self, attr): 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']: @@ -979,15 +1078,19 @@ def __set_regular_attribute(self, attr): 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']) diff --git a/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_materials.py b/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_materials.py index 69066b02c..77148f5da 100644 --- a/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_materials.py +++ b/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_materials.py @@ -36,7 +36,8 @@ 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): @@ -57,7 +58,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: @@ -309,9 +310,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), @@ -457,7 +460,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: diff --git a/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_materials_pbr_metallic_roughness.py b/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_materials_pbr_metallic_roughness.py index c0a3faaf2..df47a33fc 100644 --- a/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_materials_pbr_metallic_roughness.py +++ b/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_materials_pbr_metallic_roughness.py @@ -30,17 +30,19 @@ @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), @@ -60,7 +62,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 @@ -90,8 +92,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): @@ -109,11 +113,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): diff --git a/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_materials_unlit.py b/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_materials_unlit.py index 80128f2f3..307496d37 100644 --- a/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_materials_unlit.py +++ b/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_gather_materials_unlit.py @@ -13,7 +13,6 @@ # limitations under the License. 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, \ @@ -153,7 +152,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, {} diff --git a/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_search_node_tree.py b/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_search_node_tree.py index de6387be1..fd6ee5069 100644 --- a/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_search_node_tree.py +++ b/addons/io_scene_gltf2/blender/exp/material/gltf2_blender_search_node_tree.py @@ -447,5 +447,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