""" Copyright (C) 2023 Adobe. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . """ # file: ops/presets.py # brief:Presets Operators # author Adobe - 3D & Immersive # copyright 2023 Adobe Inc. All rights reserved. import os import bpy from bpy_extras.io_utils import ImportHelper from ..common import PRESET_DEFAULT, PRESET_CUSTOM, PRESET_EXTENSION, Code_Response from ..utils import SUBSTANCE_Utils from ..api import SUBSTANCE_Api from ..sbsar.sbsar import SBS_Preset class SUBSTANCE_OT_AddPreset(bpy.types.Operator): bl_idname = 'substance.add_preset' bl_label = 'New Preset' bl_description = "Set the current parameters as a new preset" preset_name: bpy.props.StringProperty(name="Preset Name") # noqa def invoke(self, context, event): return context.window_manager.invoke_props_dialog(self) def draw(self, context): _layout = self.layout _row = _layout.row() _row.label(text="Preset Name: ") _row.prop(self, 'preset_name', text="") def execute(self, context): if len(self.preset_name) > 0: _sbsar = context.scene.loaded_sbsars[context.scene.sbsar_index] _graph = SUBSTANCE_Utils.get_selected_graph(context) _result = SUBSTANCE_Api.sbsar_preset_add(_sbsar, _graph, self.preset_name) if _result[0] != Code_Response.success: SUBSTANCE_Utils.log_data( "ERROR", "[{}] Error while creating the preset".format(Code_Response.preset_create_get_error)) return {'FINISHED'} if _result[1]["result"] != Code_Response.success.value: SUBSTANCE_Utils.log_data( "ERROR", "[{}] Error while getting the newly created preset".format( Code_Response.preset_create_get_error)) return {'FINISHED'} _preset_value = _result[1]["data"]["value"] _obj = { "index": len(_graph.presets), "label": self.preset_name, "embedded": False, "icon": "LOCKED", "value": _preset_value } _preset = SBS_Preset(_obj) _new_preset = _graph.presets.add() _new_preset.init(_preset) _graph.preset_callback = False _graph.presets_list = _preset.index _graph.preset_callback = True SUBSTANCE_Utils.log_data("INFO", "Preset [{}] created".format(self.preset_name), display=True) self.preset_name = "" else: SUBSTANCE_Utils.log_data( "ERROR", "[{}] Error while creating new preset, please set a name for the preset".format( Code_Response.preset_create_no_name_error), display=True) return {'FINISHED'} class SUBSTANCE_OT_DeletePreset(bpy.types.Operator): bl_idname = 'substance.delete_preset' bl_label = 'Delete selected preset?' bl_description = "Delete the current preset" @classmethod def poll(cls, context): _selected_graph = SUBSTANCE_Utils.get_selected_graph(context) _selected_preset_idx = int(_selected_graph.presets_list) _selected_preset = _selected_graph.presets[_selected_preset_idx] return not _selected_preset.embedded and _selected_preset.icon != "UNLOCKED" def execute(self, context): _selected_graph = SUBSTANCE_Utils.get_selected_graph(context) _selected_preset_idx = int(_selected_graph.presets_list) _selected_graph.presets_list = "0" _selected_graph.presets.remove(_selected_preset_idx) SUBSTANCE_Utils.log_data("INFO", "Preset deleted", display=True) return {'FINISHED'} class SUBSTANCE_OT_DeletePresetModal(bpy.types.Operator): bl_idname = 'substance.delete_preset_modal' bl_label = 'Delete selected preset?' bl_description = "Delete the current preset" @classmethod def poll(cls, context): _selected_graph = SUBSTANCE_Utils.get_selected_graph(context) _selected_preset_idx = int(_selected_graph.presets_list) _selected_preset = _selected_graph.presets[_selected_preset_idx] return not _selected_preset.embedded and _selected_preset.icon != "UNLOCKED" def invoke(self, context, event): return context.window_manager.invoke_props_dialog(self) def draw(self, context): _layout = self.layout _row = _layout.row() _row.label(text="") def execute(self, context): _selected_graph = SUBSTANCE_Utils.get_selected_graph(context) _selected_preset_idx = int(_selected_graph.presets_list) _selected_graph.presets_list = "0" _selected_graph.presets.remove(_selected_preset_idx) SUBSTANCE_Utils.log_data("INFO", "Preset deleted", display=True) return {'FINISHED'} class SUBSTANCE_OT_ImportPreset(bpy.types.Operator, ImportHelper): bl_idname = 'substance.import_preset' bl_label = 'Import preset' bl_description = "Import a preset from a file" filter_glob: bpy.props.StringProperty(default='*' + PRESET_EXTENSION, options={'HIDDEN'}) # noqa files: bpy.props.CollectionProperty(name='SBSAR Presets Files', type=bpy.types.OperatorFileListElement) # noqa directory: bpy.props.StringProperty(subtype="DIR_PATH") # noqa def __init__(self): self.filepath = '' def execute(self, context): _sbsar = context.scene.loaded_sbsars[context.scene.sbsar_index] for _f in self.files: _filepath = os.path.join(self.directory, _f.name) _result = SUBSTANCE_Api.sbsar_preset_read(_filepath) if _result[0] != Code_Response.success: SUBSTANCE_Utils.log_data("ERROR", "[{}] Error while reading preset from file".format(_result)) continue _obj = _result[1] _not_found = len(_sbsar.graphs) for _graph in _sbsar.graphs: if _graph.identifier not in _obj: _not_found -= 1 continue for _preset in _obj[_graph.identifier]: if _preset["label"] in _graph.presets: if _preset["label"] == PRESET_CUSTOM or _preset["label"] == PRESET_DEFAULT: SUBSTANCE_Utils.log_data( "ERROR", "[{}] Error [{}] cannot be overwritten".format( Code_Response.preset_import_protected_error, _preset["label"]), display=True) continue for _existing_preset in _graph.presets: if _preset["label"] != _existing_preset.name: continue if _existing_preset.embedded: SUBSTANCE_Utils.log_data( "ERROR", "[{}] Error [{}] cannot be overwritten".format( Code_Response.preset_import_protected_error, _preset["label"]), display=True) continue _existing_preset.value = _preset["value"] SUBSTANCE_Utils.log_data( "INFO", "Preset [{}] updated.".format(_preset["label"]), display=True) else: _obj = { "index": len(_graph.presets), "label": _preset["label"], "embedded": False, "icon": "LOCKED", "value": _preset["value"] } _preset = SBS_Preset(_obj) _new_preset = _graph.presets.add() _new_preset.init(_preset) SUBSTANCE_Utils.log_data( "INFO", "Preset [{}] imported.".format(_preset.label), display=True) if _not_found == 0: SUBSTANCE_Utils.log_data( "ERROR", "[{}] Error Preset [{}] cannot be imported in this substance".format( Code_Response.preset_import_not_graph, _f.name), display=True) return {'FINISHED'} return {'FINISHED'} class SUBSTANCE_OT_ExportPreset(bpy.types.Operator, ImportHelper): bl_idname = 'substance.export_preset' bl_label = 'Export preset' bl_description = "Export current preset to a file" preset_name: bpy.props.StringProperty(name="Preset Name") # noqa def __init__(self): self.filepath = '' @classmethod def poll(cls, context): _selected_graph = SUBSTANCE_Utils.get_selected_graph(context) _selected_preset_idx = int(_selected_graph.presets_list) _selected_preset = _selected_graph.presets[_selected_preset_idx] return _selected_preset.name != PRESET_DEFAULT and _selected_preset.name != PRESET_CUSTOM def execute(self, context): _selected_graph = SUBSTANCE_Utils.get_selected_graph(context) _selected_preset_idx = int(_selected_graph.presets_list) _selected_preset = _selected_graph.presets[_selected_preset_idx] _result = SUBSTANCE_Api.sbsar_preset_write( self.filepath, _selected_preset) if _result != Code_Response.success: SUBSTANCE_Utils.log_data( "ERROR", "[{}] Error while writting the current preset".format(_result), display=True) else: SUBSTANCE_Utils.log_data("INFO", "Preset exported", display=True) return {'FINISHED'} class SUBSTANCE_OT_ExportAll(bpy.types.Operator, ImportHelper): bl_idname = 'substance.export_all' bl_label = 'Export all custom presets' bl_description = "Export all custom presets" def __init__(self): self.filepath = '' def execute(self, context): _selected_graph = SUBSTANCE_Utils.get_selected_graph(context) for _preset in _selected_graph.presets: if _preset.embedded or _preset.name == PRESET_CUSTOM: continue _result = SUBSTANCE_Api.sbsar_preset_write( self.filepath, _preset) if _result != Code_Response.success: SUBSTANCE_Utils.log_data( "ERROR", "[{}] Error while writting the current preset".format(_result), display=True) else: SUBSTANCE_Utils.log_data("INFO", "Preset {} exported".format(_preset.label), display=True) return {'FINISHED'}