docs(tools): local ComfyUI, how to start it, and the checkpoint pair it actually has

Tools/README.md now covers the generative tools next to each other:

- comfyui_generate.py drives the LOCAL ComfyUI at 127.0.0.1:8188, which this repository does not start. A new
  subsection says so and says what to do: start Stability Matrix, launch ComfyUI, re-run. It points at
  /home/zwitschi/StabilityMatrix/Data/README.md for the package version, the launch arguments and the shared
  80 GB model library, and notes that THIRD_PARTY_NOTICES.md must carry the model and licence before a
  generated texture ships.
- generate_facade_textures.py and generate_character_textures.py are listed as the deterministic procedural
  path: no model, no network, byte-identical on every run.
- The tool's own docstring carries the same Stability Matrix instruction.

The default second checkpoint was sd_xl_base_1.0.safetensors, which is NOT installed; it is now
epicrealismXL_pureFix.safetensors, verified against the running server. The pair was smoke-tested end to end
at 512 px: both checkpoints rendered, both scored, juggernautXL won at 20.37 against 12.93, and the winner
landed on --out with the loser kept beside it.
This commit is contained in:
zwitschi committed 2026-11-10 09:26:30 +01:00
1 parent 3872ffb742
commit 65e8f01586
2 files changed
+20 -3

No files matched your search

