supports exporting layer stack with specific channel & output with specific channel

This commit is contained in:
Kayla Man 2024-05-21 17:45:57 +08:00
parent 92fa97a563
commit f08443f844
4 changed files with 113 additions and 18 deletions

View file

@ -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)

View file

@ -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()

View file

@ -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

View file

@ -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