solidworks-mcp-server
Version:
Clean Architecture SolidWorks MCP Server - Production-ready with SOLID principles
815 lines • 37.1 kB
JavaScript
/**
* Comprehensive Sketch Tools for SolidWorks
* Provides complete sketch plane creation and geometry drawing capabilities
*/
import { z } from 'zod';
/**
* Complete set of sketch creation and manipulation tools
*/
export const sketchTools = [
// ============================================
// SKETCH CREATION & MANAGEMENT
// ============================================
{
name: 'create_sketch',
description: 'Create a new sketch on a specified plane or face',
inputSchema: z.object({
plane: z.enum(['Front', 'Top', 'Right', 'Custom']).default('Front').describe('Reference plane for sketch'),
offset: z.number().default(0).describe('Offset distance from plane in mm'),
reverse: z.boolean().default(false).describe('Reverse offset direction'),
customPlane: z.object({
origin: z.object({
x: z.number().describe('X coordinate in mm'),
y: z.number().describe('Y coordinate in mm'),
z: z.number().describe('Z coordinate in mm')
}),
normal: z.object({
x: z.number().describe('X component of normal vector'),
y: z.number().describe('Y component of normal vector'),
z: z.number().describe('Z component of normal vector')
})
}).optional().describe('Custom plane definition')
}),
handler: (args, swApi) => {
try {
const model = swApi.getCurrentModel();
if (!model)
throw new Error('No active model');
// Select the appropriate plane
let planeRef;
if (args.plane === 'Custom' && args.customPlane) {
// Create custom reference plane
const { origin, normal } = args.customPlane;
planeRef = model.FeatureManager.InsertRefPlane(8, // FirstConstraint: parallel to plane
0, // FirstConstraintAngle
4, // SecondConstraint: distance
args.offset / 1000, // SecondConstraintAngle/Distance
0, // ThirdConstraint
0 // ThirdConstraintAngle
);
}
else {
// Use standard plane
planeRef = model.FeatureManager.GetPlane(args.plane);
}
if (!planeRef)
throw new Error('Failed to get reference plane');
// Create offset plane if needed
if (args.offset !== 0) {
model.SelectByID2(args.plane + ' Plane', 'PLANE', 0, 0, 0, false, 0, null, 0);
planeRef = model.FeatureManager.InsertRefPlane(8, // Parallel to plane
0, 4, // Distance
args.offset / 1000, 0, 0);
}
// Insert sketch on plane
model.SketchManager.InsertSketch(true);
const sketchName = model.SketchManager.ActiveSketch?.Name;
return {
success: true,
sketchName,
plane: args.plane,
offset: args.offset,
message: `Sketch created on ${args.plane} plane${args.offset ? ` with ${args.offset}mm offset` : ''}`
};
}
catch (error) {
return `Failed to create sketch: ${error}`;
}
}
},
{
name: 'edit_sketch',
description: 'Enter sketch edit mode for an existing sketch',
inputSchema: z.object({
sketchName: z.string().describe('Name of the sketch to edit')
}),
handler: (args, swApi) => {
try {
const model = swApi.getCurrentModel();
if (!model)
throw new Error('No active model');
// Select the sketch
const selected = model.SelectByID2(args.sketchName, 'SKETCH', 0, 0, 0, false, 0, null, 0);
if (!selected)
throw new Error('Sketch not found');
// Edit sketch
model.EditSketch();
return {
success: true,
message: `Entered edit mode for sketch: ${args.sketchName}`
};
}
catch (error) {
return `Failed to edit sketch: ${error}`;
}
}
},
{
name: 'exit_sketch',
description: 'Exit sketch edit mode and rebuild',
inputSchema: z.object({
rebuild: z.boolean().default(true).describe('Rebuild model after exiting sketch')
}),
handler: (args, swApi) => {
try {
const model = swApi.getCurrentModel();
if (!model)
throw new Error('No active model');
// Exit sketch
model.SketchManager.InsertSketch(true);
// Rebuild if requested
if (args.rebuild) {
model.ForceRebuild3(false);
}
return {
success: true,
message: 'Exited sketch edit mode'
};
}
catch (error) {
return `Failed to exit sketch: ${error}`;
}
}
},
// ============================================
// SKETCH GEOMETRY - LINES
// ============================================
{
name: 'sketch_line',
description: 'Draw a line in the active sketch',
inputSchema: z.object({
start: z.object({
x: z.number().describe('Start X coordinate in mm'),
y: z.number().describe('Start Y coordinate in mm'),
z: z.number().default(0).describe('Start Z coordinate in mm (for 3D sketches)')
}),
end: z.object({
x: z.number().describe('End X coordinate in mm'),
y: z.number().describe('End Y coordinate in mm'),
z: z.number().default(0).describe('End Z coordinate in mm (for 3D sketches)')
}),
construction: z.boolean().default(false).describe('Create as construction geometry')
}),
handler: (args, swApi) => {
try {
const model = swApi.getCurrentModel();
if (!model)
throw new Error('No active model');
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);
if (!line)
throw new Error('Failed to create line');
// Set construction if needed
if (args.construction) {
line.ConstructionGeometry = true;
}
return {
success: true,
message: `Line created from (${args.start.x}, ${args.start.y}) to (${args.end.x}, ${args.end.y})`,
length: Math.sqrt(Math.pow(args.end.x - args.start.x, 2) +
Math.pow(args.end.y - args.start.y, 2) +
Math.pow(args.end.z - args.start.z, 2))
};
}
catch (error) {
return `Failed to create line: ${error}`;
}
}
},
{
name: 'sketch_centerline',
description: 'Draw a centerline in the active sketch',
inputSchema: z.object({
start: z.object({
x: z.number().describe('Start X coordinate in mm'),
y: z.number().describe('Start Y coordinate in mm')
}),
end: z.object({
x: z.number().describe('End X coordinate in mm'),
y: z.number().describe('End Y coordinate in mm')
})
}),
handler: (args, swApi) => {
try {
const model = swApi.getCurrentModel();
if (!model)
throw new Error('No active model');
const line = model.SketchManager.CreateCenterLine(args.start.x / 1000, args.start.y / 1000, 0, args.end.x / 1000, args.end.y / 1000, 0);
if (!line)
throw new Error('Failed to create centerline');
return {
success: true,
message: `Centerline created from (${args.start.x}, ${args.start.y}) to (${args.end.x}, ${args.end.y})`
};
}
catch (error) {
return `Failed to create centerline: ${error}`;
}
}
},
// ============================================
// SKETCH GEOMETRY - CIRCLES & ARCS
// ============================================
{
name: 'sketch_circle',
description: 'Draw a circle in the active sketch',
inputSchema: z.object({
center: z.object({
x: z.number().describe('Center X coordinate in mm'),
y: z.number().describe('Center Y coordinate in mm'),
z: z.number().default(0).describe('Center Z coordinate in mm (for 3D sketches)')
}),
radius: z.number().positive().describe('Circle radius in mm'),
construction: z.boolean().default(false).describe('Create as construction geometry')
}),
handler: (args, swApi) => {
try {
const model = swApi.getCurrentModel();
if (!model)
throw new Error('No active model');
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);
if (!circle)
throw new Error('Failed to create circle');
// Set construction if needed
if (args.construction) {
circle.ConstructionGeometry = true;
}
return {
success: true,
message: `Circle created at (${args.center.x}, ${args.center.y}) with radius ${args.radius}mm`,
area: Math.PI * args.radius * args.radius,
circumference: 2 * Math.PI * args.radius
};
}
catch (error) {
return `Failed to create circle: ${error}`;
}
}
},
{
name: 'sketch_arc',
description: 'Draw an arc in the active sketch',
inputSchema: z.object({
center: z.object({
x: z.number().describe('Center X coordinate in mm'),
y: z.number().describe('Center Y coordinate in mm')
}),
start: z.object({
x: z.number().describe('Start point X coordinate in mm'),
y: z.number().describe('Start point Y coordinate in mm')
}),
end: z.object({
x: z.number().describe('End point X coordinate in mm'),
y: z.number().describe('End point Y coordinate in mm')
}),
direction: z.enum(['clockwise', 'counterclockwise']).default('counterclockwise'),
construction: z.boolean().default(false).describe('Create as construction geometry')
}),
handler: (args, swApi) => {
try {
const model = swApi.getCurrentModel();
if (!model)
throw new Error('No active model');
// Create arc (3-point arc)
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);
if (!arc)
throw new Error('Failed to create arc');
// Set construction if needed
if (args.construction) {
arc.ConstructionGeometry = true;
}
// Calculate arc properties
const radius = Math.sqrt(Math.pow(args.start.x - args.center.x, 2) +
Math.pow(args.start.y - args.center.y, 2));
return {
success: true,
message: `Arc created with center at (${args.center.x}, ${args.center.y})`,
radius,
direction: args.direction
};
}
catch (error) {
return `Failed to create arc: ${error}`;
}
}
},
// ============================================
// SKETCH GEOMETRY - RECTANGLES & POLYGONS
// ============================================
{
name: 'sketch_rectangle',
description: 'Draw a rectangle in the active sketch',
inputSchema: z.object({
corner1: z.object({
x: z.number().describe('First corner X coordinate in mm'),
y: z.number().describe('First corner Y coordinate in mm')
}),
corner2: z.object({
x: z.number().describe('Opposite corner X coordinate in mm'),
y: z.number().describe('Opposite corner Y coordinate in mm')
}),
centered: z.boolean().default(false).describe('Create rectangle centered at corner1'),
construction: z.boolean().default(false).describe('Create as construction geometry')
}),
handler: (args, swApi) => {
try {
const model = swApi.getCurrentModel();
if (!model)
throw new Error('No active model');
let x1 = args.corner1.x;
let y1 = args.corner1.y;
let x2 = args.corner2.x;
let y2 = args.corner2.y;
// Adjust for centered rectangle
if (args.centered) {
const width = args.corner2.x;
const height = args.corner2.y;
x1 = args.corner1.x - width / 2;
y1 = args.corner1.y - height / 2;
x2 = args.corner1.x + width / 2;
y2 = args.corner1.y + height / 2;
}
// Create four lines to form rectangle
const lines = [];
lines.push(model.SketchManager.CreateLine(x1 / 1000, y1 / 1000, 0, x2 / 1000, y1 / 1000, 0));
lines.push(model.SketchManager.CreateLine(x2 / 1000, y1 / 1000, 0, x2 / 1000, y2 / 1000, 0));
lines.push(model.SketchManager.CreateLine(x2 / 1000, y2 / 1000, 0, x1 / 1000, y2 / 1000, 0));
lines.push(model.SketchManager.CreateLine(x1 / 1000, y2 / 1000, 0, x1 / 1000, y1 / 1000, 0));
// Set construction if needed
if (args.construction) {
lines.forEach(line => {
if (line)
line.ConstructionGeometry = true;
});
}
const width = Math.abs(x2 - x1);
const height = Math.abs(y2 - y1);
return {
success: true,
message: `Rectangle created`,
width,
height,
area: width * height,
perimeter: 2 * (width + height)
};
}
catch (error) {
return `Failed to create rectangle: ${error}`;
}
}
},
{
name: 'sketch_polygon',
description: 'Draw a regular polygon in the active sketch',
inputSchema: z.object({
center: z.object({
x: z.number().describe('Center X coordinate in mm'),
y: z.number().describe('Center Y coordinate in mm')
}),
sides: z.number().int().min(3).max(100).describe('Number of sides'),
radius: z.number().positive().describe('Circumscribed circle radius in mm'),
rotation: z.number().default(0).describe('Rotation angle in degrees'),
inscribed: z.boolean().default(false).describe('Use inscribed circle radius instead'),
construction: z.boolean().default(false).describe('Create as construction geometry')
}),
handler: (args, swApi) => {
try {
const model = swApi.getCurrentModel();
if (!model)
throw new Error('No active model');
const angleStep = (2 * Math.PI) / args.sides;
const startAngle = (args.rotation * Math.PI) / 180;
// Adjust radius for inscribed vs circumscribed
let radius = args.radius;
if (args.inscribed) {
radius = radius / Math.cos(Math.PI / args.sides);
}
// Create polygon lines
const lines = [];
for (let i = 0; i < args.sides; i++) {
const angle1 = startAngle + (i * angleStep);
const angle2 = startAngle + ((i + 1) * angleStep);
const x1 = args.center.x + radius * Math.cos(angle1);
const y1 = args.center.y + radius * Math.sin(angle1);
const x2 = args.center.x + radius * Math.cos(angle2);
const y2 = args.center.y + radius * Math.sin(angle2);
const line = model.SketchManager.CreateLine(x1 / 1000, y1 / 1000, 0, x2 / 1000, y2 / 1000, 0);
if (line && args.construction) {
line.ConstructionGeometry = true;
}
lines.push(line);
}
// Calculate polygon properties
const sideLength = 2 * radius * Math.sin(Math.PI / args.sides);
const apothem = radius * Math.cos(Math.PI / args.sides);
const area = 0.5 * args.sides * sideLength * apothem;
const perimeter = args.sides * sideLength;
return {
success: true,
message: `${args.sides}-sided polygon created`,
sides: args.sides,
radius,
sideLength,
area,
perimeter
};
}
catch (error) {
return `Failed to create polygon: ${error}`;
}
}
},
// ============================================
// SKETCH GEOMETRY - SPLINES & CURVES
// ============================================
{
name: 'sketch_spline',
description: 'Draw a spline through points in the active sketch',
inputSchema: z.object({
points: z.array(z.object({
x: z.number().describe('X coordinate in mm'),
y: z.number().describe('Y coordinate in mm'),
z: z.number().default(0).describe('Z coordinate in mm (for 3D sketches)')
})).min(2).describe('Array of points for the spline'),
closed: z.boolean().default(false).describe('Close the spline'),
construction: z.boolean().default(false).describe('Create as construction geometry')
}),
handler: (args, swApi) => {
try {
const model = swApi.getCurrentModel();
if (!model)
throw new Error('No active model');
// Convert points to variant array format needed by SolidWorks
const pointArray = [];
args.points.forEach((pt) => {
pointArray.push(pt.x / 1000, pt.y / 1000, pt.z / 1000);
});
// Create spline
const spline = model.SketchManager.CreateSpline(pointArray);
if (!spline)
throw new Error('Failed to create spline');
// Set construction if needed
if (args.construction) {
spline.ConstructionGeometry = true;
}
// Calculate approximate length
let length = 0;
for (let i = 1; i < args.points.length; i++) {
const dx = args.points[i].x - args.points[i - 1].x;
const dy = args.points[i].y - args.points[i - 1].y;
const dz = args.points[i].z - args.points[i - 1].z;
length += Math.sqrt(dx * dx + dy * dy + dz * dz);
}
return {
success: true,
message: `Spline created through ${args.points.length} points`,
pointCount: args.points.length,
approximateLength: length,
closed: args.closed
};
}
catch (error) {
return `Failed to create spline: ${error}`;
}
}
},
{
name: 'sketch_ellipse',
description: 'Draw an ellipse in the active sketch',
inputSchema: z.object({
center: z.object({
x: z.number().describe('Center X coordinate in mm'),
y: z.number().describe('Center Y coordinate in mm')
}),
majorAxis: z.object({
length: z.number().positive().describe('Major axis length in mm'),
angle: z.number().default(0).describe('Major axis angle in degrees')
}),
minorAxis: z.number().positive().describe('Minor axis length in mm'),
construction: z.boolean().default(false).describe('Create as construction geometry')
}),
handler: (args, swApi) => {
try {
const model = swApi.getCurrentModel();
if (!model)
throw new Error('No active model');
const angleRad = (args.majorAxis.angle * Math.PI) / 180;
// Calculate major axis endpoints
const major1X = args.center.x + (args.majorAxis.length / 2) * Math.cos(angleRad);
const major1Y = args.center.y + (args.majorAxis.length / 2) * Math.sin(angleRad);
const major2X = args.center.x - (args.majorAxis.length / 2) * Math.cos(angleRad);
const major2Y = args.center.y - (args.majorAxis.length / 2) * Math.sin(angleRad);
// Calculate minor axis point
const minorX = args.center.x + (args.minorAxis / 2) * Math.cos(angleRad + Math.PI / 2);
const minorY = args.center.y + (args.minorAxis / 2) * Math.sin(angleRad + Math.PI / 2);
// Create ellipse
const ellipse = model.SketchManager.CreateEllipse(args.center.x / 1000, args.center.y / 1000, 0, major1X / 1000, major1Y / 1000, 0, minorX / 1000, minorY / 1000, 0);
if (!ellipse)
throw new Error('Failed to create ellipse');
// Set construction if needed
if (args.construction) {
ellipse.ConstructionGeometry = true;
}
// Calculate ellipse properties
const a = args.majorAxis.length / 2;
const b = args.minorAxis / 2;
const area = Math.PI * a * b;
// Approximate perimeter using Ramanujan's formula
const h = Math.pow((a - b), 2) / Math.pow((a + b), 2);
const perimeter = Math.PI * (a + b) * (1 + (3 * h) / (10 + Math.sqrt(4 - 3 * h)));
return {
success: true,
message: `Ellipse created at (${args.center.x}, ${args.center.y})`,
majorAxis: args.majorAxis.length,
minorAxis: args.minorAxis,
area,
perimeter
};
}
catch (error) {
return `Failed to create ellipse: ${error}`;
}
}
},
// ============================================
// SKETCH CONSTRAINTS
// ============================================
{
name: 'add_sketch_constraint',
description: 'Add constraints between sketch entities',
inputSchema: z.object({
type: z.enum([
'coincident', 'parallel', 'perpendicular', 'tangent',
'concentric', 'horizontal', 'vertical', 'equal',
'symmetric', 'colinear', 'midpoint', 'fix'
]).describe('Type of constraint to add'),
entity1: z.string().describe('First entity selection'),
entity2: z.string().optional().describe('Second entity selection (if required)'),
entity3: z.string().optional().describe('Third entity selection (for symmetric constraint)')
}),
handler: (args, swApi) => {
try {
const model = swApi.getCurrentModel();
if (!model)
throw new Error('No active model');
// Map constraint types to SolidWorks constants
const constraintMap = {
'coincident': 0,
'parallel': 1,
'perpendicular': 2,
'tangent': 3,
'concentric': 4,
'horizontal': 5,
'vertical': 6,
'equal': 7,
'symmetric': 8,
'colinear': 9,
'midpoint': 10,
'fix': 11
};
const constraintType = constraintMap[args.type];
// Select entities
model.ClearSelection2(true);
model.SelectByID2(args.entity1, 'SKETCHSEGMENT', 0, 0, 0, false, 0, null, 0);
if (args.entity2) {
model.SelectByID2(args.entity2, 'SKETCHSEGMENT', 0, 0, 0, true, 0, null, 0);
}
if (args.entity3) {
model.SelectByID2(args.entity3, 'SKETCHSEGMENT', 0, 0, 0, true, 0, null, 0);
}
// Add constraint
const success = model.SketchManager.AddConstraint(constraintType);
if (!success)
throw new Error('Failed to add constraint');
return {
success: true,
message: `${args.type} constraint added`,
type: args.type
};
}
catch (error) {
return `Failed to add constraint: ${error}`;
}
}
},
// ============================================
// SKETCH DIMENSIONS
// ============================================
{
name: 'add_sketch_dimension',
description: 'Add dimensions to sketch entities',
inputSchema: z.object({
type: z.enum(['linear', 'angular', 'radial', 'diameter']).describe('Type of dimension'),
entity: z.string().describe('Entity to dimension'),
value: z.number().describe('Dimension value in mm or degrees'),
position: z.object({
x: z.number().describe('Text position X in mm'),
y: z.number().describe('Text position Y in mm')
}).optional().describe('Text position')
}),
handler: (args, swApi) => {
try {
const model = swApi.getCurrentModel();
if (!model)
throw new Error('No active model');
// Select entity
model.ClearSelection2(true);
model.SelectByID2(args.entity, 'SKETCHSEGMENT', 0, 0, 0, false, 0, null, 0);
// Add dimension
const textX = args.position?.x || 0;
const textY = args.position?.y || 0;
let dimension;
switch (args.type) {
case 'linear':
dimension = model.AddDimension2(textX / 1000, textY / 1000, 0);
break;
case 'angular':
dimension = model.AddDimension2(textX / 1000, textY / 1000, 0);
break;
case 'radial':
dimension = model.AddRadialDimension2(textX / 1000, textY / 1000, 0);
break;
case 'diameter':
dimension = model.AddDiameterDimension2(textX / 1000, textY / 1000, 0);
break;
}
if (!dimension)
throw new Error('Failed to add dimension');
// Set dimension value
dimension.SystemValue = args.type === 'angular'
? (args.value * Math.PI / 180) // Convert degrees to radians
: (args.value / 1000); // Convert mm to meters
return {
success: true,
message: `${args.type} dimension added with value ${args.value}${args.type === 'angular' ? '°' : 'mm'}`,
type: args.type,
value: args.value
};
}
catch (error) {
return `Failed to add dimension: ${error}`;
}
}
},
// ============================================
// SKETCH PATTERNS
// ============================================
{
name: 'sketch_linear_pattern',
description: 'Create a linear pattern of sketch entities',
inputSchema: z.object({
entities: z.array(z.string()).describe('Entities to pattern'),
direction1: z.object({
x: z.number().describe('Direction vector X'),
y: z.number().describe('Direction vector Y'),
count: z.number().int().min(2).describe('Number of instances'),
spacing: z.number().positive().describe('Spacing in mm')
}),
direction2: z.object({
x: z.number().describe('Direction vector X'),
y: z.number().describe('Direction vector Y'),
count: z.number().int().min(2).describe('Number of instances'),
spacing: z.number().positive().describe('Spacing in mm')
}).optional().describe('Second direction for 2D pattern')
}),
handler: (args, swApi) => {
try {
const model = swApi.getCurrentModel();
if (!model)
throw new Error('No active model');
// Select entities to pattern
model.ClearSelection2(true);
args.entities.forEach((entity) => {
model.SelectByID2(entity, 'SKETCHSEGMENT', 0, 0, 0, true, 0, null, 0);
});
// Create pattern
const totalInstances = args.direction1.count * (args.direction2?.count || 1);
// Note: Actual implementation would use SketchManager.CreateLinearSketchStepAndRepeat
return {
success: true,
message: `Linear pattern created with ${totalInstances} instances`,
direction1Count: args.direction1.count,
direction2Count: args.direction2?.count || 1,
totalInstances
};
}
catch (error) {
return `Failed to create linear pattern: ${error}`;
}
}
},
{
name: 'sketch_circular_pattern',
description: 'Create a circular pattern of sketch entities',
inputSchema: z.object({
entities: z.array(z.string()).describe('Entities to pattern'),
center: z.object({
x: z.number().describe('Center X coordinate in mm'),
y: z.number().describe('Center Y coordinate in mm')
}),
count: z.number().int().min(2).describe('Number of instances'),
angle: z.number().default(360).describe('Total angle in degrees'),
equalSpacing: z.boolean().default(true).describe('Equal spacing between instances')
}),
handler: (args, swApi) => {
try {
const model = swApi.getCurrentModel();
if (!model)
throw new Error('No active model');
// Select entities to pattern
model.ClearSelection2(true);
args.entities.forEach((entity) => {
model.SelectByID2(entity, 'SKETCHSEGMENT', 0, 0, 0, true, 0, null, 0);
});
// Calculate angular spacing
const angleStep = args.angle / (args.equalSpacing ? args.count : args.count - 1);
// Note: Actual implementation would use SketchManager.CreateCircularSketchStepAndRepeat
return {
success: true,
message: `Circular pattern created with ${args.count} instances`,
count: args.count,
totalAngle: args.angle,
anglePerInstance: angleStep
};
}
catch (error) {
return `Failed to create circular pattern: ${error}`;
}
}
},
// ============================================
// SKETCH TRANSFORMATIONS
// ============================================
{
name: 'sketch_mirror',
description: 'Mirror sketch entities about a line',
inputSchema: z.object({
entities: z.array(z.string()).describe('Entities to mirror'),
mirrorLine: z.string().describe('Mirror line (centerline or construction line)'),
copy: z.boolean().default(true).describe('Keep original entities')
}),
handler: (args, swApi) => {
try {
const model = swApi.getCurrentModel();
if (!model)
throw new Error('No active model');
// Select entities to mirror
model.ClearSelection2(true);
args.entities.forEach((entity) => {
model.SelectByID2(entity, 'SKETCHSEGMENT', 0, 0, 0, true, 0, null, 0);
});
// Select mirror line
model.SelectByID2(args.mirrorLine, 'SKETCHSEGMENT', 0, 0, 0, true, 1, null, 0);
// Mirror entities
model.SketchManager.MirrorSketch();
return {
success: true,
message: `Mirrored ${args.entities.length} entities`,
entityCount: args.entities.length,
keepOriginal: args.copy
};
}
catch (error) {
return `Failed to mirror entities: ${error}`;
}
}
},
{
name: 'sketch_offset',
description: 'Create offset curves from sketch entities',
inputSchema: z.object({
entities: z.array(z.string()).describe('Entities to offset'),
distance: z.number().describe('Offset distance in mm (positive = outward)'),
side: z.enum(['both', 'left', 'right']).default('both').describe('Offset side'),
corner: z.enum(['sharp', 'round', 'natural']).default('natural').describe('Corner treatment'),
cap: z.boolean().default(true).describe('Cap ends for open curves')
}),
handler: (args, swApi) => {
try {
const model = swApi.getCurrentModel();
if (!model)
throw new Error('No active model');
// Select entities to offset
model.ClearSelection2(true);
args.entities.forEach((entity) => {
model.SelectByID2(entity, 'SKETCHSEGMENT', 0, 0, 0, true, 0, null, 0);
});
// Create offset
const sideValue = args.side === 'both' ? 0 : (args.side === 'left' ? 1 : 2);
model.SketchManager.SketchOffset2(args.distance / 1000, // Convert to meters
sideValue, false, // Not chain
args.cap);
return {
success: true,
message: `Offset created at ${args.distance}mm`,
distance: args.distance,
side: args.side,
corner: args.corner
};
}
catch (error) {
return `Failed to create offset: ${error}`;
}
}
}
];
//# sourceMappingURL=sketch.js.map