""" 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: render/manager.py # brief: Render operations manager # author Adobe - 3D & Immersive # copyright 2023 Adobe Inc. All rights reserved. import bpy import json import threading from ..thread_ops import SUBSTANCE_Threads from ..common import Code_SbsarLoadSuffix, Code_RequestOp, INPUT_UPDATE_DELAY_S, RENDER_KEY class SUBSTANCE_RenderManager(): def __init__(self): self.input_lock = threading.Lock() self.render_lock = threading.Lock() self.render_current = "" self.render_queue = {} self.input_change_queue = {} # Inputs render call def _input_render_update(self, context, sbsar, graph, input, value, callback): with self.input_lock: _render_id = RENDER_KEY.format(sbsar.uuid, graph.index) self.input_change_queue.pop(_render_id) callback(context, sbsar, graph, input, value) def input_queue_add(self, context, sbsar, graph, input, value, callback): with self.input_lock: _render_id = RENDER_KEY.format(sbsar.uuid, graph.index) if _render_id in self.input_change_queue: self.input_change_queue[_render_id].cancel() self.input_change_queue.pop(_render_id) self.input_change_queue[_render_id] = SUBSTANCE_Threads.timer_thread_run( INPUT_UPDATE_DELAY_S, self._input_render_update, (context, sbsar, graph, input, value, callback) ) # Render call def graph_render(self, render_id, data, request_type, callback): def _set_render_tag(): for _item in bpy.context.scene.loaded_sbsars: if _item.uuid == data["sbsar"]["uuid"]: _item.suffix = Code_SbsarLoadSuffix.render.value[0] _item.icon = Code_SbsarLoadSuffix.render.value[1] break with self.render_lock: if self.render_current == "": self.render_current = render_id callback(Code_RequestOp.render, data, request_type) SUBSTANCE_Threads.main_thread_run(_set_render_tag) else: if render_id not in self.render_queue: self.render_queue[render_id] = { "render_id": render_id, "data": data, "request_type": request_type, "callback": callback } def render_finish(self, data): _current_sbsar_id = None _next_render = None with self.render_lock: if self.render_current != "": _current_sbsar_id = self.render_current.split("_")[0] self.render_current = "" if len(self.render_queue.keys()) > 0: _keys = self.render_queue.keys() _key = list(_keys)[0] _next_render = self.render_queue.pop(_key, None) if _next_render is not None: self.graph_render( _next_render["render_id"], _next_render["data"], _next_render["request_type"], _next_render["callback"] ) def _set_material_info(): import bpy str_data = json.dumps(data) bpy.ops.substance.set_material(data=str_data) for _item in bpy.context.scene.loaded_sbsars: if _current_sbsar_id is not None and _item.uuid == _current_sbsar_id: _item.suffix = Code_SbsarLoadSuffix.success.value[0] _item.icon = Code_SbsarLoadSuffix.success.value[1] SUBSTANCE_Threads.main_thread_run(_set_material_info)