13
This commit is contained in:
@@ -2,48 +2,6 @@ import * as THREE from 'three';
|
||||
import { STLExporter, mergeBufferGeometries } from 'three-stdlib';
|
||||
import { AppConfig, LayoutSplits, GeneratedPart, Partition } from '../types';
|
||||
|
||||
type Limits = { min: number; max: number };
|
||||
type LimitMap = Record<string, Limits>;
|
||||
|
||||
// --- SOLVER: Итеративный расчет границ (Улучшенный) ---
|
||||
const solveWallLimits = (partitions: Partition[]): LimitMap => {
|
||||
const limits: LimitMap = {};
|
||||
// 1. Инициализация
|
||||
partitions.forEach(p => { limits[p.id] = { min: 0, max: 1 }; });
|
||||
|
||||
// 2. Итерации (4 прохода для стабилизации сложных вложений)
|
||||
for (let pass = 0; pass < 4; pass++) {
|
||||
partitions.forEach(target => {
|
||||
let newMin = 0;
|
||||
let newMax = 1;
|
||||
const center = target.offset;
|
||||
|
||||
partitions.forEach(obstacle => {
|
||||
if (target.id === obstacle.id) return;
|
||||
if (target.axis === obstacle.axis) return; // Параллельные не влияют
|
||||
|
||||
// Берем границы препятствия с предыдущего шага
|
||||
const obsMin = limits[obstacle.id].min;
|
||||
const obsMax = limits[obstacle.id].max;
|
||||
|
||||
// Важно: используем >= и <= с небольшим запасом для надежности
|
||||
// Пересекает ли препятствие линию нашей стенки?
|
||||
if (target.offset >= obsMin - 0.001 && target.offset <= obsMax + 0.001) {
|
||||
// Препятствие на пути. Где оно относительно центра нашей стенки?
|
||||
if (obstacle.offset < center) {
|
||||
newMin = Math.max(newMin, obstacle.offset);
|
||||
} else if (obstacle.offset > center) {
|
||||
newMax = Math.min(newMax, obstacle.offset);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
limits[target.id] = { min: newMin, max: newMax };
|
||||
});
|
||||
}
|
||||
return limits;
|
||||
};
|
||||
|
||||
export const calculateParts = (config: AppConfig, splits: LayoutSplits): GeneratedPart[] => {
|
||||
const parts: GeneratedPart[] = [];
|
||||
const safeX = Array.isArray(splits?.x) ? splits.x : [];
|
||||
@@ -130,6 +88,7 @@ export const createBinGeometry = (
|
||||
): THREE.BufferGeometry => {
|
||||
const geometries: THREE.BufferGeometry[] = [];
|
||||
|
||||
// ДНО И ВНЕШНИЕ СТЕНКИ
|
||||
const floorShape = createRoundedRectShape(width, depth, radius);
|
||||
const floorGeo = new THREE.ExtrudeGeometry(floorShape, { depth: thickness, bevelEnabled: false });
|
||||
floorGeo.rotateX(-Math.PI / 2);
|
||||
@@ -151,11 +110,12 @@ export const createBinGeometry = (
|
||||
wallGeo.translate(0, thickness, 0);
|
||||
geometries.push(wallGeo);
|
||||
|
||||
// Используем солвер для расчета реальных границ
|
||||
const limitMap = solveWallLimits(partitions);
|
||||
|
||||
// ВНУТРЕННИЕ ПЕРЕГОРОДКИ
|
||||
// Мы просто верим сохраненным данным (p.min/p.max). Они должны быть корректны при создании.
|
||||
partitions.forEach(p => {
|
||||
const { min: pMin, max: pMax } = limitMap[p.id];
|
||||
const pMin = p.min ?? 0;
|
||||
const pMax = p.max ?? 1;
|
||||
|
||||
if (pMax - pMin < 0.01) return;
|
||||
|
||||
const lengthRatio = pMax - pMin;
|
||||
@@ -181,6 +141,7 @@ export const createBinGeometry = (
|
||||
partGeo.translate(pX, thickness, pY);
|
||||
geometries.push(partGeo);
|
||||
|
||||
// СКРУГЛЕНИЯ
|
||||
if (p.rounded && radius > 1) {
|
||||
const filletR = Math.min(radius, 5);
|
||||
const filletShape = createConcaveFilletShape(filletR);
|
||||
|
||||
Reference in New Issue
Block a user