bambu-printer-mcp 1.1.26 → 1.1.28
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/CONTRIBUTORS.md +4 -0
- package/README.md +43 -8
- package/dist/bambu-native.d.ts +55 -0
- package/dist/bambu-native.js +212 -13
- package/dist/index.js +154 -26
- package/dist/printers/bambu.d.ts +29 -2
- package/dist/printers/bambu.js +45 -12
- package/dist/safety/hidden-hms.d.ts +32 -0
- package/dist/safety/hidden-hms.js +405 -0
- package/dist/safety/print-file.js +54 -4
- package/dist/safety/printer-state.d.ts +9 -0
- package/dist/safety/printer-state.js +80 -13
- package/dist/slicer/profile-files.d.ts +2 -0
- package/dist/slicer/profile-files.js +24 -0
- package/dist/slicer/profile-flatten.js +27 -13
- package/dist/stl/stl-manipulator.d.ts +1 -0
- package/dist/stl/stl-manipulator.js +6 -8
- package/native/bambu-native-print.cpp +100 -26
- package/package.json +7 -5
- package/scripts/build-bambu-native.sh +53 -0
- package/scripts/setup-bambu-native.mjs +372 -0
- package/src/bambu-native.ts +229 -14
- package/src/index.ts +152 -25
- package/src/printers/bambu.ts +51 -12
- package/src/safety/hidden-hms.ts +406 -0
- package/src/safety/print-file.ts +43 -4
- package/src/safety/printer-state.ts +85 -13
- package/src/slicer/profile-files.ts +21 -0
- package/src/slicer/profile-flatten.ts +34 -11
- package/src/stl/stl-manipulator.ts +7 -10
- package/scripts/build-bambu-native.zsh +0 -33
|
@@ -28,6 +28,7 @@ import fs from "node:fs/promises";
|
|
|
28
28
|
import { existsSync, realpathSync } from "node:fs";
|
|
29
29
|
import path from "node:path";
|
|
30
30
|
import crypto from "node:crypto";
|
|
31
|
+
import { profileJsonFiles } from './profile-files.js';
|
|
31
32
|
|
|
32
33
|
export type ProfileKind = "machine" | "process" | "filament";
|
|
33
34
|
|
|
@@ -125,17 +126,7 @@ async function buildNameIndex(
|
|
|
125
126
|
...userProfileRoots.flatMap(root => ['process', 'filament'].map(sub => path.join(root, sub))),
|
|
126
127
|
];
|
|
127
128
|
for (const dir of directories) {
|
|
128
|
-
|
|
129
|
-
try {
|
|
130
|
-
entries = await fs.readdir(dir);
|
|
131
|
-
} catch {
|
|
132
|
-
// Vendor or subdir missing -- skip silently; flatten will fail later
|
|
133
|
-
// with a precise "name not found" error.
|
|
134
|
-
continue;
|
|
135
|
-
}
|
|
136
|
-
for (const entry of entries) {
|
|
137
|
-
if (!entry.endsWith(".json")) continue;
|
|
138
|
-
const filePath = path.join(dir, entry);
|
|
129
|
+
for (const filePath of profileJsonFiles(dir)) {
|
|
139
130
|
let raw: string;
|
|
140
131
|
try {
|
|
141
132
|
raw = await fs.readFile(filePath, "utf8");
|
|
@@ -344,6 +335,37 @@ function enforceMatchingNozzles(arr: unknown[]): void {
|
|
|
344
335
|
}
|
|
345
336
|
}
|
|
346
337
|
|
|
338
|
+
/**
|
|
339
|
+
* BambuStudio picks each per-variant machine, process, and filament value
|
|
340
|
+
* (e.g. filament_max_volumetric_speed) by "<extruder_type> <nozzle_volume_type>"
|
|
341
|
+
* among the variants each extruder declares in extruder_variant_list. A flow
|
|
342
|
+
* type the preset doesn't declare has no values to pick, so refuse it instead
|
|
343
|
+
* of labelling a job for a nozzle it wasn't sliced for.
|
|
344
|
+
*/
|
|
345
|
+
function assertNozzleVariantDeclared(
|
|
346
|
+
flat: Record<string, unknown>,
|
|
347
|
+
volumeType: string,
|
|
348
|
+
machineLeaf: string
|
|
349
|
+
): void {
|
|
350
|
+
const strings = (key: string): string[] =>
|
|
351
|
+
Array.isArray(flat[key]) ? (flat[key] as unknown[]).map(String) : [];
|
|
352
|
+
const extruderTypes = strings("extruder_type");
|
|
353
|
+
const declaredLists = strings("extruder_variant_list");
|
|
354
|
+
const count = (flat["nozzle_volume_type"] as unknown[]).length;
|
|
355
|
+
for (let i = 0; i < count; i++) {
|
|
356
|
+
const extruderType = extruderTypes[i] ?? extruderTypes[0];
|
|
357
|
+
const declared = (declaredLists[i] ?? declaredLists[0] ?? "").split(",").map((v) => v.trim()).filter(Boolean);
|
|
358
|
+
const matches = (variant: string) =>
|
|
359
|
+
extruderType ? variant === `${extruderType} ${volumeType}` : variant.endsWith(` ${volumeType}`);
|
|
360
|
+
// Presets without variant declarations only have Standard values.
|
|
361
|
+
if (declared.length === 0 ? volumeType === "Standard" : declared.some(matches)) continue;
|
|
362
|
+
throw new Error(
|
|
363
|
+
`Slicing for a ${volumeType} nozzle is refused: "${machineLeaf}" declares no ${volumeType} variant ` +
|
|
364
|
+
`for extruder ${i + 1} (declared: ${declared.join(", ") || "none"}).`
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
347
369
|
/** Best-effort extruder count for fallback nozzle_volume_type sizing. */
|
|
348
370
|
/** BambuStudio's built-in filament_colour default. */
|
|
349
371
|
export const DEFAULT_FILAMENT_COLOUR = "#00AE42";
|
|
@@ -696,6 +718,7 @@ export async function flattenForCli(opts: FlattenOptions): Promise<FlattenedProf
|
|
|
696
718
|
|
|
697
719
|
// CLI-specific post-processing on machine profile only.
|
|
698
720
|
deriveNozzleVolumeType(machineFlat, opts.nozzleVolumeType);
|
|
721
|
+
if (opts.nozzleVolumeType) assertNozzleVariantDeclared(machineFlat, opts.nozzleVolumeType, opts.machineLeaf);
|
|
699
722
|
applyMachineModelBedMetadata(machineFlat, machineIndex);
|
|
700
723
|
// A standalone custom machine can accompany process/filament profiles that
|
|
701
724
|
// need BBL resolution; do not impose bundled model config on that machine.
|
|
@@ -10,6 +10,7 @@ import { EventEmitter } from 'events';
|
|
|
10
10
|
import * as crypto from 'crypto';
|
|
11
11
|
import { execFile } from 'child_process';
|
|
12
12
|
import { flattenForCli, detectProfilesRoot, resolveBblMachineProfile } from '../slicer/profile-flatten.js';
|
|
13
|
+
import { profileJsonFiles } from '../slicer/profile-files.js';
|
|
13
14
|
|
|
14
15
|
const readFileAsync = promisify(fs.readFile);
|
|
15
16
|
const writeFileAsync = promisify(fs.writeFile);
|
|
@@ -165,6 +166,7 @@ export interface BambuSliceOptions {
|
|
|
165
166
|
filamentColours?: string[]; // positional #RRGGBB per loaded filament slot
|
|
166
167
|
bedType?: string; // Bambu bed type, e.g. textured_plate or cool_plate
|
|
167
168
|
nozzleType?: string; // installed hotend material written into the machine preset
|
|
169
|
+
nozzleVolumeType?: 'Standard' | 'High Flow'; // installed nozzle flow, the machine preset's nozzle_volume_type
|
|
168
170
|
enableTimelapse?: boolean; // --enable-timelapse: timelapse-aware slicing
|
|
169
171
|
allowMixTemp?: boolean; // --allow-mix-temp: allow mixed-temp filaments
|
|
170
172
|
scale?: number; // --scale factor: uniform scale
|
|
@@ -232,10 +234,9 @@ export class STLManipulator extends EventEmitter {
|
|
|
232
234
|
}
|
|
233
235
|
|
|
234
236
|
for (const root of roots) {
|
|
235
|
-
const candidate = path.join(root, category
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
}
|
|
237
|
+
const candidate = profileJsonFiles(path.join(root, category))
|
|
238
|
+
.find(file => path.basename(file) === `${profileName}.json`);
|
|
239
|
+
if (candidate) return candidate;
|
|
239
240
|
}
|
|
240
241
|
|
|
241
242
|
return undefined;
|
|
@@ -250,12 +251,7 @@ export class STLManipulator extends EventEmitter {
|
|
|
250
251
|
continue;
|
|
251
252
|
}
|
|
252
253
|
|
|
253
|
-
for (const
|
|
254
|
-
if (!entry.endsWith('.json')) {
|
|
255
|
-
continue;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
const filePath = path.join(filamentDir, entry);
|
|
254
|
+
for (const filePath of profileJsonFiles(filamentDir)) {
|
|
259
255
|
try {
|
|
260
256
|
const parsed = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
261
257
|
const filamentId = typeof parsed?.filament_id === 'string' ? parsed.filament_id.trim() : '';
|
|
@@ -568,6 +564,7 @@ export class STLManipulator extends EventEmitter {
|
|
|
568
564
|
userProfileRoots: configuredBambuProfileDirs(),
|
|
569
565
|
tempDir: this.tempDir,
|
|
570
566
|
bedType: this.resolveBambuStudioBedType(bambuOptions?.bedType),
|
|
567
|
+
nozzleVolumeType: bambuOptions?.nozzleVolumeType,
|
|
571
568
|
filamentColours: bambuOptions?.filamentColours ?? bundle.filamentColours,
|
|
572
569
|
projectTowerPosition: bundle.projectTowerPosition,
|
|
573
570
|
sourceProfiles: {
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
#!/bin/zsh
|
|
2
|
-
|
|
3
|
-
# Build the optional macOS adapter that calls Bambu Studio's installed
|
|
4
|
-
# networking plug-in at runtime. The plug-in itself is not bundled here.
|
|
5
|
-
set -euo pipefail
|
|
6
|
-
|
|
7
|
-
if [[ "$(uname -s)" != "Darwin" ]]; then
|
|
8
|
-
print -u2 "The Bambu native helper currently supports macOS only."
|
|
9
|
-
exit 1
|
|
10
|
-
fi
|
|
11
|
-
|
|
12
|
-
SCRIPT_DIR="${0:A:h}"
|
|
13
|
-
PROJECT_ROOT="${SCRIPT_DIR:h}"
|
|
14
|
-
CXX_BIN="${CXX:-clang++}"
|
|
15
|
-
OUTPUT="${PROJECT_ROOT}/native/bambu-native-print"
|
|
16
|
-
SOURCE="${PROJECT_ROOT}/native/bambu-native-print.cpp"
|
|
17
|
-
|
|
18
|
-
if ! command -v "$CXX_BIN" >/dev/null 2>&1; then
|
|
19
|
-
print -u2 "C++ compiler not found: $CXX_BIN"
|
|
20
|
-
exit 1
|
|
21
|
-
fi
|
|
22
|
-
|
|
23
|
-
"$CXX_BIN" \
|
|
24
|
-
-std=c++17 \
|
|
25
|
-
-O2 \
|
|
26
|
-
-Wall \
|
|
27
|
-
-Wextra \
|
|
28
|
-
-o "$OUTPUT" \
|
|
29
|
-
"$SOURCE" \
|
|
30
|
-
-ldl
|
|
31
|
-
|
|
32
|
-
chmod 755 "$OUTPUT"
|
|
33
|
-
print "Built $OUTPUT"
|