← LibraryTraversing SolidWorks Assemblies and Feature TreesEngineering · ComputersLesson 7/10← PrevNext →
ArticlePublished 4 Aug 20268 min readBy Kevin JoginSolidWorks APIassembliestraversalauditing

Engineering / Computers / Part 6 of 9

Traversing Assemblies & Feature Trees

Traversal is the backbone of every auditing tool worth building. Once a program can walk every component of an assembly and every feature of every component, it can answer questions that no engineer has time to answer by hand — and it can answer them the same way every time.

  • Part 6 · Applied
  • Recursion pattern
  • Suppression states
  • Audit reporting

KL-ENG-COMP-1506 · KEVOS® Knowledge Library · Australian English

Two structures matter: the component tree, which describes what an assembly is made of, and the feature tree, which describes how each piece was built. Both are walked by the same technique — obtain a starting node, process it, and hand each child back to the same routine.

1Configuration, obtained before any component
2Chains to follow — features and sub-features
0Model changes an audit tool should make

01Why traversal comes before everything else

Automation that modifies models is where the visible value is. Automation that only looks is where the safe value is, and it is almost always the better first project.

It cannot break anything

A read-only tool has no failure mode that damages data. It can be run on production assemblies on the first day without a change-control conversation.

It produces evidence

"Sixty-one of four hundred parts have no material assigned" is an argument. "Our data is a bit inconsistent" is not.

It is reusable

The traversal you write for an audit is the same traversal a corrective tool will need. Building it first means the risky tool starts from proven code.

Questions traversal answers

Which components carry no part number. Which are suppressed in the configuration being released. Which use a material not on the approved list. How many unique parts sit under how many instances. Which features are suppressed and in which configurations. Every one of these is a report, and every report is a candidate for a rule.

02Configuration first

You cannot ask an assembly directly for its components. You ask a configuration, because what an assembly contains depends on which configuration is active — components may be suppressed in one and resolved in another.

C#the route from document to root component
IConfiguration swConf = (IConfiguration)swModel.GetActiveConfiguration();
IComponent2   swRoot  = (IComponent2)swConf.GetRootComponent();

if (swRoot == null) { /* not an assembly, or nothing resolved */ return; }

Walk(swRoot, 0);

The root component represents the assembly itself. It is not something the user sees as a component, but it is the node whose children are the top-level components, and every traversal starts there.

Which configuration are you auditing?

An audit run against the active configuration reports on whatever the last user happened to leave selected. For a release check, iterate the configuration names deliberately and report per configuration. Stating which configuration a result belongs to is part of the result.

03The recursion pattern

One routine, calling itself. The depth argument is not required by the API — it exists so that the output can be indented, which turns a flat list into something a human recognises.

