Author Topic: Scripting question / asset management - batch convert .max files to proxy  (Read 446 times)

2025-04-14, 14:30:20

Joris

  • Active Users
  • **
  • Posts: 8
    • View Profile
Hello,

Is there a way to batch convert files to corona proxies?
I would like to organize some plant libraries and it would be a big timesaver if it could be automated (instead of opening each file, export to proxy, save file, open next file etc.).

There's an older post on the forum, but after searching I didn't find a solution:
https://forum.corona-renderer.com/index.php?topic=25853.0

Maybe it can be done with a script:
1. Opening each file from a source folder.
2. Select the geometry
3. Exporting the geometry as a Corona Proxy to a target folder.
4. Saving the modified scene in the target folder as a new .max file
5. Repeating this for all files in the source folder

Since I can't script, I asked ChatGPT, and got this:

-- Define folders
sourceFolder = "E:/folder_with_max_files/"
targetFolder = "E:/folder_a/"

-- Get all .max files in the source folder
maxFiles = getFiles (sourceFolder + "*.max")

for f in maxFiles do
(
    try (
        -- Open the .max file
        loadMaxFile f useFileUnits:true quiet:true

        -- Select all mesh geometry
        select (for obj in geometry where superclassof obj == GeometryClass collect obj)

        -- Build export path
        fileName = getFilenameFile f
        proxyPath = targetFolder + fileName + ".cproxy"

        -- Export selection to Corona Proxy
        coronaProxyExporter.exportToSingleFile = true
        coronaProxyExporter.exportMultipleFiles = false
        coronaProxyExporter.useObjectNames = false
        coronaProxyExporter.exportSelected proxyPath

        -- Optional: replace original geometry with proxy
        -- Uncomment below if you want to auto-replace in scene
        /*
        delete selection
        importFile proxyPath #noPrompt using:CoronaProxy
        */

        -- Save the modified file to target folder
        saveMaxFile (targetFolder + fileName + ".max")

        -- Clean the scene
        resetMaxFile #noPrompt
    )
    catch (
        format "Failed to process file: %\n" f
    )
)

messageBox "Batch export completed!"


Since no max files are saved and no proxies generated, there's obviously something wrong.

Is this possible with a script
Has anybody experience with something similar or a solution to this?

Thanks!

2025-04-14, 15:40:14
Reply #1

Aram Avetisyan

  • Corona Team
  • Active Users
  • ****
  • Posts: 877
    • View Profile
Hi,

It should be definitely possible to do with a script.
I will see if I find time and help you out with this (I have partly covered this in another script I created), unless someone does it sooner.
Aram Avetisyan | chaos-corona.com
Chaos Corona QA Specialist | contact us

2025-04-14, 15:40:41
Reply #2

Avi

  • Corona Team
  • Active Users
  • ****
  • Posts: 768
    • View Profile
Please try this.

Code: [Select]
sourceDir = @"G:\Your-file-path-containing-Max-files"
targetDir = @"G:\Your-file-path-where-all-proxy-will-be-stored"

fn fixPath dir = (
    if dir.count > 0 and dir[dir.count] != "\\" do dir += "\\"
    dir
)

sourceDir = fixPath sourceDir
targetDir = fixPath targetDir

makeDir targetDir
format "Target directory: %\n" targetDir

maxFiles = getFiles (sourceDir + "*.max")
format "Found % .max files to process\n" maxFiles.count

if maxFiles.count == 0 then (
    messageBox "No .max files found in source folder!" title:"Error"
) else (
    for f in maxFiles do (
        try (
            loadMaxFile f quiet:true useFileUnits:true
            fileName = getFilenameFile f
            proxyPath = targetDir + fileName + ".cproxy"
           
            format "Processing: %\n" fileName
           
            local geomObjects = for obj in objects where isKindOf obj GeometryClass and canConvertTo obj TriMeshGeometry collect obj
           
            if geomObjects.count > 0 then (
                format "Found % geometry objects\n" geomObjects.count
               
                if geomObjects.count == 1 then (
                    local proxyNode = CProxy name:(fileName + "_proxy")
                    CProxy.ProxyFp.fromScene proxyNode geomObjects[1] proxyPath
                    delete proxyNode
                ) else (
                    local parentNode = point name:("Parent_" + fileName)
                   
                    for obj in geomObjects do obj.parent = parentNode
                   
                    local proxyNode = CProxy name:(fileName + "_proxy")
                    CProxy.ProxyFp.fromScene proxyNode parentNode proxyPath
                   
                    delete proxyNode
                   
                    for obj in geomObjects do obj.parent = undefined
                    delete parentNode
                )
               
                format "✅ Exported proxy: %\n" proxyPath
            ) else (
                format "⚠️ No geometry in: % (skipping)\n" fileName
            )
        ) catch (
            format "❌ ERROR in % — %\n" f (getCurrentException())
        )
        resetMaxFile #noPrompt
    )
)

format "Script completed.\n"



Arpit Pandey | chaos-corona.com
3D Support Specialist - Corona | contact us

