a4cc755fb4
Три способа получить форму там, где раньше был только замкнутый контур из отрезков и дуг. 1. Примитив эскиза type=text: ksTextEx + ksConvertTextToCurve. Пока текст остаётся текстом, это оформление, и операция его не видит; после конвертации глифы становятся обычным сечением. Ответ возвращает фактическую длину строки — иначе ширину шрифта до выдавливания не узнать. 2. extrude(thinThickness, thinSide): контур трактуется как стенка заданной толщины. outward по замкнутому контуру даёт кайму-эквидистанту вокруг него — так надпись получает подложку без 2D-эквидистанты. Толщину при dtReverse КОМПАС читает из reverseThickness: положить её в normalThickness значит молча получить СПЛОШНОЕ сечение вместо рамки. 3. Инструмент primitive: элементарные тела API7 (block, cylinder, sphere, cone) с result=new|union|subtract|intersect. Карман и паз строятся вычитанием тела, без эскиза и выреза. Update() возвращает TRUE даже когда вычитание прошло мимо тела, поэтому сервис сверяет объём до и после и откатывает операцию, если ничего не изменилось.
158 lines
6.0 KiB
C#
158 lines
6.0 KiB
C#
using Kompas.Mcp.Core.Modeling;
|
|
|
|
namespace Kompas.Mcp.Tests;
|
|
|
|
/// <summary>
|
|
/// Разбор пакета примитивов эскиза. Схема слитого инструмента не может запретить неверную
|
|
/// комбинацию полей — её ловит этот разбор, и сообщение должно называть недостающий параметр
|
|
/// и позицию в списке, иначе агент не исправится с первой попытки.
|
|
/// </summary>
|
|
[Trait("Category", "Unit")]
|
|
public sealed class SketchEntityInputsTests
|
|
{
|
|
private static SketchEntityInput Circle() => new()
|
|
{
|
|
Type = "circle", CenterX = 0, CenterY = 0, Radius = 5,
|
|
};
|
|
|
|
[Fact]
|
|
public void Empty_input_gives_empty_list()
|
|
{
|
|
Assert.Empty(SketchEntityInputs.Parse(null));
|
|
Assert.Empty(SketchEntityInputs.Parse([]));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("line", SketchEntityKind.Line)]
|
|
[InlineData("LINE", SketchEntityKind.Line)]
|
|
[InlineData(" rect ", SketchEntityKind.Rectangle)]
|
|
[InlineData("rectangle", SketchEntityKind.Rectangle)]
|
|
[InlineData("arc3", SketchEntityKind.Arc3Points)]
|
|
[InlineData("arc3points", SketchEntityKind.Arc3Points)]
|
|
[InlineData("axis", SketchEntityKind.Axis)]
|
|
public void Type_names_and_aliases_are_recognized(string type, SketchEntityKind expected)
|
|
{
|
|
var e = new SketchEntityInput
|
|
{
|
|
Type = type,
|
|
Points = [new SketchPoint(0, 0), new SketchPoint(10, 10), new SketchPoint(20, 0)],
|
|
};
|
|
|
|
Assert.Equal(expected, SketchEntityInputs.Parse([e])[0].Kind);
|
|
}
|
|
|
|
[Fact]
|
|
public void Unknown_type_lists_the_allowed_ones()
|
|
{
|
|
var e = new SketchEntityInput { Type = "spiral" };
|
|
|
|
var ex = Assert.Throws<ArgumentException>(() => SketchEntityInputs.Parse([e]));
|
|
Assert.Contains("spiral", ex.Message, StringComparison.Ordinal);
|
|
Assert.Contains("polyline", ex.Message, StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public void Error_names_the_position_in_the_batch()
|
|
{
|
|
var bad = new SketchEntityInput { Type = "circle", CenterX = 0, CenterY = 0 }; // без radius
|
|
|
|
var ex = Assert.Throws<ArgumentException>(() => SketchEntityInputs.Parse([Circle(), Circle(), bad]));
|
|
Assert.Contains("entities[2]", ex.Message, StringComparison.Ordinal);
|
|
Assert.Contains("radius", ex.Message, StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public void Line_requires_two_points()
|
|
{
|
|
var e = new SketchEntityInput { Type = "line", Points = [new SketchPoint(0, 0)] };
|
|
|
|
var ex = Assert.Throws<ArgumentException>(() => SketchEntityInputs.Parse([e]));
|
|
Assert.Contains("points", ex.Message, StringComparison.Ordinal);
|
|
Assert.Contains("минимум 2", ex.Message, StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public void Arc_requires_center_radius_and_angles()
|
|
{
|
|
var e = new SketchEntityInput { Type = "arc", CenterX = 0, CenterY = 0, Radius = 10, StartAngle = 0 };
|
|
|
|
var ex = Assert.Throws<ArgumentException>(() => SketchEntityInputs.Parse([e]));
|
|
Assert.Contains("endAngle", ex.Message, StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public void Polygon_requires_vertex_count()
|
|
{
|
|
var e = new SketchEntityInput { Type = "polygon", CenterX = 0, CenterY = 0, Radius = 10 };
|
|
|
|
var ex = Assert.Throws<ArgumentException>(() => SketchEntityInputs.Parse([e]));
|
|
Assert.Contains("vertexCount", ex.Message, StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public void Defaults_are_applied_for_omitted_flags()
|
|
{
|
|
var e = new SketchEntityInput { Type = "arc", CenterX = 1, CenterY = 2, Radius = 3, StartAngle = 0, EndAngle = 90 };
|
|
|
|
var parsed = SketchEntityInputs.Parse([e])[0];
|
|
|
|
Assert.True(parsed.CounterClockwise); // умолчание — против часовой
|
|
Assert.True(parsed.Inscribed);
|
|
Assert.False(parsed.Closed);
|
|
Assert.Equal(0, parsed.Angle);
|
|
}
|
|
|
|
[Fact]
|
|
public void Text_requires_insertion_point_string_and_height()
|
|
{
|
|
var noPoint = new SketchEntityInput { Type = "text", Text = "OldMan", Height = 10 };
|
|
Assert.Contains("points", Assert.Throws<ArgumentException>(
|
|
() => SketchEntityInputs.Parse([noPoint])).Message, StringComparison.Ordinal);
|
|
|
|
var noText = new SketchEntityInput { Type = "text", Points = [new SketchPoint(0, 0)], Height = 10 };
|
|
Assert.Contains("text", Assert.Throws<ArgumentException>(
|
|
() => SketchEntityInputs.Parse([noText])).Message, StringComparison.Ordinal);
|
|
|
|
var noHeight = new SketchEntityInput { Type = "text", Points = [new SketchPoint(0, 0)], Text = "OldMan" };
|
|
Assert.Contains("height", Assert.Throws<ArgumentException>(
|
|
() => SketchEntityInputs.Parse([noHeight])).Message, StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public void Text_defaults_keep_normal_width_and_upright_face()
|
|
{
|
|
var e = new SketchEntityInput
|
|
{
|
|
Type = "text", Points = [new SketchPoint(4, 12)], Text = "EDITION", Height = 6, FontName = "Zilla Slab",
|
|
};
|
|
|
|
var parsed = SketchEntityInputs.Parse([e])[0];
|
|
|
|
Assert.Equal(SketchEntityKind.Text, parsed.Kind);
|
|
Assert.Equal("EDITION", parsed.Text);
|
|
Assert.Equal("Zilla Slab", parsed.FontName);
|
|
Assert.Equal(6, parsed.Height);
|
|
Assert.Equal(1.0, parsed.WidthFactor);
|
|
Assert.False(parsed.Bold);
|
|
Assert.False(parsed.Italic);
|
|
Assert.Equal((4.0, 12.0), parsed.Points[0]);
|
|
}
|
|
|
|
[Fact]
|
|
public void Points_keep_their_order()
|
|
{
|
|
var e = new SketchEntityInput
|
|
{
|
|
Type = "polyline",
|
|
Points = [new SketchPoint(0, 0), new SketchPoint(10, 0), new SketchPoint(10, 5)],
|
|
Closed = true,
|
|
};
|
|
|
|
var parsed = SketchEntityInputs.Parse([e])[0];
|
|
|
|
Assert.True(parsed.Closed);
|
|
Assert.Equal(3, parsed.Points.Count);
|
|
Assert.Equal((10.0, 5.0), parsed.Points[2]);
|
|
}
|
|
}
|