cad-mcp-server 0.1.0

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.
Files changed (208) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +111 -0
  3. package/THIRD_PARTY_NOTICES.md +20 -0
  4. package/dist/cad/compare.d.ts +31 -0
  5. package/dist/cad/compare.d.ts.map +1 -0
  6. package/dist/cad/compare.js +51 -0
  7. package/dist/cad/compare.js.map +1 -0
  8. package/dist/cad/model-store.d.ts +52 -0
  9. package/dist/cad/model-store.d.ts.map +1 -0
  10. package/dist/cad/model-store.js +227 -0
  11. package/dist/cad/model-store.js.map +1 -0
  12. package/dist/cad/query/edges.d.ts +6 -0
  13. package/dist/cad/query/edges.d.ts.map +1 -0
  14. package/dist/cad/query/edges.js +257 -0
  15. package/dist/cad/query/edges.js.map +1 -0
  16. package/dist/cad/query/entities.d.ts +4 -0
  17. package/dist/cad/query/entities.d.ts.map +1 -0
  18. package/dist/cad/query/entities.js +185 -0
  19. package/dist/cad/query/entities.js.map +1 -0
  20. package/dist/cad/query/faces.d.ts +6 -0
  21. package/dist/cad/query/faces.d.ts.map +1 -0
  22. package/dist/cad/query/faces.js +305 -0
  23. package/dist/cad/query/faces.js.map +1 -0
  24. package/dist/cad/query/pmi.d.ts +3 -0
  25. package/dist/cad/query/pmi.d.ts.map +1 -0
  26. package/dist/cad/query/pmi.js +141 -0
  27. package/dist/cad/query/pmi.js.map +1 -0
  28. package/dist/cad/query/shared.d.ts +74 -0
  29. package/dist/cad/query/shared.d.ts.map +1 -0
  30. package/dist/cad/query/shared.js +181 -0
  31. package/dist/cad/query/shared.js.map +1 -0
  32. package/dist/cad/schema-version.d.ts +2 -0
  33. package/dist/cad/schema-version.d.ts.map +1 -0
  34. package/dist/cad/schema-version.js +2 -0
  35. package/dist/cad/schema-version.js.map +1 -0
  36. package/dist/compare.d.ts +31 -0
  37. package/dist/compare.d.ts.map +1 -0
  38. package/dist/compare.js +51 -0
  39. package/dist/compare.js.map +1 -0
  40. package/dist/index.d.ts +17 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +113 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/kernel/aag-utils.d.ts +7 -0
  45. package/dist/kernel/aag-utils.d.ts.map +1 -0
  46. package/dist/kernel/aag-utils.js +54 -0
  47. package/dist/kernel/aag-utils.js.map +1 -0
  48. package/dist/kernel/import.d.ts +4 -0
  49. package/dist/kernel/import.d.ts.map +1 -0
  50. package/dist/kernel/import.js +25 -0
  51. package/dist/kernel/import.js.map +1 -0
  52. package/dist/kernel/kernel.d.ts +3 -0
  53. package/dist/kernel/kernel.d.ts.map +1 -0
  54. package/dist/kernel/kernel.js +7 -0
  55. package/dist/kernel/kernel.js.map +1 -0
  56. package/dist/kernel/measure.d.ts +6 -0
  57. package/dist/kernel/measure.d.ts.map +1 -0
  58. package/dist/kernel/measure.js +23 -0
  59. package/dist/kernel/measure.js.map +1 -0
  60. package/dist/kernel/query-entities.d.ts +75 -0
  61. package/dist/kernel/query-entities.d.ts.map +1 -0
  62. package/dist/kernel/query-entities.js +190 -0
  63. package/dist/kernel/query-entities.js.map +1 -0
  64. package/dist/kernel/topology.d.ts +4 -0
  65. package/dist/kernel/topology.d.ts.map +1 -0
  66. package/dist/kernel/topology.js +48 -0
  67. package/dist/kernel/topology.js.map +1 -0
  68. package/dist/model-store.d.ts +52 -0
  69. package/dist/model-store.d.ts.map +1 -0
  70. package/dist/model-store.js +227 -0
  71. package/dist/model-store.js.map +1 -0
  72. package/dist/pmi/metadata.d.ts +15 -0
  73. package/dist/pmi/metadata.d.ts.map +1 -0
  74. package/dist/pmi/metadata.js +93 -0
  75. package/dist/pmi/metadata.js.map +1 -0
  76. package/dist/pmi/parser.d.ts +46 -0
  77. package/dist/pmi/parser.d.ts.map +1 -0
  78. package/dist/pmi/parser.js +400 -0
  79. package/dist/pmi/parser.js.map +1 -0
  80. package/dist/pmi/semantic-provider.d.ts +7 -0
  81. package/dist/pmi/semantic-provider.d.ts.map +1 -0
  82. package/dist/pmi/semantic-provider.js +96 -0
  83. package/dist/pmi/semantic-provider.js.map +1 -0
  84. package/dist/providers/brep.d.ts +39 -0
  85. package/dist/providers/brep.d.ts.map +1 -0
  86. package/dist/providers/brep.js +2 -0
  87. package/dist/providers/brep.js.map +1 -0
  88. package/dist/providers/lightweight-step/metadata.d.ts +15 -0
  89. package/dist/providers/lightweight-step/metadata.d.ts.map +1 -0
  90. package/dist/providers/lightweight-step/metadata.js +93 -0
  91. package/dist/providers/lightweight-step/metadata.js.map +1 -0
  92. package/dist/providers/lightweight-step/pmi-parser.d.ts +46 -0
  93. package/dist/providers/lightweight-step/pmi-parser.d.ts.map +1 -0
  94. package/dist/providers/lightweight-step/pmi-parser.js +400 -0
  95. package/dist/providers/lightweight-step/pmi-parser.js.map +1 -0
  96. package/dist/providers/lightweight-step/semantic-provider.d.ts +7 -0
  97. package/dist/providers/lightweight-step/semantic-provider.d.ts.map +1 -0
  98. package/dist/providers/lightweight-step/semantic-provider.js +96 -0
  99. package/dist/providers/lightweight-step/semantic-provider.js.map +1 -0
  100. package/dist/providers/occt-wasm/aag-utils.d.ts +7 -0
  101. package/dist/providers/occt-wasm/aag-utils.d.ts.map +1 -0
  102. package/dist/providers/occt-wasm/aag-utils.js +54 -0
  103. package/dist/providers/occt-wasm/aag-utils.js.map +1 -0
  104. package/dist/providers/occt-wasm/import.d.ts +4 -0
  105. package/dist/providers/occt-wasm/import.d.ts.map +1 -0
  106. package/dist/providers/occt-wasm/import.js +25 -0
  107. package/dist/providers/occt-wasm/import.js.map +1 -0
  108. package/dist/providers/occt-wasm/kernel.d.ts +3 -0
  109. package/dist/providers/occt-wasm/kernel.d.ts.map +1 -0
  110. package/dist/providers/occt-wasm/kernel.js +7 -0
  111. package/dist/providers/occt-wasm/kernel.js.map +1 -0
  112. package/dist/providers/occt-wasm/measure.d.ts +6 -0
  113. package/dist/providers/occt-wasm/measure.d.ts.map +1 -0
  114. package/dist/providers/occt-wasm/measure.js +23 -0
  115. package/dist/providers/occt-wasm/measure.js.map +1 -0
  116. package/dist/providers/occt-wasm/query-entities.d.ts +71 -0
  117. package/dist/providers/occt-wasm/query-entities.d.ts.map +1 -0
  118. package/dist/providers/occt-wasm/query-entities.js +177 -0
  119. package/dist/providers/occt-wasm/query-entities.js.map +1 -0
  120. package/dist/providers/occt-wasm/topology.d.ts +4 -0
  121. package/dist/providers/occt-wasm/topology.d.ts.map +1 -0
  122. package/dist/providers/occt-wasm/topology.js +48 -0
  123. package/dist/providers/occt-wasm/topology.js.map +1 -0
  124. package/dist/providers/schema.d.ts +50 -0
  125. package/dist/providers/schema.d.ts.map +1 -0
  126. package/dist/providers/schema.js +2 -0
  127. package/dist/providers/schema.js.map +1 -0
  128. package/dist/providers/semantic.d.ts +34 -0
  129. package/dist/providers/semantic.d.ts.map +1 -0
  130. package/dist/providers/semantic.js +2 -0
  131. package/dist/providers/semantic.js.map +1 -0
  132. package/dist/query/edges.d.ts +6 -0
  133. package/dist/query/edges.d.ts.map +1 -0
  134. package/dist/query/edges.js +257 -0
  135. package/dist/query/edges.js.map +1 -0
  136. package/dist/query/entities.d.ts +4 -0
  137. package/dist/query/entities.d.ts.map +1 -0
  138. package/dist/query/entities.js +203 -0
  139. package/dist/query/entities.js.map +1 -0
  140. package/dist/query/faces.d.ts +6 -0
  141. package/dist/query/faces.d.ts.map +1 -0
  142. package/dist/query/faces.js +309 -0
  143. package/dist/query/faces.js.map +1 -0
  144. package/dist/query/pmi.d.ts +3 -0
  145. package/dist/query/pmi.d.ts.map +1 -0
  146. package/dist/query/pmi.js +141 -0
  147. package/dist/query/pmi.js.map +1 -0
  148. package/dist/query/shared.d.ts +74 -0
  149. package/dist/query/shared.d.ts.map +1 -0
  150. package/dist/query/shared.js +181 -0
  151. package/dist/query/shared.js.map +1 -0
  152. package/dist/schema-version.d.ts +2 -0
  153. package/dist/schema-version.d.ts.map +1 -0
  154. package/dist/schema-version.js +2 -0
  155. package/dist/schema-version.js.map +1 -0
  156. package/dist/tools/shared.d.ts +11 -0
  157. package/dist/tools/shared.d.ts.map +1 -0
  158. package/dist/tools/shared.js +19 -0
  159. package/dist/tools/shared.js.map +1 -0
  160. package/dist/tools/step-tools.d.ts +758 -0
  161. package/dist/tools/step-tools.d.ts.map +1 -0
  162. package/dist/tools/step-tools.js +836 -0
  163. package/dist/tools/step-tools.js.map +1 -0
  164. package/dist/types/brep.d.ts +39 -0
  165. package/dist/types/brep.d.ts.map +1 -0
  166. package/dist/types/brep.js +2 -0
  167. package/dist/types/brep.js.map +1 -0
  168. package/dist/types/schema.d.ts +50 -0
  169. package/dist/types/schema.d.ts.map +1 -0
  170. package/dist/types/schema.js +2 -0
  171. package/dist/types/schema.js.map +1 -0
  172. package/dist/types/semantic.d.ts +34 -0
  173. package/dist/types/semantic.d.ts.map +1 -0
  174. package/dist/types/semantic.js +2 -0
  175. package/dist/types/semantic.js.map +1 -0
  176. package/dist/utils/errors.d.ts +7 -0
  177. package/dist/utils/errors.d.ts.map +1 -0
  178. package/dist/utils/errors.js +7 -0
  179. package/dist/utils/errors.js.map +1 -0
  180. package/dist/utils/ids.d.ts +2 -0
  181. package/dist/utils/ids.d.ts.map +1 -0
  182. package/dist/utils/ids.js +4 -0
  183. package/dist/utils/ids.js.map +1 -0
  184. package/dist/utils/numbers.d.ts +11 -0
  185. package/dist/utils/numbers.d.ts.map +1 -0
  186. package/dist/utils/numbers.js +15 -0
  187. package/dist/utils/numbers.js.map +1 -0
  188. package/dist/utils/vectors.d.ts +4 -0
  189. package/dist/utils/vectors.d.ts.map +1 -0
  190. package/dist/utils/vectors.js +14 -0
  191. package/dist/utils/vectors.js.map +1 -0
  192. package/docs/EXAMPLE_PROMPTS.md +61 -0
  193. package/node_modules/occt-wasm/dist/index.d.ts +303 -0
  194. package/node_modules/occt-wasm/dist/index.d.ts.map +1 -0
  195. package/node_modules/occt-wasm/dist/index.js +1125 -0
  196. package/node_modules/occt-wasm/dist/index.js.map +1 -0
  197. package/node_modules/occt-wasm/dist/occt-wasm.js +2 -0
  198. package/node_modules/occt-wasm/dist/occt-wasm.wasm +0 -0
  199. package/node_modules/occt-wasm/dist/raw-types.d.ts +229 -0
  200. package/node_modules/occt-wasm/dist/raw-types.d.ts.map +1 -0
  201. package/node_modules/occt-wasm/dist/raw-types.js +8 -0
  202. package/node_modules/occt-wasm/dist/raw-types.js.map +1 -0
  203. package/node_modules/occt-wasm/dist/types.d.ts +223 -0
  204. package/node_modules/occt-wasm/dist/types.d.ts.map +1 -0
  205. package/node_modules/occt-wasm/dist/types.js +129 -0
  206. package/node_modules/occt-wasm/dist/types.js.map +1 -0
  207. package/node_modules/occt-wasm/package.json +44 -0
  208. package/package.json +102 -0
