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:
![image1](/files/inline-images/1_2.jpg)
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;
The first parameter is the row ID, and the second parameter is an array of balloons that relate to the row. Here is an example of a balloon attached to a row with item number value “1”:
![шьфпу2](/files/inline-images/2_2.jpg)
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 item number, the third is the quantity (or number of items), and the fourth one is a value map with the [attribute name – attribute value] pair.
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, itemNum will be 1 and qty also will be 1.
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;
newItemIterator returns an iterator. The first parameter is the BOM ID, the second parameter is the sort direction, and third one defines whether to collect expanded items.
virtual AcmIteratorPtr newPartDataIterator(bool mainOnly = false, bool noXref = true, OdDbDatabase* pHostDb = NULL) const;
newPartDataIterator returns an iterator. The first parameter defines whether to collect only the main BOM table data, the second parameter defines whether to use xrefs or not, and the third one is the OdDbDatabase object.
Conclusion
Mechanical BOM tables are quite complex but a powerful instrument that helps engineers make a drawing more clear and easier to understand. While this article contains only a basic description of the service class, Mechanical SDK currently supports all essential methods for the BOM Manager.