@atlisp/mcp 1.6.8 → 1.6.10
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/atlisp-mcp.js +428 -148
- package/dist/cad-worker.js +15 -5
- package/package.json +1 -1
package/dist/atlisp-mcp.js
CHANGED
|
@@ -138,7 +138,7 @@ if (!envResult.success) {
|
|
|
138
138
|
process.exit(1);
|
|
139
139
|
}
|
|
140
140
|
var env = envResult.data;
|
|
141
|
-
var configFilePath = env.CONFIG_FILE || cliArgs.configFile || path.join(os.homedir(), "
|
|
141
|
+
var configFilePath = env.CONFIG_FILE || cliArgs.configFile || path.join(os.homedir(), ".atlisp", "atlisp.config.json");
|
|
142
142
|
var fileConfig = loadConfigFile(configFilePath);
|
|
143
143
|
var config = {
|
|
144
144
|
port: fileConfig?.port || parseInt(env.PORT || cliArgs.port, 10),
|
|
@@ -905,56 +905,14 @@ ${ENTITY_PROPERTIES_LISP}
|
|
|
905
905
|
@e:i (1+ @e:i)))
|
|
906
906
|
(vl-prin1-to-string (list @e:total (reverse @e:ents))))`;
|
|
907
907
|
}
|
|
908
|
-
function buildTextCode({ layer, bbox, offset, limit }) {
|
|
909
|
-
const items = [`'(0 . "TEXT,MTEXT,ATTRIB,TCH_TEXT")`];
|
|
910
|
-
if (layer)
|
|
911
|
-
items.push(`(cons 8 "${layer.replace(/"/g, '\\"')}")`);
|
|
912
|
-
if (bbox) {
|
|
913
|
-
const parts = bbox.split(",").map((s) => parseFloat(s.trim()));
|
|
914
|
-
if (parts.length === 4) {
|
|
915
|
-
const [x1, y1, x2, y2] = parts;
|
|
916
|
-
items.push(
|
|
917
|
-
`'(-4 . "<AND")`,
|
|
918
|
-
`'(-4 . ">=,>=,*") (list 10 ${x1} ${y1} 0.0)`,
|
|
919
|
-
`'(-4 . "<=,<=,*") (list 10 ${x2} ${y2} 0.0)`,
|
|
920
|
-
`'(-4 . "AND>")`
|
|
921
|
-
);
|
|
922
|
-
}
|
|
923
|
-
}
|
|
924
|
-
const filterExpr = `(list ${items.join(" ")})`;
|
|
925
|
-
return `(progn
|
|
926
|
-
(defun @t:props (ent / ed ins)
|
|
927
|
-
(setq ed (entget ent) ins (cdr (assoc 10 ed)))
|
|
928
|
-
(list
|
|
929
|
-
(list "type" (vl-prin1-to-string (cdr (assoc 0 ed))))
|
|
930
|
-
(list "handle" (vl-prin1-to-string (cdr (assoc 5 ed))))
|
|
931
|
-
(list "layer" (vl-prin1-to-string (cdr (assoc 8 ed))))
|
|
932
|
-
(list "color" (if (assoc 62 ed) (cdr (assoc 62 ed)) 256))
|
|
933
|
-
(list "linetype" (vl-prin1-to-string (if (assoc 6 ed) (cdr (assoc 6 ed)) "ByLayer")))
|
|
934
|
-
(list "text" (vl-prin1-to-string (cdr (assoc 1 ed))))
|
|
935
|
-
(list "insert" (list (car ins) (cadr ins) (caddr ins)))
|
|
936
|
-
(list "height" (cdr (assoc 40 ed)))
|
|
937
|
-
(list "rotation" (cdr (assoc 50 ed)))
|
|
938
|
-
(list "style" (vl-prin1-to-string (if (assoc 7 ed) (cdr (assoc 7 ed)) "Standard")))))
|
|
939
|
-
(defun @t:run nil
|
|
940
|
-
(setq ss (ssget "_X" ${filterExpr}))
|
|
941
|
-
(if (null ss)
|
|
942
|
-
(list "total" 0 "offset" ${offset} "limit" ${limit})
|
|
943
|
-
(progn
|
|
944
|
-
(setq total (sslength ss) texts nil i ${offset})
|
|
945
|
-
(while (and (< i total) (< (length texts) ${limit}))
|
|
946
|
-
(setq texts (append texts (list (@t:props (ssname ss i)))) i (1+ i)))
|
|
947
|
-
(list "total" total "offset" ${offset} "limit" ${limit} "texts" texts))))
|
|
948
|
-
(@t:run))
|
|
949
|
-
`;
|
|
950
|
-
}
|
|
951
908
|
var RESOURCES = [
|
|
952
909
|
{ uri: "atlisp://cad/info", name: "CAD Info", description: "CAD \u8FDE\u63A5\u4FE1\u606F", mimeType: "application/json", subscribable: true },
|
|
953
|
-
{ uri: "atlisp://dwg/layers", name: "Layers", description: "\u56FE\u5C42\u5217\u8868", mimeType: "application/json", subscribable: true },
|
|
954
910
|
{ uri: "atlisp://dwg/entities", name: "Entities", description: "\u56FE\u5143\u5217\u8868\u3002\u65E0\u53C2\u6570\u65F6\u8FD4\u56DE\u603B\u6570\u548C\u6309\u7C7B\u578B\u7EDF\u8BA1\uFF1B\u6709\u53C2\u6570\u65F6\u8FD4\u56DE filtered \u56FE\u6587\u7684 entity:properties \u5168\u5C5E\u6027 JSON\uFF08ObjectName, Handle, Layer, Color, Center, Radius \u7B49\uFF09\uFF0C\u652F\u6301 ?type=LINE&layer=0&bbox=0,0,100,100", mimeType: "application/json", subscribable: true },
|
|
955
|
-
{ uri: "atlisp://dwg/
|
|
911
|
+
{ uri: "atlisp://dwg/text-content", name: "Text Content", description: "\u6587\u672C\u5185\u5BB9\u53CA\u4F4D\u7F6E\uFF0C\u7528\u4E8E\u8BED\u4E49\u5206\u6790\u3002\u652F\u6301 ?layer=0&bbox=0,0,100,100&limit=5000&offset=0", mimeType: "application/json", subscribable: true },
|
|
956
912
|
{ uri: "atlisp://dwg/name", name: "DWG Name", description: "\u5F53\u524D DWG \u6587\u4EF6\u540D", mimeType: "application/json", subscribable: true },
|
|
957
913
|
{ uri: "atlisp://dwg/path", name: "DWG Path", description: "\u6587\u4EF6\u5B8C\u6574\u8DEF\u5F84", mimeType: "application/json", subscribable: true },
|
|
914
|
+
{ uri: "atlisp://dwg/block-refs", name: "Block References", description: "\u5757\u53C2\u7167\u5217\u8868\u53CA\u5C5E\u6027\u503C\u3001\u52A8\u6001\u5757\u7279\u6027\uFF0C\u652F\u6301\u8DEF\u5F84\u65B9\u5F0F atlisp://dwg/block-refs/{blockName}", mimeType: "application/json", subscribable: true },
|
|
915
|
+
{ uri: "atlisp://dwg/tbl", name: "Tables", description: "CAD \u8868\u6570\u636E (layer, block, textstyle, dimstyle, linetype, ucs, view, viewport, regapp)\uFF0C\u652F\u6301\u8DEF\u5F84\u65B9\u5F0F atlisp://dwg/tbl/layer", mimeType: "application/json", subscribable: true },
|
|
958
916
|
{ uri: "atlisp://cad/dwgs", name: "DWG List", description: "\u6240\u6709\u6253\u5F00\u7684 DWG \u6587\u4EF6\u5217\u8868", mimeType: "application/json", subscribable: true },
|
|
959
917
|
{ uri: "atlisp://packages", name: "Packages", description: "\u5DF2\u5B89\u88C5\u5305\u5217\u8868", mimeType: "application/json", subscribable: true },
|
|
960
918
|
{ uri: "atlisp://platforms", name: "Platforms", description: "\u652F\u6301\u7684\u5E73\u53F0\u4FE1\u606F", mimeType: "application/json", subscribable: false },
|
|
@@ -977,9 +935,15 @@ function parseQuery(uri) {
|
|
|
977
935
|
return { base, params };
|
|
978
936
|
}
|
|
979
937
|
function parseTemplateUri(uri) {
|
|
980
|
-
const
|
|
981
|
-
if (
|
|
982
|
-
return { type: "entity", handle:
|
|
938
|
+
const entityMatch = uri.match(/^atlisp:\/\/dwg\/entity\/([^?]+)$/);
|
|
939
|
+
if (entityMatch)
|
|
940
|
+
return { type: "entity", handle: entityMatch[1] };
|
|
941
|
+
const tblMatch = uri.match(/^atlisp:\/\/dwg\/tbl\/([^?]+)$/);
|
|
942
|
+
if (tblMatch)
|
|
943
|
+
return { type: "tbl", tblName: tblMatch[1] };
|
|
944
|
+
const blockRefMatch = uri.match(/^atlisp:\/\/dwg\/block-refs\/([^?]+)$/);
|
|
945
|
+
if (blockRefMatch)
|
|
946
|
+
return { type: "block-refs", blockName: blockRefMatch[1] };
|
|
983
947
|
return null;
|
|
984
948
|
}
|
|
985
949
|
async function listResources(subscribedUris = []) {
|
|
@@ -993,23 +957,33 @@ async function listResources(subscribedUris = []) {
|
|
|
993
957
|
}
|
|
994
958
|
async function readResource(uri) {
|
|
995
959
|
const templateMatch = parseTemplateUri(uri);
|
|
996
|
-
if (templateMatch
|
|
997
|
-
|
|
960
|
+
if (templateMatch) {
|
|
961
|
+
if (templateMatch.type === "entity") {
|
|
962
|
+
return await getEntityByHandle(templateMatch.handle);
|
|
963
|
+
}
|
|
964
|
+
if (templateMatch.type === "tbl") {
|
|
965
|
+
return await getTables({ tbl: templateMatch.tblName });
|
|
966
|
+
}
|
|
967
|
+
if (templateMatch.type === "block-refs") {
|
|
968
|
+
return await getBlockRefs({ blockName: templateMatch.blockName });
|
|
969
|
+
}
|
|
998
970
|
}
|
|
999
971
|
const { base, params } = parseQuery(uri);
|
|
1000
972
|
switch (base) {
|
|
1001
973
|
case "atlisp://cad/info":
|
|
1002
974
|
return await getCadInfo();
|
|
1003
|
-
case "atlisp://dwg/layers":
|
|
1004
|
-
return await getLayers(params.name);
|
|
1005
975
|
case "atlisp://dwg/entities":
|
|
1006
976
|
return await getEntities(params);
|
|
1007
|
-
case "atlisp://dwg/
|
|
1008
|
-
return await
|
|
977
|
+
case "atlisp://dwg/text-content":
|
|
978
|
+
return await getTextContent(params);
|
|
1009
979
|
case "atlisp://dwg/name":
|
|
1010
980
|
return await getDwgName();
|
|
1011
981
|
case "atlisp://dwg/path":
|
|
1012
982
|
return await getDwgPath();
|
|
983
|
+
case "atlisp://dwg/block-refs":
|
|
984
|
+
return await getBlockRefs(params);
|
|
985
|
+
case "atlisp://dwg/tbl":
|
|
986
|
+
return await getTables(params);
|
|
1013
987
|
case "atlisp://cad/dwgs":
|
|
1014
988
|
return await getDwgList();
|
|
1015
989
|
case "atlisp://packages":
|
|
@@ -1086,58 +1060,6 @@ async function getCadInfo() {
|
|
|
1086
1060
|
setCache("cad:info", result);
|
|
1087
1061
|
return result;
|
|
1088
1062
|
}
|
|
1089
|
-
async function getLayers(filterName = null) {
|
|
1090
|
-
const cacheKey = filterName ? `dwg:layers:${filterName}` : "dwg:layers:all";
|
|
1091
|
-
const cached = getCached(cacheKey);
|
|
1092
|
-
if (cached)
|
|
1093
|
-
return cached;
|
|
1094
|
-
if (!cad.connected)
|
|
1095
|
-
await cad.connect();
|
|
1096
|
-
if (!cad.connected)
|
|
1097
|
-
return [];
|
|
1098
|
-
try {
|
|
1099
|
-
const code = filterName ? `(vl-prin1-to-string (cdr (assoc 2 (tblnext "LAYER" T))))` : `(progn (setq res nil)(while (setq e (tblnext "LAYER" (null res)))(setq res (cons (list (vl-prin1-to-string (cdr (assoc 2 e))) (cdr (assoc 62 e)) (cdr (assoc 70 e))) res))) (reverse res))`;
|
|
1100
|
-
const result = await cad.sendCommandWithResult(code);
|
|
1101
|
-
if (!result || result === "" || result === "nil") {
|
|
1102
|
-
setCache(cacheKey, []);
|
|
1103
|
-
return [];
|
|
1104
|
-
}
|
|
1105
|
-
let layers = [];
|
|
1106
|
-
try {
|
|
1107
|
-
layers = JSON.parse(result);
|
|
1108
|
-
} catch (e) {
|
|
1109
|
-
const parsed = parseLispList(result);
|
|
1110
|
-
if (parsed) {
|
|
1111
|
-
layers = parsed;
|
|
1112
|
-
} else {
|
|
1113
|
-
layers = [];
|
|
1114
|
-
}
|
|
1115
|
-
}
|
|
1116
|
-
if (!Array.isArray(layers)) {
|
|
1117
|
-
if (typeof layers === "number") {
|
|
1118
|
-
layers = [[result, layers, 0]];
|
|
1119
|
-
} else if (typeof layers === "string") {
|
|
1120
|
-
layers = [[layers, 7, 0]];
|
|
1121
|
-
}
|
|
1122
|
-
}
|
|
1123
|
-
const mapped = layers.map((l) => {
|
|
1124
|
-
const name = Array.isArray(l) ? l[0] : l;
|
|
1125
|
-
const color = Array.isArray(l) && l[1] !== void 0 ? l[1] : 7;
|
|
1126
|
-
const flags = Array.isArray(l) && l[2] !== void 0 ? l[2] : 0;
|
|
1127
|
-
return {
|
|
1128
|
-
name: String(name),
|
|
1129
|
-
color,
|
|
1130
|
-
locked: (flags & 4) !== 0,
|
|
1131
|
-
frozen: (flags & 1) !== 0
|
|
1132
|
-
};
|
|
1133
|
-
});
|
|
1134
|
-
setCache(cacheKey, mapped);
|
|
1135
|
-
return mapped;
|
|
1136
|
-
} catch (e) {
|
|
1137
|
-
setCache(cacheKey, []);
|
|
1138
|
-
return [];
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
1063
|
async function getEntities(params = {}) {
|
|
1142
1064
|
const cacheKey = `dwg:entities:${JSON.stringify(params)}`;
|
|
1143
1065
|
const cached = getCached(cacheKey);
|
|
@@ -1243,27 +1165,51 @@ async function getEntitiesSummary(cacheKey) {
|
|
|
1243
1165
|
return result;
|
|
1244
1166
|
}
|
|
1245
1167
|
}
|
|
1246
|
-
|
|
1247
|
-
const
|
|
1168
|
+
function buildTextContentCode({ layer, bbox, offset, limit }) {
|
|
1169
|
+
const items = [`'(0 . "TEXT,MTEXT,ATTRIB,TCH_TEXT")`];
|
|
1170
|
+
if (layer)
|
|
1171
|
+
items.push(`(cons 8 "${layer.replace(/"/g, '\\"')}")`);
|
|
1172
|
+
if (bbox) {
|
|
1173
|
+
const parts = bbox.split(",").map((s) => parseFloat(s.trim()));
|
|
1174
|
+
if (parts.length === 4) {
|
|
1175
|
+
const [x1, y1, x2, y2] = parts;
|
|
1176
|
+
items.push(
|
|
1177
|
+
`'(-4 . "<AND")`,
|
|
1178
|
+
`'(-4 . ">=,>=,*") (list 10 ${x1} ${y1} 0.0)`,
|
|
1179
|
+
`'(-4 . "<=,<=,*") (list 10 ${x2} ${y2} 0.0)`,
|
|
1180
|
+
`'(-4 . "AND>")`
|
|
1181
|
+
);
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
const filterExpr = `(list ${items.join(" ")})`;
|
|
1185
|
+
return `(progn
|
|
1186
|
+
(setq ss (ssget "_X" ${filterExpr}))
|
|
1187
|
+
(if (null ss)
|
|
1188
|
+
(list "total" 0 "offset" ${offset} "limit" ${limit} "texts" nil)
|
|
1189
|
+
(progn
|
|
1190
|
+
(setq total (sslength ss) i ${offset} texts nil)
|
|
1191
|
+
(while (and (< i total) (< (length texts) ${limit}))
|
|
1192
|
+
(setq ent (ssname ss i) ed (entget ent) ins (cdr (assoc 10 ed)))
|
|
1193
|
+
(setq texts (append texts (list (list "text" (vl-prin1-to-string (cdr (assoc 1 ed))) "position" (list (car ins) (cadr ins) (caddr ins))))) i (1+ i)))
|
|
1194
|
+
(list "total" total "offset" ${offset} "limit" ${limit} "texts" texts))))
|
|
1195
|
+
)`;
|
|
1196
|
+
}
|
|
1197
|
+
async function getTextContent(params = {}) {
|
|
1198
|
+
const cacheKey = `dwg:text-content:${JSON.stringify(params)}`;
|
|
1248
1199
|
const cached = getCached(cacheKey);
|
|
1249
1200
|
if (cached)
|
|
1250
1201
|
return cached;
|
|
1251
1202
|
if (!cad.connected)
|
|
1252
1203
|
await cad.connect();
|
|
1253
1204
|
if (!cad.connected) {
|
|
1254
|
-
const result = { total: 0, texts: [] };
|
|
1205
|
+
const result = { total: 0, offset: 0, limit: 5e3, texts: [] };
|
|
1255
1206
|
setCache(cacheKey, result);
|
|
1256
1207
|
return result;
|
|
1257
1208
|
}
|
|
1258
1209
|
const offset = Math.max(0, parseInt(params.offset) || 0);
|
|
1259
1210
|
const limit = Math.min(Math.max(1, parseInt(params.limit) || 5e3), 5e3);
|
|
1260
1211
|
try {
|
|
1261
|
-
const code =
|
|
1262
|
-
layer: params.layer || null,
|
|
1263
|
-
bbox: params.bbox || null,
|
|
1264
|
-
offset,
|
|
1265
|
-
limit
|
|
1266
|
-
});
|
|
1212
|
+
const code = buildTextContentCode({ layer: params.layer, bbox: params.bbox, offset, limit });
|
|
1267
1213
|
const resultStr = await cad.sendCommandWithResult(code);
|
|
1268
1214
|
if (!resultStr || resultStr === "" || resultStr === "nil" || resultStr === "0") {
|
|
1269
1215
|
const result = { total: 0, offset, limit, texts: [] };
|
|
@@ -1271,16 +1217,32 @@ async function getTexts(params = {}) {
|
|
|
1271
1217
|
return result;
|
|
1272
1218
|
}
|
|
1273
1219
|
const parsed = parseLispRecursive(resultStr);
|
|
1274
|
-
|
|
1275
|
-
|
|
1220
|
+
if (!parsed || !Array.isArray(parsed)) {
|
|
1221
|
+
const result = { total: 0, offset, limit, texts: [] };
|
|
1222
|
+
setCache(cacheKey, result);
|
|
1223
|
+
return result;
|
|
1224
|
+
}
|
|
1276
1225
|
const data = lispPairsToObject(parsed);
|
|
1277
|
-
|
|
1278
|
-
data.
|
|
1279
|
-
|
|
1226
|
+
const rawTexts = Array.isArray(data.texts) ? data.texts : [];
|
|
1227
|
+
data.texts = rawTexts.map((item) => {
|
|
1228
|
+
if (!Array.isArray(item))
|
|
1229
|
+
return null;
|
|
1230
|
+
const obj = {};
|
|
1231
|
+
item.forEach((pair) => {
|
|
1232
|
+
if (Array.isArray(pair) && pair.length >= 2) {
|
|
1233
|
+
if (pair[0] === "text")
|
|
1234
|
+
obj.text = String(pair[1] || "");
|
|
1235
|
+
else if (pair[0] === "position" && Array.isArray(pair[1])) {
|
|
1236
|
+
obj.position = pair[1].map((v) => typeof v === "number" ? v : 0);
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
});
|
|
1240
|
+
return obj.text ? obj : null;
|
|
1241
|
+
}).filter(Boolean);
|
|
1280
1242
|
setCache(cacheKey, data);
|
|
1281
1243
|
return data;
|
|
1282
1244
|
} catch (e) {
|
|
1283
|
-
log(`
|
|
1245
|
+
log(`getTextContent error: ${e.message}`);
|
|
1284
1246
|
const result = { total: 0, offset, limit, texts: [] };
|
|
1285
1247
|
setCache(cacheKey, result);
|
|
1286
1248
|
return result;
|
|
@@ -1332,6 +1294,316 @@ async function getDwgPath() {
|
|
|
1332
1294
|
return { path: null, name: null };
|
|
1333
1295
|
}
|
|
1334
1296
|
}
|
|
1297
|
+
function buildBlockRefsCode(filterBlockName) {
|
|
1298
|
+
const filterExpr = filterBlockName ? `(list (cons 2 "${filterBlockName.replace(/"/g, '\\"')}"))` : "nil";
|
|
1299
|
+
return `(progn
|
|
1300
|
+
(vl-load-com)
|
|
1301
|
+
(defun @br:attr (ent / atts)
|
|
1302
|
+
(if (= (type ent) 'VLA-OBJECT)
|
|
1303
|
+
(progn
|
|
1304
|
+
(setq atts (vlax-variant-value (vla-getattributes ent)))
|
|
1305
|
+
(if (safearray-value atts)
|
|
1306
|
+
(mapcar '(lambda (x) (cons (vla-get-tagstring x) (vla-get-textstring x)))
|
|
1307
|
+
(vlax-safearray->list atts))
|
|
1308
|
+
nil))
|
|
1309
|
+
(if (setq att (entnext ent))
|
|
1310
|
+
(progn
|
|
1311
|
+
(setq atts nil)
|
|
1312
|
+
(while (= (cdr (assoc 0 (entget att))) "ATTRIB")
|
|
1313
|
+
(setq atts (cons (cons (cdr (assoc 2 (entget att))) (cdr (assoc 1 (entget att)))) atts))
|
|
1314
|
+
att (entnext att))
|
|
1315
|
+
(reverse atts))
|
|
1316
|
+
nil))))
|
|
1317
|
+
|
|
1318
|
+
(defun @br:dynprops (ent / obj props)
|
|
1319
|
+
(if (= (type ent) 'VLA-OBJECT)
|
|
1320
|
+
(progn
|
|
1321
|
+
(setq obj ent)
|
|
1322
|
+
(if (vlax-property-available-p obj 'isdynamicblock)
|
|
1323
|
+
(if (vla-get-isdynamicblock obj)
|
|
1324
|
+
(progn
|
|
1325
|
+
(setq props (vlax-invoke obj 'getdynamicblockproperties))
|
|
1326
|
+
(mapcar '(lambda (x)
|
|
1327
|
+
(cons (vla-get-propertyname x)
|
|
1328
|
+
(list (cons "value" (vla-get-value x))
|
|
1329
|
+
(cons "readOnly" (vla-get-readonly x))
|
|
1330
|
+
(cons "show" (vla-get-show x)))))
|
|
1331
|
+
(vlax-safearray->list props)))
|
|
1332
|
+
nil)
|
|
1333
|
+
nil))
|
|
1334
|
+
(if (and (setq obj (vlax-ename->vla-object ent))
|
|
1335
|
+
(vlax-property-available-p obj 'isdynamicblock)
|
|
1336
|
+
(vla-get-isdynamicblock obj))
|
|
1337
|
+
(progn
|
|
1338
|
+
(setq props (vlax-invoke obj 'getdynamicblockproperties))
|
|
1339
|
+
(mapcar '(lambda (x)
|
|
1340
|
+
(cons (vla-get-propertyname x)
|
|
1341
|
+
(list (cons "value" (vla-get-value x))
|
|
1342
|
+
(cons "readOnly" (vla-get-readonly x))
|
|
1343
|
+
(cons "show" (vla-get-show x)))))
|
|
1344
|
+
(vlax-safearray->list props)))
|
|
1345
|
+
nil)))
|
|
1346
|
+
|
|
1347
|
+
(defun @br:props (ent / obj blkname result)
|
|
1348
|
+
(setq obj (vlax-ename->vla-object ent))
|
|
1349
|
+
(setq result (list
|
|
1350
|
+
(cons "handle" (cdr (assoc 5 (entget ent))))
|
|
1351
|
+
(cons "layer" (cdr (assoc 8 (entget ent))))
|
|
1352
|
+
(cons "blockName" (vla-get-name obj))
|
|
1353
|
+
(cons "effectiveBlockName" (vla-get-effectivename obj))
|
|
1354
|
+
(cons "insertionPoint" (vlax-safearray->list (vla-get-insertionpoint obj)))
|
|
1355
|
+
(cons "rotation" (vla-get-rotation obj))
|
|
1356
|
+
(cons "scale" (list (vla-get-xscale obj) (vla-get-yscale obj) (vla-get-zscale obj)))
|
|
1357
|
+
(cons "isDynamic" (if (vlax-property-available-p obj 'isdynamicblock) (vla-get-isdynamicblock obj) nil))
|
|
1358
|
+
(cons "attributes" (@br:attr obj))
|
|
1359
|
+
(cons "dynamicProperties" (@br:dynprops obj))))
|
|
1360
|
+
result)
|
|
1361
|
+
|
|
1362
|
+
(setq ss (ssget "_X" (list (cons 0 "INSERT") ${filterExpr})))
|
|
1363
|
+
(if (null ss)
|
|
1364
|
+
(list (cons "total" 0) (cons "blockRefs" nil))
|
|
1365
|
+
(progn
|
|
1366
|
+
(setq total (sslength ss) i 0 refs nil)
|
|
1367
|
+
(while (< i total)
|
|
1368
|
+
(setq refs (cons (@br:props (ssname ss i)) refs) i (1+ i)))
|
|
1369
|
+
(list (cons "total" total) (cons "blockRefs" (reverse refs))))))`;
|
|
1370
|
+
}
|
|
1371
|
+
async function getBlockRefs(params = {}) {
|
|
1372
|
+
const cacheKey = `dwg:block-refs:${params.blockName || "all"}`;
|
|
1373
|
+
const cached = getCached(cacheKey);
|
|
1374
|
+
if (cached)
|
|
1375
|
+
return cached;
|
|
1376
|
+
if (!cad.connected)
|
|
1377
|
+
await cad.connect();
|
|
1378
|
+
if (!cad.connected) {
|
|
1379
|
+
const result = { total: 0, blockRefs: [] };
|
|
1380
|
+
setCache(cacheKey, result);
|
|
1381
|
+
return result;
|
|
1382
|
+
}
|
|
1383
|
+
try {
|
|
1384
|
+
const code = buildBlockRefsCode(params.blockName);
|
|
1385
|
+
const resultStr = await cad.sendCommandWithResult(code);
|
|
1386
|
+
if (!resultStr || resultStr === "" || resultStr === "nil") {
|
|
1387
|
+
const result2 = { total: 0, blockRefs: [] };
|
|
1388
|
+
setCache(cacheKey, result2);
|
|
1389
|
+
return result2;
|
|
1390
|
+
}
|
|
1391
|
+
const parsed = parseLispRecursive(resultStr);
|
|
1392
|
+
if (!parsed || !Array.isArray(parsed)) {
|
|
1393
|
+
const result2 = { total: 0, blockRefs: [] };
|
|
1394
|
+
setCache(cacheKey, result2);
|
|
1395
|
+
return result2;
|
|
1396
|
+
}
|
|
1397
|
+
const result = lispPairsToObject(parsed);
|
|
1398
|
+
const blockRefs = Array.isArray(result.blockRefs) ? result.blockRefs : [];
|
|
1399
|
+
const finalResult = {
|
|
1400
|
+
total: typeof result.total === "number" ? result.total : blockRefs.length,
|
|
1401
|
+
blockRefs: blockRefs.map((br) => {
|
|
1402
|
+
const obj = {};
|
|
1403
|
+
if (Array.isArray(br)) {
|
|
1404
|
+
br.forEach((pair) => {
|
|
1405
|
+
if (Array.isArray(pair) && pair.length >= 2) {
|
|
1406
|
+
const key = pair[0];
|
|
1407
|
+
let val = pair[1];
|
|
1408
|
+
if (key === "insertionPoint" && Array.isArray(val)) {
|
|
1409
|
+
val = val.map((v) => typeof v === "number" ? v : 0);
|
|
1410
|
+
} else if (key === "scale" && Array.isArray(val)) {
|
|
1411
|
+
val = val.map((v) => typeof v === "number" ? v : 1);
|
|
1412
|
+
} else if (key === "isDynamic") {
|
|
1413
|
+
val = val === true || val === "true" || val === 1;
|
|
1414
|
+
}
|
|
1415
|
+
obj[key] = val;
|
|
1416
|
+
}
|
|
1417
|
+
});
|
|
1418
|
+
}
|
|
1419
|
+
return obj;
|
|
1420
|
+
})
|
|
1421
|
+
};
|
|
1422
|
+
setCache(cacheKey, finalResult);
|
|
1423
|
+
return finalResult;
|
|
1424
|
+
} catch (e) {
|
|
1425
|
+
log(`getBlockRefs error: ${e.message}`);
|
|
1426
|
+
const result = { total: 0, blockRefs: [] };
|
|
1427
|
+
setCache(cacheKey, result);
|
|
1428
|
+
return result;
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
var TBL_QUERIES = {
|
|
1432
|
+
layer: { name: "layer", lisp: `(progn
|
|
1433
|
+
(setq @d nil)
|
|
1434
|
+
(vlax-for e (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))
|
|
1435
|
+
(setq @d (cons (list
|
|
1436
|
+
(cons 2 (vla-get-name e))
|
|
1437
|
+
(cons 62 (vla-get-color e))
|
|
1438
|
+
(cons 6 (vla-get-linetype e))
|
|
1439
|
+
(cons 70 (logior (if (vla-get-freeze e) 1 0) (if (vla-get-lock e) 4 0)))
|
|
1440
|
+
(cons 60 (if (vla-get-layeron e) 0 1))
|
|
1441
|
+
) @d)))
|
|
1442
|
+
(list (cons 'table 'layer) (cons 'total (length @d)) (cons 'data (list (reverse @d)))))` },
|
|
1443
|
+
block: { name: "block", lisp: `(progn
|
|
1444
|
+
(setq @d nil)
|
|
1445
|
+
(vlax-for e (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
|
|
1446
|
+
(if (not (and (vlax-property-available-p e 'isfoundation) (vlax-get e 'isfoundation)))
|
|
1447
|
+
(setq @d (cons (list (cons 2 (vla-get-name e)) (cons 70 (if (and (vlax-property-available-p e 'isxref) (vlax-get e 'isxref)) 1 0))) @d))))
|
|
1448
|
+
(list (cons 'table 'block) (cons 'total (length @d)) (cons 'data (list (reverse @d)))))` },
|
|
1449
|
+
style: { name: "style", lisp: `(progn
|
|
1450
|
+
(setq @d nil)
|
|
1451
|
+
(vlax-for e (vla-get-textstyles (vla-get-activedocument (vlax-get-acad-object)))
|
|
1452
|
+
(setq @d (cons (list (cons 2 (vla-get-name e)) (cons 70 0)) @d)))
|
|
1453
|
+
(list (cons 'table 'style) (cons 'total (length @d)) (cons 'data (list (reverse @d)))))` },
|
|
1454
|
+
dimstyle: { name: "dimstyle", lisp: `(progn
|
|
1455
|
+
(setq @d nil)
|
|
1456
|
+
(vlax-for e (vla-get-dimstyles (vla-get-activedocument (vlax-get-acad-object)))
|
|
1457
|
+
(setq @d (cons (list (cons 2 (vla-get-name e)) (cons 70 0)) @d)))
|
|
1458
|
+
(list (cons 'table 'dimstyle) (cons 'total (length @d)) (cons 'data (list (reverse @d)))))` },
|
|
1459
|
+
ltype: { name: "linetype", lisp: `(progn
|
|
1460
|
+
(setq @d nil)
|
|
1461
|
+
(vlax-for e (vla-get-linetypes (vla-get-activedocument (vlax-get-acad-object)))
|
|
1462
|
+
(setq @d (cons (list (cons 2 (vla-get-name e)) (cons 70 0)) @d)))
|
|
1463
|
+
(list (cons 'table 'linetype) (cons 'total (length @d)) (cons 'data (list (reverse @d)))))` }
|
|
1464
|
+
};
|
|
1465
|
+
function buildTablesCode(tblName) {
|
|
1466
|
+
const key = tblName.toLowerCase();
|
|
1467
|
+
const query = TBL_QUERIES[key];
|
|
1468
|
+
if (query) {
|
|
1469
|
+
return `(progn (vl-load-com) ${query.lisp})`;
|
|
1470
|
+
}
|
|
1471
|
+
const parts = Object.values(TBL_QUERIES).map((q) => q.lisp);
|
|
1472
|
+
return `(progn (vl-load-com) (list ${parts.join(" ")}))`;
|
|
1473
|
+
}
|
|
1474
|
+
function parseTableRecord(rec) {
|
|
1475
|
+
if (!rec || !Array.isArray(rec))
|
|
1476
|
+
return null;
|
|
1477
|
+
const obj = {};
|
|
1478
|
+
for (const pair of rec) {
|
|
1479
|
+
if (Array.isArray(pair) && pair.length >= 2) {
|
|
1480
|
+
const key = String(pair[0]);
|
|
1481
|
+
const val = pair[1];
|
|
1482
|
+
if (key === "2")
|
|
1483
|
+
obj.name = String(val);
|
|
1484
|
+
else if (key === "62")
|
|
1485
|
+
obj.color = typeof val === "number" ? val : 7;
|
|
1486
|
+
else if (key === "6")
|
|
1487
|
+
obj.linetype = String(val);
|
|
1488
|
+
else if (key === "70") {
|
|
1489
|
+
obj.flags = typeof val === "number" ? val : 0;
|
|
1490
|
+
obj.frozen = (val & 1) !== 0;
|
|
1491
|
+
obj.locked = (val & 4) !== 0;
|
|
1492
|
+
} else if (key === "60")
|
|
1493
|
+
obj.on = val === 0;
|
|
1494
|
+
else if (key === "1")
|
|
1495
|
+
obj.font = String(val);
|
|
1496
|
+
else if (key === "40")
|
|
1497
|
+
obj.height = typeof val === "number" ? val : 0;
|
|
1498
|
+
else if (key === "41")
|
|
1499
|
+
obj.width = typeof val === "number" ? val : 1;
|
|
1500
|
+
else if (key === "42")
|
|
1501
|
+
obj.oblique = typeof val === "number" ? val : 0;
|
|
1502
|
+
else if (key === "3")
|
|
1503
|
+
obj.description = String(val);
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
return obj.name ? obj : null;
|
|
1507
|
+
}
|
|
1508
|
+
async function getTables(params = {}) {
|
|
1509
|
+
const tblName = params.tbl || params.type || "all";
|
|
1510
|
+
const cacheKey = `dwg:tbl:${tblName}`;
|
|
1511
|
+
const cached = getCached(cacheKey);
|
|
1512
|
+
if (cached)
|
|
1513
|
+
return cached;
|
|
1514
|
+
if (!cad.connected)
|
|
1515
|
+
await cad.connect();
|
|
1516
|
+
if (!cad.connected)
|
|
1517
|
+
return { table: tblName, data: [] };
|
|
1518
|
+
try {
|
|
1519
|
+
const code = buildTablesCode(tblName);
|
|
1520
|
+
const resultStr = await cad.sendCommandWithResult(code);
|
|
1521
|
+
if (!resultStr || resultStr === "" || resultStr === "nil") {
|
|
1522
|
+
const result2 = { table: tblName, data: [] };
|
|
1523
|
+
setCache(cacheKey, result2);
|
|
1524
|
+
return result2;
|
|
1525
|
+
}
|
|
1526
|
+
const parsed = parseLispRecursive(resultStr);
|
|
1527
|
+
if (!parsed || !Array.isArray(parsed)) {
|
|
1528
|
+
const result2 = { table: tblName, total: 0, data: [] };
|
|
1529
|
+
setCache(cacheKey, result2);
|
|
1530
|
+
return result2;
|
|
1531
|
+
}
|
|
1532
|
+
let result;
|
|
1533
|
+
if (parsed.length >= 3 && parsed[0] && String(parsed[0][0]).toUpperCase() === "TABLE") {
|
|
1534
|
+
const tableName = String(parsed[0][1]).toLowerCase();
|
|
1535
|
+
let total = 0;
|
|
1536
|
+
let tblData = [];
|
|
1537
|
+
for (const item of parsed) {
|
|
1538
|
+
if (Array.isArray(item) && item.length >= 2) {
|
|
1539
|
+
const key = String(item[0]).toUpperCase();
|
|
1540
|
+
if (key === "TOTAL")
|
|
1541
|
+
total = typeof item[1] === "number" ? item[1] : 0;
|
|
1542
|
+
else if (key === "DATA") {
|
|
1543
|
+
if (Array.isArray(item[1]) && item[1].length > 0 && item[1][0].length > 0 && !isNaN(parseInt(item[1][0][0]))) {
|
|
1544
|
+
tblData = item[1];
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
if (tblData.length === 0 && parsed.length > 2) {
|
|
1550
|
+
tblData = parsed.slice(2);
|
|
1551
|
+
}
|
|
1552
|
+
result = {
|
|
1553
|
+
table: tableName,
|
|
1554
|
+
total,
|
|
1555
|
+
data: tblData.map(parseTableRecord).filter(Boolean)
|
|
1556
|
+
};
|
|
1557
|
+
} else {
|
|
1558
|
+
const allData = {};
|
|
1559
|
+
parsed.forEach((item) => {
|
|
1560
|
+
if (!Array.isArray(item) || item.length < 2)
|
|
1561
|
+
return;
|
|
1562
|
+
let tableKey = null;
|
|
1563
|
+
const entry = { total: 0, data: [] };
|
|
1564
|
+
if (Array.isArray(item[0]) && item[0].length >= 2 && String(item[0][0]).toLowerCase() === "table") {
|
|
1565
|
+
tableKey = String(item[0][1]).toLowerCase();
|
|
1566
|
+
for (let i = 1; i < item.length; i++) {
|
|
1567
|
+
const sub = item[i];
|
|
1568
|
+
if (!Array.isArray(sub) || sub.length < 2)
|
|
1569
|
+
continue;
|
|
1570
|
+
const subKey = String(sub[0]).toUpperCase();
|
|
1571
|
+
if (subKey === "TOTAL")
|
|
1572
|
+
entry.total = typeof sub[1] === "number" ? sub[1] : 0;
|
|
1573
|
+
else if (subKey === "DATA") {
|
|
1574
|
+
const raw = Array.isArray(sub[1]) ? sub[1] : sub.slice(1);
|
|
1575
|
+
entry.data = raw.map(parseTableRecord).filter(Boolean);
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
} else {
|
|
1579
|
+
tableKey = String(item[0]).toLowerCase();
|
|
1580
|
+
for (let i = 1; i < item.length; i++) {
|
|
1581
|
+
const sub = item[i];
|
|
1582
|
+
if (!Array.isArray(sub) || sub.length < 2)
|
|
1583
|
+
continue;
|
|
1584
|
+
const subKey = String(sub[0]).toUpperCase();
|
|
1585
|
+
if (subKey === "TOTAL") {
|
|
1586
|
+
entry.total = typeof sub[1] === "number" ? sub[1] : 0;
|
|
1587
|
+
} else if (subKey === "DATA") {
|
|
1588
|
+
const raw = Array.isArray(sub[1]) ? sub[1] : sub.slice(1);
|
|
1589
|
+
entry.data = raw.map(parseTableRecord).filter(Boolean);
|
|
1590
|
+
}
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
if (tableKey)
|
|
1594
|
+
allData[tableKey] = entry;
|
|
1595
|
+
});
|
|
1596
|
+
result = allData;
|
|
1597
|
+
}
|
|
1598
|
+
setCache(cacheKey, result);
|
|
1599
|
+
return result;
|
|
1600
|
+
} catch (e) {
|
|
1601
|
+
log(`getTables error: ${e.message}`);
|
|
1602
|
+
const result = { table: tblName, data: [] };
|
|
1603
|
+
setCache(cacheKey, result);
|
|
1604
|
+
return result;
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1335
1607
|
async function getPackages(filterName = null) {
|
|
1336
1608
|
const cacheKey = filterName ? `packages:${filterName}` : "packages:all";
|
|
1337
1609
|
const cached = getCached(cacheKey);
|
|
@@ -3018,12 +3290,6 @@ var RESOURCE_TEMPLATES = [
|
|
|
3018
3290
|
description: "\u6309 type/layer/bbox \u8FC7\u6EE4\u56FE\u5143\uFF0C\u8FD4\u56DE entity:properties \u5168\u5C5E\u6027 JSON\uFF08ObjectName, Handle, Layer, Color, Center, Radius \u7B49\uFF09",
|
|
3019
3291
|
mimeType: "application/json"
|
|
3020
3292
|
},
|
|
3021
|
-
{
|
|
3022
|
-
uriTemplate: "atlisp://dwg/layers?name={name}",
|
|
3023
|
-
name: "Layer by Name",
|
|
3024
|
-
description: "\u6309\u540D\u79F0\u67E5\u8BE2\u56FE\u5C42",
|
|
3025
|
-
mimeType: "application/json"
|
|
3026
|
-
},
|
|
3027
3293
|
{
|
|
3028
3294
|
uriTemplate: "atlisp://packages?search={query}",
|
|
3029
3295
|
name: "Package Search",
|
|
@@ -3031,9 +3297,21 @@ var RESOURCE_TEMPLATES = [
|
|
|
3031
3297
|
mimeType: "application/json"
|
|
3032
3298
|
},
|
|
3033
3299
|
{
|
|
3034
|
-
uriTemplate: "atlisp://dwg/
|
|
3035
|
-
name: "
|
|
3036
|
-
description: "\
|
|
3300
|
+
uriTemplate: "atlisp://dwg/block-refs/{blockName}",
|
|
3301
|
+
name: "Block References",
|
|
3302
|
+
description: "\u83B7\u53D6\u5757\u53C2\u7167\u5217\u8868\uFF0C\u652F\u6301\u6309\u5757\u540D\u8FC7\u6EE4",
|
|
3303
|
+
mimeType: "application/json"
|
|
3304
|
+
},
|
|
3305
|
+
{
|
|
3306
|
+
uriTemplate: "atlisp://dwg/tbl/{tbl}",
|
|
3307
|
+
name: "CAD Tables",
|
|
3308
|
+
description: "\u83B7\u53D6 CAD \u8868\u6570\u636E (layer, block, textstyle, dimstyle, linetype, ucs, view, regapp)",
|
|
3309
|
+
mimeType: "application/json"
|
|
3310
|
+
},
|
|
3311
|
+
{
|
|
3312
|
+
uriTemplate: "atlisp://dwg/text-content?bbox={bbox}&layer={layer}&offset={offset}&limit={limit}",
|
|
3313
|
+
name: "Text Content",
|
|
3314
|
+
description: "\u6587\u672C\u5185\u5BB9\u53CA\u4F4D\u7F6E\uFF0C\u7528\u4E8E\u8BED\u4E49\u5206\u6790",
|
|
3037
3315
|
mimeType: "application/json"
|
|
3038
3316
|
}
|
|
3039
3317
|
];
|
|
@@ -8377,25 +8655,27 @@ var tools = [
|
|
|
8377
8655
|
];
|
|
8378
8656
|
function notifyResourceChanges(toolName) {
|
|
8379
8657
|
const resourceMap = {
|
|
8380
|
-
connect_cad: ["atlisp://cad/info", "atlisp://dwg/
|
|
8381
|
-
new_document: ["atlisp://dwg/name", "atlisp://dwg/path", "atlisp://cad/dwgs", "atlisp://dwg/
|
|
8658
|
+
connect_cad: ["atlisp://cad/info", "atlisp://dwg/tbl", "atlisp://dwg/name", "atlisp://dwg/path", "atlisp://cad/dwgs", "atlisp://packages"],
|
|
8659
|
+
new_document: ["atlisp://dwg/name", "atlisp://dwg/path", "atlisp://cad/dwgs", "atlisp://dwg/tbl", "atlisp://dwg/entities", "atlisp://dwg/text-content"],
|
|
8382
8660
|
install_package: ["atlisp://packages"],
|
|
8383
8661
|
install_atlisp: ["atlisp://packages", "atlisp://cad/info"],
|
|
8384
8662
|
init_atlisp: ["atlisp://packages", "atlisp://cad/info"],
|
|
8385
|
-
create_layer: ["atlisp://dwg/
|
|
8386
|
-
delete_layer: ["atlisp://dwg/
|
|
8387
|
-
set_layer: ["atlisp://dwg/
|
|
8388
|
-
set_current_layer: ["atlisp://dwg/
|
|
8389
|
-
create_block: ["atlisp://dwg/
|
|
8390
|
-
open_dwg: ["atlisp://dwg/name", "atlisp://dwg/path", "atlisp://cad/dwgs", "atlisp://dwg/
|
|
8663
|
+
create_layer: ["atlisp://dwg/tbl"],
|
|
8664
|
+
delete_layer: ["atlisp://dwg/tbl"],
|
|
8665
|
+
set_layer: ["atlisp://dwg/tbl"],
|
|
8666
|
+
set_current_layer: ["atlisp://dwg/tbl"],
|
|
8667
|
+
create_block: ["atlisp://dwg/block-refs", "atlisp://dwg/tbl"],
|
|
8668
|
+
open_dwg: ["atlisp://dwg/name", "atlisp://dwg/path", "atlisp://cad/dwgs", "atlisp://dwg/tbl", "atlisp://dwg/entities", "atlisp://dwg/block-refs", "atlisp://dwg/text-content"],
|
|
8391
8669
|
save_dwg: ["atlisp://dwg/name", "atlisp://dwg/path"],
|
|
8392
8670
|
export_pdf: [],
|
|
8393
|
-
close_dwg: ["atlisp://dwg/name", "atlisp://dwg/path", "atlisp://cad/dwgs"],
|
|
8394
|
-
|
|
8395
|
-
|
|
8671
|
+
close_dwg: ["atlisp://dwg/name", "atlisp://dwg/path", "atlisp://cad/dwgs", "atlisp://dwg/block-refs", "atlisp://dwg/text-content"],
|
|
8672
|
+
delete_entity: ["atlisp://dwg/entities", "atlisp://dwg/block-refs"],
|
|
8673
|
+
batch_delete: ["atlisp://dwg/entities", "atlisp://dwg/block-refs"],
|
|
8674
|
+
batch_explode: ["atlisp://dwg/entities", "atlisp://dwg/block-refs"],
|
|
8675
|
+
explode_block: ["atlisp://dwg/entities", "atlisp://dwg/block-refs"],
|
|
8396
8676
|
batch_set_color: ["atlisp://dwg/entities"],
|
|
8397
8677
|
batch_set_linetype: ["atlisp://dwg/entities"],
|
|
8398
|
-
batch_move: ["atlisp://dwg/entities", "atlisp://dwg/
|
|
8678
|
+
batch_move: ["atlisp://dwg/entities", "atlisp://dwg/tbl"],
|
|
8399
8679
|
batch_rename: ["atlisp://dwg/entities"],
|
|
8400
8680
|
batch_create_group: ["atlisp://dwg/groups"],
|
|
8401
8681
|
batch_add_to_group: ["atlisp://dwg/groups"],
|
|
@@ -8421,10 +8701,10 @@ function notifyResourceChanges(toolName) {
|
|
|
8421
8701
|
thicken_surface: ["atlisp://dwg/entities"],
|
|
8422
8702
|
create_region: ["atlisp://dwg/entities"],
|
|
8423
8703
|
create_loft_surface: ["atlisp://dwg/entities"],
|
|
8424
|
-
create_dimension_style: [],
|
|
8425
|
-
create_text_style: [],
|
|
8426
|
-
create_linetype: [],
|
|
8427
|
-
load_linetype: [],
|
|
8704
|
+
create_dimension_style: ["atlisp://dwg/tbl"],
|
|
8705
|
+
create_text_style: ["atlisp://dwg/tbl"],
|
|
8706
|
+
create_linetype: ["atlisp://dwg/tbl"],
|
|
8707
|
+
load_linetype: ["atlisp://dwg/tbl"],
|
|
8428
8708
|
attach_pdf: ["atlisp://dwg/entities"],
|
|
8429
8709
|
detach_pdf: ["atlisp://dwg/entities"],
|
|
8430
8710
|
import_dxf: ["atlisp://dwg/entities"],
|
|
@@ -9038,7 +9318,7 @@ Options:
|
|
|
9038
9318
|
--port <port> HTTP port (default: 8110)
|
|
9039
9319
|
--host <host> HTTP host (default: 0.0.0.0)
|
|
9040
9320
|
--stdio Shorthand for --transport stdio
|
|
9041
|
-
--config <path> Path to config file (default:
|
|
9321
|
+
--config <path> Path to config file (default: ~/.atlisp/atlisp.config.json)
|
|
9042
9322
|
--debug Enable debug mode
|
|
9043
9323
|
|
|
9044
9324
|
Environment Variables:
|
package/dist/cad-worker.js
CHANGED
|
@@ -124,29 +124,32 @@ const cadSendWithResult = edge.func(function() {/*
|
|
|
124
124
|
async (input) => {
|
|
125
125
|
string tempFile = null;
|
|
126
126
|
string lispFile = null;
|
|
127
|
+
string userCodeFile = null;
|
|
127
128
|
try {
|
|
128
129
|
dynamic d = input;
|
|
129
130
|
string code = d.code.ToString();
|
|
130
131
|
string platform = d.platform.ToString();
|
|
131
132
|
string encoding = d.encoding != null ? d.encoding.ToString() : "";
|
|
132
|
-
string progId = platform == "BricsCAD" ? "BricscadApp.
|
|
133
|
+
string progId = platform == "BricsCAD" ? "BricscadApp.AcadApplication" : platform + ".Application";
|
|
133
134
|
string tempDir = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "@lisp", "tmp");
|
|
134
135
|
System.IO.Directory.CreateDirectory(tempDir);
|
|
135
136
|
|
|
136
137
|
tempFile = System.IO.Path.Combine(tempDir, "atlisp_result_" + System.Guid.NewGuid().ToString("N") + ".txt");
|
|
137
138
|
lispFile = System.IO.Path.Combine(tempDir, "atlisp_code_" + System.Guid.NewGuid().ToString("N") + ".lsp");
|
|
139
|
+
userCodeFile = System.IO.Path.Combine(tempDir, "atlisp_user_" + System.Guid.NewGuid().ToString("N") + ".lsp");
|
|
140
|
+
|
|
141
|
+
// 用户代码单独写入文件,避免拼接注入风险
|
|
142
|
+
System.IO.File.WriteAllText(userCodeFile, code, System.Text.Encoding.GetEncoding(System.Globalization.CultureInfo.CurrentCulture.TextInfo.ANSICodePage));
|
|
138
143
|
|
|
139
|
-
// 生成 LISP 代码:使用 vl-catch-all-apply 捕获结果和错误
|
|
140
|
-
// 返回 (success . result) 或 (nil . error-msg)
|
|
141
144
|
string lispCode = "(progn"
|
|
142
145
|
+ "(setq f(open \"" + tempFile.Replace("\\", "\\\\") + "\" \"w\"))"
|
|
143
|
-
+ "(setq r(vl-catch-all-apply '(lambda ()(
|
|
146
|
+
+ "(setq r(vl-catch-all-apply '(lambda ()(load \"" + userCodeFile.Replace("\\", "\\\\") + "\"))))"
|
|
144
147
|
+ "(if (vl-catch-all-error-p r)"
|
|
145
148
|
+ "(princ(strcat \"ERROR:\"(vl-catch-all-error-message r)) f)"
|
|
146
149
|
+ "(princ r f))"
|
|
147
150
|
+ "(close f)"
|
|
148
151
|
+ "(princ))";
|
|
149
|
-
|
|
152
|
+
|
|
150
153
|
// 使用系统 ANSI 编码以兼容 GstarCAD / ZWCAD
|
|
151
154
|
System.IO.File.WriteAllText(lispFile, lispCode, System.Text.Encoding.GetEncoding(System.Globalization.CultureInfo.CurrentCulture.TextInfo.ANSICodePage));
|
|
152
155
|
|
|
@@ -201,6 +204,7 @@ string encoding = d.encoding != null ? d.encoding.ToString() : "";
|
|
|
201
204
|
|
|
202
205
|
try { System.IO.File.Delete(tempFile); } catch {}
|
|
203
206
|
try { System.IO.File.Delete(lispFile); } catch {}
|
|
207
|
+
try { System.IO.File.Delete(userCodeFile); } catch {}
|
|
204
208
|
break;
|
|
205
209
|
} catch (System.IO.IOException) {
|
|
206
210
|
System.Threading.Thread.Sleep(200);
|
|
@@ -223,6 +227,9 @@ string encoding = d.encoding != null ? d.encoding.ToString() : "";
|
|
|
223
227
|
if (lispFile != null) {
|
|
224
228
|
try { if (System.IO.File.Exists(lispFile)) System.IO.File.Delete(lispFile); } catch {}
|
|
225
229
|
}
|
|
230
|
+
if (userCodeFile != null) {
|
|
231
|
+
try { if (System.IO.File.Exists(userCodeFile)) System.IO.File.Delete(userCodeFile); } catch {}
|
|
232
|
+
}
|
|
226
233
|
return new { success = false, error = ex.Message };
|
|
227
234
|
}
|
|
228
235
|
if (tempFile != null) {
|
|
@@ -231,6 +238,9 @@ string encoding = d.encoding != null ? d.encoding.ToString() : "";
|
|
|
231
238
|
if (lispFile != null) {
|
|
232
239
|
try { if (System.IO.File.Exists(lispFile)) System.IO.File.Delete(lispFile); } catch {}
|
|
233
240
|
}
|
|
241
|
+
if (userCodeFile != null) {
|
|
242
|
+
try { if (System.IO.File.Exists(userCodeFile)) System.IO.File.Delete(userCodeFile); } catch {}
|
|
243
|
+
}
|
|
234
244
|
return new { success = false };
|
|
235
245
|
}
|
|
236
246
|
*/});
|