← back to Designer Wallcoverings
Real-sample room composites via patch-quilting (the winning method)
ad315325344c905b5e817785f3e914fadb8cd2f0 · 2026-07-07 09:59:49 -0700 · Steve
Steve feedback: swatches are 4x6 samples shot at 6in (true macro scale) — USE them.
- compose_real.py / batch_composite.py: randomized patch-quilt stitches random,
flipped, feather-blended crops of the REAL sample into a non-repeating grasscloth
field at true physical scale (~90px). No grid, no mirror symmetry, exact color.
Pure PIL/numpy: ~1s/room, $0, no GPU (300x faster than diffusion, always accurate).
- Kontext-alone invented generic textures; Kontext-relight hallucinated (green print);
SDXL img2img couldn't dissolve tile grid. Patch-quilt is the answer.
- make_wall_mask.py: tightened furniture bboxes -> full-wall coverage
- 67 rooms finalized into room_setting_images; push dry-run 67/67
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
A scripts/wallquest-refresh/carl-robinson-viewer/compare-real.htmlA scripts/wallquest-refresh/carl-robinson-viewer/room-engines/batch_composite.pyA scripts/wallquest-refresh/carl-robinson-viewer/room-engines/compose_real.pyM scripts/wallquest-refresh/carl-robinson-viewer/room-engines/make_wall_mask.pyA scripts/wallquest-refresh/carl-robinson-viewer/room-engines/sdxl_relight.py
Diff
commit ad315325344c905b5e817785f3e914fadb8cd2f0
Author: Steve <steve@designerwallcoverings.com>
Date: Tue Jul 7 09:59:49 2026 -0700
Real-sample room composites via patch-quilting (the winning method)
Steve feedback: swatches are 4x6 samples shot at 6in (true macro scale) — USE them.
- compose_real.py / batch_composite.py: randomized patch-quilt stitches random,
flipped, feather-blended crops of the REAL sample into a non-repeating grasscloth
field at true physical scale (~90px). No grid, no mirror symmetry, exact color.
Pure PIL/numpy: ~1s/room, $0, no GPU (300x faster than diffusion, always accurate).
- Kontext-alone invented generic textures; Kontext-relight hallucinated (green print);
SDXL img2img couldn't dissolve tile grid. Patch-quilt is the answer.
- make_wall_mask.py: tightened furniture bboxes -> full-wall coverage
- 67 rooms finalized into room_setting_images; push dry-run 67/67
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
.../carl-robinson-viewer/compare-real.html | 146 +++++++++++++++++++++
.../room-engines/batch_composite.py | 51 +++++++
.../room-engines/compose_real.py | 58 ++++++++
.../room-engines/make_wall_mask.py | 6 +-
.../room-engines/sdxl_relight.py | 22 ++++
5 files changed, 280 insertions(+), 3 deletions(-)
diff --git a/scripts/wallquest-refresh/carl-robinson-viewer/compare-real.html b/scripts/wallquest-refresh/carl-robinson-viewer/compare-real.html
new file mode 100644
index 00000000..7088c2f0
--- /dev/null
+++ b/scripts/wallquest-refresh/carl-robinson-viewer/compare-real.html
@@ -0,0 +1,146 @@
+<!doctype html><meta charset=utf-8><title>CR Real-Sample Rooms</title><style>
+body{font:14px/1.4 -apple-system,system-ui;margin:0;background:#111;color:#eee}
+header{position:sticky;top:0;background:#1b1b1b;padding:12px 18px;border-bottom:1px solid #333}
+h1{font-size:16px;margin:0} .sub{color:#9ad;font-size:12px}
+.card{border-bottom:1px solid #262626;padding:14px 18px} .hd{font-weight:600;margin-bottom:8px}
+.row{display:grid;grid-template-columns:1fr 2fr;gap:12px;max-width:1100px}
+.cell{background:#191919;border:1px solid #2a2a2a;border-radius:8px;overflow:hidden}
+.lbl{font-size:11px;color:#9a9a9a;padding:5px 8px;border-bottom:1px solid #2a2a2a}
+.cell img{width:100%;display:block} .pending{padding:40px;text-align:center;color:#666}</style>
+<header><h1>Carl Robinson → Phillipe Romano — Real-Sample Rooms (patch-quilt, $0 local)</h1>
+<div class=sub>Uses the actual 4×6 sample at true scale · 67 rooms · tile 90px · refresh after scale changes</div></header>
+<div class=card><div class=hd>BAM-100048 · Bamboo · Sour Cream</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/BAM-100048.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/BAM-100048-real.png" loading=lazy></div></div></div><div class=card><div class=hd>BAM-100049 · Bamboo · Sea Shell</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/BAM-100049.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/BAM-100049-real.png" loading=lazy></div></div></div><div class=card><div class=hd>BAM-100050 · Bamboo · Mica</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/BAM-100050.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/BAM-100050-real.png" loading=lazy></div></div></div><div class=card><div class=hd>BAM-100051 · Bamboo · Silver Lining</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/BAM-100051.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/BAM-100051-real.png" loading=lazy></div></div></div><div class=card><div class=hd>BAM-100052 · Bamboo · Shaved Ice</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/BAM-100052.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/BAM-100052-real.png" loading=lazy></div></div></div><div class=card><div class=hd>CORK-100057 · Cork · Chalk</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/DWCR-50001.jpeg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/CORK-100057-real.png" loading=lazy></div></div></div><div class=card><div class=hd>CORK-100058 · Cork · Water Lily</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/DWCR-50026.jpeg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/CORK-100058-real.png" loading=lazy></div></div></div><div class=card><div class=hd>FIB-100059 · Fiber · Birch Bark</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/FIB-100059.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/FIB-100059-real.png" loading=lazy></div></div></div><div class=card><div class=hd>FIB-100060 · Fiber · Cool Linen</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/FIB-100060.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/FIB-100060-real.png" loading=lazy></div></div></div><div class=card><div class=hd>GRS-100020 · Grasscloth · Plaster</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/GRS-100020.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/GRS-100020-real.png" loading=lazy></div></div></div><div class=card><div class=hd>GRS-100021 · Grasscloth · Gauze</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/GRS-100021.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/GRS-100021-real.png" loading=lazy></div></div></div><div class=card><div class=hd>GRS-100022 · Grasscloth · Bleached Coral</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/GRS-100022.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/GRS-100022-real.png" loading=lazy></div></div></div><div class=card><div class=hd>GRS-100023 · Grasscloth · Iceberg</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/GRS-100023.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/GRS-100023-real.png" loading=lazy></div></div></div><div class=card><div class=hd>GRS-100024 · Grasscloth · Egret</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/GRS-100024.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/GRS-100024-real.png" loading=lazy></div></div></div><div class=card><div class=hd>GRS-100025 · Grasscloth · Almond</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/GRS-100025.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/GRS-100025-real.png" loading=lazy></div></div></div><div class=card><div class=hd>GRS-100026 · Grasscloth · Roasted Marshmallow</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/GRS-100026.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/GRS-100026-real.png" loading=lazy></div></div></div><div class=card><div class=hd>GRS-100027 · Grasscloth · Stardust</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/GRS-100027.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/GRS-100027-real.png" loading=lazy></div></div></div><div class=card><div class=hd>GRS-100028 · Grasscloth · Moon</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/GRS-100028.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/GRS-100028-real.png" loading=lazy></div></div></div><div class=card><div class=hd>GRS-100029 · Grasscloth · Vanilla</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/GRS-100029.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/GRS-100029-real.png" loading=lazy></div></div></div><div class=card><div class=hd>GRS-100030 · Grasscloth · Ghost White</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/GRS-100030.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/GRS-100030-real.png" loading=lazy></div></div></div><div class=card><div class=hd>GRS-100031 · Grasscloth · Bone</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/GRS-100031.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/GRS-100031-real.png" loading=lazy></div></div></div><div class=card><div class=hd>GRS-100032 · Grasscloth · Parchment</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/GRS-100032.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/GRS-100032-real.png" loading=lazy></div></div></div><div class=card><div class=hd>GRS-100033 · Grasscloth · Sun Kissed</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/GRS-100033.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/GRS-100033-real.png" loading=lazy></div></div></div><div class=card><div class=hd>JUT-100061 · Jute · Cotton</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/JUT-100061.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/JUT-100061-real.png" loading=lazy></div></div></div><div class=card><div class=hd>JUT-100062 · Jute · Eggshell</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/JUT-100062.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/JUT-100062-real.png" loading=lazy></div></div></div><div class=card><div class=hd>MIC-100065 · Mica · Mother of Pearl</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/DWCR-50019.jpeg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/MIC-100065-real.png" loading=lazy></div></div></div><div class=card><div class=hd>NET-100042 · Netting · Tan</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/NET-100042.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/NET-100042-real.png" loading=lazy></div></div></div><div class=card><div class=hd>NET-100043 · Netting · Sand</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/NET-100043.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/NET-100043-real.png" loading=lazy></div></div></div><div class=card><div class=hd>NET-100044 · Netting · Tusk</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/NET-100044.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/NET-100044-real.png" loading=lazy></div></div></div><div class=card><div class=hd>NET-100045 · Netting · Flour</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/NET-100045.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/NET-100045-real.png" loading=lazy></div></div></div><div class=card><div class=hd>NET-100046 · Netting · Paper</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/NET-100046.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/NET-100046-real.png" loading=lazy></div></div></div><div class=card><div class=hd>NET-100047 · Netting · Lurex</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/NET-100047.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/NET-100047-real.png" loading=lazy></div></div></div><div class=card><div class=hd>NWV-100066 · Nonwoven · Raw Silk</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/DWCR-50031.jpeg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/NWV-100066-real.png" loading=lazy></div></div></div><div class=card><div class=hd>PWV-100001 · Paperweave · Winter white</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/PWV-100001.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/PWV-100001-real.png" loading=lazy></div></div></div><div class=card><div class=hd>PWV-100002 · Paperweave · Arctic white</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/PWV-100002.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/PWV-100002-real.png" loading=lazy></div></div></div><div class=card><div class=hd>PWV-100003 · Paperweave · Frost</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/PWV-100003.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/PWV-100003-real.png" loading=lazy></div></div></div><div class=card><div class=hd>PWV-100004 · Paperweave · Sail</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/PWV-100004.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/PWV-100004-real.png" loading=lazy></div></div></div><div class=card><div class=hd>PWV-100005 · Paperweave · Crushed Silk</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/PWV-100005.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/PWV-100005-real.png" loading=lazy></div></div></div><div class=card><div class=hd>PWV-100006 · Paperweave · Tissue</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/PWV-100006.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/PWV-100006-real.png" loading=lazy></div></div></div><div class=card><div class=hd>PWV-100007 · Paperweave · Cabana Linen</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/PWV-100007.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/PWV-100007-real.png" loading=lazy></div></div></div><div class=card><div class=hd>PWV-100008 · Paperweave · Wool</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/PWV-100008.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/PWV-100008-real.png" loading=lazy></div></div></div><div class=card><div class=hd>PWV-100009 · Paperweave · Meringue</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/PWV-100009.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/PWV-100009-real.png" loading=lazy></div></div></div><div class=card><div class=hd>PWV-100010 · Paperweave · Honeysuckle</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/PWV-100010.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/PWV-100010-real.png" loading=lazy></div></div></div><div class=card><div class=hd>PWV-100011 · Paperweave · White Chocolate</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/PWV-100011.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/PWV-100011-real.png" loading=lazy></div></div></div><div class=card><div class=hd>PWV-100012 · Paperweave · Foil</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/PWV-100012.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/PWV-100012-real.png" loading=lazy></div></div></div><div class=card><div class=hd>PWV-100013 · Paperweave · Brushed Silver</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/PWV-100013.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/PWV-100013-real.png" loading=lazy></div></div></div><div class=card><div class=hd>PWV-100014 · Paperweave · Rice Paper</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/PWV-100014.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/PWV-100014-real.png" loading=lazy></div></div></div><div class=card><div class=hd>PWV-100015 · Paperweave · White Heron</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/PWV-100015.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/PWV-100015-real.png" loading=lazy></div></div></div><div class=card><div class=hd>PWV-100016 · Paperweave · Pearla</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/PWV-100016.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/PWV-100016-real.png" loading=lazy></div></div></div><div class=card><div class=hd>PWV-100017 · Paperweave · Off White</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/PWV-100017.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/PWV-100017-real.png" loading=lazy></div></div></div><div class=card><div class=hd>PWV-100018 · Paperweave · Casablanca</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/PWV-100018.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/PWV-100018-real.png" loading=lazy></div></div></div><div class=card><div class=hd>PWV-100019 · Paperweave · Powdered Sugar</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/PWV-100019.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/PWV-100019-real.png" loading=lazy></div></div></div><div class=card><div class=hd>RAF-100034 · Raffia · Bleached Linen</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/RAF-100034.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/RAF-100034-real.png" loading=lazy></div></div></div><div class=card><div class=hd>RAF-100035 · Raffia · Rice</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/RAF-100035.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/RAF-100035-real.png" loading=lazy></div></div></div><div class=card><div class=hd>RAF-100036 · Raffia · Feather White</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/RAF-100036.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/RAF-100036-real.png" loading=lazy></div></div></div><div class=card><div class=hd>RAF-100037 · Raffia · Latte</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/RAF-100037.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/RAF-100037-real.png" loading=lazy></div></div></div><div class=card><div class=hd>RAF-100038 · Raffia · Cold Foam</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/RAF-100038.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/RAF-100038-real.png" loading=lazy></div></div></div><div class=card><div class=hd>RAF-100039 · Raffia · Dove</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/RAF-100039.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/RAF-100039-real.png" loading=lazy></div></div></div><div class=card><div class=hd>RAF-100040 · Raffia · Bleached Burlap</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/RAF-100040.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/RAF-100040-real.png" loading=lazy></div></div></div><div class=card><div class=hd>RAF-100041 · Raffia · Crisp White</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/RAF-100041.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/RAF-100041-real.png" loading=lazy></div></div></div><div class=card><div class=hd>SIS-100053 · Sisal · Buttercream</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/SIS-100053.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/SIS-100053-real.png" loading=lazy></div></div></div><div class=card><div class=hd>SIS-100054 · Sisal · Coconut</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/SIS-100054.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/SIS-100054-real.png" loading=lazy></div></div></div><div class=card><div class=hd>SIS-100055 · Sisal · Almond</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/SIS-100055.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/SIS-100055-real.png" loading=lazy></div></div></div><div class=card><div class=hd>SIS-100056 · Sisal · Cream</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/SIS-100056.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/SIS-100056-real.png" loading=lazy></div></div></div><div class=card><div class=hd>SLK-100063 · Silk · Cryslas</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/SLK-100063.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/SLK-100063-real.png" loading=lazy></div></div></div><div class=card><div class=hd>SLK-100064 · Silk · Cappuccino</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/SLK-100064.jpg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/SLK-100064-real.png" loading=lazy></div></div></div><div class=card><div class=hd>WDV-100067 · Wood Veneer · Candle</div>
+ <div class=row><div class=cell><div class=lbl>Sample (4×6)</div><img src="img/DWCR-50010.jpeg" loading=lazy></div>
+ <div class=cell><div class=lbl>Room — real sample, patch-quilt</div><img src="rooms-local/WDV-100067-real.png" loading=lazy></div></div></div>
\ No newline at end of file
diff --git a/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/batch_composite.py b/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/batch_composite.py
new file mode 100644
index 00000000..9354311c
--- /dev/null
+++ b/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/batch_composite.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python3
+# Batch REAL-SAMPLE room composites for all 67 SKUs via randomized patch-quilting.
+# Pure PIL/numpy: ~1s/room, $0, no GPU. Preserves each sample's exact texture/color/scale.
+import os, hashlib, subprocess, sys
+from PIL import Image, ImageEnhance
+import numpy as np
+
+VIEW = '/tmp/carl-robinson-viewer'
+OUT = '/Users/macstudio3/Projects/Designer-Wallcoverings/scripts/wallquest-refresh/carl-robinson-viewer/rooms-local'
+BASE = '/tmp/cr-room-bakeoff/00-empty-room.png'
+MASK = '/tmp/cr-room-bakeoff/wall-mask.png'
+TILE = int(sys.argv[1]) if len(sys.argv) > 1 else 90
+os.makedirs(OUT, exist_ok=True)
+base = Image.open(BASE).convert('RGB'); W, H = base.size
+mask = Image.open(MASK).convert('L').resize((W, H))
+lum = np.clip(0.60 + 0.70 * (np.asarray(base.convert('L'), np.float32) / 255.0), 0.4, 1.2)[..., None]
+
+def quilt(swpath, tile):
+ src = Image.open(swpath).convert('RGB'); s0 = min(src.size); mm = int(s0 * 0.12)
+ src = src.crop((mm, mm, src.size[0]-mm, src.size[1]-mm))
+ sc = (tile * 3) / min(src.size)
+ src = src.resize((max(1, int(src.size[0]*sc)), max(1, int(src.size[1]*sc))), Image.LANCZOS)
+ S = np.asarray(src, np.float32); SH, SWi = S.shape[0], S.shape[1]
+ rng = np.random.default_rng(int(hashlib.md5(swpath.encode()).hexdigest(), 16) % (2**32))
+ P = tile; ov = max(6, P // 3); step = P - ov
+ feather = np.clip(np.hanning(P)[:, None] * np.hanning(P)[None, :], 1e-3, 1)[..., None]
+ acc = np.zeros((H + P, W + P, 3), np.float32); wsum = np.zeros((H + P, W + P, 1), np.float32)
+ for y in range(0, H, step):
+ for x in range(0, W, step):
+ cy = int(rng.integers(0, max(1, SH - P))); cx = int(rng.integers(0, max(1, SWi - P)))
+ patch = S[cy:cy+P, cx:cx+P]
+ if patch.shape[0] != P or patch.shape[1] != P:
+ patch = np.asarray(Image.fromarray(patch.astype('uint8')).resize((P, P)), np.float32)
+ if rng.random() < 0.5: patch = patch[:, ::-1]
+ if rng.random() < 0.5: patch = patch[::-1]
+ acc[y:y+P, x:x+P] += patch * feather; wsum[y:y+P, x:x+P] += feather
+ t = np.clip(acc / np.maximum(wsum, 1e-3), 0, 255)[:H, :W].astype('uint8')
+ t = np.clip(t.astype(np.float32) * lum, 0, 255).astype('uint8')
+ return ImageEnhance.Contrast(Image.fromarray(t, 'RGB')).enhance(1.03)
+
+rows = [l.split('|') for l in subprocess.run(
+ ['psql', 'postgresql://dw_admin@127.0.0.1:5432/dw_unified', '-tAc',
+ "SELECT dw_sku, COALESCE((local_image_path::jsonb)->>0,'') FROM carl_robinson_catalog ORDER BY dw_sku"],
+ capture_output=True, text=True).stdout.splitlines() if '|' in l]
+ok = miss = 0
+for sku, img in rows:
+ sw = f'{VIEW}/{img}'
+ if not img or not os.path.exists(sw): miss += 1; print('MISS', sku); continue
+ tex = quilt(sw, TILE)
+ Image.composite(tex, base, mask).save(f'{OUT}/{sku}-real.png'); ok += 1
+print(f'REAL-COMPOSITE BATCH: {ok} rooms (tile {TILE}px), missing={miss} -> {OUT}/*-real.png')
diff --git a/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/compose_real.py b/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/compose_real.py
new file mode 100644
index 00000000..8115c59b
--- /dev/null
+++ b/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/compose_real.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python3
+# Real-swatch room composite at TRUE physical scale. The swatch is a 4x6" sample shot
+# from 6" (no zoom) = true macro scale, so tile it at ~sample-size on the wall (~50px =
+# 6" on a ~10ft wall, ~20 repeats), NOT one giant swatch. Full-wall coverage via mask;
+# multiply by the room's own luminance so the paper inherits real lighting. $0.
+import sys
+from PIL import Image, ImageEnhance
+import numpy as np
+
+SW = sys.argv[1] if len(sys.argv) > 1 else '/tmp/carl-robinson-viewer/img/GRS-100020.jpg'
+TILE = int(sys.argv[2]) if len(sys.argv) > 2 else 50 # px per sample repeat
+OUT = sys.argv[3] if len(sys.argv) > 3 else f'/tmp/cr-room-bakeoff/D-real-{TILE}.png'
+BASE = '/tmp/cr-room-bakeoff/00-empty-room.png'
+MASK = '/tmp/cr-room-bakeoff/wall-mask.png'
+
+base = Image.open(BASE).convert('RGB'); W, H = base.size
+mask = Image.open(MASK).convert('L').resize((W, H))
+# RANDOMIZED PATCH QUILT: stitch many random, flipped, feather-blended crops sampled
+# from the real sample into a large NON-repeating field. No grid, no mirror symmetry —
+# preserves the sample's exact texture, color and physical scale. Deterministic per SKU.
+import hashlib
+src = Image.open(SW).convert('RGB'); s0 = min(src.size); mm = int(s0 * 0.12)
+src = src.crop((mm, mm, src.size[0]-mm, src.size[1]-mm))
+# scale the whole sample so that "TILE px on the wall" == the sample's real macro scale
+scale = (TILE * 3) / min(src.size) # patches drawn ~TILE from a 3xTILE sample
+src = src.resize((max(1, int(src.size[0]*scale)), max(1, int(src.size[1]*scale))), Image.LANCZOS)
+S = np.asarray(src, np.float32); SH, SW_ = S.shape[0], S.shape[1]
+rng = np.random.default_rng(int(hashlib.md5(SW.encode()).hexdigest(), 16) % (2**32))
+
+P = TILE # patch size on the wall
+ov = max(6, P // 3) # overlap band
+step = P - ov
+# raised-cosine feather so overlapping patches blend without seams
+wx = np.hanning(P)[None, :]; wy = np.hanning(P)[:, None]
+feather = np.clip(wy * wx, 1e-3, 1)[..., None]
+acc = np.zeros((H + P, W + P, 3), np.float32); wsum = np.zeros((H + P, W + P, 1), np.float32)
+for y in range(0, H, step):
+ for x in range(0, W, step):
+ cy = rng.integers(0, max(1, SH - P)); cx = rng.integers(0, max(1, SW_ - P))
+ patch = S[cy:cy+P, cx:cx+P]
+ if patch.shape[0] != P or patch.shape[1] != P:
+ patch = np.asarray(Image.fromarray(patch.astype('uint8')).resize((P, P)), np.float32)
+ if rng.random() < 0.5: patch = patch[:, ::-1] # random H flip
+ if rng.random() < 0.5: patch = patch[::-1] # random V flip
+ acc[y:y+P, x:x+P] += patch * feather; wsum[y:y+P, x:x+P] += feather
+tiled = np.clip(acc / np.maximum(wsum, 1e-3), 0, 255)[:H, :W].astype('uint8')
+tiled = Image.fromarray(tiled, 'RGB')
+
+# inherit the room's lighting: multiply texture by normalized wall luminance
+lum = np.asarray(base.convert('L'), dtype=np.float32) / 255.0
+lum = np.clip(0.60 + 0.70 * lum, 0.4, 1.2)[..., None]
+tex = np.clip(np.asarray(tiled, np.float32) * lum, 0, 255).astype('uint8')
+tex = ImageEnhance.Contrast(Image.fromarray(tex, 'RGB')).enhance(1.03)
+
+# composite only where the wall mask is white (around furniture)
+out = Image.composite(tex, base, mask)
+out.save(OUT)
+print('wrote', OUT, f'(tile {TILE}px)')
diff --git a/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/make_wall_mask.py b/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/make_wall_mask.py
index be843f00..488656ad 100644
--- a/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/make_wall_mask.py
+++ b/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/make_wall_mask.py
@@ -10,12 +10,12 @@ W, H = room.size
# GEOMETRIC full-wall mask: everything above the floor line is wall, then knock
# out the furniture so inpaint repaints the ENTIRE visible wall (not a thin band).
# (Threshold masks left most of the wall unpainted -> blank result; geometry is robust.)
-FLOOR_Y = 715
+FLOOR_Y = 705
m = Image.new('L', (W, H), 0)
d = ImageDraw.Draw(m)
d.rectangle([0, 0, W, FLOOR_Y], fill=255) # full wall band
-d.rectangle([60, 430, 770, FLOOR_Y + 45], fill=0) # sofa
-d.rectangle([765, 470, 1010, FLOOR_Y + 45], fill=0) # side table + lamp
+d.rectangle([55, 490, 770, FLOOR_Y + 45], fill=0) # sofa (tight to actual back ~y490)
+d.rectangle([760, 505, 1015, FLOOR_Y + 45], fill=0) # side table + lamp
# light feather only (heavy blur weakens inpaint strength across the whole wall)
m = m.filter(ImageFilter.GaussianBlur(2))
m.save('/tmp/cr-room-bakeoff/wall-mask.png')
diff --git a/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/sdxl_relight.py b/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/sdxl_relight.py
new file mode 100644
index 00000000..44ccfc63
--- /dev/null
+++ b/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/sdxl_relight.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python3
+# LOW-STRENGTH img2img relight: take the real-swatch composite and only lightly refine
+# it (blend seams, add realistic light) WITHOUT reinventing the texture/color/scale.
+# strength 0.2-0.3 keeps the composite; high strength would hallucinate (like Kontext did).
+import sys, torch
+from PIL import Image
+from diffusers import StableDiffusionXLImg2ImgPipeline
+IN = sys.argv[1] if len(sys.argv) > 1 else '/tmp/cr-room-bakeoff/D-real-brick.png'
+STR = float(sys.argv[2]) if len(sys.argv) > 2 else 0.25
+OUT = sys.argv[3] if len(sys.argv) > 3 else f'/tmp/cr-room-bakeoff/F-relit-{STR}.png'
+DEV = 'mps'; DT = torch.float16
+pipe = StableDiffusionXLImg2ImgPipeline.from_pretrained(
+ 'stabilityai/stable-diffusion-xl-base-1.0', torch_dtype=DT, variant='fp16').to(DEV)
+pipe.set_progress_bar_config(disable=True)
+init = Image.open(IN).convert('RGB').resize((1024, 1024))
+prompt = ('photorealistic interior, natural grasscloth wallcovering on the wall, seamless continuous '
+ 'woven texture, soft realistic daylight and subtle shadows, high detail')
+neg = 'green, colorful pattern, floral, motif, print, cartoon, distorted, changed color, oversaturated'
+g = torch.Generator(device='cpu').manual_seed(7)
+out = pipe(prompt=prompt, negative_prompt=neg, image=init, strength=STR,
+ guidance_scale=5.0, num_inference_steps=40, generator=g).images[0]
+out.save(OUT); print('wrote', OUT, f'(strength {STR})')
← 660a9307 material envelope fix: unwrap 523 + Ultrasuede + live-theme
·
back to Designer Wallcoverings
·
Parameterize real-sample composite (CATALOG/VIEW/OUTDIR) + r 1d7baf73 →