b73748f84b
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> @
62 lines
3.0 KiB
C#
62 lines
3.0 KiB
C#
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);
|
|
}
|