2025-07-01
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
"""
|
||||
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: ui/presets.py
|
||||
# brief: Presets UI
|
||||
# author Adobe - 3D & Immersive
|
||||
# copyright 2023 Adobe Inc. All rights reserved.
|
||||
|
||||
|
||||
import bpy
|
||||
|
||||
from ..ops.presets import (
|
||||
SUBSTANCE_OT_ImportPreset,
|
||||
SUBSTANCE_OT_ExportPreset,
|
||||
SUBSTANCE_OT_ExportAll
|
||||
)
|
||||
|
||||
|
||||
class SUBSTANCE_MT_PresetOptions(bpy.types.Menu):
|
||||
bl_idname = 'SUBSTANCE_MT_PresetOptions'
|
||||
bl_label = ""
|
||||
bl_description = 'Additional Preset Options'
|
||||
# bl_options = {'REGISTER'}
|
||||
|
||||
def draw(self, context):
|
||||
_col = self.layout.column()
|
||||
_row = _col.row()
|
||||
_row.operator(SUBSTANCE_OT_ExportPreset.bl_idname, icon='EXPORT')
|
||||
_row = _col.row()
|
||||
_row.operator(SUBSTANCE_OT_ExportAll.bl_idname, icon='EXPORT')
|
||||
_row = _col.row()
|
||||
_row.operator(SUBSTANCE_OT_ImportPreset.bl_idname, icon='IMPORT')
|
||||
@@ -0,0 +1,486 @@
|
||||
"""
|
||||
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: ui/sbsar.py
|
||||
# brief: Substance UI
|
||||
# author Adobe - 3D & Immersive
|
||||
# copyright 2023 Adobe Inc. All rights reserved.
|
||||
|
||||
|
||||
import bpy
|
||||
|
||||
from ..ops.web import SUBSTANCE_OT_GoToShare, SUBSTANCE_OT_GoToSource
|
||||
from ..ops.sbsar import (
|
||||
SUBSTANCE_OT_LoadSBSAR,
|
||||
SUBSTANCE_OT_ApplySBSAR,
|
||||
SUBSTANCE_OT_RemoveSBSAR,
|
||||
SUBSTANCE_OT_ReloadSBSAR,
|
||||
SUBSTANCE_OT_DuplicateSBSAR
|
||||
)
|
||||
from ..ops.inputs import (
|
||||
SUBSTANCE_OT_RandomizeSeed,
|
||||
SUBSTANCE_OT_InputGroupsCollapse,
|
||||
SUBSTANCE_OT_InputGroupsExpand
|
||||
)
|
||||
from ..ops.presets import SUBSTANCE_OT_AddPreset, SUBSTANCE_OT_DeletePreset, SUBSTANCE_OT_DeletePresetModal
|
||||
from .presets import SUBSTANCE_MT_PresetOptions
|
||||
|
||||
from ..api import SUBSTANCE_Api
|
||||
from ..utils import SUBSTANCE_Utils
|
||||
from ..common import (
|
||||
ADDON_PACKAGE,
|
||||
ICONS_DICT,
|
||||
DRAW_DEFAULT_FACTOR,
|
||||
Code_InputIdentifier,
|
||||
Code_OutputSizeSuffix,
|
||||
Code_InputWidget,
|
||||
Code_InputType,
|
||||
INPUT_CHANNELS_GROUP,
|
||||
OUTPUTS_FILTER_DICT,
|
||||
INPUT_TECHINCAL_GROUP,
|
||||
INPUT_DEFAULT_GROUP,
|
||||
INPUT_IMAGE_DEFAULT_GROUP,
|
||||
Code_SbsarLoadSuffix
|
||||
)
|
||||
|
||||
|
||||
class SUBSTANCE_UL_SbsarList(bpy.types.UIList):
|
||||
bl_idname = 'SUBSTANCE_UL_SbsarList'
|
||||
bl_label = 'Loaded Substance 3D Materials'
|
||||
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
||||
_suffix = item.suffix
|
||||
_is_rendering = SUBSTANCE_Api.sbsar_is_rendering(item.uuid)
|
||||
if item.icon == Code_SbsarLoadSuffix.render.value[1] or _is_rendering == 2:
|
||||
_icon = ICONS_DICT["render"].icon_id
|
||||
_suffix = Code_SbsarLoadSuffix.render.value[0]
|
||||
elif _is_rendering == 1:
|
||||
_icon = ICONS_DICT["render_queue"].icon_id
|
||||
_suffix = Code_SbsarLoadSuffix.render_queue.value[0]
|
||||
elif item.icon != Code_SbsarLoadSuffix.success.value[1]:
|
||||
_icon = ICONS_DICT[item.icon].icon_id
|
||||
else:
|
||||
_icon = 0
|
||||
|
||||
_name = item.name + " " + _suffix
|
||||
|
||||
# draw the item in the layout
|
||||
if self.layout_type in {'DEFAULT', 'COMPACT'}:
|
||||
layout.label(text=_name, icon_value=_icon)
|
||||
elif self.layout_type in {'GRID'}:
|
||||
layout.alignment = 'CENTER'
|
||||
layout.label(text='', icon_value=_icon)
|
||||
|
||||
|
||||
def SubstanceMainPanelFactory(space):
|
||||
class SUBSTANCE_PT_MAIN(bpy.types.Panel):
|
||||
bl_idname = 'SUBSTANCE_PT_MAIN_{}'.format(space)
|
||||
bl_space_type = space
|
||||
bl_label = 'Substance 3D Panel'
|
||||
bl_region_type = 'UI'
|
||||
bl_category = 'Substance 3D'
|
||||
|
||||
def draw(self, context):
|
||||
# Shortcut
|
||||
_shortcut = context.preferences.addons[ADDON_PACKAGE].preferences.shortcuts
|
||||
self.layout.label(text="(Quick Access: " + _shortcut.menu_label + ")")
|
||||
_row = self.layout.row(align=True)
|
||||
|
||||
# Buttons (Operators)
|
||||
_row.operator(SUBSTANCE_OT_LoadSBSAR.bl_idname, text="Load")
|
||||
_row.separator()
|
||||
_row.operator(SUBSTANCE_OT_ApplySBSAR.bl_idname, text="Apply")
|
||||
_row.separator()
|
||||
_row.operator(SUBSTANCE_OT_GoToShare.bl_idname, text="", icon_value=ICONS_DICT["share_icon"].icon_id)
|
||||
_row.separator()
|
||||
_row.operator(SUBSTANCE_OT_GoToSource.bl_idname, text="", icon_value=ICONS_DICT["source_icon"].icon_id)
|
||||
_row.separator()
|
||||
_row.operator(SUBSTANCE_OT_DuplicateSBSAR.bl_idname, text="", icon='DUPLICATE')
|
||||
_row.separator()
|
||||
_row.operator(SUBSTANCE_OT_ReloadSBSAR.bl_idname, text="", icon='FILE_REFRESH')
|
||||
_row.separator()
|
||||
_row.operator(SUBSTANCE_OT_RemoveSBSAR.bl_idname, text="", icon='TRASH')
|
||||
_row.separator()
|
||||
|
||||
# SBSAR List
|
||||
if len(context.scene.loaded_sbsars) > 0:
|
||||
_col = self.layout.column()
|
||||
_col.label(text="Loaded 3D Substance Materials")
|
||||
_col.template_list(
|
||||
SUBSTANCE_UL_SbsarList.bl_idname,
|
||||
'Loaded 3D Substance Materials',
|
||||
context.scene,
|
||||
'loaded_sbsars',
|
||||
context.scene,
|
||||
'sbsar_index')
|
||||
|
||||
_selected_sbsar = context.scene.loaded_sbsars[context.scene.sbsar_index]
|
||||
if len(_selected_sbsar.graphs) > 1:
|
||||
_row = _col.row()
|
||||
_split = _row.split(factor=0.25)
|
||||
_col_1 = _split.column()
|
||||
_col_2 = _split.column()
|
||||
_col_1.label(text="Graph")
|
||||
_col_2.prop(_selected_sbsar, "graphs_list", text="")
|
||||
|
||||
return SUBSTANCE_PT_MAIN
|
||||
|
||||
|
||||
def SubstancePreviewFactory(space):
|
||||
class SUBSTANCE_PT_PREVIEW(bpy.types.Panel):
|
||||
bl_idname = 'SUBSTANCE_PT_PREVIEW_{}'.format(space)
|
||||
bl_space_type = space
|
||||
bl_label = 'Preview'
|
||||
bl_region_type = 'UI'
|
||||
bl_category = 'Substance 3D'
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return len(context.scene.loaded_sbsars) > 0
|
||||
|
||||
def draw(self, context):
|
||||
_selected_graph = SUBSTANCE_Utils.get_selected_graph(context)
|
||||
|
||||
_col = self.layout.column(align=True)
|
||||
|
||||
if context.scene.sbsar_redraw == 0:
|
||||
_col.scale_y = 0.99
|
||||
elif context.scene.sbsar_redraw == 1:
|
||||
_col.scale_y = 1.0
|
||||
else:
|
||||
_col.scale_y = 1.01
|
||||
|
||||
# Thumbnail
|
||||
if _selected_graph.material.name in bpy.data.materials:
|
||||
_grid = _col.grid_flow(columns=1, align=True)
|
||||
if _selected_graph.material.name in bpy.data.materials:
|
||||
_grid.template_preview(bpy.data.materials[_selected_graph.material.name], show_buttons=False)
|
||||
# if _selected_graph.thumbnail in bpy.data.textures:
|
||||
# _grid.template_ID_preview(bpy.data.textures[_selected_graph.thumbnail], "image")
|
||||
|
||||
return SUBSTANCE_PT_PREVIEW
|
||||
|
||||
|
||||
def SubstanceGraphPanelFactory(space):
|
||||
class SUBSTANCE_PT_GRAPH(bpy.types.Panel):
|
||||
bl_idname = 'SUBSTANCE_PT_GRAPH_{}'.format(space)
|
||||
bl_space_type = space
|
||||
bl_label = 'Graph Parameters'
|
||||
bl_region_type = 'UI'
|
||||
bl_category = 'Substance 3D'
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return len(context.scene.loaded_sbsars) > 0
|
||||
|
||||
def draw(self, context):
|
||||
_selected_graph = SUBSTANCE_Utils.get_selected_graph(context)
|
||||
_addon_prefs = context.preferences.addons[ADDON_PACKAGE].preferences
|
||||
|
||||
_col = self.layout.column(align=True)
|
||||
|
||||
# Presets
|
||||
_row = _col.row()
|
||||
_split = _row.split(factor=DRAW_DEFAULT_FACTOR)
|
||||
_col_1 = _split.column()
|
||||
_col_2 = _split.column()
|
||||
_row = _col_1.row()
|
||||
_row.alignment = "RIGHT"
|
||||
_row.label(text="Preset")
|
||||
_row = _col_2.row()
|
||||
_row.prop(_selected_graph, "presets_list", text='')
|
||||
_row.operator(SUBSTANCE_OT_AddPreset.bl_idname, text='', icon='ADD')
|
||||
if _addon_prefs.preset_auto_delete_enabled:
|
||||
_row.operator(SUBSTANCE_OT_DeletePreset.bl_idname, text='', icon='TRASH')
|
||||
else:
|
||||
_row.operator(SUBSTANCE_OT_DeletePresetModal.bl_idname, text='', icon='TRASH')
|
||||
_row.menu(SUBSTANCE_MT_PresetOptions.bl_idname, icon='TRIA_DOWN')
|
||||
|
||||
# Phyisical Size
|
||||
_row = _col.row()
|
||||
_split = _row.split(factor=DRAW_DEFAULT_FACTOR)
|
||||
_col_1 = _split.column()
|
||||
_col_2 = _split.column()
|
||||
_row = _col_1.row()
|
||||
_row.alignment = "RIGHT"
|
||||
_row.label(text="Physical Size")
|
||||
_row = _col_2.row()
|
||||
_row.prop(_selected_graph.physical_size, "x", text='')
|
||||
_row.enabled = False
|
||||
_row_2 = _row.column()
|
||||
_row_2.prop(_selected_graph.physical_size, "y", text='')
|
||||
_row_2.enabled = False
|
||||
_row_3 = _row.column()
|
||||
_row_3.prop(_selected_graph.physical_size, "z", text='')
|
||||
_row_3.enabled = False
|
||||
|
||||
# Tiling
|
||||
_row = _col.row()
|
||||
_split = _row.split(factor=DRAW_DEFAULT_FACTOR)
|
||||
_col_1 = _split.column()
|
||||
_col_2 = _split.column()
|
||||
_row = _col_1.row()
|
||||
_row.alignment = "RIGHT"
|
||||
_row.label(text="Tiling")
|
||||
_row = _col_2.row()
|
||||
_row.prop(_selected_graph.tiling, "x", text='')
|
||||
_row_2 = _row.column()
|
||||
_row_2.prop(_selected_graph.tiling, "y", text='')
|
||||
_row_2.enabled = not _selected_graph.tiling.linked
|
||||
_row_3 = _row.column()
|
||||
_row_3.prop(_selected_graph.tiling, "z", text='')
|
||||
_row_3.enabled = not _selected_graph.tiling.linked
|
||||
_row.prop(_selected_graph.tiling, "linked", text='', icon='LOCKED')
|
||||
|
||||
_inputs = getattr(context.scene, _selected_graph.inputs_class_name)
|
||||
if _selected_graph.outputsize_exists:
|
||||
_row = _col.row()
|
||||
_split = _row.split(factor=DRAW_DEFAULT_FACTOR)
|
||||
_col_1 = _split.column()
|
||||
_col_2 = _split.column()
|
||||
_row = _col_1.row()
|
||||
_row.alignment = "RIGHT"
|
||||
_row.label(text="Resolution")
|
||||
_row = _col_2.row()
|
||||
_row.prop(
|
||||
_inputs,
|
||||
Code_InputIdentifier.outputsize.value + Code_OutputSizeSuffix.width.value,
|
||||
text='')
|
||||
_row_2 = _row.column()
|
||||
_row_2.prop(
|
||||
_inputs,
|
||||
Code_InputIdentifier.outputsize.value + Code_OutputSizeSuffix.height.value,
|
||||
text='')
|
||||
_linked = getattr(_inputs, Code_InputIdentifier.outputsize.value + Code_OutputSizeSuffix.linked.value)
|
||||
_row_2.enabled = not _linked
|
||||
_row.prop(
|
||||
_inputs,
|
||||
Code_InputIdentifier.outputsize.value + Code_OutputSizeSuffix.linked.value,
|
||||
text='',
|
||||
icon='LOCKED')
|
||||
|
||||
if _selected_graph.randomseed_exists:
|
||||
_row = _col.row()
|
||||
_split = _row.split(factor=DRAW_DEFAULT_FACTOR)
|
||||
_col_1 = _split.column()
|
||||
_col_2 = _split.column()
|
||||
_row = _col_1.row()
|
||||
_row.alignment = "RIGHT"
|
||||
_row.label(text="Random Seed")
|
||||
_row = _col_2.row()
|
||||
_row.prop(
|
||||
_inputs,
|
||||
Code_InputIdentifier.randomseed.value,
|
||||
text="")
|
||||
_row.operator(
|
||||
SUBSTANCE_OT_RandomizeSeed.bl_idname,
|
||||
text="",
|
||||
icon_value=ICONS_DICT["random_icon"].icon_id)
|
||||
|
||||
# Update textures only
|
||||
_row = _col.row()
|
||||
_split = _row.split(factor=DRAW_DEFAULT_FACTOR)
|
||||
_col_1 = _split.column()
|
||||
_col_2 = _split.column()
|
||||
_row = _col_1.row()
|
||||
_row.alignment = "RIGHT"
|
||||
_row.label(text="")
|
||||
_row = _col_2.row()
|
||||
_row.prop(_selected_graph, "update_tx_only", text="Only update texture images")
|
||||
|
||||
return SUBSTANCE_PT_GRAPH
|
||||
|
||||
|
||||
def SubstanceOutputsPanelFactory(space):
|
||||
class SUBSTANCE_PT_OUTPUTS(bpy.types.Panel):
|
||||
bl_idname = 'SUBSTANCE_PT_OUTPUTS_{}'.format(space)
|
||||
bl_space_type = space
|
||||
bl_label = 'Outputs'
|
||||
bl_region_type = 'UI'
|
||||
bl_category = 'Substance 3D'
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
if len(context.scene.loaded_sbsars) > 0:
|
||||
return True
|
||||
return False
|
||||
|
||||
def draw(self, context):
|
||||
_selected_graph = SUBSTANCE_Utils.get_selected_graph(context)
|
||||
|
||||
_col = self.layout.column(align=True)
|
||||
|
||||
_box = _col.box()
|
||||
|
||||
_row = _box.row()
|
||||
_split = _row.split(factor=DRAW_DEFAULT_FACTOR)
|
||||
_col_1 = _split.column()
|
||||
_col_2 = _split.column()
|
||||
_row = _col_1.row()
|
||||
_row.alignment = "RIGHT"
|
||||
_row.label(text="Shader")
|
||||
_row = _col_2.row()
|
||||
_row.prop(_selected_graph, 'shaders_list', text="")
|
||||
_row.prop(_selected_graph, 'outputs_filter', text="", expand=True)
|
||||
|
||||
# Show current outputs
|
||||
_selected_preset_idx = int(_selected_graph.shaders_list)
|
||||
_, _, _selected_shader_preset = SUBSTANCE_Utils.get_selected_shader(context, _selected_preset_idx)
|
||||
_shader_outputs = _selected_shader_preset.outputs
|
||||
|
||||
for _output in _selected_graph.outputs:
|
||||
if _selected_graph.outputs_filter == OUTPUTS_FILTER_DICT[0][0] and not _output.shader_enabled:
|
||||
continue
|
||||
if (_selected_graph.outputs_filter == OUTPUTS_FILTER_DICT[1][0] and
|
||||
_output.defaultChannelUse not in _shader_outputs):
|
||||
continue
|
||||
|
||||
_row = _box.row()
|
||||
_split = _row.split(factor=DRAW_DEFAULT_FACTOR)
|
||||
_col_1 = _split.column()
|
||||
_col_2 = _split.column()
|
||||
_row = _col_1.row()
|
||||
_row.alignment = "RIGHT"
|
||||
_row.label(text=_output.label)
|
||||
_row = _col_2.row()
|
||||
_row.prop(_output, "shader_enabled", text="")
|
||||
if _output.type == "image":
|
||||
_row.prop(_output, "shader_format", text="")
|
||||
_row.prop(_output, "shader_bitdepth", text="")
|
||||
|
||||
return SUBSTANCE_PT_OUTPUTS
|
||||
|
||||
|
||||
def SubstanceInputsPanelFactory(space):
|
||||
class SUBSTANCE_PT_INPUTS(bpy.types.Panel):
|
||||
bl_idname = 'SUBSTANCE_PT_INPUTS_{}'.format(space)
|
||||
bl_space_type = space
|
||||
bl_label = 'Parameters'
|
||||
bl_region_type = 'UI'
|
||||
bl_category = 'Substance 3D'
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
if len(context.scene.loaded_sbsars) > 0:
|
||||
return True
|
||||
return False
|
||||
|
||||
def draw(self, context):
|
||||
_selected_graph = SUBSTANCE_Utils.get_selected_graph(context)
|
||||
|
||||
_col = self.layout.column(align=True)
|
||||
|
||||
_row = _col.row()
|
||||
_row.operator(SUBSTANCE_OT_InputGroupsExpand.bl_idname, text='Expand Groups', icon='TRIA_DOWN')
|
||||
_row.operator(SUBSTANCE_OT_InputGroupsCollapse.bl_idname, text='Collapse Groups', icon='TRIA_RIGHT')
|
||||
|
||||
if SUBSTANCE_Utils.inputs_empty(_selected_graph.inputs):
|
||||
_row = _col.row()
|
||||
_row.label(text="No parameters available")
|
||||
else:
|
||||
_group_labels = []
|
||||
|
||||
for _group in _selected_graph.input_groups:
|
||||
if _group.label == INPUT_IMAGE_DEFAULT_GROUP:
|
||||
_group_labels.append(_group)
|
||||
|
||||
for _group in _selected_graph.input_groups:
|
||||
if _group.label == INPUT_DEFAULT_GROUP:
|
||||
_group_labels.append(_group)
|
||||
|
||||
for _group in _selected_graph.input_groups:
|
||||
if (_group.label != INPUT_TECHINCAL_GROUP and
|
||||
_group.label != INPUT_DEFAULT_GROUP and
|
||||
_group.label != INPUT_IMAGE_DEFAULT_GROUP):
|
||||
_group_labels.append(_group)
|
||||
|
||||
for _group in _selected_graph.input_groups:
|
||||
if _group.label == INPUT_TECHINCAL_GROUP:
|
||||
_group_labels.append(_group)
|
||||
|
||||
for _group in _group_labels:
|
||||
if _group.label == INPUT_CHANNELS_GROUP:
|
||||
continue
|
||||
|
||||
_empty = True
|
||||
|
||||
for _idx, _input in enumerate(_selected_graph.inputs):
|
||||
if (_group.label == _input.guiGroup and
|
||||
_input.visibleIf and
|
||||
_input.identifier != Code_InputIdentifier.randomseed.value and
|
||||
_input.identifier != Code_InputIdentifier.outputsize.value):
|
||||
_empty = False
|
||||
break
|
||||
|
||||
if _empty:
|
||||
continue
|
||||
|
||||
_box = _col.box()
|
||||
_row = _box.row()
|
||||
_row.alignment = "LEFT"
|
||||
_row.prop(
|
||||
_group,
|
||||
"collapsed",
|
||||
icon='TRIA_DOWN' if not _group.collapsed else 'TRIA_RIGHT',
|
||||
text=_group.label+":",
|
||||
emboss=False)
|
||||
|
||||
if not _group.collapsed:
|
||||
_inputs = getattr(context.scene, _selected_graph.inputs_class_name)
|
||||
for _idx, _input in enumerate(_selected_graph.inputs):
|
||||
if _input.guiGroup != _group.label:
|
||||
continue
|
||||
if (_input.guiWidget == Code_InputWidget.nowidget.value and
|
||||
_input.type != Code_InputType.string.name):
|
||||
continue
|
||||
if not _input.visibleIf:
|
||||
continue
|
||||
|
||||
_row = _box.row()
|
||||
_split = _row.split(factor=DRAW_DEFAULT_FACTOR)
|
||||
_col_1 = _split.column()
|
||||
_col_2 = _split.column()
|
||||
_row = _col_1.row()
|
||||
_row.alignment = "RIGHT"
|
||||
_row.label(text=_input.label)
|
||||
_row = _col_2.row()
|
||||
|
||||
if _input.type == Code_InputType.string.name:
|
||||
_row.prop(_inputs, _input.identifier, text="")
|
||||
elif _input.guiWidget == Code_InputWidget.combobox.value:
|
||||
_row.prop(_inputs, _input.identifier, text="")
|
||||
elif _input.guiWidget == Code_InputWidget.slider.value:
|
||||
_row.prop(_inputs, _input.identifier, text="", slider=True)
|
||||
elif _input.guiWidget == Code_InputWidget.togglebutton.value:
|
||||
_row.prop(_inputs, _input.identifier, expand=True)
|
||||
elif _input.guiWidget == Code_InputWidget.color.value:
|
||||
if _input.type == Code_InputType.float.name:
|
||||
_row.prop(_inputs, _input.identifier, text="", slider=True)
|
||||
else:
|
||||
_row.prop(_inputs, _input.identifier, text="")
|
||||
elif _input.guiWidget == Code_InputWidget.angle.value:
|
||||
_row.prop(_inputs, _input.identifier, text="", slider=True)
|
||||
elif _input.guiWidget == Code_InputWidget.position.value:
|
||||
_row.prop(_inputs, _input.identifier, text="", slider=True)
|
||||
elif _input.guiWidget == Code_InputWidget.image.value:
|
||||
_row.template_ID(_inputs, _input.identifier, open="image.open")
|
||||
else:
|
||||
_row.alert = True
|
||||
_row.label(text="Parameter type [{}] not supported yet".format(
|
||||
_input.guiWidget))
|
||||
_row.alert = False
|
||||
|
||||
return SUBSTANCE_PT_INPUTS
|
||||
@@ -0,0 +1,78 @@
|
||||
"""
|
||||
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: ui/shortcut.py
|
||||
# brief: Shortcuts UI
|
||||
# author Adobe - 3D & Immersive
|
||||
# copyright 2023 Adobe Inc. All rights reserved.
|
||||
|
||||
|
||||
import bpy
|
||||
|
||||
from ..utils import SUBSTANCE_Utils
|
||||
from ..common import SHORTCUT_CLASS_NAME
|
||||
from ..ops.sbsar import (
|
||||
SUBSTANCE_OT_LoadSBSAR,
|
||||
SUBSTANCE_OT_ApplySBSAR,
|
||||
SUBSTANCE_OT_RemoveSBSAR,
|
||||
SUBSTANCE_OT_DuplicateSBSAR,
|
||||
SUBSTANCE_OT_ReloadSBSAR
|
||||
)
|
||||
|
||||
|
||||
def SubstanceShortcutMenuFactory(space):
|
||||
|
||||
class SUBSTANCE_MT_Main(bpy.types.Menu):
|
||||
bl_idname = SHORTCUT_CLASS_NAME.format(space)
|
||||
bl_label = 'Substance 3D Menu'
|
||||
|
||||
def draw(self, context):
|
||||
self.layout.operator_context = 'INVOKE_REGION_WIN'
|
||||
|
||||
_row = self.layout.row(align=True)
|
||||
_row.operator(SUBSTANCE_OT_LoadSBSAR.bl_idname, text="Load New Substance File(s)")
|
||||
|
||||
_row = self.layout.row()
|
||||
_row.separator()
|
||||
|
||||
if len(context.scene.loaded_sbsars) > 0:
|
||||
_selected_sbsar = context.scene.loaded_sbsars[context.scene.sbsar_index]
|
||||
_selected_graph = SUBSTANCE_Utils.get_selected_graph(context)
|
||||
|
||||
_sbsar_name = _selected_sbsar.name + " - " + _selected_graph.name
|
||||
|
||||
_row = self.layout.row()
|
||||
_row.operator(
|
||||
SUBSTANCE_OT_ApplySBSAR.bl_idname,
|
||||
text="Apply " + _sbsar_name,
|
||||
icon='MATERIAL')
|
||||
|
||||
_row = self.layout.row()
|
||||
_row.operator(
|
||||
SUBSTANCE_OT_DuplicateSBSAR.bl_idname,
|
||||
text="Duplicate " + _selected_sbsar.name,
|
||||
icon='DUPLICATE')
|
||||
|
||||
_row = self.layout.row()
|
||||
_row.operator(
|
||||
SUBSTANCE_OT_ReloadSBSAR.bl_idname,
|
||||
text="Refresh " + _selected_sbsar.name,
|
||||
icon='FILE_REFRESH')
|
||||
|
||||
_row = self.layout.row()
|
||||
_row.operator(SUBSTANCE_OT_RemoveSBSAR.bl_idname, text="Remove " + _selected_sbsar.name, icon='TRASH')
|
||||
|
||||
return SUBSTANCE_MT_Main
|
||||
Reference in New Issue
Block a user