302 lines
12 KiB
Python
302 lines
12 KiB
Python
"""
|
|
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 <http://www.gnu.org/licenses/>.
|
|
"""
|
|
|
|
# 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'}
|