fix(back-end): fix 3mf calculator
This commit is contained in:
@@ -146,6 +146,7 @@ public class QuoteSessionController {
|
||||
Files.copy(inputStream, persistentPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
|
||||
Path convertedPersistentPath = null;
|
||||
try {
|
||||
// Apply Basic/Advanced Logic
|
||||
applyPrintSettings(settings);
|
||||
@@ -182,10 +183,21 @@ public class QuoteSessionController {
|
||||
if (settings.getLayerHeight() != null) processOverrides.put("layer_height", String.valueOf(settings.getLayerHeight()));
|
||||
if (settings.getInfillDensity() != null) processOverrides.put("sparse_infill_density", settings.getInfillDensity() + "%");
|
||||
if (settings.getInfillPattern() != null) processOverrides.put("sparse_infill_pattern", settings.getInfillPattern());
|
||||
|
||||
Path slicerInputPath = persistentPath;
|
||||
if ("3mf".equals(ext)) {
|
||||
String convertedFilename = UUID.randomUUID() + "-converted.stl";
|
||||
convertedPersistentPath = sessionStorageDir.resolve(convertedFilename).normalize();
|
||||
if (!convertedPersistentPath.startsWith(sessionStorageDir)) {
|
||||
throw new IOException("Invalid converted STL storage path");
|
||||
}
|
||||
slicerService.convert3mfToPersistentStl(persistentPath.toFile(), convertedPersistentPath);
|
||||
slicerInputPath = convertedPersistentPath;
|
||||
}
|
||||
|
||||
// 3. Slice (Use persistent path)
|
||||
PrintStats stats = slicerService.slice(
|
||||
persistentPath.toFile(),
|
||||
slicerInputPath.toFile(),
|
||||
machineProfile,
|
||||
filamentProfile,
|
||||
processProfile,
|
||||
@@ -193,7 +205,7 @@ public class QuoteSessionController {
|
||||
processOverrides
|
||||
);
|
||||
|
||||
Optional<ModelDimensions> modelDimensions = slicerService.inspectModelDimensions(persistentPath.toFile());
|
||||
Optional<ModelDimensions> modelDimensions = slicerService.inspectModelDimensions(slicerInputPath.toFile());
|
||||
|
||||
// 4. Calculate Quote
|
||||
QuoteResult result = quoteCalculator.calculate(stats, machine.getPrinterDisplayName(), selectedVariant);
|
||||
@@ -216,6 +228,9 @@ public class QuoteSessionController {
|
||||
Map<String, Object> breakdown = new HashMap<>();
|
||||
breakdown.put("machine_cost", result.getTotalPrice()); // Excludes setup fee which is at session level
|
||||
breakdown.put("setup_fee", 0);
|
||||
if (convertedPersistentPath != null) {
|
||||
breakdown.put("convertedStoredPath", QUOTE_STORAGE_ROOT.relativize(convertedPersistentPath).toString());
|
||||
}
|
||||
item.setPricingBreakdown(breakdown);
|
||||
|
||||
// Dimensions for shipping/package checks are computed server-side from the uploaded model.
|
||||
@@ -237,6 +252,9 @@ public class QuoteSessionController {
|
||||
} catch (Exception e) {
|
||||
// Cleanup if failed
|
||||
Files.deleteIfExists(persistentPath);
|
||||
if (convertedPersistentPath != null) {
|
||||
Files.deleteIfExists(convertedPersistentPath);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -331,6 +331,31 @@ public class SlicerService {
|
||||
return convertedStlPaths;
|
||||
}
|
||||
|
||||
public Path convert3mfToPersistentStl(File input3mf, Path destinationStl) throws IOException {
|
||||
Path tempDir = Files.createTempDirectory("slicer_convert_");
|
||||
try {
|
||||
List<String> convertedPaths = convert3mfToStlInputPaths(input3mf, tempDir);
|
||||
if (convertedPaths.isEmpty()) {
|
||||
throw new ModelProcessingException(
|
||||
"MODEL_CONVERSION_FAILED",
|
||||
"Unable to process this 3MF file. Try another format or contact us directly via Request Consultation."
|
||||
);
|
||||
}
|
||||
Path source = Path.of(convertedPaths.get(0));
|
||||
Path parent = destinationStl.toAbsolutePath().normalize().getParent();
|
||||
if (parent != null) {
|
||||
Files.createDirectories(parent);
|
||||
}
|
||||
Files.copy(source, destinationStl, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
|
||||
return destinationStl;
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new IOException("Interrupted during 3MF conversion", e);
|
||||
} finally {
|
||||
deleteRecursively(tempDir);
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> convert3mfToStlInputPaths(File input3mf, Path tempDir) throws IOException, InterruptedException {
|
||||
Path conversionOutputDir = tempDir.resolve("converted-from-3mf");
|
||||
Files.createDirectories(conversionOutputDir);
|
||||
@@ -378,7 +403,16 @@ public class SlicerService {
|
||||
try {
|
||||
objLog = runAssimpExport(input3mfPath, conversionOutputObjPath, tempDir.resolve("assimp-convert-obj.log"));
|
||||
if (hasRenderableGeometry(convertedObj)) {
|
||||
return List.of(convertedObj.toString());
|
||||
Path stlFromObj = conversionOutputDir.resolve("converted-from-obj.stl");
|
||||
runAssimpExport(
|
||||
convertedObj.toString(),
|
||||
stlFromObj.toString(),
|
||||
tempDir.resolve("assimp-convert-obj-to-stl.log")
|
||||
);
|
||||
if (hasRenderableGeometry(stlFromObj)) {
|
||||
return List.of(stlFromObj.toString());
|
||||
}
|
||||
logger.warning("Assimp OBJ->STL conversion produced empty geometry.");
|
||||
}
|
||||
logger.warning("Assimp OBJ conversion produced empty geometry.");
|
||||
} catch (IOException e) {
|
||||
|
||||
Reference in New Issue
Block a user