2025-07-01
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
"""
|
||||
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: sbsar/async_ops.py
|
||||
# brief: Asynchronous substance operations
|
||||
# author Adobe - 3D & Immersive
|
||||
# copyright 2023 Adobe Inc. All rights reserved.
|
||||
|
||||
|
||||
import os
|
||||
import bpy
|
||||
import traceback
|
||||
|
||||
from ..utils import SUBSTANCE_Utils
|
||||
from ..thread_ops import SUBSTANCE_Threads
|
||||
from ..common import RENDER_KEY, ADDON_PACKAGE
|
||||
|
||||
|
||||
def _render_sbsar(context, sbsar, index):
|
||||
_addon_prefs = context.preferences.addons[ADDON_PACKAGE].preferences
|
||||
if not os.path.exists(_addon_prefs.path_default):
|
||||
os.makedirs(_addon_prefs.path_default)
|
||||
|
||||
from ..api import SUBSTANCE_Api
|
||||
_render_id = RENDER_KEY.format(sbsar.uuid, sbsar.graphs[index].index)
|
||||
_graph = sbsar.graphs[index]
|
||||
|
||||
_outputs = []
|
||||
for _output in _graph.outputs:
|
||||
_item = {
|
||||
"identifier": _output.identifier,
|
||||
"enabled": _output.shader_enabled,
|
||||
"format": _output.shader_format,
|
||||
"bitdepth": _output.shader_bitdepth
|
||||
}
|
||||
_outputs.append(_item)
|
||||
|
||||
_data = {
|
||||
"uuid": sbsar.uuid,
|
||||
"index": index,
|
||||
"out_path": _addon_prefs.path_default,
|
||||
"outputs": _outputs
|
||||
}
|
||||
SUBSTANCE_Api.sbsar_render(_render_id, _data)
|
||||
|
||||
|
||||
def _set_input_visibility(sbsar, graph, inputs):
|
||||
try:
|
||||
def _callback_visibility():
|
||||
_selected_sbsar = None
|
||||
for _item in bpy.context.scene.loaded_sbsars:
|
||||
if _item.uuid == sbsar.uuid:
|
||||
_selected_sbsar = _item
|
||||
break
|
||||
|
||||
if _selected_sbsar is None:
|
||||
return
|
||||
|
||||
_graph = _selected_sbsar.graphs[int(graph.index)]
|
||||
for _input in inputs:
|
||||
if _input["identifier"] in _graph.inputs:
|
||||
_graph.inputs[_input["identifier"]].visibleIf = _input["visibleIf"]
|
||||
|
||||
SUBSTANCE_Threads.main_thread_run(_callback_visibility)
|
||||
|
||||
except Exception:
|
||||
SUBSTANCE_Utils.log_data("ERROR", "Exception - Unknown Error while setting parameter visibility:")
|
||||
SUBSTANCE_Utils.log_traceback(traceback.format_exc())
|
||||
@@ -0,0 +1,139 @@
|
||||
"""
|
||||
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: shader/callbacks.py
|
||||
# brief: Callbacks for susbtance outputs and properties
|
||||
# author Adobe - 3D & Immersive
|
||||
# copyright 2023 Adobe Inc. All rights reserved.
|
||||
|
||||
|
||||
import bpy
|
||||
|
||||
from ..thread_ops import SUBSTANCE_Threads
|
||||
from ..sbsar.async_ops import _render_sbsar, _set_input_visibility
|
||||
from ..utils import SUBSTANCE_Utils
|
||||
from ..common import (
|
||||
PRESET_CUSTOM,
|
||||
Code_InputType,
|
||||
Code_InputIdentifier,
|
||||
Code_InputWidget,
|
||||
Code_OutputSizeSuffix,
|
||||
Code_Response
|
||||
)
|
||||
|
||||
|
||||
class SUBSTANCE_SbsarCallbacks():
|
||||
# Output Size
|
||||
@staticmethod
|
||||
def on_linked_changed(self, context, parm_identifier):
|
||||
if not hasattr(self, Code_InputIdentifier.outputsize.value + Code_OutputSizeSuffix.linked.value):
|
||||
return
|
||||
|
||||
_linked = getattr(self, Code_InputIdentifier.outputsize.value + Code_OutputSizeSuffix.linked.value)
|
||||
_new_width_width = getattr(self, Code_InputIdentifier.outputsize.value + Code_OutputSizeSuffix.width.value)
|
||||
if _linked:
|
||||
setattr(self, Code_InputIdentifier.outputsize.value + Code_OutputSizeSuffix.height.value, _new_width_width)
|
||||
else:
|
||||
SUBSTANCE_SbsarCallbacks.on_outputsize_changed(self, context, parm_identifier)
|
||||
|
||||
@staticmethod
|
||||
def on_outputsize_changed(self, context, identifier):
|
||||
if not self.callback["enabled"]:
|
||||
return
|
||||
_sbsar = context.scene.loaded_sbsars[context.scene.sbsar_index]
|
||||
_graph = SUBSTANCE_Utils.get_selected_graph(context)
|
||||
_preset = int(_graph.presets_list)
|
||||
|
||||
if not _graph.outputsize_exists:
|
||||
return
|
||||
|
||||
_input = _graph.inputs[Code_InputIdentifier.outputsize.value]
|
||||
_output_size_x = getattr(self, Code_InputIdentifier.outputsize.value + Code_OutputSizeSuffix.width.value)
|
||||
_output_size_y = getattr(self, Code_InputIdentifier.outputsize.value + Code_OutputSizeSuffix.height.value)
|
||||
_new_value = [int(_output_size_x), int(_output_size_y)]
|
||||
|
||||
from ..api import SUBSTANCE_Api
|
||||
_result = SUBSTANCE_Api.sbsar_input_update(
|
||||
context,
|
||||
_sbsar,
|
||||
_graph,
|
||||
_input,
|
||||
_new_value,
|
||||
SUBSTANCE_SbsarCallbacks.on_input_update
|
||||
)
|
||||
|
||||
if _result[0] == Code_Response.success:
|
||||
_new_preset_value = SUBSTANCE_Utils.update_preset_outputsize(
|
||||
_graph.presets[_preset].value,
|
||||
_input,
|
||||
Code_InputType.integer2.value,
|
||||
_new_value
|
||||
)
|
||||
_graph.presets[_preset].value = _new_preset_value
|
||||
|
||||
# Parameters
|
||||
@staticmethod
|
||||
def on_input_update(context, sbsar, graph, input, value):
|
||||
_value = SUBSTANCE_Utils.value_fix_type(input.identifier, input.guiWidget, input.type, value)
|
||||
if input.guiWidget == Code_InputWidget.image.value:
|
||||
if _value == "":
|
||||
_value = "NONE"
|
||||
else:
|
||||
_filepath = bpy.data.images[_value].filepath
|
||||
if _filepath == "":
|
||||
_filepath = SUBSTANCE_Utils.render_image_input(bpy.data.images[_value], bpy.context)
|
||||
_value = _filepath
|
||||
|
||||
from ..api import SUBSTANCE_Api
|
||||
_result = SUBSTANCE_Api.sbsar_input_set(sbsar, graph, input, _value)
|
||||
if context is not None and _result[0] == Code_Response.success:
|
||||
SUBSTANCE_Threads.alt_thread_run(_set_input_visibility, (
|
||||
sbsar,
|
||||
graph,
|
||||
_result[1]["data"]["inputs"]))
|
||||
SUBSTANCE_Threads.alt_thread_run(_render_sbsar, (
|
||||
context,
|
||||
sbsar,
|
||||
int(graph.index)))
|
||||
graph.presets[PRESET_CUSTOM].value = _result[1]["data"]["preset"]
|
||||
return _result
|
||||
|
||||
@staticmethod
|
||||
def on_input_changed(self, context, identifier):
|
||||
if not self.callback["enabled"]:
|
||||
return
|
||||
|
||||
_sbsar = context.scene.loaded_sbsars[context.scene.sbsar_index]
|
||||
_graph = SUBSTANCE_Utils.get_selected_graph(context)
|
||||
_preset = int(_graph.presets_list)
|
||||
|
||||
if _graph.presets[_preset].name != PRESET_CUSTOM:
|
||||
_graph.preset_callback = False
|
||||
_graph.presets_list = _graph.presets[PRESET_CUSTOM].index
|
||||
_graph.preset_callback = True
|
||||
|
||||
_input = _graph.inputs[identifier]
|
||||
_new_value = getattr(self, identifier)
|
||||
|
||||
from ..api import SUBSTANCE_Api
|
||||
SUBSTANCE_Api.sbsar_input_update(
|
||||
context,
|
||||
_sbsar,
|
||||
_graph,
|
||||
_input,
|
||||
_new_value,
|
||||
SUBSTANCE_SbsarCallbacks.on_input_update
|
||||
)
|
||||
@@ -0,0 +1,57 @@
|
||||
"""
|
||||
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: sbsar/manager.py
|
||||
# brief: Substance operations manager
|
||||
# author Adobe - 3D & Immersive
|
||||
# copyright 2023 Adobe Inc. All rights reserved.
|
||||
|
||||
|
||||
import traceback
|
||||
|
||||
from ..factory.sbsar import SUBSTANCE_SbsarFactory
|
||||
from ..common import Code_Response
|
||||
from ..utils import SUBSTANCE_Utils
|
||||
|
||||
|
||||
class SUBSTANCE_SbsarManager():
|
||||
def __init__(self):
|
||||
self.sbsars = {}
|
||||
|
||||
def get(self, uuid):
|
||||
if uuid not in self.sbsars:
|
||||
return None
|
||||
return self.sbsars[uuid]
|
||||
|
||||
def register(self, sbsar):
|
||||
self.sbsars[sbsar.uuid] = sbsar
|
||||
_result = SUBSTANCE_SbsarFactory.register_class(sbsar)
|
||||
return _result
|
||||
|
||||
def unregister(self, uuid):
|
||||
try:
|
||||
if uuid in self.sbsars:
|
||||
_sbsar = self.sbsars[uuid]
|
||||
for _graph in _sbsar.graphs:
|
||||
SUBSTANCE_SbsarFactory.unregister_class(_graph.inputs_class_name)
|
||||
del self.sbsars[uuid]
|
||||
return (Code_Response.success, None)
|
||||
else:
|
||||
return (Code_Response.sbsar_remove_not_found_error, None)
|
||||
except Exception:
|
||||
SUBSTANCE_Utils.log_data("ERROR", "Exception - Substance removal error:")
|
||||
SUBSTANCE_Utils.log_traceback(traceback.format_exc())
|
||||
return (Code_Response.sbsar_factory_unregister_error, None)
|
||||
@@ -0,0 +1,344 @@
|
||||
"""
|
||||
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: sbsar/sbsar.py
|
||||
# brief: Substance class object definition
|
||||
# author Adobe - 3D & Immersive
|
||||
# copyright 2023 Adobe Inc. All rights reserved.
|
||||
|
||||
|
||||
from ..utils import SUBSTANCE_Utils
|
||||
from ..common import (
|
||||
Code_InputType,
|
||||
Code_InputWidget,
|
||||
INPUT_DEFAULT_GROUP,
|
||||
INPUT_IMAGE_DEFAULT_GROUP,
|
||||
PRESET_CUSTOM,
|
||||
CLASS_GRAPH_INPUTS
|
||||
)
|
||||
|
||||
|
||||
class SBS_EnumValue():
|
||||
def __init__(self, enum):
|
||||
self.first = enum["first"]
|
||||
self.second = enum["second"]
|
||||
|
||||
def to_json(self):
|
||||
_obj = {
|
||||
"first": self.first,
|
||||
"second": self.second,
|
||||
}
|
||||
return _obj
|
||||
|
||||
|
||||
class SBS_Input():
|
||||
def __init__(self, index, input):
|
||||
if "index" in input:
|
||||
self.index = input["index"]
|
||||
else:
|
||||
self.index = index
|
||||
|
||||
self.id = input["id"]
|
||||
self.graphID = input["graphID"]
|
||||
self.identifier = input["identifier"]
|
||||
self.label = input["label"]
|
||||
self.guiDescription = input["guiDescription"]
|
||||
|
||||
if input["type"] == Code_InputType.image.name:
|
||||
self.guiGroup = INPUT_IMAGE_DEFAULT_GROUP
|
||||
elif len(input["guiGroup"]) == 0:
|
||||
self.guiGroup = INPUT_DEFAULT_GROUP
|
||||
else:
|
||||
self.guiGroup = input["guiGroup"]
|
||||
|
||||
self.guiVisibleIf = input["guiVisibleIf"]
|
||||
self.userTag = input["userTag"]
|
||||
self.type = input["type"]
|
||||
self.guiWidget = input["guiWidget"]
|
||||
self.showAsPin = input["showAsPin"]
|
||||
self.useCache = input["useCache"]
|
||||
self.visibleIf = input["visibleIf"]
|
||||
self.isHeavyDuty = input["isHeavyDuty"]
|
||||
self.enumValues = []
|
||||
|
||||
if "labelFalse" in input:
|
||||
self.labelFalse = input["labelFalse"]
|
||||
if "labelTrue" in input:
|
||||
self.labelTrue = input["labelTrue"]
|
||||
if "sliderClamp" in input:
|
||||
self.sliderClamp = input["sliderClamp"]
|
||||
if "sliderStep" in input:
|
||||
self.sliderStep = input["sliderStep"]
|
||||
|
||||
if "maxValue" in input:
|
||||
self.maxValue = input["maxValue"]
|
||||
if "minValue" in input:
|
||||
self.minValue = input["minValue"]
|
||||
if "defaultValue" in input:
|
||||
self.defaultValue = input["defaultValue"]
|
||||
if "value" in input:
|
||||
self.value = input["value"]
|
||||
if "channelUse" in input:
|
||||
self.channelUse = input["channelUse"]
|
||||
|
||||
if "enumValues" in input:
|
||||
for _enum in input["enumValues"]:
|
||||
_new_enum = SBS_EnumValue(_enum)
|
||||
self.enumValues.append(_new_enum)
|
||||
|
||||
def to_json(self):
|
||||
_obj = {
|
||||
"id": self.id,
|
||||
"graphID": self.graphID,
|
||||
"identifier": self.identifier,
|
||||
"label": self.label,
|
||||
"guiDescription": self.guiDescription,
|
||||
"guiGroup": self.guiGroup,
|
||||
"guiVisibleIf": self.guiVisibleIf,
|
||||
"userTag": self.userTag,
|
||||
"type": self.type,
|
||||
"guiWidget": self.guiWidget,
|
||||
"showAsPin": self.showAsPin,
|
||||
"useCache": self.useCache,
|
||||
"visibleIf": self.visibleIf,
|
||||
"isHeavyDuty": self.isHeavyDuty
|
||||
}
|
||||
|
||||
if hasattr(self, "labelFalse"):
|
||||
_obj["labelFalse"] = self.labelFalse
|
||||
if hasattr(self, "labelTrue"):
|
||||
_obj["labelTrue"] = self.labelTrue
|
||||
if hasattr(self, "sliderClamp"):
|
||||
_obj["sliderClamp"] = self.sliderClamp
|
||||
if hasattr(self, "sliderStep"):
|
||||
_obj["sliderStep"] = self.sliderStep
|
||||
|
||||
if hasattr(self, "maxValue"):
|
||||
_obj["maxValue"] = self.maxValue
|
||||
if hasattr(self, "minValue"):
|
||||
_obj["minValue"] = self.minValue
|
||||
if hasattr(self, "defaultValue"):
|
||||
_obj["defaultValue"] = self.defaultValue
|
||||
if hasattr(self, "value"):
|
||||
_obj["value"] = self.value
|
||||
if hasattr(self, "channelUse"):
|
||||
_obj["channelUse"] = self.channelUse
|
||||
if hasattr(self, "enumValues"):
|
||||
_obj["enumValues"] = self.enumValues
|
||||
|
||||
return _obj
|
||||
|
||||
|
||||
class SBS_Output():
|
||||
def __init__(self, output, index):
|
||||
self.id = output["id"]
|
||||
self.index = index
|
||||
self.graphID = output["graphID"]
|
||||
self.format = output["format"]
|
||||
self.mipmaps = output["mipmaps"]
|
||||
self.identifier = output["identifier"]
|
||||
self.label = output["label"]
|
||||
self.guiDescription = output["guiDescription"]
|
||||
self.group = output["group"]
|
||||
self.guiVisibleIf = output["guiVisibleIf"]
|
||||
self.userTag = output["userTag"]
|
||||
self.type = output["type"]
|
||||
self.guiType = output["guiType"]
|
||||
self.defaultChannelUse = output["defaultChannelUse"]
|
||||
self.enabled = output["enabled"]
|
||||
self.channelUseSpecified = output["channelUseSpecified"]
|
||||
self.channelUse = output["channelUse"]
|
||||
|
||||
def to_json(self):
|
||||
_obj = {
|
||||
"id": self.id,
|
||||
"graphID": self.graphID,
|
||||
"format": self.format,
|
||||
"mipmaps": self.mipmaps,
|
||||
"identifier": self.identifier,
|
||||
"label": self.label,
|
||||
"guiDescription": self.guiDescription,
|
||||
"group": self.group,
|
||||
"guiVisibleIf": self.guiVisibleIf,
|
||||
"userTag": self.userTag,
|
||||
"type": self.type,
|
||||
"guiType": self.guiType,
|
||||
"defaultChannelUse": self.defaultChannelUse,
|
||||
"enabled": self.enabled,
|
||||
"channelUseSpecified": self.channelUseSpecified,
|
||||
"channelUse": self.channelUse
|
||||
}
|
||||
return _obj
|
||||
|
||||
|
||||
class SBS_Preset():
|
||||
def __init__(self, preset, addon_prefs=None, inputs=None):
|
||||
self.index = str(preset["index"])
|
||||
self.label = preset["label"]
|
||||
self.value = preset["value"]
|
||||
|
||||
if "icon" in preset:
|
||||
self.icon = preset["icon"]
|
||||
else:
|
||||
self.icon = "LOCKED" if self.label != PRESET_CUSTOM else "UNLOCKED"
|
||||
if "embedded" in preset:
|
||||
self.embedded = preset["embedded"]
|
||||
else:
|
||||
self.embedded = True if self.label != PRESET_CUSTOM else False
|
||||
|
||||
if addon_prefs is not None and inputs is not None:
|
||||
if "$outputsize" in inputs:
|
||||
self.value = SUBSTANCE_Utils.update_preset_outputsize(
|
||||
self.value,
|
||||
inputs["$outputsize"],
|
||||
Code_InputType.integer2.value,
|
||||
addon_prefs.default_resolution.get())
|
||||
if "normal_format" in inputs:
|
||||
self.value = SUBSTANCE_Utils.update_preset_outputsize(
|
||||
self.value,
|
||||
inputs["normal_format"],
|
||||
Code_InputType.integer.value,
|
||||
0 if addon_prefs.default_normal_format == "DirectX" else 1)
|
||||
|
||||
def to_json(self):
|
||||
_obj = {
|
||||
"index": int(self.index),
|
||||
"label": self.label,
|
||||
"value": self.value,
|
||||
"icon": self.icon,
|
||||
"embedded": self.embedded
|
||||
}
|
||||
return _obj
|
||||
|
||||
|
||||
class SBS_Graph():
|
||||
def __init__(self, unique_name, uuid, index, graph, multi_graph, addon_prefs=None):
|
||||
self.index = str(index)
|
||||
self.uid = str(graph["uid"])
|
||||
self.label = graph["label"]
|
||||
self.identifier = graph["packageUrl"].replace("pkg://", "")
|
||||
self.packageUrl = graph["packageUrl"]
|
||||
if graph["physicalSize"][0] == 0 or graph["physicalSize"][1] == 0:
|
||||
self.physicalSize = (1/100, 1/100, 1/100)
|
||||
else:
|
||||
self.physicalSize = (graph["physicalSize"][0]/100,
|
||||
graph["physicalSize"][1]/100,
|
||||
graph["physicalSize"][2]/100)
|
||||
self.tiling = addon_prefs.default_tiling.get()
|
||||
self.inputs = {}
|
||||
self.inputs_groups = {}
|
||||
self.outputs = {}
|
||||
self.presets = []
|
||||
|
||||
if multi_graph:
|
||||
_material_name = "{}-{}".format(unique_name, graph["label"]).replace(" ", "_")
|
||||
_class_name = "{}-{}".format(uuid, self.uid)
|
||||
else:
|
||||
_material_name = "{}".format(unique_name).replace(" ", "_")
|
||||
_class_name = "{}".format(uuid)
|
||||
|
||||
self.material = _material_name
|
||||
self.inputs_class_name = CLASS_GRAPH_INPUTS.format(_class_name)
|
||||
|
||||
if len(graph["inputs"]) > 0 and "index" in graph["inputs"][0]:
|
||||
_sorted_inputs = sorted(graph["inputs"], key=lambda d: d['index'])
|
||||
else:
|
||||
_sorted_inputs = graph["inputs"]
|
||||
|
||||
_input_index = 0
|
||||
for _input in _sorted_inputs:
|
||||
if _input["guiWidget"] != Code_InputWidget.nowidget.value or _input["type"] != Code_InputType.string.name:
|
||||
if _input["type"] == Code_InputType.image.name:
|
||||
_group = INPUT_IMAGE_DEFAULT_GROUP
|
||||
else:
|
||||
_group = _input["guiGroup"] if len(_input["guiGroup"]) > 0 else INPUT_DEFAULT_GROUP
|
||||
|
||||
if _group not in self.inputs_groups:
|
||||
self.inputs_groups[_group] = [_input["identifier"]]
|
||||
else:
|
||||
self.inputs_groups[_group].append(_input["identifier"])
|
||||
|
||||
_new_input = SBS_Input(_input_index, _input)
|
||||
_input_index += 1
|
||||
self.inputs[_input["identifier"]] = _new_input
|
||||
|
||||
for _idx, _output in enumerate(graph["outputs"]):
|
||||
_new_output = SBS_Output(_output, _idx)
|
||||
self.outputs[_output["identifier"]] = _new_output
|
||||
|
||||
_pre_sort_presets = []
|
||||
for _preset in graph["presets"]:
|
||||
_new_preset = SBS_Preset(_preset, addon_prefs, self.inputs)
|
||||
_pre_sort_presets.append(_new_preset)
|
||||
self.presets = sorted(_pre_sort_presets, key=lambda _preset: _preset.index, reverse=False)
|
||||
|
||||
def to_json(self):
|
||||
_obj = {
|
||||
"uid": self.uid,
|
||||
"label": self.label,
|
||||
"physicalSize": self.physicalSize,
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"presets": []
|
||||
}
|
||||
|
||||
for _preset in self.presets:
|
||||
_obj["presets"].append(_preset.to_json())
|
||||
|
||||
for _key, _output in self.outputs.items():
|
||||
_obj["outputs"].append(_output.to_json())
|
||||
|
||||
for _key, _input in self.inputs.items():
|
||||
_obj["inputs"].append(_input.to_json())
|
||||
|
||||
return _obj
|
||||
|
||||
def reset_presets(self, presets):
|
||||
self.presets = []
|
||||
_pre_sort_presets = []
|
||||
for _preset in presets:
|
||||
_new_preset = SBS_Preset(_preset)
|
||||
_pre_sort_presets.append(_new_preset)
|
||||
self.presets = sorted(_pre_sort_presets, key=lambda _preset: _preset.index, reverse=False)
|
||||
|
||||
|
||||
class SBSAR():
|
||||
def __init__(self, unique_name, filename, data, addon_prefs=None):
|
||||
self.uuid = data["uuid"]
|
||||
self.version = data["version"]
|
||||
self.name = unique_name
|
||||
self.filename = filename
|
||||
self.filepath = data["filename"]
|
||||
self.graphs = []
|
||||
|
||||
_multi_graph = len(data["graphs"]) > 1
|
||||
|
||||
for _idx, _graph in enumerate(data["graphs"]):
|
||||
_new_graph = SBS_Graph(unique_name, self.uuid, _idx, _graph, _multi_graph, addon_prefs)
|
||||
self.graphs.append(_new_graph)
|
||||
|
||||
def to_json(self):
|
||||
_obj = {
|
||||
"uuid": self.uuid,
|
||||
"name": self.name,
|
||||
"filename": self.filename,
|
||||
"filepath": self.filepath,
|
||||
"graphs": []
|
||||
}
|
||||
|
||||
for _graph in self.graphs:
|
||||
_obj["graphs"].append(_graph.to_json())
|
||||
return _obj
|
||||
Reference in New Issue
Block a user