""" 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: 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)