feat: Implement upscale functionality with ONNX models

- Added upscale operator to handle image upscaling by 4x using AI models.
- Introduced new jobs for upscale processing in the server, including debug and standard upscale jobs.
- Created a new ONNX model handler for upscale operations, supporting tiled inference and resource management.
- Updated tests to cover new upscale functionality, including input validation and output verification.
- Added documentation for the upscale feature, detailing usage and model options.
This commit is contained in:
2026-08-23 20:34:35 +08:00
parent 1613bd3194
commit 0cf04a13c6
66 changed files with 2156 additions and 1088 deletions

View File

@@ -151,24 +151,6 @@ def data_name_matches(name, base_name):
return suffix != name and suffix.isdigit()
def material_uses_balloon_texture(material, color_name):
node_tree = getattr(material, "node_tree", None)
if node_tree is None:
return False
has_texture_layer = any(
getattr(node, "type", None) == "GROUP"
and getattr(getattr(node, "node_tree", None), "name", None)
== TEXTURE_MATERIAL_NODE_GROUP_NAME
for node in node_tree.nodes
)
has_color_image = any(
getattr(node, "type", None) == "TEX_IMAGE"
and getattr(node, "image", None) is not None
and data_name_matches(node.image.name, color_name)
for node in node_tree.nodes
)
return has_texture_layer and has_color_image
def marked_balloon_material(source_image, normal_required=False):
return next(
@@ -194,30 +176,8 @@ def mark_balloon_material(material, source_image, normal_image=None):
material[BALLOON_NORMAL_IMAGE_PROPERTY] = normal_image
def reusable_balloon_material(
material_name,
color_name,
source_image=None,
normal_required=False,
):
marked = (
marked_balloon_material(source_image, normal_required)
if source_image is not None
else None
)
if marked is not None:
return marked
if normal_required:
return None
return next(
(
material
for material in bpy.data.materials
if data_name_matches(material.name, material_name)
and material_uses_balloon_texture(material, color_name)
),
None,
)
def reusable_balloon_material(source_image, normal_required=False):
return marked_balloon_material(source_image, normal_required)
def load_balloon_normal_image(path, source_object):
@@ -331,8 +291,6 @@ def extract_balloon_object(
uses_normal = normal_path is not None
material = (
reusable_balloon_material(
material_name,
color_name,
image,
normal_required=uses_normal,
)