## Geometric scene clustering, assembly modeling The principle of hierarchy is the basis of the geometric model of the constraint system. This principle means that geometric objects may be grouped as geometrically rigid sets called clusters. A Cluster is a similar to such CAD abstraction of a geometric model as a solid or subassembly. Clusters may be grouped in tree-structured hierarchies whose dependencies can be traced using the following function: ```cpp GCM_geom GCM_Parent(GCM_system gSys, GCM_geom subGeom) ``` This function returns the cluster of the **subGeom** object registered in the **gSys** constraint system. If the function returns zero descriptor **GCM_NULL**, it means that the requested object is not contained in any clusters and was registered in the constraint using the **GCM_AddGeom** call. Geometric objects subordinate to a cluster are created using another call -- **GCM_SubGeom** (see [Adding and deleting geometric objects](./Adding_and_deleting_geometric_objects.md)). **Constraints within clusters**. Geometric constraints and dimensions, as well as geometric objects, are parts of the hierarchy of clusters. There is no need to expressly specify the level, at which a certain constraint is calculated. The level is selected depending on which clusters its arguments belong to. When adding a constraint, the solver selects the minimum-sized subsystem that includes all of its arguments. In other words, the geometric constraint level is determined by the minimum subtree of the hierarchy that includes all of its arguments. Fig. 1 illustrates an assembly example with two dimensions to be calculated at various hierarchy levels. The assembly consists of two parallelepipeds represented by Cluster1 and Cluster2, and each of them combines the planes, edges, and vertices of each parallelepiped. ![image](../../pictures/S.6.12.1.png){width="50%"} Fig. 1 The entire hierarchy consists of three constraint subsystems, calculated independently from the bottom up (see Fig. fig:S.6.12.2). There are two dimensions in the assembly: D1 -- distance between Plane1 and Plane2 that belong to the same Cluster1, D2 -- distance between Plane2 and Plane3 that belong to different clusters (Cluster1, Cluster2). In this case, D1 will be calculated in Cluster1 of the cluster hierarchy, while dimensions D2 will be calculated after D2 together with all constraints of the root assembly level. Therefore, the D1 calculation results will determine the size of one parallelepiped only, while D2 will affect the positioning of two parallelepipeds with respect to one another. ![image](../../pictures/S.6.12.2.png){width="50%"} Fig. 2 Thus, the constraint level is determined by the minimum subtree of clusters that includes all of its arguments. In particular, if the constraint arguments are included in the same cluster, the constraint is part of the same cluster. If the constraint arguments are included in different clusters, the level is selected that constitutes the minimum subtree including all the constraint arguments. The following is the source code that reproduces the case illustrated in Fig. 1. This code is an example demonstrating how the solver creates the cluster hierarchy shown in Fig. fig:S.6.12.2. ```cpp 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 32.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 32.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); ``` **Cluster calculation order**. Note that the cluster structure created as a result of the combination of **GCM_AddGeom** and **GCM_SubGeom** calls strictly determines the order of constraint calculation. Constraints of a single cluster are calculated at the same time but not before constraints of nested clusters have been calculated. Thus, all clusters are calculated from the bottom up, from subordinate to superior, including the root level.