diff --git a/src/App.tsx b/src/App.tsx index 7070898..9c6279f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -29,12 +29,12 @@ const App = () => { const [step, setStep] = useState(1); const [config, setConfig] = useState({ - drawer: { width: 300, depth: 400, height: 80 }, - wallThickness: 1.2, + drawer: { width: 100, depth: 100, height: 100 }, + wallThickness: 0.8, printerTolerance: 0.5, cornerRadius: 4, perforation: { - enabled: false, + enabled: true, shape: 'honeycomb', size: 8, gap: 2 diff --git a/src/services/geometryGenerator.ts b/src/services/geometryGenerator.ts index afafb14..35a4fff 100644 --- a/src/services/geometryGenerator.ts +++ b/src/services/geometryGenerator.ts @@ -297,82 +297,49 @@ export const createBinGeometry = ( partitions.forEach(p => { const hEff = Math.max(0.1, p.height - thickness); // Exclude only up to partition height + // Ensure solid strip around partition by adding padding to exclusion zone + const padding = (perforation?.gap ?? 2) + 1; if (p.axis === 'x') { // Runs Depth-wise (Y axis in Layout). - // Intersects Front and Back walls (which are Width-wise plates). - - // X pos on Front/Back walls: - // Partition X global: (-effectiveInnerW / 2) + (effectiveInnerW * p.offset) - // Wall plate local X: 0 to straightW. - // Wall Global X range: [-straightW/2, straightW/2]. - // Map partition global X to wall local X: - // localX = partGlobalX - (-straightW/2) = partGlobalX + straightW/2. - - // Note: straightW = width - 2*effRadius. - // effectiveInnerW = width - 2*thickness. - // These coordinate spaces are slightly different if radius > thickness. - // We should use the ACTUAL spatial intersection. + // Intersects Front and Back walls. const partGlobalX = (-effectiveInnerW / 2) + (effectiveInnerW * p.offset); const sW = width - 2 * effRadius; const localXOnWall = partGlobalX + sW / 2; - // Check if partition intersects the wall's X range - if (localXOnWall + thickness / 2 > 0 && localXOnWall - thickness / 2 < sW) { - // Check if it touches Back (min approx 0) - // Mapping check: - // If p.min (0) is at -Depth/2. And p.max (1) is at +Depth/2. - // Wall 1 is at +Depth/2. So Wall 1 contacts p.max. - // Wall 2 is at -Depth/2. So Wall 2 contacts p.min. + // Check intersection with active straight wall area + padding + if (localXOnWall + thickness / 2 + padding > 0 && localXOnWall - thickness / 2 - padding < sW) { + const zone = { + start: localXOnWall - thickness / 2 - padding, + end: localXOnWall + thickness / 2 + padding, + yMax: hEff + }; - // Let's store EXCLUSIONS per contact point. - // p.min touches Wall 2. So add to 'exclusionsWall2'. - // p.max touches Wall 1. So add to 'exclusionsWall1'. - - // I used names 'exclusionsBack' and 'exclusionsFront'. - // Let's adhere to names: - // 'Back' typically means +Z (User side) or -Z? - // In 3D graphics: Camera at +Z looking -Z. - // Objects at +Z are "Front" (Near). Objects at -Z are "Background" (Far). - // So Wall 1 (+Z) is Front. Wall 2 (-Z) is Back. - - // 'p.min' (0) -> -Z -> Back/Far Wall (Wall 2). - // 'p.max' (1) -> +Z -> Front/Near Wall (Wall 1). - - // So: - // p.min contacts Wall 2 (Back). - // p.max contacts Wall 1 (Front). - - // Array 'exclusionsBack' should store contacts for Wall 2. - // Array 'exclusionsFront' should store contacts for Wall 1. - - if ((p.min ?? 0) < 0.01) { - exclusionsBack.push({ start: localXOnWall - thickness / 2, end: localXOnWall + thickness / 2, yMax: hEff }); - } - // Check if it touches Front (max approx 1) - if ((p.max ?? 1) > 0.99) { - exclusionsFront.push({ start: localXOnWall - thickness / 2, end: localXOnWall + thickness / 2, yMax: hEff }); - } + if ((p.max ?? 1) > 0.99) exclusionsFront.push(zone); // Near + if ((p.min ?? 0) < 0.01) exclusionsBack.push(zone); // Far } } else { // p.axis === 'y' // Runs Width-wise (X axis in Layout). - // Intersects Left and Right walls (Length-wise plates). + // Intersects Left and Right walls. const partGlobalZ = (-effectiveInnerD / 2) + (effectiveInnerD * p.offset); const sD = depth - 2 * effRadius; const localXOnWall = partGlobalZ + sD / 2; - // Check if partition intersects the wall's X range (which maps to depth) - if (localXOnWall + thickness / 2 > 0 && localXOnWall - thickness / 2 < sD) { - // Check if it touches Left (min approx 0) + if (localXOnWall + thickness / 2 + padding > 0 && localXOnWall - thickness / 2 - padding < sD) { + const zone = { + start: localXOnWall - thickness / 2 - padding, + end: localXOnWall + thickness / 2 + padding, + yMax: hEff + }; + if ((p.min ?? 0) < 0.01) { - exclusionsLeft.push({ start: localXOnWall - thickness / 2, end: localXOnWall + thickness / 2, yMax: hEff }); + exclusionsLeft.push(zone); } - // Check if it touches Right (max approx 1) if ((p.max ?? 1) > 0.99) { - exclusionsRight.push({ start: localXOnWall - thickness / 2, end: localXOnWall + thickness / 2, yMax: hEff }); + exclusionsRight.push(zone); } } }