123 lines
3.2 KiB
JavaScript
123 lines
3.2 KiB
JavaScript
/**
|
|
* Cost Calculator Service
|
|
* Estimates filament/resin costs based on file size
|
|
*/
|
|
|
|
// Default material costs (per kg)
|
|
const DEFAULT_COSTS = {
|
|
// FDM Filaments
|
|
'pla': 15, // PLA ~$15/kg
|
|
'abs': 18, // ABS ~$18/kg
|
|
'petg': 20, // PETG ~$20/kg
|
|
'nylon': 35, // Nylon ~$35/kg
|
|
'tpu': 40, // TPU ~$40/kg
|
|
'carbon': 50, // Carbon Fiber ~$50/kg
|
|
'bamboo': 25, // Bamboo ~$25/kg
|
|
|
|
// Resin
|
|
'standard': 12, // Standard Resin ~$12/ml
|
|
'tough': 18, // Tough Resin ~$18/ml
|
|
'flexible': 20, // Flexible Resin ~$20/ml
|
|
'castable': 25, // Castable Resin ~$25/ml
|
|
};
|
|
|
|
// Density of materials (g/cm³)
|
|
const MATERIAL_DENSITY = {
|
|
// FDM Filaments
|
|
'pla': 1.24,
|
|
'abs': 1.04,
|
|
'petg': 1.27,
|
|
'nylon': 1.14,
|
|
'tpu': 1.21,
|
|
'carbon': 1.30,
|
|
'bamboo': 1.25,
|
|
|
|
// Resin
|
|
'standard': 1.15,
|
|
'tough': 1.18,
|
|
'flexible': 1.20,
|
|
'castable': 1.22,
|
|
};
|
|
|
|
/**
|
|
* Estimate material weight from file size
|
|
* Using heuristic: file size in bytes → approximate volume → weight
|
|
*
|
|
* Formula: Weight (g) = (File Size in MB) * 50 * density / material_type_factor
|
|
* This is a rough estimation since we don't have actual 3D geometry
|
|
*/
|
|
export function estimateWeight(fileSizeBytes, materialType = 'pla') {
|
|
// Convert bytes to MB
|
|
const fileSizeMB = fileSizeBytes / (1024 * 1024);
|
|
|
|
// Heuristic factor: roughly 50-70g per MB of STL/OBJ, less for compressed 3MF
|
|
// Average density is ~1.2, so we use that as baseline
|
|
const baseFactor = 55;
|
|
const density = MATERIAL_DENSITY[materialType] || 1.2;
|
|
|
|
// Estimate weight in grams
|
|
const weightGrams = fileSizeMB * baseFactor * (density / 1.2);
|
|
|
|
return Math.max(weightGrams, 1); // Minimum 1 gram
|
|
}
|
|
|
|
/**
|
|
* Calculate cost based on estimated weight and material type
|
|
*/
|
|
export function calculateCost(fileSizeBytes, materialType = 'pla', customCostPerUnit = null) {
|
|
const costPerUnit = customCostPerUnit || DEFAULT_COSTS[materialType] || DEFAULT_COSTS['pla'];
|
|
const weight = estimateWeight(fileSizeBytes, materialType);
|
|
|
|
// Convert to kg for FDM or ml for resin
|
|
const units = weight / 1000;
|
|
|
|
return {
|
|
material: materialType,
|
|
weight: Math.round(weight * 100) / 100, // grams
|
|
units: Math.round(units * 100) / 100,
|
|
costPerUnit: costPerUnit,
|
|
estimatedCost: Math.round(units * costPerUnit * 100) / 100,
|
|
confidence: 'low' // Note: This is a rough estimate
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Get all available materials with their costs
|
|
*/
|
|
export function getMaterials() {
|
|
return Object.keys(DEFAULT_COSTS).map(material => ({
|
|
type: material,
|
|
costPerUnit: DEFAULT_COSTS[material],
|
|
density: MATERIAL_DENSITY[material]
|
|
}));
|
|
}
|
|
|
|
/**
|
|
* Update cost for a material
|
|
*/
|
|
export function updateMaterialCost(materialType, costPerUnit) {
|
|
if (DEFAULT_COSTS.hasOwnProperty(materialType)) {
|
|
DEFAULT_COSTS[materialType] = costPerUnit;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Batch calculate costs for multiple models
|
|
*/
|
|
export function batchCalculateCosts(models, materialType = 'pla') {
|
|
return models.map(model => ({
|
|
modelId: model.id,
|
|
name: model.name,
|
|
...calculateCost(model.file_size, materialType)
|
|
}));
|
|
}
|
|
|
|
export default {
|
|
estimateWeight,
|
|
calculateCost,
|
|
getMaterials,
|
|
updateMaterialCost,
|
|
batchCalculateCosts
|
|
};
|