107 lines
3.7 KiB
Python
107 lines
3.7 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: factory/shader.py
|
|
# brief: Dynamic class creation for shader objects
|
|
# author Adobe - 3D & Immersive
|
|
# copyright 2023 Adobe Inc. All rights reserved.
|
|
|
|
|
|
import bpy
|
|
import traceback
|
|
from ..utils import SUBSTANCE_Utils
|
|
from ..shader.callbacks import SUBSTANCE_ShaderCallbacks
|
|
from ..common import (
|
|
Code_ShaderInputType,
|
|
Code_Response
|
|
)
|
|
|
|
|
|
class SUBSTANCE_ShaderFactory():
|
|
# Shader preset inputs
|
|
@staticmethod
|
|
def create_input_item(input):
|
|
if (input.type == Code_ShaderInputType.float_slider.value or
|
|
input.type == Code_ShaderInputType.float_maxmin.value):
|
|
return bpy.props.FloatProperty(
|
|
name=input.id,
|
|
default=input.default,
|
|
soft_max=input.max,
|
|
soft_min=input.min,
|
|
update=SUBSTANCE_ShaderCallbacks.on_input_changed)
|
|
else:
|
|
return None
|
|
|
|
@staticmethod
|
|
def register_inputs_class(shader_preset):
|
|
_attributes = {}
|
|
for _key, _input in shader_preset.inputs.items():
|
|
_attribute = SUBSTANCE_ShaderFactory.create_input_item(_input)
|
|
if _attribute:
|
|
_attributes[_key] = _attribute
|
|
|
|
def _on_reset(self):
|
|
for _attr_name in self.__annotations__:
|
|
_input = None
|
|
for _key, _i in self.shader_preset.inputs.items():
|
|
if _i.id == _attr_name:
|
|
_input = _i
|
|
break
|
|
if _input is not None:
|
|
setattr(self, _attr_name, _input.default)
|
|
|
|
def _get(self):
|
|
_obj = self.shader_preset.to_json()
|
|
for _key, _item in _obj["inputs"].items():
|
|
_item["default"] = getattr(self, _item["id"])
|
|
return _obj["inputs"]
|
|
|
|
_inputs_class = type(
|
|
shader_preset.inputs_class_name,
|
|
(bpy.types.PropertyGroup,),
|
|
{
|
|
"__annotations__": _attributes,
|
|
"shader_preset": shader_preset,
|
|
"reset": _on_reset,
|
|
"get": _get
|
|
})
|
|
|
|
bpy.utils.register_class(_inputs_class)
|
|
setattr(
|
|
bpy.types.Scene,
|
|
shader_preset.inputs_class_name,
|
|
bpy.props.PointerProperty(name=shader_preset.inputs_class_name, type=_inputs_class))
|
|
|
|
# General
|
|
@staticmethod
|
|
def register_class(shader_preset):
|
|
try:
|
|
SUBSTANCE_ShaderFactory.register_inputs_class(shader_preset)
|
|
return (Code_Response.success, shader_preset)
|
|
except Exception:
|
|
SUBSTANCE_Utils.log_data("ERROR", "Exception - Shader register error:")
|
|
SUBSTANCE_Utils.log_traceback(traceback.format_exc())
|
|
return (Code_Response.sbsar_factory_register_error, None)
|
|
|
|
@staticmethod
|
|
def unregister_class(class_name):
|
|
if hasattr(bpy.context.scene, class_name):
|
|
_object = getattr(bpy.context.scene, class_name)
|
|
_class_type = type(_object)
|
|
|
|
delattr(bpy.types.Scene, class_name)
|
|
bpy.utils.unregister_class(_class_type)
|