Пример #1
0
def draw_scs_looks_panel(layout, scene, active_object, scs_root_object):
    """Creates 'SCS Looks' settings sub-panel.

    :param layout: Blender UI Layout to draw to
    :type layout: bpy.types.UILayout
    :param scene: Blender Scene
    :type scene: bpy.types.Scene
    :param active_object: active object
    :type active_object: bpy.types.Object
    :param scs_root_object: SCS Root Object
    :type scs_root_object: bpy.types.Object
    """

    layout_column = layout.column(align=True)
    layout_box = layout_column.box()

    if scene.scs_props.scs_look_panel_expand:

        # HEADER (COLLAPSIBLE - OPENED)
        row = layout_box.row()
        row.prop(scene.scs_props, 'scs_look_panel_expand', text="SCS Looks:", icon='TRIA_DOWN', icon_only=True, emboss=False)
        row.prop(scene.scs_props, 'scs_look_panel_expand', text=" ", icon='NONE', icon_only=True, emboss=False)

        layout_box = layout_column.box()  # body box

        if len(_object_utils.gather_scs_roots(bpy.context.selected_objects)) > 1 and active_object is not scs_root_object:

            col = layout_box.box().column(align=True)
            row = col.row()
            row.label("WARNING", icon="ERROR")
            row = col.row()
            row.label("Can not edit looks! Selection has multiple game objects.")

        else:  # more roots or active object is root object

            row = layout_box.row()
            row.template_list(
                'SCSObjectLookSlots',
                list_id="",
                dataptr=scs_root_object,
                propname="scs_object_look_inventory",
                active_dataptr=scs_root_object.scs_props,
                active_propname="active_scs_look",
                rows=3,
                maxrows=5,
                type='DEFAULT',
                columns=9
            )

            # LIST BUTTONS
            col = row.column(align=True)
            col.operator('object.add_scs_look', text="", icon='ZOOMIN')
            col.operator('object.remove_scs_look', text="", icon='ZOOMOUT')

    else:
        row = layout_box.row()
        row.prop(scene.scs_props, 'scs_look_panel_expand', text="SCS Looks:", icon='TRIA_RIGHT', icon_only=True, emboss=False)
        row.prop(scene.scs_props, 'scs_look_panel_expand', text=" ", icon='NONE', icon_only=True, emboss=False)
Пример #2
0
def draw_scs_looks_panel(layout,
                         active_object,
                         scs_root_object,
                         without_box=False):
    """Creates 'SCS Looks' settings sub-panel.

    :param layout: Blender UI Layout to draw to
    :type layout: bpy.types.UILayout
    :param active_object: active object
    :type active_object: bpy.types.Object
    :param scs_root_object: SCS Root Object
    :type scs_root_object: bpy.types.Object
    :param without_box: draw without extra box layout?
    :type without_box: bool
    """

    layout_column = layout.column(align=True)

    if without_box:
        layout_box = layout_column
    else:
        layout_box = layout_column.box()

    if len(_object_utils.gather_scs_roots(bpy.context.selected_objects)
           ) > 1 and active_object is not scs_root_object:

        warning_box = layout_box.column(align=True)

        header = warning_box.box()
        header.label(text="WARNING", icon='ERROR')
        body = warning_box.box()
        col = body.column(align=True)
        col.label(text="Can not edit looks!")
        col.label(text="Selection has multiple game objects.")

    else:  # more roots or active object is root object

        row = layout_box.row()
        row.template_list(SCS_TOOLS_UL_ObjectLookSlots.__name__,
                          list_id="",
                          dataptr=scs_root_object,
                          propname="scs_object_look_inventory",
                          active_dataptr=scs_root_object.scs_props,
                          active_propname="active_scs_look",
                          rows=3,
                          maxrows=5,
                          type='DEFAULT',
                          columns=9)

        # LIST BUTTONS
        col = row.column(align=True)
        col.operator('object.scs_tools_add_look', text="", icon='ADD')
        col.operator('object.scs_tools_remove_active_look',
                     text="",
                     icon='REMOVE')
