Ben Traje
← Back to 3ds-max

Batch Export 3ds Max Hair to Splines via MAXScript

28 Sep 26 (1mo ago)

Automating the Hair and Fur (WSM) modifier in 3ds Max is notoriously difficult due to unreliable or missing API hooks in standard Python (pymxs) and MAXScript.

When direct commands like Tools_Convert.Hair_To_Splines() fail, the most reliable workaround is using UIAccessor to virtually "click" the UI button, bypassing the broken API entirely.

This production-tested MAXScript iterates through selected objects, clicks the conversion button, targets the predictably generated Line001 object, exports it as an OBJ, and cleans up the scene.

Prerequisites

For UIAccessor to work, the target button must be drawn on the screen.

  • Select an object with the Hair modifier, open the Modify panel, and expand the Tools rollout before running the script. 3ds Max will remember this UI state.

The MAXScript

(
    -- 1. CONFIGURATION: Set your export path
    local outputFolder = @"C:\Users\BT\Desktop\"
    makeDir outputFolder
    
    -- 2. UI CLICKER FUNCTION
    fn clickButtonByName btnName = (
        local maxHWND = windows.getMAXHWND()
        local children = windows.getChildrenHWND maxHWND 
        local pressed = false
        for child in children do (
            if (child[5] == btnName) do (
                UIAccessor.PressButton child[1]
                pressed = true
                exit
            )
        )
        return pressed
    )

    local selectionList = selection as array
    
    if selectionList.count == 0 then (
        print "No objects selected."
    )
    else (
        with undo off (
            
            -- SAFETY CLEANUP: Delete leftover 'Line001' from previous crashes
            if ($Line001 != undefined) do delete $Line001

            for obj in selectionList do (
                format "\n------------------------------------------\nProcessing: %\n" obj.name
                
                local hairMod = undefined
                for m in obj.modifiers do (
                    local s = (classOf m) as string
                    if (matchPattern s pattern:"*Hair*Fur*" or matchPattern s pattern:"HairMod") do (
                        hairMod = m
                        exit
                    )
                )
                
                if hairMod != undefined then (
                    
                    -- Force Max into Modify mode to expose UI buttons
                    max modify mode
                    select obj
                    modPanel.setCurrentObject hairMod
                    
                    -- Click the button using UIAccessor
                    if (clickButtonByName "Hair -> Splines") then (
                        
                        windows.processPostedMessages() 
                        
                        -- Directly target the generated spline
                        local newSpline = $Line001
                        
                        if (newSpline != undefined) then (
                            newSpline.name = obj.name
                            local outputFile = outputFolder + obj.name + ".obj"
                            format "  -> Exporting to: %\n" outputFile
                            
                            select newSpline
                            exportFile outputFile #noPrompt selectedOnly:true using:ObjExp
                            delete newSpline
                            format "  -> SUCCESS.\n"
                        ) else (
                            format "  FAILURE: 'Line001' was not generated.\n"
                        )
                    ) else (
                        format "  FAILURE: 'Hair -> Splines' button not found. Expand the Tools rollout.\n"
                    )
                ) else (
                    format "  SKIPPING: No Hair modifier found.\n"
                )
            )
        )
        select selectionList
        format "\nBatch Process Complete.\n"
    )
)

How to Use

  1. Update the outputFolder variable on Line 3 to your desired directory.
  2. In 3ds Max, navigate to Scripting > New Script and paste the code.
  3. Select all target meshes in your scene.
  4. Ensure the Tools rollout is expanded in the Modify panel.
  5. Press Ctrl + E (Evaluate All) to execute the batch process.