STL Macro Unit Body for Each Configuration

I use 2 macros: one to make unit STLs of each body in a room. And another macro that performs a complete STL of the file but all the configuration.

My wish is to make a macro that can make unitary STLs of each body of all the configurations of the part.

I'm on SW2023 and I'm using old macros. But I don't know how to modify it to do this, can you help me with this?

I send you the 2 macros in the subject.

Option Explicit

Dim swApp As Object
Dim swPart As SldWorks.ModelDoc2
Dim swFeat As SldWorks.Feature
Dim Indent As Long
Dim BodyFolderType(5)  As String
Dim sModelName         As String
Dim iNbCar             As Integer
Dim boolstatus         As Boolean
Dim fileName           As String
Dim file2save          As String
Dim swErrors            As Long
Dim swWarnings          As Long
Dim bRet                As Boolean

Sub main()

    BodyFolderType(0) = "dummy"
    BodyFolderType(1) = "swSolidBodyFolder"
    BodyFolderType(2) = "swSurfaceBodyFolder"
    BodyFolderType(3) = "swBodySubFolder"
    BodyFolderType(4) = "swWeldmentSubFolder"
    BodyFolderType(5) = "swWeldmentCutListFolder"

    Set swApp = Application.SldWorks
    Set swPart = swApp.ActiveDoc
    Call StlParam
    Debug.Print "File = " & swPart.GetPathName
    fileName = swPart.GetPathName
     
     fileName = Strings.Left(fileName, Len(fileName) - 7)


    Indent = -3

    Set swFeat = swPart.FirstFeature
     TraverseFeatures swFeat, True

End Sub
Function StlParam()
boolstatus = swApp.SetUserPreferenceToggle(swSTLBinaryFormat, True) 
boolstatus = swApp.SetUserPreferenceIntegerValue(swExportStlUnits, 0)
boolstatus = swApp.SetUserPreferenceIntegerValue(swSTLQuality, swSTLQuality_e.swSTLQuality_Fine) 
boolstatus = swApp.SetUserPreferenceToggle(swSTLShowInfoOnSave, True) 
boolstatus = swApp.SetUserPreferenceToggle(swSTLComponentsIntoOneFile, True) 
End Function


Function DoTheWork(thisFeat As SldWorks.Feature)

    Dim IsBodyFolder As Boolean
     IsBodyFolder = False

    Dim FeatType As String
     FeatType = thisFeat.GetTypeName

    If FeatType = "SolidBodyFolder" Then IsBodyFolder = True
   
    If IsBodyFolder Then

        Debug.Print Format(String(Indent, " ") & thisFeat.Name, "!" & String(40, "@")); Format(FeatType, "!" & String(30, "@"));

        Dim BodyFolder As SldWorks.BodyFolder
         Set BodyFolder = thisFeat.GetSpecificFeature2

        Dim BodyFolderTypeE As Long
         BodyFolderTypeE = BodyFolder.Type

        Debug.Print Format(BodyFolderType(BodyFolderTypeE), "!" & String(30, "@")); Format(BodyFolderTypeE, "!@@@@");

        Dim BodyCount As Long
         BodyCount = BodyFolder.GetBodyCount

        Debug.Print "Body Count is " & BodyCount

        Dim vBodies As Variant
         vBodies = BodyFolder.GetBodies

        Dim i As Long

        If Not IsEmpty(vBodies) Then
             For i = LBound(vBodies) To UBound(vBodies)
                 Dim Body As SldWorks.Body2
                 Set Body = vBodies(i)
                    sModelName = Body.Name
                     If InStr(sModelName, "[") <> 0 Then
                         iNbCar = Len(sModelName) - (Len(sModelName) - InStr(sModelName, "[")) - 1
                         sModelName = Left(sModelName, iNbCar)
                     End If
                 Debug.Print sModelName
                 boolstatus = swPart.Extension.SelectByID2(Body.Name, "SOLIDBODY", 0, 0, 0, False, 0, Nothing, 0)
                 file2save = fileName & " - " & sModelName & ".STL"
                 Debug.Print file2save
                boolstatus = swPart.SaveToFile2(file2save, swSaveAsOptions_e.swSaveAsOptions_Silent, swErrors, swWarnings)
                 Set swPart = swApp.ActiveDoc
                 swApp.CloseDoc (swPart.GetTitle)
                 Set swPart = swApp.ActiveDoc
                'swPart.ClearSelection2 True
                 Debug.Print Format(String(Indent + 3, " ") & Body.Name, "!" & String(30, "@"))
             Next i
         End If

        Dim FeatureFromBodyFolder As SldWorks.Feature
         Set FeatureFromBodyFolder = BodyFolder.GetFeature

        If Not FeatureFromBodyFolder Is thisFeat Then
             MsgBox "Features don't match!"
         End If
     Else

    End If

