solidworks-mcp-server 2.2.0 → 3.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/README.md +33 -10
- package/dist/application/services/command-bus.d.ts +39 -0
- package/dist/application/services/command-bus.d.ts.map +1 -0
- package/dist/application/services/command-bus.js +88 -0
- package/dist/application/services/command-bus.js.map +1 -0
- package/dist/application/services/event-bus.d.ts +31 -0
- package/dist/application/services/event-bus.d.ts.map +1 -0
- package/dist/application/services/event-bus.js +83 -0
- package/dist/application/services/event-bus.js.map +1 -0
- package/dist/application/services/query-bus.d.ts +30 -0
- package/dist/application/services/query-bus.d.ts.map +1 -0
- package/dist/application/services/query-bus.js +59 -0
- package/dist/application/services/query-bus.js.map +1 -0
- package/dist/application/services/tool-registry.d.ts +53 -0
- package/dist/application/services/tool-registry.d.ts.map +1 -0
- package/dist/application/services/tool-registry.js +81 -0
- package/dist/application/services/tool-registry.js.map +1 -0
- package/dist/application/use-cases/analysis/index.d.ts +13 -0
- package/dist/application/use-cases/analysis/index.d.ts.map +1 -0
- package/dist/application/use-cases/analysis/index.js +17 -0
- package/dist/application/use-cases/analysis/index.js.map +1 -0
- package/dist/application/use-cases/drawing/index.d.ts +13 -0
- package/dist/application/use-cases/drawing/index.d.ts.map +1 -0
- package/dist/application/use-cases/drawing/index.js +17 -0
- package/dist/application/use-cases/drawing/index.js.map +1 -0
- package/dist/application/use-cases/export/index.d.ts +13 -0
- package/dist/application/use-cases/export/index.d.ts.map +1 -0
- package/dist/application/use-cases/export/index.js +17 -0
- package/dist/application/use-cases/export/index.js.map +1 -0
- package/dist/application/use-cases/macro/index.d.ts +13 -0
- package/dist/application/use-cases/macro/index.d.ts.map +1 -0
- package/dist/application/use-cases/macro/index.js +17 -0
- package/dist/application/use-cases/macro/index.js.map +1 -0
- package/dist/application/use-cases/modeling/index.d.ts +56 -0
- package/dist/application/use-cases/modeling/index.d.ts.map +1 -0
- package/dist/application/use-cases/modeling/index.js +385 -0
- package/dist/application/use-cases/modeling/index.js.map +1 -0
- package/dist/core/interfaces/core-abstractions.d.ts +289 -0
- package/dist/core/interfaces/core-abstractions.d.ts.map +1 -0
- package/dist/core/interfaces/core-abstractions.js +121 -0
- package/dist/core/interfaces/core-abstractions.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -4
- package/dist/index.js.map +1 -1
- package/dist/index.refactored.d.ts +7 -0
- package/dist/index.refactored.d.ts.map +1 -0
- package/dist/index.refactored.js +254 -0
- package/dist/index.refactored.js.map +1 -0
- package/dist/infrastructure/config/configuration-manager.d.ts +381 -0
- package/dist/infrastructure/config/configuration-manager.d.ts.map +1 -0
- package/dist/infrastructure/config/configuration-manager.js +566 -0
- package/dist/infrastructure/config/configuration-manager.js.map +1 -0
- package/dist/infrastructure/container/service-locator.d.ts +14 -0
- package/dist/infrastructure/container/service-locator.d.ts.map +1 -0
- package/dist/infrastructure/container/service-locator.js +38 -0
- package/dist/infrastructure/container/service-locator.js.map +1 -0
- package/dist/infrastructure/logging/logger.d.ts +24 -0
- package/dist/infrastructure/logging/logger.d.ts.map +1 -0
- package/dist/infrastructure/logging/logger.js +65 -0
- package/dist/infrastructure/logging/logger.js.map +1 -0
- package/dist/infrastructure/solidworks/solidworks-adapter.d.ts +43 -0
- package/dist/infrastructure/solidworks/solidworks-adapter.d.ts.map +1 -0
- package/dist/infrastructure/solidworks/solidworks-adapter.js +527 -0
- package/dist/infrastructure/solidworks/solidworks-adapter.js.map +1 -0
- package/dist/presentation/mcp/request-handler.d.ts +41 -0
- package/dist/presentation/mcp/request-handler.d.ts.map +1 -0
- package/dist/presentation/mcp/request-handler.js +100 -0
- package/dist/presentation/mcp/request-handler.js.map +1 -0
- package/dist/presentation/transformers/error-transformer.d.ts +16 -0
- package/dist/presentation/transformers/error-transformer.d.ts.map +1 -0
- package/dist/presentation/transformers/error-transformer.js +44 -0
- package/dist/presentation/transformers/error-transformer.js.map +1 -0
- package/dist/presentation/transformers/response-transformer.d.ts +24 -0
- package/dist/presentation/transformers/response-transformer.d.ts.map +1 -0
- package/dist/presentation/transformers/response-transformer.js +102 -0
- package/dist/presentation/transformers/response-transformer.js.map +1 -0
- package/dist/shared/constants/solidworks-constants.d.ts +302 -0
- package/dist/shared/constants/solidworks-constants.d.ts.map +1 -0
- package/dist/shared/constants/solidworks-constants.js +471 -0
- package/dist/shared/constants/solidworks-constants.js.map +1 -0
- package/dist/tools/diagnostics.d.ts +21 -0
- package/dist/tools/diagnostics.d.ts.map +1 -0
- package/dist/tools/diagnostics.js +120 -0
- package/dist/tools/diagnostics.js.map +1 -0
- package/dist/tools/drawing-analysis.d.ts +9 -0
- package/dist/tools/drawing-analysis.d.ts.map +1 -0
- package/dist/tools/drawing-analysis.js +239 -0
- package/dist/tools/drawing-analysis.js.map +1 -0
- package/dist/tools/enhanced-drawing.d.ts +51 -0
- package/dist/tools/enhanced-drawing.d.ts.map +1 -0
- package/dist/tools/enhanced-drawing.js +193 -0
- package/dist/tools/enhanced-drawing.js.map +1 -0
- package/dist/tools/macro-security.d.ts +9 -0
- package/dist/tools/macro-security.d.ts.map +1 -0
- package/dist/tools/macro-security.js +86 -0
- package/dist/tools/macro-security.js.map +1 -0
- package/dist/tools/native-macro.d.ts +149 -0
- package/dist/tools/native-macro.d.ts.map +1 -0
- package/dist/tools/native-macro.js +654 -0
- package/dist/tools/native-macro.js.map +1 -0
- package/dist/tools/sketch.d.ts +663 -0
- package/dist/tools/sketch.d.ts.map +1 -0
- package/dist/tools/sketch.js +815 -0
- package/dist/tools/sketch.js.map +1 -0
- package/dist/tools/template-manager.d.ts +231 -0
- package/dist/tools/template-manager.d.ts.map +1 -0
- package/dist/tools/template-manager.js +626 -0
- package/dist/tools/template-manager.js.map +1 -0
- package/package.json +12 -7
|
@@ -0,0 +1,815 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Comprehensive Sketch Tools for SolidWorks
|
|
3
|
+
* Provides complete sketch plane creation and geometry drawing capabilities
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
/**
|
|
7
|
+
* Complete set of sketch creation and manipulation tools
|
|
8
|
+
*/
|
|
9
|
+
export const sketchTools = [
|
|
10
|
+
// ============================================
|
|
11
|
+
// SKETCH CREATION & MANAGEMENT
|
|
12
|
+
// ============================================
|
|
13
|
+
{
|
|
14
|
+
name: 'create_sketch',
|
|
15
|
+
description: 'Create a new sketch on a specified plane or face',
|
|
16
|
+
inputSchema: z.object({
|
|
17
|
+
plane: z.enum(['Front', 'Top', 'Right', 'Custom']).default('Front').describe('Reference plane for sketch'),
|
|
18
|
+
offset: z.number().default(0).describe('Offset distance from plane in mm'),
|
|
19
|
+
reverse: z.boolean().default(false).describe('Reverse offset direction'),
|
|
20
|
+
customPlane: z.object({
|
|
21
|
+
origin: z.object({
|
|
22
|
+
x: z.number().describe('X coordinate in mm'),
|
|
23
|
+
y: z.number().describe('Y coordinate in mm'),
|
|
24
|
+
z: z.number().describe('Z coordinate in mm')
|
|
25
|
+
}),
|
|
26
|
+
normal: z.object({
|
|
27
|
+
x: z.number().describe('X component of normal vector'),
|
|
28
|
+
y: z.number().describe('Y component of normal vector'),
|
|
29
|
+
z: z.number().describe('Z component of normal vector')
|
|
30
|
+
})
|
|
31
|
+
}).optional().describe('Custom plane definition')
|
|
32
|
+
}),
|
|
33
|
+
handler: (args, swApi) => {
|
|
34
|
+
try {
|
|
35
|
+
const model = swApi.getCurrentModel();
|
|
36
|
+
if (!model)
|
|
37
|
+
throw new Error('No active model');
|
|
38
|
+
// Select the appropriate plane
|
|
39
|
+
let planeRef;
|
|
40
|
+
if (args.plane === 'Custom' && args.customPlane) {
|
|
41
|
+
// Create custom reference plane
|
|
42
|
+
const { origin, normal } = args.customPlane;
|
|
43
|
+
planeRef = model.FeatureManager.InsertRefPlane(8, // FirstConstraint: parallel to plane
|
|
44
|
+
0, // FirstConstraintAngle
|
|
45
|
+
4, // SecondConstraint: distance
|
|
46
|
+
args.offset / 1000, // SecondConstraintAngle/Distance
|
|
47
|
+
0, // ThirdConstraint
|
|
48
|
+
0 // ThirdConstraintAngle
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
// Use standard plane
|
|
53
|
+
planeRef = model.FeatureManager.GetPlane(args.plane);
|
|
54
|
+
}
|
|
55
|
+
if (!planeRef)
|
|
56
|
+
throw new Error('Failed to get reference plane');
|
|
57
|
+
// Create offset plane if needed
|
|
58
|
+
if (args.offset !== 0) {
|
|
59
|
+
model.SelectByID2(args.plane + ' Plane', 'PLANE', 0, 0, 0, false, 0, null, 0);
|
|
60
|
+
planeRef = model.FeatureManager.InsertRefPlane(8, // Parallel to plane
|
|
61
|
+
0, 4, // Distance
|
|
62
|
+
args.offset / 1000, 0, 0);
|
|
63
|
+
}
|
|
64
|
+
// Insert sketch on plane
|
|
65
|
+
model.SketchManager.InsertSketch(true);
|
|
66
|
+
const sketchName = model.SketchManager.ActiveSketch?.Name;
|
|
67
|
+
return {
|
|
68
|
+
success: true,
|
|
69
|
+
sketchName,
|
|
70
|
+
plane: args.plane,
|
|
71
|
+
offset: args.offset,
|
|
72
|
+
message: `Sketch created on ${args.plane} plane${args.offset ? ` with ${args.offset}mm offset` : ''}`
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
return `Failed to create sketch: ${error}`;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: 'edit_sketch',
|
|
82
|
+
description: 'Enter sketch edit mode for an existing sketch',
|
|
83
|
+
inputSchema: z.object({
|
|
84
|
+
sketchName: z.string().describe('Name of the sketch to edit')
|
|
85
|
+
}),
|
|
86
|
+
handler: (args, swApi) => {
|
|
87
|
+
try {
|
|
88
|
+
const model = swApi.getCurrentModel();
|
|
89
|
+
if (!model)
|
|
90
|
+
throw new Error('No active model');
|
|
91
|
+
// Select the sketch
|
|
92
|
+
const selected = model.SelectByID2(args.sketchName, 'SKETCH', 0, 0, 0, false, 0, null, 0);
|
|
93
|
+
if (!selected)
|
|
94
|
+
throw new Error('Sketch not found');
|
|
95
|
+
// Edit sketch
|
|
96
|
+
model.EditSketch();
|
|
97
|
+
return {
|
|
98
|
+
success: true,
|
|
99
|
+
message: `Entered edit mode for sketch: ${args.sketchName}`
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
return `Failed to edit sketch: ${error}`;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: 'exit_sketch',
|
|
109
|
+
description: 'Exit sketch edit mode and rebuild',
|
|
110
|
+
inputSchema: z.object({
|
|
111
|
+
rebuild: z.boolean().default(true).describe('Rebuild model after exiting sketch')
|
|
112
|
+
}),
|
|
113
|
+
handler: (args, swApi) => {
|
|
114
|
+
try {
|
|
115
|
+
const model = swApi.getCurrentModel();
|
|
116
|
+
if (!model)
|
|
117
|
+
throw new Error('No active model');
|
|
118
|
+
// Exit sketch
|
|
119
|
+
model.SketchManager.InsertSketch(true);
|
|
120
|
+
// Rebuild if requested
|
|
121
|
+
if (args.rebuild) {
|
|
122
|
+
model.ForceRebuild3(false);
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
success: true,
|
|
126
|
+
message: 'Exited sketch edit mode'
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
return `Failed to exit sketch: ${error}`;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
// ============================================
|
|
135
|
+
// SKETCH GEOMETRY - LINES
|
|
136
|
+
// ============================================
|
|
137
|
+
{
|
|
138
|
+
name: 'sketch_line',
|
|
139
|
+
description: 'Draw a line in the active sketch',
|
|
140
|
+
inputSchema: z.object({
|
|
141
|
+
start: z.object({
|
|
142
|
+
x: z.number().describe('Start X coordinate in mm'),
|
|
143
|
+
y: z.number().describe('Start Y coordinate in mm'),
|
|
144
|
+
z: z.number().default(0).describe('Start Z coordinate in mm (for 3D sketches)')
|
|
145
|
+
}),
|
|
146
|
+
end: z.object({
|
|
147
|
+
x: z.number().describe('End X coordinate in mm'),
|
|
148
|
+
y: z.number().describe('End Y coordinate in mm'),
|
|
149
|
+
z: z.number().default(0).describe('End Z coordinate in mm (for 3D sketches)')
|
|
150
|
+
}),
|
|
151
|
+
construction: z.boolean().default(false).describe('Create as construction geometry')
|
|
152
|
+
}),
|
|
153
|
+
handler: (args, swApi) => {
|
|
154
|
+
try {
|
|
155
|
+
const model = swApi.getCurrentModel();
|
|
156
|
+
if (!model)
|
|
157
|
+
throw new Error('No active model');
|
|
158
|
+
const line = model.SketchManager.CreateLine(args.start.x / 1000, args.start.y / 1000, args.start.z / 1000, args.end.x / 1000, args.end.y / 1000, args.end.z / 1000);
|
|
159
|
+
if (!line)
|
|
160
|
+
throw new Error('Failed to create line');
|
|
161
|
+
// Set construction if needed
|
|
162
|
+
if (args.construction) {
|
|
163
|
+
line.ConstructionGeometry = true;
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
success: true,
|
|
167
|
+
message: `Line created from (${args.start.x}, ${args.start.y}) to (${args.end.x}, ${args.end.y})`,
|
|
168
|
+
length: Math.sqrt(Math.pow(args.end.x - args.start.x, 2) +
|
|
169
|
+
Math.pow(args.end.y - args.start.y, 2) +
|
|
170
|
+
Math.pow(args.end.z - args.start.z, 2))
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
return `Failed to create line: ${error}`;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
name: 'sketch_centerline',
|
|
180
|
+
description: 'Draw a centerline in the active sketch',
|
|
181
|
+
inputSchema: z.object({
|
|
182
|
+
start: z.object({
|
|
183
|
+
x: z.number().describe('Start X coordinate in mm'),
|
|
184
|
+
y: z.number().describe('Start Y coordinate in mm')
|
|
185
|
+
}),
|
|
186
|
+
end: z.object({
|
|
187
|
+
x: z.number().describe('End X coordinate in mm'),
|
|
188
|
+
y: z.number().describe('End Y coordinate in mm')
|
|
189
|
+
})
|
|
190
|
+
}),
|
|
191
|
+
handler: (args, swApi) => {
|
|
192
|
+
try {
|
|
193
|
+
const model = swApi.getCurrentModel();
|
|
194
|
+
if (!model)
|
|
195
|
+
throw new Error('No active model');
|
|
196
|
+
const line = model.SketchManager.CreateCenterLine(args.start.x / 1000, args.start.y / 1000, 0, args.end.x / 1000, args.end.y / 1000, 0);
|
|
197
|
+
if (!line)
|
|
198
|
+
throw new Error('Failed to create centerline');
|
|
199
|
+
return {
|
|
200
|
+
success: true,
|
|
201
|
+
message: `Centerline created from (${args.start.x}, ${args.start.y}) to (${args.end.x}, ${args.end.y})`
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
return `Failed to create centerline: ${error}`;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
// ============================================
|
|
210
|
+
// SKETCH GEOMETRY - CIRCLES & ARCS
|
|
211
|
+
// ============================================
|
|
212
|
+
{
|
|
213
|
+
name: 'sketch_circle',
|
|
214
|
+
description: 'Draw a circle in the active sketch',
|
|
215
|
+
inputSchema: z.object({
|
|
216
|
+
center: z.object({
|
|
217
|
+
x: z.number().describe('Center X coordinate in mm'),
|
|
218
|
+
y: z.number().describe('Center Y coordinate in mm'),
|
|
219
|
+
z: z.number().default(0).describe('Center Z coordinate in mm (for 3D sketches)')
|
|
220
|
+
}),
|
|
221
|
+
radius: z.number().positive().describe('Circle radius in mm'),
|
|
222
|
+
construction: z.boolean().default(false).describe('Create as construction geometry')
|
|
223
|
+
}),
|
|
224
|
+
handler: (args, swApi) => {
|
|
225
|
+
try {
|
|
226
|
+
const model = swApi.getCurrentModel();
|
|
227
|
+
if (!model)
|
|
228
|
+
throw new Error('No active model');
|
|
229
|
+
const circle = model.SketchManager.CreateCircle(args.center.x / 1000, args.center.y / 1000, args.center.z / 1000, (args.center.x + args.radius) / 1000, args.center.y / 1000, args.center.z / 1000);
|
|
230
|
+
if (!circle)
|
|
231
|
+
throw new Error('Failed to create circle');
|
|
232
|
+
// Set construction if needed
|
|
233
|
+
if (args.construction) {
|
|
234
|
+
circle.ConstructionGeometry = true;
|
|
235
|
+
}
|
|
236
|
+
return {
|
|
237
|
+
success: true,
|
|
238
|
+
message: `Circle created at (${args.center.x}, ${args.center.y}) with radius ${args.radius}mm`,
|
|
239
|
+
area: Math.PI * args.radius * args.radius,
|
|
240
|
+
circumference: 2 * Math.PI * args.radius
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
return `Failed to create circle: ${error}`;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
name: 'sketch_arc',
|
|
250
|
+
description: 'Draw an arc in the active sketch',
|
|
251
|
+
inputSchema: z.object({
|
|
252
|
+
center: z.object({
|
|
253
|
+
x: z.number().describe('Center X coordinate in mm'),
|
|
254
|
+
y: z.number().describe('Center Y coordinate in mm')
|
|
255
|
+
}),
|
|
256
|
+
start: z.object({
|
|
257
|
+
x: z.number().describe('Start point X coordinate in mm'),
|
|
258
|
+
y: z.number().describe('Start point Y coordinate in mm')
|
|
259
|
+
}),
|
|
260
|
+
end: z.object({
|
|
261
|
+
x: z.number().describe('End point X coordinate in mm'),
|
|
262
|
+
y: z.number().describe('End point Y coordinate in mm')
|
|
263
|
+
}),
|
|
264
|
+
direction: z.enum(['clockwise', 'counterclockwise']).default('counterclockwise'),
|
|
265
|
+
construction: z.boolean().default(false).describe('Create as construction geometry')
|
|
266
|
+
}),
|
|
267
|
+
handler: (args, swApi) => {
|
|
268
|
+
try {
|
|
269
|
+
const model = swApi.getCurrentModel();
|
|
270
|
+
if (!model)
|
|
271
|
+
throw new Error('No active model');
|
|
272
|
+
// Create arc (3-point arc)
|
|
273
|
+
const arc = model.SketchManager.Create3PointArc(args.start.x / 1000, args.start.y / 1000, 0, args.end.x / 1000, args.end.y / 1000, 0, args.center.x / 1000, args.center.y / 1000, 0);
|
|
274
|
+
if (!arc)
|
|
275
|
+
throw new Error('Failed to create arc');
|
|
276
|
+
// Set construction if needed
|
|
277
|
+
if (args.construction) {
|
|
278
|
+
arc.ConstructionGeometry = true;
|
|
279
|
+
}
|
|
280
|
+
// Calculate arc properties
|
|
281
|
+
const radius = Math.sqrt(Math.pow(args.start.x - args.center.x, 2) +
|
|
282
|
+
Math.pow(args.start.y - args.center.y, 2));
|
|
283
|
+
return {
|
|
284
|
+
success: true,
|
|
285
|
+
message: `Arc created with center at (${args.center.x}, ${args.center.y})`,
|
|
286
|
+
radius,
|
|
287
|
+
direction: args.direction
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
catch (error) {
|
|
291
|
+
return `Failed to create arc: ${error}`;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
},
|
|
295
|
+
// ============================================
|
|
296
|
+
// SKETCH GEOMETRY - RECTANGLES & POLYGONS
|
|
297
|
+
// ============================================
|
|
298
|
+
{
|
|
299
|
+
name: 'sketch_rectangle',
|
|
300
|
+
description: 'Draw a rectangle in the active sketch',
|
|
301
|
+
inputSchema: z.object({
|
|
302
|
+
corner1: z.object({
|
|
303
|
+
x: z.number().describe('First corner X coordinate in mm'),
|
|
304
|
+
y: z.number().describe('First corner Y coordinate in mm')
|
|
305
|
+
}),
|
|
306
|
+
corner2: z.object({
|
|
307
|
+
x: z.number().describe('Opposite corner X coordinate in mm'),
|
|
308
|
+
y: z.number().describe('Opposite corner Y coordinate in mm')
|
|
309
|
+
}),
|
|
310
|
+
centered: z.boolean().default(false).describe('Create rectangle centered at corner1'),
|
|
311
|
+
construction: z.boolean().default(false).describe('Create as construction geometry')
|
|
312
|
+
}),
|
|
313
|
+
handler: (args, swApi) => {
|
|
314
|
+
try {
|
|
315
|
+
const model = swApi.getCurrentModel();
|
|
316
|
+
if (!model)
|
|
317
|
+
throw new Error('No active model');
|
|
318
|
+
let x1 = args.corner1.x;
|
|
319
|
+
let y1 = args.corner1.y;
|
|
320
|
+
let x2 = args.corner2.x;
|
|
321
|
+
let y2 = args.corner2.y;
|
|
322
|
+
// Adjust for centered rectangle
|
|
323
|
+
if (args.centered) {
|
|
324
|
+
const width = args.corner2.x;
|
|
325
|
+
const height = args.corner2.y;
|
|
326
|
+
x1 = args.corner1.x - width / 2;
|
|
327
|
+
y1 = args.corner1.y - height / 2;
|
|
328
|
+
x2 = args.corner1.x + width / 2;
|
|
329
|
+
y2 = args.corner1.y + height / 2;
|
|
330
|
+
}
|
|
331
|
+
// Create four lines to form rectangle
|
|
332
|
+
const lines = [];
|
|
333
|
+
lines.push(model.SketchManager.CreateLine(x1 / 1000, y1 / 1000, 0, x2 / 1000, y1 / 1000, 0));
|
|
334
|
+
lines.push(model.SketchManager.CreateLine(x2 / 1000, y1 / 1000, 0, x2 / 1000, y2 / 1000, 0));
|
|
335
|
+
lines.push(model.SketchManager.CreateLine(x2 / 1000, y2 / 1000, 0, x1 / 1000, y2 / 1000, 0));
|
|
336
|
+
lines.push(model.SketchManager.CreateLine(x1 / 1000, y2 / 1000, 0, x1 / 1000, y1 / 1000, 0));
|
|
337
|
+
// Set construction if needed
|
|
338
|
+
if (args.construction) {
|
|
339
|
+
lines.forEach(line => {
|
|
340
|
+
if (line)
|
|
341
|
+
line.ConstructionGeometry = true;
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
const width = Math.abs(x2 - x1);
|
|
345
|
+
const height = Math.abs(y2 - y1);
|
|
346
|
+
return {
|
|
347
|
+
success: true,
|
|
348
|
+
message: `Rectangle created`,
|
|
349
|
+
width,
|
|
350
|
+
height,
|
|
351
|
+
area: width * height,
|
|
352
|
+
perimeter: 2 * (width + height)
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
catch (error) {
|
|
356
|
+
return `Failed to create rectangle: ${error}`;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
name: 'sketch_polygon',
|
|
362
|
+
description: 'Draw a regular polygon in the active sketch',
|
|
363
|
+
inputSchema: z.object({
|
|
364
|
+
center: z.object({
|
|
365
|
+
x: z.number().describe('Center X coordinate in mm'),
|
|
366
|
+
y: z.number().describe('Center Y coordinate in mm')
|
|
367
|
+
}),
|
|
368
|
+
sides: z.number().int().min(3).max(100).describe('Number of sides'),
|
|
369
|
+
radius: z.number().positive().describe('Circumscribed circle radius in mm'),
|
|
370
|
+
rotation: z.number().default(0).describe('Rotation angle in degrees'),
|
|
371
|
+
inscribed: z.boolean().default(false).describe('Use inscribed circle radius instead'),
|
|
372
|
+
construction: z.boolean().default(false).describe('Create as construction geometry')
|
|
373
|
+
}),
|
|
374
|
+
handler: (args, swApi) => {
|
|
375
|
+
try {
|
|
376
|
+
const model = swApi.getCurrentModel();
|
|
377
|
+
if (!model)
|
|
378
|
+
throw new Error('No active model');
|
|
379
|
+
const angleStep = (2 * Math.PI) / args.sides;
|
|
380
|
+
const startAngle = (args.rotation * Math.PI) / 180;
|
|
381
|
+
// Adjust radius for inscribed vs circumscribed
|
|
382
|
+
let radius = args.radius;
|
|
383
|
+
if (args.inscribed) {
|
|
384
|
+
radius = radius / Math.cos(Math.PI / args.sides);
|
|
385
|
+
}
|
|
386
|
+
// Create polygon lines
|
|
387
|
+
const lines = [];
|
|
388
|
+
for (let i = 0; i < args.sides; i++) {
|
|
389
|
+
const angle1 = startAngle + (i * angleStep);
|
|
390
|
+
const angle2 = startAngle + ((i + 1) * angleStep);
|
|
391
|
+
const x1 = args.center.x + radius * Math.cos(angle1);
|
|
392
|
+
const y1 = args.center.y + radius * Math.sin(angle1);
|
|
393
|
+
const x2 = args.center.x + radius * Math.cos(angle2);
|
|
394
|
+
const y2 = args.center.y + radius * Math.sin(angle2);
|
|
395
|
+
const line = model.SketchManager.CreateLine(x1 / 1000, y1 / 1000, 0, x2 / 1000, y2 / 1000, 0);
|
|
396
|
+
if (line && args.construction) {
|
|
397
|
+
line.ConstructionGeometry = true;
|
|
398
|
+
}
|
|
399
|
+
lines.push(line);
|
|
400
|
+
}
|
|
401
|
+
// Calculate polygon properties
|
|
402
|
+
const sideLength = 2 * radius * Math.sin(Math.PI / args.sides);
|
|
403
|
+
const apothem = radius * Math.cos(Math.PI / args.sides);
|
|
404
|
+
const area = 0.5 * args.sides * sideLength * apothem;
|
|
405
|
+
const perimeter = args.sides * sideLength;
|
|
406
|
+
return {
|
|
407
|
+
success: true,
|
|
408
|
+
message: `${args.sides}-sided polygon created`,
|
|
409
|
+
sides: args.sides,
|
|
410
|
+
radius,
|
|
411
|
+
sideLength,
|
|
412
|
+
area,
|
|
413
|
+
perimeter
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
catch (error) {
|
|
417
|
+
return `Failed to create polygon: ${error}`;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
},
|
|
421
|
+
// ============================================
|
|
422
|
+
// SKETCH GEOMETRY - SPLINES & CURVES
|
|
423
|
+
// ============================================
|
|
424
|
+
{
|
|
425
|
+
name: 'sketch_spline',
|
|
426
|
+
description: 'Draw a spline through points in the active sketch',
|
|
427
|
+
inputSchema: z.object({
|
|
428
|
+
points: z.array(z.object({
|
|
429
|
+
x: z.number().describe('X coordinate in mm'),
|
|
430
|
+
y: z.number().describe('Y coordinate in mm'),
|
|
431
|
+
z: z.number().default(0).describe('Z coordinate in mm (for 3D sketches)')
|
|
432
|
+
})).min(2).describe('Array of points for the spline'),
|
|
433
|
+
closed: z.boolean().default(false).describe('Close the spline'),
|
|
434
|
+
construction: z.boolean().default(false).describe('Create as construction geometry')
|
|
435
|
+
}),
|
|
436
|
+
handler: (args, swApi) => {
|
|
437
|
+
try {
|
|
438
|
+
const model = swApi.getCurrentModel();
|
|
439
|
+
if (!model)
|
|
440
|
+
throw new Error('No active model');
|
|
441
|
+
// Convert points to variant array format needed by SolidWorks
|
|
442
|
+
const pointArray = [];
|
|
443
|
+
args.points.forEach((pt) => {
|
|
444
|
+
pointArray.push(pt.x / 1000, pt.y / 1000, pt.z / 1000);
|
|
445
|
+
});
|
|
446
|
+
// Create spline
|
|
447
|
+
const spline = model.SketchManager.CreateSpline(pointArray);
|
|
448
|
+
if (!spline)
|
|
449
|
+
throw new Error('Failed to create spline');
|
|
450
|
+
// Set construction if needed
|
|
451
|
+
if (args.construction) {
|
|
452
|
+
spline.ConstructionGeometry = true;
|
|
453
|
+
}
|
|
454
|
+
// Calculate approximate length
|
|
455
|
+
let length = 0;
|
|
456
|
+
for (let i = 1; i < args.points.length; i++) {
|
|
457
|
+
const dx = args.points[i].x - args.points[i - 1].x;
|
|
458
|
+
const dy = args.points[i].y - args.points[i - 1].y;
|
|
459
|
+
const dz = args.points[i].z - args.points[i - 1].z;
|
|
460
|
+
length += Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
461
|
+
}
|
|
462
|
+
return {
|
|
463
|
+
success: true,
|
|
464
|
+
message: `Spline created through ${args.points.length} points`,
|
|
465
|
+
pointCount: args.points.length,
|
|
466
|
+
approximateLength: length,
|
|
467
|
+
closed: args.closed
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
catch (error) {
|
|
471
|
+
return `Failed to create spline: ${error}`;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
},
|
|
475
|
+
{
|
|
476
|
+
name: 'sketch_ellipse',
|
|
477
|
+
description: 'Draw an ellipse in the active sketch',
|
|
478
|
+
inputSchema: z.object({
|
|
479
|
+
center: z.object({
|
|
480
|
+
x: z.number().describe('Center X coordinate in mm'),
|
|
481
|
+
y: z.number().describe('Center Y coordinate in mm')
|
|
482
|
+
}),
|
|
483
|
+
majorAxis: z.object({
|
|
484
|
+
length: z.number().positive().describe('Major axis length in mm'),
|
|
485
|
+
angle: z.number().default(0).describe('Major axis angle in degrees')
|
|
486
|
+
}),
|
|
487
|
+
minorAxis: z.number().positive().describe('Minor axis length in mm'),
|
|
488
|
+
construction: z.boolean().default(false).describe('Create as construction geometry')
|
|
489
|
+
}),
|
|
490
|
+
handler: (args, swApi) => {
|
|
491
|
+
try {
|
|
492
|
+
const model = swApi.getCurrentModel();
|
|
493
|
+
if (!model)
|
|
494
|
+
throw new Error('No active model');
|
|
495
|
+
const angleRad = (args.majorAxis.angle * Math.PI) / 180;
|
|
496
|
+
// Calculate major axis endpoints
|
|
497
|
+
const major1X = args.center.x + (args.majorAxis.length / 2) * Math.cos(angleRad);
|
|
498
|
+
const major1Y = args.center.y + (args.majorAxis.length / 2) * Math.sin(angleRad);
|
|
499
|
+
const major2X = args.center.x - (args.majorAxis.length / 2) * Math.cos(angleRad);
|
|
500
|
+
const major2Y = args.center.y - (args.majorAxis.length / 2) * Math.sin(angleRad);
|
|
501
|
+
// Calculate minor axis point
|
|
502
|
+
const minorX = args.center.x + (args.minorAxis / 2) * Math.cos(angleRad + Math.PI / 2);
|
|
503
|
+
const minorY = args.center.y + (args.minorAxis / 2) * Math.sin(angleRad + Math.PI / 2);
|
|
504
|
+
// Create ellipse
|
|
505
|
+
const ellipse = model.SketchManager.CreateEllipse(args.center.x / 1000, args.center.y / 1000, 0, major1X / 1000, major1Y / 1000, 0, minorX / 1000, minorY / 1000, 0);
|
|
506
|
+
if (!ellipse)
|
|
507
|
+
throw new Error('Failed to create ellipse');
|
|
508
|
+
// Set construction if needed
|
|
509
|
+
if (args.construction) {
|
|
510
|
+
ellipse.ConstructionGeometry = true;
|
|
511
|
+
}
|
|
512
|
+
// Calculate ellipse properties
|
|
513
|
+
const a = args.majorAxis.length / 2;
|
|
514
|
+
const b = args.minorAxis / 2;
|
|
515
|
+
const area = Math.PI * a * b;
|
|
516
|
+
// Approximate perimeter using Ramanujan's formula
|
|
517
|
+
const h = Math.pow((a - b), 2) / Math.pow((a + b), 2);
|
|
518
|
+
const perimeter = Math.PI * (a + b) * (1 + (3 * h) / (10 + Math.sqrt(4 - 3 * h)));
|
|
519
|
+
return {
|
|
520
|
+
success: true,
|
|
521
|
+
message: `Ellipse created at (${args.center.x}, ${args.center.y})`,
|
|
522
|
+
majorAxis: args.majorAxis.length,
|
|
523
|
+
minorAxis: args.minorAxis,
|
|
524
|
+
area,
|
|
525
|
+
perimeter
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
catch (error) {
|
|
529
|
+
return `Failed to create ellipse: ${error}`;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
},
|
|
533
|
+
// ============================================
|
|
534
|
+
// SKETCH CONSTRAINTS
|
|
535
|
+
// ============================================
|
|
536
|
+
{
|
|
537
|
+
name: 'add_sketch_constraint',
|
|
538
|
+
description: 'Add constraints between sketch entities',
|
|
539
|
+
inputSchema: z.object({
|
|
540
|
+
type: z.enum([
|
|
541
|
+
'coincident', 'parallel', 'perpendicular', 'tangent',
|
|
542
|
+
'concentric', 'horizontal', 'vertical', 'equal',
|
|
543
|
+
'symmetric', 'colinear', 'midpoint', 'fix'
|
|
544
|
+
]).describe('Type of constraint to add'),
|
|
545
|
+
entity1: z.string().describe('First entity selection'),
|
|
546
|
+
entity2: z.string().optional().describe('Second entity selection (if required)'),
|
|
547
|
+
entity3: z.string().optional().describe('Third entity selection (for symmetric constraint)')
|
|
548
|
+
}),
|
|
549
|
+
handler: (args, swApi) => {
|
|
550
|
+
try {
|
|
551
|
+
const model = swApi.getCurrentModel();
|
|
552
|
+
if (!model)
|
|
553
|
+
throw new Error('No active model');
|
|
554
|
+
// Map constraint types to SolidWorks constants
|
|
555
|
+
const constraintMap = {
|
|
556
|
+
'coincident': 0,
|
|
557
|
+
'parallel': 1,
|
|
558
|
+
'perpendicular': 2,
|
|
559
|
+
'tangent': 3,
|
|
560
|
+
'concentric': 4,
|
|
561
|
+
'horizontal': 5,
|
|
562
|
+
'vertical': 6,
|
|
563
|
+
'equal': 7,
|
|
564
|
+
'symmetric': 8,
|
|
565
|
+
'colinear': 9,
|
|
566
|
+
'midpoint': 10,
|
|
567
|
+
'fix': 11
|
|
568
|
+
};
|
|
569
|
+
const constraintType = constraintMap[args.type];
|
|
570
|
+
// Select entities
|
|
571
|
+
model.ClearSelection2(true);
|
|
572
|
+
model.SelectByID2(args.entity1, 'SKETCHSEGMENT', 0, 0, 0, false, 0, null, 0);
|
|
573
|
+
if (args.entity2) {
|
|
574
|
+
model.SelectByID2(args.entity2, 'SKETCHSEGMENT', 0, 0, 0, true, 0, null, 0);
|
|
575
|
+
}
|
|
576
|
+
if (args.entity3) {
|
|
577
|
+
model.SelectByID2(args.entity3, 'SKETCHSEGMENT', 0, 0, 0, true, 0, null, 0);
|
|
578
|
+
}
|
|
579
|
+
// Add constraint
|
|
580
|
+
const success = model.SketchManager.AddConstraint(constraintType);
|
|
581
|
+
if (!success)
|
|
582
|
+
throw new Error('Failed to add constraint');
|
|
583
|
+
return {
|
|
584
|
+
success: true,
|
|
585
|
+
message: `${args.type} constraint added`,
|
|
586
|
+
type: args.type
|
|
587
|
+
};
|
|
588
|
+
}
|
|
589
|
+
catch (error) {
|
|
590
|
+
return `Failed to add constraint: ${error}`;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
},
|
|
594
|
+
// ============================================
|
|
595
|
+
// SKETCH DIMENSIONS
|
|
596
|
+
// ============================================
|
|
597
|
+
{
|
|
598
|
+
name: 'add_sketch_dimension',
|
|
599
|
+
description: 'Add dimensions to sketch entities',
|
|
600
|
+
inputSchema: z.object({
|
|
601
|
+
type: z.enum(['linear', 'angular', 'radial', 'diameter']).describe('Type of dimension'),
|
|
602
|
+
entity: z.string().describe('Entity to dimension'),
|
|
603
|
+
value: z.number().describe('Dimension value in mm or degrees'),
|
|
604
|
+
position: z.object({
|
|
605
|
+
x: z.number().describe('Text position X in mm'),
|
|
606
|
+
y: z.number().describe('Text position Y in mm')
|
|
607
|
+
}).optional().describe('Text position')
|
|
608
|
+
}),
|
|
609
|
+
handler: (args, swApi) => {
|
|
610
|
+
try {
|
|
611
|
+
const model = swApi.getCurrentModel();
|
|
612
|
+
if (!model)
|
|
613
|
+
throw new Error('No active model');
|
|
614
|
+
// Select entity
|
|
615
|
+
model.ClearSelection2(true);
|
|
616
|
+
model.SelectByID2(args.entity, 'SKETCHSEGMENT', 0, 0, 0, false, 0, null, 0);
|
|
617
|
+
// Add dimension
|
|
618
|
+
const textX = args.position?.x || 0;
|
|
619
|
+
const textY = args.position?.y || 0;
|
|
620
|
+
let dimension;
|
|
621
|
+
switch (args.type) {
|
|
622
|
+
case 'linear':
|
|
623
|
+
dimension = model.AddDimension2(textX / 1000, textY / 1000, 0);
|
|
624
|
+
break;
|
|
625
|
+
case 'angular':
|
|
626
|
+
dimension = model.AddDimension2(textX / 1000, textY / 1000, 0);
|
|
627
|
+
break;
|
|
628
|
+
case 'radial':
|
|
629
|
+
dimension = model.AddRadialDimension2(textX / 1000, textY / 1000, 0);
|
|
630
|
+
break;
|
|
631
|
+
case 'diameter':
|
|
632
|
+
dimension = model.AddDiameterDimension2(textX / 1000, textY / 1000, 0);
|
|
633
|
+
break;
|
|
634
|
+
}
|
|
635
|
+
if (!dimension)
|
|
636
|
+
throw new Error('Failed to add dimension');
|
|
637
|
+
// Set dimension value
|
|
638
|
+
dimension.SystemValue = args.type === 'angular'
|
|
639
|
+
? (args.value * Math.PI / 180) // Convert degrees to radians
|
|
640
|
+
: (args.value / 1000); // Convert mm to meters
|
|
641
|
+
return {
|
|
642
|
+
success: true,
|
|
643
|
+
message: `${args.type} dimension added with value ${args.value}${args.type === 'angular' ? '°' : 'mm'}`,
|
|
644
|
+
type: args.type,
|
|
645
|
+
value: args.value
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
catch (error) {
|
|
649
|
+
return `Failed to add dimension: ${error}`;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
},
|
|
653
|
+
// ============================================
|
|
654
|
+
// SKETCH PATTERNS
|
|
655
|
+
// ============================================
|
|
656
|
+
{
|
|
657
|
+
name: 'sketch_linear_pattern',
|
|
658
|
+
description: 'Create a linear pattern of sketch entities',
|
|
659
|
+
inputSchema: z.object({
|
|
660
|
+
entities: z.array(z.string()).describe('Entities to pattern'),
|
|
661
|
+
direction1: z.object({
|
|
662
|
+
x: z.number().describe('Direction vector X'),
|
|
663
|
+
y: z.number().describe('Direction vector Y'),
|
|
664
|
+
count: z.number().int().min(2).describe('Number of instances'),
|
|
665
|
+
spacing: z.number().positive().describe('Spacing in mm')
|
|
666
|
+
}),
|
|
667
|
+
direction2: z.object({
|
|
668
|
+
x: z.number().describe('Direction vector X'),
|
|
669
|
+
y: z.number().describe('Direction vector Y'),
|
|
670
|
+
count: z.number().int().min(2).describe('Number of instances'),
|
|
671
|
+
spacing: z.number().positive().describe('Spacing in mm')
|
|
672
|
+
}).optional().describe('Second direction for 2D pattern')
|
|
673
|
+
}),
|
|
674
|
+
handler: (args, swApi) => {
|
|
675
|
+
try {
|
|
676
|
+
const model = swApi.getCurrentModel();
|
|
677
|
+
if (!model)
|
|
678
|
+
throw new Error('No active model');
|
|
679
|
+
// Select entities to pattern
|
|
680
|
+
model.ClearSelection2(true);
|
|
681
|
+
args.entities.forEach((entity) => {
|
|
682
|
+
model.SelectByID2(entity, 'SKETCHSEGMENT', 0, 0, 0, true, 0, null, 0);
|
|
683
|
+
});
|
|
684
|
+
// Create pattern
|
|
685
|
+
const totalInstances = args.direction1.count * (args.direction2?.count || 1);
|
|
686
|
+
// Note: Actual implementation would use SketchManager.CreateLinearSketchStepAndRepeat
|
|
687
|
+
return {
|
|
688
|
+
success: true,
|
|
689
|
+
message: `Linear pattern created with ${totalInstances} instances`,
|
|
690
|
+
direction1Count: args.direction1.count,
|
|
691
|
+
direction2Count: args.direction2?.count || 1,
|
|
692
|
+
totalInstances
|
|
693
|
+
};
|
|
694
|
+
}
|
|
695
|
+
catch (error) {
|
|
696
|
+
return `Failed to create linear pattern: ${error}`;
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
},
|
|
700
|
+
{
|
|
701
|
+
name: 'sketch_circular_pattern',
|
|
702
|
+
description: 'Create a circular pattern of sketch entities',
|
|
703
|
+
inputSchema: z.object({
|
|
704
|
+
entities: z.array(z.string()).describe('Entities to pattern'),
|
|
705
|
+
center: z.object({
|
|
706
|
+
x: z.number().describe('Center X coordinate in mm'),
|
|
707
|
+
y: z.number().describe('Center Y coordinate in mm')
|
|
708
|
+
}),
|
|
709
|
+
count: z.number().int().min(2).describe('Number of instances'),
|
|
710
|
+
angle: z.number().default(360).describe('Total angle in degrees'),
|
|
711
|
+
equalSpacing: z.boolean().default(true).describe('Equal spacing between instances')
|
|
712
|
+
}),
|
|
713
|
+
handler: (args, swApi) => {
|
|
714
|
+
try {
|
|
715
|
+
const model = swApi.getCurrentModel();
|
|
716
|
+
if (!model)
|
|
717
|
+
throw new Error('No active model');
|
|
718
|
+
// Select entities to pattern
|
|
719
|
+
model.ClearSelection2(true);
|
|
720
|
+
args.entities.forEach((entity) => {
|
|
721
|
+
model.SelectByID2(entity, 'SKETCHSEGMENT', 0, 0, 0, true, 0, null, 0);
|
|
722
|
+
});
|
|
723
|
+
// Calculate angular spacing
|
|
724
|
+
const angleStep = args.angle / (args.equalSpacing ? args.count : args.count - 1);
|
|
725
|
+
// Note: Actual implementation would use SketchManager.CreateCircularSketchStepAndRepeat
|
|
726
|
+
return {
|
|
727
|
+
success: true,
|
|
728
|
+
message: `Circular pattern created with ${args.count} instances`,
|
|
729
|
+
count: args.count,
|
|
730
|
+
totalAngle: args.angle,
|
|
731
|
+
anglePerInstance: angleStep
|
|
732
|
+
};
|
|
733
|
+
}
|
|
734
|
+
catch (error) {
|
|
735
|
+
return `Failed to create circular pattern: ${error}`;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
},
|
|
739
|
+
// ============================================
|
|
740
|
+
// SKETCH TRANSFORMATIONS
|
|
741
|
+
// ============================================
|
|
742
|
+
{
|
|
743
|
+
name: 'sketch_mirror',
|
|
744
|
+
description: 'Mirror sketch entities about a line',
|
|
745
|
+
inputSchema: z.object({
|
|
746
|
+
entities: z.array(z.string()).describe('Entities to mirror'),
|
|
747
|
+
mirrorLine: z.string().describe('Mirror line (centerline or construction line)'),
|
|
748
|
+
copy: z.boolean().default(true).describe('Keep original entities')
|
|
749
|
+
}),
|
|
750
|
+
handler: (args, swApi) => {
|
|
751
|
+
try {
|
|
752
|
+
const model = swApi.getCurrentModel();
|
|
753
|
+
if (!model)
|
|
754
|
+
throw new Error('No active model');
|
|
755
|
+
// Select entities to mirror
|
|
756
|
+
model.ClearSelection2(true);
|
|
757
|
+
args.entities.forEach((entity) => {
|
|
758
|
+
model.SelectByID2(entity, 'SKETCHSEGMENT', 0, 0, 0, true, 0, null, 0);
|
|
759
|
+
});
|
|
760
|
+
// Select mirror line
|
|
761
|
+
model.SelectByID2(args.mirrorLine, 'SKETCHSEGMENT', 0, 0, 0, true, 1, null, 0);
|
|
762
|
+
// Mirror entities
|
|
763
|
+
model.SketchManager.MirrorSketch();
|
|
764
|
+
return {
|
|
765
|
+
success: true,
|
|
766
|
+
message: `Mirrored ${args.entities.length} entities`,
|
|
767
|
+
entityCount: args.entities.length,
|
|
768
|
+
keepOriginal: args.copy
|
|
769
|
+
};
|
|
770
|
+
}
|
|
771
|
+
catch (error) {
|
|
772
|
+
return `Failed to mirror entities: ${error}`;
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
},
|
|
776
|
+
{
|
|
777
|
+
name: 'sketch_offset',
|
|
778
|
+
description: 'Create offset curves from sketch entities',
|
|
779
|
+
inputSchema: z.object({
|
|
780
|
+
entities: z.array(z.string()).describe('Entities to offset'),
|
|
781
|
+
distance: z.number().describe('Offset distance in mm (positive = outward)'),
|
|
782
|
+
side: z.enum(['both', 'left', 'right']).default('both').describe('Offset side'),
|
|
783
|
+
corner: z.enum(['sharp', 'round', 'natural']).default('natural').describe('Corner treatment'),
|
|
784
|
+
cap: z.boolean().default(true).describe('Cap ends for open curves')
|
|
785
|
+
}),
|
|
786
|
+
handler: (args, swApi) => {
|
|
787
|
+
try {
|
|
788
|
+
const model = swApi.getCurrentModel();
|
|
789
|
+
if (!model)
|
|
790
|
+
throw new Error('No active model');
|
|
791
|
+
// Select entities to offset
|
|
792
|
+
model.ClearSelection2(true);
|
|
793
|
+
args.entities.forEach((entity) => {
|
|
794
|
+
model.SelectByID2(entity, 'SKETCHSEGMENT', 0, 0, 0, true, 0, null, 0);
|
|
795
|
+
});
|
|
796
|
+
// Create offset
|
|
797
|
+
const sideValue = args.side === 'both' ? 0 : (args.side === 'left' ? 1 : 2);
|
|
798
|
+
model.SketchManager.SketchOffset2(args.distance / 1000, // Convert to meters
|
|
799
|
+
sideValue, false, // Not chain
|
|
800
|
+
args.cap);
|
|
801
|
+
return {
|
|
802
|
+
success: true,
|
|
803
|
+
message: `Offset created at ${args.distance}mm`,
|
|
804
|
+
distance: args.distance,
|
|
805
|
+
side: args.side,
|
|
806
|
+
corner: args.corner
|
|
807
|
+
};
|
|
808
|
+
}
|
|
809
|
+
catch (error) {
|
|
810
|
+
return `Failed to create offset: ${error}`;
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
];
|
|
815
|
+
//# sourceMappingURL=sketch.js.map
|