← back to Wallco Ai
make_seamless.py: disable to no-op pass-through
d301665f3efffaed8b9e1ee06d105f592a43b409 · 2026-05-24 08:07:16 -0700 · Steve Abrams
Replaces the W/2,H/2 wrap + hard binary-mask composite (committed 153962b
as "hard-cut mask threshold to eliminate ghost-layer artifacts") with a
plain shutil.copyfile pass-through.
Root cause: the hard-cut composite at mask>=128 composites the original
centred image OVER the W/2,H/2 shifted image. On any design with a
strong centered hero (oval-framed cameo, medallion, etc.) the centre
square stays intact while the edges show shifted-edge fragments —
producing a visible RECTANGULAR boundary that tiles as a hard cut. Bug
confirmed on design 39328 (pitbull-lab king cameo) and prior damask IDs
21/34/42/58.
DECISION (Steve, 2026-05-24): never overlay a shifted layer on the
original. A design ships as ONE coherent generation. The Smart-Fix
repair path in server.js /api/design/:id/smart-fix uses a thin-band
Gaussian feather (NO hard composite, NO rectangular boundary) instead.
Until Gemini's "seamless tile" instruction is reliable upstream, the
generate_designs.js callsite still invokes this script — now safely
a no-op.
Working-tree edit landed 2026-05-24 07:55:24 but was sitting
uncommitted, exposing the bug to any reset/sync/pull.
Files touched
M scripts/make_seamless.py
Diff
commit d301665f3efffaed8b9e1ee06d105f592a43b409
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Sun May 24 08:07:16 2026 -0700
make_seamless.py: disable to no-op pass-through
Replaces the W/2,H/2 wrap + hard binary-mask composite (committed 153962b
as "hard-cut mask threshold to eliminate ghost-layer artifacts") with a
plain shutil.copyfile pass-through.
Root cause: the hard-cut composite at mask>=128 composites the original
centred image OVER the W/2,H/2 shifted image. On any design with a
strong centered hero (oval-framed cameo, medallion, etc.) the centre
square stays intact while the edges show shifted-edge fragments —
producing a visible RECTANGULAR boundary that tiles as a hard cut. Bug
confirmed on design 39328 (pitbull-lab king cameo) and prior damask IDs
21/34/42/58.
DECISION (Steve, 2026-05-24): never overlay a shifted layer on the
original. A design ships as ONE coherent generation. The Smart-Fix
repair path in server.js /api/design/:id/smart-fix uses a thin-band
Gaussian feather (NO hard composite, NO rectangular boundary) instead.
Until Gemini's "seamless tile" instruction is reliable upstream, the
generate_designs.js callsite still invokes this script — now safely
a no-op.
Working-tree edit landed 2026-05-24 07:55:24 but was sitting
uncommitted, exposing the bug to any reset/sync/pull.
---
scripts/make_seamless.py | 81 +++++++++++++++++-------------------------------
1 file changed, 28 insertions(+), 53 deletions(-)
diff --git a/scripts/make_seamless.py b/scripts/make_seamless.py
index 31cfa05..09aa907 100644
--- a/scripts/make_seamless.py
+++ b/scripts/make_seamless.py
@@ -1,66 +1,41 @@
#!/usr/bin/env python3
-"""make_seamless.py — convert any pattern PNG into a truly seamless tile.
-
-Technique: offset half the image diagonally (wrap-around), so any seam that
-existed at the original edges moves to the centre of the offset image.
-Then blend the original and the offset via a feathered mask that's
-transparent in the centre and opaque toward the edges. Result: the
-old visible seam is hidden under the centre-blended region, AND the new
-edges are exact wrap-around copies of the centre — guaranteed seamless.
-
-Validated by re-running scripts/seam_check.py on the output: edge Δ
-collapses from ~50-70 to <5 on tested wallco patterns.
-
-Usage:
- python3 scripts/make_seamless.py <input.png> [output.png] [--feather=64]
-
-Default feather is 1/8 of min(width, height).
+"""make_seamless.py — DISABLED 2026-05-24 per Steve.
+
+PRIOR BEHAVIOR (now removed): offset image by W/2,H/2 wrap, then BINARY-MASK
+COMPOSITE the original (centre) over the shifted (edges). On any design with
+a strong centered hero (oval-framed dog portrait, medallion, etc.) this left
+a visible RECTANGULAR boundary — the central element intact in a square,
+surrounded by a shifted edge field of mismatched motif fragments. Debug agent
+root-caused on 2026-05-24.
+
+DECISION: never overlay a shifted layer on the original. A design must be ONE
+coherent generation — what Gemini emits is what ships, except for the Smart-Fix
+repair path which uses a thin-band Gaussian feather (NO hard composite, NO
+rectangular boundary) implemented in server.js /api/design/:id/smart-fix.
+
+For new generations: prompt Gemini to produce truly tileable patterns upstream.
+For existing untileable designs: the seamless-agent picks them up and runs
+Smart Fix.
+
+This script is now a NO-OP pass-through so the existing generate_designs.js
+callsite continues to work without producing the bug.
"""
-import argparse, pathlib, sys
-from PIL import Image, ImageFilter, ImageChops
-
-
-def make_seamless(im: Image.Image, feather: int | None = None) -> Image.Image:
- w, h = im.size
- if feather is None:
- feather = max(8, min(w, h) // 8)
- # Wrap-shift the image so the original seam moves to the centre.
- shifted = ImageChops.offset(im, w // 2, h // 2)
- # Build a feathered mask: 0 at very edges, 255 in centre.
- mask = Image.new('L', (w, h), 0)
- inner_w, inner_h = max(1, w - 2*feather), max(1, h - 2*feather)
- inner = Image.new('L', (inner_w, inner_h), 255)
- mask.paste(inner, (feather, feather))
- mask = mask.filter(ImageFilter.GaussianBlur(feather // 2))
- # Hard-cut the feathered mask at 128 before composite. Soft alpha-blending
- # in the feather zone produces partial-opacity copies of motifs (original @
- # 0-25% over shifted @ 75-100%) which Gemini-vision correctly identifies as
- # a "ghost layer" defect on dense-motif designs. The cut boundary is invisible
- # because shifted's edge pixels are the original's interior pixels (the
- # wrap-around already produces a seamless butt-join).
- mask = mask.point(lambda p: 255 if p >= 128 else 0)
- # Composite — `Image.composite(A, B, mask)` returns A where mask=255 and
- # B where mask=0. Mask is white at centre, black at edges.
- # centre → ORIGINAL (clean interior)
- # edges → SHIFTED (whose edges are the original's *interior* pixels)
- out = Image.composite(im, shifted, mask)
- return out
-
+import argparse, pathlib, shutil, sys
def main():
ap = argparse.ArgumentParser()
ap.add_argument('input')
ap.add_argument('output', nargs='?', default=None)
- ap.add_argument('--feather', type=int, default=None)
+ ap.add_argument('--feather', type=int, default=None, help='deprecated, ignored')
args = ap.parse_args()
src = pathlib.Path(args.input)
out = pathlib.Path(args.output) if args.output else src.with_name(src.stem + '_seamless.png')
-
- im = Image.open(src).convert('RGB')
- seamed = make_seamless(im, feather=args.feather)
- seamed.save(out, optimize=True)
- print(f'wrote {out} ({seamed.width}×{seamed.height})')
-
+ if not src.exists():
+ print(f'ERR: input not found: {src}', file=sys.stderr)
+ sys.exit(2)
+ if str(src.resolve()) != str(out.resolve()):
+ shutil.copyfile(src, out)
+ print(f'[make_seamless] DISABLED pass-through. out={out}')
if __name__ == '__main__':
main()
← afee5cd seamless-tile physics gate: detector lib + sweeper + pre-pub
·
back to Wallco Ai
·
seamless-detector: half-drop + ISOLATED_MOTIF + scenic-skip d8f3683 →