End Function

Function TraverseFeatures(thisFeat As SldWorks.Feature, isTopLevel As Boolean)

    Dim curFeat As SldWorks.Feature
     Set curFeat = thisFeat

    Indent = Indent + 3

    While Not curFeat Is Nothing
         DoTheWork curFeat 

        Dim subfeat As SldWorks.Feature
         Set subfeat = curFeat.GetFirstSubFeature

        While Not subfeat Is Nothing
             TraverseFeatures subfeat, False
             Dim nextSubFeat As SldWorks.Feature
             Set nextSubFeat = subfeat.GetNextSubFeature
             Set subfeat = nextSubFeat
             Set nextSubFeat = Nothing
         Wend

        Set subfeat = Nothing

        Dim nextFeat As SldWorks.Feature

        If isTopLevel Then
             Set nextFeat = curFeat.GetNextFeature
         Else
             Set nextFeat = Nothing
         End If

        Set curFeat = nextFeat
         Set nextFeat = Nothing

    Wend
     Indent = Indent - 3

End Function

and

Dim swApp As Object

Dim Part As Object
Dim boolstatus As Boolean
Dim longstatus As Long, longwarnings As Long

Sub main()

Set swApp = Application.SldWorks
Set Part = swApp.ActiveDoc

Dim V As Variant
V = swApp.GetConfigurationNames(Part.GetPathName)
   
Dim i As Long
For i = 0 To UBound(V)
    boolstatus = Part.ShowConfiguration2(V(i))
    longstatus = Part.SaveAs3(Part.GetPathName & "-" & V(i) & ".STL", 0, 0)
Next

End Sub

Hello

Basically, you have to put the whole part of the code that manages the export of bodies in the loop:

For i = 0 To UBound(V)
boolstatus = Part.ShowConfiguration2(V(i))
'Insérer ici le bout de code lié à l'export des corps
longstatus = Part.SaveAs3(Part.GetPathName & « - » & V(i) & " .STL ", 0, 0)
Next

1 Like

I tried to reproduce this but it still gives me compilation errors... I don't understand ...

Dim swApp As Object
Dim Part As ModelDoc2
Dim boolstatus As Boolean
Dim longstatus As Long, longwarnings As Long
Dim swBodies As Object
Dim swBody As Body2
Dim savePath As String

Const swAllBodies As Long = 0 ' Constant to get all bodies

Sub main()

' Initialiser SolidWorks et le document actif
Set swApp = Application.SldWorks
Set Part = swApp.ActiveDoc

' Vérifier si le document actif est une pièce
If Part Is Nothing Or Not Part.GetType = swDocPART Then
    MsgBox "Veuillez ouvrir une pièce."
    Exit Sub
End If

' Récupérer les noms de toutes les configurations
Dim V As Variant
Dim configCount As Long
configCount = Part.GetConfigurationCount()

If configCount = 0 Then
    MsgBox "Aucune configuration trouvée."
    Exit Sub
End If

V = Part.GetConfigurationNames() ' Utiliser GetConfigurationNames sur l'objet Part

