def __active_scs_root_change__(new_scs_root_obj): """Hookup function for changing active object. :param new_scs_root_obj: new active SCS Root Object :type new_scs_root_obj: bpy.types.Object """ _looks.apply_active_look(new_scs_root_obj)
def set_active_scs_look(self, value): if value != self.get_active_scs_look(): self["active_scs_look"] = value if bpy.context.active_object: scs_root = _object_utils.get_scs_root(bpy.context.active_object) if scs_root: _looks.apply_active_look(scs_root)
def export(root_object, filepath, name_suffix, used_parts, used_materials): """Export PIT. :param root_object: SCS root object :type root_object: bpy.types.Object :param filepath: PIT file path :type filepath: str :param name_suffix: file name suffix :type name_suffix: str :param used_parts: parts transitional structure for accessing stored parts from PIM, PIC and PIP :type used_parts: io_scs_tools.exp.transition_structs.parts.PartsTrans :param used_materials: materials transitional structure for accessing stored materials from PIM :type used_materials: io_scs_tools.exp.transition_structs.materials.MaterialsTrans :return: True if successful; False otherwise; :rtype: bool """ scs_globals = _get_scs_globals() file_name = root_object.name print("\n************************************") print("** SCS PIT Exporter **") print("** (c)2014 SCS Software **") print("************************************\n") # DATA GATHERING look_list = [] variant_list = [] saved_active_look = root_object.scs_props.active_scs_look looks_inventory = root_object.scs_object_look_inventory looks_count = len(looks_inventory) if looks_count <= 0: looks_count = 1 used_materials_pairs = used_materials.get_as_pairs() for i in range(0, looks_count): # apply each look from inventory first if len(looks_inventory) > 0: root_object.scs_props.active_scs_look = i # set index for curret look _looks.apply_active_look( root_object ) # apply look manually, as active look setter method works only when user sets index from UI curr_look_name = looks_inventory[i].name else: # if no looks create default curr_look_name = "default" material_dict = {} material_list = [] # get materials data for material_name, material in used_materials_pairs: if material is None: material_name = str("_default_material_-_default_settings_") # DEFAULT MATERIAL material_export_data = default_material(material_name) material_list.append(material_name) else: # print('material name: %r' % material.name) material_list.append(material) # MATERIAL EFFECT effect_name = material.scs_props.mat_effect_name # PRESET SHADERS flags = 0 attribute_cnt = texture_cnt = 0 attribute_sections = [] texture_sections = [] active_shader_preset_name = material.scs_props.active_shader_preset_name # SUBSTANCE substance_value = material.scs_props.substance # only write substance to material if it's assigned if substance_value != "None" and substance_value != "": substance_data = _SectionData("Attribute") substance_data.props.append(("Format", "STRING")) substance_data.props.append(("Tag", "substance")) substance_data.props.append( ("Value", ["i", (substance_value, )])) attribute_sections.append(substance_data) attribute_cnt += 1 if _shader_presets.has_preset( active_shader_preset_name ) and active_shader_preset_name != "<none>": preset = _shader_presets.get_preset( active_shader_preset_name) flavors_str = effect_name[len(preset.effect):] section = _shader_presets.get_section( active_shader_preset_name, flavors_str) # FLAGS for prop in section.props: if prop[0] == "Flags": flags = int(not material.scs_props.enable_aliasing) break # COLLECT ATTRIBUTES AND TEXTURES for item in section.sections: # if attribute is hidden in shader preset ignore it on export # this is useful for flavor hiding some attributes from original material # eg: airbrush on "truckpaint" hides R G B aux attributes which are not present # when using airbrush flavor hidden = item.get_prop_value("Hide") if hidden and hidden == "True": continue preview_only = item.get_prop_value("PreviewOnly") if preview_only and preview_only == "True": continue # ATTRIBUTES if item.type == "Attribute": # print(' Attribute:') attribute_data = _SectionData("Attribute") for rec in item.props: # print(' rec: %r' % str(rec)) if rec[0] == "Format": attribute_data.props.append( (rec[0], rec[1])) elif rec[0] == "Tag": # tag_prop = rec[1].replace("[", "").replace("]", "") # attribute_data.props.append((rec[0], tag_prop)) attribute_data.props.append( (rec[0], rec[1])) elif rec[0] == "Value": format_prop = item.get_prop("Format")[1] tag_prop = item.get_prop("Tag")[1] tag_prop = tag_prop.replace("[", "").replace( "]", "") # print(' format_prop: %r' % str(format_prop)) # print(' tag_prop: %r' % str(tag_prop)) if "aux" in tag_prop: aux_props = getattr( material.scs_props, "shader_attribute_" + tag_prop) value = [] for aux_prop in aux_props: value.append(aux_prop.value) # extract list if there is only one value inside and tagged as FLOAT # otherwise it gets saved as: "Value: ( [0.0] )" instead of: "Value: ( 0.0 )" if len( value ) == 1 and format_prop == "FLOAT": value = value[0] else: value = getattr( material.scs_props, "shader_attribute_" + tag_prop, "NO TAG") # print(' value: %s' % str(value)) if format_prop == 'FLOAT': attribute_data.props.append( (rec[0], ["&&", (value, )])) elif format_prop == 'INT': attribute_data.props.append( (rec[0], ["ii", (value, )])) else: attribute_data.props.append( (rec[0], ["i", tuple(value)])) attribute_sections.append(attribute_data) attribute_cnt += 1 # TEXTURES elif item.type == "Texture": # print(' Texture:') texture_data = _SectionData("Texture") for rec in item.props: # print(' rec: %r' % str(rec)) if rec[0] == "Tag": tag_prop = rec[1].split(":")[1] tag = str("texture[" + str(texture_cnt) + "]:" + tag_prop) texture_data.props.append((rec[0], tag)) elif rec[0] == "Value": tag_prop = item.get_prop("Tag")[1].split( ":")[1] # print(' tag_prop: %r' % str(tag_prop)) # create and get path to tobj tobj_rel_path = get_texture_path_from_material( material, tag_prop, os.path.dirname(filepath)) texture_data.props.append( (rec[0], tobj_rel_path)) texture_sections.append(texture_data) texture_cnt += 1 material_export_data = _SectionData("Material") material_export_data.props.append(("Alias", material.name)) material_export_data.props.append(("Effect", effect_name)) material_export_data.props.append(("Flags", flags)) material_export_data.props.append( ("AttributeCount", attribute_cnt)) material_export_data.props.append( ("TextureCount", texture_cnt)) for attribute in attribute_sections: material_export_data.sections.append(attribute) for texture in texture_sections: material_export_data.sections.append(texture) elif active_shader_preset_name == "<imported>": material_attributes = material['scs_shader_attributes'][ 'attributes'].to_dict().values() material_textures = material['scs_shader_attributes'][ 'textures'].to_dict().values() material_export_data = _SectionData("Material") material_export_data.props.append(("Alias", material.name)) material_export_data.props.append(("Effect", effect_name)) material_export_data.props.append( ("Flags", int(not material.scs_props.enable_aliasing))) material_export_data.props.append( ("AttributeCount", len(material_attributes))) material_export_data.props.append( ("TextureCount", len(material_textures))) for attribute_dict in material_attributes: attribute_section = _SectionData("Attribute") format_value = "" for attr_prop in sorted(attribute_dict.keys()): # get the format of current attribute (we assume that "Format" attribute is before "Value" attribute in this for loop) if attr_prop == "Format": format_value = attribute_dict[attr_prop] if attr_prop == "Value" and ( "FLOAT" in format_value or "STRING" in format_value or "INT" in format_value): tag_prop = attribute_dict["Tag"].replace( "[", "").replace("]", "") if "aux" in tag_prop: aux_props = getattr( material.scs_props, "shader_attribute_" + tag_prop) value = [] for aux_prop in aux_props: value.append(aux_prop.value) else: value = getattr( material.scs_props, "shader_attribute_" + tag_prop, None) if isinstance(value, float): value = [value] if value is None: attribute_section.props.append( (attr_prop, [ "i", tuple(attribute_dict[attr_prop]) ])) else: attribute_section.props.append( (attr_prop, ["i", tuple(value)])) elif attr_prop == "Tag" and "aux" in attribute_dict[ attr_prop]: attribute_section.props.append( (attr_prop, "aux[" + attribute_dict[attr_prop][3:] + "]")) else: attribute_section.props.append( (attr_prop, attribute_dict[attr_prop])) material_export_data.sections.append(attribute_section) for texture_dict in material_textures: texture_section = _SectionData("Texture") tag_id_string = "" for tex_prop in sorted(texture_dict.keys()): if tex_prop == "Tag": tag_id_string = texture_dict[tex_prop].split( ':')[1] if tex_prop == "Value" and tag_id_string != "": tobj_rel_path = get_texture_path_from_material( material, tag_id_string, os.path.dirname(filepath)) texture_section.props.append( (tex_prop, tobj_rel_path)) else: texture_section.props.append( (tex_prop, texture_dict[tex_prop])) material_export_data.sections.append(texture_section) else: # when user made material presets were there, but there is no preset library at export for some reason lprint( "W Shader preset used on %r not found in Shader Presets Library (Did you set correct path?), " "exporting default material instead!", (material_name, )) material_name = str("_" + material_name + "_-_default_settings_") material_export_data = default_material(material_name) material_dict[material_name] = material_export_data # create materials sections for looks material_sections = fill_material_sections(material_list, material_dict) look_data = { "name": curr_look_name, "material_sections": material_sections } look_list.append(look_data) # restore look applied before export root_object.scs_props.active_scs_look = saved_active_look # set index for curret look _looks.apply_active_look( root_object ) # apply look manually, as active look setter method works only when user sets index from UI # PARTS AND VARIANTS... used_parts_names = used_parts.get_as_list() if len(root_object.scs_object_variant_inventory) == 0: # If there is no Variant, add the Default one... part_list = fill_part_list(root_object.scs_object_part_inventory, used_parts_names, all_parts=True) variant_list.append((_VARIANT_consts.default_name, part_list), ) else: for variant in root_object.scs_object_variant_inventory: part_list = fill_part_list(variant.parts, used_parts_names) variant_list.append((variant.name, part_list), ) # DATA CREATION header_section = fill_header_section(1, file_name, scs_globals.export_write_signature) look_section = fill_look_sections(look_list) # part_sections = fill_part_section(part_list) variant_section = fill_variant_sections(variant_list) comment_header_section = fill_comment_header_section( look_list, variant_list) global_section = fill_global_section(len(look_list), len(variant_list), used_parts.count(), len(used_materials_pairs)) # DATA ASSEMBLING pit_container = [comment_header_section, header_section, global_section] for section in look_section: pit_container.append(section) for section in variant_section: pit_container.append(section) # FILE EXPORT ind = " " pit_filepath = str(filepath + ".pit" + name_suffix) result = _pix_container.write_data_to_file(pit_container, pit_filepath, ind) # print("************************************") return result
def export(root_object, used_parts, used_materials, scene, filepath): scs_globals = _get_scs_globals() output_type = scs_globals.output_type file_name = root_object.name print("\n************************************") print("** SCS PIT Exporter **") print("** (c)2014 SCS Software **") print("************************************\n") # DATA GATHERING look_list = [] variant_list = [] saved_active_look = root_object.scs_props.active_scs_look looks_inventory = root_object.scs_object_look_inventory looks_count = len(looks_inventory) if looks_count <= 0: looks_count = 1 for i in range(0, looks_count): # apply each look from inventory first if len(looks_inventory) > 0: root_object.scs_props.active_scs_look = i # actually write values to material because Blender might not refresh data yet _looks.apply_active_look(root_object) curr_look_name = looks_inventory[i].name else: # if no looks create default curr_look_name = "default" material_dict = {} material_list = [] # get materials data for material in used_materials: if material is not None: # if material in ("_empty_slot_", "_empty_material_"): # NOTE: only workaround until module doesn't gets rewritten if material in bpy.data.materials: material = bpy.data.materials[material] if isinstance(material, str): material_name = str(material + "-_default_settings_") # DEFAULT MATERIAL material_export_data = _default_material(material_name) material_list.append(material_name) else: # print('material name: %r' % material.name) material_name = material.name material_list.append(material) # SUBSTANCE if material.scs_props.substance != 'None': lprint( 'D material.name: %r\tmat.scs_props.substance: "%s"', (material.name, str(material.scs_props.substance))) # TODO: Substance Export... # MATERIAL EFFECT # shader_data = material.get("scs_shader_attributes", {}) # effect_name = shader_data.get('effect', "NO EFFECT") effect_name = material.scs_props.mat_effect_name # CgFX SHADERS # print("\n=== GET SHADER EXPORT DATA =======================") ## NOTE: The following code is OBSOLETE!!! # cgfx_export_data = None # print(" cgfx_export_data:\n%s" % str(cgfx_export_data)) # if cgfx_export_data: # print("\nAttributes:") # for attribute in cgfx_export_data['attributes']: # if cgfx_export_data['attributes'][attribute]: # print(" %s:" % str(attribute)) # for rec in cgfx_export_data['attributes'][attribute]: # print(" %s: %s" % (str(rec), str(cgfx_export_data['attributes'][attribute][rec]))) # else: # print("%s:\n %s" % (str(attribute), cgfx_export_data['attributes'][attribute])) # print("\nTextures:") # for attribute in cgfx_export_data['textures']: # if cgfx_export_data['textures'][attribute]: # print(" %s:" % str(attribute)) # for rec in cgfx_export_data['textures'][attribute]: # print(" %s: %s" % (str(rec), str(cgfx_export_data['textures'][attribute][rec]))) # else: # print("%s:\n %s" % (str(attribute), cgfx_export_data['textures'][attribute])) # else: # Print(1, 'E No CgFX data for material %r!' % material.name) # print("==================================================") # PRESET SHADERS preset_found = False alias = "NO SHADER" def_cnt = attribute_cnt = texture_cnt = 0 def_sections = [] attribute_sections = [] texture_sections = [] active_shader_preset_name = material.scs_props.active_shader_preset_name # print(' active_shader_preset_name: %r' % active_shader_preset_name) for preset_i, preset in enumerate( bpy.data.worlds[0].scs_shader_presets_inventory): # print(' preset[%i]: %r' % (preset_i, preset.name)) if preset.name == active_shader_preset_name: # print(' - material %r - %r' % (material.name, preset.name)) # LOAD PRESET shader_presets_abs_path = _path_utils.get_abs_path( scs_globals.shader_presets_filepath) # shader_presets_filepath = _get_scs_globals().shader_presets_filepath # print('shader_presets_filepath: %r' % shader_presets_filepath) # if shader_presets_filepath.startswith(str(os.sep + os.sep)): ## RELATIVE PATH # shader_presets_abs_path = get_abs_path(shader_presets_filepath) # else: # shader_presets_abs_path = shader_presets_filepath if os.path.isfile(shader_presets_abs_path): presets_container = _pix_container.get_data_from_file( shader_presets_abs_path, ' ') # FIND THE PRESET IN FILE if presets_container: for section in presets_container: if section.type == "Shader": section_properties = _get_properties( section) if 'PresetName' in section_properties: preset_name = section_properties[ 'PresetName'] if preset_name == active_shader_preset_name: alias = material.name # print(' + preset name: %r' % preset_name) # COLLECT ATTRIBUTES AND TEXTURES for item in section.sections: # DATA EXCHANGE FORMAT ATRIBUTE if item.type == "DataExchangeFormat": def_data = _SectionData( "DataExchangeFormat" ) for rec in item.props: def_data.props.append( (rec[0], rec[1])) def_sections.append( def_data) def_cnt += 1 # ATTRIBUTES if item.type == "Attribute": # print(' Attribute:') attribute_data = _SectionData( "Attribute") for rec in item.props: # print(' rec: %r' % str(rec)) if rec[0] == "Format": attribute_data.props.append( (rec[ 0], rec[1] )) elif rec[ 0] == "Tag": # tag_prop = rec[1].replace("[", "").replace("]", "") # attribute_data.props.append((rec[0], tag_prop)) attribute_data.props.append( (rec[ 0], rec[1] )) elif rec[ 0] == "Value": format_prop = item.get_prop( "Format" )[1] tag_prop = item.get_prop( "Tag" )[1] tag_prop = tag_prop.replace( "[", "" ).replace( "]", "") # print(' format_prop: %r' % str(format_prop)) # print(' tag_prop: %r' % str(tag_prop)) if "aux" in tag_prop: aux_props = getattr( material . scs_props, "shader_attribute_" + tag_prop ) value = [] for aux_prop in aux_props: value.append( aux_prop . value ) else: value = getattr( material . scs_props, "shader_attribute_" + tag_prop, "NO TAG" ) # print(' value: %s' % str(value)) if format_prop == 'FLOAT': attribute_data.props.append( (rec[ 0], [ "&&", (value, ) ] )) else: attribute_data.props.append( (rec[ 0], [ "i", tuple( value ) ] )) attribute_sections.append( attribute_data) attribute_cnt += 1 # TEXTURES elif item.type == "Texture": # print(' Texture:') texture_data = _SectionData( "Texture") for rec in item.props: # print(' rec: %r' % str(rec)) if rec[0] == "Tag": tag_prop = rec[ 1].split( ":" )[1] tag = str( "texture[" + str(texture_cnt ) + "]:" + tag_prop ) texture_data.props.append( (rec[ 0], tag)) elif rec[ 0] == "Value": tag_prop = item.get_prop( "Tag" )[1].split( ":")[1] # print(' tag_prop: %r' % str(tag_prop)) # create and get path to tobj tobj_rel_path = _get_texture_path_from_material( material, tag_prop, os. path. dirname( filepath )) texture_data.props.append( (rec[ 0], tobj_rel_path )) texture_sections.append( texture_data) texture_cnt += 1 preset_found = True break else: lprint('\nW The file path "%s" is not valid!', (shader_presets_abs_path, )) if preset_found: break if preset_found: material_export_data = _SectionData("Material") material_export_data.props.append(("Alias", alias)) material_export_data.props.append( ("Effect", effect_name)) material_export_data.props.append(("Flags", 0)) if output_type.startswith('def'): material_export_data.props.append( ("DataExchangeFormatCount", def_cnt)) material_export_data.props.append( ("AttributeCount", attribute_cnt)) material_export_data.props.append( ("TextureCount", texture_cnt)) if output_type.startswith('def'): for def_section in def_sections: material_export_data.sections.append( def_section) for attribute in attribute_sections: material_export_data.sections.append(attribute) for texture in texture_sections: material_export_data.sections.append(texture) elif active_shader_preset_name == "<imported>": material_attributes = material[ 'scs_shader_attributes']['attributes'].to_dict( ).values() material_textures = material['scs_shader_attributes'][ 'textures'].to_dict().values() material_export_data = _SectionData("Material") material_export_data.props.append( ("Alias", material.name)) material_export_data.props.append( ("Effect", effect_name)) material_export_data.props.append(("Flags", 0)) material_export_data.props.append( ("AttributeCount", len(material_attributes))) material_export_data.props.append( ("TextureCount", len(material_textures))) for attribute_dict in material_attributes: attribute_section = _SectionData("Attribute") format_value = "" for attr_prop in sorted(attribute_dict.keys()): # get the format of current attribute (we assume that "Format" attribute is before "Value" attribute in this for loop) if attr_prop == "Format": format_value = attribute_dict[attr_prop] if attr_prop == "Value" and ( "FLOAT" in format_value or "STRING" in format_value): attribute_section.props.append( (attr_prop, [ "i", tuple(attribute_dict[attr_prop]) ])) elif attr_prop == "Tag" and "aux" in attribute_dict[ attr_prop]: attribute_section.props.append( (attr_prop, "aux[" + attribute_dict[attr_prop][3:] + "]")) else: attribute_section.props.append( (attr_prop, attribute_dict[attr_prop])) material_export_data.sections.append( attribute_section) for texture_dict in material_textures: texture_section = _SectionData("Texture") tag_id_string = "" for tex_prop in sorted(texture_dict.keys()): if tex_prop == "Tag": tag_id_string = texture_dict[ tex_prop].split(':')[1] if tex_prop == "Value" and tag_id_string != "": tobj_rel_path = _get_texture_path_from_material( material, tag_id_string, os.path.dirname(filepath)) texture_section.props.append( (tex_prop, tobj_rel_path)) else: texture_section.props.append( (tex_prop, texture_dict[tex_prop])) material_export_data.sections.append( texture_section) else: # DEFAULT MATERIAL material_name = str("_" + material_name + "_-_default_settings_") material_export_data = _default_material(material_name) material_dict[material_name] = material_export_data # create materials sections for looks material_sections = _fill_material_sections(material_list, material_dict) look_data = { "name": curr_look_name, "material_sections": material_sections } look_list.append(look_data) # restore look applied before export root_object.scs_props.active_scs_look = saved_active_look # PARTS AND VARIANTS... part_list_cnt = len(used_parts.keys()) if len(root_object.scs_object_variant_inventory) == 0: # If there is no Variant, add the Default one... part_list = _fill_part_list(root_object.scs_object_part_inventory, used_parts, all_parts=True) variant_list.append((_VARIANT_consts.default_name, part_list), ) else: for variant in root_object.scs_object_variant_inventory: part_list = _fill_part_list(variant.parts, used_parts) variant_list.append((variant.name, part_list), ) # DATA CREATION header_section = _fill_header_section(file_name, scs_globals.sign_export) look_section = _fill_look_sections(look_list) # part_sections = fill_part_section(part_list) variant_section = _fill_variant_sections(variant_list) comment_header_section = _fill_comment_header_section( look_list, variant_list) global_section = _fill_global_section(len(look_list), len(variant_list), part_list_cnt, len(used_materials)) # DATA ASSEMBLING pit_container = [comment_header_section, header_section, global_section] for section in look_section: pit_container.append(section) for section in variant_section: pit_container.append(section) # FILE EXPORT ind = " " pit_filepath = str(filepath + ".pit") result = _pix_container.write_data_to_file(pit_container, pit_filepath, ind) # print("************************************") return result
def export(root_object, used_parts, used_materials, scene, filepath): scs_globals = _get_scs_globals() output_type = scs_globals.output_type file_name = root_object.name print("\n************************************") print("** SCS PIT Exporter **") print("** (c)2014 SCS Software **") print("************************************\n") # DATA GATHERING look_list = [] variant_list = [] saved_active_look = root_object.scs_props.active_scs_look looks_inventory = root_object.scs_object_look_inventory looks_count = len(looks_inventory) if looks_count <= 0: looks_count = 1 for i in range(0, looks_count): # apply each look from inventory first if len(looks_inventory) > 0: root_object.scs_props.active_scs_look = i # actually write values to material because Blender might not refresh data yet _looks.apply_active_look(root_object) curr_look_name = looks_inventory[i].name else: # if no looks create default curr_look_name = "default" material_dict = {} material_list = [] # get materials data for material in used_materials: if material is not None: # if material in ("_empty_slot_", "_empty_material_"): # NOTE: only workaround until module doesn't gets rewritten if material in bpy.data.materials: material = bpy.data.materials[material] if isinstance(material, str): material_name = str(material + "-_default_settings_") # DEFAULT MATERIAL material_export_data = _default_material(material_name) material_list.append(material_name) else: # print('material name: %r' % material.name) material_name = material.name material_list.append(material) # SUBSTANCE if material.scs_props.substance != 'None': lprint('D material.name: %r\tmat.scs_props.substance: "%s"', (material.name, str(material.scs_props.substance))) # TODO: Substance Export... # MATERIAL EFFECT # shader_data = material.get("scs_shader_attributes", {}) # effect_name = shader_data.get('effect', "NO EFFECT") effect_name = material.scs_props.mat_effect_name # CgFX SHADERS # print("\n=== GET SHADER EXPORT DATA =======================") ## NOTE: The following code is OBSOLETE!!! # cgfx_export_data = None # print(" cgfx_export_data:\n%s" % str(cgfx_export_data)) # if cgfx_export_data: # print("\nAttributes:") # for attribute in cgfx_export_data['attributes']: # if cgfx_export_data['attributes'][attribute]: # print(" %s:" % str(attribute)) # for rec in cgfx_export_data['attributes'][attribute]: # print(" %s: %s" % (str(rec), str(cgfx_export_data['attributes'][attribute][rec]))) # else: # print("%s:\n %s" % (str(attribute), cgfx_export_data['attributes'][attribute])) # print("\nTextures:") # for attribute in cgfx_export_data['textures']: # if cgfx_export_data['textures'][attribute]: # print(" %s:" % str(attribute)) # for rec in cgfx_export_data['textures'][attribute]: # print(" %s: %s" % (str(rec), str(cgfx_export_data['textures'][attribute][rec]))) # else: # print("%s:\n %s" % (str(attribute), cgfx_export_data['textures'][attribute])) # else: # Print(1, 'E No CgFX data for material %r!' % material.name) # print("==================================================") # PRESET SHADERS preset_found = False alias = "NO SHADER" def_cnt = attribute_cnt = texture_cnt = 0 def_sections = [] attribute_sections = [] texture_sections = [] active_shader_preset_name = material.scs_props.active_shader_preset_name # print(' active_shader_preset_name: %r' % active_shader_preset_name) for preset_i, preset in enumerate(scene.scs_shader_presets_inventory): # print(' preset[%i]: %r' % (preset_i, preset.name)) if preset.name == active_shader_preset_name: # print(' - material %r - %r' % (material.name, preset.name)) # LOAD PRESET shader_presets_abs_path = _path_utils.get_abs_path(scs_globals.shader_presets_filepath) # shader_presets_filepath = _get_scs_globals().shader_presets_filepath # print('shader_presets_filepath: %r' % shader_presets_filepath) # if shader_presets_filepath.startswith(str(os.sep + os.sep)): ## RELATIVE PATH # shader_presets_abs_path = get_abs_path(shader_presets_filepath) # else: # shader_presets_abs_path = shader_presets_filepath if os.path.isfile(shader_presets_abs_path): presets_container = _pix_container.get_data_from_file(shader_presets_abs_path, ' ') # FIND THE PRESET IN FILE if presets_container: for section in presets_container: if section.type == "Shader": section_properties = _get_properties(section) if 'PresetName' in section_properties: preset_name = section_properties['PresetName'] if preset_name == active_shader_preset_name: alias = material.name # print(' + preset name: %r' % preset_name) # COLLECT ATTRIBUTES AND TEXTURES for item in section.sections: # DATA EXCHANGE FORMAT ATRIBUTE if item.type == "DataExchangeFormat": def_data = _SectionData("DataExchangeFormat") for rec in item.props: def_data.props.append((rec[0], rec[1])) def_sections.append(def_data) def_cnt += 1 # ATTRIBUTES if item.type == "Attribute": # print(' Attribute:') attribute_data = _SectionData("Attribute") for rec in item.props: # print(' rec: %r' % str(rec)) if rec[0] == "Format": attribute_data.props.append((rec[0], rec[1])) elif rec[0] == "Tag": # tag_prop = rec[1].replace("[", "").replace("]", "") # attribute_data.props.append((rec[0], tag_prop)) attribute_data.props.append((rec[0], rec[1])) elif rec[0] == "Value": format_prop = item.get_prop("Format")[1] tag_prop = item.get_prop("Tag")[1] tag_prop = tag_prop.replace("[", "").replace("]", "") # print(' format_prop: %r' % str(format_prop)) # print(' tag_prop: %r' % str(tag_prop)) if "aux" in tag_prop: aux_props = getattr(material.scs_props, "shader_attribute_" + tag_prop) value = [] for aux_prop in aux_props: value.append(aux_prop.value) else: value = getattr(material.scs_props, "shader_attribute_" + tag_prop, "NO TAG") # print(' value: %s' % str(value)) if format_prop == 'FLOAT': attribute_data.props.append((rec[0], ["&&", (value,)])) else: attribute_data.props.append((rec[0], ["i", tuple(value)])) attribute_sections.append(attribute_data) attribute_cnt += 1 # TEXTURES elif item.type == "Texture": # print(' Texture:') texture_data = _SectionData("Texture") for rec in item.props: # print(' rec: %r' % str(rec)) if rec[0] == "Tag": tag_prop = rec[1].split(":")[1] tag = str("texture[" + str(texture_cnt) + "]:" + tag_prop) texture_data.props.append((rec[0], tag)) elif rec[0] == "Value": tag_prop = item.get_prop("Tag")[1].split(":")[1] # print(' tag_prop: %r' % str(tag_prop)) # create and get path to tobj tobj_rel_path = _get_texture_path_from_material(material, tag_prop, os.path.dirname(filepath)) texture_data.props.append((rec[0], tobj_rel_path)) texture_sections.append(texture_data) texture_cnt += 1 preset_found = True break else: lprint('\nW The file path "%s" is not valid!', (shader_presets_abs_path,)) if preset_found: break if preset_found: material_export_data = _SectionData("Material") material_export_data.props.append(("Alias", alias)) material_export_data.props.append(("Effect", effect_name)) material_export_data.props.append(("Flags", 0)) if output_type.startswith('def'): material_export_data.props.append(("DataExchangeFormatCount", def_cnt)) material_export_data.props.append(("AttributeCount", attribute_cnt)) material_export_data.props.append(("TextureCount", texture_cnt)) if output_type.startswith('def'): for def_section in def_sections: material_export_data.sections.append(def_section) for attribute in attribute_sections: material_export_data.sections.append(attribute) for texture in texture_sections: material_export_data.sections.append(texture) elif active_shader_preset_name == "<imported>": material_attributes = material['scs_shader_attributes']['attributes'].to_dict().values() material_textures = material['scs_shader_attributes']['textures'].to_dict().values() material_export_data = _SectionData("Material") material_export_data.props.append(("Alias", material.name)) material_export_data.props.append(("Effect", effect_name)) material_export_data.props.append(("Flags", 0)) material_export_data.props.append(("AttributeCount", len(material_attributes))) material_export_data.props.append(("TextureCount", len(material_textures))) for attribute_dict in material_attributes: attribute_section = _SectionData("Attribute") format_value = "" for attr_prop in sorted(attribute_dict.keys()): # get the format of current attribute (we assume that "Format" attribute is before "Value" attribute in this for loop) if attr_prop == "Format": format_value = attribute_dict[attr_prop] if attr_prop == "Value" and ("FLOAT" in format_value or "STRING" in format_value): attribute_section.props.append((attr_prop, ["i", tuple(attribute_dict[attr_prop])])) elif attr_prop == "Tag" and "aux" in attribute_dict[attr_prop]: attribute_section.props.append((attr_prop, "aux[" + attribute_dict[attr_prop][3:] + "]")) else: attribute_section.props.append((attr_prop, attribute_dict[attr_prop])) material_export_data.sections.append(attribute_section) for texture_dict in material_textures: texture_section = _SectionData("Texture") tag_id_string = "" for tex_prop in sorted(texture_dict.keys()): if tex_prop == "Tag": tag_id_string = texture_dict[tex_prop].split(':')[1] if tex_prop == "Value" and tag_id_string != "": tobj_rel_path = _get_texture_path_from_material(material, tag_id_string, os.path.dirname(filepath)) texture_section.props.append((tex_prop, tobj_rel_path)) else: texture_section.props.append((tex_prop, texture_dict[tex_prop])) material_export_data.sections.append(texture_section) else: # DEFAULT MATERIAL material_name = str("_" + material_name + "_-_default_settings_") material_export_data = _default_material(material_name) material_dict[material_name] = material_export_data # create materials sections for looks material_sections = _fill_material_sections(material_list, material_dict) look_data = { "name": curr_look_name, "material_sections": material_sections } look_list.append(look_data) # restore look applied before export root_object.scs_props.active_scs_look = saved_active_look # PARTS AND VARIANTS... part_list_cnt = len(used_parts.keys()) if len(root_object.scs_object_variant_inventory) == 0: # If there is no Variant, add the Default one... part_list = _fill_part_list(root_object.scs_object_part_inventory, used_parts, all_parts=True) variant_list.append((_VARIANT_consts.default_name, part_list), ) else: for variant in root_object.scs_object_variant_inventory: part_list = _fill_part_list(variant.parts, used_parts) variant_list.append((variant.name, part_list), ) # DATA CREATION header_section = _fill_header_section(file_name, scs_globals.sign_export) look_section = _fill_look_sections(look_list) # part_sections = fill_part_section(part_list) variant_section = _fill_variant_sections(variant_list) comment_header_section = _fill_comment_header_section(look_list, variant_list) global_section = _fill_global_section(len(look_list), len(variant_list), part_list_cnt, len(used_materials)) # DATA ASSEMBLING pit_container = [comment_header_section, header_section, global_section] for section in look_section: pit_container.append(section) for section in variant_section: pit_container.append(section) # FILE EXPORT ind = " " pit_filepath = str(filepath + ".pit") result = _pix_container.write_data_to_file(pit_container, pit_filepath, ind) # print("************************************") return result
def export(root_object, filepath, used_materials, used_parts): """Export PIT. :param root_object: SCS root object :type root_object: bpy.types.Object :param filepath: PIT file path :type filepath: str :param used_materials: materials transitional structure for accessing stored materials from PIM :type used_materials: io_scs_tools.exp.transition_structs.materials.MaterialsTrans :param used_parts: parts transitional structure for accessing stored parts from PIM, PIC and PIP :type used_parts: io_scs_tools.exp.transition_structs.parts.PartsTrans :return: True if successful; False otherwise; :rtype: bool """ scs_globals = _get_scs_globals() output_type = scs_globals.output_type file_name = root_object.name print("\n************************************") print("** SCS PIT Exporter **") print("** (c)2014 SCS Software **") print("************************************\n") # DATA GATHERING look_list = [] variant_list = [] saved_active_look = root_object.scs_props.active_scs_look looks_inventory = root_object.scs_object_look_inventory looks_count = len(looks_inventory) if looks_count <= 0: looks_count = 1 used_materials_pairs = used_materials.get_as_pairs() for i in range(0, looks_count): # apply each look from inventory first if len(looks_inventory) > 0: root_object.scs_props.active_scs_look = i # actually write values to material because Blender might not refresh data yet _looks.apply_active_look(root_object) curr_look_name = looks_inventory[i].name else: # if no looks create default curr_look_name = "default" material_dict = {} material_list = [] # get materials data for material_name, material in used_materials_pairs: if material is None: material_name = str("_default_material_-_default_settings_") # DEFAULT MATERIAL material_export_data = _default_material(material_name) material_list.append(material_name) else: # print('material name: %r' % material.name) material_list.append(material) # MATERIAL EFFECT effect_name = material.scs_props.mat_effect_name # PRESET SHADERS flags = 0 def_cnt = attribute_cnt = texture_cnt = 0 def_sections = [] attribute_sections = [] texture_sections = [] active_shader_preset_name = material.scs_props.active_shader_preset_name # SUBSTANCE substance_value = material.scs_props.substance # only write substance to material if it's assigned if substance_value != "None" and substance_value != "": substance_data = _SectionData("Attribute") substance_data.props.append(("Format", "STRING")) substance_data.props.append(("Tag", "substance")) substance_data.props.append(("Value", ["i", (substance_value,)])) attribute_sections.append(substance_data) attribute_cnt += 1 if active_shader_preset_name in _get_shader_presets_inventory() and active_shader_preset_name != "<none>": preset = _get_shader_presets_inventory()[active_shader_preset_name] flavors_str = effect_name[len(preset.effect):] section = _shader_presets_cache.get_section(preset, flavors_str) # FLAGS for prop in section.props: if prop[0] == "Flags": flags = int(not material.scs_props.enable_aliasing) break # COLLECT ATTRIBUTES AND TEXTURES for item in section.sections: # DATA EXCHANGE FORMAT ATRIBUTE if item.type == "DataExchangeFormat": def_data = _SectionData("DataExchangeFormat") for rec in item.props: def_data.props.append((rec[0], rec[1])) def_sections.append(def_data) def_cnt += 1 # if attribute is hidden in shader preset ignore it on export # this is useful for flavor hiding some attributes from original material # eg: airbrush on "truckpaint" hides R G B aux attributes which are not present # when using airbrush flavor hidden = item.get_prop_value("Hide") if hidden and hidden == "True": continue preview_only = item.get_prop_value("PreviewOnly") if preview_only and preview_only == "True": continue # ATTRIBUTES if item.type == "Attribute": # print(' Attribute:') attribute_data = _SectionData("Attribute") for rec in item.props: # print(' rec: %r' % str(rec)) if rec[0] == "Format": attribute_data.props.append((rec[0], rec[1])) elif rec[0] == "Tag": # tag_prop = rec[1].replace("[", "").replace("]", "") # attribute_data.props.append((rec[0], tag_prop)) attribute_data.props.append((rec[0], rec[1])) elif rec[0] == "Value": format_prop = item.get_prop("Format")[1] tag_prop = item.get_prop("Tag")[1] tag_prop = tag_prop.replace("[", "").replace("]", "") # print(' format_prop: %r' % str(format_prop)) # print(' tag_prop: %r' % str(tag_prop)) if "aux" in tag_prop: aux_props = getattr(material.scs_props, "shader_attribute_" + tag_prop) value = [] for aux_prop in aux_props: value.append(aux_prop.value) # extract list if there is only one value inside and tagged as FLOAT # otherwise it gets saved as: "Value: ( [0.0] )" instead of: "Value: ( 0.0 )" if len(value) == 1 and format_prop == "FLOAT": value = value[0] else: value = getattr(material.scs_props, "shader_attribute_" + tag_prop, "NO TAG") # print(' value: %s' % str(value)) if format_prop == 'FLOAT': attribute_data.props.append((rec[0], ["&&", (value,)])) else: attribute_data.props.append((rec[0], ["i", tuple(value)])) attribute_sections.append(attribute_data) attribute_cnt += 1 # TEXTURES elif item.type == "Texture": # print(' Texture:') texture_data = _SectionData("Texture") for rec in item.props: # print(' rec: %r' % str(rec)) if rec[0] == "Tag": tag_prop = rec[1].split(":")[1] tag = str("texture[" + str(texture_cnt) + "]:" + tag_prop) texture_data.props.append((rec[0], tag)) elif rec[0] == "Value": tag_prop = item.get_prop("Tag")[1].split(":")[1] # print(' tag_prop: %r' % str(tag_prop)) # create and get path to tobj tobj_rel_path = _get_texture_path_from_material(material, tag_prop, os.path.dirname(filepath)) texture_data.props.append((rec[0], tobj_rel_path)) texture_sections.append(texture_data) texture_cnt += 1 material_export_data = _SectionData("Material") material_export_data.props.append(("Alias", material.name)) material_export_data.props.append(("Effect", effect_name)) material_export_data.props.append(("Flags", flags)) if output_type.startswith('def'): material_export_data.props.append(("DataExchangeFormatCount", def_cnt)) material_export_data.props.append(("AttributeCount", attribute_cnt)) material_export_data.props.append(("TextureCount", texture_cnt)) if output_type.startswith('def'): for def_section in def_sections: material_export_data.sections.append(def_section) for attribute in attribute_sections: material_export_data.sections.append(attribute) for texture in texture_sections: material_export_data.sections.append(texture) elif active_shader_preset_name == "<imported>": material_attributes = material['scs_shader_attributes']['attributes'].to_dict().values() material_textures = material['scs_shader_attributes']['textures'].to_dict().values() material_export_data = _SectionData("Material") material_export_data.props.append(("Alias", material.name)) material_export_data.props.append(("Effect", effect_name)) material_export_data.props.append(("Flags", int(not material.scs_props.enable_aliasing))) material_export_data.props.append(("AttributeCount", len(material_attributes))) material_export_data.props.append(("TextureCount", len(material_textures))) for attribute_dict in material_attributes: attribute_section = _SectionData("Attribute") format_value = "" for attr_prop in sorted(attribute_dict.keys()): # get the format of current attribute (we assume that "Format" attribute is before "Value" attribute in this for loop) if attr_prop == "Format": format_value = attribute_dict[attr_prop] if attr_prop == "Value" and ("FLOAT" in format_value or "STRING" in format_value): tag_prop = attribute_dict["Tag"].replace("[", "").replace("]", "") if "aux" in tag_prop: aux_props = getattr(material.scs_props, "shader_attribute_" + tag_prop) value = [] for aux_prop in aux_props: value.append(aux_prop.value) else: value = getattr(material.scs_props, "shader_attribute_" + tag_prop, None) if isinstance(value, float): value = [value] if value is None: attribute_section.props.append((attr_prop, ["i", tuple(attribute_dict[attr_prop])])) else: attribute_section.props.append((attr_prop, ["i", tuple(value)])) elif attr_prop == "Tag" and "aux" in attribute_dict[attr_prop]: attribute_section.props.append((attr_prop, "aux[" + attribute_dict[attr_prop][3:] + "]")) else: attribute_section.props.append((attr_prop, attribute_dict[attr_prop])) material_export_data.sections.append(attribute_section) for texture_dict in material_textures: texture_section = _SectionData("Texture") tag_id_string = "" for tex_prop in sorted(texture_dict.keys()): if tex_prop == "Tag": tag_id_string = texture_dict[tex_prop].split(':')[1] if tex_prop == "Value" and tag_id_string != "": tobj_rel_path = _get_texture_path_from_material(material, tag_id_string, os.path.dirname(filepath)) texture_section.props.append((tex_prop, tobj_rel_path)) else: texture_section.props.append((tex_prop, texture_dict[tex_prop])) material_export_data.sections.append(texture_section) else: # DEFAULT MATERIAL material_name = str("_" + material_name + "_-_default_settings_") material_export_data = _default_material(material_name) material_dict[material_name] = material_export_data # create materials sections for looks material_sections = _fill_material_sections(material_list, material_dict) look_data = { "name": curr_look_name, "material_sections": material_sections } look_list.append(look_data) # restore look applied before export root_object.scs_props.active_scs_look = saved_active_look # PARTS AND VARIANTS... used_parts_names = used_parts.get_as_list() part_list_cnt = len(used_parts_names) if len(root_object.scs_object_variant_inventory) == 0: # If there is no Variant, add the Default one... part_list = _fill_part_list(root_object.scs_object_part_inventory, used_parts_names, all_parts=True) variant_list.append((_VARIANT_consts.default_name, part_list), ) else: for variant in root_object.scs_object_variant_inventory: part_list = _fill_part_list(variant.parts, used_parts_names) variant_list.append((variant.name, part_list), ) # DATA CREATION header_section = _fill_header_section(file_name, scs_globals.sign_export) look_section = _fill_look_sections(look_list) # part_sections = fill_part_section(part_list) variant_section = _fill_variant_sections(variant_list) comment_header_section = _fill_comment_header_section(look_list, variant_list) global_section = _fill_global_section(len(look_list), len(variant_list), part_list_cnt, len(used_materials_pairs)) # DATA ASSEMBLING pit_container = [comment_header_section, header_section, global_section] for section in look_section: pit_container.append(section) for section in variant_section: pit_container.append(section) # FILE EXPORT ind = " " pit_filepath = str(filepath + ".pit") result = _pix_container.write_data_to_file(pit_container, pit_filepath, ind) # print("************************************") return result