Assemblies code architecture
In boundary representation, we do not have many design choices: any model is composed of vertices, edges and faces. The representation of assemblies is, in contrast, often application-dependent as it expresses not just a shape, but some domain knowledge as well. The attempts to design generic representation schemes for CAD assemblies gave rise to verbose standards like STEP, PRC or JT. A comprehensive representation scheme covers many digital product representation aspects, such as versioning, design review notes, configurations, and many others. While having a rich data model is a must for enterprise applications, you do not really need all these options for the geometry-centric CAD algorithms. Therefore, we will not focus on niche or rare use cases below. In Analysis Situs, we designed our data framework for CAD assemblies based on the following requirements:
- In-memory access has the first-class support. For performant algorithms, the data should be available in memory. Of course, you cannot store everything in RAM in some scenarios, especially if you work with huge CAD assemblies. Hence the second requirement.
- Clear implementation-independent API. We have been working with many data frameworks that violated this simple rule not to mix up the exposed API with the implementation details. In some frameworks, it is a B-rep shape that is messed up with the assembly structure. In others, it is the need to call SQL queries to get product structure from databases. A good data model should not bother the caller code with the nuances of its implementation. The underlying technology (whether it is OCAF, Mongo, or Sqlite) should be kept where it is supposed to be: in the engine room.
- Extensibility. The data framework should expose some extension points so that the client applications are free to add their domain-specific information. Think of all sorts of metadata, including the design review notes mentioned above. A good data model should not fall apart whenever a new object type is added there.
Building up a data framework requires careful thinking of the employed primitive types and their interplay. We have derived the entity types based on years of experience in the CAD domain and other products we've ever touched, used or developed ourselves.
The first entity type that's one step close to a geometric primitive is a Part. A Part does not have to contain any geometry though. Also, it might contain more than one representation, e.g., you may have a single bolt represented with different levels of detail (LOD). A Part is something instanced in the assembly structure, i.e., it can have multiple occurrences with different locations in the modeling space.
A Subassembly is a composite unit containing references (Instances) to several Parts or nested Subassemblies (yeah, recursive definition is intentional here).
An Instance is a located reference to a Part or Subassembly. An Instance is nested into a Subassembly, i.e., a Subassembly contains Instances as its child elements.
A Prototype is something instanced. I.e., it is either a Part or a Subassembly. A Prototype is a term we use to denote reusable units in the assembly structure.
A Representation is a piece of geometric data associated with a Prototype. One Prototype may have a set of Representations, e.g., a B-rep and a series of LOD. It is also valid for a Subassembly to have some Representations (hence Representations are attached to Prototypes and not to Parts).
A Subdomain is a subset selection of elements in a specific representation. It is assumed that any Representation is indexed in some way (e.g., all B-rep or mesh elements are given numeric IDs), and a Subdomain contains a series of indices of interest. Subdomains capture a geometric region of a Representation that allows for attaching boundary conditions, materials or appearance attributes, such as colors.
A Metadata is an abstract object that can be attached to the following entities:
- Assembly item.