' Parcourir chaque configuration
Dim i As Long
For i = LBound(V) To UBound(V)
    boolstatus = Part.ShowConfiguration2(V(i))

    ' Vérifier si l'activation a réussi
    If boolstatus Then
        Debug.Print "Exporting configuration: " & V(i)

        ' Obtenir les corps du modèle actif
        Set swBodies = Part.GetBodies2(swAllBodies, False)

        ' Vérifier si des corps existent
        If Not swBodies Is Nothing And swBodies.Count > 0 Then
            ' Parcourir chaque corps
            Dim j As Integer
            For j = 0 To swBodies.Count - 1
                Set swBody = swBodies(j)

                ' Définir le chemin de sauvegarde pour chaque corps
                savePath = Left(Part.GetPathName, InStrRev(Part.GetPathName, ".") - 1) & "-" & V(i) & "_Body" & j & ".stl"
                
                ' Exporter le corps en STL
                longstatus = Part.SaveAs3(savePath, 0, 0)

                Debug.Print "Exported body: " & j & " in configuration: " & V(i)
            Next j
        Else
            Debug.Print "Aucun corps trouvé dans la configuration: " & V(i)
        End If
    Else
        Debug.Print "Failed to activate configuration: " & V(i)
    End If
Next i

MsgBox "Exportation STL terminée pour toutes les configurations et corps."

End Sub

Hello

No compilation error at my level on this code. Which line is it blocking?

   Set swBodies = Part.GetBodies2(swAllBodies, False) erreur d'execution 424. objet requis.

And I don't understand why...

I tried other methods but it still doesn't want to...

I did the test with a part that has different configs and bodies but nothing ...

