Home Technical Talk

Unwrapping multiple objects using maxscript

polycounter lvl 6
Offline / Send Message
boon polycounter lvl 6
Hi guys,

I'm having some trouble creating a script with which I can unwrap multiple objects that share the same UV layout. I can achieve it all by hand, but I want to automate it for future use.

I can create a script that flattens per object in the selection, but I want to use FlatIron for packing. And when you flatten objects individually, the elements don't get sized reletive to each other when FlatIron packs them all together.

I tried flatten the objects without normalising enabled so they assume worldspace coordinates (or something like it, they extend very far beyond the boundaries), but that also doesn't generate usable uv's when packing it with FlatIron.

By hand I would do it like this: select all object that I want to share uv's, apply uvw unwrap modifier, open editor, select all faces, flatten quick and dirty, collapse modifier, open FlatIron, pack existing uv's and collapse. That's basicly what I want to do by script. But for some reason it's not very simple to do it seams.

Replies

  • boon
    Options
    Offline / Send Message
    boon polycounter lvl 6
    Hmm... I redid some stuff and individually unwrapping the objects works. I don't know exactly what I did wrong, but it is working now, which is nice.

    for whoever is interested, here's how it works:
    /*--------------------------------------------------------------
    
        OPTIO_batch_unwrapper
        
        Unwraps selection with semi-default settings.
        If you have flatIron installed you can use that to create a 
        decent packed map.
        
        v0.4
            - Actually fixed the incorrect unwrapping of multiple selected objects that shared the same uv space ...
            - ...and in the process simplified the logic a bit.
            - Added individual FlatIron packing per object for quickly unwrapping objects
        
        v0.3
            - Fixed the incorrect unwrapping of multiple selected objects that need to share the same uv space.
        
        v0.2
            - Added support RTT element sizes
        
        v 0.1
            - Initial version
            
        
    -------------------------------------------------------------*/
    
    
        try destroydialog uvToolRollout catch()
    
        struct UnwrapSettings (
            public 
            myChannel = 2,
            myWidth = 256,
            myHeight = 256,
            myAngle = 45.0,
            seePreview = false,
            asGroup = false,
            useRttElementSize = true,
            
            fn SetSettings useChannel texWidth texHeight faceAngle showPreview packAsGroup useRttSizes = (
                myChannel = useChannel
                myWidth = texWidth
                myHeight = texHeight
                myAngle = faceAngle
                seePreview = showPreview
                asGroup = packAsGroup
                useRttElementSize = useRttSizes
            )
        )
        global theSettings = UnwrapSettings()
        
        fn UnwrapIt doFlatIron doCollapse =(
            if doFlatIron == true then (
                Flatiron.unwrap_mode = 2 -- 0 = organic, 1 = hard surface, 2 = pack existing, 3 = keep existing
                Flatiron.map_channel = theSettings.myChannel
                Flatiron.stretch = 0.05
                Flatiron.width = theSettings.myWidth
                Flatiron.height = theSettings.myHeight
                Flatiron.padding = 4
                FlatIron.preview = theSettings.seePreview
                Flatiron.source_channel = theSettings.myChannel
                Flatiron.bake_mode = 1 -- 0 = Multi Pass baking, 1 = Single Pass baking
            )
            
            myObjects = selection as array
            myObjectCount = myObjects.count        
            myNormals = #([1,0,0], [-1,0,0], [0,1,0], [0,-1,0], [0,0,1], [0,0,-1])
            
            max modify mode
            
            if myObjectCount > 0 then (
                for i = 1 to myObjectCount do (
                    myObject = myObjects[i]
                    select myObject
                    
                    addModifier myObject (UVW_Mapping_Clear ())
                    myObject.modifiers[#UVW_Mapping_Clear].mapID = theSettings.myChannel
                    
                    myPolygons = #{}
                    polyop.setFaceSelection myObject myPolygons
                    addModifier myObject (Unwrap_UVW())
                    unwrap = myObject.modifiers[#unwrap_uvw]
                    unwrap.unwrap.setMapChannel theSettings.myChannel
                    
                    if theSettings.asGroup == true do unwrap.unwrap2.flattenMap theSettings.myAngle myNormals 0.002 false 0 true true 
                    if theSettings.asGroup == false do ( 
                        unwrap.unwrap2.flattenMap theSettings.myAngle myNormals 0.002 true 0 true true
                        unwrap.unwrap2.pack 0 0.002 true true true
                    )
                        
                    if doCollapse == true then ConvertTo myObject Editable_Poly
                )            
                
                if doFlatIron == true then (
                    if theSettings.useRttElementSize == true then (
                        if theSettings.asGroup == true then (
                            -- collect the rtt element map size from the selection
                            currSizes = #()
                            for i = 1 to myObjectCount do (
                                myObject = myObjects[i]
                                
                                rttelement = myObject.INodeBakeProperties.getBakeElement 1
                                if rttelement != undefined then  append currSizes rttelement.outputszx
                            )
                                        
                            -- get the largest map size from objects
                            sort currSizes -- sort it out
                            -- get the last one, which is the biggest
                            
                            if currSizes.count > 0 then (
                                Flatiron.width = currSizes[currSizes.count]
                                Flatiron.height = currSizes[currSizes.count]
                            )
                        
                            select myObjects
                            
                            print "Baking selected group"
                            Flatiron.unwrap "unnamed"
                            if doCollapse == true then ConvertTo $ Editable_Poly
                        
                        ) else (
                            for i = 1 to myObjectCount do (
                                myObject = myObjects[i]
                                rttelement = myObject.INodeBakeProperties.getBakeElement 1
                                
                                if rttelement != undefined then (
                                    Flatiron.width = rttelement.outputszx
                                    Flatiron.height = rttelement.outputszy
                                )
                        
                                print ("Baking " + myObject.name + " with RTT sizes")
                                select myObject
                                Flatiron.unwrap "unnamed"
                                if doCollapse == true then ConvertTo $ Editable_Poly
                            )
                        )
                    ) else (
                        for i = 1 to myObjectCount do (
                            myObject = myObjects[i]
                            
                            print ("Baking " + myObject.name + " without RTT sizes")
                            select myObject
                            Flatiron.unwrap "unnamed"
                            if doCollapse == true then ConvertTo $ Editable_Poly
                        )
                    )
                )
            )
            
            myObjects = undefined
            clearselection()
        )
    
        rollout uvToolRollout "UV Batch Packer" (
                    
            group "FlatIron parameters" (
                checkbox useFlatIron "Pack with FlatIron" checked: (try (if FlatIron != undefined then true) catch ( false ) )
                checkbox useRttSizes "Use size of RTT element" checked:true tooltip:"This ignores the width and height settings below"
                spinner texWidth  "Width: \t\t\t" type:#integer range:[128,8192,1024] align:#left enabled:(try not useRttSizes.checked catch false)
                spinner texHeight "Heigth:\t\t\t" type:#integer range:[128,8192,1024] align:#left enabled:(try not useRttSizes.checked catch false)
                checkbox showPreview "Show FlatIron preview" checked:(try FlatIron.preview catch false) tooltip:"Opens the preview from FlatIron. Can open a lot of windows if selection not packed as a group"
                
                button unwrapSelected "Only unwrap selected" width:140 height:50 align:#center
                
                on useFlatIron changed state do (
                    texWidth.enabled = state
                    texHeight.enabled = state
                    useRttSizes.enabled = state
                    showPreview.enabled = state
                    keepTheSeams.enabled = state
                    
                    if state == true then (
                        texWidth.enabled = not state
                        texHeight.enabled = not state
                    )
                )
                
                on useRttSizes changed state do (
                    texWidth.enabled = not state
                    texHeight.enabled = not state
                    
                    theSettings.useRttElementSize = state
                )
                
                on showPreview changed state do ( 
                    theSettings.seePreview = state
                    FlatIron.preview = state 
                )
                
                on packAsGroup changed state do theSettings.asGroup = state
                    
                on unwrapSelected pressed do (
                    Flatiron.unwrap_mode = 1
                    myObjects = selection as array
                    for i = 1 to myObjectCount do (
                        myObject = myObjects[i]
                        rttelement = myObject.INodeBakeProperties.getBakeElement 1
                        
                        if rttelement != undefined then (
                            Flatiron.width = rttelement.outputszx
                            Flatiron.height = rttelement.outputszy
                        )
                        
                        Flatiron.padding = (myObject.INodeBakeProperties.ndilations * 2)
                        
                        print ("Baking " + myObject.name)
                        select myObject
                        Flatiron.unwrap "unnamed"
                        if doCollapse == true then ConvertTo $ Editable_Poly
                    )
                )
            )
            
            group "Options" (
                checkbox packAsGroup "Pack selection as group" checked:true tooltip:"This picks the largest map size from the selected objects"
                spinner useChannel "UV channel:\t" type:#integer range:[1,999,2] align:#left
                spinner faceAngle  "Face angle:\t" type:#float range:[0,180,30] align:#left
                checkbox collapseTo "Collapse when done" align:#left checked:true
            )
    
            /*on showThePreview changed state do (
                print state
                if state == true then (
                    modPanel.addModToSelection (Unwrap_UVW ()) ui:on
                    $.unwrap_uvw.unwrap.setMapChannel theSettings.myChannel
                    modPanel.setCurrentObject $.unwrap_uvw
                    $.modifiers[#unwrap_uvw].unwrap.edit()
                ) else  (
                    if $.modifiers[#unwrap_uvw] != undefined do deleteModifier $ 1
                )         
    
            )*/
    
            button doTheThing "Unwrap and pack selection" width:150 height:50 align:#center
            
            on doTheThing pressed do (
                theSettings.myWidth = texWidth.value
                theSettings.myHeight = texHeight.value
                theSettings.myChannel = useChannel.value
                theSettings.myAngle = faceAngle.value
    
                UnwrapIt useFlatIron.checked collapseTo.checked
            )
            
            on uvToolRollout open do theSettings.SetSettings useChannel.value texWidth.value texHeight.value faceAngle.value showPreview.checked packAsGroup.checked useRttSizes.checked 
                    
            group "About"(
                label lbl1 "v0.4"
            )
        )
        createdialog uvToolRollout 
    
    
  • peanut™
    Options
    Offline / Send Message
    peanut™ polycounter lvl 19
    Hey thanks for this little jewel, i'm not in Max right now but when i do, i will gladly give it a kick.
  • boon
    Options
    Offline / Send Message
    boon polycounter lvl 6
    Thanks. Just be aware that if you don't have FlatIron, it renders some errors. But it can definitly be used without FlatIron if the default packing is good enough for you. Because it already packs the selection.
Sign In or Register to comment.