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>
@
This commit is contained in:
2026-05-26 10:01:26 +03:00
parent 5a689ad461
commit 88dad09ea7
4 changed files with 130 additions and 6 deletions
@@ -120,6 +120,41 @@ public sealed class ModelingTests
}
}
[Fact]
public async Task Fillet_and_chamfer_edges()
{
await _docs.CreateAsync(KompasDocumentType.Part);
try
{
// Цилиндр R10×H20 → верхнее ребро на (10,0,20), нижнее на (10,0,0).
var s = await _modeler.OpenSketchAsync(BasePlane.XOY);
await _modeler.AddCircleAsync(s, 0, 0, 10);
await _modeler.CloseSketchAsync(s);
await _modeler.ExtrudeAsync(s, depth: 20);
var cylinderVolume = (await _query.GetPartInfoAsync()).Volume;
// Скругление верхнего ребра R3 и фаска нижнего 2×2.
var fil = await _modeler.FilletEdgeAsync(10, 0, 20, 3);
Assert.True(fil > 0);
var cha = await _modeler.ChamferEdgeAsync(10, 0, 0, 2);
Assert.True(cha > 0);
await _modeler.RebuildAsync();
var path = TestPaths.NewFile("_fillet.png");
var snap = await _snap.CaptureActiveModelAsync(saveToFile: path);
Assert.True(snap.Bytes.Length > 1000);
// Скругление и фаска снимают материал с рёбер → объём уменьшается, но незначительно.
var after = (await _query.GetPartInfoAsync()).Volume;
Assert.True(after < cylinderVolume, "После скругления/фаски объём должен уменьшиться.");
Assert.InRange(after, cylinderVolume * 0.9, cylinderVolume);
}
finally
{
await _docs.CloseAsync(save: false);
}
}
[Fact]
public async Task Reset_invalidates_sketch_ids()
{