Задать формат (A0–A5/user) и ориентацию (книжная/альбомная) листа чертежа через API7 ILayoutSheet.Format (ISheetFormat). Стандартный формат — размеры авто; user — явные width/height (landscape игнорируется, ориентация из соотношения сторон). - DrawingService.SetSheetFormatAsync + RequireLayoutSheet - PaperFormat (enum + Parse/ToKompas/FromKompas), SheetFormatResult - DrawingValidation.ValidateFormatDimensions (user: >0; стандартный: размеры запрещены) - 19 unit + 7 интеграционных тестов (всего 304 зелёных), сборка Release чистая Спайк подтвердил: дефолт A4 portrait; стандартный формат пересчитывает W/H авто (A3 landscape→420×297); user применяет width/height. Ревью спека pi/glm-5.1 + pi/kimi-k2.6 учтено (FromKompas для дружелюбного имени, запрет размеров у стандартного, sheetNumber>0, landscape игнорируется для user). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
9.9 KiB
Дизайн: формат и ориентация листа чертежа (drawing_set_sheet_format) через API7
Дата: 2026-05-27 Статус: дизайн согласован, спайк проведён, ревью pi/glm-5.1 + pi/kimi-k2.6 учтено — к реализации
Правки по ревью (pi/glm-5.1 + pi/kimi-k2.6)
- A для
userфлагlandscapeигнорируется — ориентация задаётся соотношениемwidth/height(КОМПАС сам выставитVerticalOrientation).VerticalOrientation=!landscapeставим ТОЛЬКО для стандартных форматов (избегаем неоднозначного свопа W/H). Задокументировано в описании инструмента. - B/E
width/heightдля стандартного формата запрещены: валидаторValidateFormatDimensions(дляUser— оба конечны и>0; для стандартного — оба==0, иначеArgumentException«размеры только для user»). - C read-back формата возвращает дружелюбное имя через новый
PaperFormats.FromKompas(ksEnum)→SheetFormatResult.Format="A3"/"User"(симметрия вход/выход), а не COM-имя"ksFormatA3". - D
RequireLayoutSheet(sheetNumber):sheetNumber>0(ArgumentOutOfRangeException) + null-check послеItemByNumber[sheetNumber](InvalidOperationException«нет листа N»); + интеграционный тест. - F read-back
fmt2 = sheet.Formatс null-check. - G
SheetFormatResult—public sealed recordсpublic required … { get; init; }(какDrawingDimensionResult/DrawingViewsResult). - H интеграционные сравнения размеров — через
Assert.InRange(допуск на float). - I члены
PaperFormat— с XML-<summary>(какRoughSignType). - J
FormatMultiplicityоставляем на COM-дефолте (1) — отмечено в реализации. - K (верхняя граница
width/height) — отклонено, в OPEN_QUESTIONS как будущее упрочнение (консистентно сRequirePositiveRadius— верхней границы нет).
Цель
Веха 2D-ЧЕРТЁЖ, инкремент 8. Задать формат (A0–A5 или пользовательский) и ориентацию (книжная/альбомная) листа активного чертежа. Фундамент «правильного» по ГОСТ чертежа (сейчас лист всегда дефолтный A4 книжный).
Спайк: механизм подтверждён вживую (НЕ разучивать)
Спайк (_SpikeSheetFormat, прогнан на реальном КОМПАС, затем удалён): новый чертёж →
doc.LayoutSheets.ItemByNumber[1] (ILayoutSheet) → sheet.Format (ISheetFormat).
ISheetFormat fmt = sheet.Format;
fmt.Format = ksDocumentFormatEnum.ksFormatA3; // A0=0..A5=5, User=6
fmt.VerticalOrientation = false; // true=книжная (portrait), false=альбомная (landscape)
sheet.Update(); // True
// для стандартного формата FormatWidth/Height пересчитываются АВТО (A3 landscape → 420×297)
Проверено:
- Дефолт нового чертежа:
ksFormatA4,VerticalOrientation=true, 210×297,FormatMultiplicity=1. - A3 landscape:
Update=True, read-backFormat=ksFormatA3,Vertical=False, W=420, H=297 (авто) — для стандартных форматов размеры не задаём, их даёт enum+ориентация. - A4 portrait: 210×297.
- Пользовательский:
Format=ksFormatUser+FormatWidth=500+FormatHeight=300+Update→ применён.
ksDocumentFormatEnum: ksFormatA0=0, A1=1, A2=2, A3=3, A4=4, A5=5, ksFormatUser=6.
ISheetFormat: Format (enum), VerticalOrientation (bool), FormatWidth/FormatHeight (double, мм),
FormatMultiplicity (int).
MCP-инструмент
| Инструмент | Параметры | Поведение |
|---|---|---|
drawing_set_sheet_format |
format="A4" (A0|A1|A2|A3|A4|A5|user), landscape=false (false=книжная), width=0,height=0 (ТОЛЬКО для user, мм, >0), sheetNumber=1 |
Задать формат и ориентацию листа sheetNumber активного чертежа. Стандартный формат — размеры авто (по enum+ориентации), width/height для него запрещены (должны быть 0). user — задать width/height (>0); для user флаг landscape ИГНОРИРУЕТСЯ (ориентация — из соотношения сторон). Возвращает итоговый формат («A3»/«User»), ширину, высоту, ориентацию (read-back). |
Архитектура
В DrawingService (namespace Kompas.Mcp.Core.Drawings).
SetSheetFormatAsync(PaperFormat format, bool landscape, double width, double height, int sheetNumber, ct)→SheetFormatResult.- Helper
RequireLayoutSheet(sheetNumber)→ILayoutSheet:sheetNumber>0(ArgumentOutOfRangeException) → нет активного чертежа /LayoutSheetsnull /ItemByNumber[sheetNumber]null («нет листа N») — раздельная диагностика, рядом сRequireActiveStamp. - Новый файл
src/Kompas.Mcp.Core/Drawings/PaperFormat.cs:enum PaperFormat {A0,A1,A2,A3,A4,A5,User}(каждый член с XML-<summary>) +PaperFormats.Parse(string)/ToKompas(PaperFormat)→ksDocumentFormatEnum/FromKompas(ksDocumentFormatEnum)→PaperFormat(для read-back дружелюбного имени), по образцуRoughSignTypes. - Новый файл
src/Kompas.Mcp.Core/Drawings/SheetFormatResult.cs:public sealed record SheetFormatResult { public required string Format; public required double Width; public required double Height; public required bool Landscape; }(стильDrawingDimensionResult).
Реализация
SetSheetFormatCore: DrawingValidation.ValidateFormatDimensions(format, width, height) →
PaperFormats.ToKompas(format) → RequireLayoutSheet(sheetNumber) → fmt = sheet.Format (null-check) →
fmt.Format = ksEnum; if format==User: fmt.FormatWidth=width, fmt.FormatHeight=height (ориентацию
НЕ трогаем — задаётся W/H); else: fmt.VerticalOrientation = !landscape (размеры авто) → sheet.Update()
(FALSE → ошибка; объект уровня листа, перезапись идемпотентна — отката Delete нет) → read-back
fmt2 = sheet.Format (null-check) → SheetFormatResult { Format = PaperFormats.FromKompas(fmt2.Format) .ToString(), Width = fmt2.FormatWidth, Height = fmt2.FormatHeight, Landscape = !fmt2.VerticalOrientation }.
FormatMultiplicity оставляем на COM-дефолте (1) — не читаем и не задаём. RCW точечно не освобождаем
(консистентно; долг v2-2).
Валидация (чистые static, unit)
PaperFormats.Parse—A0..A5/user(+ регистр/пробелы); неизвестное →ArgumentException; null →ArgumentNullException.- Новый
DrawingValidation.ValidateFormatDimensions(PaperFormat format, double width, double height): дляUser—widthиheightоба конечны и> 0(иначеArgumentOutOfRangeException); для стандартного —width==0 && height==0(иначеArgumentException«размеры задаются только для format=user»). PaperFormats.ToKompas/FromKompas(↔ksDocumentFormatEnum) НЕ покрываем unit — граница проекта (тест не ссылается наKompas6Constants), как у прочих enum-маппингов; покрываются интеграцией.
Тестирование
Unit (PaperFormatsTests, DrawingValidationTests)
PaperFormats.Parse:A4/a3/ A2 /a0/a5/user→ enum; неизвестное →ArgumentException; null →ArgumentNullException.ValidateFormatDimensions:User: бросает на (0,300)/(500,0)/(−1,300)/(NaN,300)/(500,∞); пропускает (500,300).- стандартный (
A4): бросает на (500,0)/(0,300)/(500,300); пропускает (0,0).
Integration (DrawingSheetFormatTests; сравнения размеров — Assert.InRange)
- A3 landscape:
format=A3, landscape=true→Format=="A3",Width≈420,Height≈297,Landscape==true. - A4 portrait (
landscape=false): →Format=="A4",Width≈210,Height≈297,Landscape==false. - User 500×300:
format=user, width=500, height=300→Format=="User",Width≈500,Height≈300. - User без размеров (
width=0) →ArgumentOutOfRangeException(до COM). - Размеры для стандартного (
format=A3, width=400) →ArgumentException(до COM). - Несуществующий лист (
sheetNumber=99) →InvalidOperationException. - Активный документ не чертёж (деталь) → понятная ошибка.
Дальнейшее (вне спека)
- Рамка/основная надпись по конкретному ГОСТ-стилю оформления (
LayoutLibraryFileName/LayoutStyleNumber), несколько листов (LayoutSheets.Add); привязка к дуге, угловой/шероховатость; выноски/базы/допуски формы.