RSS FEED

Incremental Grid Slice

If you ever needed a lot of individual chunks instead of a large mesh, you know that it's not so easy to spilt the mesh (in a grid) and detach all the resulting elements into individual meshes. If you only need to separate it in let's say 10,000 individual pieces, this script may be for you:

try destroyDialog sliceInChunks catch()
rollout sliceInChunks "Slice in Chunks" width:187
(
    spinner spnStep1 "" range:[1,10,4] type:#integer width:40 across:3 align:#left
    spinner spnStep2 "\xd7  " range:[1,10,3] type:#integer width:55 offset:[-14,0]
    spinner spnStep3 "\xd7  " range:[1,10,3] type:#integer width:55 align:#right
    checkBox chxHidden "Make the sliced chunks hidden" checked:true align:#center offset:[0,3]
    button btnSlice "" height:27 align:#center offset:[0,5]
    progressBar pbStep1 "" width:170 height:10 color:orange offset:[-5,5]
    progressBar pbStep2 "" width:170 height:10 color:[0,100,180] offset:[-5,0]

    local detachFaces = meshOp.detachFaces
    local getElement = meshOp.getElementsUsingFace
    local meshSlice = meshOp.slice

    fn updateCount =
        btnSlice.text = "     Slice into " + (spnStep1.value^2 * spnStep2.value^2 * spnStep3.value^2) as string + " pieces     "

    mapped fn renameDetached obj formatStr &objCount =
        obj.name += formattedPrint (objCount += 1) format:formatStr

    fn explodeMesh obj intCount &detachedObjs =
    (
        detachedObjs[1] = obj
        for element = 2 to intCount do
        (
            local newMesh = detachFaces obj (getElement obj 1) delete:true asMesh:true
            (detachedObjs[element] = (copy obj name:#detached isHidden:true)).mesh = newMesh
            delete newMesh
        )
    )

    fn explodeMeshNoCollect obj intCount =
        for element = 2 to intCount do
        (
            local newMesh = detachFaces obj (getElement obj 1) delete:true asMesh:true
            (copy obj name:#detached isHidden:true).mesh = newMesh
            delete newMesh
        )

    fn sliceObjXY obj intCount =
    (
        local objFaces = obj.faces
        local sliceWidthX = (obj.max - obj.min).x/intCount
        local slicePosX = obj.min.x - obj.pos.x
        local sliceWidthY = (obj.max - obj.min).y/intCount
        local slicePosY = obj.min.y - obj.pos.y

        for i = 2 to intCount do
        (
            meshSlice obj objFaces [1,0,0] (slicePosX += sliceWidthX) separate:true
            meshSlice obj objFaces [0,1,0] (slicePosY += sliceWidthY) separate:true
        )
        obj
    )

    fn sliceObjChunks obj intStep1 intStep2 intStep3 =
    (
        if queryBox ("This operation will reset undo buffer.\nAre you sure you want to continue?") title:"Warning"
        do with redraw off, undo off
        (
            gc()
            clearSelection()
            statusPanel.visible = false
            setCommandPanelTaskMode mode:#create

            if NOT isKindOf obj Editable_mesh do
                convertToMesh obj

            obj.name = #detached
            hide obj

            local intStep1_2 = intStep1^2, intStep2_2 = intStep2^2, intStep3_2 = intStep3^2
            local progressStep1 = 100/intStep1_2, progressStep2 = 100/intStep2_2
            local detachedObjs = #() ; detachedObjs[intStep1_2] = undefined
            local explodedArr = #() ; explodedArr[intStep2_2] = undefined

            explodeMesh (sliceObjXY obj intStep1) intStep1_2 &detachedObjs

            for each in detachedObjs do
            (
                pbStep2.value = 0
                explodeMesh (sliceObjXY each intStep2) intStep2_2 &explodedArr

                for chunk in explodedArr do
                (
                    explodeMeshNoCollect (sliceObjXY chunk intStep3) intStep3_2
                    pbStep2.value += progressStep2
                )
                each = undefined
                if keyboard.escPressed do exit
                pbStep1.value += progressStep1
            )

            detachedObjs = $detached* as array
            local objCount = 0
            local formatStr = "." + ((detachedObjs.count as string).count as string) + "i"
            renameDetached detachedObjs formatStr &objCount
            if NOT chxHidden.checked do unhide detachedObjs

            statusPanel.visible = true
            pbStep1.value = pbStep2.value = 0
            completeRedraw()
        )
    )

    on sliceInChunks open do updateCount()

    on spnStep1 changed val do updateCount()
    on spnStep2 changed val do updateCount()
    on spnStep3 changed val do updateCount()

    on btnSlice pressed do
    (
        st = timeStamp()
        sliceObjChunks selection[1] spnStep1.value spnStep2.value spnStep3.value
        format "Time: % sec.\n" ((timeStamp() - st)/1000.)        
    ) 
)
createDialog sliceInChunks

USAGE: Select an object that you want to slice, enter numbers that when multiplied together give the number of segments in X as well as Y direction and press the button. If you want to stop execution of the script, press and hold ESC key (it needs to be pressed when the blue bar reaches end). If you don't want the resulting meshes to be hidden, uncheck the checkbox.

Slicer UI

DISCLAIMER: All scripts and snippets are provided as is under Creative Commons Zero (public domain, no restrictions) license. The author and this blog cannot be held liable for any loss caused as a result of inaccuracy or error within these web pages. Use at your own risk.

This Post needs Your Comment!

Return to top