feat: зеркало операций и тела (mirror_operation, mirror_body)

- MirrorOperationAsync: ksMirrorCopyDefinition o3d_mirrorOperation, SetPlane + GetOperationArray
- MirrorBodyAsync: ksMirrorCopyAllDefinition o3d_mirrorAllOperation, SetPlane +
  ChooseBodies().ChooseBodiesType=ksAllBodies (отражает все тела, оригинал сохраняется)
- инструменты mirror_operation (featureIds, plane), mirror_body (plane)
- интеграционные тесты: mirror_operation на ДВУХ источниках (коллекция), mirror_body — оба ±5%
- пакет C завершён: 62 инструмента, 100 тестов (60 unit + 40 integration)
This commit is contained in:
2026-05-27 00:11:02 +03:00
parent be6a99b9b6
commit 2aeed5ba3d
3 changed files with 143 additions and 0 deletions
@@ -194,6 +194,67 @@ public sealed class FeatureOpsTests
finally { await _docs.CloseAsync(save: false); }
}
[Fact]
public async Task MirrorOperation_mirrors_two_features_across_YOZ()
{
await _docs.CreateAsync(KompasDocumentType.Part);
try
{
// Две отдельные операции (проверяем заполнение коллекции несколькими источниками):
// цилиндр R3 центр (20,0) и цилиндр R2 центр (10,0), оба H10.
var s1 = await _modeler.OpenSketchAsync(BasePlane.XOY);
await _modeler.AddCircleAsync(s1, 20, 0, 3);
await _modeler.CloseSketchAsync(s1);
var c1 = await _modeler.ExtrudeAsync(s1, depth: 10);
var s2 = await _modeler.OpenSketchAsync(BasePlane.XOY);
await _modeler.AddCircleAsync(s2, 10, 0, 2);
await _modeler.CloseSketchAsync(s2);
var c2 = await _modeler.ExtrudeAsync(s2, depth: 10);
var before = (await _query.GetPartInfoAsync()).Volume; // π·9·10 + π·4·10 ≈ 408.4
// Зеркало обеих операций относительно YOZ (x=0) → копии в (-20,0),(-10,0).
var id = await _modeler.MirrorOperationAsync(new[] { c1, c2 }, BasePlane.YOZ);
Assert.True(id > 0);
await _modeler.RebuildAsync();
var v = (await _query.GetPartInfoAsync()).Volume; // удвоение
Assert.InRange(v, before * 2 * 0.95, before * 2 * 1.05);
// Габарит X симметричен: от -23 до 23 → 46.
var box = await _query.GetBoundingBoxAsync();
Assert.InRange(box.SizeX, 46 * 0.95, 46 * 1.05);
}
finally { await _docs.CloseAsync(save: false); }
}
[Fact]
public async Task MirrorBody_makes_symmetric_part_across_YOZ()
{
await _docs.CreateAsync(KompasDocumentType.Part);
try
{
// Цилиндр R3×H10 центр (20,0) (объём ≈ 282.7 мм³).
var s = await _modeler.OpenSketchAsync(BasePlane.XOY);
await _modeler.AddCircleAsync(s, 20, 0, 3);
await _modeler.CloseSketchAsync(s);
await _modeler.ExtrudeAsync(s, depth: 10);
var before = (await _query.GetPartInfoAsync()).Volume;
// Зеркально отразить тело относительно YOZ → оригинал + зеркало в (-20,0).
var id = await _modeler.MirrorBodyAsync(BasePlane.YOZ);
Assert.True(id > 0);
await _modeler.RebuildAsync();
var v = (await _query.GetPartInfoAsync()).Volume;
Assert.InRange(v, before * 2 * 0.95, before * 2 * 1.05);
var box = await _query.GetBoundingBoxAsync();
Assert.InRange(box.SizeX, 46 * 0.95, 46 * 1.05); // от -23 до 23
}
finally { await _docs.CloseAsync(save: false); }
}
[Fact]
public async Task Loft_two_squares_makes_solid()
{