How to traverse a cutlist folder?

I need to just list all the features in the immediate window, together with the subfeatures and all the dimensions (sketches and feature parameters) which parent is a cutlist body.

I can get the cutlist (body) folder, then the first body, its main features, but no subfeatures, like absorbed sketches and the dimensions.

I can traverse the whole tree ignoring the cutlist folders and get all the dimensions, but I am interested to filter and group those feature for a single body or cutlist, not the whole tree.


' Iterate Through Dimensions in Model Example (VBA)

' This example shows how to iterate through the features and dimensions in a part.

'--------------------------------------------------
' Preconditions:
' 1. Open public_documents\samples utorial\lesson2 utor1.sldprt.
' 2. Open the Immediate window.
'
' Postconditions:
' 1. Iterates through the features and dimensions in the part.
' 2. Examine the Immediate window.
'
' NOTE: Because the part is used elsewhere, do not save changes.
'---------------------------------------------------
Option Explicit

Sub main()

    Dim swApp As SldWorks.SldWorks
    Dim swModel As SldWorks.ModelDoc2
    Dim swFeat As SldWorks.Feature
    Dim swSubFeat As SldWorks.Feature
    Dim swDispDim As SldWorks.DisplayDimension
    Dim swDim As SldWorks.Dimension
    Dim swAnn As SldWorks.Annotation
    Dim bRet As Boolean

    Set swApp = CreateObject("SldWorks.Application")
    Set swModel = swApp.ActiveDoc
    Set swFeat = swModel.FirstFeature

    Debug.Print "File = " & swModel.GetPathName

    Do While Not swFeat Is Nothing
        Debug.Print "  " + swFeat.Name

        Set swSubFeat = swFeat.GetFirstSubFeature
        Do While Not swSubFeat Is Nothing
            Debug.Print "      " + swSubFeat.Name
            Set swDispDim = swSubFeat.GetFirstDisplayDimension
            Do While Not swDispDim Is Nothing
                Set swAnn = swDispDim.GetAnnotation
                Set swDim = swDispDim.GetDimension
                Debug.Print "          [" & swDim.FullName & "] = " & swDim.GetSystemValue2("") *1000
                Set swDispDim = swSubFeat.GetNextDisplayDimension(swDispDim)
            Loop
            Set swSubFeat = swSubFeat.GetNextSubFeature
        Loop
        Set swDispDim = swFeat.GetFirstDisplayDimension
        Do While Not swDispDim Is Nothing
            Set swAnn = swDispDim.GetAnnotation
            Set swDim = swDispDim.GetDimension
            Debug.Print "    [" & swDim.FullName & "] = " & swDim.GetSystemValue2("") *1000
            Set swDispDim = swFeat.GetNextDisplayDimension(swDispDim)
        Loop
        Set swFeat = swFeat.GetNextFeature
    Loop

End Sub

Check this macro from Artem if this can help Traverse feature manager nodes using SOLIDWORKS API

Thank you for the link, it looks very useful!

I am dealing with an issue related to different legacy models and the way SW evolved over the time apparently. I leave this comment here as a reminder:

The feature tree has two lists of features: the feature list and the subfeature list.
They are independent from each other and former points at the latter so you must scan the tree like: first feature → first subfeature → all its subfeatures → next feature → all its subfeatures etc

Cutlist folder is a strange beast: there are three kind of tree I saw inside files made in different ways and across ten or more years with SW.

1. some files have the cutlists shown as a feature

2. some files have the cutlists shown as a subfeature

3. some files have the cutlists shown as both features and subfeatures. (same unique id in the tree is duplicated as feature and subfeature)

The reason is apparently, sometimes, the top node “Cutlists” , while visible in the model tree, it is seen as the “ordinary” (at least for parts without the welding feature in the tree) “solid bodies” folder when inquired via API.

If you are filtering the features according to getTypeName be aware of that or the type “cutlistfolder” is going to filter your real cutlist folders, because according to API it is under a non visible “solidbodies” folder in the tree root… so you have to look for “solidbodies” and its subfeatures as well. There is also a case the cutlists are in the root only and both in the root and as a subfeature of the cutlists top folder that apperas in place of the ordinary “solid bodies”…

Actually there is also a fourth case: empty cutlists folders hidden in the tree.
Those must be purged (and I posted a macro to do that) otherwise the list of cutlist folders is going to include them and since they have zero bodies inside, they will cause other issues if not managed.

