Кластеризация геометрической сцены, моделирование сборок
В основе геометрической модели системы ограничений лежит принцип иерархичности. Этот принцип находит свое выражение, в том что геометрические объекты могут группироваться в виде геометрически-жестких множеств, называемых кластерами (Кластер). Кластер отвечает такой абстракции геометрической модели САПР, как твердое тело или подсборка. Кластеры могут образовывать древо-подобные иерархии, зависимости в которых можно проследить с помощью функции
GCM_geom GCM_Parent(GCM_system gSys, GCM_geom subGeom)
которая вернет для объекта subGeom, зарегистрированного в системе ограничений gSys, кластер, которому принадлежит subGeom. Если функция вернет нулевой дескриптор GCM_NULL, это означает что запрашиваемый объект не содержится ни в одном кластере и был зарегистрирован в системе ограничений вызовом GCM_AddGeom. Геометрические объекты, подчиненные какому-либо кластеру, получаются с помощью другого вызова, GCM_SubGeom (подробности см. Добавление и удаление геометрических объектов).
Принадлежность ограничений кластерам. Геометрические ограничения и размеры также, как и геометрические объекты имеют свое место в иерархии кластеров. Уровень, на котором будет вычисляться то или иное ограничение, не требуется указывать явно, он определяется в зависимости от того, каким кластерам принадлежат его аргументы. При добавлении ограничения решатель выбирает минимальную по размеру подсистему, включающую все его аргументы. Другими словами, уровень геометрического ограничения определяется минимальным поддеревом иерархии, включающим все его аргументы. На рис. 1 изображен пример сборки, где имеются два размера, которые будут вычисляться на разных уровнях иерархии. Сборка состоит из двух параллелепипедов, представленных кластерами Cluster1 и Cluster2, каждый из которых объединяет плоскости, ребра и вершины каждого из параллелепипедов.
{width=»50%»}
Рис. 1
Таким образом, вся иерархия состоит из трех подсистем ограничений, вычисляемых отдельно друг от друга снизу вверх (см. рис. 2). В сборке есть два размера: D1 – расстояние, заданное между плоскостями Plane1 и Plane2, принадлежащими одному и тому же кластеру Cluster1, D2 – расстояние, заданное между плоскостями Plane2 и Plane3, принадлежащими разным кластерам (Cluster1, Cluster2). В этому случае размер D1 в иерархии кластеров будет вычисляться в кластере Cluster1, а размер D2 будет вычисляться после D2 вместе со всеми ограничениями корневого уровня сборки. Так результаты вычисления D1 будут определять габариты только одного параллелепипеда, в то время, как размер D2 будет влиять на позиционирование двух параллелепипедов относительно друг друга.
{width=»50%»}
Рис. 2
Итак уровень ограничения определяется минимальным поддеревом кластеров, охватывающим все его аргументы. В частности, если аргументы ограничения лежат в одном и том же кластере, то ограничение будет принадлежать тому же кластеру. Если аргументы ограничения принадлежат разным кластерам, то выбирается уровень, образующий минимальное поддерево, включающее все аргументы ограничения.
Ниже приведен исходный код, который воспроизводит ситуацию, изображенную на рис. 1. Данный код приведен в качестве примера, показывающего, как в решателе формируется иерархия кластеров, представленная на рис. 2.
GCM_system gSys = GCM_CreateSystem();
/*
Add LCS of the first cluster, it represents the first parallelepiped.
Also its two planes will be added.
*/
GCM_geom cluster1 = GCM_AddGeom(gSys, GCM_SolidLCS(MbCartPoint3D::origin));
GCM_FixGeom(gSys, cluster1); // First cluster will have a fixed LCS.
const MbCartPoint3D org1(50.0, 0, 0); // Position of 'Plane1' in LCS of the first cluster.
GCM_geom plane1 = GCM_SubGeom(gSys, cluster1, GCM_Plane(org1, MbVector3D::xAxis));
const MbCartPoint3D org2(-112.0, 0, 0); // Position of 'Plane2' in LCS of the first cluster.
GCM_geom plane2 = GCM_SubGeom(gSys, cluster1, GCM_Plane(org2, -MbVector3D::xAxis));
/*
Set a distance dimension D1 between 'Plane1' and 'Plane2'.
(opposite sides of the parallelepiped, see figure 31.12.1)
*/
GCM_constraint D1 = GCM_AddDistance(gSys, plane1, plane2, -162.0);
/*
Add LCS of 'Cluster2' (the second box).
*/
const MbCartPoint3D pos2(-262.0, 0, 0);// Position of the second cluster.
GCM_geom cluster2 = GCM_AddGeom(gSys, GCM_SolidLCS(pos2));
const MbCartPoint3D org3(50.0, 0, 0); // Position of 'Plane3' in LCS of 'Cluster2'.
GCM_geom plane3 = GCM_SubGeom(gSys, cluster2, GCM_Plane(org3, MbVector3D::xAxis));
/*
Set distance dimension D2 between 'Plane2' and 'Plane3'.
(D2 defines a distance between the boxes, see figure 31.12.1)
*/
GCM_constraint D2 = GCM_AddDistance(gSys, plane2, plane3, 100.0);
/*
Dimension D2 can change the position of 'Cluster2' relative to 'Cluster1'.
*/
GCM_ChangeDrivingDimension(gSys, D2, 120.0);
GCM_Evaluate(gSys);
GCM_RemoveSystem(gSys);
Порядок вычисления кластеров. Обратим внимание, что схема кластеров, которая образовалась в результате комбинации вызовов GCM_AddGeom и GCM_SubGeom строго определяет порядок вычисления ограничений. Ограничения одного и того же кластера вычисляются одновременно, но не раньше, чем будут вычислены ограничения вложенных кластеров. Таким образом все кластеры вычисляются последовательно снизу вверх, от подчиненных к вышестоящим, включая корневой уровень.