"use strict"
/**
* ...
* @namespace builders.entryways
*/
const entrywayBuilder = ({ lib, swLib }) => {
const { union, subtract, intersect } = lib.booleans;
const { translate, rotate, mirror } = lib.transforms;
const { cuboid } = lib.primitives;
const { measureDimensions } = lib.measurements;
const { extrudeLinear } = lib.extrusions
const { hull } = lib.hulls
const {
arches,
walls,
} = swLib.builders
return {
/**
* Builds a gothic entryway.
* @memberof builders.entryways
* @instance
* @param {Object} opts
* @param {number} opts.wallLength
* @param {number} opts.wallThickness
* @param {number} opts.wallHeight
* @param {number} opts.entryLength
* @param {number} opts.trimUnitHeight
* @param {number} opts.trimUnitDepth
* @param {number} opts.crownUnits
* @param {number} opts.dadoHeight
* @param {number} opts.dadoUnits
* @param {number} opts.baseUnits
* @param {number} opts.wallOpts
* @param {number} opts.trimSides
* @param {string[]} opts.trimOpts - ['base', 'dado', 'crown']
* @param {string[]} opts.entryOpts
* @param {number} opts.archRadFactor - arch radius factor
* @returns Entryway geometry
*/
buildGothicEntryway: (opts) => {
const wallSpace = opts.wallLength - opts.entryLength;
const wall1Specs = [wallSpace / 2, opts.wallThickness, opts.wallHeight];
const wall2Specs = [wallSpace / 2, opts.wallThickness, opts.wallHeight];
const topWallSpecs = [opts.wallLength, opts.wallThickness, opts.wallHeight];
const trimUnits = walls.verifyTrimUnits({
trimOpts: opts.trimOpts,
baseUnits: opts.baseUnits,
dadoUnits: opts.dadoUnits,
crownUnits: opts.crownUnits,
})
const wall1 = walls.buildWall({
height: wall1Specs[2],
thickness: wall1Specs[1],
length: wall1Specs[0],
// wallOpts: 0,
half: 'lower',
trimOpts: opts.trimOpts,
baseUnits: trimUnits.baseUnits,
dadoUnits: trimUnits.dadoUnits,
crownUnits: trimUnits.crownUnits,
dadoHeight: opts.dadoHeight,
trimUnitHeight: opts.trimUnitHeight,
trimUnitDepth: opts.trimUnitDepth,
});
const wall1Dims = measureDimensions(wall1);
console.log(wall1Dims);
const wall2 = walls.buildWall({
height: wall2Specs[2],
thickness: wall2Specs[1],
length: wall2Specs[0],
half: 'lower',
trimOpts: opts.trimOpts,
baseUnits: trimUnits.baseUnits,
dadoUnits: trimUnits.dadoUnits,
crownUnits: trimUnits.crownUnits,
dadoHeight: opts.dadoHeight,
trimUnitHeight: opts.trimUnitHeight,
trimUnitDepth: opts.trimUnitDepth,
});
const topWall = walls.buildWall({
height: topWallSpecs[2],
thickness: topWallSpecs[1],
length: topWallSpecs[0],
half: 'upper',
trimOpts: opts.trimOpts,
baseUnits: trimUnits.baseUnits,
dadoUnits: trimUnits.dadoUnits,
crownUnits: trimUnits.crownUnits,
dadoHeight: opts.dadoHeight,
trimUnitHeight: opts.trimUnitHeight,
trimUnitDepth: opts.trimUnitDepth,
});
let archTrimProfile = walls.getEntryTrimForDadoUnits({
dadoUnits: trimUnits.dadoUnits,
trimUnitHeight: opts.trimUnitHeight,
trimUnitDepth: opts.trimUnitDepth,
});
archTrimProfile = rotate([0, 0, Math.PI * 1.5], archTrimProfile);
const archTrimProfileSpecs = measureDimensions(archTrimProfile);
console.log(`archTrimProfileSpecs = ${archTrimProfileSpecs}`)
const archRadFactor = opts.archRadFactor || 0.75;
const thinWallThickness = opts.wallThickness - (archTrimProfileSpecs[1] * 2);
const trimArch = arches.twoPtArch({ arcRadius: opts.entryLength * archRadFactor, archWidth: opts.entryLength, profileWidth: 5 }, archTrimProfile);
const adjTrimArch = translate([0, (thinWallThickness + archTrimProfileSpecs[1]) / 2, wall1Dims[2]], trimArch);
const adjTrimArchOpp = mirror({ normal: [0, 1, 0] }, adjTrimArch);
const trimArchDims = measureDimensions(trimArch);
const innerOpeningSpecs = [opts.entryLength, 5 * opts.wallThickness, null];
const innerOpeningProfile = arches.twoPtArch({ arcRadius: innerOpeningSpecs[0] * archRadFactor, archWidth: innerOpeningSpecs[0] });
const innerOpening = rotate([Math.PI / 2, 0, 0], extrudeLinear({ height: innerOpeningSpecs[1] }, innerOpeningProfile));
const adjInnerOpening = translate([0, innerOpeningSpecs[1] / 2, wall1Dims[2]], innerOpening);
const trimOpeningSpecs = [
archTrimProfileSpecs[0] * 2 + opts.entryLength,
4 * opts.wallThickness,
wall1Dims[2] + trimArchDims[2]
];
const trimOpening = hull([
translate([0, trimOpeningSpecs[1] / -2, 0], adjTrimArch),
translate([0, trimOpeningSpecs[1] / 2, 0], adjTrimArch),
]);
const adjTrimOpening = translate([0, 0, 0], trimOpening);
const thinWall = intersect(
translate([0, 0, opts.wallHeight / 2], cuboid({
size: [
opts.wallLength,
thinWallThickness,
opts.wallHeight,
]
})),
topWall,
);
let punchedTopWall = subtract(topWall, adjInnerOpening);
if (opts.trimOpts.includes('dado')) {
punchedTopWall = subtract(punchedTopWall, adjTrimOpening);
punchedTopWall = union(punchedTopWall, thinWall);
punchedTopWall = subtract(punchedTopWall, adjInnerOpening);
}
const wallAdj = wallSpace / 4 + (opts.entryLength / 2)
const trimArches = union(
adjTrimArch,
adjTrimArchOpp,
)
const entryway = union(
translate([-wallAdj, 0, 0], wall1),
translate([wallAdj, 0, 0], wall2),
translate([0, 0, 0], punchedTopWall),
);
return union(entryway, trimArches);
}
};
}
module.exports = { init: entrywayBuilder }