@@ -0,0 +1,181 @@
1
+ import { CAD_RESPONSE_SCHEMA_VERSION } from '../schema-version.js';
2
+ import { normalizeVector, angleDegreesNormalized } from '../../utils/vectors.js';
3
+ /**
4
+ * Shared query utilities for pagination, filtering, sorting, and response envelopes.
5
+ */
6
+ export const DEFAULT_QUERY_LIMITS = {
7
+ limit: 100,
8
+ offset: 0,
9
+ sample_entity_limit: 5,
10
+ max_page_size: 1000,
11
+ };
12
+ /**
13
+ * Hardcoded bucket widths for continuous-value grouping.
14
+ * Single source of truth; the model does not control these.
15
+ */
16
+ export const GROUP_BUCKETS = {
17
+ // Log-scale magnitude bins (mm or mm^2) for size dimensions.
18
+ // A value v falls in the first bin whose upper bound exceeds it.
19
+ magnitude_bins: [1, 10, 100, 1000, 10000],
20
+ // Round radius/diameter to this granularity (mm) to separate standard sizes
21
+ // while merging floating-point noise.
22
+ radius_step: 0.5,
23
+ // Faces/edges within this angle (degrees) of a principal axis snap to it.
24
+ axis_snap_degrees: 15,
25
+ };
26
+ /**
27
+ * Bucket a continuous magnitude (length, area, depth) into a labelled range
28
+ * using fixed log-scale bins. Returns a stable string key like "10-100".
29
+ */
30
+ export function magnitudeBucketKey(value) {
31
+ const bins = GROUP_BUCKETS.magnitude_bins;
32
+ if (value < bins[0])
33
+ return `0-${bins[0]}`;
34
+ for (let i = 0; i < bins.length - 1; i++) {
35
+ if (value < bins[i + 1])
36
+ return `${bins[i]}-${bins[i + 1]}`;
37
+ }
38
+ return `${bins[bins.length - 1]}+`;
39
+ }
40
+ /**
41
+ * Bucket a radius or diameter by rounding to the nearest fixed step.
42
+ * Returns the rounded numeric value (used directly as the group key).
43
+ */
44
+ export function radiusBucketValue(value) {
45
+ const step = GROUP_BUCKETS.radius_step;
46
+ return Math.round(value / step) * step;
47
+ }
48
+ /**
49
+ * Snap a direction vector to the nearest principal axis (+X..-Z) when within
50
+ * the axis-snap tolerance; otherwise return "off-axis". Keys are stable strings.
51
+ */
52
+ export function axisDirectionKey(direction) {
53
+ const unit = normalizeVector(direction);
54
+ if (unit[0] === 0 && unit[1] === 0 && unit[2] === 0)
55
+ return 'undefined';
56
+ const axes = [
57
+ { key: '+X', vec: [1, 0, 0] },
58
+ { key: '-X', vec: [-1, 0, 0] },
59
+ { key: '+Y', vec: [0, 1, 0] },
60
+ { key: '-Y', vec: [0, -1, 0] },
61
+ { key: '+Z', vec: [0, 0, 1] },
62
+ { key: '-Z', vec: [0, 0, -1] },
63
+ ];
64
+ let best = 'off-axis';
65
+ let bestAngle = GROUP_BUCKETS.axis_snap_degrees;
66
+ for (const axis of axes) {
67
+ const angle = angleDegreesNormalized(unit, axis.vec);
68
+ if (angle <= bestAngle) {
69
+ bestAngle = angle;
70
+ best = axis.key;
71
+ }
72
+ }
73
+ return best;
74
+ }
75
+ /**
76
+ * Group entities deterministically by a composite key derived from each
77
+ * requested dimension. Groups are sorted by descending entity count, then by
78
+ * key for stable ordering. Each group includes bounded sample entity IDs.
79
+ */
80
+ export function groupEntities(entities, dimensions, keyOf, sampleLimit, summarize) {
81
+ const buckets = new Map();
82
+ for (const entity of entities) {
83
+ const key = {};
84
+ for (const dimension of dimensions) {
85
+ key[dimension] = keyOf(entity, dimension);
86
+ }
87
+ const mapKey = JSON.stringify(dimensions.map((d) => key[d]));
88
+ let bucket = buckets.get(mapKey);
89
+ if (!bucket) {
90
+ bucket = { key, members: [] };
91
+ buckets.set(mapKey, bucket);
92
+ }
93
+ bucket.members.push(entity);
94
+ }
95
+ const groups = [...buckets.values()].map((bucket) => {
96
+ const ids = bucket.members.map((m) => m.id);
97
+ const { sampled, is_complete } = sampleEntityIds(ids, sampleLimit);
98
+ return {
99
+ key: bucket.key,
100
+ entity_count: bucket.members.length,
101
+ entity_ids: ids,
102
+ sample_entity_ids: sampled,
103
+ sample_entity_limit: sampleLimit,
104
+ sample_is_complete: is_complete,
105
+ summary: summarize ? summarize(bucket.members) : {},
106
+ };
107
+ });
108
+ // Deterministic ordering: largest groups first, then by key string.
109
+ groups.sort((a, b) => {
110
+ if (b.entity_count !== a.entity_count)
111
+ return b.entity_count - a.entity_count;
112
+ return JSON.stringify(a.key).localeCompare(JSON.stringify(b.key));
113
+ });
114
+ return groups.map((group, i) => ({ id: `group:${i}`, ...group }));
115
+ }
116
+ export function normalizePagination(limit, offset) {
117
+ return {
118
+ limit: limit ?? DEFAULT_QUERY_LIMITS.limit,
119
+ offset: offset ?? DEFAULT_QUERY_LIMITS.offset,
120
+ };
121
+ }
122
+ export function createPagination(limit, offset, returned, total_matched) {
123
+ return {
124
+ limit,
125
+ offset,
126
+ returned,
127
+ total_matched,
128
+ has_more: offset + returned < total_matched,
129
+ };
130
+ }
131
+ export const STEP_QUERY_UNITS = {
132
+ length: 'mm',
133
+ area: 'mm^2',
134
+ volume: 'mm^3',
135
+ angle: 'deg',
136
+ };
137
+ export const STEP_QUERY_COORDINATE_SYSTEM = {
138
+ origin: 'STEP model origin',
139
+ axes: 'model coordinates',
140
+ handedness: 'right',
141
+ };
142
+ /**
143
+ * Build a query response envelope.
144
+ */
145
+ export function createQueryResponse(file_path, query, pagination, entities, statistics, groups = [], warnings = [], limitations = []) {
146
+ return {
147
+ schema_version: CAD_RESPONSE_SCHEMA_VERSION,
148
+ file_path,
149
+ units: STEP_QUERY_UNITS,
150
+ coordinate_system: STEP_QUERY_COORDINATE_SYSTEM,
151
+ query,
152
+ statistics: statistics ?? {},
153
+ pagination,
154
+ entities,
155
+ groups: groups.map((g) => ({
156
+ id: g.id,
157
+ key: g.key,
158
+ entity_count: g.entity_count,
159
+ sample_entity_ids: g.sample_entity_ids,
160
+ sample_entity_limit: g.sample_entity_limit,
161
+ sample_is_complete: g.sample_is_complete,
162
+ summary: g.summary,
163
+ })),
164
+ warnings,
165
+ limitations,
166
+ };
167
+ }
168
+ /**
169
+ * Sample entity IDs from a larger set, deterministically.
170
+ */
171
+ export function sampleEntityIds(entity_ids, sample_limit) {
172
+ if (sample_limit <= 0) {
173
+ return { sampled: [], is_complete: entity_ids.length === 0 };
174
+ }
175
+ const sampled = entity_ids.slice(0, sample_limit);
176
+ return {
177
+ sampled,
178
+ is_complete: sampled.length === entity_ids.length,
179
+ };
180
+ }
181
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/cad/query/shared.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const CAD_RESPONSE_SCHEMA_VERSION: "0.4";
2
+ //# sourceMappingURL=schema-version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-version.d.ts","sourceRoot":"","sources":["../../src/cad/schema-version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,2BAA2B,EAAG,KAAc,CAAC"}
@@ -0,0 +1,2 @@
1
+ export const CAD_RESPONSE_SCHEMA_VERSION = '0.4';
2
+ //# sourceMappingURL=schema-version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-version.js","sourceRoot":"","sources":["../../src/cad/schema-version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,2BAA2B,GAAG,KAAc,CAAC"}
@@ -0,0 +1,31 @@
1
+ export declare function compareStepFiles(fileA: string, fileB: string): Promise<{
2
+ schema_version: "0.4";
3
+ files: {
4
+ a: string;
5
+ b: string;
6
+ };
7
+ deltas: {
8
+ dimensions: {
9
+ width: number;
10
+ height: number;
11
+ depth: number;
12
+ };
13
+ volume: number;
14
+ surfaceArea: number;
15
+ bodyCount: number;
16
+ faceCount: number | undefined;
17
+ edgeCount: number | undefined;
18
+ };
19
+ exchange: {
20
+ schemaChanged: boolean;
21
+ productNamesA: string[];
22
+ productNamesB: string[];
23
+ };
24
+ warnings: import("./types/schema.js").Warning[];
25
+ limitations: import("./types/schema.js").Limitation[];
26
+ providers: {
27
+ a: import("./types/schema.js").ProviderInfo[];
28
+ b: import("./types/schema.js").ProviderInfo[];
29
+ };
30
+ }>;
31
+ //# sourceMappingURL=compare.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../src/compare.ts"],"names":[],"mappings":"AAGA,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDlE"}
@@ -0,0 +1,51 @@
1
+ import { withStepModel } from './model-store.js';
2
+ import { CAD_RESPONSE_SCHEMA_VERSION } from './schema-version.js';
3
+ export async function compareStepFiles(fileA, fileB) {
4
+ return withStepModel(fileA, async (modelA) => withStepModel(fileB, async (modelB) => {
5
+ const [brepA, brepB, semanticA, semanticB] = await Promise.all([
6
+ modelA.getBRepModel(),
7
+ modelB.getBRepModel(),
8
+ modelA.getSemanticModel(),
9
+ modelB.getSemanticModel(),
10
+ ]);
11
+ return {
12
+ schema_version: CAD_RESPONSE_SCHEMA_VERSION,
13
+ files: { a: fileA, b: fileB },
14
+ deltas: {
15
+ dimensions: {
16
+ width: brepB.dimensions.width - brepA.dimensions.width,
17
+ height: brepB.dimensions.height - brepA.dimensions.height,
18
+ depth: brepB.dimensions.depth - brepA.dimensions.depth,
19
+ },
20
+ volume: brepB.volume - brepA.volume,
21
+ surfaceArea: brepB.surfaceArea - brepA.surfaceArea,
22
+ bodyCount: brepB.bodyCount - brepA.bodyCount,
23
+ faceCount: brepB.faceCount !== undefined && brepA.faceCount !== undefined
24
+ ? brepB.faceCount - brepA.faceCount
25
+ : undefined,
26
+ edgeCount: brepB.edgeStatistics && brepA.edgeStatistics
27
+ ? brepB.edgeStatistics.count - brepA.edgeStatistics.count
28
+ : undefined,
29
+ },
30
+ exchange: {
31
+ schemaChanged: semanticA.schema !== semanticB.schema,
32
+ productNamesA: semanticA.productNames,
33
+ productNamesB: semanticB.productNames,
34
+ },
35
+ warnings: [...brepA.health.warnings, ...brepB.health.warnings],
36
+ limitations: [
37
+ ...semanticA.limitations,
38
+ ...semanticB.limitations,
39
+ {
40
+ source: 'compare_step_files',
41
+ message: 'Comparison uses metric and metadata deltas only; stable feature identity and adjacency across revisions are not inferred.',
42
+ },
43
+ ],
44
+ providers: {
45
+ a: [brepA.provider, semanticA.provider],
46
+ b: [brepB.provider, semanticB.provider],
47
+ },
48
+ };
49
+ }));
50
+ }
51
+ //# sourceMappingURL=compare.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare.js","sourceRoot":"","sources":["../src/compare.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAElE,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAAa,EAAE,KAAa;IACjE,OAAO,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,CAC3C,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QACpC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC7D,MAAM,CAAC,YAAY,EAAE;YACrB,MAAM,CAAC,YAAY,EAAE;YACrB,MAAM,CAAC,gBAAgB,EAAE;YACzB,MAAM,CAAC,gBAAgB,EAAE;SAC1B,CAAC,CAAC;QAEH,OAAO;YACL,cAAc,EAAE,2BAA2B;YAC3C,KAAK,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE;YAC7B,MAAM,EAAE;gBACN,UAAU,EAAE;oBACV,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,KAAK;oBACtD,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM;oBACzD,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,KAAK;iBACvD;gBACD,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM;gBACnC,WAAW,EAAE,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW;gBAClD,SAAS,EAAE,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS;gBAC5C,SAAS,EACP,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;oBAC5D,CAAC,CAAC,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS;oBACnC,CAAC,CAAC,SAAS;gBACf,SAAS,EACP,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,cAAc;oBAC1C,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,GAAG,KAAK,CAAC,cAAc,CAAC,KAAK;oBACzD,CAAC,CAAC,SAAS;aAChB;YACD,QAAQ,EAAE;gBACR,aAAa,EAAE,SAAS,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM;gBACpD,aAAa,EAAE,SAAS,CAAC,YAAY;gBACrC,aAAa,EAAE,SAAS,CAAC,YAAY;aACtC;YACD,QAAQ,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC;YAC9D,WAAW,EAAE;gBACX,GAAG,SAAS,CAAC,WAAW;gBACxB,GAAG,SAAS,CAAC,WAAW;gBACxB;oBACE,MAAM,EAAE,oBAAoB;oBAC5B,OAAO,EACL,2HAA2H;iBAC9H;aACF;YACD,SAAS,EAAE;gBACT,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,QAAQ,CAAC;gBACvC,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,QAAQ,CAAC;aACxC;SACF,CAAC;IACJ,CAAC,CAAC,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ export declare function jsonToolResult(result: unknown): {
3
+ content: {
4
+ type: "text";
5
+ text: string;
6
+ }[];
7
+ structuredContent: unknown;
8
+ isError?: undefined;
9
+ } | {
10
+ content: {
11
+ type: "text";
12
+ text: string;
13
+ }[];
14
+ isError: boolean;
15
+ structuredContent?: undefined;
16
+ };
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAmCA,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO;;;;;;;;;;;;;;EAsB7C"}
package/dist/index.js ADDED
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env node
2
+ import { pathToFileURL } from 'node:url';
3
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
4
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
5
+ import { handleCompareStepFiles, handleFindStepEdges, handleFindStepFaces, handleGetStepEntities, handleInspectStepFile, handleQueryStepPmi, stepToolOutputSchemas, stepToolSchemas, } from './tools/step-tools.js';
6
+ const server = new McpServer({
7
+ name: 'cad-mcp-server',
8
+ version: '0.1.0',
9
+ });
10
+ function isToolResult(value) {
11
+ return (typeof value === 'object' &&
12
+ value !== null &&
13
+ 'ok' in value &&
14
+ typeof value.ok === 'boolean');
15
+ }
16
+ export function jsonToolResult(result) {
17
+ if (isToolResult(result)) {
18
+ if (result.ok) {
19
+ return {
20
+ content: [{ type: 'text', text: JSON.stringify(result.data, null, 2) }],
21
+ structuredContent: result.data,
22
+ };
23
+ }
24
+ return {
25
+ content: [
26
+ {
27
+ type: 'text',
28
+ text: `${result.error.type}: ${result.error.message}`,
29
+ },
30
+ ],
31
+ isError: true,
32
+ };
33
+ }
34
+ return {
35
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
36
+ structuredContent: result,
37
+ };
38
+ }
39
+ const registerTool = server.registerTool.bind(server);
40
+ function withErrorContext(toolName, handler) {
41
+ return async (args) => {
42
+ try {
43
+ return await handler(args);
44
+ }
45
+ catch (error) {
46
+ console.error(`Tool ${toolName} failed:`, error);
47
+ throw error;
48
+ }
49
+ };
50
+ }
51
+ registerTool('inspect_step_file', {
52
+ title: 'Inspect STEP File',
53
+ description: 'Compact first-pass overview of a STEP file. Use this FIRST to identify the part, check validity, dimensions, body count, and topology counts. Expensive face area extremes and adjacency are deferred; follow up with find_step_faces, find_step_edges, or get_step_entities for detail. Do NOT use for entity-level searches. IMPORTANT: Omit all optional filter parameters you do not need — do not pass placeholder values (0, 999999, empty array). Example: {file_path:"model.step"}',
54
+ inputSchema: stepToolSchemas.inspectStepFile,
55
+ outputSchema: stepToolOutputSchemas.inspectStepFile,
56
+ }, withErrorContext('inspect_step_file', async ({ file_path }) => jsonToolResult(await handleInspectStepFile(String(file_path)))));
57
+ registerTool('find_step_faces', {
58
+ title: 'Find STEP Faces',
59
+ description: 'Search faces by surface type, area, spatial region, or proximity. Use when you need specific faces such as large faces, cylindrical faces, faces near a point, or grouped face statistics. Do NOT use for known face IDs; use get_step_entities. CRITICAL: Omit every optional parameter you do not need. Adding a filter narrows results. Do NOT pass placeholder values. Example small faces: {file_path:"model.step",area_max:1,sort:{by:"area"}}. Example cylinders: {file_path:"model.step",surface_types:["cylinder"],return_type:"groups",group_by:["surface_type"]}',
60
+ inputSchema: stepToolSchemas.findStepFaces,
61
+ outputSchema: stepToolOutputSchemas.findStepFaces,
62
+ }, withErrorContext('find_step_faces', async (args) => {
63
+ const query = args;
64
+ return jsonToolResult(await handleFindStepFaces(String(query.file_path), query));
65
+ }));
66
+ registerTool('find_step_edges', {
67
+ title: 'Find STEP Edges',
68
+ description: 'Search edges by curve type, length, circular radius, spatial region, or proximity. Use for tiny-edge investigation, long edges, circular edges, or grouped edge statistics. For tiny edges use length_max and sort:{by:"length"}. The "radius" filter restricts to circular/curved edges only; omit it unless specifically querying circular edges by radius. Do NOT use for known edge IDs; use get_step_entities. CRITICAL: Omit every optional parameter you do not need. Do NOT pass placeholder values. Example tiny edges: {file_path:"model.step",length_max:0.5,sort:{by:"length"},fields:["id","length","curve_type"]}',
69
+ inputSchema: stepToolSchemas.findStepEdges,
70
+ outputSchema: stepToolOutputSchemas.findStepEdges,
71
+ }, withErrorContext('find_step_edges', async (args) => {
72
+ const query = args;
73
+ return jsonToolResult(await handleFindStepEdges(String(query.file_path), query));
74
+ }));
75
+ registerTool('get_step_entities', {
76
+ title: 'Get STEP Entities',
77
+ description: 'Retrieve one or more known faces or edges by exact entity ID. IDs come from inspect_step_file, find_step_faces, or find_step_edges. Use ONLY when you already have specific IDs. Do NOT use for searching or filtering; use find_step_faces or find_step_edges. Example: {file_path:"model.step",entity_type:"face",entity_ids:["face:0"],fields:["id","area","normal"]}. IMPORTANT: Omit fields if you want the default projection.',
78
+ inputSchema: stepToolSchemas.getStepEntities,
79
+ outputSchema: stepToolOutputSchemas.getStepEntities,
80
+ }, withErrorContext('get_step_entities', async (args) => {
81
+ const query = args;
82
+ return jsonToolResult(await handleGetStepEntities(String(query.file_path), query));
83
+ }));
84
+ registerTool('compare_step_files', {
85
+ title: 'Compare STEP Files',
86
+ description: 'Compare two STEP files and return whole-model metric deltas and metadata changes. Use for two revisions of a part when you need factual differences in dimensions, volume, area, topology counts, or exchange metadata. Does NOT track feature identity across revisions. Deltas are comparison_file_path minus baseline_file_path. Both parameters are required. Example: {baseline_file_path:"model_v1.step",comparison_file_path:"model_v2.step"}',
87
+ inputSchema: stepToolSchemas.compareStepFiles,
88
+ outputSchema: stepToolOutputSchemas.compareStepFiles,
89
+ }, withErrorContext('compare_step_files', async (args) => {
90
+ const { baseline_file_path, comparison_file_path } = args;
91
+ return jsonToolResult(await handleCompareStepFiles(String(baseline_file_path), String(comparison_file_path)));
92
+ }));
93
+ registerTool('query_step_pmi', {
94
+ title: 'Query STEP PMI',
95
+ description: 'Query Product Manufacturing Information (PMI): geometric tolerances, dimensions, datums, and annotations. Use return_type:"summary" first to check whether PMI exists. Not all STEP files contain PMI; AP203 files commonly do not. CRITICAL: Omit every optional parameter you do not need. Do NOT pass placeholder values. Example quick check: {file_path:"model.step",return_type:"summary"}',
96
+ inputSchema: stepToolSchemas.queryStepPmi,
97
+ outputSchema: stepToolOutputSchemas.queryStepPmi,
98
+ }, withErrorContext('query_step_pmi', async (args) => {
99
+ const query = args;
100
+ return jsonToolResult(await handleQueryStepPmi(String(query.file_path), query));
101
+ }));
102
+ async function main() {
103
+ const transport = new StdioServerTransport();
104
+ await server.connect(transport);
105
+ console.error('CAD MCP Server started');
106
+ }
107
+ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
108
+ main().catch((error) => {
109
+ console.error('Fatal error:', error);
110
+ process.exit(1);
111
+ });
112
+ }
113
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,EACrB,kBAAkB,EAClB,qBAAqB,EACrB,eAAe,GAChB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,gBAAgB;IACtB,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAMH,SAAS,YAAY,CAAC,KAAc;IAClC,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,IAAI,IAAI,KAAK;QACb,OAAQ,KAA+B,CAAC,EAAE,KAAK,SAAS,CACzD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAe;IAC5C,IAAI,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;gBAChF,iBAAiB,EAAE,MAAM,CAAC,IAAI;aAC/B,CAAC;QACJ,CAAC;QACD,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE;iBACtD;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IACD,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;QAC3E,iBAAiB,EAAE,MAAM;KAC1B,CAAC;AACJ,CAAC;AAgBD,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAiB,CAAC;AAEtE,SAAS,gBAAgB,CACvB,QAAgB,EAChB,OAA0D;IAE1D,OAAO,KAAK,EAAE,IAA6B,EAAE,EAAE;QAC7C,IAAI,CAAC;YACH,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,QAAQ,QAAQ,UAAU,EAAE,KAAK,CAAC,CAAC;YACjD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,YAAY,CACV,mBAAmB,EACnB;IACE,KAAK,EAAE,mBAAmB;IAC1B,WAAW,EACT,4dAA4d;IAC9d,WAAW,EAAE,eAAe,CAAC,eAAe;IAC5C,YAAY,EAAE,qBAAqB,CAAC,eAAe;CACpD,EACD,gBAAgB,CAAC,mBAAmB,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CAC5D,cAAc,CAAC,MAAM,qBAAqB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAC/D,CACF,CAAC;AAEF,YAAY,CACV,iBAAiB,EACjB;IACE,KAAK,EAAE,iBAAiB;IACxB,WAAW,EACT,6iBAA6iB;IAC/iB,WAAW,EAAE,eAAe,CAAC,aAAa;IAC1C,YAAY,EAAE,qBAAqB,CAAC,aAAa;CAClD,EACD,gBAAgB,CAAC,iBAAiB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IACjD,MAAM,KAAK,GAAG,IAA+B,CAAC;IAC9C,OAAO,cAAc,CAAC,MAAM,mBAAmB,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,KAAc,CAAC,CAAC,CAAC;AAC5F,CAAC,CAAC,CACH,CAAC;AAEF,YAAY,CACV,iBAAiB,EACjB;IACE,KAAK,EAAE,iBAAiB;IACxB,WAAW,EACT,imBAAimB;IACnmB,WAAW,EAAE,eAAe,CAAC,aAAa;IAC1C,YAAY,EAAE,qBAAqB,CAAC,aAAa;CAClD,EACD,gBAAgB,CAAC,iBAAiB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IACjD,MAAM,KAAK,GAAG,IAA+B,CAAC;IAC9C,OAAO,cAAc,CAAC,MAAM,mBAAmB,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,KAAc,CAAC,CAAC,CAAC;AAC5F,CAAC,CAAC,CACH,CAAC;AAEF,YAAY,CACV,mBAAmB,EACnB;IACE,KAAK,EAAE,mBAAmB;IAC1B,WAAW,EACT,saAAsa;IACxa,WAAW,EAAE,eAAe,CAAC,eAAe;IAC5C,YAAY,EAAE,qBAAqB,CAAC,eAAe;CACpD,EACD,gBAAgB,CAAC,mBAAmB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IACnD,MAAM,KAAK,GAAG,IAA+B,CAAC;IAC9C,OAAO,cAAc,CAAC,MAAM,qBAAqB,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,KAAc,CAAC,CAAC,CAAC;AAC9F,CAAC,CAAC,CACH,CAAC;AAEF,YAAY,CACV,oBAAoB,EACpB;IACE,KAAK,EAAE,oBAAoB;IAC3B,WAAW,EACT,sbAAsb;IACxb,WAAW,EAAE,eAAe,CAAC,gBAAgB;IAC7C,YAAY,EAAE,qBAAqB,CAAC,gBAAgB;CACrD,EACD,gBAAgB,CAAC,oBAAoB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IACpD,MAAM,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,GAAG,IAA8B,CAAC;IACpF,OAAO,cAAc,CACnB,MAAM,sBAAsB,CAAC,MAAM,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC,oBAAoB,CAAC,CAAC,CACvF,CAAC;AACJ,CAAC,CAAC,CACH,CAAC;AAEF,YAAY,CACV,gBAAgB,EAChB;IACE,KAAK,EAAE,gBAAgB;IACvB,WAAW,EACT,kYAAkY;IACpY,WAAW,EAAE,eAAe,CAAC,YAAY;IACzC,YAAY,EAAE,qBAAqB,CAAC,YAAY;CACjD,EACD,gBAAgB,CAAC,gBAAgB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAChD,MAAM,KAAK,GAAG,IAA+B,CAAC;IAC9C,OAAO,cAAc,CAAC,MAAM,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,KAAc,CAAC,CAAC,CAAC;AAC3F,CAAC,CAAC,CACH,CAAC;AAEF,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;AAC1C,CAAC;AAED,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/E,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { OcctKernel, ShapeHandle } from 'occt-wasm';
2
+ export type EdgeVexity = 'convex' | 'concave' | 'smooth' | 'unknown';
3
+ export declare function computeEdgeVexity(kernel: OcctKernel, faceA: ShapeHandle, faceB: ShapeHandle, sharedEdge: ShapeHandle): {
4
+ vexity: EdgeVexity;
5
+ dihedralAngleDeg: number;
6
+ };
7
+ //# sourceMappingURL=aag-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aag-utils.d.ts","sourceRoot":"","sources":["../../src/kernel/aag-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAQ,MAAM,WAAW,CAAC;AAE/D,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAErE,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,WAAW,EAClB,UAAU,EAAE,WAAW,GACtB;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,CAsClD"}
@@ -0,0 +1,54 @@
1
+ export function computeEdgeVexity(kernel, faceA, faceB, sharedEdge) {
2
+ try {
3
+ const params = kernel.curveParameters(sharedEdge);
4
+ const midParam = (params.first + params.last) / 2;
5
+ const tangent = kernel.curveTangent(sharedEdge, midParam);
6
+ const point = kernel.curvePointAtParam(sharedEdge, midParam);
7
+ const uvA = kernel.uvFromPoint(faceA, point);
8
+ const uvB = kernel.uvFromPoint(faceB, point);
9
+ const normalA = kernel.surfaceNormal(faceA, uvA.u, uvA.v);
10
+ const normalB = kernel.surfaceNormal(faceB, uvB.u, uvB.v);
11
+ const ta = { x: tangent.x, y: tangent.y, z: tangent.z };
12
+ const nA = { x: normalA.x, y: normalA.y, z: normalA.z };
13
+ const nB = { x: normalB.x, y: normalB.y, z: normalB.z };
14
+ const taLen = magnitude(ta);
15
+ if (taLen < 1e-12) {
16
+ return { vexity: 'unknown', dihedralAngleDeg: 0 };
17
+ }
18
+ const tHat = { x: ta.x / taLen, y: ta.y / taLen, z: ta.z / taLen };
19
+ const cA = normalize(cross(nA, tHat));
20
+ const cB = normalize(cross(nB, tHat));
21
+ const dot = dotProduct(cA, cB);
22
+ const clamped = Math.max(-1, Math.min(1, dot));
23
+ const angleRad = Math.acos(clamped);
24
+ const dihedralAngleDeg = angleRad * (180 / Math.PI);
25
+ if (dot > 0.05)
26
+ return { vexity: 'convex', dihedralAngleDeg };
27
+ if (dot < -0.05)
28
+ return { vexity: 'concave', dihedralAngleDeg };
29
+ return { vexity: 'smooth', dihedralAngleDeg };
30
+ }
31
+ catch {
32
+ return { vexity: 'unknown', dihedralAngleDeg: 0 };
33
+ }
34
+ }
35
+ function cross(a, b) {
36
+ return {
37
+ x: a.y * b.z - a.z * b.y,
38
+ y: a.z * b.x - a.x * b.z,
39
+ z: a.x * b.y - a.y * b.x,
40
+ };
41
+ }
42
+ function dotProduct(a, b) {
43
+ return a.x * b.x + a.y * b.y + a.z * b.z;
44
+ }
45
+ function magnitude(v) {
46
+ return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
47
+ }
48
+ function normalize(v) {
49
+ const len = magnitude(v);
50
+ if (len < 1e-12)
51
+ return { x: 0, y: 0, z: 1 };
52
+ return { x: v.x / len, y: v.y / len, z: v.z / len };
53
+ }
54
+ //# sourceMappingURL=aag-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aag-utils.js","sourceRoot":"","sources":["../../src/kernel/aag-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { type AnalysisError } from '../utils/errors.js';
2
+ export declare function mapOcctError(error: unknown, action: string): AnalysisError;
3
+ export declare function readStepText(filePath: string): Promise<string>;
4
+ //# sourceMappingURL=import.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import.d.ts","sourceRoot":"","sources":["../../src/kernel/import.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAgB,MAAM,oBAAoB,CAAC;AAEtE,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CAS1E;AAED,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAUpE"}
@@ -0,0 +1,25 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { OcctError, OcctErrorCode } from 'occt-wasm';
3
+ import { unknownError } from '../utils/errors.js';
4
+ export function mapOcctError(error, action) {
5
+ if (error instanceof OcctError) {
6
+ return {
7
+ type: error.code === OcctErrorCode.ImportExportFailed ? 'invalid_format' : 'unknown',
8
+ message: `${action} failed: ${error.message}`,
9
+ };
10
+ }
11
+ return unknownError(error, action);
12
+ }
13
+ export async function readStepText(filePath) {
14
+ try {
15
+ return await readFile(filePath, 'utf8');
16
+ }
17
+ catch (error) {
18
+ const message = error instanceof Error ? error.message : String(error);
19
+ throw {
20
+ type: 'file_not_found',
21
+ message: `File not found: ${filePath}. ${message}`,
22
+ };
23
+ }
24
+ }
25
+ //# sourceMappingURL=import.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import.js","sourceRoot":"","sources":["../../src/kernel/import.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAsB,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEtE,MAAM,UAAU,YAAY,CAAC,KAAc,EAAE,MAAc;IACzD,IAAI,KAAK,YAAY,SAAS,EAAE,CAAC;QAC/B,OAAO;YACL,IAAI,EAAE,KAAK,CAAC,IAAI,KAAK,aAAa,CAAC,kBAAkB,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS;YACpF,OAAO,EAAE,GAAG,MAAM,YAAY,KAAK,CAAC,OAAO,EAAE;SAC9C,CAAC;IACJ,CAAC;IAED,OAAO,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB;IACjD,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,MAAM;YACJ,IAAI,EAAE,gBAAgB;YACtB,OAAO,EAAE,mBAAmB,QAAQ,KAAK,OAAO,EAAE;SAC3B,CAAC;IAC5B,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { OcctKernel } from 'occt-wasm';
2
+ export declare function getOcctKernel(): Promise<OcctKernel>;
3
+ //# sourceMappingURL=kernel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kernel.d.ts","sourceRoot":"","sources":["../../src/kernel/kernel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAIvC,wBAAsB,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC,CAGzD"}
@@ -0,0 +1,7 @@
1
+ import { OcctKernel } from 'occt-wasm';
2
+ let kernelPromise;
3
+ export async function getOcctKernel() {
4
+ kernelPromise ??= OcctKernel.init();
5
+ return kernelPromise;
6
+ }
7
+ //# sourceMappingURL=kernel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kernel.js","sourceRoot":"","sources":["../../src/kernel/kernel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,IAAI,aAA8C,CAAC;AAEnD,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,aAAa,KAAK,UAAU,CAAC,IAAI,EAAE,CAAC;IACpC,OAAO,aAAa,CAAC;AACvB,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { OcctKernel, ShapeHandle } from 'occt-wasm';
2
+ import type { BoundingBox, Dimensions } from '../types/schema.js';
3
+ export declare function toBoundingBox(kernel: OcctKernel, shape: ShapeHandle): BoundingBox;
4
+ export declare function getDimensions(boundingBox: BoundingBox): Dimensions;
5
+ export declare function guessShapeClass(dimensions: Dimensions): 'box' | 'cylindrical' | 'complex';
6
+ //# sourceMappingURL=measure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"measure.d.ts","sourceRoot":"","sources":["../../src/kernel/measure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAElE,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,GAAG,WAAW,CAOjF;AAED,wBAAgB,aAAa,CAAC,WAAW,EAAE,WAAW,GAAG,UAAU,CAMlE;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,UAAU,GAAG,KAAK,GAAG,aAAa,GAAG,SAAS,CAMzF"}
@@ -0,0 +1,23 @@
1
+ export function toBoundingBox(kernel, shape) {
2
+ const bbox = kernel.getBoundingBox(shape, false);
3
+ return {
4
+ min: { x: bbox.xmin, y: bbox.ymin, z: bbox.zmin },
5
+ max: { x: bbox.xmax, y: bbox.ymax, z: bbox.zmax },
6
+ };
7
+ }
8
+ export function getDimensions(boundingBox) {
9
+ return {
10
+ width: boundingBox.max.x - boundingBox.min.x,
11
+ height: boundingBox.max.y - boundingBox.min.y,
12
+ depth: boundingBox.max.z - boundingBox.min.z,
13
+ };
14
+ }
15
+ export function guessShapeClass(dimensions) {
16
+ const { width, height, depth } = dimensions;
17
+ if (width > height * 2 || width > depth * 2)
18
+ return 'box';
19
+ if (Math.abs(height - depth) < Math.max(height, depth) * 0.2)
20
+ return 'cylindrical';
21
+ return 'complex';
22
+ }
23
+ //# sourceMappingURL=measure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"measure.js","sourceRoot":"","sources":["../../src/kernel/measure.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,aAAa,CAAC,MAAkB,EAAE,KAAkB;IAClE,MAAM,IAAI,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAEjD,OAAO;QACL,GAAG,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE;QACjD,GAAG,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE;KAClD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,WAAwB;IACpD,OAAO;QACL,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QAC5C,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QAC7C,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;KAC7C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,UAAsB;IACpD,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC;IAE5C,IAAI,KAAK,GAAG,MAAM,GAAG,CAAC,IAAI,KAAK,GAAG,KAAK,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1D,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,GAAG;QAAE,OAAO,aAAa,CAAC;IACnF,OAAO,SAAS,CAAC;AACnB,CAAC"}