Deploy App / deploy (push) Successful in 28s
Nach erneutem Detailstudium des Gartenplans und der Referenzbilder darin: - Sichtschutz ist nicht durchgehend: 28 aufrechte Travertinstelen (50x6 cm, Dreiergruppen, Positionen direkt aus dem Plan) wechseln sich mit Eibengruppen ab, alle in einem Dekorkiesbett. Hoehe 1.80 m gegen den Suednachbarn, 1.50 m gegen Zollet auf der unteren Ebene. - Zwei schwebende Travertinstufen fuehren vom gedeckten Sitzplatz (-0.02) auf den Hauptsitzplatz hinunter, als auskragende Platten mit Schattenfuge. - Hoehenprofil auf zwei klare Ebenen gebracht: untere Ebene -0.33, Travertinsitzmauer mit 31 cm Ansicht, obere Ebene -0.02. Die Niveaus stehen fest in LEVELS statt aus streuenden Koten geschaetzt zu werden. - Jede Hoehenkote gehoert neu zu genau einer Flaeche, der kleinsten, die sie enthaelt - sonst kippen benachbarte Ebenen ineinander. - Der schmale Streifen am Sichtschutz ist Kiesbett, nicht Plattenbelag. - Travertin nach den Referenzbildern deutlich heller, eigene Steintextur fuer die Stelen; Flammengrill als Stahlkubus mit Holzfach und Feueroeffnung. - Stirnflaechen der Hecken hatten entartete UVs und zeigten Strahlenmuster. - tools/plan-bilder.mjs zieht die Referenzfotos aus dem Plan-PDF. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
39 lines
1.8 KiB
JavaScript
39 lines
1.8 KiB
JavaScript
/**
|
|
* Zieht die Referenzfotos aus dem Gartenplan-PDF (Mauerwerk, schwebende Stufen,
|
|
* Travertin, Flammengrill, Eibenhecke). Sie sind die Vorlage fuer die
|
|
* Materialisierung in der Szene.
|
|
*
|
|
* Aufruf: node tools/plan-bilder.mjs [Zielordner]
|
|
*/
|
|
import * as mupdf from 'mupdf'; import fs from 'fs';
|
|
import path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const PDF = path.join(__dirname, '..', 'Info Dateien', 'Gartenplan 1 Jasmin und Damian Kellenberger.pdf');
|
|
const OUT = process.argv[2] ?? path.join(__dirname, 'out', 'planbilder');
|
|
fs.mkdirSync(OUT, { recursive: true });
|
|
const doc = mupdf.Document.openDocument(fs.readFileSync(PDF),'application/pdf');
|
|
const page = doc.loadPage(0);
|
|
let n=0;
|
|
const noop=()=>{};
|
|
const dev = new mupdf.Device({
|
|
fillImage: (img, ctm, alpha) => {
|
|
n++;
|
|
const w = img.getWidth(), h = img.getHeight();
|
|
// Platzierung auf dem Blatt aus der Matrix
|
|
const x = ctm[4], y = ctm[5], sx = Math.hypot(ctm[0],ctm[1]), sy = Math.hypot(ctm[2],ctm[3]);
|
|
console.log(`Bild ${n}: ${w}x${h}px auf Blatt bei (${x.toFixed(0)}, ${(y-sy).toFixed(0)}) Groesse ${sx.toFixed(0)}x${sy.toFixed(0)}pt`);
|
|
try {
|
|
const pix = img.toPixmap();
|
|
fs.writeFileSync(path.join(OUT, `planbild-${n}.png`), pix.asPNG());
|
|
} catch (e) { console.log(' (nicht extrahierbar)', e.message); }
|
|
},
|
|
fillPath: noop, strokePath: noop, fillShade: noop, fillImageMask: noop,
|
|
clipPath: noop, clipStrokePath: noop, clipImageMask: noop, popClip: noop,
|
|
fillText: noop, strokeText: noop, clipText: noop, clipStrokeText: noop, ignoreText: noop,
|
|
beginMask: noop, endMask: noop, beginGroup: noop, endGroup: noop,
|
|
beginTile: () => 0, endTile: noop, beginLayer: noop, endLayer: noop, close: noop,
|
|
});
|
|
page.run(dev, mupdf.Matrix.identity);
|
|
dev.close();
|