/** * Standard material densities for common 3D printing filaments. * Values are in g/cm³. * * Reference: https://www.simplify3d.com/resources/materials-guide/ */ export const MATERIAL_DENSITY_MAP: Record = { PLA: 1.24, ABS: 1.04, PETG: 1.27, NYLON: 1.52, TPU: 1.21, PC: 1.3, WOOD: 1.28, CF: 1.3, "PC/ABS": 1.19, HIPS: 1.03, PVA: 1.23, ASA: 1.05, PP: 0.9, POM: 1.4, PMMA: 1.18, FPE: 2.16, }; /** * Default filament diameter in mm (most common standard). */ export const DEFAULT_DIAMETER = 1.75; /** * Default density in g/cm³ (PLA, most common material). */ export const DEFAULT_DENSITY = 1.24; /** * List of known materials for AutoComplete suggestions. */ export const KNOWN_MATERIALS = Object.keys(MATERIAL_DENSITY_MAP); /** * Get the density for a material type using fuzzy matching. * Handles variations like "PLA Silk", "PETG-CF", "Wood PLA", etc. * * @param material - The material string to look up * @returns The density if a match is found, undefined otherwise */ export function getDensityForMaterial(material: string | undefined): number | undefined { if (!material) return undefined; const normalizedInput = material.toUpperCase().trim(); // Exact match first if (MATERIAL_DENSITY_MAP[normalizedInput]) { return MATERIAL_DENSITY_MAP[normalizedInput]; } // Fuzzy match: check if input starts with or contains a known material // Sort by length descending to match longer patterns first (e.g., "PC/ABS" before "PC") const sortedMaterials = KNOWN_MATERIALS.sort((a, b) => b.length - a.length); for (const knownMaterial of sortedMaterials) { // Check if the input starts with the material (e.g., "PLA Silk" starts with "PLA") if (normalizedInput.startsWith(knownMaterial)) { return MATERIAL_DENSITY_MAP[knownMaterial]; } // Check if the input contains the material as a word boundary // This handles cases like "Wood PLA" or "CF-PETG" const regex = new RegExp(`\\b${knownMaterial}\\b`, "i"); if (regex.test(normalizedInput)) { return MATERIAL_DENSITY_MAP[knownMaterial]; } } return undefined; } /** * Filter materials for AutoComplete based on input. * Returns materials that contain the search string (case-insensitive). * * @param searchValue - The search string * @returns Filtered list of material suggestions */ export function filterMaterials(searchValue: string): string[] { if (!searchValue) return KNOWN_MATERIALS; const normalizedSearch = searchValue.toUpperCase().trim(); return KNOWN_MATERIALS.filter((material) => material.includes(normalizedSearch)); }