Files
kompas3d-mcp/src/Kompas.Mcp.Core/Assemblies/AssemblyValidation.cs
T
mikhail 5eee7ad1af feat: assembly_add_component — вставка детали из .m3d в сборку (API7)
Веха СБОРКИ, инкремент 1. Новый AssemblyService (API7, паттерн HoleService):
IParts7.AddFromFile → Placement.SetOrigin → RebuildModel. Новый AssemblyTools
(MCP-инструмент assembly_add_component), регистрация в DI.

Ключевая находка: UpdatePlacement возвращает FALSE для вручную позиционируемого
компонента (не ошибка), позицию применяет SetOrigin + RebuildModel(true).

Валидация — чистый AssemblyValidation (расширение .m3d/.a3d, нормализация пути,
конечность координат). RequireActiveAssembly — раздельные ошибки по типу документа.

Тесты: +14 unit (AssemblyValidation), +3 integration (AssemblyTests: вставка в
origin, позиционирование со сдвигом, отклонение не-сборки). Итого 83 unit + 53
integration = 136 зелёных.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 13:04:19 +03:00

39 lines
2.1 KiB
C#

namespace Kompas.Mcp.Core.Assemblies;
/// <summary>
/// Чистые валидаторы операций сборки (без COM) — выделены для unit-тестов.
/// </summary>
public static class AssemblyValidation
{
/// <summary>Допустимые расширения файла-источника компонента: деталь (.m3d) и сборка (.a3d).</summary>
private static readonly HashSet<string> AllowedExtensions =
new(StringComparer.OrdinalIgnoreCase) { ".m3d", ".a3d" };
/// <summary>
/// Нормализовать путь к файлу компонента: обрезать пробелы, проверить непустоту и расширение
/// (.m3d/.a3d, без учёта регистра), вернуть абсолютный путь. Существование файла НЕ проверяет
/// (это делает сервис на реальной ФС).
/// </summary>
public static string NormalizeComponentPath(string? path)
{
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentException("Путь к файлу компонента не задан.", nameof(path));
var trimmed = path.Trim();
var ext = Path.GetExtension(trimmed);
if (!AllowedExtensions.Contains(ext))
throw new ArgumentException(
$"Недопустимое расширение файла компонента '{ext}'. Ожидается .m3d (деталь) или .a3d (сборка).",
nameof(path));
return Path.GetFullPath(trimmed);
}
/// <summary>Проверить, что координаты вставки конечны (отсекает NaN/Infinity).</summary>
public static void RequireFinitePosition(double x, double y, double z)
{
if (!double.IsFinite(x) || !double.IsFinite(y) || !double.IsFinite(z))
throw new ArgumentException("Координаты вставки компонента должны быть конечными числами (не NaN/Infinity).");
}
}