feat: круговой массив (circular_pattern) — ksCircularCopyDefinition o3d_circularCopy

- CircularPatternAsync: SetAxis + свойства напрямую (count1=1 радиально, count2=count кольцевое,
  step2 угол°, factor2=false, inverce=reverse), GetOperationArray
- инструмент circular_pattern (axis, count, step°, reverse, geometric)
- интеграционный тест (3 экз. вокруг Z, шаг 90°, объём ±5% + габарит подтверждает поворот)
- эмпирически: count1=1/count2=N даёт чистый круговой массив, step2 в градусах между соседними
This commit is contained in:
2026-05-27 00:08:35 +03:00
parent bc0adaf830
commit be6a99b9b6
3 changed files with 92 additions and 0 deletions
@@ -165,6 +165,35 @@ public sealed class FeatureOpsTests
finally { await _docs.CloseAsync(save: false); }
}
[Fact]
public async Task CircularPattern_replicates_cylinder_around_Z()
{
await _docs.CreateAsync(KompasDocumentType.Part);
try
{
// Цилиндр R3×H10 со смещением: центр (20,0) (объём π·9·10 ≈ 282.7 мм³).
var s = await _modeler.OpenSketchAsync(BasePlane.XOY);
await _modeler.AddCircleAsync(s, 20, 0, 3);
await _modeler.CloseSketchAsync(s);
var cyl = await _modeler.ExtrudeAsync(s, depth: 10);
var one = (await _query.GetPartInfoAsync()).Volume;
// Круговой массив вокруг Z: 3 экз. с шагом 90° → центры (20,0),(0,20),(-20,0).
var id = await _modeler.CircularPatternAsync(new[] { cyl }, CoordinateAxis.Z, count: 3, step: 90);
Assert.True(id > 0);
await _modeler.RebuildAsync();
var v = (await _query.GetPartInfoAsync()).Volume;
Assert.InRange(v, one * 3 * 0.95, one * 3 * 1.05);
// Габарит: X от -23 до 23 → 46; Y от -3 до 23 → 26 (поворот реально произошёл).
var box = await _query.GetBoundingBoxAsync();
Assert.InRange(box.SizeX, 46 * 0.95, 46 * 1.05);
Assert.InRange(box.SizeY, 26 * 0.95, 26 * 1.05);
}
finally { await _docs.CloseAsync(save: false); }
}
[Fact]
public async Task Loft_two_squares_makes_solid()
{