docs: спек drawing_fill_title_block — основная надпись чертежа (API7)
Веха 2D-ЧЕРТЁЖ, инкремент 2. Спайк подтвердил round-trip графы: LayoutSheets. ItemByNumber[1].Stamp.Text[id].Str + Update(). Enum StampField→номер графы ГОСТ (designation=2, name=1, material=3). Заполнение нескольких граф за вызов. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
# Дизайн: основная надпись чертежа (drawing_fill_title_block) через API7
|
||||
|
||||
**Дата:** 2026-05-27
|
||||
**Статус:** спайк зелёный (round-trip графы подтверждён); спроектировано; на ревью (Codex)
|
||||
|
||||
## Цель
|
||||
|
||||
Веха 2D-ЧЕРТЁЖ, инкремент 2 (оформление). После стандартных видов (`drawing_create_standard_views`)
|
||||
— заполнить **основную надпись** (штамп, title block) чертежа: обозначение, наименование, материал.
|
||||
Чертёж с видами + заполненным штампом = презентабельный конструкторский документ. Размеры на видах
|
||||
— отдельный инкремент 3 (нужен спайк по размерным интерфейсам).
|
||||
|
||||
## Спайк: механизм подтверждён вживую (НЕ разучивать)
|
||||
|
||||
Спайк (`DrawingStampSpikeTests`, зелёный) подтвердил путь API7 — round-trip графы:
|
||||
|
||||
```
|
||||
IKompasDocument2D doc2d = (IKompasDocument2D)app.ActiveDocument; // активный чертёж
|
||||
ILayoutSheet sheet = (ILayoutSheet)doc2d.LayoutSheets.ItemByNumber[1]; // лист 1 (1-based)
|
||||
IStamp stamp = (IStamp)sheet.Stamp;
|
||||
stamp.Text[columnId].Str = text; // Text[Int32 Id] — индексированное свойство; Id = номер графы
|
||||
stamp.Update(); // фиксирует
|
||||
string readBack = stamp.Text[columnId].Str; // чтение для проверки
|
||||
```
|
||||
|
||||
**Проверено:** запись в графу 2 (обозначение) «ДЕТАЛЬ.001» → чтение возвращает «ДЕТАЛЬ.001».
|
||||
`IText.Str` — read/write; `IStamp.Text[Id]` — индексированное свойство (рефлексия: `get_Text(Int32 Id)`).
|
||||
`Update()` фиксирует; перестроение документа не нужно.
|
||||
|
||||
**Номера граф ГОСТ (форма 1), `ksStampEnum`:** `ksStPartNumber=1` (наименование изделия),
|
||||
`ksStDescription=2` (обозначение документа), `ksStMaterial=3` (материал), `ksStScale=6` (масштаб),
|
||||
`ksStAuthor=110` (разработал) и т.д.
|
||||
|
||||
## Архитектура
|
||||
|
||||
Метод в существующем `DrawingService`. Свой enum `StampField` (паттерн `BasePlane`/`MateType`)
|
||||
маппится на номера граф — COM-числа не текут в Host/тесты.
|
||||
|
||||
- `src/Kompas.Mcp.Core/Drawings/StampField.cs` — enum `StampField` + static `StampFields`
|
||||
(`ColumnId(field)` → номер графы).
|
||||
- `DrawingService.FillTitleBlockAsync(designation?, name?, material?, ct)` — реализация.
|
||||
- Инструмент `drawing_fill_title_block` в `DrawingTools`.
|
||||
|
||||
## MCP-инструмент
|
||||
|
||||
| Инструмент | Параметры | Поведение |
|
||||
|---|---|---|
|
||||
| `drawing_fill_title_block` | `designation?`, `name?`, `material?` (все опц.) | Заполнить графы основной надписи активного чертежа: обозначение (графа 2), наименование (1), материал (3). Передаются только нужные поля (null/пусто — пропускается). Возвращает число заполненных граф. |
|
||||
|
||||
Контракт: активный документ — чертёж; хотя бы одно поле задано (иначе ошибка). Набор полей —
|
||||
3 ключевые графы ГОСТ (расширяемо). За один вызов заполняются все переданные (меньше round-trip'ов
|
||||
для LLM-агента, чем у «одна графа за вызов»).
|
||||
|
||||
## Валидация (чистые static, unit-тест)
|
||||
|
||||
- `StampFields.ColumnId(StampField)` — `Designation→2`, `Name→1`, `Material→3` (unit-тест маппинга).
|
||||
- В сервисе: собрать непустые (после `Trim`) поля; если ни одного — `ArgumentException`
|
||||
«укажите хотя бы одно поле». (Чистый помощник `StampFields.Collect(...)` → список (columnId,text)
|
||||
— unit-тестируемо без COM.)
|
||||
|
||||
## Проверка активного документа
|
||||
|
||||
`RequireActiveDrawing()` → `IKompasDocument2D` (тип `ksDocumentDrawing`, иначе раздельная ошибка) —
|
||||
выделить из существующего `RequireActiveDrawingViews` общий шаг (тот станет надстройкой: вернуть
|
||||
`.ViewsAndLayersManager.Views`).
|
||||
|
||||
## Реализация
|
||||
|
||||
`FillTitleBlockCore`: собрать поля (`StampFields.Collect`) → если пусто, ошибка → `RequireActiveDrawing`
|
||||
→ `sheet = LayoutSheets.ItemByNumber[1]` → `stamp = (IStamp)sheet.Stamp` → для каждого поля
|
||||
`stamp.Text[columnId].Str = text` → `stamp.Update()` (результат проверить) → вернуть число граф.
|
||||
Транзитные RCW не освобождаем точечно (долг v2-2, как везде).
|
||||
|
||||
## Тестирование
|
||||
|
||||
### Unit (`StampFieldsTests`)
|
||||
- `StampFields.ColumnId` — каждое поле → ожидаемый номер графы (2/1/3).
|
||||
- `StampFields.Collect` — пропускает null/пусто/пробелы; при всех пустых даёт пустой список;
|
||||
собирает заданные с обрезкой пробелов.
|
||||
|
||||
### Integration (`DrawingStampTests`)
|
||||
Паттерн: создать чертёж → `FillTitleBlockAsync(...)` → перечитать графы напрямую (helper в сервисе
|
||||
`ReadStampCellAsync(columnId)` для теста ИЛИ проверка через возврат) → `finally CloseAsync` (база
|
||||
`IntegrationTestBase`).
|
||||
1. **Заполнение и чтение**: `designation="ДЕТАЛЬ.001", material="Сталь 45"` → 2 графы; чтение графы
|
||||
2 == «ДЕТАЛЬ.001», графы 3 == «Сталь 45».
|
||||
2. **Пустой ввод**: все поля null → `ArgumentException` (ни одной графы не тронуто).
|
||||
3. **Не-чертёж**: активный документ — деталь → ошибка.
|
||||
|
||||
(Для чтения в тесте — добавить `DrawingService.ReadStampCellAsync(columnId)` — он же подтверждает
|
||||
round-trip; спайк-файл удаляется.)
|
||||
|
||||
## Дальнейшее (вне спека)
|
||||
- Прочие графы (масштаб, разработал, даты, литера), размеры/обозначения на видах (инкремент 3),
|
||||
рамка/формат листа.
|
||||
Reference in New Issue
Block a user