task(CAD-11): truss professional upgrade - chordCount (1-4 belt tubes) with adjustable rendering, free length input (10-1000cm), variable angle corners (15-165), circle truss tool with diameter option, BOM with chordCount grouping + Pi*d circumference
This commit is contained in:
@@ -10,16 +10,20 @@ import type { CADElement } from '../types/cad.types';
|
||||
|
||||
export interface BOMRow {
|
||||
pos: number;
|
||||
type: 'Traverse' | 'Eck-Traverse';
|
||||
/** Laenge in cm (Traverse: length; Eck-Traverse: armLength). */
|
||||
type: 'Traverse' | 'Eck-Traverse' | 'Kreis-Traverse';
|
||||
/** Laenge in cm (Traverse: length; Eck-Traverse: armLength; Kreis: Durchmesser). */
|
||||
length: number;
|
||||
/** Breite in cm (trussWidth). */
|
||||
width: number;
|
||||
count: number;
|
||||
/** Gesamtlaenge dieser Position in cm (count * length, Ecken * 2). */
|
||||
/** Gesamtlaenge dieser Position in cm. */
|
||||
totalCm: number;
|
||||
/** Bezeichnung, z.B. "Traverse 200 x 29". */
|
||||
/** Bezeichnung. */
|
||||
label: string;
|
||||
/** Gurtrohr-Anzahl (optional, CAD-11). */
|
||||
chordCount?: number;
|
||||
/** Eck-Winkel in Grad (optional, CAD-11). */
|
||||
angle?: number;
|
||||
}
|
||||
|
||||
export interface BOMResult {
|
||||
@@ -29,9 +33,11 @@ export interface BOMResult {
|
||||
}
|
||||
|
||||
interface GroupKey {
|
||||
type: 'Traverse' | 'Eck-Traverse';
|
||||
type: 'Traverse' | 'Eck-Traverse' | 'Kreis-Traverse';
|
||||
length: number;
|
||||
width: number;
|
||||
chordCount?: number;
|
||||
angle?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,16 +52,27 @@ export function buildBOM(elements: CADElement[]): BOMResult {
|
||||
if (String(el.type) === 'truss' && el.properties.truss === true) {
|
||||
const length = (el.properties.length as number | undefined) ?? el.width ?? 0;
|
||||
const width = (el.properties.trussWidth as number | undefined) ?? el.height ?? 29;
|
||||
const key: GroupKey = { type: 'Traverse', length, width };
|
||||
const id = `T|${length}|${width}`;
|
||||
const chordCount = (el.properties.chordCount as number | undefined) ?? 2;
|
||||
const key: GroupKey = { type: 'Traverse', length, width, chordCount };
|
||||
const id = `T|${length}|${width}|${chordCount}`;
|
||||
const g = groups.get(id) ?? { key, count: 0 };
|
||||
g.count++;
|
||||
groups.set(id, g);
|
||||
} else if (String(el.type) === 'boxcorner' && el.properties.boxcorner === true) {
|
||||
const length = (el.properties.armLength as number | undefined) ?? 50;
|
||||
const width = (el.properties.trussWidth as number | undefined) ?? 29;
|
||||
const key: GroupKey = { type: 'Eck-Traverse', length, width };
|
||||
const id = `C|${length}|${width}`;
|
||||
const angle = (el.properties.angle as number | undefined) ?? 90;
|
||||
const key: GroupKey = { type: 'Eck-Traverse', length, width, angle };
|
||||
const id = `C|${length}|${width}|${angle}`;
|
||||
const g = groups.get(id) ?? { key, count: 0 };
|
||||
g.count++;
|
||||
groups.set(id, g);
|
||||
} else if (String(el.type) === 'circletruss' && el.properties.circletruss === true) {
|
||||
const diameter = (el.properties.diameter as number | undefined) ?? el.width;
|
||||
const width = (el.properties.trussWidth as number | undefined) ?? 29;
|
||||
const chordCount = (el.properties.chordCount as number | undefined) ?? 2;
|
||||
const key: GroupKey = { type: 'Kreis-Traverse', length: diameter, width, chordCount };
|
||||
const id = `K|${diameter}|${width}|${chordCount}`;
|
||||
const g = groups.get(id) ?? { key, count: 0 };
|
||||
g.count++;
|
||||
groups.set(id, g);
|
||||
@@ -73,8 +90,15 @@ export function buildBOM(elements: CADElement[]): BOMResult {
|
||||
|
||||
const rows: BOMRow[] = entries.map((g, i) => {
|
||||
// Ecken haben 2 Arme: Gesamtlaenge = count * length * 2
|
||||
// Kreis-Traversen: Umfang = Pi * Durchmesser
|
||||
const isCircle = g.key.type === 'Kreis-Traverse';
|
||||
const armFactor = g.key.type === 'Eck-Traverse' ? 2 : 1;
|
||||
const totalCm = g.count * g.key.length * armFactor;
|
||||
const perPieceCm = isCircle ? Math.PI * g.key.length : g.key.length * armFactor;
|
||||
const totalCm = g.count * perPieceCm;
|
||||
const detailParts: string[] = [];
|
||||
if (g.key.chordCount !== undefined && g.key.chordCount > 0) detailParts.push(`${g.key.chordCount}-rohr`);
|
||||
if (g.key.angle !== undefined && g.key.angle !== 90) detailParts.push(`${g.key.angle}°`);
|
||||
const detailSuffix = detailParts.length > 0 ? ` (${detailParts.join(', ')})` : '';
|
||||
return {
|
||||
pos: i + 1,
|
||||
type: g.key.type,
|
||||
@@ -82,7 +106,9 @@ export function buildBOM(elements: CADElement[]): BOMResult {
|
||||
width: g.key.width,
|
||||
count: g.count,
|
||||
totalCm,
|
||||
label: `${g.key.type} ${g.key.length} \u00d7 ${g.key.width}`,
|
||||
label: `${g.key.type} ${isCircle ? '⌀' : ''}${g.key.length} × ${g.key.width}${detailSuffix}`,
|
||||
chordCount: g.key.chordCount,
|
||||
angle: g.key.angle,
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user