A big part of Mechanical SDK is the Bill Of Materials table feature, which helps structure elements of a drawing. A Bill Of Materials table is a special database persistent object that interacts with other Mechanical SDK entities.
Mechanical SDK’s BOM tables were previously described in Introduction to Bill of Materials and also other articles related to Mechanical structure and parts (part references).
BOM tables explained
A mechanical drawing is not just a set of primitives like polylines, circles, etc. Usually, mechanical drawings are complex and layered. Mechanical SDK allows users to mark a drawing’s geometry and then collect it into a BOM table. Geometry can be marked as a component or a part. Each piece is represented in a BOM table as a row. This functionality is complex, and a BOM Manager service class is used to make the work easier.
BOM tables and Drawings SDK
On the database level, a BOM table is an object that looks like a dictionary object in Drawings SDK. Logically, a Bill Of Materials table is just a set of rows but it doesn’t have graphical representation itself. For this purpose Mechanical SDK has a PartList entity that displays contents of the table. A PartList is not just BOM rows; it is reconfigurable via filters and groups, which is why any BOM table can hold more than one PartList entity.
This PartList shows the contents of a BOM table:
How to use the BOM Manager
To use the BOM Manager, just include the following file:
#include "AcmBOMManager.h"
And call this function:
AcmBOMManagerPtr pBomMgr = getAcmBomMgr();
Essential create methods
Currently, the BOM Manager has three creation methods for creating a BOM table:
virtual OdResult createBomTable(OdDbObjectId& aNewBomTableId, const OdDbObjectId targetId = OdDbObjectId::kNull, const OdString& name = "", bool addToBrowser = true, OdDbDatabase * pHostDb = NULL);
virtual OdResult createBomTable(OdDbObjectId& aNewBomTableId, const AmiCompDefKey* pTargetKey, OdString name = OdString::kEmpty);
virtual OdResult createBorderBomTable(OdDbObjectId& aNewBomTableId, const OdDbObjectId borderId, OdString name = "", bool populate = false);
These methods have similar signatures. At the beginning is a BOM table parameter, then a target parameter (block or component definition), BOM table name, and OdDbDatabase. The first two methods produce the same table but with different signatures, and the third one produces a BOM table that is attached to a particular title border.
Essential getters
BOM tables and BOM rows have complex interactions with different mechanical entities, for example balloons. Balloons are attached to BOM rows. The BOM Manager has a special method that selects balloons for a particular BOM row (also, sometimes a BOM row can be called an item or BOM item):
virtual OdResult getItemBalloons(const OdDbObjectId& itemId, OdDbObjectIdArray& ballIdArray, const OdDbObjectId& refId) const; virtual OdResult getItemBalloons(const OdDbObjectId& itemId, OdDbObjectIdArray& ballIdArray, const OdDbObjectIdArray& refIds) const;
The first parameter is the row ID, second parameter is an array of balloons that relate to the row and the third parameter is a single reference ID or an array of reference IDs to get a particular balloon or balloons.
Here is an example of a balloon attached to a row with item number value "1":
Another useful BOM feature is that its rows can hold attributes (or components that are attached to a row), for example quantity, name, standard, etc. In most cases, a set of attributes is bounded by its standard (BOMStd). The BOM Manager has a couple of methods that can get data for a particular row:
virtual OdResult getItemAttribute(const OdDbObjectId& itemId, const OdString& key, OdString& attrib, bool evaluate = true, const OdDbObjectId& bomStdId = OdDbObjectId::kNull) const;
The first parameter is the row ID, the second one is the attribute name, and the third one is the attribute value.
virtual OdResult getItemData(const OdDbObjectId& itemId, OdString& itemNo, OdUInt32& numOfItems, OdMapStringToString& valueMap, const OdDbObjectId& bomStdId = OdDbObjectId::kNull) const;
The first parameter is the row ID, the second is the BOM Row number, the third is the quantity (or number of items), and the fourth one is a value map with a set of pairs 'attribute name' — 'attribute value'.
For example, let’s look at the first picture in this article and suppose we want getItemData for the first row. We get a map with the following values:
- NAME: Screw Plug
- STANDARD: DIN 910 - M18 x 1.5
- MATERIAL: *empty*
Also,'itemNo' will be '1' indicating the number of the BOM Row, and 'numOfItems' will be '1' indicating the quantity of items.
BOM Manager iterators
BOM Manager offers two iterators:
- Item iterator, which iterates through BOM rows.
- Part data iterator, which iterates through part data.
virtual AcmIteratorPtr newItemIterator(const OdDbObjectId& bomId, Acm::PartListDirection sort = Acm::kTopDown, bool expanded = false) const;
The 'newPartDataIterator' method returns a part data iterator. The first parameter is an OdDbDatabase object, the second parameter defines whether only main BOM table data is collected or not, the third parameter defines whether xrefs are used or not.
Mechanical BOM is quite complex but powerful instrument that helps engineers to make drawing more clear and easier to understand. Mechanical SDK currently supports all essential methods that BOM Manager should support. This article contains only basic description of the service class and will be extended in future.