mcp-3d-printer-server 1.2.19 → 1.2.20
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 +10 -0
- package/dist/stl/stl-manipulator.js +8 -7
- package/package.json +1 -1
- package/server.json +2 -2
- package/src/stl/stl-manipulator.ts +8 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.2.20 — 2026-10-30
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Keep already-horizontal faces eligible when `lay_flat` chooses the largest flat face. Thin plates now rest on their broad face at Z=0 instead of standing on an edge, including after repeated calls. When up- and down-facing areas tie exactly, as for a plate with a raised block or lettering, keep the face that already points down so a seated part is not flipped. Validate with generated STL geometry in horizontal, upside-down, edge-on, and tilted orientations and with a raised block in either face order; no printer or live Blender scene is used.
|
|
8
|
+
|
|
9
|
+
### Tests
|
|
10
|
+
|
|
11
|
+
- Verify malformed HTTP JSON returns a structured 400 response while the active MCP session remains usable. Exercise loopback HTTP only; no real printer or live Blender scene is used.
|
|
12
|
+
|
|
3
13
|
## 1.2.19 — 2026-10-30
|
|
4
14
|
|
|
5
15
|
### Fixed
|
|
@@ -1194,22 +1194,23 @@ export class STLManipulator extends EventEmitter {
|
|
|
1194
1194
|
throw new Error("Operation cancelled");
|
|
1195
1195
|
if (progressCallback)
|
|
1196
1196
|
progressCallback(75, "Finding largest flat surface...");
|
|
1197
|
-
//
|
|
1197
|
+
// Include already-horizontal faces: excluding Z-aligned normals can
|
|
1198
|
+
// stand a flat model on its edge, including on a repeated layFlat call.
|
|
1198
1199
|
let largestArea = 0;
|
|
1199
1200
|
let targetNormal = null;
|
|
1200
|
-
const upVector = new THREE.Vector3(0, 1, 0); // Assuming Y is up for most models initially?
|
|
1201
1201
|
const downVector = new THREE.Vector3(0, 0, -1); // Target normal (pointing down)
|
|
1202
|
+
// Faces are grouped by direction, so a part whose flat faces are all
|
|
1203
|
+
// horizontal has equal up- and down-facing areas. On a tie, keep the
|
|
1204
|
+
// face that already points down so a seated part is not flipped.
|
|
1202
1205
|
for (const group of normalGroups.values()) {
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
if (Math.abs(group.representativeNormal.z) < 0.99 && group.totalArea > largestArea) {
|
|
1206
|
+
const tied = targetNormal !== null && Math.abs(group.totalArea - largestArea) <= largestArea * 1e-6;
|
|
1207
|
+
if (tied ? group.representativeNormal.z < targetNormal.z : group.totalArea > largestArea) {
|
|
1206
1208
|
largestArea = group.totalArea;
|
|
1207
1209
|
targetNormal = group.representativeNormal;
|
|
1208
1210
|
}
|
|
1209
1211
|
}
|
|
1210
1212
|
if (!targetNormal) {
|
|
1211
|
-
//
|
|
1212
|
-
// For now, throw an error or return unchanged.
|
|
1213
|
+
// Only a mesh without any face area reaches this.
|
|
1213
1214
|
console.warn("Could not find a suitable large flat face to lay down. No changes made.");
|
|
1214
1215
|
this.emit('operationComplete', { operationId, type: 'layFlat', success: true, output: stlFilePath, message: "No suitable flat face found." });
|
|
1215
1216
|
return stlFilePath;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-3d-printer-server",
|
|
3
3
|
"mcpName": "io.github.DMontgomery40/mcp-3d-printer-server",
|
|
4
|
-
"version": "1.2.
|
|
4
|
+
"version": "1.2.20",
|
|
5
5
|
"description": "MCP server for connecting Claude with 3D printer management systems",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"repository": "https://github.com/DMontgomery40/mcp-3D-printer-server",
|
package/server.json
CHANGED
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
"url": "https://github.com/DMontgomery40/mcp-3D-printer-server",
|
|
8
8
|
"source": "github"
|
|
9
9
|
},
|
|
10
|
-
"version": "1.2.
|
|
10
|
+
"version": "1.2.20",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"identifier": "mcp-3d-printer-server",
|
|
15
|
-
"version": "1.2.
|
|
15
|
+
"version": "1.2.20",
|
|
16
16
|
"runtimeHint": "npx",
|
|
17
17
|
"transport": {
|
|
18
18
|
"type": "stdio"
|
|
@@ -1503,24 +1503,25 @@ export class STLManipulator extends EventEmitter {
|
|
|
1503
1503
|
if (!this.activeOperations.get(operationId)) throw new Error("Operation cancelled");
|
|
1504
1504
|
if (progressCallback) progressCallback(75, "Finding largest flat surface...");
|
|
1505
1505
|
|
|
1506
|
-
//
|
|
1506
|
+
// Include already-horizontal faces: excluding Z-aligned normals can
|
|
1507
|
+
// stand a flat model on its edge, including on a repeated layFlat call.
|
|
1507
1508
|
let largestArea = 0;
|
|
1508
1509
|
let targetNormal: THREE.Vector3 | null = null;
|
|
1509
|
-
const upVector = new THREE.Vector3(0, 1, 0); // Assuming Y is up for most models initially?
|
|
1510
1510
|
const downVector = new THREE.Vector3(0, 0, -1); // Target normal (pointing down)
|
|
1511
1511
|
|
|
1512
|
+
// Faces are grouped by direction, so a part whose flat faces are all
|
|
1513
|
+
// horizontal has equal up- and down-facing areas. On a tie, keep the
|
|
1514
|
+
// face that already points down so a seated part is not flipped.
|
|
1512
1515
|
for (const group of normalGroups.values()) {
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
if (Math.abs(group.representativeNormal.z) < 0.99 && group.totalArea > largestArea) {
|
|
1516
|
+
const tied = targetNormal !== null && Math.abs(group.totalArea - largestArea) <= largestArea * 1e-6;
|
|
1517
|
+
if (tied ? group.representativeNormal.z < targetNormal!.z : group.totalArea > largestArea) {
|
|
1516
1518
|
largestArea = group.totalArea;
|
|
1517
1519
|
targetNormal = group.representativeNormal;
|
|
1518
1520
|
}
|
|
1519
1521
|
}
|
|
1520
1522
|
|
|
1521
1523
|
if (!targetNormal) {
|
|
1522
|
-
//
|
|
1523
|
-
// For now, throw an error or return unchanged.
|
|
1524
|
+
// Only a mesh without any face area reaches this.
|
|
1524
1525
|
console.warn("Could not find a suitable large flat face to lay down. No changes made.");
|
|
1525
1526
|
this.emit('operationComplete', { operationId, type: 'layFlat', success: true, output: stlFilePath, message: "No suitable flat face found." });
|
|
1526
1527
|
return stlFilePath;
|