Introduction: VBscript to Automate Convesion To/from STL, STP, DAE and IGES Files Via FreeCAD

About: 78 years old, retired with much time to spend.

Finally I found a way to do conversions between different 3D files without wasting time!

Supplies

Link to download the script:

https://mega.nz/file/O4kWVLCC#p7L71F6waeni2dAxE2qLWPrKde0UxHMrY8qka0gj65g

Step 1: My Goal

I use Tinkercad to realize my 3D projects, so I make intensive use of STL files, but I was asked many times to render my STL in STEP, IGES or DAE format.

That's really a tedious work, due to large number of items to process.

To convert STL to other file type I use FreeCAD, whose flexibility let me make several types of conversion between formats, but it's a time consuming operation, of course.

I decided to face the problem one time for all and write down some script to automatize the conversions.

You can place this script wherever you want in your disk.

Step 2: The VBS Script

' Created by Francesco Francescangeli

' 2021-10-18


Set objFSO = CreateObject("Scripting.FileSystemObject")

Set objShell = CreateObject("WScript.Shell")

Set objPopup = CreateObject("WScript.Shell")

Set Arg = Wscript.Arguments

Const ForReading = 1, ForWriting = 2

const ShowWindow = 1, DontShowWindow = 0, WaitUntilFinished = true, DontWaitUntilFinished = false


INsupported = "STL,STP,DAE,IGES"

OUTsupported = INsupported


' Check all is OK

'====================================================================================================================

If Arg.count < 4 Then

 wscript.echo "Missing parameters!" & vbCrLf & "Syntax:" & vbCrLf & "CONVERT.VBS [INtype] [OUTtype] [Full INpath] [Full OUTpath]"

 WScript.Quit   

End If


INfiletype = UCase(Arg(0))

OUTfiletype = UCase(Arg(1))

INdir = Arg(2)