Пример #3
0
        def execute(self, context):
            lprint("I " + self.bl_label + "...")

            from io_scs_tools.internals.shader_presets import cache as _shader_presets_cache
            from io_scs_tools.utils import get_shader_presets_inventory as _get_shader_presets_inventory

            mat = context.material
            mat_scs_props = mat.scs_props
            """:type: io_scs_tools.properties.material.MaterialSCSTools"""
            preset = _get_shader_presets_inventory()[mat_scs_props.active_shader_preset_name]
            """:type: io_scs_tools.properties.world.ShaderPresetsInventoryItem"""

            # extract only flavor effect part of string
            flavor_effect_part = mat_scs_props.mat_effect_name[len(preset.effect):]

            new_flavor_state = not self.flavor_enabled
            flavors_suffix = ""
            for flavor in preset.flavors:
                flavor_variant_found = False
                for flavor_variant in flavor.variants:

                    if flavor_variant.name == self.flavor_name:
                        # add founded flavor to flavors suffix only if enabled
                        if new_flavor_state:
                            flavors_suffix += "." + flavor_variant.name

                        flavor_variant_found = True
                        break

                # if one variant of flavor is found skip all other variants
                if flavor_variant_found:
                    continue

                # make sure to add all other enabled flavors to flavors suffix
                for flavor_variant in flavor.variants:

                    is_in_middle = "." + flavor_variant.name + "." in flavor_effect_part
                    is_on_end = flavor_effect_part.endswith("." + flavor_variant.name)

                    if is_in_middle or is_on_end:
                        flavors_suffix += "." + flavor_variant.name

            # finally set new shader data to material
            section = _shader_presets_cache.get_section(preset, flavors_suffix)
            context.material.scs_props.mat_effect_name = preset.effect + flavors_suffix
            _material_utils.set_shader_data_to_material(context.material, section)

            # sync shader types on all scs roots by updating looks on them
            # to avoid different shader types on different scs roots for same material
            for scs_root in _object_utils.gather_scs_roots(bpy.data.objects):
                _looks.update_look_from_material(scs_root, mat, True)

            return {'FINISHED'}
Пример #4
0
    def get_objects_for_export(self):
        """Get objects for export, list filtered and extended depending on export scope.

        :return: list of objects to export calculated from selection
        :rtype: list[bpy.types.Object]
        """

        # if cached, just return
        if self.cached_objects:
            return self.cached_objects

        objs_to_export = []

        export_scope = _get_scs_globals().export_scope
        if export_scope == "selection":
            for root in _object_utils.gather_scs_roots(
                    bpy.context.selected_objects):
                objs_to_export.append(root)

                children = _object_utils.get_children(root)
                children_unselected = []
                children_selected = []

                for child_obj in children:
                    if child_obj.select_get():
                        children_selected.append(child_obj)
                    elif child_obj.users_scene:  # unlinked objects shouldn't be exported
                        children_unselected.append(child_obj)

                # if any children was selected make sure, to export only them
                if len(children_selected) > 0:
                    objs_to_export.extend(children_selected)
                else:
                    objs_to_export.extend(children_unselected)
        elif export_scope == "scene":
            objs_to_export = tuple(bpy.context.scene.objects)
        elif export_scope == "scenes":
            scenes_objs = set()
            for scene in bpy.data.scenes:
                scenes_objs.update(scene.objects)
            objs_to_export = tuple(scenes_objs)

        # cache filtered list, to be able to retrive it quickly on second call
        self.cached_objects = objs_to_export

        return self.cached_objects
