@
feat(query): габариты детали (get_bounding_box) QueryService.GetBoundingBoxAsync через API5 ksPart.GetGabarit(full=false) → габаритный параллелепипед (мм) + размеры по осям. Помогает агенту оценить протяжённость модели и подбирать точки для select-by-point (грани/рёбра). Новый инструмент get_bounding_box; запись BoundingBox. Тест: цилиндр R10×H20 → X,Y ∈ [-10;10], Z ∈ [0;20] (расширен QueryTests). Презентация: 26 инструментов. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> @
This commit is contained in:
@@ -125,7 +125,7 @@
|
||||
<!-- HERO -->
|
||||
<header class="hero">
|
||||
<div class="wrap">
|
||||
<span class="badge"><span class="dot" style="background:var(--green);box-shadow:0 0 10px var(--green)"></span> Статус: v1 работает — цикл эскиз→операции→снимок через MCP (25 инструментов)</span>
|
||||
<span class="badge"><span class="dot" style="background:var(--green);box-shadow:0 0 10px var(--green)"></span> Статус: v1 работает — цикл эскиз→операции→снимок через MCP (26 инструментов)</span>
|
||||
<h1>КОМПАС-3D <span class="g">MCP-сервер</span><br>управление CAD языком LLM</h1>
|
||||
<p class="lead">MCP-сервер, который превращает операции КОМПАС-3D — создание документов,
|
||||
эскизы, 3D-операции, параметры — в инструменты для языковой модели. Под капотом —
|
||||
@@ -282,15 +282,15 @@
|
||||
<!-- TOOLS -->
|
||||
<div class="panel">
|
||||
<h3>Инструменты v1 <span class="tag done">ГОТОВО</span></h3>
|
||||
<p class="meta">25 инструментов, отдаются по MCP-протоколу</p>
|
||||
<p class="meta">26 инструментов, отдаются по MCP-протоколу</p>
|
||||
<ul class="list">
|
||||
<li class="muted"><span class="mark ok">✓</span><span class="t"><code>System</code>: connect · status · set_visible</span></li>
|
||||
<li class="muted"><span class="mark ok">✓</span><span class="t"><code>Documents</code>: create · open · save · save_as · close · active</span></li>
|
||||
<li class="muted"><span class="mark ok">✓</span><span class="t"><code>Sketch</code>: create · create_on_face · add line/circle/rectangle/axis · close</span></li>
|
||||
<li class="muted"><span class="mark ok">✓</span><span class="t"><code>Features</code>: extrude · revolve · fillet_edge/chamfer_edge 🆕 · rebuild</span></li>
|
||||
<li class="muted"><span class="mark ok">✓</span><span class="t"><code>Vision</code>: model_snapshot 👁️</span></li>
|
||||
<li class="muted"><span class="mark ok">✓</span><span class="t"><code>Query</code>: get_part_info (объём/масса/площадь/центр масс)</span></li>
|
||||
<li><span class="mark todo"></span><span><code>Query</code>: select_face · list_bodies (далее)</span></li>
|
||||
<li class="muted"><span class="mark ok">✓</span><span class="t"><code>Query</code>: get_part_info · get_bounding_box 🆕</span></li>
|
||||
<li><span class="mark todo"></span><span><code>Query</code>: list_bodies · list_faces (далее)</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace Kompas.Mcp.Core.Query;
|
||||
|
||||
/// <summary>Габаритный параллелепипед детали (мировые координаты модели, мм).</summary>
|
||||
public sealed record BoundingBox
|
||||
{
|
||||
public required double MinX { get; init; }
|
||||
public required double MinY { get; init; }
|
||||
public required double MinZ { get; init; }
|
||||
public required double MaxX { get; init; }
|
||||
public required double MaxY { get; init; }
|
||||
public required double MaxZ { get; init; }
|
||||
|
||||
public double SizeX => MaxX - MinX;
|
||||
public double SizeY => MaxY - MinY;
|
||||
public double SizeZ => MaxZ - MinZ;
|
||||
}
|
||||
@@ -60,4 +60,32 @@ public sealed class QueryService
|
||||
if (Marshal.IsComObject(part)) Marshal.ReleaseComObject(part);
|
||||
}
|
||||
}, ct);
|
||||
|
||||
/// <summary>Габаритный параллелепипед активной детали (по телам), мм.</summary>
|
||||
public Task<BoundingBox> GetBoundingBoxAsync(CancellationToken ct = default)
|
||||
=> _dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
var doc3d = _session.Kompas.ActiveDocument3D() as ksDocument3D
|
||||
?? throw new InvalidOperationException("Нет активного 3D-документа.");
|
||||
var part = doc3d.GetPart((short)Part_Type.pTop_Part) as ksPart
|
||||
?? throw new InvalidOperationException("Не удалось получить вершинный компонент (ksPart).");
|
||||
try
|
||||
{
|
||||
// full=false → только тела (без вспомогательной геометрии); customizable игнорируется.
|
||||
if (!part.GetGabarit(false, false,
|
||||
out double x1, out double y1, out double z1,
|
||||
out double x2, out double y2, out double z2))
|
||||
throw new InvalidOperationException("GetGabarit вернул FALSE (модель пуста?).");
|
||||
|
||||
return new BoundingBox
|
||||
{
|
||||
MinX = Math.Min(x1, x2), MinY = Math.Min(y1, y2), MinZ = Math.Min(z1, z2),
|
||||
MaxX = Math.Max(x1, x2), MaxY = Math.Max(y1, y2), MaxZ = Math.Max(z1, z2),
|
||||
};
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (Marshal.IsComObject(part)) Marshal.ReleaseComObject(part);
|
||||
}
|
||||
}, ct);
|
||||
}
|
||||
|
||||
@@ -18,4 +18,14 @@ public sealed class QueryTools(KompasSession session, QueryService query)
|
||||
return $"Объём: {i.Volume:F2} мм³; масса: {i.Mass:F4} кг; площадь: {i.Area:F2} мм²; " +
|
||||
$"центр масс: ({i.CenterX:F2}, {i.CenterY:F2}, {i.CenterZ:F2}).";
|
||||
}
|
||||
|
||||
[McpServerTool(Name = "get_bounding_box")]
|
||||
[Description("Габариты активной детали: координаты габаритного параллелепипеда (мм) и его размеры. Помогает оценить протяжённость модели и подобрать точки для выбора граней/рёбер.")]
|
||||
public async Task<string> GetBoundingBox()
|
||||
{
|
||||
await session.ConnectAsync();
|
||||
var b = await query.GetBoundingBoxAsync();
|
||||
return $"Габарит: X [{b.MinX:F2}; {b.MaxX:F2}], Y [{b.MinY:F2}; {b.MaxY:F2}], Z [{b.MinZ:F2}; {b.MaxZ:F2}]; " +
|
||||
$"размеры (Д×Ш×В): {b.SizeX:F2} × {b.SizeY:F2} × {b.SizeZ:F2} мм.";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,14 @@ public sealed class QueryTests
|
||||
|
||||
// Масса стального цилиндра (плотность ≈ 7.856 г/см³): V[см³]·ρ ≈ 6.283·7.856 ≈ 49.36 г = 0.0494 кг.
|
||||
Assert.InRange(info.Mass, 0.045, 0.055);
|
||||
|
||||
// Габарит цилиндра R10×H20 на XOY: X,Y ∈ [-10;10], Z ∈ [0;20].
|
||||
var bb = await _query.GetBoundingBoxAsync();
|
||||
Assert.InRange(bb.MinX, -10.1, -9.9);
|
||||
Assert.InRange(bb.MaxX, 9.9, 10.1);
|
||||
Assert.InRange(bb.MinZ, -0.1, 0.1);
|
||||
Assert.InRange(bb.MaxZ, 19.9, 20.1);
|
||||
Assert.InRange(bb.SizeZ, 19.9, 20.1);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user