Are you saying that the feature tree looks different visually? Or that when traversing via the API the cut list items are some times found as features and other times as subfeatures?

Here’s a macro to traverse the tree and print out the cut list items with their associated features:

Option Explicit
Dim swApp As SldWorks.SldWorks
Dim mDoc As ModelDoc2
Dim featMgr As FeatureManager
Dim treeItem As TreeControlItem
Sub main()
    Set swApp = Application.SldWorks
    Set mDoc = swApp.ActiveDoc
    Set featMgr = mDoc.FeatureManager
    Set treeItem = featMgr.GetFeatureTreeRootItem2(swFeatMgrPane_e.swFeatMgrPaneTop)
    traverseItem treeItem
End Sub

Private Sub traverseItem(item As TreeControlItem)
    Dim child As TreeControlItem
    Dim nextFeat As Feature
    Set child = item.GetFirstChild()
    While Not child Is Nothing
        traverseItem child
        Set child = child.GetNext
    Wend
    If item.ObjectType = swFeatureManagerItem_Feature Then
        Set nextFeat = item.Object
        If nextFeat.GetTypeName2 = "CutListFolder" Then
            Dim cutListBodyFolder As BodyFolder
            Set cutListBodyFolder = nextFeat.GetSpecificFeature2
            Debug.Print nextFeat.Name
            processCutListFolder cutListBodyFolder
            Debug.Print 'Blank line
        End If
    End If
End Sub

Private Sub processCutListFolder(folder As BodyFolder)
    Dim vBodies As Variant
    Dim bodyCount As Integer
    bodyCount = folder.GetBodyCount
    vBodies = folder.GetBodies
    If IsEmpty(vBodies) Then
        Exit Sub
    End If
    Dim i As Integer
    Dim nextBody As Body2
    For i = LBound(vBodies) To UBound(vBodies)
        Set nextBody = vBodies(i)
        processBody nextBody
    Next i
End Sub

Private Sub processBody(bod As Body2)
   Dim featCount As Integer
   featCount = bod.GetFeatureCount
   Dim vFeats As Variant
   vFeats = bod.GetFeatures
   Dim i As Integer
   Dim nextFeat As Feature
   For i = LBound(vFeats) To UBound(vFeats)
        Set nextFeat = vFeats(i)
        Debug.Print Chr(9) & nextFeat.Name
        traverseFeature nextFeat
   Next i
End Sub

Private Sub traverseFeature(feat As Feature)
    Dim subFeat As Feature
    Set subFeat = feat.GetFirstSubFeature
    While Not subFeat Is Nothing
        Debug.Print Chr(9) & subFeat.Name
        traverseFeature subFeat
        Set subFeat = subFeat.GetNextSubFeature
    Wend
End Sub

For this feature tree


the output looks like this

CHANNEL,MISCELLANEOUS,MC6 X 12 LB/FT<1>
    Mc channel 6 X 12(1)
    Plane6
    Sketch121

BEAM,MISCELLANEOUS,M4 X 4.08 LB/FT<1>
    M beam 4 X 4.08(1)
    Plane7
    Sketch123

Z SECTION,3" X 2-11/16" X 1/4" THICK<1>
    Aluminum z section 3 X 2.688 X 2.33(1)
    Plane8
    Sketch128

Cut-List-Item2
    C channel 3 X 6(1)
    Plane4
    Sketch117

Cut-List-Item3
    M channel 5 X 18.9(1)
    Plane5
    Sketch119

Cut-List-Item1

Sheet<2>
    Sheet-Metal20
    Base-Flange1
    Sketch129
    BaseBend1
    BaseBend2
    Split1
    Flat-Pattern21
    Bend-Lines3
    Bounding-Box3
    Flatten-<BaseBend2>2
    Sketch Transformation2

Sheet<3>
    Sheet-Metal20
    Base-Flange1
    Sketch129
    BaseBend1
    BaseBend2
    Split1
    Flat-Pattern22
    Bend-Lines4
    Bounding-Box4
    Flatten-<BaseBend1>2
    Sketch Transformation3
1 Like

@JimSculley thank you. the macro looks promising.

my trees are visually similar, but according to api, their structure is completely different. it couldbe related to the custom properties since sw changed them like a couple of times since 2012 and our data was made with very old templates.