INdir = Replace(INdir, "\", "/")

OUTdir = Arg(3)

OUTdir = Replace(OUTdir, "\", "/") & "/"


Set objFolder = objFSO.GetFolder(INdir)

numFiles = objFolder.Files.Count

If numFiles = 0 Then

 wscript.echo "Input directory empty!"

 WScript.Quit   

End If


If INfiletype = OUTfiletype Then

 wscript.echo "IN and OUT file format is identical!"

 WScript.Quit   

End If


If InStr(INsupported, INfiletype) = 0 Or InStr(OUTsupported, OUTfiletype) = 0 Then

 wscript.echo "Input file type not supported!"

 WScript.Quit   

End If


Set allFiles = objFolder.Files

numTot = 0

For Each objFile in allFiles

 If UCase(objFSO.GetExtensionName(objFile.Name)) = INfiletype Then

  numTot = numTot + 1

 End If

Next

If numTot = 0 Then

 wscript.echo "No " & INfiletype & " file found!"

 WScript.Quit   

End If

'====================================================================================================================


'Functions

'====================================================================================================================

Function ControlName(FileName)

 If IsNumeric(Mid(FileName,1,1)) Then

  ControlName = "_" & Mid(FileName,2)

 Else  

  ControlName = FileName

 End If

End Function


Function sendIN(str)

 MsgLine = Trim(str)

 x = objPopup.Popup(MsgLine, 3, "Work in progress" , 64)

End Function


Function sendEND(str)

 MsgLine = Trim(str)

 x = objPopup.Popup(MsgLine, 10, "Job completed!" , 64)

End Function


Function FileConv(extIN, extOUT, nameIN, nameOUT, namePart, path)

 FileConv = false

 If objFSO.FileExists(nameOUT) Then

  objFSO.DeleteFile(nameOUT)

 End If


 Set filetxt = objFSO.CreateTextFile(ConvScript, ForWriting)

 Select Case extIN

  Case "STL"

   Select Case extOUT

    Case "STP"

     filetxt.WriteLine("import FreeCAD, Mesh, Part, Import")

     filetxt.WriteLine("Mesh.open('" & nameIN & "')")

     filetxt.WriteLine("FreeCAD.getDocument('Unnamed').addObject('Part::Feature', '" & namePart & "001')")

     filetxt.WriteLine("__shape__ = Part.Shape()")

     filetxt.WriteLine("__shape__.makeShapeFromMesh(FreeCAD.getDocument('Unnamed').getObject('" & namePart & "').Mesh.Topology, 0.1)")

     filetxt.WriteLine("FreeCAD.getDocument('Unnamed').getObject('" & namePart & "001').Shape = __shape__")

     filetxt.WriteLine("FreeCAD.getDocument('Unnamed').getObject('" & namePart & "001').purgeTouched()")

     filetxt.WriteLine("del __shape__")

     filetxt.WriteLine("__objs__ = []")

     filetxt.WriteLine("__objs__.append(FreeCAD.getDocument('Unnamed').getObject('" & namePart & "001'))")

     filetxt.WriteLine("Import.export(__objs__, '" & path & nameOUT & "')")

     filetxt.WriteLine("del __objs__")

    Case "DAE"

     filetxt.WriteLine("import FreeCAD, Mesh, importDAE")

     filetxt.WriteLine("Mesh.open(u'" & nameIN & "')")

     filetxt.WriteLine("__objs__ = []")

     filetxt.WriteLine("__objs__.append(FreeCAD.getDocument('Unnamed').getObject('" & namePart & "'))")

     filetxt.WriteLine("importDAE.export(__objs__, u'" & path & nameOUT & "')")

     filetxt.WriteLine("del __objs__")

    Case "IGES"

     filetxt.WriteLine("import FreeCAD, Mesh, Part")

     filetxt.WriteLine("Mesh.open(u'" & nameIN & "')")

     filetxt.WriteLine("FreeCAD.getDocument('Unnamed').addObject('Part::Feature', '" & namePart & "001')")

     filetxt.WriteLine("__shape__=Part.Shape()")

     filetxt.WriteLine("__shape__.makeShapeFromMesh(FreeCAD.getDocument('Unnamed').getObject('" & namePart & "').Mesh.Topology, 0.1)")

     filetxt.WriteLine("FreeCAD.getDocument('Unnamed').getObject('" & namePart & "001').Shape=__shape__")

     filetxt.WriteLine("FreeCAD.getDocument('Unnamed').getObject('" & namePart & "001').purgeTouched()")

     filetxt.WriteLine("del __shape__")

     filetxt.WriteLine("__objs__ = []")

     filetxt.WriteLine("__objs__.append(FreeCAD.getDocument('Unnamed').getObject('" & namePart & "001'))")

     filetxt.WriteLine("Part.export(__objs__, u'" & path & nameOUT & "')")

     filetxt.WriteLine("del __objs__")

   End Select

  Case "STP"

   Select Case extOUT

    Case "STL"

     filetxt.WriteLine("import FreeCAD, Mesh, Part")

     filetxt.WriteLine("shape = Part.Shape()")

     filetxt.WriteLine("shape.read('" & nameIN & "')")

     filetxt.WriteLine("doc = App.newDocument(""Doc"")")

     filetxt.WriteLine("pf = doc.addObject(""Part::Feature"",""MyShape"")")

     filetxt.WriteLine("pf.Shape = shape")

     filetxt.WriteLine("Mesh.export([pf], " & chr(34) & path & nameOUT & chr(34) & ")")

    Case "DAE"

     filetxt.WriteLine("import FreeCAD, Mesh, Part, importDAE")

     filetxt.WriteLine("shape = Part.Shape()")

     filetxt.WriteLine("shape.read('" & nameIN & "')")

     filetxt.WriteLine("doc = App.newDocument(""Doc"")")

     filetxt.WriteLine("pf = doc.addObject(""Part::Feature"",""MyShape"")")

     filetxt.WriteLine("pf.Shape = shape")

     filetxt.WriteLine("importDAE.export([pf], " & chr(34) & path & nameOUT & chr(34) & ")")

    Case "IGES"

     filetxt.WriteLine("import FreeCAD, Part")

     filetxt.WriteLine("shape = Part.Shape()")

     filetxt.WriteLine("shape.read('" & nameIN & "')")

     filetxt.WriteLine("doc = App.newDocument(""Doc"")")

     filetxt.WriteLine("pf = doc.addObject(""Part::Feature"",""MyShape"")")

     filetxt.WriteLine("pf.Shape = shape")

     filetxt.WriteLine("Part.export([pf], " & chr(34) & path & nameOUT & chr(34) & ")")

   End Select

  Case "DAE"

   Select Case extOUT

    Case "STL"

     filetxt.WriteLine("import FreeCAD, Mesh, importDAE")

     filetxt.WriteLine("importDAE.open(u'" & nameIN & "')")

     filetxt.WriteLine("__objs__ = []")

     filetxt.WriteLine("__objs__.append(FreeCAD.getDocument('" & namePart & "').getObject('Mesh'))")

     filetxt.WriteLine("Mesh.export(__objs__, u'" & path & nameOUT & "')")

     filetxt.WriteLine("del __objs__")

    Case "STP"

     filetxt.WriteLine("import FreeCAD, importDAE, Part, Import")

     filetxt.WriteLine("importDAE.open(u'" & nameIN & "')")

     filetxt.WriteLine("FreeCAD.getDocument('" & namePart & "').addObject('Part::Feature', 'Mesh001')")

     filetxt.WriteLine("__shape__=Part.Shape()")

     filetxt.WriteLine("__shape__.makeShapeFromMesh(FreeCAD.getDocument('" & namePart & "').getObject('Mesh').Mesh.Topology, 0.1)")

     filetxt.WriteLine("FreeCAD.getDocument('" & namePart & "').getObject('Mesh001').Shape=__shape__")

     filetxt.WriteLine("FreeCAD.getDocument('" & namePart & "').getObject('Mesh001').purgeTouched()")

     filetxt.WriteLine("del __shape__")

     filetxt.WriteLine("__objs__ = []")

     filetxt.WriteLine("__objs__.append(FreeCAD.getDocument('" & namePart & "').getObject('Mesh001'))")

     filetxt.WriteLine("Import.export(__objs__, u'" & path & nameOUT & "')")

     filetxt.WriteLine("del __objs__")

    Case "IGES"

     filetxt.WriteLine("import FreeCAD, importDAE, Part")

     filetxt.WriteLine("importDAE.open(u'" & nameIN & "')")

     filetxt.WriteLine("FreeCAD.getDocument('" & namePart & "').addObject('Part::Feature', 'Mesh001')")

     filetxt.WriteLine("__shape__=Part.Shape()")

     filetxt.WriteLine("__shape__.makeShapeFromMesh(FreeCAD.getDocument('" & namePart & "').getObject('Mesh').Mesh.Topology, 0.1)")

     filetxt.WriteLine("FreeCAD.getDocument('" & namePart & "').getObject('Mesh001').Shape=__shape__")

     filetxt.WriteLine("FreeCAD.getDocument('" & namePart & "').getObject('Mesh001').purgeTouched()")

     filetxt.WriteLine("del __shape__")

     filetxt.WriteLine("__objs__ = []")

     filetxt.WriteLine("__objs__.append(FreeCAD.getDocument('" & namePart & "').getObject('Mesh001'))")

     filetxt.WriteLine("Part.export(__objs__, u'" & path & nameOUT & "')")

     filetxt.WriteLine("del __objs__")

   End Select

  Case "IGES"

   Select Case extOUT

    Case "STL"

     filetxt.WriteLine("import FreeCAD, Part, Mesh")

     filetxt.WriteLine("shape = Part.Shape()")

     filetxt.WriteLine("shape.read('" & nameIN & "')")

     filetxt.WriteLine("doc = App.newDocument(""Doc"")")

     filetxt.WriteLine("pf = doc.addObject(""Part::Feature"",""MyShape"")")

     filetxt.WriteLine("pf.Shape = shape")

     filetxt.WriteLine("Mesh.export([pf], " & chr(34) & path & nameOUT & chr(34) & ")")

    Case "STP"

     filetxt.WriteLine("import FreeCAD, Part, Import")

     filetxt.WriteLine("shape = Part.Shape()")

     filetxt.WriteLine("shape.read('" & nameIN & "')")

     filetxt.WriteLine("doc = App.newDocument(""Doc"")")

     filetxt.WriteLine("pf = doc.addObject(""Part::Feature"",""MyShape"")")

     filetxt.WriteLine("pf.Shape = shape")

     filetxt.WriteLine("Import.export([pf], " & chr(34) & path & nameOUT & chr(34) & ")")

    Case "DAE"

     filetxt.WriteLine("import FreeCAD, Part, importDAE")

     filetxt.WriteLine("shape = Part.Shape()")

     filetxt.WriteLine("shape.read('" & nameIN & "')")

     filetxt.WriteLine("doc = App.newDocument(""Doc"")")

     filetxt.WriteLine("pf = doc.addObject(""Part::Feature"",""MyShape"")")

     filetxt.WriteLine("pf.Shape = shape")

     filetxt.WriteLine("importDAE.export([pf], " & chr(34) & path & nameOUT & chr(34) & ")")

   End Select

 End Select

 filetxt.Close

 If objFSO.FileExists(ConvScript) Then

  FileConv = true

 End If

End Function

'====================================================================================================================


DestDir = "C:\Users\ff\AppData\Roaming\FreeCAD\Macro\"

ConvScript = DestDir & "FILECONV.FCMACRO"

CurDir = objFSO.GetAbsolutePathName(".") & "\"


numDone = 0

For Each objFile in allFiles

 nameFile = ControlName(objFSO.GetBaseName(objFile.Name))

 If UCase(objFSO.GetExtensionName(objFile.Name)) = INfiletype Then

  if FileConv(INfiletype, OUTfiletype, INdir & "/" & objFile.Name, objFSO.GetBaseName(objFile.Name) & "." & OUTfiletype, objFSO.GetBaseName(objFile.Name), OUTdir) Then

   sendIN("Please wait..." & vbCrLf & vbCrLf & "Converting:" & vbCrLf & objFile.Name)

   objShell.Run """C:\Program Files\FreeCAD 0.18\bin\freecadcmd"" " & ConvScript, DontShowWindow, WaitUntilFinished

   numDone = numDone + 1

   If numDone = numTot Then

    sendEND("All files processed.")

   End If

   If objFSO.FileExists(DestDir & ConvScript) Then

    objFSO.DeleteFile(DestDir & ConvScript)

   End If

  End If

 End If

Next


Step 3: VBS Arguments

INfiletype = UCase(Arg(0))

The first argument to pass to script is the file type to convert from (STL, STP, DAE, IGES)

OUTfiletype = UCase(Arg(1))

The 2nd one to pass to script is the file type to convert to (STL, STP, DAE, IGES)

INdir = Arg(2)

The 3rd one is the full path of directory containing the files to convert from in the form

C:\***\***\SourceDir (no trailing backslash).

OUTdir = Arg(3)

The 4th argument to pass to script is the destination path in the form C:\***\***\DestinationDir (no trailing backslash).

It's ininfluent that inside the source dir reside other types of files, they're filtered out by the script.

Example:

C:\convert.vbs stp iges C:\myfiles\stpfiles C:\myfiles\igesfiles

Step 4: Here It Comes...

Let's say we have:

- FreeCAD installed

Mine is 0.18 release, so if your is different you'll have to modify the line in script according to:

objShell.Run """C:\Program Files\FreeCAD 0.18\bin\freecadcmd"" " & ConvScript, DontShowWindow, WaitUntilFinished

_________________________________________________________________________

1) Open Command Prompt (cmd.exe)

2) execute (i.e.):

C:\(path to convert.vbs)\convert.vbs stp iges C:\myfiles\stpfiles C:\myfiles\igesfiles

3) a number of info popup, informing you about work progress

4) when done, a new popup will show you how many files have been processed.

That's all!