@
feat(query): инструмент get_part_info (МЦХ детали) QueryService через IMassInertiaParam7: объём, масса, площадь, центр масс. Единицы выставляются детерминированно (мм/кг) через LengthUnits/MassUnits — иначе КОМПАС отдаёт значения в единицах отображения МЦХ (по умолчанию см/г). Calculate() возвращает FALSE даже при успехе → опираемся на свойство Actual. Интеграционный тест: цилиндр R10×H20 → V≈6283 мм³, S≈1885 мм², m≈0.049 кг, Zc=10 мм. Находка задокументирована в OPEN_QUESTIONS; презентация обновлена (19 инструментов, 14 тестов). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> @
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
namespace Kompas.Mcp.Core.Query;
|
||||
|
||||
/// <summary>Массово-центровочные характеристики детали (в единицах документа, по умолчанию мм).</summary>
|
||||
public sealed record PartInfo
|
||||
{
|
||||
public required double Volume { get; init; } // объём, мм³
|
||||
public required double Mass { get; init; } // масса, кг (по материалу/плотности)
|
||||
public required double Area { get; init; } // площадь поверхности, мм²
|
||||
public required double CenterX { get; init; } // центр масс, X
|
||||
public required double CenterY { get; init; }
|
||||
public required double CenterZ { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
using Kompas.Mcp.Core.Threading;
|
||||
using Kompas6Constants;
|
||||
using KompasAPI7;
|
||||
|
||||
namespace Kompas.Mcp.Core.Query;
|
||||
|
||||
/// <summary>Запросы к активной 3D-модели: массово-центровочные характеристики.</summary>
|
||||
[SupportedOSPlatform("windows")]
|
||||
public sealed class QueryService
|
||||
{
|
||||
private readonly KompasSession _session;
|
||||
private readonly KompasDispatcher _dispatcher;
|
||||
|
||||
public QueryService(KompasSession session, KompasDispatcher dispatcher)
|
||||
{
|
||||
_session = session ?? throw new ArgumentNullException(nameof(session));
|
||||
_dispatcher = dispatcher ?? throw new ArgumentNullException(nameof(dispatcher));
|
||||
}
|
||||
|
||||
/// <summary>Рассчитать и вернуть МЦХ активной детали (объём, масса, площадь, центр масс).</summary>
|
||||
public Task<PartInfo> GetPartInfoAsync(CancellationToken ct = default)
|
||||
=> _dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
var doc3d = _session.Application.ActiveDocument as IKompasDocument3D
|
||||
?? throw new InvalidOperationException("Активный документ не является 3D-моделью.");
|
||||
var part = doc3d.TopPart
|
||||
?? throw new InvalidOperationException("Не удалось получить вершинный компонент.");
|
||||
try
|
||||
{
|
||||
var mass = (IMassInertiaParam7)part;
|
||||
|
||||
// Детерминированные единицы: длина — мм, масса — кг. Иначе КОМПАС вернёт
|
||||
// значения в единицах отображения МЦХ (по умолчанию см/г), что зависит от настроек.
|
||||
mass.LengthUnits = ksLengthUnitsEnum.ksLUnMM;
|
||||
mass.MassUnits = ksMassUnitsEnum.ksMUnKG;
|
||||
|
||||
// Calculate() возвращает FALSE и при успехе (когда расчёт уже актуален),
|
||||
// поэтому ориентируемся на свойство Actual, а не на возвращаемое значение.
|
||||
mass.Calculate();
|
||||
if (!mass.Actual)
|
||||
throw new InvalidOperationException("МЦХ не рассчитаны (модель пуста или не перестроена?).");
|
||||
|
||||
return new PartInfo
|
||||
{
|
||||
Volume = mass.Volume,
|
||||
Mass = mass.Mass,
|
||||
Area = mass.Area,
|
||||
CenterX = mass.Xc,
|
||||
CenterY = mass.Yc,
|
||||
CenterZ = mass.Zc,
|
||||
};
|
||||
}
|
||||
finally
|
||||
{
|
||||
// part и его QI-приведение mass — один RCW; release один раз.
|
||||
if (Marshal.IsComObject(part)) Marshal.ReleaseComObject(part);
|
||||
}
|
||||
}, ct);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using Kompas.Mcp.Core;
|
||||
using Kompas.Mcp.Core.Documents;
|
||||
using Kompas.Mcp.Core.Modeling;
|
||||
using Kompas.Mcp.Core.Query;
|
||||
using Kompas.Mcp.Core.Threading;
|
||||
using Kompas.Mcp.Core.Vision;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@@ -19,6 +20,7 @@ builder.Services.AddSingleton<KompasSession>();
|
||||
builder.Services.AddSingleton<DocumentService>();
|
||||
builder.Services.AddSingleton<PartModeler>();
|
||||
builder.Services.AddSingleton<SnapshotService>();
|
||||
builder.Services.AddSingleton<QueryService>();
|
||||
|
||||
// MCP-сервер поверх stdio; инструменты находятся по атрибутам в этой сборке.
|
||||
builder.Services
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
using System.ComponentModel;
|
||||
using Kompas.Mcp.Core;
|
||||
using Kompas.Mcp.Core.Query;
|
||||
using ModelContextProtocol.Server;
|
||||
|
||||
namespace Kompas.Mcp.Host.Tools;
|
||||
|
||||
/// <summary>Инструменты запросов к модели.</summary>
|
||||
[McpServerToolType]
|
||||
public sealed class QueryTools(KompasSession session, QueryService query)
|
||||
{
|
||||
[McpServerTool(Name = "get_part_info")]
|
||||
[Description("Массово-центровочные характеристики активной детали: объём (мм³), масса (кг), площадь (мм²) и центр масс. Полезно для числовой проверки построения.")]
|
||||
public async Task<string> GetPartInfo()
|
||||
{
|
||||
await session.ConnectAsync();
|
||||
var i = await query.GetPartInfoAsync();
|
||||
return $"Объём: {i.Volume:F2} мм³; масса: {i.Mass:F4} кг; площадь: {i.Area:F2} мм²; " +
|
||||
$"центр масс: ({i.CenterX:F2}, {i.CenterY:F2}, {i.CenterZ:F2}).";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user