2025-04-14, 17:16:14
Reply #3

Joris

  • Active Users
  • **
  • Posts: 8
    • View Profile
Hi Arpit,

Thanks for the quick reply!

I tested the script and it cycles through all files: opening each file + exporting proxies.

But is it also possible that, before switching to the next file, the scripts saves each .max file as a seperate file (.i.e. with the name + Proxy)?
This way I would have a .max file with the proxy (and the proxy material) which I can merge into a new scene.

Thanks.

2025-04-15, 07:15:24
Reply #4

Avi

  • Corona Team
  • Active Users
  • ****
  • Posts: 768
    • View Profile
Code: [Select]

sourceDir = @"G:\Your-file-path-containing-Max-files"
targetDir = @"G:\Your-file-path-where-all-proxy-will-be-stored"

fn fixPath dir = (
    if dir.count > 0 and dir[dir.count] != "\\" do dir += "\\"
    dir
)

sourceDir = fixPath sourceDir
targetDir = fixPath targetDir
makeDir targetDir

format "Target directory: %\n" targetDir
maxFiles = getFiles (sourceDir + "*.max")
format "Found % .max files to process\n" maxFiles.count

if maxFiles.count == 0 then (
    messageBox "No .max files found in source folder!" title:"Error"
) else (
    for f in maxFiles do (
        try (
            loadMaxFile f quiet:true useFileUnits:true
            fileName = getFilenameFile f
            proxyPath = targetDir + fileName + ".cproxy"
            maxWithProxyPath = targetDir + fileName + "_WithProxy.max"
           
            format "Processing: %\n" fileName
           
            local geomObjects = for obj in objects where isKindOf obj GeometryClass and canConvertTo obj TriMeshGeometry collect obj
           
            if geomObjects.count > 0 then (
                format "Found % geometry objects\n" geomObjects.count
               
                local proxyNode = undefined
               
                if geomObjects.count == 1 then (
                    proxyNode = CProxy name:(fileName + "_proxy")
                    CProxy.ProxyFp.fromScene proxyNode geomObjects[1] proxyPath
                ) else (
                    local parentNode = point name:("Parent_" + fileName)
                   
                    for obj in geomObjects do obj.parent = parentNode
                   
                    proxyNode = CProxy name:(fileName + "_proxy")
                    CProxy.ProxyFp.fromScene proxyNode parentNode proxyPath
                   
                    for obj in geomObjects do obj.parent = undefined
                    delete parentNode
                )
               
                if proxyNode != undefined then (
                    select proxyNode
                   
                    for obj in geomObjects do (
                        if isValidNode obj do delete obj
                    )
                   
                    saveMaxFile maxWithProxyPath quiet:true
                    format "✅ Exported proxy: %\n" proxyPath
                    format "✅ Saved MAX with proxy only: %\n" maxWithProxyPath
                )
            ) else (
                format "⚠️ No geometry in: % (skipping)\n" fileName
            )
        ) catch (
            format "❌ ERROR in % — %\n" f (getCurrentException())
        )
        resetMaxFile #noPrompt
    )
)

format "Script completed.\n"




I hope this helps.
Arpit Pandey | chaos-corona.com
3D Support Specialist - Corona | contact us

2025-04-15, 09:10:20
Reply #5

Tom

  • Active Users
  • **
  • Posts: 322
    • View Profile
To me, it sounds like what you want to do can easily be done with Project Manager. Not a free plugin, but very useful and worth the money: https://3d-kstudio.com/product/project-manager/

2025-04-15, 10:51:28
Reply #6

Joris

  • Active Users
  • **
  • Posts: 8
    • View Profile
Hi Arpit,

That's exactly what I was trying to do ;)

A few questions:
- if I understand correctly: the option "cache in RAM" is checked on while exporting the proxy? Is that the recommended option? For most scenes, I'm using a lot of proxies, but with 256GB RAM I should be ok? In the Corona lister there's not an option to enable/disable cache in RAM, it can be be switched off in the CoronaProxy properties panel but then I need to do this for each proxy individually.
Just trying to make sure I'm setting everything up in the best possible way.
- Is it possible to export the proxy to point cloud or full mesh? I can change it with the proxy lister, but it would be a bit more practical.

Many thanks.

2025-04-15, 11:05:06
Reply #7

Joris

  • Active Users
  • **
  • Posts: 8
    • View Profile
Hi Tom,

I'm using Connecter for asset management. But maybe Project Manager can be a useful addition, thanks for the suggestion.
Also the PBR Materials Generator seems pretty good.

2025-04-15, 13:47:29
Reply #8

clemens_at

  • Active Users
  • **
  • Posts: 149
    • View Profile
If you are using connecter why don't use the "merge and place as proxy" option?

2025-04-15, 14:22:24
Reply #9

Joris

  • Active Users
  • **
  • Posts: 8
    • View Profile
Hi, with a script I can make the entire library proxies. With Connecter that would require: merging files one by one, retagging an re-assinging previews.