Веха 2D-ЧЕРТЁЖ, инкремент 4. DrawingService.AddDiametralDimensionAsync: (ISymbols2DContainer)view.DiametralDimensions.Add → Xc/Yc/Radius/Angle(рад) + AutoNominalValue → Update → Valid → NominalValue (= диаметр 2R). angle в градусах (DimensionAngles.ToRadians). Новый инструмент drawing_add_diametral_dimension. Рефактор по ревью Codex: извлечён RequireSymbols2DContainer(viewNumber) (общий для линейных/диаметральных размеров); AutoNominalValue выставляется явно (как у линейного); DimensionType — COM-дефолт; ToRadians — чистый helper с unit-тестом. Валидаторы: RequirePositiveRadius (новый). Тесты: +10 unit (ToRadians, RequirePositiveRadius), +4 integration (DrawingDiametralTests: диаметр=2R, адресация вида, radius<=0, нет видов). Итого 141 unit + 76 integration = 217. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7.1 KiB
Дизайн: диаметральный размер на виде чертежа (drawing_add_diametral_dimension) через API7
Дата: 2026-05-27 Статус: реализовано и проверено (4 интеграционных + unit, всего 217); ревью Codex спека учтено
Правки по ревью Codex
- #5
((IDimensionText)dim).AutoNominalValue = trueвыставляем явно (консистентно с линейным). - #7 извлечь
RequireSymbols2DContainer(viewNumber)(=(ISymbols2DContainer)FindView(...)) — переиспользуют диаметральный путь и счётчики (радиальный — следующий, тот же паттерн). - #4 конверсия °→рад вынесена в чистый
DimensionAngles.ToRadians(deg)+ unit-тест (значение от угла не зависит → математику проверяем отдельно). - #2
DimensionTypeНЕ задаём — принимаем COM-дефолт (стандартный стиль; полярность bool не подтверждена, спайк с дефолтом далValid+ верное значение). Зафиксировано комментарием. - #1 размер «свободный» (по Xc/Yc/Radius, без
BaseObject) — как у линейного; LLM задаёт верные параметры окружности. Ассоциативная привязка — будущее. Отражено в описании инструмента. - #3
angle— любой конечный (направление выноски, КОМПАС нормализует); валидируем лишь конечность. #6 откат послеAdd()для диаметрального не форсируется (radius>0 → всегда Valid, value=2R>0); код отката идентичен протестированному линейному (zero-projection тест).
Цель
Веха 2D-ЧЕРТЁЖ, инкремент 4. После линейного размера — диаметральный размер окружности на виде (Ø для отверстий/цилиндров — частый случай конструкторского чертежа). Радиальный (с ветвями) и угловой — следующие инкременты.
Спайк: механизм подтверждён (НЕ разучивать)
Та же модель, что у линейного размера (ISymbols2DContainer QI от вида). Спайк
(DrawingDiametralSpikeTests, зелёный):
ISymbols2DContainer symbols = (ISymbols2DContainer)view; // QI от конкретного IView
IDiametralDimension dim = symbols.DiametralDimensions.Add();
dim.Xc = xc; dim.Yc = yc; // центр окружности (ЛОКАЛЬНАЯ СК вида, мм)
dim.Radius = radius; // радиус окружности (мм)
dim.Angle = angleRad; // направление выноски (РАДИАНЫ)
bool ok = dim.Update();
double value = ((IDimensionText)dim).NominalValue; // = ДИАМЕТР (2·Radius)
Проверено: Xc=10,Yc=10,Radius=15,Angle=0.785 → Update=True, Valid=True,
NominalValue == 30 (= диаметр = 2·Radius). Angle — в радианах (конвенция 2D-API КОМПАС;
для размера задаёт лишь направление выноски, на значение не влияет).
Координаты — локальная СК вида (как у линейного). Размер «свободный» (по Xc/Yc/Radius), без
ассоциативной привязки к геометрии (BaseObject не задаём — будущее).
MCP-инструмент
| Инструмент | Параметры | Поведение |
|---|---|---|
drawing_add_diametral_dimension |
xc,yc (центр), radius, angle=0 (°), viewNumber=0 |
Поставить диаметральный размер (Ø) окружности с центром (xc,yc) и радиусом radius (ЛОКАЛЬНАЯ СК вида, мм) на виде. angle — направление выноски в ГРАДУСАХ (внутри → радианы). viewNumber: 0 = первый/главный вид. Значение (диаметр = 2·radius) измеряется автоматически. Возвращает диаметр и номер вида. |
angle экспонируется в градусах (LLM-дружелюбно), внутри умножается на π/180.
Архитектура
В существующем DrawingService (рядом с AddLinearDimensionAsync); переиспользуем FindView,
DrawingDimensionResult, паттерн отката.
DrawingService.AddDiametralDimensionAsync(viewNumber, xc, yc, radius, angleDeg, ct).- Инструмент
drawing_add_diametral_dimensionвDrawingTools. - Helper
GetViewDiametralDimensionCountAsync(для теста — попадание в вид; размеры вISymbols2DContainer, не вObjectCount— как выяснено для линейных).
Валидация (чистые static, unit-тест)
DrawingValidation.RequireFiniteCoords(xc, yc, angleDeg)(уже есть).DrawingValidation.RequirePositiveRadius(double radius)(новый) — конечный и> 0.
Реализация
AddDiametralDimensionCore: валидация (coords + radius>0) → FindView → (ISymbols2DContainer)view
→ DiametralDimensions.Add() (null-check) → Xc/Yc/Radius, Angle = angleDeg·π/180 → Update()
(FALSE → откат dim.Delete + ошибка) → Valid (false → откат) → value = ((IDimensionText)dim). NominalValue (диаметр); если ≤ 0 → откат + ошибка → вернуть DrawingDimensionResult { Value, ViewNumber }.
RCW точечно не освобождаем (v2-2).
Тестирование
Unit (DrawingValidationTests)
RequirePositiveRadius— бросает на 0/отрицательном/NaN/Infinity; пропускает положительный.
Integration (DrawingDiametralTests)
- Значение = диаметр: Radius=15 →
Value ≈ 30. - Попадание в вид:
*DiametralDimensions.Countцелевого вида +1 (адресация поviewNumberизViewNumbers). - Радиус ≤ 0 →
ArgumentOutOfRangeException(откат не нужен — доAdd). - Нет видов → понятная ошибка.
(Сценарий 1 = промотированный спайк; спайк-файл удаляется.)
Дальнейшее (вне спека)
- Радиальный размер (
RadialDimensions, ветви), угловой; ассоциативная привязка к окружности вида (BaseObject); рамка/формат листа.