feat: drawing_add_linear_dimension — линейный размер на виде (API7)
Веха 2D-ЧЕРТЁЖ, инкремент 3. DrawingService.AddLinearDimensionAsync: (ISymbols2D Container)view (QI) → LineDimensions.Add → X1..Y3 (локальная СК вида) + Orientation + AutoNominalValue → Update → проверка Valid → ((IDimensionText)dim).NominalValue. Свой enum DimensionOrientation (horizontal/vertical/parallel). Новый инструмент drawing_add_linear_dimension. DrawingViewsResult += ViewNumbers (адресация видов). Находка: размеры НЕ в IView.ObjectCount (он про геометрию IDrawingContainer) — проверка попадания в вид через ISymbols2DContainer.LineDimensions.Count. Ревью Codex спека учтено: RequireDistinctPoints (нулевая длина) + Valid после Update; контракт «первый несистемный вид»; null-check Add; AutoNominalValue явно; ViewNumbers required + текст ответа create_standard_views; тесты адресации/негатив. Тесты: +8 unit (DimensionOrientations, DrawingValidation), +5 integration (DrawingDimensionTests). Итого 131 unit + 70 integration = 201. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,29 @@
|
||||
# Дизайн: линейный размер на виде чертежа (drawing_add_linear_dimension) через API7
|
||||
|
||||
**Дата:** 2026-05-27
|
||||
**Статус:** спайк зелёный (механизм + авто-значение подтверждены); спроектировано; на ревью (Codex)
|
||||
**Статус:** реализовано и проверено (5 интеграционных + unit, всего 201); ревью Codex спека учтено
|
||||
|
||||
## Находка реализации: размеры НЕ в IView.ObjectCount
|
||||
|
||||
`IView.ObjectCount` считает **геометрию** (`IDrawingContainer`: линии/дуги), а размеры живут в
|
||||
`ISymbols2DContainer` отдельно → после простановки размера `ObjectCount` НЕ меняется (проверено: 4→4).
|
||||
Поэтому «размер попал в целевой вид» проверяем счётом `ISymbols2DContainer.LineDimensions.Count`
|
||||
(helper `GetViewLineDimensionCountAsync`), а не `ObjectCount`. (Гарантия непустоты у стандартных видов
|
||||
по `ObjectCount` остаётся верной — там именно геометрия.)
|
||||
|
||||
## Правки по ревью Codex
|
||||
|
||||
- **Нулевая длина** (#1): `DrawingValidation.RequireDistinctPoints(x1,y1,x2,y2)` — расстояние между
|
||||
точками > 1e-7 (иначе вырожденный размер); + проверка `dim.Valid` после `Update()` (откат);
|
||||
+ негативный тест.
|
||||
- **Контракт вида** (#4): честно — «первый НЕСИСТЕМНЫЙ вид (Number != 0)» при `viewNumber<=0`, без
|
||||
претензии на ассоциативность и без QI к `IAssociationView` (в наших чертежах иных видов нет).
|
||||
- **null-check + порядок** (#9): `LineDimensions.Add()` проверять на null; `AutoNominalValue=true`
|
||||
выставлять явно; `NominalValue` читать ТОЛЬКО после `Update()==true && Valid==true`.
|
||||
- **ViewNumbers** (#7): поле `required` в `DrawingViewsResult`; инициализатор и текст MCP-ответа
|
||||
`drawing_create_standard_views` обновить (вернуть номера видов).
|
||||
- **Тесты** (#6): ObjectCount ЦЕЛЕВОГО вида до/после; адресация конкретного `viewNumber`; негатив на
|
||||
совпадающие точки. **viewNumber не найден** (#2) → понятная ошибка. 3D-конвертер точек (#8) — будущее.
|
||||
|
||||
## Цель
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
using Kompas6Constants;
|
||||
|
||||
namespace Kompas.Mcp.Core.Drawings;
|
||||
|
||||
/// <summary>Ориентация линейного размера (обёртка над <see cref="ksLineDimensionOrientationEnum"/>).</summary>
|
||||
public enum DimensionOrientation
|
||||
{
|
||||
/// <summary>Горизонтальный (измеряет |X2−X1|).</summary>
|
||||
Horizontal,
|
||||
/// <summary>Вертикальный (измеряет |Y2−Y1|).</summary>
|
||||
Vertical,
|
||||
/// <summary>Параллельный отрезку P1→P2 (реальная длина).</summary>
|
||||
Parallel,
|
||||
}
|
||||
|
||||
/// <summary>Маппинг ориентации размера ↔ перечисление КОМПАС и разбор строки.</summary>
|
||||
public static class DimensionOrientations
|
||||
{
|
||||
public static ksLineDimensionOrientationEnum ToKompas(DimensionOrientation orientation) => orientation switch
|
||||
{
|
||||
DimensionOrientation.Horizontal => ksLineDimensionOrientationEnum.ksLinDHorizontal,
|
||||
DimensionOrientation.Vertical => ksLineDimensionOrientationEnum.ksLinDVertical,
|
||||
DimensionOrientation.Parallel => ksLineDimensionOrientationEnum.ksLinDParallel,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(orientation), orientation, "Неизвестная ориентация размера."),
|
||||
};
|
||||
|
||||
/// <summary>Разобрать строку ориентации (англ./рус.) в <see cref="DimensionOrientation"/>.</summary>
|
||||
public static DimensionOrientation Parse(string value)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(value);
|
||||
return value.Trim().ToLowerInvariant() switch
|
||||
{
|
||||
"horizontal" or "h" or "горизонтальный" or "горизонтальная" => DimensionOrientation.Horizontal,
|
||||
"vertical" or "v" or "вертикальный" or "вертикальная" => DimensionOrientation.Vertical,
|
||||
"parallel" or "p" or "параллельный" or "параллельная" => DimensionOrientation.Parallel,
|
||||
_ => throw new ArgumentException(
|
||||
$"Неизвестная ориентация размера '{value}'. Допустимо: horizontal, vertical, parallel.",
|
||||
nameof(value)),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Kompas.Mcp.Core.Drawings;
|
||||
|
||||
/// <summary>Результат простановки размера на чертеже.</summary>
|
||||
public sealed record DrawingDimensionResult
|
||||
{
|
||||
/// <summary>Измеренное значение размера (мм).</summary>
|
||||
public required double Value { get; init; }
|
||||
|
||||
/// <summary>Номер вида, на котором поставлен размер.</summary>
|
||||
public required int ViewNumber { get; init; }
|
||||
}
|
||||
@@ -84,6 +84,79 @@ public sealed class DrawingService
|
||||
?? throw new InvalidOperationException("У листа оформления нет основной надписи (Stamp).");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Поставить линейный размер на виде активного чертежа между точками (x1,y1)-(x2,y2) в ЛОКАЛЬНОЙ
|
||||
/// СК вида (мм); размерная линия проходит через (x3,y3). <paramref name="viewNumber"/> — номер вида
|
||||
/// (≤0 = первый несистемный/главный). Значение измеряется автоматически. Возвращает значение и номер вида.
|
||||
/// </summary>
|
||||
public Task<DrawingDimensionResult> AddLinearDimensionAsync(int viewNumber, double x1, double y1,
|
||||
double x2, double y2, double x3, double y3, DimensionOrientation orientation, CancellationToken ct = default)
|
||||
=> _dispatcher.InvokeAsync(() =>
|
||||
AddLinearDimensionCore(viewNumber, x1, y1, x2, y2, x3, y3, orientation), ct);
|
||||
|
||||
private DrawingDimensionResult AddLinearDimensionCore(int viewNumber, double x1, double y1,
|
||||
double x2, double y2, double x3, double y3, DimensionOrientation orientation)
|
||||
{
|
||||
DrawingValidation.RequireFiniteCoords(x1, y1, x2, y2, x3, y3);
|
||||
DrawingValidation.RequireDistinctPoints(x1, y1, x2, y2);
|
||||
|
||||
var view = FindView(viewNumber);
|
||||
var symbols = view as ISymbols2DContainer
|
||||
?? throw new InvalidOperationException("Вид не приводится к ISymbols2DContainer.");
|
||||
var dim = symbols.LineDimensions?.Add()
|
||||
?? throw new InvalidOperationException("LineDimensions.Add вернул null.");
|
||||
try
|
||||
{
|
||||
dim.X1 = x1; dim.Y1 = y1; dim.X2 = x2; dim.Y2 = y2; dim.X3 = x3; dim.Y3 = y3;
|
||||
dim.Orientation = DimensionOrientations.ToKompas(orientation);
|
||||
((IDimensionText)dim).AutoNominalValue = true; // авто-измерение значения (по умолчанию, явно)
|
||||
|
||||
if (!dim.Update())
|
||||
throw new InvalidOperationException("ILineDimension.Update вернул FALSE — размер не построен.");
|
||||
if (!dim.Valid)
|
||||
throw new InvalidOperationException("Размер построен невалидным (проверьте точки/ориентацию).");
|
||||
|
||||
// NominalValue читаем ТОЛЬКО после успешного Update и Valid.
|
||||
var value = ((IDimensionText)dim).NominalValue;
|
||||
return new DrawingDimensionResult { Value = value, ViewNumber = view.Number };
|
||||
}
|
||||
catch
|
||||
{
|
||||
try { dim.Delete(); } catch { /* лучшее усилие */ }
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Число линейных размеров на виде по номеру (для проверки/диагностики). Размеры живут
|
||||
/// в ISymbols2DContainer вида, а НЕ в IView.ObjectCount (тот считает геометрию).</summary>
|
||||
public Task<int> GetViewLineDimensionCountAsync(int viewNumber, CancellationToken ct = default)
|
||||
=> _dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
var symbols = (ISymbols2DContainer)FindView(viewNumber);
|
||||
return symbols.LineDimensions?.Count ?? 0;
|
||||
}, ct);
|
||||
|
||||
/// <summary>Найти вид: при viewNumber ≤ 0 — первый несистемный (Number != 0); иначе по номеру.</summary>
|
||||
private IView FindView(int viewNumber)
|
||||
{
|
||||
var views = RequireActiveDrawingViews();
|
||||
foreach (var o in views)
|
||||
{
|
||||
if (o is not IView v) continue;
|
||||
if (viewNumber <= 0)
|
||||
{
|
||||
if (v.Number != 0) return v; // первый несистемный
|
||||
}
|
||||
else if (v.Number == viewNumber)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
}
|
||||
throw new InvalidOperationException(viewNumber <= 0
|
||||
? "На чертеже нет несистемного вида. Сначала создайте виды: drawing_create_standard_views."
|
||||
: $"Вид с номером {viewNumber} не найден на чертеже.");
|
||||
}
|
||||
|
||||
// Стандартная тройка проекций: ksPtFront=1, ksPtUp=3, ksPtLeft=5 (ksRelativeProjectionTypeEnum).
|
||||
private static readonly object[] StandardProjections = { 1, 3, 5 };
|
||||
private const int ExpectedCreated = 3;
|
||||
@@ -122,7 +195,12 @@ public sealed class DrawingService
|
||||
throw new InvalidOperationException(
|
||||
"Стандартные виды созданы, но пусты (модель не спроецировалась). Проверьте файл модели.");
|
||||
|
||||
return new DrawingViewsResult { Created = newViews.Count, Total = views.Count };
|
||||
return new DrawingViewsResult
|
||||
{
|
||||
Created = newViews.Count,
|
||||
Total = views.Count,
|
||||
ViewNumbers = newViews.Select(v => v.Number).ToArray(),
|
||||
};
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
@@ -32,4 +32,26 @@ public static class DrawingValidation
|
||||
if (!double.IsFinite(scale) || scale <= 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(scale), "Масштаб должен быть конечным и > 0.");
|
||||
}
|
||||
|
||||
/// <summary>Проверить, что все координаты конечны (отсекает NaN/Infinity).</summary>
|
||||
public static void RequireFiniteCoords(params double[] coords)
|
||||
{
|
||||
foreach (var c in coords)
|
||||
if (!double.IsFinite(c))
|
||||
throw new ArgumentException("Координаты должны быть конечными числами (не NaN/Infinity).");
|
||||
}
|
||||
|
||||
/// <summary>Минимальное расстояние между выносными точками линейного размера (мм).</summary>
|
||||
private const double MinPointDistance = 1e-7;
|
||||
|
||||
/// <summary>
|
||||
/// Проверить, что выносные точки размера различны (иначе размер вырожден — нулевая длина).
|
||||
/// </summary>
|
||||
public static void RequireDistinctPoints(double x1, double y1, double x2, double y2)
|
||||
{
|
||||
var dx = x2 - x1;
|
||||
var dy = y2 - y1;
|
||||
if (Math.Sqrt(dx * dx + dy * dy) < MinPointDistance)
|
||||
throw new ArgumentException("Выносные точки размера совпадают — нельзя поставить размер нулевой длины.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,4 +8,7 @@ public sealed record DrawingViewsResult
|
||||
|
||||
/// <summary>Общее число видов на чертеже после операции (включая системный вид).</summary>
|
||||
public required int Total { get; init; }
|
||||
|
||||
/// <summary>Номера созданных видов (для адресации при простановке размеров).</summary>
|
||||
public required IReadOnlyList<int> ViewNumbers { get; init; }
|
||||
}
|
||||
|
||||
@@ -24,7 +24,9 @@ public sealed class DrawingTools(KompasSession session, DrawingService drawing)
|
||||
{
|
||||
await session.ConnectAsync();
|
||||
var r = await drawing.CreateStandardViewsAsync(partFilePath, scale, x, y);
|
||||
return $"Создано {r.Created} стандартных вида на чертеже (всего видов: {r.Total}, масштаб {scale}).";
|
||||
var numbers = string.Join(", ", r.ViewNumbers);
|
||||
return $"Создано {r.Created} стандартных вида на чертеже (всего видов: {r.Total}, масштаб {scale}). " +
|
||||
$"Номера созданных видов: {numbers} (для drawing_add_linear_dimension).";
|
||||
}
|
||||
|
||||
[McpServerTool(Name = "drawing_fill_title_block")]
|
||||
@@ -41,4 +43,26 @@ public sealed class DrawingTools(KompasSession session, DrawingService drawing)
|
||||
var filled = await drawing.FillTitleBlockAsync(designation, name, material);
|
||||
return $"Заполнено граф основной надписи: {filled}.";
|
||||
}
|
||||
|
||||
[McpServerTool(Name = "drawing_add_linear_dimension")]
|
||||
[Description("Поставить линейный размер на виде активного чертежа между точками (x1,y1)-(x2,y2) " +
|
||||
"в ЛОКАЛЬНОЙ СК вида (мм; при масштабе 1:1 = координаты модели на плоскости вида). Размерная " +
|
||||
"линия проходит через (x3,y3). orientation: horizontal (|X2-X1|) | vertical (|Y2-Y1|) | parallel " +
|
||||
"(длина отрезка). viewNumber — номер вида из drawing_create_standard_views (0 = первый/главный вид). " +
|
||||
"Значение измеряется автоматически. Возвращает измеренное значение и номер вида.")]
|
||||
public async Task<string> AddLinearDimension(
|
||||
[Description("X первой выносной точки (СК вида, мм)")] double x1,
|
||||
[Description("Y первой выносной точки")] double y1,
|
||||
[Description("X второй выносной точки")] double x2,
|
||||
[Description("Y второй выносной точки")] double y2,
|
||||
[Description("X положения размерной линии")] double x3,
|
||||
[Description("Y положения размерной линии")] double y3,
|
||||
[Description("Ориентация: horizontal | vertical | parallel")] string orientation = "horizontal",
|
||||
[Description("Номер вида (0 = первый/главный)")] int viewNumber = 0)
|
||||
{
|
||||
await session.ConnectAsync();
|
||||
var o = DimensionOrientations.Parse(orientation);
|
||||
var r = await drawing.AddLinearDimensionAsync(viewNumber, x1, y1, x2, y2, x3, y3, o);
|
||||
return $"Линейный размер ({orientation}) поставлен на виде {r.ViewNumber}, значение {r.Value:0.###} мм.";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
using Kompas.Mcp.Core.Drawings;
|
||||
|
||||
namespace Kompas.Mcp.Tests;
|
||||
|
||||
[Trait("Category", "Unit")]
|
||||
public sealed class DimensionOrientationsTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("horizontal", DimensionOrientation.Horizontal)]
|
||||
[InlineData("vertical", DimensionOrientation.Vertical)]
|
||||
[InlineData("parallel", DimensionOrientation.Parallel)]
|
||||
[InlineData("ГОРИЗОНТАЛЬНЫЙ", DimensionOrientation.Horizontal)]
|
||||
[InlineData(" vertical ", DimensionOrientation.Vertical)]
|
||||
public void Parse_maps_known(string value, DimensionOrientation expected)
|
||||
=> Assert.Equal(expected, DimensionOrientations.Parse(value));
|
||||
|
||||
[Fact]
|
||||
public void Parse_throws_on_unknown()
|
||||
=> Assert.Throws<ArgumentException>(() => DimensionOrientations.Parse("diagonal"));
|
||||
|
||||
// ToKompas (→ ksLineDimensionOrientationEnum) намеренно НЕ покрыт unit-тестом: тестовый проект
|
||||
// не ссылается на Kompas6Constants (граница проекта). Маппинг тривиален и проверяется интеграцией
|
||||
// (horizontal → |X2-X1|, vertical → |Y2-Y1|).
|
||||
}
|
||||
@@ -53,4 +53,19 @@ public sealed class DrawingValidationTests
|
||||
[InlineData(2.0)]
|
||||
public void RequireScale_accepts_positive(double scale)
|
||||
=> Assert.Null(Record.Exception(() => DrawingValidation.RequireScale(scale)));
|
||||
|
||||
[Fact]
|
||||
public void RequireFiniteCoords_throws_on_non_finite()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => DrawingValidation.RequireFiniteCoords(0, double.NaN));
|
||||
Assert.Throws<ArgumentException>(() => DrawingValidation.RequireFiniteCoords(double.PositiveInfinity));
|
||||
Assert.Null(Record.Exception(() => DrawingValidation.RequireFiniteCoords(0, 1, -5, 40)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RequireDistinctPoints_throws_on_coincident()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => DrawingValidation.RequireDistinctPoints(10, 20, 10, 20));
|
||||
Assert.Null(Record.Exception(() => DrawingValidation.RequireDistinctPoints(0, 0, 40, 0)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
using Kompas.Mcp.Core.Documents;
|
||||
using Kompas.Mcp.Core.Drawings;
|
||||
using Kompas.Mcp.Core.Modeling;
|
||||
|
||||
namespace Kompas.Mcp.Tests.Integration;
|
||||
|
||||
/// <summary>Интеграция: линейный размер на виде чертежа (API7 ISymbols2DContainer.LineDimensions).</summary>
|
||||
[Trait("Category", "Integration")]
|
||||
[Collection(KompasCollection.Name)]
|
||||
public sealed class DrawingDimensionTests : IntegrationTestBase
|
||||
{
|
||||
private readonly DocumentService _docs;
|
||||
private readonly PartModeler _modeler;
|
||||
private readonly DrawingService _drawing;
|
||||
|
||||
public DrawingDimensionTests(KompasFixture fx) : base(fx)
|
||||
{
|
||||
_docs = new DocumentService(fx.Session, fx.Dispatcher);
|
||||
_modeler = new PartModeler(fx.Session, fx.Dispatcher);
|
||||
_drawing = new DrawingService(fx.Session, fx.Dispatcher);
|
||||
}
|
||||
|
||||
private async Task<string> BuildAndSaveBoxAsync()
|
||||
{
|
||||
var path = TestPaths.NewFile(".m3d");
|
||||
await _docs.CreateAsync(KompasDocumentType.Part);
|
||||
try
|
||||
{
|
||||
var s = await _modeler.OpenSketchAsync(BasePlane.XOY);
|
||||
await _modeler.AddRectangleAsync(s, 0, 0, 40, 30);
|
||||
await _modeler.CloseSketchAsync(s);
|
||||
await _modeler.ExtrudeAsync(s, depth: 20);
|
||||
await _modeler.RebuildAsync();
|
||||
await _docs.SaveAsAsync(path);
|
||||
}
|
||||
finally { await _docs.CloseAsync(save: false); }
|
||||
return path;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Horizontal_dimension_auto_measures_distance()
|
||||
{
|
||||
var partFile = await BuildAndSaveBoxAsync();
|
||||
await _docs.CreateAsync(KompasDocumentType.Drawing);
|
||||
try
|
||||
{
|
||||
var views = await _drawing.CreateStandardViewsAsync(partFile, 1.0, 100, 150);
|
||||
Assert.Equal(3, views.ViewNumbers.Count);
|
||||
|
||||
var r = await _drawing.AddLinearDimensionAsync(
|
||||
viewNumber: 0, x1: 0, y1: 0, x2: 40, y2: 0, x3: 20, y3: -10, DimensionOrientation.Horizontal);
|
||||
|
||||
Assert.InRange(r.Value, 39.9, 40.1); // авто-значение = |X2-X1|
|
||||
Assert.Contains(r.ViewNumber, views.ViewNumbers); // размер попал в один из видов
|
||||
}
|
||||
finally { await _docs.CloseAsync(save: false); }
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Vertical_dimension_measures_y_span()
|
||||
{
|
||||
var partFile = await BuildAndSaveBoxAsync();
|
||||
await _docs.CreateAsync(KompasDocumentType.Drawing);
|
||||
try
|
||||
{
|
||||
await _drawing.CreateStandardViewsAsync(partFile, 1.0, 100, 150);
|
||||
var r = await _drawing.AddLinearDimensionAsync(
|
||||
viewNumber: 0, x1: 0, y1: 0, x2: 0, y2: 20, x3: -10, y3: 10, DimensionOrientation.Vertical);
|
||||
Assert.InRange(r.Value, 19.9, 20.1);
|
||||
}
|
||||
finally { await _docs.CloseAsync(save: false); }
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Targets_specific_view_by_number_and_increments_its_object_count()
|
||||
{
|
||||
var partFile = await BuildAndSaveBoxAsync();
|
||||
await _docs.CreateAsync(KompasDocumentType.Drawing);
|
||||
try
|
||||
{
|
||||
var views = await _drawing.CreateStandardViewsAsync(partFile, 1.0, 100, 150);
|
||||
var targetNumber = views.ViewNumbers[1]; // второй созданный вид (напр. сверху)
|
||||
|
||||
// Размеры живут в ISymbols2DContainer вида — считаем именно их у ЦЕЛЕВОГО вида.
|
||||
var before = await _drawing.GetViewLineDimensionCountAsync(targetNumber);
|
||||
var r = await _drawing.AddLinearDimensionAsync(
|
||||
viewNumber: targetNumber, x1: 0, y1: 0, x2: 40, y2: 0, x3: 20, y3: -10, DimensionOrientation.Horizontal);
|
||||
var after = await _drawing.GetViewLineDimensionCountAsync(targetNumber);
|
||||
|
||||
Assert.Equal(targetNumber, r.ViewNumber);
|
||||
Assert.Equal(before + 1, after); // размер попал именно в целевой вид
|
||||
}
|
||||
finally { await _docs.CloseAsync(save: false); }
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Coincident_points_throw()
|
||||
{
|
||||
var partFile = await BuildAndSaveBoxAsync();
|
||||
await _docs.CreateAsync(KompasDocumentType.Drawing);
|
||||
try
|
||||
{
|
||||
await _drawing.CreateStandardViewsAsync(partFile, 1.0, 100, 150);
|
||||
await Assert.ThrowsAsync<ArgumentException>(() => _drawing.AddLinearDimensionAsync(
|
||||
viewNumber: 0, x1: 10, y1: 10, x2: 10, y2: 10, x3: 0, y3: 0, DimensionOrientation.Horizontal));
|
||||
}
|
||||
finally { await _docs.CloseAsync(save: false); }
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task No_views_throws()
|
||||
{
|
||||
// Чертёж без ассоциативных видов: только системный вид → понятная ошибка.
|
||||
await _docs.CreateAsync(KompasDocumentType.Drawing);
|
||||
try
|
||||
{
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() => _drawing.AddLinearDimensionAsync(
|
||||
viewNumber: 0, x1: 0, y1: 0, x2: 40, y2: 0, x3: 20, y3: -10, DimensionOrientation.Horizontal));
|
||||
}
|
||||
finally { await _docs.CloseAsync(save: false); }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user