mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-02 00:44:52 +01:00
supports exporting layer stack with specific channel & output with specific channel
This commit is contained in:
parent
92fa97a563
commit
f08443f844
4 changed files with 113 additions and 18 deletions
|
|
@ -3,6 +3,8 @@ import re
|
|||
import json
|
||||
from collections import defaultdict
|
||||
|
||||
import contextlib
|
||||
import substance_painter as sp
|
||||
import substance_painter.project
|
||||
import substance_painter.resource
|
||||
import substance_painter.js
|
||||
|
|
@ -640,3 +642,58 @@ def prompt_new_file_with_mesh(mesh_filepath):
|
|||
return
|
||||
|
||||
return project_mesh
|
||||
|
||||
|
||||
def get_export_presets_by_filtering(export_preset_name, channel_type_list):
|
||||
new_maps = []
|
||||
|
||||
export_presets = get_export_presets()
|
||||
resource_presets = substance_painter.export.list_resource_export_presets()
|
||||
preset = next((preset for preset in resource_presets
|
||||
if preset.resource_id.name == (
|
||||
export_presets[export_preset_name])), None)
|
||||
|
||||
if preset is not None:
|
||||
maps = preset.list_output_maps()
|
||||
for channel_map in maps:
|
||||
for n in channel_type_list:
|
||||
if n in channel_map["fileName"]:
|
||||
new_maps.append(channel_map)
|
||||
# Create a new preset
|
||||
return {
|
||||
"exportPresets": [
|
||||
{
|
||||
"name": export_preset_name,
|
||||
"maps": new_maps
|
||||
}
|
||||
],
|
||||
}
|
||||
return {}
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def supsend_publish_layer_stack(node_ids, channel_type):
|
||||
all_selected_nodes = []
|
||||
opacity_set_list = []
|
||||
stack = sp.textureset.get_active_stack()
|
||||
stack_root_layers = sp.layerstack.get_root_layer_nodes(stack)
|
||||
if node_ids and channel_type:
|
||||
for node_id in node_ids:
|
||||
node = sp.layerstack.get_node_by_uid(int(node_id))
|
||||
all_selected_nodes.append(node)
|
||||
filtered_nodes = [node for node in stack_root_layers
|
||||
if node not in all_selected_nodes]
|
||||
for node in filtered_nodes:
|
||||
for channel in channel_type:
|
||||
chan = getattr(sp.textureset.ChannelType, channel)
|
||||
opacity_set_list.append((chan, node.get_opacity(chan)))
|
||||
try:
|
||||
for node in filtered_nodes:
|
||||
for channel, _ in opacity_set_list:
|
||||
node.set_opacity(0.0, channel)
|
||||
yield
|
||||
finally:
|
||||
for node in filtered_nodes:
|
||||
for channel, opacity in opacity_set_list:
|
||||
node.set_opacity(opacity, channel)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Creator plugin for creating textures."""
|
||||
|
||||
from ayon_core.pipeline import CreatedInstance, Creator, CreatorError
|
||||
from ayon_core.lib import (
|
||||
EnumDef,
|
||||
|
|
@ -18,6 +17,7 @@ from ayon_core.hosts.substancepainter.api.pipeline import (
|
|||
from ayon_core.hosts.substancepainter.api.lib import get_export_presets
|
||||
|
||||
import substance_painter.project
|
||||
import substance_painter as sp
|
||||
|
||||
|
||||
class CreateTextures(Creator):
|
||||
|
|
@ -42,10 +42,20 @@ class CreateTextures(Creator):
|
|||
"exportFileFormat",
|
||||
"exportSize",
|
||||
"exportPadding",
|
||||
"exportDilationDistance"
|
||||
"exportDilationDistance",
|
||||
"useCustomExportPreset",
|
||||
"exportChannel"
|
||||
]:
|
||||
if key in pre_create_data:
|
||||
creator_attributes[key] = pre_create_data[key]
|
||||
#TODO: add the layer stack option
|
||||
if sp.application.version_info()[0] >= 10 or (
|
||||
pre_create_data.get("use_selection")):
|
||||
stack = sp.textureset.get_active_stack()
|
||||
|
||||
instance_data["selected_node_id"] = [
|
||||
node_number.uid() for node_number in
|
||||
sp.layerstack.get_selected_nodes(stack)]
|
||||
|
||||
instance = self.create_instance_in_context(product_name,
|
||||
instance_data)
|
||||
|
|
@ -88,8 +98,25 @@ class CreateTextures(Creator):
|
|||
return instance
|
||||
|
||||
def get_instance_attr_defs(self):
|
||||
|
||||
layer_stack_channel_enum = ["BaseColor", "Metallic", "Roughness",
|
||||
"Normal", "Height", "Specular",
|
||||
"SpecularEdgeColor", "Emissive", "Opacity",
|
||||
"Displacement", "Glossiness", "Anisotropylevel",
|
||||
"AO", "Anisotropyangle", "Transmissive",
|
||||
"Reflection", "Diffuse", "Ior",
|
||||
"Specularlevel", "BlendingMask", "Translucency",
|
||||
"Scattering", "ScatterColor", "SheenOpacity",
|
||||
"SheenRoughness", "SheenColor", "CoatOpacity",
|
||||
"CoatColor", "CoatRoughness", "CoatSpecularLevel",
|
||||
"CoatNormal"]
|
||||
return [
|
||||
EnumDef("exportChannel",
|
||||
items=layer_stack_channel_enum,
|
||||
multiselection=True,
|
||||
default=None,
|
||||
label="Export Channel(s)",
|
||||
tooltip="Choose the channel which you "
|
||||
"want to solely export"),
|
||||
EnumDef("exportPresetUrl",
|
||||
items=get_export_presets(),
|
||||
label="Output Template"),
|
||||
|
|
@ -149,7 +176,6 @@ class CreateTextures(Creator):
|
|||
},
|
||||
default=None,
|
||||
label="Size"),
|
||||
|
||||
EnumDef("exportPadding",
|
||||
items={
|
||||
"passthrough": "No padding (passthrough)",
|
||||
|
|
@ -172,4 +198,7 @@ class CreateTextures(Creator):
|
|||
|
||||
def get_pre_create_attr_defs(self):
|
||||
# Use same attributes as for instance attributes
|
||||
return self.get_instance_attr_defs()
|
||||
return [
|
||||
BoolDef("use_selection", label="Use selection",
|
||||
tooltip="Select Layer Stack(s) for exporting")
|
||||
] + self.get_instance_attr_defs()
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import substance_painter.textureset
|
|||
from ayon_core.pipeline import publish
|
||||
from ayon_core.hosts.substancepainter.api.lib import (
|
||||
get_parsed_export_maps,
|
||||
get_export_presets_by_filtering,
|
||||
strip_template
|
||||
)
|
||||
from ayon_core.pipeline.create import get_product_name
|
||||
|
|
@ -207,5 +208,8 @@ class CollectTextureSet(pyblish.api.InstancePlugin):
|
|||
for key, value in dict(parameters).items():
|
||||
if value is None:
|
||||
parameters.pop(key)
|
||||
|
||||
channel_layer = creator_attrs.get("exportChannel", [])
|
||||
if channel_layer:
|
||||
maps = get_export_presets_by_filtering(preset_url, channel_layer)
|
||||
config.update(maps)
|
||||
return config
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import substance_painter.export
|
||||
|
||||
from ayon_core.pipeline import KnownPublishError, publish
|
||||
from ayon_core.hosts.substancepainter.api.lib import supsend_publish_layer_stack
|
||||
|
||||
|
||||
class ExtractTextures(publish.Extractor,
|
||||
|
|
@ -25,19 +25,24 @@ class ExtractTextures(publish.Extractor,
|
|||
def process(self, instance):
|
||||
|
||||
config = instance.data["exportConfig"]
|
||||
result = substance_painter.export.export_project_textures(config)
|
||||
creator_attrs = instance.data["creator_attributes"]
|
||||
export_channel = creator_attrs.get("exportChannel", [])
|
||||
node_ids = instance.data.get("selected_node_id", [])
|
||||
|
||||
if result.status != substance_painter.export.ExportStatus.Success:
|
||||
raise KnownPublishError(
|
||||
"Failed to export texture set: {}".format(result.message)
|
||||
)
|
||||
with supsend_publish_layer_stack(node_ids, export_channel):
|
||||
result = substance_painter.export.export_project_textures(config)
|
||||
|
||||
# Log what files we generated
|
||||
for (texture_set_name, stack_name), maps in result.textures.items():
|
||||
# Log our texture outputs
|
||||
self.log.info(f"Exported stack: {texture_set_name} {stack_name}")
|
||||
for texture_map in maps:
|
||||
self.log.info(f"Exported texture: {texture_map}")
|
||||
if result.status != substance_painter.export.ExportStatus.Success:
|
||||
raise KnownPublishError(
|
||||
"Failed to export texture set: {}".format(result.message)
|
||||
)
|
||||
|
||||
# Log what files we generated
|
||||
for (texture_set_name, stack_name), maps in result.textures.items():
|
||||
# Log our texture outputs
|
||||
self.log.info(f"Exported stack: {texture_set_name} {stack_name}")
|
||||
for texture_map in maps:
|
||||
self.log.info(f"Exported texture: {texture_map}")
|
||||
|
||||
# We'll insert the color space data for each image instance that we
|
||||
# added into this texture set. The collector couldn't do so because
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue