Files
kompas3d-mcp/tests/Kompas.Mcp.Tests/Integration/SolidEditTests.cs
T
mikhail 28d2ae3868 feat(inspection): структурное «зрение» модели — осмотр без снимка
Новый слой «модель как данные» (приоритетный над model_snapshot):
- describe_model — структурный «паспорт» детали одним вызовом (габарит,
  МЦХ, тела, сводка топологии, дерево построения с параметрами, переменные)
- list_features / list_bodies / list_variables
- describe_face / describe_edge (drill-down по индексу)
- measure (расстояние/угол между гранями/рёбрами/вершинами)
- model_snapshot понижен до fallback для визуально-пространственных вопросов

Реализация: ModelInspectionService (COM) + чистый InspectionText (рендер,
группировка, детект «импорт без истории») + record-модели; InspectionTools.
Дерево читается через ksPart.GetFeature()->SubFeatureCollection; точный тип
и параметры операций берутся из GetObject()->GetDefinition() (ksFeature.type
отдаёт лишь coarse o3d_entity).

Снимок дерева также включает слои conversion (STEP), editing (move_face/solid)
и validation, развивавшиеся параллельно. Полный прогон: 61 тест зелёный,
43 MCP-инструмента. Документация (README, ARCHITECTURE, OPEN_QUESTIONS,
CLAUDE.md, presentation.html) синхронизирована.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 18:44:38 +03:00

70 lines
2.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Kompas.Mcp.Core.Documents;
using Kompas.Mcp.Core.Editing;
using Kompas.Mcp.Core.Modeling;
using Kompas.Mcp.Core.Query;
using Kompas.Mcp.Core.Validation;
namespace Kompas.Mcp.Tests.Integration;
/// <summary>Интеграция: рассечение тела, перемещение тела, объединение (cut→spread→union).</summary>
[Trait("Category", "Integration")]
[Collection(KompasCollection.Name)]
public sealed class SolidEditTests
{
private readonly DocumentService _docs;
private readonly PartModeler _modeler;
private readonly SolidEditService _solid;
private readonly FaceEditService _face;
private readonly QueryService _query;
private readonly ValidationService _validation;
public SolidEditTests(KompasFixture fx)
{
_docs = new DocumentService(fx.Session, fx.Dispatcher);
_modeler = new PartModeler(fx.Session, fx.Dispatcher);
_solid = new SolidEditService(fx.Session, fx.Dispatcher);
_face = new FaceEditService(fx.Session, fx.Dispatcher);
_query = new QueryService(fx.Session, fx.Dispatcher);
_validation = new ValidationService(fx.Session, fx.Dispatcher);
}
[Fact]
public async Task Split_move_bridge_union_grows_height_cleanly()
{
await _docs.CreateAsync(KompasDocumentType.Part);
try
{
// Брусок 20×20×10 на XOY: Z[0;10].
var s = await _modeler.OpenSketchAsync(BasePlane.XOY);
await _modeler.AddRectangleAsync(s, 0, 0, 20, 20);
await _modeler.CloseSketchAsync(s);
await _modeler.ExtrudeAsync(s, depth: 10);
await _modeler.RebuildAsync();
// 1) Рассечь по XOY на Z=5 → 2 тела.
var bodies = await _solid.SplitByPlaneAsync(BasePlane.XOY, offset: 5);
Assert.Equal(2, bodies.Count);
// 2) Сдвинуть верхнее тело (max Z) на +2 по Z.
var upper = bodies.OrderByDescending(b => b.MaxZ).First();
await _solid.MoveBodyAsync(upper.Index, dz: 2);
// 3) Мост: толкнуть грань реза нижнего тела (центр (10,10,5)) на +2 вверх до стыка.
await _face.MoveFaceAsync(10, 10, 5, distance: 2);
// 4) Объединить тела в одно.
await _solid.UnionAllAsync();
await _modeler.RebuildAsync();
// Итог: высота 10 → 12, единое тело, построение чистое.
var bb = await _query.GetBoundingBoxAsync();
Assert.InRange(bb.SizeZ, 11.9, 12.1);
Assert.Empty(await _validation.ValidatePartAsync());
}
finally
{
await _docs.CloseAsync(save: false);
}
}
}