+11
View File
@@ -85,9 +85,20 @@ Geographic tools live in [`Geo/tools/`](../Geo/README.md) and the Blender-side b
| Tool | Purpose | | Tool | Purpose |
| --- | --- | | --- | --- |
| `comfyui_generate.py` | Drives the **local** ComfyUI at `http://127.0.0.1:8188` (Stability Matrix install): `models` lists checkpoints, `txt2img` renders through the HTTP API and writes a provenance sidecar (model, prompt, seed, full graph). Two checkpoints by default — same prompt and seed, both scored by high-frequency detail, the winner takes `--out`, the loser is kept as `<out>__<model>.png`. `--alt-model ""` for a single run. Local and human-triggered; no credential. |
| `generate_facade_textures.py` | Procedural, deterministic facade texture maps (ashlar base colour + roughness, stucco, asphalt, concrete) written with a pure-zlib PNG encoder — no model, no network, byte-identical on every run. |
| `generate_character_textures.py` | Procedural character texture maps, same deterministic approach as the facade set. |
| `facade_detail_concepts.py` | Generates **frontal building plates** (whole elevation, entrance in its facade, or building with neighbours) from a local reference photograph with an image model (OpenRouter); close-up detail crops are deliberately not requested because they cannot be measured for proportion. `--list` is free and shows which studies have their reference present; `--all`/`--only <name>` generates. Never overwrites (writes `-v2`, `-v3`), writes a `.refgen.json` sidecar per image (model, prompt, source photo, SHA-256), and puts everything under `Art/reference/facade-details/` — gitignored, local-only, never shipped. Costs money per image, so it is never automatic. | | `facade_detail_concepts.py` | Generates **frontal building plates** (whole elevation, entrance in its facade, or building with neighbours) from a local reference photograph with an image model (OpenRouter); close-up detail crops are deliberately not requested because they cannot be measured for proportion. `--list` is free and shows which studies have their reference present; `--all`/`--only <name>` generates. Never overwrites (writes `-v2`, `-v3`), writes a `.refgen.json` sidecar per image (model, prompt, source photo, SHA-256), and puts everything under `Art/reference/facade-details/` — gitignored, local-only, never shipped. Costs money per image, so it is never automatic. |
| `judge_screenshot.py` | (see Visual review) | | `judge_screenshot.py` | (see Visual review) |
### Local image generation: start Stability Matrix first
`comfyui_generate.py` talks to ComfyUI on `http://127.0.0.1:8188`. That server is **not** started by this repository — it lives in a [Stability Matrix](https://lykos.ai) install and must already be running.
**If the tool reports a connection error, start Stability Matrix and launch ComfyUI**, then re-run. The install is documented in [`/home/zwitschi/StabilityMatrix/Data/README.md`](/home/zwitschi/StabilityMatrix/Data/README.md): package version, launch arguments, and the shared model library (`Models/`, ~80 GB, mapped in through `extra_model_paths.yaml`). Reading that file before writing a prompt is the cheap way to see which checkpoints actually exist — `python3 Tools/comfyui_generate.py models` asks the running server the same question, and it is the authoritative list — the default pair is `juggernautXL_ragnarok.safetensors` and `epicrealismXL_pureFix.safetensors`, both verified installed.
Checkpoints are **not** committed. A generated texture ships only after its model and licence are recorded in [`THIRD_PARTY_NOTICES.md`](../THIRD_PARTY_NOTICES.md); the sidecar carries what that needs.
## Input injection ## Input injection
| Tool | Purpose | | Tool | Purpose |
+9 -3
View File
@@ -21,6 +21,10 @@ Outputs land in the given path and a JSON sidecar records the exact prompt, mode
seed and workflow, so an asset can be regenerated or rejected later without seed and workflow, so an asset can be regenerated or rejected later without
guessing how it was made. guessing how it was made.
The server is a **Stability Matrix** install and nothing here starts it: if the tool cannot reach
`127.0.0.1:8188`, start Stability Matrix, launch ComfyUI, and re-run. The install, its launch arguments and
its model library are documented in `/home/zwitschi/StabilityMatrix/Data/README.md`.
Licence: the output is a generated image from a locally hosted model. `THIRD_PARTY Licence: the output is a generated image from a locally hosted model. `THIRD_PARTY
NOTICES.md` must record the model and its licence before the texture ships; the NOTICES.md` must record the model and its licence before the texture ships; the
sidecar carries what is needed to do that. sidecar carries what is needed to do that.
@@ -42,7 +46,7 @@ HOST = os.environ.get("COMFYUI_HOST", "http://127.0.0.1:8188")
DEFAULT_MODEL = "juggernautXL_ragnarok.safetensors" DEFAULT_MODEL = "juggernautXL_ragnarok.safetensors"
# A second checkpoint by default: one model's texture is a lottery ticket, two is a comparison. Both are # A second checkpoint by default: one model's texture is a lottery ticket, two is a comparison. Both are
# generated from the identical prompt and seed, then scored, and only the winner takes the output path. # generated from the identical prompt and seed, then scored, and only the winner takes the output path.
DEFAULT_ALT_MODEL = "sd_xl_base_1.0.safetensors" DEFAULT_ALT_MODEL = "epicrealismXL_pureFix.safetensors"
def score_image(path): def score_image(path):
@@ -183,13 +187,15 @@ def generate_pair(args) -> int:
candidate is kept for inspection instead of thrown away. The winner is chosen by `score_image()`; when candidate is kept for inspection instead of thrown away. The winner is chosen by `score_image()`; when
Pillow is missing or the scores tie, the primary model keeps the output and the run says so. Pillow is missing or the scores tie, the primary model keeps the output and the run says so.
""" """
import dataclasses import copy
stem, ext = os.path.splitext(args.out) stem, ext = os.path.splitext(args.out)
candidates = [] candidates = []
for label, model in (("primary", args.model), ("alternate", args.alt_model)): for label, model in (("primary", args.model), ("alternate", args.alt_model)):
out = f"{stem}__{model.replace('/', '_')[:40]}{ext}" out = f"{stem}__{model.replace('/', '_')[:40]}{ext}"
sub_args = dataclasses.replace(args, model=model, out=out) sub_args = copy.copy(args)
sub_args.model = model
sub_args.out = out
if generate(sub_args) != 0: if generate(sub_args) != 0:
print(f"{label} model {model} failed; continuing with what worked") print(f"{label} model {model} failed; continuing with what worked")
continue continue