88dad09ea7
feat(features): скругление и фаска ребра (fillet_edge / chamfer_edge) PartModeler.FilletEdgeAsync / ChamferEdgeAsync через API5 o3d_fillet/o3d_chamfer: ребро выбирается по точке (общий хелпер SelectEdgeByPoint поверх EntityCollection(o3d_edge).SelectByPoint), добавляется в def.array(), радиус/катет задаются (ksFilletDefinition.radius, ksChamferDefinition.SetChamferParam). Новые MCP-инструменты: fillet_edge, chamfer_edge. Тест Fillet_and_chamfer_edges: цилиндр → скругление верхнего ребра R3 + фаска нижнего 2×2, проверка успеха, уменьшения объёма и снимка (визуально подтверждено). Презентация: 25 инструментов, 17 тестов. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> @
85 lines
5.1 KiB
C#
85 lines
5.1 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 FeatureTools(KompasSession session, PartModeler modeler)
|
||
{
|
||
[McpServerTool(Name = "extrude_boss")]
|
||
[Description("Выдавить эскиз, добавив материал (на глубину depth, мм). Возвращает id операции.")]
|
||
public async Task<string> ExtrudeBoss(int sketchId, double depth, [Description("Прямое направление")] bool forward = true)
|
||
{
|
||
await session.ConnectAsync();
|
||
var id = await modeler.ExtrudeAsync(sketchId, depth, cut: false, forward: forward);
|
||
return $"Выдавливание (boss) создано, id={id}.";
|
||
}
|
||
|
||
[McpServerTool(Name = "extrude_cut")]
|
||
[Description("Вырезать выдавливанием по эскизу. Для сквозного отверстия передайте throughAll=true (depth не нужен). Иначе вырез на глубину depth (мм).")]
|
||
public async Task<string> ExtrudeCut(
|
||
int sketchId,
|
||
[Description("Глубина, мм (нужна, если throughAll=false)")] double depth = 0,
|
||
[Description("Вырезать насквозь через всю деталь")] bool throughAll = false,
|
||
[Description("Прямое направление")] bool forward = true)
|
||
{
|
||
await session.ConnectAsync();
|
||
var id = await modeler.ExtrudeAsync(sketchId, depth, cut: true, forward: forward, throughAll: throughAll);
|
||
return $"Вырез (cut) создан, id={id}.";
|
||
}
|
||
|
||
[McpServerTool(Name = "revolve_boss")]
|
||
[Description("Вращать эскиз вокруг его осевой линии, добавив материал. Эскиз должен содержать профиль и осевую линию (sketch_add_axis). angle — угол в градусах (по умолчанию 360). Возвращает id операции.")]
|
||
public async Task<string> RevolveBoss(
|
||
int sketchId,
|
||
[Description("Угол вращения, градусы (0..360]")] double angle = 360,
|
||
[Description("Прямое направление")] bool forward = true)
|
||
{
|
||
await session.ConnectAsync();
|
||
var id = await modeler.RevolveAsync(sketchId, angle, cut: false, forward: forward);
|
||
return $"Вращение (boss) создано, id={id}.";
|
||
}
|
||
|
||
[McpServerTool(Name = "revolve_cut")]
|
||
[Description("Вырезать вращением эскиза вокруг его осевой линии. Эскиз должен содержать профиль и осевую линию (sketch_add_axis). angle — угол в градусах (по умолчанию 360). Возвращает id операции.")]
|
||
public async Task<string> RevolveCut(
|
||
int sketchId,
|
||
[Description("Угол вращения, градусы (0..360]")] double angle = 360,
|
||
[Description("Прямое направление")] bool forward = true)
|
||
{
|
||
await session.ConnectAsync();
|
||
var id = await modeler.RevolveAsync(sketchId, angle, cut: true, forward: forward);
|
||
return $"Вырез вращением (cut) создан, id={id}.";
|
||
}
|
||
|
||
[McpServerTool(Name = "fillet_edge")]
|
||
[Description("Скруглить ребро детали, выбранное по точке (мировые координаты x,y,z в мм, точка должна лежать на ребре), радиусом radius (мм). Сделайте model_snapshot, прикиньте точку на ребре. Возвращает id операции.")]
|
||
public async Task<string> FilletEdge(double x, double y, double z, double radius)
|
||
{
|
||
await session.ConnectAsync();
|
||
var id = await modeler.FilletEdgeAsync(x, y, z, radius);
|
||
return $"Скругление R{radius} создано на ребре в точке ({x}, {y}, {z}), id={id}.";
|
||
}
|
||
|
||
[McpServerTool(Name = "chamfer_edge")]
|
||
[Description("Снять фаску с ребра детали, выбранного по точке (мировые координаты x,y,z в мм, точка должна лежать на ребре), катетом distance (мм). Сделайте model_snapshot, прикиньте точку на ребре. Возвращает id операции.")]
|
||
public async Task<string> ChamferEdge(double x, double y, double z, double distance)
|
||
{
|
||
await session.ConnectAsync();
|
||
var id = await modeler.ChamferEdgeAsync(x, y, z, distance);
|
||
return $"Фаска {distance}×{distance} создана на ребре в точке ({x}, {y}, {z}), id={id}.";
|
||
}
|
||
|
||
[McpServerTool(Name = "rebuild")]
|
||
[Description("Перестроить активный документ.")]
|
||
public async Task<string> Rebuild()
|
||
{
|
||
await session.ConnectAsync();
|
||
await modeler.RebuildAsync();
|
||
return "Документ перестроен.";
|
||
}
|
||
}
|