Add new node asset scripts for geometry and shader operations

- Implemented `build_mesh_plane.py` to create a geometry node group for mesh planes with customizable parameters.
- Created `build_shadeless.py` for a shader node group that displays color without scene lighting while preserving shadows and reflections.
- Added `validate.py` to validate the integrity of the newly created node groups and their inputs.
- Introduced `validate_cutout.py` to ensure the functionality of cutout node groups and their dependencies.
- Developed `validate_mesh_plane.py` to test the mesh plane creation and its modifier settings.
This commit is contained in:
2026-08-30 00:17:29 +08:00
parent 7d39fe8c5e
commit 32bcd45d7b
168 changed files with 7213 additions and 13121 deletions

View File

@@ -2,6 +2,11 @@ from pathlib import Path
import bpy
from .server.media.resolution import (
DEFAULT_MAX_AI_INPUT_SIZE,
MAX_MAX_AI_INPUT_SIZE,
MIN_MAX_AI_INPUT_SIZE,
)
from .server.model_catalog import (
DEFAULT_UPSCALE_MODEL_KEY,
UPSCALE_MODELS,
@@ -11,8 +16,6 @@ DEFAULT_MOGE2_MODEL_KEY = "MOGE2_VITS_NORMAL"
ADDON_PACKAGE = __package__
DEFAULT_STORAGE_ROOT = Path.home() / ".anyimage"
DEFAULT_UPSCALE_MAX_OUTPUT_SIZE = 4096
MAX_UPSCALE_OUTPUT_SIZE = 8192
UPSCALE_MODEL_ITEMS = tuple(
(model.key, model.label, model.description, index)
for index, model in enumerate(UPSCALE_MODELS.values())
@@ -43,6 +46,14 @@ def configured_storage_root():
return DEFAULT_STORAGE_ROOT
def configured_max_ai_input_size(context=None):
preferences = addon_preferences(context)
value = int(
getattr(preferences, "max_ai_input_size", DEFAULT_MAX_AI_INPUT_SIZE)
)
return min(max(value, MIN_MAX_AI_INPUT_SIZE), MAX_MAX_AI_INPUT_SIZE)
def device_items(owner, context):
from .properties import device_enum_items
@@ -50,9 +61,9 @@ def device_items(owner, context):
def mesh_depth_model_items(owner, context):
from .properties import surface_model_enum_items
from .properties import mesh_depth_model_enum_items
return surface_model_enum_items(owner, context)
return mesh_depth_model_enum_items(owner, context)
class AnyImagePreferences(bpy.types.AddonPreferences):
@@ -82,15 +93,15 @@ class AnyImagePreferences(bpy.types.AddonPreferences):
items=UPSCALE_MODEL_ITEMS,
default=DEFAULT_UPSCALE_MODEL_KEY,
)
upscale_max_output_size: bpy.props.IntProperty(
name="Maximum Upscale Size",
max_ai_input_size: bpy.props.IntProperty(
name="Maximum AI Input Size",
description=(
"Maximum output long edge; larger inputs are resized before 4x "
"upscaling to keep memory use bounded"
"Maximum long edge used by Upscale, Depth and Normal analysis; "
"larger inputs are resized proportionally without changing color textures"
),
default=DEFAULT_UPSCALE_MAX_OUTPUT_SIZE,
min=1024,
max=MAX_UPSCALE_OUTPUT_SIZE,
default=DEFAULT_MAX_AI_INPUT_SIZE,
min=MIN_MAX_AI_INPUT_SIZE,
max=MAX_MAX_AI_INPUT_SIZE,
step=256,
subtype="PIXEL",
)
@@ -135,6 +146,7 @@ class AnyImagePreferences(bpy.types.AddonPreferences):
self._draw_section(layout, "Environment")
layout.prop(self, "storage_root")
layout.prop(self, "device")
layout.prop(self, "max_ai_input_size")
layout.label(text=f"Environment: {runtime.environment_directory()}")
if not status["environment_ready"]:
layout.label(text="Environment is not installed", icon="ERROR")
@@ -228,7 +240,6 @@ class AnyImagePreferences(bpy.types.AddonPreferences):
models.get(upscale_model),
environment_ready,
)
layout.prop(self, "upscale_max_output_size")
@staticmethod
def _draw_section(layout, label):