v0.7.0: exports voor CAD, BIM en renders (Bestand › Exporteren, los van Opslaan/Ctrl+S): CAD (DXF R12, plattegrond met wanden/sparingen/gevelbekleding/kozijnen met draaicirkel, ruimtes, inrichting, dakrand, elektra en echte maatvoering, plus vier gevels als lijntekening met verborgen lijnen weg; lagen PL-/AZ-, 1:1 mm, afgestemd op 1:50; in CAD op te slaan als DWG), BIM (IFC4 met alleen de bouwconstructie: stijlen, regels, vloer- en dakbalken, stalen nokbalk, palen, spaanplaat/OSB/cementplaat en elektra per leiding, gegroepeerd per unit en element met Pset_Tectum en kleur per soort) en Render (OBJ + MTL + texturen in een ZIP voor Blender, volledige afgewerkte woning, kleuren lineair, PBR); schoorsteen tegen een buitenwand (ChimneyModel: sparing in wand en dak met raveelwerk, steenstrip/stuc, verslepen langs de gevel); kozijnen koppelen met een eigen schakelaar; kozijnindeling (deurblad, zij-/bovenlicht, schuifbladen) gedeeld tussen 3D, plattegrond en aanzicht
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
86fcd57b96
commit
adb3c74f85
@@ -0,0 +1,70 @@
|
||||
/*!
|
||||
* Tectum
|
||||
* Copyright © 2026 Machiel Heinen.
|
||||
* Alle rechten voorbehouden. Gebruik uitsluitend met schriftelijke toestemming.
|
||||
* Zie LICENTIE.md.
|
||||
*/
|
||||
// ZIP zonder compressie (stored): meerdere bestanden in één download.
|
||||
|
||||
window.ZipWriter = (() => {
|
||||
const CRC = new Uint32Array(256);
|
||||
for (let n = 0; n < 256; n++) {
|
||||
let c = n;
|
||||
for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
|
||||
CRC[n] = c >>> 0;
|
||||
}
|
||||
function crc32(parts) {
|
||||
let c = 0xffffffff;
|
||||
parts.forEach(b => { for (let i = 0; i < b.length; i++) c = CRC[(c ^ b[i]) & 0xff] ^ (c >>> 8); });
|
||||
return (c ^ 0xffffffff) >>> 0;
|
||||
}
|
||||
|
||||
// files: [{ name, data: Uint8Array | Uint8Array[] }]
|
||||
function build(files) {
|
||||
const enc = new TextEncoder();
|
||||
const out = [], central = [];
|
||||
let offset = 0;
|
||||
const d = new Date();
|
||||
const time = (d.getHours() << 11) | (d.getMinutes() << 5) | (d.getSeconds() >> 1);
|
||||
const date = ((d.getFullYear() - 1980) << 9) | ((d.getMonth() + 1) << 5) | d.getDate();
|
||||
files.forEach(f => {
|
||||
const parts = Array.isArray(f.data) ? f.data : [f.data];
|
||||
const size = parts.reduce((a, b) => a + b.length, 0);
|
||||
const name = enc.encode(f.name), crc = crc32(parts);
|
||||
const head = (sig, extra) => {
|
||||
const h = new DataView(new ArrayBuffer(extra ? 46 : 30));
|
||||
let p = 0;
|
||||
const u32 = (v) => { h.setUint32(p, v, true); p += 4; }, u16 = (v) => { h.setUint16(p, v, true); p += 2; };
|
||||
u32(sig);
|
||||
if (extra) u16(20);
|
||||
u16(20); u16(0x0800); u16(0); u16(time); u16(date); u32(crc); u32(size); u32(size); u16(name.length); u16(0);
|
||||
if (extra) { u16(0); u16(0); u16(0); u32(0); u32(offset); }
|
||||
return new Uint8Array(h.buffer);
|
||||
};
|
||||
const local = head(0x04034b50, false);
|
||||
central.push(head(0x02014b50, true), name);
|
||||
out.push(local, name, ...parts);
|
||||
offset += local.length + name.length + size;
|
||||
});
|
||||
const cdSize = central.reduce((a, b) => a + b.length, 0);
|
||||
const end = new DataView(new ArrayBuffer(22));
|
||||
end.setUint32(0, 0x06054b50, true);
|
||||
end.setUint16(8, files.length, true); end.setUint16(10, files.length, true);
|
||||
end.setUint32(12, cdSize, true); end.setUint32(16, offset, true);
|
||||
return out.concat(central, [new Uint8Array(end.buffer)]);
|
||||
}
|
||||
|
||||
function save(files, filename) {
|
||||
const blob = new Blob(build(files), { type: 'application/zip' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = filename;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
return { build, save };
|
||||
})();
|
||||
Reference in New Issue
Block a user