mcp-3d-printer-server 1.2.13 → 1.2.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/CONTRIBUTORS.md +2 -0
- package/README.md +2 -2
- package/dist/fulu-orca.d.ts +8 -0
- package/dist/fulu-orca.js +107 -10
- package/dist/index.js +3 -3
- package/dist/printers/bambu.js +11 -4
- package/dist/safety/confirmation.js +9 -2
- package/dist/safety/printer-state.d.ts +2 -0
- package/dist/safety/printer-state.js +42 -1
- package/dist/slicer/bambu-cli.d.ts +21 -1
- package/dist/slicer/bambu-cli.js +86 -11
- package/dist/slicer/run-slicer.d.ts +2 -0
- package/dist/slicer/run-slicer.js +3 -2
- package/dist/stl/stl-manipulator.d.ts +8 -0
- package/dist/stl/stl-manipulator.js +31 -2
- package/package.json +2 -2
- package/server.json +2 -2
- package/src/fulu-orca.ts +102 -10
- package/src/index.ts +3 -3
- package/src/printers/bambu.ts +11 -3
- package/src/safety/confirmation.ts +8 -2
- package/src/safety/printer-state.ts +42 -1
- package/src/slicer/bambu-cli.ts +92 -7
- package/src/slicer/run-slicer.ts +5 -2
- package/src/stl/stl-manipulator.ts +29 -1
|
@@ -11,7 +11,9 @@ import { detectProfilesRoot } from '../slicer/profile-flatten.js';
|
|
|
11
11
|
import {
|
|
12
12
|
BambuCliProfilePreparer,
|
|
13
13
|
assertSlicedProjectOutput,
|
|
14
|
+
bambuCliFailureReason,
|
|
14
15
|
buildBambuCliArgs,
|
|
16
|
+
planBambuCliInput,
|
|
15
17
|
type BambuCliSlicerType,
|
|
16
18
|
type BambuSliceOptions,
|
|
17
19
|
} from '../slicer/bambu-cli.js';
|
|
@@ -182,6 +184,27 @@ export class STLManipulator extends EventEmitter {
|
|
|
182
184
|
return timeoutMs;
|
|
183
185
|
}
|
|
184
186
|
|
|
187
|
+
/**
|
|
188
|
+
* Apply slice_stl's scale and rotations to a copy of the mesh as OrcaSlicer's
|
|
189
|
+
* CLI would, about the model's centre. Orca adds each --rotate* to the
|
|
190
|
+
* object's Euler angles (ModelVolume::rotate), so the result rotates about X,
|
|
191
|
+
* then Y, then Z whatever the argument order, after scaling. The slicer then
|
|
192
|
+
* places the result on the plate.
|
|
193
|
+
*/
|
|
194
|
+
private async transformMeshForCli(stlFilePath: string, options: BambuSliceOptions, outputDir: string): Promise<string> {
|
|
195
|
+
const { geometry, boundingBox } = await this.loadSTL(stlFilePath);
|
|
196
|
+
const center = new THREE.Vector3();
|
|
197
|
+
boundingBox.getCenter(center);
|
|
198
|
+
const radians = (degrees: number) => degrees * Math.PI / 180;
|
|
199
|
+
geometry.applyMatrix4(new THREE.Matrix4().makeTranslation(-center.x, -center.y, -center.z));
|
|
200
|
+
if (options.scale !== undefined) geometry.applyMatrix4(new THREE.Matrix4().makeScale(options.scale, options.scale, options.scale));
|
|
201
|
+
if (options.rotateX) geometry.applyMatrix4(new THREE.Matrix4().makeRotationX(radians(options.rotateX)));
|
|
202
|
+
if (options.rotateY) geometry.applyMatrix4(new THREE.Matrix4().makeRotationY(radians(options.rotateY)));
|
|
203
|
+
if (options.rotate) geometry.applyMatrix4(new THREE.Matrix4().makeRotationZ(radians(options.rotate)));
|
|
204
|
+
geometry.applyMatrix4(new THREE.Matrix4().makeTranslation(center.x, center.y, center.z));
|
|
205
|
+
return this.saveSTL(geometry, path.join(outputDir, `${path.basename(stlFilePath, path.extname(stlFilePath))}_transformed.stl`));
|
|
206
|
+
}
|
|
207
|
+
|
|
185
208
|
/**
|
|
186
209
|
* Load STL file and return geometry and bounding box
|
|
187
210
|
*/
|
|
@@ -1060,6 +1083,7 @@ export class STLManipulator extends EventEmitter {
|
|
|
1060
1083
|
}
|
|
1061
1084
|
options.loadFilaments = legacyFilaments;
|
|
1062
1085
|
}
|
|
1086
|
+
const cliInput = planBambuCliInput(cliType, is3mf, options);
|
|
1063
1087
|
const profilesRoot = detectProfilesRoot(slicerPath, cliType);
|
|
1064
1088
|
const preparer = new BambuCliProfilePreparer(path.join(this.tempDir, 'slicer-profiles'));
|
|
1065
1089
|
const bundle = await preparer.prepare(
|
|
@@ -1072,7 +1096,9 @@ export class STLManipulator extends EventEmitter {
|
|
|
1072
1096
|
options
|
|
1073
1097
|
);
|
|
1074
1098
|
bambuOutputDir = fs.mkdtempSync(path.join(this.tempDir, `${operationId}-bambu-output-`));
|
|
1075
|
-
|
|
1099
|
+
// The transformed copy lives in the run's output directory, which is removed afterwards.
|
|
1100
|
+
const inputPath = cliInput.meshTransformed ? await this.transformMeshForCli(stlFilePath, options, bambuOutputDir) : stlFilePath;
|
|
1101
|
+
args = [...buildBambuCliArgs(bundle, bambuOutputDir, exportName, options, cliInput), inputPath];
|
|
1076
1102
|
bambuExport = {
|
|
1077
1103
|
producedPath: path.join(bambuOutputDir, exportName),
|
|
1078
1104
|
// One folder per operation: concurrent slices of same-named inputs
|
|
@@ -1135,12 +1161,14 @@ export class STLManipulator extends EventEmitter {
|
|
|
1135
1161
|
if (progressCallback) progressCallback(20, `Executing slicer: ${slicerPath} ${args.join(' ')}`);
|
|
1136
1162
|
console.error(`Executing: ${slicerPath} ${args.join(' ')}`);
|
|
1137
1163
|
|
|
1164
|
+
const cliOutputDir = bambuOutputDir;
|
|
1138
1165
|
await runSlicerProcess({
|
|
1139
1166
|
command: slicerPath,
|
|
1140
1167
|
args,
|
|
1141
1168
|
timeoutMs: this.resolveSlicerTimeoutMs(),
|
|
1142
1169
|
slicerType,
|
|
1143
1170
|
isCancelled: () => !this.activeOperations.get(operationId),
|
|
1171
|
+
failureReason: cliOutputDir ? (exitCode) => bambuCliFailureReason(exitCode, cliOutputDir) : undefined,
|
|
1144
1172
|
});
|
|
1145
1173
|
|
|
1146
1174
|
if (!this.activeOperations.get(operationId)) {
|