"use strict"
const reinforcedRectInit = ({ jscad, swcadJs }) => {
const {
square,
circle,
} = jscad.primitives
const {
translate,
} = jscad.transforms
const {
union,
} = jscad.booleans
const {
hull,
hullChain
} = jscad.hulls
const {
math,
} = swcadJs.calcs
const {
standards,
} = swcadJs.data
const {
reinforcement,
} = swcadJs.calcs.geometry
//==============================================================================
/**
* Builds default values and opts for the model
* @param {*} opts
* @returns default values and opts
* @memberof reinforcedRect
* @access private
*/
const reinforcedRectDefaults = () => {
/** Specific value declarations */
const defaultValues = {
constants: {
reinforcementPatterns: ['x', 'cross', 'diamond', 'full'],
},
dims: {
size: [
math.inchesToMm(3),
math.inchesToMm(4),
],
reinforcementThickness: [
standards.LG_REINFORCEMENT_WIDTH,
standards.MD_REINFORCEMENT_WIDTH,
standards.SM_REINFORCEMENT_WIDTH,
],
},
points: {
centrePt: [0, 0, 0]
},
types: {
default: standards.types.TYPE_DEFAULT,
alt: standards.types.TYPE_ALT,
},
}
/** Options used by SW models */
const standardOpts = {
type: defaultValues.types.default.id,
scale: 1,
interfaceThickness: standards.INTERFACE_THICKNESS,
fitGap: standards.FIT_GAP,
}
/** Computed values for option defaults */
const defaultOpts = {
...standardOpts,
size: defaultValues.dims.size,
reinforcementPattern: defaultValues.constants.reinforcementPatterns[0],
reinforcementThickness: defaultValues.dims.reinforcementThickness,
}
return {
opts: defaultOpts,
vals: defaultValues,
}
}
//------------------------------------------------------------------------------
/**
* Initializes options with user input
* @param {*} opts
* @returns model properties
* @memberof reinforcedRect
* @access private
*/
const reinforcedRectOpts = (opts) => {
const defaults = reinforcedRectDefaults()
// User options
const {
size = defaults.opts.size,
reinforcementPattern = defaults.opts.reinforcementPattern,
reinforcementThickness = defaults.opts.reinforcementThickness,
type = defaults.opts.type,
scale = defaults.opts.scale,
interfaceThickness = defaults.opts.interfaceThickness,
fitGap = defaults.opts.fitGap,
} = opts
const stdOpts = {
type,
scale,
interfaceThickness,
fitGap,
}
const initOpts = {
size,
reinforcementPattern,
reinforcementThickness,
...stdOpts,
}
return initOpts
}
//------------------------------------------------------------------------------
/**
* Builds model properties from the given opts
* @param {*} opts
* @returns model properties
* @memberof reinforcedRect
* @access private
*/
const reinforcedRectProps = (opts) => {
const defaults = reinforcedRectDefaults()
const {
size,
reinforcementPattern,
reinforcementThickness,
type,
scale,
interfaceThickness,
fitGap,
} = opts
/* ----------------------------------------
* Prop calculations
* ------------------------------------- */
const width = size[0]
const depth = size[1]
let rThickness = [
defaults.vals.dims.reinforcementThickness,
defaults.vals.dims.reinforcementThickness,
defaults.vals.dims.reinforcementThickness,
]
if (typeof reinforcementThickness == 'number') {
rThickness = [
reinforcementThickness,
reinforcementThickness,
reinforcementThickness,
]
} else if (Array.isArray(reinforcementThickness)) {
if (reinforcementThickness.length == 3 && typeof reinforcementThickness[0] == 'number') {
rThickness = [
reinforcementThickness[0],
reinforcementThickness[1],
reinforcementThickness[2],
]
}
if (reinforcementThickness.length == 2 && typeof reinforcementThickness[0] == 'number') {
rThickness = [
reinforcementThickness[0],
reinforcementThickness[1],
reinforcementThickness[1],
]
}
}
const reinforcementDataSize = [
size[0] - reinforcementThickness[0],
size[1] - reinforcementThickness[0],
]
const reinforcementData = reinforcement.reinforcedRectangle({
size: reinforcementDataSize,
reinforcementPattern: reinforcementPattern,
})
const reinforcementNodes = [
circle({ radius: rThickness[0] / 2 }),
circle({ radius: rThickness[1] / 2 }),
circle({ radius: rThickness[2] / 2 }),
]
const cornerNode = square({ size: rThickness[0] })
/* ----------------------------------------
* Preparing Model Properties, Dimensions
* ------------------------------------- */
/** Constant values for model */
const modelConstants = {
}
/** Derived user options for the model */
const modelOpts = {
type,
scale,
reinforcementPattern,
}
/** Various dimensions for model */
const modelDims = {
size,
width,
depth,
reinforcementThickness: rThickness,
interfaceThickness,
fitGap,
}
/** Various key points for model */
const modelPoints = {
centrePt: defaults.vals.points.centrePt,
...reinforcementData.points,
}
/** Components used by model */
const modelComponents = {
reinforcementNodes,
cornerNode,
}
/* ---------------------------------------------
* Model Properties
* ----------------------------------------------
* Properties accessible to all model functions.
* --------------------------------------------- */
const modelProperties = {
metadata: {
id: '9999',
name: 'New Model',
project: 'New Project',
author: 'Somebody Somewhere',
organization: 'Salvador Workshop',
client: null,
},
constants: modelConstants,
opts: modelOpts,
dims: modelDims,
points: modelPoints,
components: modelComponents,
}
return modelProperties
}
//------------------------------------------------------------------------------
/**
* Reinforced rectangle
* @param {*} opts
* @returns Array with model, parts, and properties: [`geom3`, `Object.<string, geom3>`, `Object.<string, any>`]
* @memberof profiles.shapes.rectangle
*/
const reinforcedRect = (opts) => {
const defaults = reinforcedRectDefaults()
const initOpts = reinforcedRectOpts(opts)
const modelProperties = reinforcedRectProps(initOpts)
/* ----------------------------------------
* Modelling, Component/Assembly Modules
* ------------------------------------- */
const rectOutline = (modelProps) => {
const {
corners,
} = modelProps.points
const {
cornerNode,
} = modelProps.components
const hullPts = corners
hullPts.push(hullPts[0])
const hullNodes = hullPts.map(hullPt => {
return translate([hullPt[0], hullPt[1], 0], cornerNode)
})
return hullChain(hullNodes)
}
const rectPrimaryBracing = (modelProps) => {
const {
primaryLines,
} = modelProps.points
const {
reinforcementNodes,
} = modelProps.components
let returnBracing = null
const braceLines = primaryLines.map(pLine => {
const lineStartPt = pLine[0]
const lineEndPt = pLine[1]
const nodeStart = translate(lineStartPt, reinforcementNodes[1])
const nodeEnd = translate(lineEndPt, reinforcementNodes[1])
return hull(nodeStart, nodeEnd)
})
if (braceLines.length > 0) {
returnBracing = union(...braceLines)
}
return braceLines
}
const rectSecondaryBracing = (modelProps) => {
const {
secondaryLines,
} = modelProps.points
const {
reinforcementNodes,
} = modelProps.components
let returnBracing = null
const braceLines = secondaryLines.map(pLine => {
const lineStartPt = pLine[0]
const lineEndPt = pLine[1]
const nodeStart = translate(lineStartPt, reinforcementNodes[2])
const nodeEnd = translate(lineEndPt, reinforcementNodes[2])
return hull(nodeStart, nodeEnd)
})
if (braceLines.length > 0) {
returnBracing = union(...braceLines)
}
return braceLines
}
/* ----------------------------------------
* Complete Assembly
* ------------------------------------- */
/** Final Assembly */
const finalAssembly = (modelProps) => {
const rectOutlineInst = rectOutline(modelProps)
const rectPrimaryBracingInst = rectPrimaryBracing(modelProperties)
const rectSecondaryBracingInst = rectSecondaryBracing(modelProperties)
let finalShape = rectOutlineInst
if (rectPrimaryBracingInst) {
finalShape = union(finalShape, rectPrimaryBracingInst)
}
if (rectSecondaryBracingInst) {
finalShape = union(finalShape, rectSecondaryBracingInst)
}
return finalShape
}
/* ----------------------------------------
* Outputs
* ------------------------------------- */
const rectOutlineInst = rectOutline(modelProperties)
const rectPrimaryBracingInst = rectPrimaryBracing(modelProperties)
const rectSecondaryBracingInst = rectSecondaryBracing(modelProperties)
let mainModel = finalAssembly(modelProperties)
let modelParts = {
rectOutline: rectOutlineInst,
rectPrimaryBracing: rectPrimaryBracingInst,
rectSecondaryBracing: rectSecondaryBracingInst,
}
return [mainModel, modelParts, modelProperties]
}
return reinforcedRect
}
module.exports = {
init: reinforcedRectInit
}