404 lines
14 KiB
Python
404 lines
14 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: __init__.py
|
|
# brief: Addon registration
|
|
# author Adobe - 3D & Immersive
|
|
# copyright 2023 Adobe Inc. All rights reserved.
|
|
|
|
|
|
bl_info = {
|
|
"name": "Adobe Substance 3D add-on for Blender",
|
|
"author": "Adobe Inc.",
|
|
"location": "Node Editor Toolbar -- Shift-Ctrl-U",
|
|
"version": (2, 1, 1),
|
|
"blender": (2, 90, 0),
|
|
"description": "Adobe Substance 3D add-on for Blender",
|
|
'tracker_url': "https://discord.gg/substance3d",
|
|
"category": "Node"
|
|
}
|
|
|
|
try:
|
|
import traceback
|
|
import bpy
|
|
|
|
from bpy.utils import register_class, unregister_class
|
|
from .persistance import SUBSTANCE_Persistance
|
|
from .api import SUBSTANCE_Api
|
|
from .utils import SUBSTANCE_Utils
|
|
from .thread_ops import SUBSTANCE_Threads
|
|
from .callbacks.render import Server_POST_Render
|
|
from .callbacks.link import Server_POST_Link
|
|
from .common import Code_Response, UI_SPACES, ADDON_PACKAGE, SHORTCUT_CLASS_NAME
|
|
|
|
from .ui.presets import SUBSTANCE_MT_PresetOptions
|
|
from .ui.shortcut import SubstanceShortcutMenuFactory
|
|
from .ui.sbsar import (
|
|
SubstanceMainPanelFactory,
|
|
SubstanceGraphPanelFactory,
|
|
SubstancePreviewFactory,
|
|
SubstanceOutputsPanelFactory,
|
|
SubstanceInputsPanelFactory,
|
|
SUBSTANCE_UL_SbsarList
|
|
)
|
|
|
|
from .preferences import SUBSTANCE_AddonPreferences
|
|
|
|
from .ops.common import SUBSTANCE_OT_Message, SUBSTANCE_OT_Version
|
|
from .ops.material import SUBSTANCE_OT_SetMaterial
|
|
from .ops.toolkit import (
|
|
SUBSTANCE_OT_InstallTools,
|
|
SUBSTANCE_OT_UpdateTools,
|
|
SUBSTANCE_OT_UninstallTools,
|
|
SUBSTANCE_OT_OpenTools,
|
|
SUBSTANCE_OT_ResetTools
|
|
)
|
|
from .ops.web import (
|
|
SUBSTANCE_OT_GoToWebsite,
|
|
SUBSTANCE_OT_GetTools,
|
|
SUBSTANCE_OT_GoToShare,
|
|
SUBSTANCE_OT_GoToSource,
|
|
SUBSTANCE_OT_GoToDocs,
|
|
SUBSTANCE_OT_GoToForums,
|
|
SUBSTANCE_OT_GoToDiscord
|
|
)
|
|
from .ops.inputs import (
|
|
SUBSTANCE_OT_RandomizeSeed,
|
|
SUBSTANCE_OT_InputGroupsCollapse,
|
|
SUBSTANCE_OT_InputGroupsExpand
|
|
)
|
|
from .ops.presets import (
|
|
SUBSTANCE_OT_AddPreset,
|
|
SUBSTANCE_OT_ImportPreset,
|
|
SUBSTANCE_OT_ExportPreset,
|
|
SUBSTANCE_OT_ExportAll,
|
|
SUBSTANCE_OT_DeletePreset,
|
|
SUBSTANCE_OT_DeletePresetModal
|
|
)
|
|
from .ops.sbsar import (
|
|
SUBSTANCE_OT_LoadSBSAR,
|
|
SUBSTANCE_OT_ApplySBSAR,
|
|
SUBSTANCE_OT_RemoveSBSAR,
|
|
SUBSTANCE_OT_ReloadSBSAR,
|
|
SUBSTANCE_OT_DuplicateSBSAR
|
|
)
|
|
from .ops.shader import (
|
|
SUBSTANCE_OT_ResetShaderPreset,
|
|
SUBSTANCE_OT_LoadShaderPresets,
|
|
SUBSTANCE_OT_RemoveShaderPresets,
|
|
SUBSTANCE_OT_SaveShaderPresets
|
|
)
|
|
from .ops.sync import (
|
|
SUBSTANCE_OT_SyncInitTools,
|
|
SUBSTANCE_OT_SyncLoadSBSAR
|
|
)
|
|
|
|
from .props.shortcuts import SUBSTANCE_PG_Shortcuts
|
|
from .props.common import SUBSTANCE_PG_Tiling, SUBSTANCE_PG_Resolution, SUBSTANCE_PG_SbsarPhysicalSize
|
|
from .props.sbsar_graph import SUBSTANCE_PG_SbsarGraph, SUBSTANCE_PG_SbsarMaterial, SUBSTANCE_PG_SbsarTiling
|
|
from .props.sbsar_input import SUBSTANCE_PG_SbsarInputGroup, SUBSTANCE_PG_SbsarInput
|
|
from .props.sbsar_output import SUBSTANCE_PG_SbsarOutput, SUBSTANCE_PG_SbsarOutputChannelUse
|
|
from .props.sbsar_preset import SUBSTANCE_PG_SbsarPreset
|
|
from .props.sbsar import SUBSTANCE_PG_Sbsar
|
|
from .props.shader import SUBSTANCE_PG_ShaderPreset, SUBSTANCE_PG_ShaderInput, SUBSTANCE_PG_ShaderOutput
|
|
|
|
SHORTCUT_KEYMAPS = []
|
|
FACTORY_CLASSES = []
|
|
DEFAULT_CLASSES = [
|
|
# /props/common
|
|
SUBSTANCE_PG_Tiling,
|
|
SUBSTANCE_PG_Resolution,
|
|
|
|
# /props/sbsar
|
|
SUBSTANCE_PG_SbsarPhysicalSize,
|
|
SUBSTANCE_PG_SbsarInputGroup,
|
|
SUBSTANCE_PG_SbsarInput,
|
|
SUBSTANCE_PG_SbsarOutputChannelUse,
|
|
SUBSTANCE_PG_SbsarOutput,
|
|
SUBSTANCE_PG_SbsarPreset,
|
|
SUBSTANCE_PG_SbsarMaterial,
|
|
SUBSTANCE_PG_SbsarTiling,
|
|
SUBSTANCE_PG_SbsarGraph,
|
|
SUBSTANCE_PG_Sbsar,
|
|
|
|
# /props/shader
|
|
SUBSTANCE_PG_ShaderOutput,
|
|
SUBSTANCE_PG_ShaderInput,
|
|
SUBSTANCE_PG_ShaderPreset,
|
|
|
|
# /props/shortcuts
|
|
SUBSTANCE_PG_Shortcuts,
|
|
|
|
# /preferences
|
|
SUBSTANCE_AddonPreferences,
|
|
|
|
# /ops/common
|
|
SUBSTANCE_OT_Version,
|
|
SUBSTANCE_OT_Message,
|
|
|
|
# /ops/toolkit
|
|
SUBSTANCE_OT_InstallTools,
|
|
SUBSTANCE_OT_UpdateTools,
|
|
SUBSTANCE_OT_UninstallTools,
|
|
SUBSTANCE_OT_OpenTools,
|
|
SUBSTANCE_OT_ResetTools,
|
|
|
|
# /ops/web
|
|
SUBSTANCE_OT_GoToWebsite,
|
|
SUBSTANCE_OT_GetTools,
|
|
SUBSTANCE_OT_GoToShare,
|
|
SUBSTANCE_OT_GoToSource,
|
|
SUBSTANCE_OT_GoToDocs,
|
|
SUBSTANCE_OT_GoToForums,
|
|
SUBSTANCE_OT_GoToDiscord,
|
|
|
|
# /ops/inputs
|
|
SUBSTANCE_OT_RandomizeSeed,
|
|
SUBSTANCE_OT_InputGroupsCollapse,
|
|
SUBSTANCE_OT_InputGroupsExpand,
|
|
|
|
# /ops/presets
|
|
SUBSTANCE_OT_AddPreset,
|
|
SUBSTANCE_OT_ImportPreset,
|
|
SUBSTANCE_OT_ExportPreset,
|
|
SUBSTANCE_OT_ExportAll,
|
|
SUBSTANCE_OT_DeletePreset,
|
|
SUBSTANCE_OT_DeletePresetModal,
|
|
|
|
# /ops/sbsar
|
|
SUBSTANCE_OT_LoadSBSAR,
|
|
SUBSTANCE_OT_ApplySBSAR,
|
|
SUBSTANCE_OT_RemoveSBSAR,
|
|
SUBSTANCE_OT_ReloadSBSAR,
|
|
SUBSTANCE_OT_DuplicateSBSAR,
|
|
|
|
# /ops/shader
|
|
SUBSTANCE_OT_LoadShaderPresets,
|
|
SUBSTANCE_OT_RemoveShaderPresets,
|
|
SUBSTANCE_OT_SaveShaderPresets,
|
|
SUBSTANCE_OT_ResetShaderPreset,
|
|
|
|
# /ops/material
|
|
SUBSTANCE_OT_SetMaterial,
|
|
|
|
# /ops/sync
|
|
SUBSTANCE_OT_SyncInitTools,
|
|
SUBSTANCE_OT_SyncLoadSBSAR,
|
|
|
|
# /ui/presets
|
|
SUBSTANCE_MT_PresetOptions,
|
|
|
|
# /ui/sbsar
|
|
SUBSTANCE_UL_SbsarList
|
|
]
|
|
|
|
# Callback for SBSAR
|
|
def sbsar_index_changed(self, context):
|
|
SUBSTANCE_Utils.toggle_redraw(context)
|
|
|
|
# Preview Update FIX
|
|
def sbsar_redraw_changed(self, context):
|
|
try:
|
|
context.area.tag_redraw()
|
|
except Exception:
|
|
pass
|
|
|
|
post_render = Server_POST_Render()
|
|
post_link = Server_POST_Link()
|
|
|
|
def register():
|
|
# Add Panels
|
|
if len(FACTORY_CLASSES) == 0:
|
|
for _space in UI_SPACES:
|
|
# Add Substance List Panel
|
|
_cls = SubstanceMainPanelFactory(_space[1])
|
|
FACTORY_CLASSES.append(_cls)
|
|
_cls = SubstancePreviewFactory(_space[1])
|
|
FACTORY_CLASSES.append(_cls)
|
|
_cls = SubstanceGraphPanelFactory(_space[1])
|
|
FACTORY_CLASSES.append(_cls)
|
|
_cls = SubstanceOutputsPanelFactory(_space[1])
|
|
FACTORY_CLASSES.append(_cls)
|
|
_cls = SubstanceInputsPanelFactory(_space[1])
|
|
FACTORY_CLASSES.append(_cls)
|
|
|
|
_menu_cls = SubstanceShortcutMenuFactory(_space[1])
|
|
FACTORY_CLASSES.append(_menu_cls)
|
|
|
|
# Register blender classes
|
|
for _cls in DEFAULT_CLASSES:
|
|
register_class(_cls)
|
|
|
|
for _cls in FACTORY_CLASSES:
|
|
register_class(_cls)
|
|
|
|
# Addon Preferences
|
|
_addon_prefs = bpy.context.preferences.addons[ADDON_PACKAGE].preferences
|
|
|
|
# Shortcuts
|
|
_shortcuts = _addon_prefs.shortcuts
|
|
wm = bpy.context.window_manager
|
|
_kc = wm.keyconfigs.addon
|
|
for _space in UI_SPACES:
|
|
if _kc:
|
|
_km = wm.keyconfigs.addon.keymaps.new(name=_space[0], space_type=_space[1])
|
|
_kmi = _km.keymap_items.new(
|
|
'wm.call_menu',
|
|
_shortcuts.menu_key,
|
|
'PRESS',
|
|
ctrl=_shortcuts.menu_ctrl,
|
|
shift=_shortcuts.menu_shift,
|
|
alt=_shortcuts.menu_alt
|
|
)
|
|
_kmi.properties.name = SHORTCUT_CLASS_NAME.format(_space[1])
|
|
SHORTCUT_KEYMAPS.append((_km, _kmi))
|
|
|
|
_kmi = _km.keymap_items.new(
|
|
SUBSTANCE_OT_LoadSBSAR.bl_idname,
|
|
_shortcuts.load_key,
|
|
'PRESS',
|
|
ctrl=_shortcuts.load_ctrl,
|
|
shift=_shortcuts.load_shift,
|
|
alt=_shortcuts.load_alt
|
|
)
|
|
SHORTCUT_KEYMAPS.append((_km, _kmi))
|
|
|
|
_kmi = _km.keymap_items.new(
|
|
SUBSTANCE_OT_ApplySBSAR.bl_idname,
|
|
_shortcuts.apply_key,
|
|
'PRESS',
|
|
ctrl=_shortcuts.apply_ctrl,
|
|
shift=_shortcuts.apply_shift,
|
|
alt=_shortcuts.apply_alt
|
|
)
|
|
SHORTCUT_KEYMAPS.append((_km, _kmi))
|
|
|
|
# Create scene SBSAR variables
|
|
bpy.types.Scene.loaded_sbsars = bpy.props.CollectionProperty(type=SUBSTANCE_PG_Sbsar)
|
|
bpy.types.Scene.sbsar_index = bpy.props.IntProperty(
|
|
name='sbsar_index',
|
|
default=0,
|
|
options={'HIDDEN'},
|
|
update=sbsar_index_changed
|
|
)
|
|
|
|
# Create a dumb variable to fix the Preview Update
|
|
bpy.types.Scene.sbsar_redraw = bpy.props.IntProperty(
|
|
name='sbsar_redraw',
|
|
default=0,
|
|
options={'HIDDEN'},
|
|
update=sbsar_redraw_changed
|
|
)
|
|
|
|
# Init icons
|
|
SUBSTANCE_Utils.init_icons()
|
|
|
|
# Shader Presets
|
|
_result = SUBSTANCE_Api.shader_initialize(_addon_prefs)
|
|
if _result[0] != Code_Response.success:
|
|
SUBSTANCE_Utils.log_data("ERROR", "[{}] Shader presets cannot be initialized...".format(_result))
|
|
return
|
|
SUBSTANCE_Utils.log_data("INFO", "Shader Presets initialized...")
|
|
|
|
# Add main thread listener
|
|
if not bpy.app.timers.is_registered(SUBSTANCE_Threads.exec_queued_function):
|
|
bpy.app.timers.register(SUBSTANCE_Threads.exec_queued_function)
|
|
|
|
# Initialize blender handlers
|
|
bpy.app.handlers.load_post.append(SUBSTANCE_Persistance.sbs_load_post_handler)
|
|
bpy.app.handlers.load_pre.append(SUBSTANCE_Persistance.sbs_load_pre_handler)
|
|
bpy.app.handlers.save_pre.append(SUBSTANCE_Persistance.sbs_save_pre_handler)
|
|
bpy.app.handlers.save_post.append(SUBSTANCE_Persistance.sbs_save_post_handler)
|
|
bpy.app.handlers.undo_post.append(SUBSTANCE_Persistance.sbs_undo_post_handler)
|
|
bpy.app.handlers.depsgraph_update_post.append(SUBSTANCE_Persistance.sbs_depsgraph_update_post)
|
|
|
|
# Initialize SUBSTANCE_Api listeners
|
|
SUBSTANCE_Api.listeners_add("post", post_render)
|
|
SUBSTANCE_Api.listeners_add("post", post_link)
|
|
|
|
# Initialize SRE if enabled
|
|
if _addon_prefs.auto_start_sre:
|
|
_result = SUBSTANCE_Api.initialize()
|
|
if _result[0] != Code_Response.success:
|
|
SUBSTANCE_Utils.log_data("ERROR", "[{}] The SRE cannot initialize...".format(_result))
|
|
|
|
def unregister():
|
|
# Remove shortcuts
|
|
for _km, _kmi in SHORTCUT_KEYMAPS:
|
|
_km.keymap_items.remove(_kmi)
|
|
SHORTCUT_KEYMAPS.clear()
|
|
|
|
# Remove sbsar dynamic classes
|
|
for _scene in bpy.data.scenes:
|
|
for _item in _scene.loaded_sbsars:
|
|
SUBSTANCE_Api.sbsar_unregister(_item.uuid)
|
|
_scene.loaded_sbsars.clear()
|
|
|
|
# Shutdown SUBSTANCE_Api
|
|
SUBSTANCE_Api.listeners_remove("post", post_render)
|
|
SUBSTANCE_Api.listeners_remove("post", post_link)
|
|
SUBSTANCE_Api.shutdown()
|
|
|
|
# Remove blender handlers
|
|
for _func in bpy.app.handlers.load_pre[:]:
|
|
if _func.__name__ == SUBSTANCE_Persistance.sbs_load_pre_handler.__name__:
|
|
bpy.app.handlers.load_pre.remove(_func)
|
|
|
|
for _func in bpy.app.handlers.load_post[:]:
|
|
if _func.__name__ == SUBSTANCE_Persistance.sbs_load_post_handler.__name__:
|
|
bpy.app.handlers.load_post.remove(_func)
|
|
|
|
for _func in bpy.app.handlers.save_pre[:]:
|
|
if _func.__name__ == SUBSTANCE_Persistance.sbs_save_pre_handler.__name__:
|
|
bpy.app.handlers.save_pre.remove(_func)
|
|
|
|
for _func in bpy.app.handlers.save_post[:]:
|
|
if _func.__name__ == SUBSTANCE_Persistance.sbs_save_post_handler.__name__:
|
|
bpy.app.handlers.save_post.remove(_func)
|
|
|
|
for _func in bpy.app.handlers.undo_post[:]:
|
|
if _func.__name__ == SUBSTANCE_Persistance.sbs_undo_post_handler.__name__:
|
|
bpy.app.handlers.undo_post.remove(_func)
|
|
|
|
for _func in bpy.app.handlers.depsgraph_update_post[:]:
|
|
if _func.__name__ == SUBSTANCE_Persistance.sbs_depsgraph_update_post.__name__:
|
|
bpy.app.handlers.depsgraph_update_post.remove(_func)
|
|
|
|
# Remove main thread listener
|
|
if bpy.app.timers.is_registered(SUBSTANCE_Threads.exec_queued_function):
|
|
bpy.app.timers.unregister(SUBSTANCE_Threads.exec_queued_function)
|
|
|
|
# Cleanup Shader Presets list
|
|
bpy.ops.substance.save_shader_presets()
|
|
bpy.ops.substance.remove_shader_presets()
|
|
|
|
# Delete scene SBSAR variables
|
|
del bpy.types.Scene.loaded_sbsars
|
|
del bpy.types.Scene.sbsar_index
|
|
del bpy.types.Scene.sbsar_redraw
|
|
|
|
# Unregister blender classes
|
|
for _cls in reversed(DEFAULT_CLASSES):
|
|
unregister_class(_cls)
|
|
for _cls in reversed(FACTORY_CLASSES):
|
|
unregister_class(_cls)
|
|
|
|
if __name__ == "__main__":
|
|
register()
|
|
|
|
except Exception:
|
|
print(traceback.format_exc())
|