One directory with sixty scripts stopped being navigable, and the grouping is also the sandbox boundary:
Tools/unreal/ commandlets and the two map builders, with ue_common.py and ue_placement.py as the
shared imports (they need the engine)
Tools/blender/ builders, exporters, the FBX preset, the MPFB character pipeline, blender_screenshots
(they need the Blender Flatpak)
Tools/review/ the visual loop: render_screenshots.sh, judge_screenshot.py, hero_compare.py,
build_comparison_md.py, e2e_asset_check.py, hero_iterate.sh, visual_loop.py,
visual_targets.json
Tools/gen/ image and texture generation: the ComfyUI driver, deterministic texture writers,
reference fetching
Tools/input/ OS-level input injection
root _common.py, check-lfs.sh, addon_compat_probe.py, sibling_asset_audit.py, tests/
Every moved script now resolves the repository root as ../.. and puts the tools root plus its siblings on
sys.path, so 'import ue_common' still works from unreal/. The test suite bootstrap does the same for the five
folders. render_screenshots.sh takes the folder as a third argument to run_cmdlet, and the e2e driver,
hero_iterate.sh and the comparison generator were repointed.
51 README rows now link to their new location, the README gains a Layout section naming each folder's
sandbox, and the architecture notes and Blender README follow the moves.
Verified: 108 tests pass, prettier is clean, judge_screenshot.py and hero_compare.py run from their new
homes, and the e2e run was aborted mid-way (it had been rebuilding an empty DemoMap for 15 minutes) and is
being rerun against the new layout.
54 lines
2.3 KiB
Python
54 lines
2.3 KiB
Python
"""Graph shape for the documented texture workflows (no ComfyUI process involved)."""
|
|
|
|
import os
|
|
import sys
|
|
|
|
_TOOLS = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
sys.path.insert(0, _TOOLS)
|
|
for _sub in ("review", "gen", "unreal", "blender", "input"):
|
|
sys.path.insert(0, os.path.join(_TOOLS, _sub))
|
|
|
|
|
|
import unittest
|
|
|
|
from comfyui_generate import TEXTURE_PROFILES, texture_workflow
|
|
|
|
|
|
class TextureWorkflowTests(unittest.TestCase):
|
|
def test_sdxl_profile_uses_a_checkpoint_and_a_real_negative(self):
|
|
graph = texture_workflow("albedobase", "stone", 1024, 1024, 7)
|
|
self.assertEqual(graph["1"]["class_type"], "CheckpointLoaderSimple")
|
|
self.assertEqual(graph["5"]["class_type"], "CLIPTextEncode")
|
|
sampler = graph["7"]["inputs"]
|
|
self.assertEqual(sampler["steps"], TEXTURE_PROFILES["albedobase"]["steps"])
|
|
self.assertEqual(sampler["negative"], ["5", 0])
|
|
|
|
def test_unet_profile_loads_unet_clip_and_vae(self):
|
|
graph = texture_workflow("krea2", "stone", 1024, 1024, 7)
|
|
self.assertEqual(graph["1"]["class_type"], "UNETLoader")
|
|
self.assertEqual(graph["2"]["class_type"], "CLIPLoader")
|
|
self.assertEqual(graph["2"]["inputs"]["type"], "krea2")
|
|
self.assertEqual(graph["3"]["class_type"], "VAELoader")
|
|
self.assertIn("texture_fix", graph["3"]["inputs"]["vae_name"])
|
|
|
|
def test_krea2_zeroes_the_negative_at_cfg_one(self):
|
|
graph = texture_workflow("krea2", "stone", 1024, 1024, 7)
|
|
self.assertEqual(graph["5"]["class_type"], "ConditioningZeroOut")
|
|
self.assertEqual(graph["7"]["inputs"]["negative"], ["5", 0])
|
|
|
|
def test_qwen_profile_uses_its_own_text_encode_node(self):
|
|
graph = texture_workflow("qwen21", "stone", 1024, 1024, 7)
|
|
self.assertEqual(graph["4"]["class_type"], "TextEncodeQwenImage21")
|
|
# CFG 1 with no negative: the positive conditioning is reused.
|
|
self.assertEqual(graph["7"]["inputs"]["negative"], ["4", 0])
|
|
|
|
def test_every_profile_names_installed_models(self):
|
|
for name, spec in TEXTURE_PROFILES.items():
|
|
self.assertTrue(spec.get("checkpoint") or spec.get("unet"), name)
|
|
if "unet" in spec:
|
|
self.assertTrue(spec["clip"] and spec["vae"], name)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|