namespace Kompas.Mcp.Core.Drawings; /// Чистые валидаторы операций чертежа (без COM) — выделены для unit-тестов. public static class DrawingValidation { /// Допустимые расширения файла-источника модели: деталь (.m3d) и сборка (.a3d). private static readonly HashSet AllowedExtensions = new(StringComparer.OrdinalIgnoreCase) { ".m3d", ".a3d" }; /// /// Нормализовать путь к файлу 3D-модели: обрезать пробелы, проверить непустоту и расширение /// (.m3d/.a3d), вернуть абсолютный путь. Существование файла НЕ проверяет (это делает сервис). /// public static string NormalizeModelPath(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); } /// Проверить масштаб чертежа: конечный и строго положительный. public static void RequireScale(double scale) { if (!double.IsFinite(scale) || scale <= 0) throw new ArgumentOutOfRangeException(nameof(scale), "Масштаб должен быть конечным и > 0."); } /// Проверить, что все координаты конечны (отсекает NaN/Infinity). public static void RequireFiniteCoords(params double[] coords) { foreach (var c in coords) if (!double.IsFinite(c)) throw new ArgumentException("Координаты должны быть конечными числами (не NaN/Infinity)."); } /// Проверить радиус: конечный и строго положительный. public static void RequirePositiveRadius(double radius) { if (!double.IsFinite(radius) || radius <= 0) throw new ArgumentOutOfRangeException(nameof(radius), "Радиус должен быть конечным и > 0."); } /// Проверить, что текст не пустой и не только из пробелов. public static void RequireNonEmptyText(string? text, string paramName) { if (string.IsNullOrWhiteSpace(text)) throw new ArgumentException("Текст не должен быть пустым.", paramName); } /// Минимальное расстояние между выносными точками линейного размера (мм). private const double MinPointDistance = 1e-7; /// /// Проверить, что выносные точки размера различны (иначе размер вырожден — нулевая длина). /// 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("Выносные точки размера совпадают — нельзя поставить размер нулевой длины."); } }