b2aac016af
OpenSketchOnOffsetPlaneAsync (o3d_planeOffset=14, ksPlaneOffsetDefinition) — эскиз на смещённой плоскости. LoftAsync (o3d_baseLoft=30, ksBaseLoftDefinition): Sketchs().Add сечений + SetLoftParam + SetThinParam(false). Смещённая плоскость разблокировала loft (параллельные сечения). Integration: цилиндр на высоте 20; loft 2 квадратов → призма 16000 мм³. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
165 lines
11 KiB
C#
165 lines
11 KiB
C#
using System.ComponentModel;
|
||
using Kompas.Mcp.Core;
|
||
using Kompas.Mcp.Core.Modeling;
|
||
using ModelContextProtocol.Server;
|
||
|
||
namespace Kompas.Mcp.Host.Tools;
|
||
|
||
/// <summary>Инструменты построения эскизов в активной детали.</summary>
|
||
[McpServerToolType]
|
||
public sealed class SketchTools(KompasSession session, PartModeler modeler)
|
||
{
|
||
[McpServerTool(Name = "sketch_create")]
|
||
[Description("Создать эскиз на базовой плоскости (XOY, XOZ или YOZ) активной детали и открыть его на редактирование. Возвращает id эскиза для последующих sketch_add_* и операций.")]
|
||
public async Task<string> Create([Description("Плоскость: XOY, XOZ или YOZ")] string plane)
|
||
{
|
||
await session.ConnectAsync();
|
||
var id = await modeler.OpenSketchAsync(BasePlanes.Parse(plane));
|
||
return $"Эскиз создан, id={id}. Добавьте геометрию (sketch_add_*) и завершите sketch_close.";
|
||
}
|
||
|
||
[McpServerTool(Name = "sketch_create_on_face")]
|
||
[Description("Создать эскиз на плоской грани детали, выбранной по точке (мировые координаты модели x,y,z в мм), и открыть его на редактирование. Используйте для построения «на грани» поверх уже созданной геометрии: сделайте model_snapshot, прикиньте координаты точки на нужной грани, затем вызовите этот инструмент. Возвращает id эскиза.")]
|
||
public async Task<string> CreateOnFace(double x, double y, double z)
|
||
{
|
||
await session.ConnectAsync();
|
||
var id = await modeler.OpenSketchOnFaceAsync(x, y, z);
|
||
return $"Эскиз создан на грани в точке ({x}, {y}, {z}), id={id}. Координаты геометрии — в локальной плоскости эскиза.";
|
||
}
|
||
|
||
[McpServerTool(Name = "sketch_create_on_offset_plane")]
|
||
[Description("Создать эскиз на плоскости, смещённой от базовой (XOY|XOZ|YOZ) на offset мм, и открыть на редактирование. Позволяет строить геометрию на произвольной высоте/смещении (например сечения для операции loft). direction — направление смещения от базовой плоскости. Возвращает id эскиза.")]
|
||
public async Task<string> CreateOnOffsetPlane(
|
||
[Description("Базовая плоскость: XOY | XOZ | YOZ")] string basePlane,
|
||
[Description("Смещение от базовой плоскости, мм")] double offset,
|
||
[Description("Прямое направление смещения")] bool direction = true)
|
||
{
|
||
await session.ConnectAsync();
|
||
var id = await modeler.OpenSketchOnOffsetPlaneAsync(BasePlanes.Parse(basePlane), offset, direction);
|
||
return $"Эскиз создан на смещённой плоскости {basePlane}+{offset}, id={id}.";
|
||
}
|
||
|
||
[McpServerTool(Name = "sketch_add_circle")]
|
||
[Description("Добавить окружность в открытый эскиз. Координаты — в плоскости эскиза, мм.")]
|
||
public async Task<string> AddCircle(int sketchId, double centerX, double centerY, double radius)
|
||
{
|
||
await session.ConnectAsync();
|
||
await modeler.AddCircleAsync(sketchId, centerX, centerY, radius);
|
||
return "Окружность добавлена.";
|
||
}
|
||
|
||
[McpServerTool(Name = "sketch_add_line")]
|
||
[Description("Добавить отрезок в открытый эскиз (две точки, мм).")]
|
||
public async Task<string> AddLine(int sketchId, double x1, double y1, double x2, double y2)
|
||
{
|
||
await session.ConnectAsync();
|
||
await modeler.AddLineAsync(sketchId, x1, y1, x2, y2);
|
||
return "Отрезок добавлен.";
|
||
}
|
||
|
||
[McpServerTool(Name = "sketch_create_on_face_index")]
|
||
[Description("Создать эскиз на грани детали, заданной индексом из list_faces, и открыть на редактирование. Надёжнее выбора по точке (не нужно угадывать координаты). Возвращает id эскиза.")]
|
||
public async Task<string> CreateOnFaceIndex([Description("Индекс грани из list_faces")] int faceIndex)
|
||
{
|
||
await session.ConnectAsync();
|
||
var id = await modeler.OpenSketchOnFaceIndexAsync(faceIndex);
|
||
return $"Эскиз создан на грани [{faceIndex}], id={id}.";
|
||
}
|
||
|
||
[McpServerTool(Name = "sketch_add_axis")]
|
||
[Description("Добавить осевую линию (ось вращения) в открытый эскиз — нужна для revolve_boss/revolve_cut. Две точки в плоскости эскиза, мм.")]
|
||
public async Task<string> AddAxis(int sketchId, double x1, double y1, double x2, double y2)
|
||
{
|
||
await session.ConnectAsync();
|
||
await modeler.AddAxisAsync(sketchId, x1, y1, x2, y2);
|
||
return "Осевая линия добавлена.";
|
||
}
|
||
|
||
[McpServerTool(Name = "sketch_add_rectangle")]
|
||
[Description("Добавить прямоугольник по двум противоположным углам в открытый эскиз (мм).")]
|
||
public async Task<string> AddRectangle(int sketchId, double x1, double y1, double x2, double y2)
|
||
{
|
||
await session.ConnectAsync();
|
||
await modeler.AddRectangleAsync(sketchId, x1, y1, x2, y2);
|
||
return "Прямоугольник добавлен.";
|
||
}
|
||
|
||
[McpServerTool(Name = "sketch_close")]
|
||
[Description("Завершить редактирование эскиза (перед операцией выдавливания).")]
|
||
public async Task<string> Close(int sketchId)
|
||
{
|
||
await session.ConnectAsync();
|
||
await modeler.CloseSketchAsync(sketchId);
|
||
return "Эскиз закрыт.";
|
||
}
|
||
|
||
[McpServerTool(Name = "sketch_add_arc_3points")]
|
||
[Description("Добавить дугу по трём точкам (начало, промежуточная точка на дуге, конец) в открытый эскиз. Координаты — в плоскости эскиза, мм.")]
|
||
public async Task<string> AddArc3Points(int sketchId, double x1, double y1, double x2, double y2, double x3, double y3)
|
||
{
|
||
await session.ConnectAsync();
|
||
await modeler.AddArc3PointsAsync(sketchId, x1, y1, x2, y2, x3, y3);
|
||
return "Дуга по 3 точкам добавлена.";
|
||
}
|
||
|
||
[McpServerTool(Name = "sketch_add_arc")]
|
||
[Description("Добавить дугу по центру, радиусу и углам (в градусах, от оси X) в открытый эскиз. counterClockwise=true — против часовой стрелки, false — по часовой. Координаты центра — в плоскости эскиза, мм.")]
|
||
public async Task<string> AddArc(int sketchId, double centerX, double centerY, double radius, double startAngle, double endAngle, bool counterClockwise = true)
|
||
{
|
||
await session.ConnectAsync();
|
||
await modeler.AddArcByAngleAsync(sketchId, centerX, centerY, radius, startAngle, endAngle, counterClockwise);
|
||
return "Дуга добавлена.";
|
||
}
|
||
|
||
[McpServerTool(Name = "sketch_add_ellipse")]
|
||
[Description("Добавить эллипс в открытый эскиз: центр, большая полуось semiMajor, малая полуось semiMinor (мм), угол наклона большой оси к X (градусы, по умолчанию 0).")]
|
||
public async Task<string> AddEllipse(int sketchId, double centerX, double centerY, double semiMajor, double semiMinor, double angle = 0)
|
||
{
|
||
await session.ConnectAsync();
|
||
await modeler.AddEllipseAsync(sketchId, centerX, centerY, semiMajor, semiMinor, angle);
|
||
return "Эллипс добавлен.";
|
||
}
|
||
|
||
[McpServerTool(Name = "sketch_add_polyline")]
|
||
[Description("Добавить ломаную — цепочку прямых отрезков по списку точек — в открытый эскиз. closed=true замыкает последнюю точку с первой (тогда нужно минимум 3 точки). Координаты — в плоскости эскиза, мм.")]
|
||
public async Task<string> AddPolyline(int sketchId, SketchPoint[] points, bool closed = false)
|
||
{
|
||
await session.ConnectAsync();
|
||
await modeler.AddPolylineAsync(sketchId, Map(points), closed);
|
||
return $"Ломаная из {points.Length} точек добавлена{(closed ? " (замкнута)" : "")}.";
|
||
}
|
||
|
||
[McpServerTool(Name = "sketch_add_polygon")]
|
||
[Description("Добавить правильный многоугольник в открытый эскиз: центр, vertexCount вершин (>=3), radius (мм). inscribed=true — вершины лежат на окружности радиуса (вписанный в окружность); false — стороны касаются окружности (описанный). angle — поворот первой вершины (градусы, по умолчанию 0).")]
|
||
public async Task<string> AddPolygon(int sketchId, double centerX, double centerY, int vertexCount, double radius, bool inscribed = true, double angle = 0)
|
||
{
|
||
await session.ConnectAsync();
|
||
await modeler.AddPolygonAsync(sketchId, centerX, centerY, vertexCount, radius, inscribed, angle);
|
||
return $"Правильный многоугольник ({vertexCount} вершин) добавлен.";
|
||
}
|
||
|
||
[McpServerTool(Name = "sketch_add_spline")]
|
||
[Description("Добавить сплайн (кубический NURBS) через список точек в открытый эскиз. closed=true замыкает кривую. Координаты — в плоскости эскиза, мм.")]
|
||
public async Task<string> AddSpline(int sketchId, SketchPoint[] points, bool closed = false)
|
||
{
|
||
await session.ConnectAsync();
|
||
await modeler.AddSplineAsync(sketchId, Map(points), closed);
|
||
return $"Сплайн по {points.Length} точкам добавлен{(closed ? " (замкнут)" : "")}.";
|
||
}
|
||
|
||
[McpServerTool(Name = "sketch_add_point")]
|
||
[Description("Добавить точку в открытый эскиз (опорная точка для построений). Координаты — в плоскости эскиза, мм.")]
|
||
public async Task<string> AddPoint(int sketchId, double x, double y)
|
||
{
|
||
await session.ConnectAsync();
|
||
await modeler.AddPointAsync(sketchId, x, y);
|
||
return "Точка добавлена.";
|
||
}
|
||
|
||
private static IReadOnlyList<(double x, double y)> Map(SketchPoint[] points)
|
||
{
|
||
ArgumentNullException.ThrowIfNull(points);
|
||
return points.Select(p => (p.X, p.Y)).ToList();
|
||
}
|
||
}
|