mcp-3d-printer-server 1.0.0 → 1.0.1
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/dist/3mf_parser.d.ts +3 -0
- package/dist/3mf_parser.js +216 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1018 -0
- package/dist/index.js.map +1 -0
- package/dist/printers/bambu.d.ts +42 -0
- package/dist/printers/bambu.js +278 -0
- package/dist/printers/creality.d.ts +10 -0
- package/dist/printers/creality.js +90 -0
- package/dist/printers/duet.d.ts +10 -0
- package/dist/printers/duet.js +66 -0
- package/dist/printers/klipper.d.ts +10 -0
- package/dist/printers/klipper.js +62 -0
- package/dist/printers/octoprint.d.ts +10 -0
- package/dist/printers/octoprint.js +97 -0
- package/dist/printers/printer-factory.d.ts +9 -0
- package/dist/printers/printer-factory.js +33 -0
- package/dist/printers/prusa.d.ts +10 -0
- package/dist/printers/prusa.js +93 -0
- package/dist/printers/repetier.d.ts +10 -0
- package/dist/printers/repetier.js +59 -0
- package/dist/stl/stl-manipulator.d.ts +140 -0
- package/dist/stl/stl-manipulator.js +1081 -0
- package/dist/test/stl-manipulator-test.d.ts +2 -0
- package/dist/test/stl-manipulator-test.js +91 -0
- package/dist/types.d.ts +75 -0
- package/dist/types.js +26 -0
- package/package.json +9 -3
- package/.dockerignore +0 -52
- package/.env.example +0 -17
- package/Dockerfile +0 -31
- package/docker-compose.yml +0 -31
- package/scripts/docker-run.sh +0 -25
- package/scripts/mcp-inspector.js +0 -49
- package/test/sample_cube.stl +0 -86
- package/test/sample_cube_extended.stl +0 -172
- package/test/sample_cube_modified.stl +0 -86
- package/test/sample_cube_rotated.stl +0 -86
- package/test/sample_cube_scaled.stl +0 -86
- package/test/sample_cube_translated.stl +0 -86
- package/tsconfig.json +0 -16
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { PrinterImplementation } from "../types.js";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import FormData from "form-data";
|
|
4
|
+
export class OctoPrintImplementation extends PrinterImplementation {
|
|
5
|
+
async getStatus(host, port, apiKey) {
|
|
6
|
+
const url = `http://${host}:${port}/api/printer`;
|
|
7
|
+
const response = await this.apiClient.get(url, {
|
|
8
|
+
headers: {
|
|
9
|
+
"X-Api-Key": apiKey
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
return response.data;
|
|
13
|
+
}
|
|
14
|
+
async getFiles(host, port, apiKey) {
|
|
15
|
+
const url = `http://${host}:${port}/api/files`;
|
|
16
|
+
const response = await this.apiClient.get(url, {
|
|
17
|
+
headers: {
|
|
18
|
+
"X-Api-Key": apiKey
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
return response.data;
|
|
22
|
+
}
|
|
23
|
+
async getFile(host, port, apiKey, filename) {
|
|
24
|
+
const url = `http://${host}:${port}/api/files/local/${filename}`;
|
|
25
|
+
const response = await this.apiClient.get(url, {
|
|
26
|
+
headers: {
|
|
27
|
+
"X-Api-Key": apiKey
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
return response.data;
|
|
31
|
+
}
|
|
32
|
+
async uploadFile(host, port, apiKey, filePath, filename, print) {
|
|
33
|
+
const url = `http://${host}:${port}/api/files/local`;
|
|
34
|
+
const formData = new FormData();
|
|
35
|
+
formData.append("file", fs.createReadStream(filePath));
|
|
36
|
+
formData.append("filename", filename);
|
|
37
|
+
if (print) {
|
|
38
|
+
formData.append("print", "true");
|
|
39
|
+
}
|
|
40
|
+
const response = await this.apiClient.post(url, formData, {
|
|
41
|
+
headers: {
|
|
42
|
+
"X-Api-Key": apiKey,
|
|
43
|
+
...formData.getHeaders()
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
return response.data;
|
|
47
|
+
}
|
|
48
|
+
async startJob(host, port, apiKey, filename) {
|
|
49
|
+
const url = `http://${host}:${port}/api/files/local/${filename}`;
|
|
50
|
+
const response = await this.apiClient.post(url, {
|
|
51
|
+
command: "select",
|
|
52
|
+
print: true
|
|
53
|
+
}, {
|
|
54
|
+
headers: {
|
|
55
|
+
"X-Api-Key": apiKey,
|
|
56
|
+
"Content-Type": "application/json"
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
return response.data;
|
|
60
|
+
}
|
|
61
|
+
async cancelJob(host, port, apiKey) {
|
|
62
|
+
const url = `http://${host}:${port}/api/job`;
|
|
63
|
+
const response = await this.apiClient.post(url, {
|
|
64
|
+
command: "cancel"
|
|
65
|
+
}, {
|
|
66
|
+
headers: {
|
|
67
|
+
"X-Api-Key": apiKey,
|
|
68
|
+
"Content-Type": "application/json"
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
return response.data;
|
|
72
|
+
}
|
|
73
|
+
async setTemperature(host, port, apiKey, component, temperature) {
|
|
74
|
+
let url = `http://${host}:${port}/api/printer/tool`;
|
|
75
|
+
const data = {};
|
|
76
|
+
if (component === "bed") {
|
|
77
|
+
data.command = "target";
|
|
78
|
+
data.target = temperature;
|
|
79
|
+
url = `http://${host}:${port}/api/printer/bed`;
|
|
80
|
+
}
|
|
81
|
+
else if (component.startsWith("extruder")) {
|
|
82
|
+
data.command = "target";
|
|
83
|
+
data.targets = {};
|
|
84
|
+
data.targets[component] = temperature;
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
throw new Error(`Unsupported component: ${component}`);
|
|
88
|
+
}
|
|
89
|
+
const response = await this.apiClient.post(url, data, {
|
|
90
|
+
headers: {
|
|
91
|
+
"X-Api-Key": apiKey,
|
|
92
|
+
"Content-Type": "application/json"
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
return response.data;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { PrinterImplementation } from "../types.js";
|
|
2
|
+
export declare class PrinterFactory {
|
|
3
|
+
private implementations;
|
|
4
|
+
private bambuPrinterStore;
|
|
5
|
+
private apiClient;
|
|
6
|
+
constructor();
|
|
7
|
+
getImplementation(type: string): PrinterImplementation;
|
|
8
|
+
disconnectAll(): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { BambuPrinterStore } from "../types.js";
|
|
2
|
+
import { OctoPrintImplementation } from "./octoprint.js";
|
|
3
|
+
import { KlipperImplementation } from "./klipper.js";
|
|
4
|
+
import { DuetImplementation } from "./duet.js";
|
|
5
|
+
import { RepetierImplementation } from "./repetier.js";
|
|
6
|
+
import { BambuImplementation } from "./bambu.js";
|
|
7
|
+
import { PrusaImplementation } from "./prusa.js";
|
|
8
|
+
import { CrealityImplementation } from "./creality.js";
|
|
9
|
+
import axios from "axios";
|
|
10
|
+
export class PrinterFactory {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.implementations = new Map();
|
|
13
|
+
this.bambuPrinterStore = new BambuPrinterStore();
|
|
14
|
+
this.apiClient = axios.create({ timeout: 10000 });
|
|
15
|
+
this.implementations.set("octoprint", new OctoPrintImplementation(this.apiClient));
|
|
16
|
+
this.implementations.set("klipper", new KlipperImplementation(this.apiClient));
|
|
17
|
+
this.implementations.set("duet", new DuetImplementation(this.apiClient));
|
|
18
|
+
this.implementations.set("repetier", new RepetierImplementation(this.apiClient));
|
|
19
|
+
this.implementations.set("bambu", new BambuImplementation(this.apiClient, this.bambuPrinterStore));
|
|
20
|
+
this.implementations.set("prusa", new PrusaImplementation(this.apiClient));
|
|
21
|
+
this.implementations.set("creality", new CrealityImplementation(this.apiClient));
|
|
22
|
+
}
|
|
23
|
+
getImplementation(type) {
|
|
24
|
+
const implementation = this.implementations.get(type.toLowerCase());
|
|
25
|
+
if (!implementation) {
|
|
26
|
+
throw new Error(`Unsupported printer type: ${type}`);
|
|
27
|
+
}
|
|
28
|
+
return implementation;
|
|
29
|
+
}
|
|
30
|
+
async disconnectAll() {
|
|
31
|
+
await this.bambuPrinterStore.disconnectAll();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PrinterImplementation } from "../types.js";
|
|
2
|
+
export declare class PrusaImplementation extends PrinterImplementation {
|
|
3
|
+
getStatus(host: string, port: string, apiKey: string): Promise<any>;
|
|
4
|
+
getFiles(host: string, port: string, apiKey: string): Promise<any>;
|
|
5
|
+
getFile(host: string, port: string, apiKey: string, filename: string): Promise<any>;
|
|
6
|
+
uploadFile(host: string, port: string, apiKey: string, filePath: string, filename: string, print: boolean): Promise<any>;
|
|
7
|
+
startJob(host: string, port: string, apiKey: string, filename: string): Promise<any>;
|
|
8
|
+
cancelJob(host: string, port: string, apiKey: string): Promise<any>;
|
|
9
|
+
setTemperature(host: string, port: string, apiKey: string, component: string, temperature: number): Promise<any>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { PrinterImplementation } from "../types.js";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import FormData from "form-data";
|
|
4
|
+
export class PrusaImplementation extends PrinterImplementation {
|
|
5
|
+
async getStatus(host, port, apiKey) {
|
|
6
|
+
const url = `http://${host}:${port}/api/v1/printer`;
|
|
7
|
+
const response = await this.apiClient.get(url, {
|
|
8
|
+
headers: {
|
|
9
|
+
"X-Api-Key": apiKey
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
return response.data;
|
|
13
|
+
}
|
|
14
|
+
async getFiles(host, port, apiKey) {
|
|
15
|
+
const url = `http://${host}:${port}/api/v1/storage`;
|
|
16
|
+
const response = await this.apiClient.get(url, {
|
|
17
|
+
headers: {
|
|
18
|
+
"X-Api-Key": apiKey
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
return response.data;
|
|
22
|
+
}
|
|
23
|
+
async getFile(host, port, apiKey, filename) {
|
|
24
|
+
const url = `http://${host}:${port}/api/v1/storage/${encodeURIComponent(filename)}`;
|
|
25
|
+
const response = await this.apiClient.get(url, {
|
|
26
|
+
headers: {
|
|
27
|
+
"X-Api-Key": apiKey
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
return response.data;
|
|
31
|
+
}
|
|
32
|
+
async uploadFile(host, port, apiKey, filePath, filename, print) {
|
|
33
|
+
const url = `http://${host}:${port}/api/v1/storage`;
|
|
34
|
+
const formData = new FormData();
|
|
35
|
+
formData.append("file", fs.createReadStream(filePath));
|
|
36
|
+
formData.append("filename", filename);
|
|
37
|
+
const response = await this.apiClient.post(url, formData, {
|
|
38
|
+
headers: {
|
|
39
|
+
"X-Api-Key": apiKey,
|
|
40
|
+
...formData.getHeaders()
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
if (print && response.data.success) {
|
|
44
|
+
await this.startJob(host, port, apiKey, filename);
|
|
45
|
+
}
|
|
46
|
+
return response.data;
|
|
47
|
+
}
|
|
48
|
+
async startJob(host, port, apiKey, filename) {
|
|
49
|
+
const url = `http://${host}:${port}/api/v1/job`;
|
|
50
|
+
const response = await this.apiClient.post(url, {
|
|
51
|
+
command: "start",
|
|
52
|
+
file: filename
|
|
53
|
+
}, {
|
|
54
|
+
headers: {
|
|
55
|
+
"X-Api-Key": apiKey,
|
|
56
|
+
"Content-Type": "application/json"
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
return response.data;
|
|
60
|
+
}
|
|
61
|
+
async cancelJob(host, port, apiKey) {
|
|
62
|
+
const url = `http://${host}:${port}/api/v1/job`;
|
|
63
|
+
const response = await this.apiClient.post(url, {
|
|
64
|
+
command: "cancel"
|
|
65
|
+
}, {
|
|
66
|
+
headers: {
|
|
67
|
+
"X-Api-Key": apiKey,
|
|
68
|
+
"Content-Type": "application/json"
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
return response.data;
|
|
72
|
+
}
|
|
73
|
+
async setTemperature(host, port, apiKey, component, temperature) {
|
|
74
|
+
const url = `http://${host}:${port}/api/v1/printer/temperature`;
|
|
75
|
+
let data = { command: "set" };
|
|
76
|
+
if (component === "bed") {
|
|
77
|
+
data.target = { bed: temperature };
|
|
78
|
+
}
|
|
79
|
+
else if (component.startsWith("extruder")) {
|
|
80
|
+
data.target = { tool0: temperature }; // Prusa typically uses tool0 for the extruder
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
throw new Error(`Unsupported component: ${component}`);
|
|
84
|
+
}
|
|
85
|
+
const response = await this.apiClient.post(url, data, {
|
|
86
|
+
headers: {
|
|
87
|
+
"X-Api-Key": apiKey,
|
|
88
|
+
"Content-Type": "application/json"
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
return response.data;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PrinterImplementation } from "../types.js";
|
|
2
|
+
export declare class RepetierImplementation extends PrinterImplementation {
|
|
3
|
+
getStatus(host: string, port: string, apiKey: string): Promise<any>;
|
|
4
|
+
getFiles(host: string, port: string, apiKey: string): Promise<any>;
|
|
5
|
+
getFile(host: string, port: string, apiKey: string, filename: string): Promise<any>;
|
|
6
|
+
uploadFile(host: string, port: string, apiKey: string, filePath: string, filename: string, print: boolean): Promise<any>;
|
|
7
|
+
startJob(host: string, port: string, apiKey: string, filename: string): Promise<any>;
|
|
8
|
+
cancelJob(host: string, port: string, apiKey: string): Promise<any>;
|
|
9
|
+
setTemperature(host: string, port: string, apiKey: string, component: string, temperature: number): Promise<any>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { PrinterImplementation } from "../types.js";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import FormData from "form-data";
|
|
4
|
+
export class RepetierImplementation extends PrinterImplementation {
|
|
5
|
+
async getStatus(host, port, apiKey) {
|
|
6
|
+
const url = `http://${host}:${port}/printer/api/?a=getPrinterInfo&apikey=${apiKey}`;
|
|
7
|
+
const response = await this.apiClient.get(url);
|
|
8
|
+
return response.data;
|
|
9
|
+
}
|
|
10
|
+
async getFiles(host, port, apiKey) {
|
|
11
|
+
const url = `http://${host}:${port}/printer/api/?a=ls&apikey=${apiKey}`;
|
|
12
|
+
const response = await this.apiClient.get(url);
|
|
13
|
+
return response.data;
|
|
14
|
+
}
|
|
15
|
+
async getFile(host, port, apiKey, filename) {
|
|
16
|
+
const url = `http://${host}:${port}/printer/api/?a=getFileInfo&apikey=${apiKey}&filename=${encodeURIComponent(filename)}`;
|
|
17
|
+
const response = await this.apiClient.get(url);
|
|
18
|
+
return response.data;
|
|
19
|
+
}
|
|
20
|
+
async uploadFile(host, port, apiKey, filePath, filename, print) {
|
|
21
|
+
const url = `http://${host}:${port}/printer/api/`;
|
|
22
|
+
const formData = new FormData();
|
|
23
|
+
formData.append("a", "upload");
|
|
24
|
+
formData.append("apikey", apiKey);
|
|
25
|
+
formData.append("filename", filename);
|
|
26
|
+
formData.append("print", print ? "1" : "0");
|
|
27
|
+
formData.append("file", fs.createReadStream(filePath));
|
|
28
|
+
const response = await this.apiClient.post(url, formData, {
|
|
29
|
+
headers: {
|
|
30
|
+
...formData.getHeaders()
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
return response.data;
|
|
34
|
+
}
|
|
35
|
+
async startJob(host, port, apiKey, filename) {
|
|
36
|
+
const url = `http://${host}:${port}/printer/api/?a=startJob&apikey=${apiKey}&filename=${encodeURIComponent(filename)}`;
|
|
37
|
+
const response = await this.apiClient.get(url);
|
|
38
|
+
return response.data;
|
|
39
|
+
}
|
|
40
|
+
async cancelJob(host, port, apiKey) {
|
|
41
|
+
const url = `http://${host}:${port}/printer/api/?a=stopJob&apikey=${apiKey}`;
|
|
42
|
+
const response = await this.apiClient.get(url);
|
|
43
|
+
return response.data;
|
|
44
|
+
}
|
|
45
|
+
async setTemperature(host, port, apiKey, component, temperature) {
|
|
46
|
+
let url;
|
|
47
|
+
if (component === "bed") {
|
|
48
|
+
url = `http://${host}:${port}/printer/api/?a=setBedTemp&apikey=${apiKey}&temp=${temperature}`;
|
|
49
|
+
}
|
|
50
|
+
else if (component === "extruder") {
|
|
51
|
+
url = `http://${host}:${port}/printer/api/?a=setExtruderTemp&apikey=${apiKey}&temp=${temperature}`;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
throw new Error(`Unsupported component: ${component}`);
|
|
55
|
+
}
|
|
56
|
+
const response = await this.apiClient.get(url);
|
|
57
|
+
return response.data;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
3
|
+
export type ProgressCallback = (progress: number, message?: string) => void;
|
|
4
|
+
export type OperationResult = {
|
|
5
|
+
success: boolean;
|
|
6
|
+
filePath?: string;
|
|
7
|
+
error?: string;
|
|
8
|
+
operationId: string;
|
|
9
|
+
};
|
|
10
|
+
export type TransformationType = 'scale' | 'rotate' | 'translate' | 'extendBase' | 'customModify';
|
|
11
|
+
export type TransformationAxis = 'x' | 'y' | 'z' | 'all';
|
|
12
|
+
export type BoundingBox = {
|
|
13
|
+
min: THREE.Vector3;
|
|
14
|
+
max: THREE.Vector3;
|
|
15
|
+
center: THREE.Vector3;
|
|
16
|
+
dimensions: THREE.Vector3;
|
|
17
|
+
};
|
|
18
|
+
export type TransformationParams = {
|
|
19
|
+
type: TransformationType;
|
|
20
|
+
axis?: TransformationAxis;
|
|
21
|
+
value: number | number[];
|
|
22
|
+
relative?: boolean;
|
|
23
|
+
selectionBounds?: THREE.Box3;
|
|
24
|
+
};
|
|
25
|
+
export declare class STLManipulator extends EventEmitter {
|
|
26
|
+
private tempDir;
|
|
27
|
+
private activeOperations;
|
|
28
|
+
constructor(tempDir?: string);
|
|
29
|
+
/**
|
|
30
|
+
* Generate a unique operation ID
|
|
31
|
+
*/
|
|
32
|
+
private generateOperationId;
|
|
33
|
+
/**
|
|
34
|
+
* Load STL file and return geometry and bounding box
|
|
35
|
+
*/
|
|
36
|
+
private loadSTL;
|
|
37
|
+
/**
|
|
38
|
+
* Save a geometry to STL file
|
|
39
|
+
*/
|
|
40
|
+
private saveSTL;
|
|
41
|
+
/**
|
|
42
|
+
* Get comprehensive information about an STL file
|
|
43
|
+
*/
|
|
44
|
+
getSTLInfo(stlFilePath: string): Promise<{
|
|
45
|
+
filePath: string;
|
|
46
|
+
fileName: string;
|
|
47
|
+
fileSize: number;
|
|
48
|
+
boundingBox: BoundingBox;
|
|
49
|
+
vertexCount: number;
|
|
50
|
+
faceCount: number;
|
|
51
|
+
}>;
|
|
52
|
+
/**
|
|
53
|
+
* Scale an STL model uniformly or along specific axes
|
|
54
|
+
*/
|
|
55
|
+
scaleSTL(stlFilePath: string, scaleFactors: number | [number, number, number], progressCallback?: ProgressCallback): Promise<string>;
|
|
56
|
+
/**
|
|
57
|
+
* Rotate an STL model around specific axes
|
|
58
|
+
*/
|
|
59
|
+
rotateSTL(stlFilePath: string, rotationAngles: [number, number, number], // [x, y, z] in degrees
|
|
60
|
+
progressCallback?: ProgressCallback): Promise<string>;
|
|
61
|
+
/**
|
|
62
|
+
* Translate (move) an STL model along specific axes
|
|
63
|
+
*/
|
|
64
|
+
translateSTL(stlFilePath: string, translationValues: [number, number, number], // [x, y, z] in mm
|
|
65
|
+
progressCallback?: ProgressCallback): Promise<string>;
|
|
66
|
+
/**
|
|
67
|
+
* Cancel an ongoing operation
|
|
68
|
+
*/
|
|
69
|
+
cancelOperation(operationId: string): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Generate an SVG visualization of an STL file from multiple angles
|
|
72
|
+
* @param stlFilePath Path to the STL file
|
|
73
|
+
* @param width Width of each view in pixels
|
|
74
|
+
* @param height Height of each view in pixels
|
|
75
|
+
* @param progressCallback Optional callback for progress updates
|
|
76
|
+
* @returns Path to the generated SVG file
|
|
77
|
+
*/
|
|
78
|
+
generateVisualization(stlFilePath: string, width?: number, height?: number, progressCallback?: ProgressCallback): Promise<string>;
|
|
79
|
+
/**
|
|
80
|
+
* Apply a specific transformation to a selected section of an STL file
|
|
81
|
+
* This allows for targeted modifications of specific parts of a model
|
|
82
|
+
*/
|
|
83
|
+
modifySection(stlFilePath: string, selection: THREE.Box3 | 'top' | 'bottom' | 'center', transformation: TransformationParams, progressCallback?: ProgressCallback): Promise<string>;
|
|
84
|
+
/**
|
|
85
|
+
* Enhanced version of extendBase with progress reporting
|
|
86
|
+
* @param stlFilePath Path to the input STL file
|
|
87
|
+
* @param extensionInches Amount to extend base in inches
|
|
88
|
+
* @param progressCallback Optional callback for progress updates
|
|
89
|
+
* @returns Path to the modified STL file
|
|
90
|
+
*/
|
|
91
|
+
extendBase(stlFilePath: string, extensionInches: number, progressCallback?: ProgressCallback): Promise<string>;
|
|
92
|
+
/**
|
|
93
|
+
* Slice an STL file using the specified slicer
|
|
94
|
+
* @param stlFilePath Path to the input STL file
|
|
95
|
+
* @param slicerType Type of slicer (prusaslicer, cura, slic3r, orcaslicer)
|
|
96
|
+
* @param slicerPath Path to the slicer executable
|
|
97
|
+
* @param slicerProfile Optional path to the slicer profile/config file
|
|
98
|
+
* @param progressCallback Optional callback for progress updates
|
|
99
|
+
* @returns Path to the generated G-code file
|
|
100
|
+
*/
|
|
101
|
+
sliceSTL(stlFilePath: string, slicerType: 'prusaslicer' | 'cura' | 'slic3r' | 'orcaslicer', slicerPath: string, slicerProfile?: string, progressCallback?: ProgressCallback): Promise<string>;
|
|
102
|
+
/**
|
|
103
|
+
* Enhanced version of confirmTemperatures with better error handling
|
|
104
|
+
* @param gcodePath Path to the G-code file
|
|
105
|
+
* @param expected Expected temperature settings
|
|
106
|
+
* @param progressCallback Optional callback for progress updates
|
|
107
|
+
* @returns Object with comparison results
|
|
108
|
+
*/
|
|
109
|
+
confirmTemperatures(gcodePath: string, expected: {
|
|
110
|
+
extruder?: number;
|
|
111
|
+
bed?: number;
|
|
112
|
+
}, progressCallback?: ProgressCallback): Promise<{
|
|
113
|
+
match: boolean;
|
|
114
|
+
actual: {
|
|
115
|
+
extruder?: number;
|
|
116
|
+
bed?: number;
|
|
117
|
+
};
|
|
118
|
+
expected: {
|
|
119
|
+
extruder?: number;
|
|
120
|
+
bed?: number;
|
|
121
|
+
};
|
|
122
|
+
allTemperatures: {
|
|
123
|
+
extruder: number[];
|
|
124
|
+
bed: number[];
|
|
125
|
+
};
|
|
126
|
+
}>;
|
|
127
|
+
/**
|
|
128
|
+
* Merge vertices within a specified tolerance.
|
|
129
|
+
*/
|
|
130
|
+
mergeVertices(stlFilePath: string, tolerance?: number, // Default tolerance in mm
|
|
131
|
+
progressCallback?: ProgressCallback): Promise<string>;
|
|
132
|
+
/**
|
|
133
|
+
* Center the model at the origin (0,0,0).
|
|
134
|
+
*/
|
|
135
|
+
centerModel(stlFilePath: string, progressCallback?: ProgressCallback): Promise<string>;
|
|
136
|
+
/**
|
|
137
|
+
* Rotate the model so its largest flat face lies on the XY plane (Z=0).
|
|
138
|
+
*/
|
|
139
|
+
layFlat(stlFilePath: string, progressCallback?: ProgressCallback): Promise<string>;
|
|
140
|
+
}
|