docs: переписан handoff набело под продолжение (веха 2D-чертёж, инкремент 5)
Убраны наслоения старой сессии (фокус «начни со сборок», дубли состояния, стартовая инструкция про IParts7). Актуально: 76 инструментов / 218 тестов; сборки завершены, чертёж 4 инкремента; следующий — радиальный/угловой размер (A) или рамка/формат (B). Процесс, ловушки, паттерн теста, отрицательный результат сохранены и сжаты. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,173 +4,113 @@
|
||||
|
||||
---
|
||||
|
||||
Продолжаем разработку MCP-сервера КОМПАС-3D (kompas3d-mcp). Работай автономно,
|
||||
с коммитами и пушами в `main`; используй Codex для ревью каждой реализованной фичи.
|
||||
Продолжаем разработку MCP-сервера КОМПАС-3D (kompas3d-mcp). Работай автономно, с коммитами и
|
||||
пушами в `main`; используй Codex для ревью КАЖДОЙ реализованной фичи (спека и реализации).
|
||||
КОМПАС-3D должен быть запущен (нужен для интеграционных тестов).
|
||||
|
||||
**Фокус этой сессии — два новых крупных класса: СБОРКИ и 2D-ЧЕРТЁЖ.** До сих пор сделана
|
||||
только геометрия ДЕТАЛИ (она близка к насыщению). Сборки и чертёж — самый ценный
|
||||
нереализованный функционал. Начни со СБОРОК (тестируются объёмом/габаритом/числом компонентов),
|
||||
затем ЧЕРТЁЖ.
|
||||
**Фокус — продолжать ВЕХУ 2D-ЧЕРТЁЖ** (самый ценный развивающийся класс). Деталь и сборки близки
|
||||
к насыщению. Следующий инкремент — **радиальный/угловой размер** ИЛИ **рамка/формат листа** (см.
|
||||
«Следующий инкремент»).
|
||||
|
||||
## Текущее состояние (main, синхронизирован с origin)
|
||||
- 76 MCP-инструментов, 218 тестов зелёных (141 unit + 77 integration).
|
||||
- **ВЕХА 2D-ЧЕРТЁЖ: 4 инкремента готовы.** (1) `drawing_create_standard_views` (возвращает
|
||||
`ViewNumbers`). (2) `drawing_fill_title_block` — основная надпись. (3) `drawing_add_linear_dimension`
|
||||
— линейный размер. (4) `drawing_add_diametral_dimension(xc,yc,radius,angle°,viewNumber)` —
|
||||
диаметральный размер (Ø) через `(ISymbols2DContainer)view.DiametralDimensions.Add` → `Xc/Yc/Radius/
|
||||
Angle(рад)` → `Update` → `NominalValue`=2R. Общий хелпер `RequireSymbols2DContainer(viewNumber)` для
|
||||
всех размеров. Размеры — в `ISymbols2DContainer` (QI от вида), НЕ в `IView.ObjectCount`. Координаты —
|
||||
локальная СК вида. Память: `kompas-drawing-api7`. **СЛЕДУЮЩЕЕ — инкремент 5: радиальный
|
||||
(`RadialDimensions`, есть ветви) / угловой (`AngleDimensions`) размер** (те же `ISymbols2DContainer`;
|
||||
спайк) ИЛИ рамка/формат листа (`ILayoutSheet.Format`/`SheetFormat` — проще, без спайка).
|
||||
- **ВЕХА 2 (2D-ЧЕРТЁЖ) НАЧАТА:** `drawing_create_standard_views(partFilePath, scale, x, y)` СДЕЛАН
|
||||
(инкремент 1) — стандартные ассоциативные виды (спереди/сверху/слева) детали/сборки на активном
|
||||
чертеже (API7, `DrawingService`, namespace `Kompas.Mcp.Core.Drawings`). Workflow:
|
||||
`doc2d.ViewsAndLayersManager.Views.AddStandartViews(path, "#Спереди", object[]{1,3,5}, x, y, scale,
|
||||
20, 20)`. Эмпирика: `object[]`→SAFEARRAY VT_I4 ОК; новый чертёж стартует с Count=1 (системный вид),
|
||||
3 проекции → Count=4; ObjectCount>0 сразу (rebuild не нужен); проверка `created==3` + непустота по
|
||||
новым видам (разница `IView.Number`) + откат `IView.Delete`. Спек:
|
||||
`2026-05-27-drawing-standard-views-design.md`. **СЛЕДУЮЩЕЕ — инкремент 2 чертежа: оформление
|
||||
(размеры/обозначения на видах, рамка, основная надпись).**
|
||||
- **СБОРКИ: инкременты 1 и 2 СДЕЛАНЫ** (API7, `AssemblyService`, namespace `Kompas.Mcp.Core.Assemblies`):
|
||||
- `assembly_add_component(filePath, x, y, z)` — вставка детали/подсборки из `.m3d`/`.a3d` с позицией.
|
||||
Workflow: `IParts7.AddFromFile(path,true,true)` → `part.Placement.SetOrigin(x,y,z)` →
|
||||
`UpdatePlacement(true)` → `top.RebuildModel(true)`. Эмпирика: `UpdatePlacement`=FALSE для вручную
|
||||
позиционируемого компонента — НЕ ошибка; позицию применяет SetOrigin+RebuildModel; разфиксация
|
||||
первого компонента НЕ нужна.
|
||||
- `assembly_add_mate(mateType, x1,y1,z1, x2,y2,z2, value)` — сопряжение граней двух компонентов.
|
||||
Workflow: `(IMateConstraints3D)top.MateConstraints` → `Add(MateConstraintType)` → `BaseObject1/2`
|
||||
(грани через `top.FindObjectsByPoint(x,y,z,FirstLevel=false)`) → `ParamValue` (distance) →
|
||||
`Update()` → `RebuildModel(true)` → проверка `mate.Valid` (false→ошибка+откат). Типы: `coincidence`,
|
||||
`distance` (value>0). Решатель может двигать любой компонент → тест по ширине габарита.
|
||||
- Спеки: `2026-05-27-assembly-add-component-design.md`, `2026-05-27-assembly-add-mate-design.md`.
|
||||
- **Тест-инфра:** `IntegrationTestBase` (per-test `DocumentService.CloseAllAsync`) — все интеграционные
|
||||
классы наследуют его.
|
||||
- **СЛЕДУЮЩЕЕ — инкремент 3 (по желанию) или ВЕХА 2 (2D-ЧЕРТЁЖ).** См. ниже.
|
||||
- Деталь: эскизы (пакет A), формообразующие (extrude/revolve/fillet/chamfer/shell/rib/sweep/loft),
|
||||
массивы и зеркало (пакет C), уклон (`draft`), все типы отверстий (`hole`/`_counterbore`/
|
||||
`_countersink`/`_conic`, API7), переменные (`create/set/delete_variable`), STEP import/export,
|
||||
прямое редактирование B-rep (`move_face`/`split_solid_by_plane`/`move_body`/`boolean_union`),
|
||||
структурный осмотр (`describe_model`/`list_*`/`measure`).
|
||||
- **`list_components` УЖЕ ЕСТЬ** (читает сборку: `IKompasDocument3D.TopPart → IPart7.Parts (IParts7)`).
|
||||
- Документы: `DocumentService` уже умеет создавать `Assembly` и `Drawing`
|
||||
(`KompasDocumentType.Assembly/Drawing` → `DocumentTypeEnum.ksDocumentAssembly/ksDocumentDrawing`).
|
||||
Есть `document_save_as` (сохранить деталь в файл — нужно, чтобы вставить её в сборку/на чертёж).
|
||||
- API7-сервисы существуют как образец: `HoleService`, `FaceEditService` (паттерн: `(IXxx)part`
|
||||
через COM-QI, операции на STA-потоке `KompasDispatcher`).
|
||||
- Прочитай память: `kompas-step-and-assembly-api` (обход сборки, извлечение компонента, STEP),
|
||||
`kompas-hole-api7` (паттерн API7-сервиса), `kompas-parametric-sketch-findings` (тупик — не повторять).
|
||||
## Текущее состояние (main = origin)
|
||||
|
||||
**76 MCP-инструментов, 218 тестов зелёных (141 unit + 77 integration).** Сборка Release чистая.
|
||||
|
||||
Три класса функционала:
|
||||
- **ДЕТАЛЬ** (насыщена): эскизы (полный набор 2D-примитивов), формообразующие (extrude/revolve/
|
||||
fillet/chamfer/shell/rib/sweep/loft), массивы и зеркало, уклон (`draft`), все типы отверстий
|
||||
(`hole`/`_counterbore`/`_countersink`/`_conic`), переменные (`create/set/delete_variable`),
|
||||
STEP import/export, прямое редактирование B-rep (`move_face`/`split_solid_by_plane`/`move_body`/
|
||||
`boolean_union`), структурный осмотр (`describe_model`/`list_*`/`measure`).
|
||||
- **СБОРКИ — завершены** (`AssemblyService`, namespace `Kompas.Mcp.Core.Assemblies`, API7):
|
||||
- `assembly_add_component(filePath, x, y, z)` — вставка детали/подсборки `.m3d`/`.a3d` с позицией.
|
||||
`IParts7.AddFromFile(path,true,true)` → `part.Placement.SetOrigin` → `UpdatePlacement(true)` →
|
||||
`top.RebuildModel(true)`.
|
||||
- `assembly_add_mate(mateType, x1,y1,z1, x2,y2,z2, value)` — сопряжение граней двух компонентов
|
||||
(`coincidence`/`distance`). `(IMateConstraints3D)top.MateConstraints.Add(...)` → `BaseObject1/2`
|
||||
(грани через `top.FindObjectsByPoint(x,y,z,FirstLevel=false)`) → `Update` → проверка `mate.Valid`.
|
||||
- `list_components` (чтение сборки) был и раньше.
|
||||
- **2D-ЧЕРТЁЖ — 4 инкремента готовы** (`DrawingService`, namespace `Kompas.Mcp.Core.Drawings`, API7):
|
||||
1. `drawing_create_standard_views(partFilePath, scale, x, y)` — стандартные виды (спереди/сверху/
|
||||
слева) сохранённой модели; возвращает `ViewNumbers` (для адресации видов при простановке размеров).
|
||||
2. `drawing_fill_title_block(designation?, name?, material?)` — основная надпись (графы 2/1/3).
|
||||
3. `drawing_add_linear_dimension(x1,y1,x2,y2,x3,y3, orientation, viewNumber)` — линейный размер
|
||||
(horizontal/vertical/parallel).
|
||||
4. `drawing_add_diametral_dimension(xc,yc,radius,angle°, viewNumber)` — диаметральный размер (Ø=2R).
|
||||
|
||||
Спеки всех фич — в `docs/superpowers/specs/2026-05-27-*.md`. Память (читать перед работой):
|
||||
`kompas-drawing-api7` (чертёж: виды, штамп, размеры — все приёмы), `kompas-assembly-insert-api7`
|
||||
(сборки: вставка + сопряжения), `kompas-step-and-assembly-api`, `kompas-hole-api7` (паттерн API7-
|
||||
сервиса), `kompas-parametric-sketch-findings` (тупик — не повторять).
|
||||
|
||||
## Следующий инкремент (на выбор; оба расписаны)
|
||||
|
||||
### Вариант A — радиальный / угловой размер (продолжает размеры, ценнее)
|
||||
Тот же контейнер, что у линейного/диаметрального — `ISymbols2DContainer` (QI от вида); есть готовый
|
||||
хелпер `RequireSymbols2DContainer(viewNumber)` в `DrawingService`. Точки входа (рефлексия подтвердила):
|
||||
- Радиальный: `symbols.RadialDimensions` (`IRadialDimensions.Add()` → `IRadialDimension`):
|
||||
`Xc,Yc,Radius,Angle` + `DimensionType` + ветви (`AddBranch`/`AddBranchByArcParam`/`ShelfX,Y`).
|
||||
- Угловой: `symbols.AngleDimensions` (`IAngleDimension`) — задание через две прямые/точки.
|
||||
**Сделай спайк ДО спека** (у радиального — `DimensionType`/ветви; у углового — что измеряет и как
|
||||
задаются стороны угла; что в `NominalValue`). Значение читается `((IDimensionText)dim).NominalValue`.
|
||||
Тест — `*Dimensions.Count` целевого вида вырос + значение (как у диаметрального).
|
||||
|
||||
### Вариант B — рамка / формат листа (проще, без спайка)
|
||||
`ILayoutSheet.Format` (`SheetFormat`) — задать формат листа (A4/A3) и ориентацию. Детерминированно
|
||||
тестируется (задать формат → прочитать). `doc2d.LayoutSheets.ItemByNumber[1]` → `.Format`.
|
||||
Менее ценно, чем размеры, но низкий риск.
|
||||
|
||||
## ОТРИЦАТЕЛЬНЫЙ результат (не повторять)
|
||||
- **Параметрические эскизы (переменная двигает геометрию) — НЕДОСТИЖИМЫ через COM-API.**
|
||||
`ksCDimWithVariable` (`IDrawingObject1.NewConstraint`) `Create()`=FALSE из внешней автоматизации;
|
||||
`ksCFixedLenght` игнорирует `Expression`-ссылку на переменную. См.
|
||||
`docs/superpowers/specs/2026-05-27-parametric-sketch-findings.md`. НЕ трогать повторно.
|
||||
**Параметрические эскизы (переменная двигает геометрию) — НЕДОСТИЖИМЫ через COM-API.**
|
||||
`ksCDimWithVariable` (`IDrawingObject1.NewConstraint`) `Create()`=FALSE из внешней автоматизации;
|
||||
`ksCFixedLenght` игнорирует `Expression`-ссылку. См.
|
||||
`docs/superpowers/specs/2026-05-27-parametric-sketch-findings.md`. НЕ трогать.
|
||||
|
||||
## Веха 1 — СБОРКИ (начать отсюда; новый `AssemblyService` на API7)
|
||||
|
||||
Точки входа (проверено рефлексией interop, всё есть):
|
||||
- Создать сборку: `DocumentService.CreateAsync(KompasDocumentType.Assembly)`.
|
||||
- `IKompasDocument3D.TopPart → IPart7` → `IPart7.Parts` (это `IParts7`).
|
||||
- **Вставка компонента из файла:** `IParts7.AddFromFile(string fileName, bool, bool)` или
|
||||
`AddFromFileWithParam(string fileName, IPlacement3D placement, IInsertPartParameters prm, bool)`.
|
||||
Позиция/ориентация — `IPlacement3D` (есть `IPlacement3DManipulator`).
|
||||
- **Сопряжения (mates):** `IMateConstraints3D`/`IMateConstraint3D` + типы `IMate3DByAngle`,
|
||||
`IMate3DByTangent`, `IMate3DSymmetry`, и др. (совпадение/параллельность/расстояние/угол).
|
||||
|
||||
Рекомендуемые инкременты (по одному, до зелёного → merge):
|
||||
1. ✅ **СДЕЛАНО:** `assembly_add_component(filePath, x, y, z)` — вставка детали из файла в сборку.
|
||||
2. ✅ **СДЕЛАНО:** `assembly_add_mate` — сопряжения coincidence/distance (см. «Текущее состояние»).
|
||||
Расширения (будущее): прочие типы (parallel/perpendicular/concentric/angle/tangency — добавить с
|
||||
геометрической проверкой, concentric требует цилиндрических граней), параметр `Alignment`
|
||||
(`ksMCAlignmentCooriented`/`Opposite`/`Closest`). Для concentric/angle проверять тип грани.
|
||||
3. **(по желанию)** Перемещение/массив/фиксация компонентов. ИЛИ сразу переходить к ВЕХЕ 2 (чертёж) —
|
||||
она самый ценный нереализованный класс после сборок.
|
||||
|
||||
Проверенный API сопряжений (для расширений): `(IMateConstraints3D)top.MateConstraints` →
|
||||
`Add(MateConstraintType)` → `IMateConstraint3D` (`BaseObject1`/`BaseObject2` = IModelObject граней;
|
||||
`ParamValue` для distance/angle; `Alignment`) → `Update()` → `RebuildModel(true)`. Типы:
|
||||
`mc_Coincidence=0`, `mc_Parallel=1`, `mc_Perpendicular=2`, `mc_Tangency=3`, `mc_Concentric=4`,
|
||||
`mc_Distance=5`, `mc_Angle=6`, `mc_Symmetric=11`. Грани компонентов — `top.FindObjectsByPoint(x,y,z,
|
||||
FirstLevel=false)` (мировые координаты с учётом placement). Память: `kompas-assembly-insert-api7`.
|
||||
|
||||
Тонкости: компоненту нужен сохранённый файл-источник (сначала сохрани деталь). Уточни через
|
||||
`kompas-sdk-research` точные сигнатуры `AddFromFile`/`AddFromFileWithParam`, что такое
|
||||
`IInsertPartParameters` и как задать `IPlacement3D` (СК вставки).
|
||||
|
||||
## Веха 2 — 2D-ЧЕРТЁЖ (после сборок; новый `DrawingService` на API7)
|
||||
|
||||
Точки входа (проверено):
|
||||
- Создать чертёж: `DocumentService.CreateAsync(KompasDocumentType.Drawing)`.
|
||||
- `IKompasDocument2D.ViewsAndLayersManager.Views` (это `IViews`).
|
||||
- **Стандартные ассоциативные виды детали из файла:**
|
||||
`IViews.AddStandartViews(string FileName, string ProjectionName, object ProjectionsTypes,
|
||||
double X, double Y, double Scale, double DX, double DY)` — создаёт виды (спереди/сверху/слева)
|
||||
по сохранённой модели.
|
||||
- Отдельный вид: `IViews.Add(LtViewType)`; геометрия/размеры вида — через `IDrawingContainer`
|
||||
вида (`LineSegments`/`Circles`/… — как в разведке параметрики).
|
||||
|
||||
Рекомендуемые инкременты:
|
||||
1. ✅ **СДЕЛАНО:** `drawing_create_standard_views(partFilePath, scale, x, y)` — стандартные виды
|
||||
(спереди/сверху/слева) детали/сборки на чертеже. `AddStandartViews(path, "#Спереди",
|
||||
object[]{1,3,5}, x, y, scale, 20, 20)`; проверено `created==3` + непустота. Память:
|
||||
`kompas-drawing-api7`.
|
||||
2. ✅ **СДЕЛАНО:** `drawing_fill_title_block(designation?, name?, material?)` — основная надпись.
|
||||
3. ✅ **СДЕЛАНО:** `drawing_add_linear_dimension` — линейный размер на виде (`ISymbols2DContainer.
|
||||
LineDimensions`). Размеры — в `ISymbols2DContainer` (QI от `IView`), НЕ в `IDrawingContainer`/
|
||||
`IView.ObjectCount`. Координаты — локальная СК вида. Память `kompas-drawing-api7`.
|
||||
4. ✅ **СДЕЛАНО:** `drawing_add_diametral_dimension(xc,yc,radius,angle°,viewNumber)` — диаметральный
|
||||
размер (Ø). `(ISymbols2DContainer)view.DiametralDimensions.Add` → `Xc/Yc/Radius/Angle(рад)`;
|
||||
`NominalValue`=2R. Общий хелпер `RequireSymbols2DContainer(viewNumber)`. Память `kompas-drawing-api7`.
|
||||
5. **СЛЕДУЮЩЕЕ:** радиальный (`RadialDimensions`, `IRadialDimension` — Xc/Yc/Radius/Angle + ветви
|
||||
`AddBranch`/`AddBranchByArcParam`) / угловой (`AngleDimensions`, `IAngleDimension`) размер. Тот же
|
||||
`ISymbols2DContainer` (переиспользуй `RequireSymbols2DContainer`). **Спайк ДО спека** (у радиального
|
||||
— `DimensionType`/ветви; у углового — задание двух прямых/точек). Тест — `*Dimensions.Count` вырос,
|
||||
значение. Альтернатива (проще, без спайка): рамка/формат листа (`ILayoutSheet.Format`→`SheetFormat`).
|
||||
|
||||
Тонкости: чертёж проверяется не объёмом, а числом видов/объектов; ассоциативные виды требуют
|
||||
сохранённого `.m3d`/`.a3d`-файла. Коды видов `ksRelativeProjectionTypeEnum`: `ksPtFront=1`,
|
||||
`ksPtUp=3`, `ksPtLeft=5`, `ksPtIsoXYZ=7` и т.д.
|
||||
|
||||
## Процесс на каждую операцию (отлажен в прошлых сессиях)
|
||||
Сборки/чертёж — это НЕ `PartModeler` (он API5-деталь). Заводи НОВЫЕ сервисы (`AssemblyService`,
|
||||
`DrawingService`) и НОВЫЕ классы инструментов (`AssemblyTools`, `DrawingTools`); регистрируй
|
||||
сервисы в DI (`Program.cs`, `AddSingleton`). Образец API7-сервиса — `HoleService`.
|
||||
|
||||
1. Рефлексия interop — подтверди сигнатуры (`AddFromFile`, `AddStandartViews`, mate-типы):
|
||||
## Процесс на каждый инкремент (отлажен — 6 фич за прошлую сессию)
|
||||
1. **Рефлексия interop** — подтверди сигнатуры (имена/типы могут отличаться от справки):
|
||||
```powershell
|
||||
$a7=[Reflection.Assembly]::LoadFrom((Resolve-Path 'libs/kompas-interop/KompasAPI7.dll'))
|
||||
# члены IParts7 / IMateConstraints3D / IViews — имена методов, типы параметров
|
||||
$a7=[Reflection.Assembly]::LoadFrom((Resolve-Path 'libs/kompas-interop/KompasAPI7.dll').Path)
|
||||
($a7.GetTypes()|?{$_.Name -eq 'IRadialDimension'}).GetProperties()|%{ "$($_.PropertyType.Name) $($_.Name)" }
|
||||
```
|
||||
Если высокая неопределённость (как было с параметрикой) — сделай spike ДО спека.
|
||||
2. Семантику API уточняй через навык `kompas-sdk-research` (субагент Sonnet), не рой справку сам.
|
||||
3. Краткий спек в `docs/superpowers/specs/` → коммит → ОТДАЙ НА РЕВЬЮ Codex (`codex:rescue`,
|
||||
`--fresh` для новой темы) → внеси обоснованные правки (оценивай технически, не слепо).
|
||||
4. Реализация TDD: метод в новом сервисе (паттерн API7 как в `HoleService`), инструмент в новом
|
||||
классе `*Tools.cs`, интеграционный тест в новом `*Tests.cs` (Collection `KompasCollection`).
|
||||
5. Codex-ревью реализации (`--resume` того же треда) → правки.
|
||||
6. Документация через навык `docs-delegate` (Sonnet обновит README/CLAUDE/ARCHITECTURE/
|
||||
presentation.html). **ВАЖНО:** число тестов задавай субагенту ТОЧНО (по `dotnet test` раннеру,
|
||||
НЕ по числу `[Fact]`/`[Theory]` — теории разворачиваются в несколько кейсов).
|
||||
7. `merge --no-ff` в main, удали ветку, `push origin main`. Обнови этот handoff.
|
||||
Enum'ы — в `Kompas6Constants`/`Kompas6Constants3D`. **Тестовый проект НЕ ссылается на эти
|
||||
constants-сборки** → COM-enum в публичном API сервиса оборачивай СВОИМ enum (как `MateType`/
|
||||
`DimensionOrientation`), unit-тесть по `(int)`-коду нельзя — проверяй только свой enum/Parse.
|
||||
2. **Семантику API** уточняй навыком `kompas-sdk-research` (субагент Sonnet), не рой справку сам.
|
||||
3. **При неопределённости (привязка к геометрии, координаты, единицы) — СПАЙК ДО СПЕКА**: черновой
|
||||
метод сервиса + временный `*SpikeTests.cs`, прогнать, зафиксировать находку. (Так делалось для
|
||||
сопряжений, видов, штампа, линейного и диаметрального размеров — всегда окупалось.)
|
||||
4. **Краткий спек** в `docs/superpowers/specs/` → коммит → **ревью Codex** (`codex:rescue --fresh` для
|
||||
новой темы) → внеси обоснованные правки (оценивай технически, отклоняй неуместное с обоснованием —
|
||||
напр. точечный release RCW отклоняется по конвенции v2-2).
|
||||
5. **TDD**: метод в `DrawingService` (или новом сервисе), инструмент в `*Tools.cs`, чистые валидаторы
|
||||
в static (unit), интеграционный тест в `*Tests.cs` (наследует `IntegrationTestBase`, Collection
|
||||
`KompasCollection`). Спайк-методы/тесты УДАЛИ, промотировав в финальный код.
|
||||
6. **Ревью Codex реализации** (`--resume` того же треда) → правки.
|
||||
7. **Документация** навыком `docs-delegate` (Sonnet: README/CLAUDE/ARCHITECTURE/OPEN_QUESTIONS/
|
||||
presentation.html). **Число тестов задавай ТОЧНО по `dotnet test` раннеру** (НЕ по числу
|
||||
`[Fact]`/`[Theory]` — теории разворачиваются в несколько кейсов).
|
||||
8. `merge --no-ff` в main → удали ветку → `push origin main` → обнови этот handoff + память.
|
||||
|
||||
## Паттерн интеграционного теста
|
||||
`CreateAsync(...)` → построить/вставить → операция → `RebuildAsync`/`Update` →
|
||||
проверить результат; `finally CloseAsync`. Для СБОРКИ — объём/габарит сборки или `list_components`
|
||||
(число компонентов). Для ЧЕРТЕЖА — число видов (`Views.Count`)/объектов (объёмом не проверить).
|
||||
Артефакты (сохранённые `.m3d`) — в gitignored `.scratch/`.
|
||||
`CreateAsync(...)` → построить/вставить → операция → проверить → `finally CloseAsync`.
|
||||
- ДЕТАЛЬ — объём/габарит/МЦХ. СБОРКА — габарит/`list_components`.
|
||||
- ЧЕРТЁЖ — числом, не объёмом: **виды** — `Views.Count`/`ObjectCount`; **размеры** — НЕ в
|
||||
`IView.ObjectCount` (они в `ISymbols2DContainer`) → считать `ISymbols2DContainer.*Dimensions.Count`
|
||||
целевого вида; **значение размера** — `((IDimensionText)dim).NominalValue`.
|
||||
- Артефакты (`.m3d` детали для видов/сборок) — в gitignored `.scratch/` (`TestPaths.NewFile`).
|
||||
- Возможен ТРАНЗИЕНТНЫЙ сбой пакета сразу после большого прогона (нестабильность КОМПАС) — перезапусти.
|
||||
|
||||
## Ключевые ловушки (проверено)
|
||||
- Все COM-вызовы — на STA-потоке (`KompasDispatcher.InvokeAsync`). Контейнеры API7 берём
|
||||
COM-QI: `(IModelContainer)part`, `(IParts7)part.Parts` и т.п.
|
||||
- Выбор грани/ребра — по стабильному индексу из `list_faces`/`list_edges`; для сопряжений
|
||||
объекты компонентов искать через их `IPart7`/`FindObjectsByPoint`.
|
||||
- Углы — в градусах. Валидацию — в чистые static (unit-тестируемо), проверяй `double.IsFinite`.
|
||||
- Все COM-вызовы — на STA-потоке (`KompasDispatcher.InvokeAsync`). Контейнеры берём COM-QI:
|
||||
`(IModelContainer)part`, `(ISymbols2DContainer)view`, `(IMateConstraints3D)top.MateConstraints`.
|
||||
- **Размеры чертежа** — в `ISymbols2DContainer` (QI ОТ КОНКРЕТНОГО `IView`), координаты — в ЛОКАЛЬНОЙ
|
||||
СК вида (= координаты модели на плоскости вида при 1:1). `AutoNominalValue=true` авто-измеряет.
|
||||
- Углы 2D-размеров — в РАДИАНАХ в API (инструмент экспонирует градусы → `DimensionAngles.ToRadians`).
|
||||
- Валидацию — в чистые static (unit-тестируемо), проверяй `double.IsFinite`. Проверяй результат
|
||||
`Update()`/`RebuildModel()`; при неуспехе после `Add()` — откат `.Delete()`.
|
||||
- НЕ освобождай транзитные RCW точечно — общий отложенный долг (OPEN_QUESTIONS v2-2).
|
||||
- Команды: `dotnet build -c Release`; `dotnet test --filter "Category=Unit"`;
|
||||
`dotnet test --filter "Category=Integration"` (нужен запущенный КОМПАС).
|
||||
|
||||
Начни с рефлексии interop `IParts7` (вставка компонента) + `kompas-sdk-research` по
|
||||
`AddFromFile`/`AddFromFileWithParam`/`IPlacement3D`, затем первый инкремент —
|
||||
`assembly_add_component` (вставка детали из файла в сборку).
|
||||
Начни с выбора варианта (A — радиальный/угловой размер, рекомендуется; B — рамка/формат листа),
|
||||
затем рефлексия interop соответствующих интерфейсов + (для A) спайк до спека.
|
||||
|
||||
Reference in New Issue
Block a user