C#depth-first traversal of every component
void Walk(IComponent2 component, int depth)
{
    Record(component, depth);          // your own reporting

    object[] children = (object[])component.GetChildren();
    if (children == null) return;      // a leaf: a part, or nothing resolved

    foreach (object child in children)
        Walk((IComponent2)child, depth + 1);
}
Assembly (root component)
|- Frame Weldment resolved
| |- RHS 75x50 Rail x4
| `- Gusset Plate x8
|- Drive Unit resolved
| |- Gearmotor lightweight
| `- Coupling suppressed
`- Guarding resolved

Three details make the difference between a traversal that works and one that works on real assemblies:

  • Test the children for null. A part has no children, and the call returns nothing rather than an empty array. Iterating without the test fails on the first part reached.
  • The same part appears many times. Traversal visits instances, not unique documents. Counting parts means collecting distinct paths; counting instances means counting visits. Decide which question you are answering.
  • Suppressed branches stop. A suppressed component reports no children, so an audit that ignores suppression silently under-reports. Record the state alongside the name.

04Walking features

The feature tree is a chain rather than a nested structure: each feature knows the next one. Sub-features hang off individual features as a second chain.

C#features, then sub-features
IFeature feat = (IFeature)component.FirstFeature();

while (feat != null)
{
    Record(feat.Name, feat.GetTypeName2());

    IFeature sub = (IFeature)feat.GetFirstSubFeature();
    while (sub != null)
    {
        Record("   " + sub.Name, sub.GetTypeName2());
        sub = (IFeature)sub.GetNextSubFeature();
    }

    feat = (IFeature)feat.GetNextFeature();
}

The same chain is walked from a document rather than a component when you are working inside a single part — the document exposes its own first feature, and the loop is otherwise identical.

Two names, two purposes

A feature has a name, which the user can change and often has, and a type name, which identifies what kind of feature it is and does not change. Never make a decision on the user-visible name; a part renamed for clarity would silently change your tool's behaviour. Branch on the type name.

05Filtering what you report

A raw feature dump is unreadable. Every useful traversal filters, and the type name is how you filter.

Typical filtering decisions in a feature traversal
GoalFilter onWhy
A tree a user recognisesExclude reference geometry and originsPlanes and origins exist in every part and carry no information for the reader
Manufacturing reviewInclude material-removal and sheet-metal feature typesThese are the features that determine how the part is made
Standards complianceInclude features whose parameters your standard constrainsHole types, thread callouts, fillet radii
Rebuild healthInclude anything reporting an error or warning stateFinds problems before a release rather than after
Library detectionCompare against known library feature type namesDistinguishes standard content from bespoke modelling
Build the vocabulary once

Run an unfiltered traversal over a representative part and record every type name it produces. That list is the vocabulary your filters will use, and it is far more reliable than guessing at names. Keep it beside the tool; it also documents what the tool can and cannot see.

06Suppression states

Suppression is the most common thing an audit needs to read and the most common thing an engineer wants to change in bulk. Components and features handle it differently.

Components

A component reports a suppression state that distinguishes suppressed, resolved and lightweight. Setting the state changes it for the current configuration scope. Reading before writing lets you build a toggle rather than a one-way switch.

Features

A feature reports suppression per configuration, so the answer arrives as an array rather than a single value. Setting takes an explicit configuration scope argument — this configuration, all configurations, or a named list.

Lightweight is not resolved

A lightweight component is loaded but not fully evaluated, and many members return incomplete information for one. An audit that treats lightweight as resolved will report missing data that is not missing at all. Either resolve components before reading them, or record the state alongside every result so the reader knows what was actually inspected.

Bulk changes need a way back

Any tool that suppresses in bulk should first record what it found. A tool that can restore the previous state is a tool people will use; one that cannot is one they will run once and never again.

07Reporting and performance

Traversal produces data. What you do with it determines whether the tool gets used twice.

Indent to show structure

Depth is already in your recursion. Using it to indent turns a list into a tree the reader can navigate.

Export, do not just display

A results window is read once. A file — comma-separated at minimum — gets sorted, filtered and circulated.

Summarise first

Lead with counts and exceptions. The full listing belongs underneath, for the reader who disputes the summary.

Large assemblies

Traversal is fast until it is not. Four measures keep it usable:

  • Read once, use many times. Collect what you need into your own structures during a single pass, rather than making repeated calls across the interop boundary for the same information.
  • Do not resolve what you do not need. Resolving lightweight components to read a name is expensive. Resolve only where the data you require demands it.
  • Report progress. A traversal of a large assembly takes long enough that silence will be interpreted as a hang.
  • Guard the depth. A depth limit costs nothing and protects against pathological structures that would otherwise exhaust the stack.

08Quick reference

IModelDoc2::GetActiveConfiguration
The configuration whose tree you are about to walk.
IConfiguration::GetRootComponent
The node representing the assembly itself; the starting point.
IComponent2::GetChildren
Immediate children, as an array to cast. Returns nothing for a leaf.
IComponent2::GetPathName
Document behind an instance; the key for counting unique parts.
IComponent2::GetSuppression2 / SetSuppression2
Reads and writes component suppression state.
swComponentSuppressionState_e
Suppressed, resolved and lightweight states.
IComponent2::FirstFeature
Start of the feature chain for a component.
IFeature::GetNextFeature
Next feature in the chain; null ends the loop.
IFeature::GetFirstSubFeature / GetNextSubFeature
The second chain, hanging off an individual feature.
IFeature::GetTypeName2
Stable identifier of the feature kind. Branch on this, never on the user-visible name.
IFeature::IsSuppressed2 / SetSuppression2
Feature suppression, reported per configuration and set with explicit scope.
swInConfigurationOpts_e
This configuration, all configurations, or a named list.

Continue learning

SolidWorks PropertyManager Pages: Building Native User InterfaceArticle · ComputersNEXT LESSON →SolidWorks Custom Properties and Configurations Through the APIArticle · ComputersWorking with Selected Objects in the SolidWorks APIArticle · ComputersSolidWorks Drawing Automation: Creation, Views and PrintingArticle · Computers