Работа с деталью
Деталь (CADPart) состоит из тел (CADBody) и может также содержать отдельные кривые, точки и PMI. Тело — это оболочка из граней. Замкнутое тело (солид) сохраняется отдельно через ComboSolid, который обеспечивает сшивку: грани, вершины и рёбра оболочки записываются внутрь пары ComboModel → ComboSolid, и при загрузке CAM-система собирает из них единый твёрдотельный солид. Незамкнутые оболочки, а также отдельные кривые и точки в ComboSolid не попадают — они добавляются в дерево модели напрямую через AddEntity (см. ниже).
Зачем сшивать модель. Из CAD-модели приходит вся топология тела — и поверхности, и рёбра, и вершины вместе со связями между ними. ComboSolid переносит эти связи в SGF без потерь: CAM получает ту же связную топологию (B-rep) с понятными «внутри/снаружи» и соседством граней, что была в CAD, и ему не нужно заново искать и угадывать стыки.
Грани добавляются в тело уже после того, как они созданы через StartFace (Грань (обрезанная поверхность)); связи по общим рёбрам и вершинам и задают сшивку.
| Метод | Описание |
|---|---|
StartComboModel(GeomFile: string) |
Начать модель с топологией (будет «сшита»). GeomFile — уникальное имя модели. |
StartComboSolid(ID: string) |
Начать тело внутри ComboModel. |
AddComboSolidVertex(p: TST3DPoint; VertexID: string) |
Добавить вершину тела p под идентификатором VertexID (на него ссылаются рёбра). |
AddComboSolidEdge(EdgeID, CurveID, StartVertexID, EndVertexID, LeftFaceID, RightFaceID: string) |
Ребро тела между вершинами StartVertexID…EndVertexID, разделяющее левую (LeftFaceID) и правую (RightFaceID) грани — именно эта связь задаёт сшивку. CurveID обычно лучше передавать пустым: собственная геометрия топологическому ребру не особо нужна — она и так локализуется стыком левой и правой поверхностей. Если передать CurveID, при сшивке движок попытается вставить геометрию указанной кривой, а она не всегда учитывает, что ребро при сшивке может быть разбито на несколько. |
AddComboSolidFace(FaceID, FaceName: string) |
Добавить ранее созданную (через StartFace) грань. |
CloseComboSolid() |
Закрыть тело. |
CloseComboModel() |
Закрыть модель. |
Уникальные идентификаторы и ассоциативность. Для топологических элементов — грани, ребра и вершины — критично задавать уникальные идентификаторы. По ним элементы ссылаются друг на друга (ребро — на две свои грани и две вершины, и т.д.), и это обеспечивает ассоциативность: после сшивки и последующих пересчётов CAM может однозначно сопоставить операцию с конкретной гранью, а не «потерять» её. Поэтому идентификаторы должны быть уникальными и стабильными.
Сами уникальные идентификаторы обеспечивает CAD-система: у каждого топологического элемента в её модели есть собственный постоянный идентификатор, который сохраняется между перестроениями. Транслятору не нужно генерировать идентификаторы самостоятельно — достаточно взять штатный идентификатор элемента из API CAD-системы и передать его в SGF. Это гарантирует и уникальность, и стабильность: при повторном импорте изменённой модели неизменные элементы сохранят те же идентификаторы, и привязки операций не разрушатся.
Пример: сохранение детали. Метод SavePart, вызываемый при обходе сборки (Работа со сборкой), получает деталь и её мировую матрицу, задаёт текущее преобразование и сохраняет её содержимое — тела, отдельные кривые, точки и PMI. Саму деталь удобно обернуть в папку дерева модели (StartGroupEntity, Работа со сборкой) — здесь это организационная папка, а не сшивка.
void SavePart(CADPart part, TST3DMatrix transform)
{
sgr.SetCurrentTransform2(transform.vT, transform.vX, transform.vY, transform.vZ);
sgr.StartGroupEntity(part.Name);
try
{
SaveBodies(part.Bodies); // замкнутые тела — через ComboSolid, открытые — через AddEntity
SaveCurves(part.Curves); // кривые, см. «Кривые и точки»
SavePoints(part.Points); // точки, см. «Кривые и точки»
SavePMI(part.PMIs); // PMI (резьбы и т.п.), см. «PMI»
}
finally
{
sgr.CloseGroupEntity();
}
}
void SaveBodies(CADBody[] bodies)
{
foreach (CADBody body in bodies)
{
if (body.IsClosed)
SaveClosedShell(body); // замкнутое тело → ComboSolid (сшивка)
else
SaveOpenShell(body); // открытая оболочка → AddEntity
}
}
// Открытая оболочка — не тело: грани добавляются в дерево напрямую через AddEntity, вне ComboModel.
void SaveOpenShell(CADBody body)
{
sgr.StartGroupEntity(body.Name); // папка оболочки в дереве модели
try
{
foreach (CADFace face in body.Faces)
if (SaveTrimmedFace(face)) // создаёт грань под face.Id (см. «Грань»)
sgr.AddEntity(face.Id, face.Name);
}
finally
{
sgr.CloseGroupEntity();
}
}
// Замкнутая оболочка → один ComboSolid внутри ComboModel; сшивку обеспечивает сам ComboSolid.
void SaveClosedShell(CADBody body)
{
sgr.StartComboModel(body.Id);
try
{
sgr.StartComboSolid(body.Id);
try
{
// 1) грани оболочки: сохраняем каждую и добавляем в тело
foreach (CADFace face in body.Faces)
if (SaveTrimmedFace(face))
sgr.AddComboSolidFace(face.Id, face.Name);
// 2) вершины тела (на них по Id ссылаются рёбра); координаты приводим к TST3DPoint
foreach (CADVertex vertex in body.Vertices)
sgr.AddComboSolidVertex(ToPoint(vertex.Point), vertex.Id);
// 3) рёбра тела: какие грани (левая/правая) сходятся на общем ребре — это и есть сшивка
foreach (CADEdge edge in body.Edges)
sgr.AddComboSolidEdge(edge.Id, "",
edge.Start.Id, edge.End.Id,
edge.LeftFaceId, edge.RightFaceId);
}
finally
{
sgr.CloseComboSolid();
}
}
finally
{
sgr.CloseComboModel();
}
}
body.Verticesиbody.Edges— это топология тела: вершины с координатами (Point) и идентификаторами (Id); каждое ребро (CADEdge) хранит концевые вершины (Start,End) и идентификаторы смежных граней (LeftFaceId,RightFaceId). Вершины добавляются раньше рёбер — ребро ссылается на них поId. ДляCurveIDпередаётся пустая строка: как и в импортёре STEP, геометрию ребра несут грани.
Открытые оболочки, кривые и точки. Не всё в детали — замкнутые тела. Незамкнутая оболочка (body.IsClosed == false), отдельные 3D-кривые и точки в ComboSolid не попадают: класть открытую оболочку в ComboSolid бессмысленно — сшивать нечего, замкнутого тела не выйдет, — а с кривыми и точками он не работает вовсе. Такие объекты создают вне StartComboModel и добавляют в дерево модели напрямую вызовом AddEntity(ID, EntityName) (Работа со сборкой) — по тому же ID, под которым объект был создан (см. SaveOpenShell / SaveCurves / SavePoints в примере выше). Размещение, если нужно, задаётся матрицей SetCurrentTransform2 перед AddEntity.
| Метод | Описание |
|---|---|
AddEntity(ID: string; EntityName: string) |
Добавить в дерево модели созданную ранее сущность по её ID (грань, кривую, точку) под именем EntityName. Её локальные координаты умножаются на матрицу, заданную через SetCurrentTransform2. Метод можно вызывать и внутри ComboModel — сущность попадёт в дерево самостоятельным объектом, вне сшивки (в сшивку тела грани добавляет AddComboSolidFace). |