Пример #5
0
def post_load(scene):
    # get Blender Tools version from last blend file load
    last_load_bt_ver = _get_scs_globals().last_load_bt_version

    scs_roots = None

    """
    Applies fixes for v0.6 or less:
    1. fixes reflection textures tga's for tobjs as TOBJ load is now supported and unlock that textures
    2. calls update on all set textures to correct paths for them
    3. tries to fix active shader preset name for materials, because of new flavor system
    """
    if _info_utils.cmp_ver_str(last_load_bt_ver, "0.6") <= 0:

        print("INFO\t-  Applying fixes for version <= 0.6")

        for material in bpy.data.materials:

            # ignore materials not related to blender tools
            if material.scs_props.mat_effect_name == "":
                continue

            for tex_type in material.scs_props.get_texture_types().keys():

                texture_attr_str = "shader_texture_" + tex_type
                if texture_attr_str in material.scs_props.keys():

                    # 1. fix reflection textures
                    if tex_type == "reflection":

                        is_building_ref = material.scs_props[texture_attr_str].endswith("/bulding_ref.tga")
                        is_generic_s = material.scs_props[texture_attr_str].endswith("material/environment/generic_s.tga")
                        is_glass_interior = material.scs_props.active_shader_preset_name == "glass - interior"
                        is_dif_spec_weight_add_env = material.scs_props.active_shader_preset_name == "dif.spec.weight.add.env"
                        is_truckpaint = material.scs_props.active_shader_preset_name.startswith("truckpaint")

                        # fix paths
                        if is_building_ref:
                            material.scs_props[texture_attr_str] = material.scs_props[texture_attr_str][:-4]
                            material.scs_props[texture_attr_str + "_locked"] = False
                        elif is_generic_s:
                            if is_glass_interior:
                                material.scs_props[texture_attr_str] = "//material/environment/interior_reflection"
                            elif is_dif_spec_weight_add_env:
                                material.scs_props[texture_attr_str] = "//material/environment/generic_reflection"
                            else:
                                material.scs_props[texture_attr_str] = "//material/environment/vehicle_reflection"

                            # unlock reflection textures everywhere except on truckpaint shader
                            if not is_truckpaint:
                                material.scs_props[texture_attr_str + "_locked"] = False

                        # acquire roots on demand only once
                        scs_roots = _object_utils.gather_scs_roots(bpy.data.objects) if not scs_roots else scs_roots

                        # propagate reflection texture change on all of the looks.
                        # NOTE: We can afford write through because old BT had all reflection textures locked
                        # meaning user had to use same texture on all looks
                        # NOTE#2: Printouts like:
                        # "Look with ID: X doesn't have entry for material 'X' in SCS Root 'X',
                        #  property 'shader_texture_reflection' won't be updated!"
                        # are expected here, because we don't use any safety check,
                        # if material is used on the mesh objects inside scs root
                        for scs_root in scs_roots:
                            _looks.write_through(scs_root, material, texture_attr_str)

                    # 2. trigger update function for path reload and reload of possible missing textures
                    update_func = getattr(material.scs_props, "update_" + texture_attr_str, None)
                    if update_func:
                        update_func(material)

            # ignore already properly set materials
            if material.scs_props.active_shader_preset_name in _get_shader_presets_inventory():
                continue

            # 3. try to recover "active_shader_preset_name" from none flavor times Blender Tools
            material_textures = {}
            if "scs_shader_attributes" in material and "textures" in material["scs_shader_attributes"]:
                for texture in material["scs_shader_attributes"]["textures"].values():
                    tex_id = texture["Tag"].split(":")[1]
                    tex_value = texture["Value"]
                    material_textures[tex_id] = tex_value

            (preset_name, preset_section) = _material_utils.find_preset(material.scs_props.mat_effect_name, material_textures)
            if preset_name:
                material.scs_props.active_shader_preset_name = preset_name

                # acquire roots on demand only once
                scs_roots = _object_utils.gather_scs_roots(bpy.data.objects) if not scs_roots else scs_roots

                # make sure to fix active preset shader name in all looks
                # NOTE: Printouts like:
                # "Look with ID: X doesn't have entry for material 'X' in SCS Root 'X',
                #  property 'active_shader_preset_name' won't be updated!"
                # are expected here, because we don't use any safety check,
                # if material is used on the mesh objects inside scs root
                for scs_root in scs_roots:
                    _looks.write_through(scs_root, material, "active_shader_preset_name")

    # as last update "last load" Blender Tools version to current
    _get_scs_globals().last_load_bt_version = get_tools_version()
Пример #6
0
        def execute(self, context):
            material = context.active_object.active_material

            if not material or not hasattr(material.scs_props, self.property_str):
                return {'CANCELLED'}

            scs_roots = []
            active_scs_root = _object_utils.get_scs_root(context.active_object)
            if active_scs_root:
                scs_roots.append(active_scs_root)

            if self.is_ctrl:
                scs_roots = _object_utils.gather_scs_roots(bpy.data.objects)

            if self.is_shift or not self.is_ctrl:  # WT either on active only or all SCS roots; (Shift + Ctrl) or none

                altered_looks = 0
                for scs_root in scs_roots:
                    altered_looks += _looks.write_through(scs_root, material, self.property_str)

                if altered_looks > 0:
                    message = "Write through successfully altered %s looks on %s SCS Root Objects!" % (altered_looks, len(scs_roots))
                else:
                    message = "Nothing to write through."

                self.report({'INFO'}, message)

            elif self.is_ctrl:  # special WT only into the same look of other SCS Roots

                # get current look id
                look_i = active_scs_root.scs_props.active_scs_look
                look_name = active_scs_root.scs_object_look_inventory[look_i].name if look_i >= 0 else None

                if look_name is None:
                    self.report({'WARNING'}, "Aborting as current object is not in any SCS Game Object, parent it to SCS Root first!")
                    return {'CANCELLED'}

                altered_looks = 0
                for scs_root in scs_roots:

                    # ignore active root
                    if scs_root == active_scs_root:
                        continue

                    look_id = -1

                    # search for same look by name on other scs root
                    for look in scs_root.scs_object_look_inventory:
                        if look.name == look_name:
                            look_id = look.id
                            break

                    if _looks.write_prop_to_look(scs_root, look_id, material, self.property_str):
                        altered_looks += 1

                if len(scs_roots) - 1 != altered_looks:
                    self.report({'WARNING'}, "WT partially done, same look was found on %s/%s other SCS Root Objects!" %
                                (altered_looks, len(scs_roots) - 1))
                else:
                    self.report({'INFO'}, "Write through altered property on %s other SCS Root Objects!" % altered_looks)

            return {'FINISHED'}