DATAKIT SDK  V2026.4
BillOfMaterial.hpp File Reference

Go to the source code of this file.

Data Structures

struct  BomEntry
 

Functions

void CreateBomForMainDoc (Dtk_MainDocPtr inMainDoc, Dtk_tab< BomEntry > &outBomEntries)
 
void PrintBom (const Dtk_tab< BomEntry > &inBomEntries)
 
void PrintBomSummary (const Dtk_tab< BomEntry > &inBomEntries)
 
void TraverseBom (Dtk_ComponentPtr inComponent, Dtk_tab< BomEntry > &outBomEntries, Dtk_Int32 inDepth=0)
 

Function Documentation

◆ CreateBomForMainDoc()

void CreateBomForMainDoc ( Dtk_MainDocPtr  inMainDoc,
Dtk_tab< BomEntry > &  outBomEntries 
)
25 {
26  Dtk_ComponentPtr rootComponent = inMainDoc->RootComponent();
27  if( rootComponent.IsNULL() )
28  {
29  std::cout << "Warning: document has no root component." << std::endl;
30 
31  }
32  else
33  {
34  TraverseBom( rootComponent, outBomEntries, 0 );
35  }
36 }

◆ PrintBom()

void PrintBom ( const Dtk_tab< BomEntry > &  inBomEntries)
134 {
135  std::cout << std::endl;
136  std::cout << "Bill of Materials" << std::endl;
137  std::cout << "-----------------" << std::endl;
138 
139  if (inBomEntries.size() == 0)
140  {
141  std::cout << " (no components found)" << std::endl;
142  return;
143  }
144 
145  for (Dtk_Size_t i = 0; i < inBomEntries.size(); ++i)
146  {
147  const BomEntry &entry = inBomEntries[i];
148  const Dtk_Int32 depth = entry.depth;
149 
150  // Build the prefix: one "| " per ancestor level, then "|-- " for the branch.
151  std::string prefix;
152  for (Dtk_Int32 d = 0; d < depth - 1; ++d)
153  prefix += "| ";
154  if (depth > 0)
155  prefix += "|-- ";
156 
157  std::cout << prefix;
158 
159  // Print instance name if available.
160  if (entry.instanceName.is_not_NULL() && entry.instanceName.len() > 0)
161  std::cout << "[" << entry.instanceName.c_str() << "] -> ";
162 
163  std::cout << entry.partName.c_str();
164 
165  // Append availability tags.
166  if (entry.isMissing)
167  std::cout << " [MISSING]";
168 
169  std::cout << std::endl;
170  }
171 }

◆ PrintBomSummary()

void PrintBomSummary ( const Dtk_tab< BomEntry > &  inBomEntries)
179 {
180  std::cout << std::endl;
181  std::cout << "Summary (flattened occurrence count)" << std::endl;
182  std::cout << "------------------------------------" << std::endl;
183 
184  if (inBomEntries.size() == 0)
185  {
186  std::cout << " (no components found)" << std::endl;
187  return;
188  }
189 
190  // Accumulate per part name: occurrence count and availability flags.
191  std::map<std::string, int> countMap;
192  std::map<std::string, bool> missingMap;
193 
194  for (Dtk_Size_t i = 0; i < inBomEntries.size(); ++i)
195  {
196  const BomEntry &entry = inBomEntries[i];
197  std::string key = entry.partName.is_not_NULL() ? entry.partName.c_str() : "(unnamed)";
198  countMap[key]++;
199  if (entry.isMissing)
200  missingMap[key] = true;
201  }
202 
203  // Print the table header.
204  std::cout << " Part Name | Count | Status" << std::endl;
205  std::cout << " ---------------------------------- | ----- | --------------------" << std::endl;
206 
207  for (std::map<std::string, int>::const_iterator it = countMap.begin();
208  it != countMap.end(); ++it)
209  {
210  const std::string &key = it->first;
211 
212  // Left-align the part name in a 34-character field.
213  std::string name = key;
214  if (name.size() > 34)
215  name = name.substr(0, 31) + "...";
216 
217  std::cout << " ";
218  std::cout << name;
219  for (size_t pad = name.size(); pad < 34; ++pad)
220  std::cout << ' ';
221 
222  // Count column (5 chars wide).
223  std::cout << " | ";
224  std::string countStr = std::to_string(it->second);
225  for (size_t pad = countStr.size(); pad < 5; ++pad)
226  std::cout << ' ';
227  std::cout << countStr;
228 
229  // Status column.
230  std::cout << " | ";
231  bool hasMissing = missingMap.count(key) > 0;
232  if (hasMissing )
233  std::cout << " [MISSING]";
234  std::cout << std::endl;
235  }
236  std::cout << std::endl;
237 }

◆ TraverseBom()

