v2.1
Ship configurator updates with catalog DB included for server deploy. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
+268
-62
@@ -12,12 +12,19 @@ import {
|
||||
HINGE,
|
||||
tourillonFaceDrillDepthMm,
|
||||
DRAWER_REINFORCEMENT,
|
||||
DRAWER_RENFORT_PANEL_IXCONNECT
|
||||
DRAWER_RENFORT_PANEL_IXCONNECT,
|
||||
getBackGrooveInnerEndInsetFromBackEdgeMm
|
||||
} from './manufacturing.js';
|
||||
|
||||
/** Perçage ferrure en face — Ø8 mm (même diamètre que tourillon / Ixconnect face) */
|
||||
export const CARCASS_FERRURE_FACE_DIAMETER_MM = 8;
|
||||
|
||||
/** Axe X du trou Inbus sur le panneau qui porte le long perçage Ixconnect en chant. */
|
||||
function ixconnectInbusXFromEndMm({ endSide, widthMm, clampX }) {
|
||||
const offset = Number(CONNECTORS.ixconnect.lockScrewInbus?.offsetFromAssemblyEdgeMm) || 25;
|
||||
return clampX(endSide === 'left' ? offset : Number(widthMm) - offset);
|
||||
}
|
||||
|
||||
/** Montants / séparateurs : rangées Ixconnect jonction dessus·fond — retrait depuis bords haut/bas (mm, origine Y = bas pièce en G-code). */
|
||||
export const IXCONNECT_VERTICAL_JOINT_ROW_INSET_MM = 23;
|
||||
|
||||
@@ -32,6 +39,98 @@ export function mapJunctionXAcrossWidthMm(widthMm, xmm) {
|
||||
return clamped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Machining X is stored in finished-panel millimetres (origin = left). Saw blanks
|
||||
* (`rawCutWidthMm`) are longer; that extra sits on +X, so right-edge features
|
||||
* (montants, AXILO) look too far from the right until they are re-anchored.
|
||||
* Features within `edgeBandMm` of the finished right edge keep the same inset
|
||||
* on the workpiece; everything else stays left-origin.
|
||||
*/
|
||||
export function mapFinishedXOntoWorkpieceMm(xMm, finishedWidthMm, workpieceWidthMm, edgeBandMm = 120) {
|
||||
const x = Number(xMm) || 0;
|
||||
const fw = Math.max(0, Number(finishedWidthMm) || 0);
|
||||
const ww = Math.max(0, Number(workpieceWidthMm) || 0);
|
||||
if (ww < 0.5) return x;
|
||||
if (fw < 0.5 || Math.abs(ww - fw) < 0.05) return Math.max(0, Math.min(ww, x));
|
||||
const distRight = fw - x;
|
||||
const distLeft = x;
|
||||
if (distRight <= edgeBandMm && distRight <= distLeft + 0.05) {
|
||||
return Math.max(0, Math.min(ww, ww - distRight));
|
||||
}
|
||||
return Math.max(0, Math.min(ww, x));
|
||||
}
|
||||
|
||||
/** AXILO 78 Press-fit holes on the underside of a bottom panel. */
|
||||
export function buildAxiloFootHoleSpecsMm(piece, widthMm, heightMm) {
|
||||
const axilo = piece?.machining?.axiloFootPlates;
|
||||
if ((piece?.elementType || '') !== 'fond' || !axilo?.centers?.length) return [];
|
||||
|
||||
const finishedW = Number(piece?.widthMm) > 0 ? Number(piece.widthMm) : widthMm;
|
||||
const diameterMm = Number(axilo.holeDiameterMm) || 10;
|
||||
const depthMm = Number(axilo.holeDepthMm) || 12;
|
||||
const clampX = (v) => Math.max(0, Math.min(widthMm, Number(v) || 0));
|
||||
const clampY = (v) => Math.max(0, Math.min(heightMm, Number(v) || 0));
|
||||
const out = [];
|
||||
|
||||
for (const center of axilo.centers) {
|
||||
for (const offset of axilo.holeOffsetsFromCenterMm || []) {
|
||||
out.push({
|
||||
xMm: clampX(
|
||||
mapFinishedXOntoWorkpieceMm(
|
||||
Number(center.xMm) + Number(offset.x || 0),
|
||||
finishedW,
|
||||
widthMm
|
||||
)
|
||||
),
|
||||
yMm: clampY(Number(center.yMm) + Number(offset.y || 0)),
|
||||
diameterMm,
|
||||
depthMm,
|
||||
type: 'axilo_press_fit',
|
||||
face: 'back',
|
||||
row: center.row
|
||||
});
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/** System 32 rows; the rear row clears the back-groove zone when present. */
|
||||
export function buildSystem32HoleSpecsMm(piece, widthMm, heightMm) {
|
||||
const system32 = piece?.machining?.system32;
|
||||
if (!system32?.positions?.length) return [];
|
||||
|
||||
const finishedW = Number(piece?.widthMm) > 0 ? Number(piece.widthMm) : widthMm;
|
||||
const clampX = (v) => Math.max(0, Math.min(widthMm, Number(v) || 0));
|
||||
const clampY = (v) => Math.max(0, Math.min(heightMm, Number(v) || 0));
|
||||
const mapX = (v) => clampX(mapFinishedXOntoWorkpieceMm(v, finishedW, widthMm));
|
||||
const backClearanceMm = piece?.machining?.groove
|
||||
? getBackGrooveInnerEndInsetFromBackEdgeMm()
|
||||
: 0;
|
||||
const xRows = [
|
||||
mapX(37),
|
||||
mapX(Math.max(0, finishedW - 37 - backClearanceMm))
|
||||
];
|
||||
const diameterMm = Number(system32.holeDiameter) || 5;
|
||||
const depthMm = Number(system32.holeDepth || piece?.thicknessMm) || 12;
|
||||
const toolMode = system32.throughHole ? 'through' : 'blind';
|
||||
const out = [];
|
||||
|
||||
for (const pos of system32.positions) {
|
||||
for (const xMm of xRows) {
|
||||
out.push({
|
||||
xMm,
|
||||
yMm: clampY(pos),
|
||||
diameterMm,
|
||||
depthMm,
|
||||
type: 'system32',
|
||||
face: 'face',
|
||||
toolMode
|
||||
});
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/** Même logique que `getCarcassDowelStationsForPlan` dans cuttingEngine.js */
|
||||
export function getCarcassDowelStationsForPlan(cf, edgeLengthMm) {
|
||||
const L = Math.max(1, Number(edgeLengthMm) || 0);
|
||||
@@ -50,14 +149,22 @@ export function buildTopBottomPlanHoleSpecsMm(piece, widthMm, heightMm) {
|
||||
const out = [];
|
||||
const m = piece?.machining || {};
|
||||
const thicknessMm = Math.max(1, Number(piece?.thicknessMm) || 19);
|
||||
if (!['dessus', 'fond'].includes(piece.elementType || '')) return out;
|
||||
const et = piece.elementType || '';
|
||||
if (!['dessus', 'fond'].includes(et)) return out;
|
||||
|
||||
const clampX = (v) => Math.max(0, Math.min(widthMm, Number(v) || 0));
|
||||
const clampY = (v) => Math.max(0, Math.min(heightMm, Number(v) || 0));
|
||||
/** Largeur « caisse » (finie) pour repères jonctions — peut être < widthMm (brut CNC). */
|
||||
const refW =
|
||||
Number(piece?.widthMm) > 0 ? Math.min(widthMm, Number(piece.widthMm)) : widthMm;
|
||||
const mapX = (xmm) => clampX(mapFinishedXOntoWorkpieceMm(xmm, refW, widthMm));
|
||||
const edgeTolMm = 0.5;
|
||||
/**
|
||||
* Face d’entrée en épaisseur pour jonctions caisse (côtés / séparateurs) :
|
||||
* — dessus : sous-face (intérieur caisse) → FACE=back (MPR von unten / 3D fromBottom)
|
||||
* — fond : face supérieure (intérieur caisse) → FACE=face
|
||||
*/
|
||||
const carcassFace = et === 'dessus' ? 'back' : 'face';
|
||||
|
||||
const cf = m.carcassFasteners;
|
||||
if (cf && (cf.dowelStations?.length || cf.positionsAlongJointMm?.length)) {
|
||||
@@ -69,11 +176,15 @@ export function buildTopBottomPlanHoleSpecsMm(piece, widthMm, heightMm) {
|
||||
const zFerr = Number(cf.ferrureDepthInThicknessMm ?? CARCASS_FASTENERS.ferrureDepthInThicknessMm);
|
||||
const zFerrEdge = Number(cf.ferrureDepthAlongLengthMm ?? 46);
|
||||
|
||||
for (const xmm of jax) {
|
||||
for (let junctionIndex = 0; junctionIndex < jax.length; junctionIndex++) {
|
||||
const xmm = jax[junctionIndex];
|
||||
const rawX = clampX(xmm);
|
||||
const isEnd = rawX <= edgeTolMm || rawX >= refW - edgeTolMm;
|
||||
const explicitFaceMode = cf.junctionFaceModes?.[junctionIndex];
|
||||
const isEnd = explicitFaceMode
|
||||
? explicitFaceMode === 'end'
|
||||
: rawX <= edgeTolMm || rawX >= refW - edgeTolMm;
|
||||
const endSide = rawX <= refW / 2 ? 'left' : 'right';
|
||||
const x = clampX(mapJunctionXAcrossWidthMm(widthMm, xmm));
|
||||
const x = mapX(mapJunctionXAcrossWidthMm(refW, xmm));
|
||||
for (const st of stations) {
|
||||
const along = st.holesAlongMm || [];
|
||||
for (let hi = 0; hi < along.length; hi++) {
|
||||
@@ -87,7 +198,7 @@ export function buildTopBottomPlanHoleSpecsMm(piece, widthMm, heightMm) {
|
||||
diameterMm: dTour,
|
||||
depthMm: zTour,
|
||||
type: 'tourillon',
|
||||
face: isEnd ? 'end' : 'face',
|
||||
face: isEnd ? 'end' : carcassFace,
|
||||
...(isEnd ? { end: endSide } : {})
|
||||
});
|
||||
} else {
|
||||
@@ -98,32 +209,25 @@ export function buildTopBottomPlanHoleSpecsMm(piece, widthMm, heightMm) {
|
||||
diameterMm: CARCASS_FERRURE_FACE_DIAMETER_MM,
|
||||
depthMm: isEnd ? zFerrEdge : zFerr,
|
||||
type: 'ixconnect',
|
||||
face: isEnd ? 'end' : 'face',
|
||||
face: isEnd ? 'end' : carcassFace,
|
||||
...(isEnd ? { end: endSide } : {})
|
||||
});
|
||||
/* Trou Inbus : même règle que connecteur T–IX–T (un par Ixconnect ferrure). Sans ceci, les jeux côté rainure
|
||||
* (souvent issus de ferrures caisse seules) n’ont pas de trou violet Inbus en plan / G-code / 3D. */
|
||||
{
|
||||
/* Le Ø6 d'accès appartient au même panneau que le long Ø8 percé en chant. */
|
||||
if (isEnd) {
|
||||
const lock = CONNECTORS.ixconnect.lockScrewInbus;
|
||||
const dLock = Number(lock?.diameter) || 6;
|
||||
const zLock = Number(lock?.depth) || 9;
|
||||
const epsMm = 0.1;
|
||||
let xInbus = clampX(x);
|
||||
if (isEnd) {
|
||||
const depthAlongMm = Math.min(zFerrEdge, widthMm * 0.48, 80);
|
||||
xInbus =
|
||||
endSide === 'left'
|
||||
? depthAlongMm / 2 + epsMm
|
||||
: widthMm - depthAlongMm / 2 - epsMm;
|
||||
xInbus = clampX(xInbus);
|
||||
}
|
||||
out.push({
|
||||
xMm: xInbus,
|
||||
xMm: ixconnectInbusXFromEndMm({
|
||||
endSide,
|
||||
widthMm,
|
||||
clampX
|
||||
}),
|
||||
yMm,
|
||||
diameterMm: dLock,
|
||||
depthMm: zLock,
|
||||
type: 'ixconnect_inbus',
|
||||
face: 'face'
|
||||
face: carcassFace
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -134,7 +238,14 @@ export function buildTopBottomPlanHoleSpecsMm(piece, widthMm, heightMm) {
|
||||
|
||||
const ch = m.connectorHoles;
|
||||
const joints = ch?.ixconnectJointsAlongDepth;
|
||||
if (joints?.length) {
|
||||
/* Quand les ferrures caisse (carcassFasteners) sont déjà posées, elles portent le trio
|
||||
* T–IX–T + Inbus le long de chaque jonction. Réémettre ixconnectJointsAlongDepth
|
||||
* (motif bord avant 20/50/80) doublonne le jeu avant — d’où deux trous au centre Ixconnect. */
|
||||
const carcassOwnsHorizontalJoints =
|
||||
Array.isArray(cf?.dowelStations) && cf.dowelStations.length > 0
|
||||
? true
|
||||
: Array.isArray(cf?.positionsAlongJointMm) && cf.positionsAlongJointMm.length > 0;
|
||||
if (joints?.length && !carcassOwnsHorizontalJoints) {
|
||||
const dTour = Number(ch.tourillonDiameter || CONNECTORS.tourillonDiameter || 8);
|
||||
const zTour = tourillonFaceDrillDepthMm(thicknessMm);
|
||||
const dFace = Number(ch.faceHole?.diameter || CONNECTORS.ixconnect.faceHole.diameter || 8);
|
||||
@@ -148,14 +259,15 @@ export function buildTopBottomPlanHoleSpecsMm(piece, widthMm, heightMm) {
|
||||
* clampX(axe droit) recule sous refW−ε et la jonction droite n’est plus « extrémité » → un seul Inbus. */
|
||||
const axisNominal = Number(j.axisAcrossWidthMm) || 0;
|
||||
const rawAcross = clampX(axisNominal);
|
||||
const isEnd =
|
||||
axisNominal <= edgeTolMm || axisNominal >= refW - edgeTolMm;
|
||||
const isEnd = j.junctionFace
|
||||
? j.junctionFace === 'end'
|
||||
: axisNominal <= edgeTolMm || axisNominal >= refW - edgeTolMm;
|
||||
const endSide = rawAcross <= refW / 2 ? 'left' : 'right';
|
||||
const x = isEnd
|
||||
? rawAcross <= edgeTolMm
|
||||
? 0
|
||||
: refW
|
||||
: clampX(mapJunctionXAcrossWidthMm(widthMm, j.axisAcrossWidthMm));
|
||||
: widthMm
|
||||
: mapX(mapJunctionXAcrossWidthMm(refW, j.axisAcrossWidthMm));
|
||||
const seq = [
|
||||
{ axis: j.tourillon1Axis, d: dTour, z: isEnd ? zTourEdge : zTour, type: 'tourillon' },
|
||||
{ axis: j.ixconnectAxis, d: isEnd ? dEdge : dFace, z: isEnd ? zEdge : zFace, type: 'ixconnect' },
|
||||
@@ -170,37 +282,27 @@ export function buildTopBottomPlanHoleSpecsMm(piece, widthMm, heightMm) {
|
||||
diameterMm: h.d,
|
||||
depthMm: h.z,
|
||||
type: h.type,
|
||||
face: isEnd ? 'end' : 'face',
|
||||
face: isEnd ? 'end' : carcassFace,
|
||||
...(isEnd ? { end: endSide } : {})
|
||||
});
|
||||
}
|
||||
|
||||
/* Trou de serrage Inbus : un par Ixconnect — même (Y) que l’axe Ixconnect ; X aligné sur le centre du
|
||||
* perçage tel qu’affiché en 3D (même formule que Cnc3DViewer pour FACE=end : min(prof chant, 48 % largeur, 80 mm) / 2).
|
||||
* Sur jonction face : X = x du trio. Sur extrémité (montant) : entrée toujours face grande (perpendiculaire),
|
||||
* mais X ne peut pas rester 0/refW sinon le cylindre est sur le bord au lieu du centre du violet sur chant. */
|
||||
{
|
||||
/* Le Ø6 d'accès appartient au même panneau que le long Ø8 percé en chant. */
|
||||
if (isEnd) {
|
||||
const lock = CONNECTORS.ixconnect.lockScrewInbus;
|
||||
const dLock = Number(lock?.diameter) || 6;
|
||||
const zLock = Number(lock?.depth) || 9;
|
||||
const yIx = clampY(Number(j.ixconnectAxis));
|
||||
const epsMm = 0.1;
|
||||
let xInbus = clampX(x);
|
||||
if (isEnd) {
|
||||
const depthAlongMm = Math.min(zEdge, widthMm * 0.48, 80);
|
||||
xInbus =
|
||||
endSide === 'left'
|
||||
? depthAlongMm / 2 + epsMm
|
||||
: widthMm - depthAlongMm / 2 - epsMm;
|
||||
xInbus = clampX(xInbus);
|
||||
}
|
||||
out.push({
|
||||
xMm: xInbus,
|
||||
yMm: yIx,
|
||||
xMm: ixconnectInbusXFromEndMm({
|
||||
endSide,
|
||||
widthMm,
|
||||
clampX
|
||||
}),
|
||||
yMm: clampY(Number(j.ixconnectAxis)),
|
||||
diameterMm: dLock,
|
||||
depthMm: zLock,
|
||||
type: 'ixconnect_inbus',
|
||||
face: 'face'
|
||||
face: carcassFace
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -369,6 +471,81 @@ export function buildDrawerRenfortPanelIxconnectSpecsMm(piece, widthMm, heightMm
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Coulisses Legrabox — perçages de vissage sur montants / séparateurs.
|
||||
* Repère plan pièce : X depuis chant AVANT (origine bas-gauche), Y depuis bas panneau.
|
||||
* `machining.drawerSlideDrilling` : { holeDiameterMm, holeDepthMm, positionsXFromFrontMm,
|
||||
* cotes: { leftInnerFace: { railAxesYMm }, rightInnerFace: { railAxesYMm } },
|
||||
* separators: [{ faceTowardLowerModule: { railAxesYMm }, faceTowardHigherModule: { railAxesYMm } }] }
|
||||
* @param {number} [partIndex] — cotes: 0 = montant gauche, 1 = droit ; séparateurs: index
|
||||
*/
|
||||
export function buildLegraboxRailHoleSpecsMm(piece, widthMm, heightMm, partIndex = 0) {
|
||||
const et = piece?.elementType || '';
|
||||
const m = piece?.machining?.drawerSlideDrilling;
|
||||
if (!m?.positionsXFromFrontMm?.length) return [];
|
||||
const d = Number(m.holeDiameterMm) || 5;
|
||||
const z = Number(m.holeDepthMm) || 13;
|
||||
const clampX = (v) => Math.max(0, Math.min(widthMm, Number(v) || 0));
|
||||
const clampY = (v) => Math.max(0, Math.min(heightMm, Number(v) || 0));
|
||||
const out = [];
|
||||
|
||||
const pushFace = (axesYMm, faceKey, tag) => {
|
||||
if (!Array.isArray(axesYMm) || !axesYMm.length) return;
|
||||
for (const y of axesYMm) {
|
||||
for (const x of m.positionsXFromFrontMm) {
|
||||
out.push({
|
||||
xMm: clampX(x),
|
||||
yMm: clampY(y),
|
||||
diameterMm: d,
|
||||
depthMm: z,
|
||||
type: `legrabox_rail${tag ? `_${tag}` : ''}`,
|
||||
face: faceKey
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (et === 'cotes' && m.cotes) {
|
||||
const L = m.cotes.leftInnerFace;
|
||||
const R = m.cotes.rightInnerFace;
|
||||
const hasL = Array.isArray(L?.railAxesYMm) && L.railAxesYMm.length > 0;
|
||||
const hasR = Array.isArray(R?.railAxesYMm) && R.railAxesYMm.length > 0;
|
||||
const face = hasL && hasR ? (partIndex === 0 ? L : R) : hasL ? L : hasR ? R : null;
|
||||
pushFace(face?.railAxesYMm, 'face');
|
||||
return out;
|
||||
}
|
||||
|
||||
if (et === 'panneauxInterieurs' && Array.isArray(m.separators)) {
|
||||
const sep = m.separators[partIndex];
|
||||
if (!sep) return [];
|
||||
pushFace(sep.faceTowardLowerModule?.railAxesYMm, 'face', 'sep_lower');
|
||||
pushFace(sep.faceTowardHigherModule?.railAxesYMm, 'back', 'sep_higher');
|
||||
return out;
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Façades tiroir Legrabox — fixation INSERTA (cheville expansible Ø10, prof. 13 mm).
|
||||
* Repère plan façade : origine bas-gauche, X/Y en mm (face arrière de la façade).
|
||||
*/
|
||||
export function buildLegraboxFacadeInsertaSpecsMm(piece, widthMm, heightMm) {
|
||||
if ((piece?.elementType || '') !== 'tiroirFacade') return [];
|
||||
const ins = piece?.machining?.legraboxInserta;
|
||||
if (!ins?.holes?.length) return [];
|
||||
const d = Number(ins.holeDiameterMm) || 10;
|
||||
const z = Number(ins.holeDepthMm) || 13;
|
||||
return ins.holes.map((h) => ({
|
||||
xMm: Math.max(0, Math.min(widthMm, Number(h.xMm) || 0)),
|
||||
yMm: Math.max(0, Math.min(heightMm, Number(h.yMm) || 0)),
|
||||
diameterMm: d,
|
||||
depthMm: z,
|
||||
type: 'legrabox_inserta',
|
||||
face: 'face'
|
||||
}));
|
||||
}
|
||||
|
||||
export function buildDrawerReinforcementHoleSpecsMm(piece, widthMm, heightMm) {
|
||||
if ((piece?.elementType || '') !== 'renfortsTiroir') return [];
|
||||
const ix = piece?.machining?.drawerReinforcement?.ixconnectFixing;
|
||||
@@ -402,6 +579,19 @@ export function buildVerticalPanelIxconnectFaceHoleSpecsMm(piece, widthMm, heigh
|
||||
|
||||
const H = Math.max(1, Number(heightMm) || 1);
|
||||
const W = Math.max(1, Number(widthMm) || 1);
|
||||
const finishedW =
|
||||
Number(piece?.widthMm) > 0 ? Math.min(W, Number(piece.widthMm)) : W;
|
||||
const backClearanceMm =
|
||||
et === 'cotes' && piece?.machining?.groove
|
||||
? getBackGrooveInnerEndInsetFromBackEdgeMm()
|
||||
: 0;
|
||||
const backReferenceMm = Math.max(0, finishedW - backClearanceMm);
|
||||
const mapAxisX = (axisMm) =>
|
||||
mapFinishedXOntoWorkpieceMm(
|
||||
mapJunctionXAcrossWidthMm(finishedW, axisMm),
|
||||
finishedW,
|
||||
W
|
||||
);
|
||||
const inset = IXCONNECT_VERTICAL_JOINT_ROW_INSET_MM;
|
||||
if (H < 2 * inset + 5) return out;
|
||||
|
||||
@@ -420,9 +610,9 @@ export function buildVerticalPanelIxconnectFaceHoleSpecsMm(piece, widthMm, heigh
|
||||
const t2 = Number(p.tourillon2Axis);
|
||||
const ix = Number(p.ixconnectAxis);
|
||||
const mirrorBack =
|
||||
W >= IXCONNECT_SEPARATOR_BACK_ROW_MIN_WIDTH_MM && t2 > t1;
|
||||
finishedW >= IXCONNECT_SEPARATOR_BACK_ROW_MIN_WIDTH_MM && t2 > t1;
|
||||
|
||||
if (et === 'panneauxInterieurs') {
|
||||
if (et === 'panneauxInterieurs' || (et === 'cotes' && ch.verticalJointMode === 'edge')) {
|
||||
const seqFront = [
|
||||
{ axis: t1, d: dTour, z: zTourEdge, type: 'tourillon' },
|
||||
{ axis: ix, d: dEdge, z: zIxEdge, type: 'ixconnect' },
|
||||
@@ -430,16 +620,21 @@ export function buildVerticalPanelIxconnectFaceHoleSpecsMm(piece, widthMm, heigh
|
||||
];
|
||||
const seqBack = mirrorBack
|
||||
? [
|
||||
{ axis: W - t2, d: dTour, z: zTourEdge, type: 'tourillon' },
|
||||
{ axis: W - ix, d: dEdge, z: zIxEdge, type: 'ixconnect' },
|
||||
{ axis: W - t1, d: dTour, z: zTourEdge, type: 'tourillon' }
|
||||
{ axis: backReferenceMm - t2, d: dTour, z: zTourEdge, type: 'tourillon' },
|
||||
{ axis: backReferenceMm - ix, d: dEdge, z: zIxEdge, type: 'ixconnect' },
|
||||
{ axis: backReferenceMm - t1, d: dTour, z: zTourEdge, type: 'tourillon' }
|
||||
]
|
||||
: null;
|
||||
|
||||
const lock = CONNECTORS.ixconnect.lockScrewInbus;
|
||||
const dLock = Number(lock?.diameter) || 6;
|
||||
const zLock = Number(lock?.depth) || 9;
|
||||
const inbusOffset = Number(lock?.offsetFromAssemblyEdgeMm) || 25;
|
||||
const pushEndRow = (yMm, seq, endSide) => {
|
||||
const cy = clampY(yMm);
|
||||
const inbusY = clampY(endSide === 'bottom' ? inbusOffset : H - inbusOffset);
|
||||
for (const h of seq) {
|
||||
const xMm = mapJunctionXAcrossWidthMm(W, Number(h.axis));
|
||||
const xMm = mapAxisX(Number(h.axis));
|
||||
out.push({
|
||||
xMm,
|
||||
yMm: cy,
|
||||
@@ -449,6 +644,16 @@ export function buildVerticalPanelIxconnectFaceHoleSpecsMm(piece, widthMm, heigh
|
||||
face: 'end',
|
||||
end: endSide
|
||||
});
|
||||
if (h.type === 'ixconnect') {
|
||||
out.push({
|
||||
xMm,
|
||||
yMm: inbusY,
|
||||
diameterMm: dLock,
|
||||
depthMm: zLock,
|
||||
type: 'ixconnect_inbus',
|
||||
face: 'face'
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -460,7 +665,8 @@ export function buildVerticalPanelIxconnectFaceHoleSpecsMm(piece, widthMm, heigh
|
||||
return out;
|
||||
}
|
||||
|
||||
/* cotes : face */
|
||||
/* cotes sans habillage latéral : logement face uniquement.
|
||||
* L'accès Inbus est sur la pièce opposée qui porte le long perçage en chant. */
|
||||
const seqFront = [
|
||||
{ axis: t1, d: dTour, z: zTour, type: 'tourillon' },
|
||||
{ axis: ix, d: dFace, z: zFace, type: 'ixconnect' },
|
||||
@@ -468,15 +674,15 @@ export function buildVerticalPanelIxconnectFaceHoleSpecsMm(piece, widthMm, heigh
|
||||
];
|
||||
const seqBack = mirrorBack
|
||||
? [
|
||||
{ axis: W - t2, d: dTour, z: zTour, type: 'tourillon' },
|
||||
{ axis: W - ix, d: dFace, z: zFace, type: 'ixconnect' },
|
||||
{ axis: W - t1, d: dTour, z: zTour, type: 'tourillon' }
|
||||
{ axis: backReferenceMm - t2, d: dTour, z: zTour, type: 'tourillon' },
|
||||
{ axis: backReferenceMm - ix, d: dFace, z: zFace, type: 'ixconnect' },
|
||||
{ axis: backReferenceMm - t1, d: dTour, z: zTour, type: 'tourillon' }
|
||||
]
|
||||
: null;
|
||||
const pushFaceRow = (yMm, seq) => {
|
||||
const cy = clampY(yMm);
|
||||
for (const h of seq) {
|
||||
const xMm = mapJunctionXAcrossWidthMm(W, Number(h.axis));
|
||||
const xMm = mapAxisX(Number(h.axis));
|
||||
out.push({
|
||||
xMm,
|
||||
yMm: cy,
|
||||
@@ -487,10 +693,10 @@ export function buildVerticalPanelIxconnectFaceHoleSpecsMm(piece, widthMm, heigh
|
||||
});
|
||||
}
|
||||
};
|
||||
for (const yMm of yRows) {
|
||||
pushFaceRow(yMm, seqFront);
|
||||
if (seqBack) pushFaceRow(yMm, seqBack);
|
||||
}
|
||||
pushFaceRow(yRows[0], seqFront);
|
||||
if (seqBack) pushFaceRow(yRows[0], seqBack);
|
||||
pushFaceRow(yRows[1], seqFront);
|
||||
if (seqBack) pushFaceRow(yRows[1], seqBack);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user