This is a run-time error, not a compilation error.
Possibility to make a file available to test? (I don't have that at hand)

Biensur !

Piece test corps. SLDPRT (186.6 Ko)

Hello

So I looked a little bit more closely at the code. So as it stands, the error comes from the fact that the line Set swBodies = Part.GetBodies2(swAllBodies, False) is wrong.
Part.GetBodies2(swAllBodies, False) Expects a variant variable in return.
In my opinion, the easiest way is to have only one macro.
From the code of the first macro for files without configuration, change the code of the sub main to the code below:

Sub main()

    BodyFolderType(0) = "dummy"
    BodyFolderType(1) = "swSolidBodyFolder"
    BodyFolderType(2) = "swSurfaceBodyFolder"
    BodyFolderType(3) = "swBodySubFolder"
    BodyFolderType(4) = "swWeldmentSubFolder"
    BodyFolderType(5) = "swWeldmentCutListFolder"

    Set swApp = Application.SldWorks
    Set swPart = swApp.ActiveDoc
    
    ' Vérifier si le document actif est une pièce
    If swPart Is Nothing Or Not swPart.GetType = swDocPART Then
        MsgBox "Veuillez ouvrir une pièce."
        Exit Sub
    End If

    Call StlParam
    Debug.Print "File = " & swPart.GetPathName
    fileName = swPart.GetPathName
     
     fileName = Strings.Left(fileName, Len(fileName) - 7)


    Indent = -3
    
    configCount = swPart.GetConfigurationCount()
    If configCount = 0 Then
        Set swFeat = swPart.FirstFeature
        TraverseFeatures swFeat, True
    ElseIf configCount > 0 Then
        V = swPart.GetConfigurationNames() ' Utiliser GetConfigurationNames sur l'objet Part
        For i = LBound(V) To UBound(V)
            boolstatus = swPart.ShowConfiguration2(V(i))
            Set swFeat = swPart.FirstFeature
            TraverseFeatures swFeat, True
        Next i
    End If

End Sub

3 Likes

Registers all V4 Valid .swp bodies in STL (67.5 KB)
Body test part. SLDPRT (186.6 KB)

Well, I modified to take the example on the first macro, it's valid but doesn't do the job ask hahah.
I tried to fix the problem but I don't see it!

Hello

The problem comes from the control of swErrors of this line If swErrors <> 0 Or swWarnings <> 0 Then
In the case of exporting bodies via SaveToFile2, the 512 error is normal.
swFileSaveError_e Enumeration - 2023 - SOLIDWORKS API Help
There are two options, either not to monitor for errors, or to take into account the fact that the 512 error is valid.

2 Likes

Body test part. SLDPRT (211.1 KB)
Saves all V10.swp bodies in single STL (62.5 KB)

So thank you very much Cyril.f for your help, it helped me a lot!
I still have a small problem for this macro, it does the job but for example, on this test part which serves as an example it does the macro and the files for the 1corp and 2body configuration but not for the 3body (it stops leaving the Stock files open). I don't know what can lead to this. I think that after that the function will be nickel haha

Hello

I'll look at this if I have 5 minutes if not next week.

Hello;

You probably just have to check the Ubound(V) limits to see if it corresponds to the number of configurations:

And possibly replace it with:
For i = LBound(V) To UBound(V)+1

(I say this but I haven't tested the macro then...)

FYI, Solidworks considers " Default " as a configuration:
image

Hello

No problem with the terminals, whether the configuration is called default or xxx the macro counts the number of configurations.
Couldn't use the test file (future version) so I took the original one of the subject.
I hadn't checked the rest of the code (I based myself on the original code I had already given for the initial topics from which the code came at the beginning of the subject).
After testing, the problem is in the DoTheWork function. You have to close the open files as you go, the modified code below works:

Function DoTheWork(thisFeat As SldWorks.Feature)

    Dim IsBodyFolder As Boolean
    IsBodyFolder = False

    Dim FeatType As String
    FeatType = thisFeat.GetTypeName

    If FeatType = "SolidBodyFolder" Then IsBodyFolder = True
   
    If IsBodyFolder Then

        Dim BodyFolder As SldWorks.BodyFolder
        Set BodyFolder = thisFeat.GetSpecificFeature2

        Dim BodyCount As Long
        BodyCount = BodyFolder.GetBodyCount

        Dim vBodies As Variant
        vBodies = BodyFolder.GetBodies

        Dim i As Long

        ' Vérifier si des corps sont présents
        If Not IsEmpty(vBodies) Then
            For i = LBound(vBodies) To UBound(vBodies)
                Dim Body As SldWorks.Body2
                Set Body = vBodies(i)
                
                ' Obtenir le nom du corps
                sModelName = Body.Name
                If InStr(sModelName, "[") <> 0 Then
                    iNbCar = Len(sModelName) - (Len(sModelName) - InStr(sModelName, "[")) - 1
                    sModelName = Left(sModelName, iNbCar)
                End If

                ' Ajouter le nom de la configuration active
                Dim configName As String
                configName = swPart.ConfigurationManager.ActiveConfiguration.Name
                
                ' Créer le nom de fichier pour l'exportation
                file2save = fileName & " - " & configName & " - " & sModelName & ".STL"
                
                ' Sélectionner le corps pour l'exportation
                boolstatus = swPart.Extension.SelectByID2(Body.Name, "SOLIDBODY", 0, 0, 0, False, 0, Nothing, 0)
                
                ' Exporter le corps en STL
                boolstatus = swPart.SaveToFile2(file2save, swSaveAsOptions_e.swSaveAsOptions_Silent, swErrors, swWarnings)
                Set swPart = swApp.ActiveDoc
                swApp.CloseDoc (swPart.GetTitle)
                Set swPart = swApp.ActiveDoc

                ' Vérifier les erreurs d'enregistrement
                If swErrors <> 0 And swErrors <> 512 Then
                    Debug.Print "Erreur lors de l'exportation du corps : " & sModelName & " - Code d'erreur : " & swErrors
                    MsgBox "Erreur lors de l'export de " & sModelName & " avec le code d'erreur : " & swErrors
                Else
                    Debug.Print "Exportation réussie pour le corps : " & sModelName
                End If
            Next i
        End If

    End If

End Function

2 Likes