void TraverseBom ( Dtk_ComponentPtr  inComponent,
Dtk_tab< BomEntry > &  outBomEntries,
Dtk_Int32  inDepth = 0 
)
44 {
45  if (inComponent.IsNULL())
46  return;
47 
48  Dtk_Component::ComponentTypeEnum type = inComponent->ComponentType();
49 
51  {
52  // An instance holds a placement (transformation) and references a prototype.
53  Dtk_string instanceName = inComponent->InstanceName();
54 
55  // The prototype is the first (and only) child of an instance.
56  if (inComponent->GetNumChildren() > 0)
57  {
58  Dtk_ComponentPtr prototype = inComponent->GetChild(0);
59  if (prototype.IsNotNULL())
60  {
61  BomEntry entry;
62  entry.partName = prototype->Name();
63  entry.instanceName = instanceName;
64  entry.depth = inDepth;
65  entry.occurrenceCount = 1;
66  entry.isMissing = prototype->IsAvailabilityFlaggedAs(Dtk_Component::ComponentMissing) == DTK_TRUE;
67  outBomEntries.push_back(entry);
68 
69  // Only recurse into the prototype's children if it is not missing.
70  if (!entry.isMissing)
71  TraverseBom(prototype, outBomEntries, inDepth + 1);
72  }
73  }
74  }
76  {
77  // A prototype may have sub-components (instances of sub-parts).
78  Dtk_Size_t numChildren = inComponent->GetNumChildren();
79  for (Dtk_Size_t i = 0; i < numChildren; ++i)
80  {
81  TraverseBom(inComponent->GetChild(i), outBomEntries, inDepth);
82  }
83  }
84  else if (type == Dtk_Component::CatalogComponentType)
85  {
86  // A catalog holds multiple alternative configurations.
87  // Only the activated children contribute to the BOM; if none are activated
88  // the default child is used.
89  Dtk_Size_t numChildren = inComponent->GetNumChildren();
90  if (numChildren > 0)
91  {
92  Dtk_tab<Dtk_Int32> activatedIndices = inComponent->GetActivatedChildrenInCatalog();
93  if (activatedIndices.size() > 0)
94  {
95  for (Dtk_Size_t i = 0; i < activatedIndices.size(); ++i)
96  {
97  TraverseBom(inComponent->GetChild(activatedIndices[i]), outBomEntries, inDepth);
98  }
99  }
100  else
101  {
102  // Fall back to the default child.
103  Dtk_Int32 defaultIndex = inComponent->GetDefaultChildInCatalog();
104  if (defaultIndex >= 0 && static_cast<Dtk_Size_t>(defaultIndex) < numChildren)
105  {
106  TraverseBom(inComponent->GetChild(defaultIndex), outBomEntries, inDepth);
107  }
108  }
109  }
110  }
111  else if (type == Dtk_Component::VirtualComponentType)
112  {
113  // A virtual component is a transparent grouping node with no geometry of
114  // its own. Traverse all its children without adding a BOM entry.
115  Dtk_Size_t numChildren = inComponent->GetNumChildren();
116  for (Dtk_Size_t i = 0; i < numChildren; ++i)
117  {
118  TraverseBom(inComponent->GetChild(i), outBomEntries, inDepth);
119  }
120  }
121 }
TraverseBom
void TraverseBom(Dtk_ComponentPtr inComponent, Dtk_tab< BomEntry > &outBomEntries, Dtk_Int32 inDepth)
Definition: BillOfMaterial.cpp:43
Dtk_Component::CatalogComponentType
@ CatalogComponentType
Definition: dtk_maindoc.hpp:575
BomEntry::depth
Dtk_Int32 depth
Definition: BillOfMaterial.hpp:15
Dtk_SmartPtr::IsNotNULL
Dtk_bool IsNotNULL() const
Definition: util_ptr_dtk.hpp:119
DTK_TRUE
#define DTK_TRUE
Definition: define.h:726
Dtk_string
This is a high level string class.
Definition: dtk_string.hpp:53
Dtk_Size_t
size_t Dtk_Size_t
Definition: define.h:711
BomEntry::isMissing
bool isMissing
Definition: BillOfMaterial.hpp:17
Dtk_Component::VirtualComponentType
@ VirtualComponentType
Definition: dtk_maindoc.hpp:576
Dtk_Component::InstanceComponentType
@ InstanceComponentType
Definition: dtk_maindoc.hpp:573
Dtk_string::is_not_NULL
Dtk_bool is_not_NULL() const
Dtk_Int32
int32_t Dtk_Int32
Definition: define.h:686
BomEntry::occurrenceCount
Dtk_Int32 occurrenceCount
Definition: BillOfMaterial.hpp:16
Dtk_Component::ComponentTypeEnum
ComponentTypeEnum
Definition: dtk_maindoc.hpp:572
Dtk_SmartPtr::IsNULL
Dtk_bool IsNULL() const
Definition: util_ptr_dtk.hpp:118
Dtk_SmartPtr
Definition: util_ptr_dtk.hpp:37
Dtk_string::c_str
const char * c_str() const
Retrieve the ASCII conversion string.
Dtk_tab< Dtk_Int32 >
Dtk_tab::size
Dtk_Size_t size() const
Returns the size of the array.
Definition: util_stl_dtk.hpp:503
BomEntry
Definition: BillOfMaterial.hpp:12
BomEntry::partName
Dtk_string partName
Definition: BillOfMaterial.hpp:13
Dtk_Component::PrototypeComponentType
@ PrototypeComponentType
Definition: dtk_maindoc.hpp:574
Dtk_Component::ComponentMissing
@ ComponentMissing
Definition: dtk_maindoc.hpp:562
Dtk_string::len
int len() const
Retrieve the length of the Dtk_string.
Dtk_tab::push_back
void push_back(const T &x)
Inserts an element at the end of the array.
Definition: util_stl_dtk.hpp:416
BomEntry::instanceName
Dtk_string instanceName
Definition: BillOfMaterial.hpp:14