RSS FEED

Select by length

Recently I found myself cleaning up quite heavy terrain mesh where many tiny edges had to be collapsed. Yet another task for maxscript, and as this time I had some time extra I expanded the tool to work on editable splines as well:
try destroyDialog segmentsSelectByLength catch()
rollout segmentsSelectByLength "Select by Length"
(
    spinner spnMinLength "Min. Length: " offset:[-12,0] range:[0,10000,5] enabled:false
    spinner spnMaxLength "Max. Length: " offset:[-12,0] range:[0,10000,50]
    checkBox chxMinLength offset:[142,-40]
    checkBox chxMaxLength offset:[142,0] checked:true
    radioButtons rbSpline labels:#("Splines", "Segments")
    button btnSelect "SELECT" width:160 height:25 offset:[0,2]
    
    local get_vert = polyOp.getVert
    local get_edge_verts = polyOp.getEdgeVerts

    fn getEdgeLengths node edge_index =
    (
        local edge_vertices = get_edge_verts node edge_index
        distance (get_vert node edge_vertices[1]) (get_vert node edge_vertices[2])
    )

    on chxMinLength changed state do
        spnMinLength.enabled = state

    on chxMaxLength changed state do
        spnMaxLength.enabled = state

    on btnSelect pressed do
    (
        case classOf selection[1] of
        (
            Editable_Poly:
            (
                local e_Poly = selection[1]

                clearSelection()

                local lenght_edges
                local min_length = spnMinLength.value
                local max_length = spnMaxLength.value
                local num_edges = polyOp.getNumEdges e_Poly

                setCommandPanelTaskMode mode:#create

                case of
                (
                    (spnMinLength.enabled AND spnMaxLength.enabled): lenght_edges = for i = 1 to num_edges where (local lengths = getEdgeLengths e_Poly i) > min_length AND lengths < max_length collect i
                    (spnMinLength.enabled): lenght_edges = for i = 1 to num_edges where getEdgeLengths e_Poly i > min_length collect i
                    (spnMaxLength.enabled): lenght_edges = for i = 1 to num_edges where getEdgeLengths e_Poly i < max_length collect i
                )
                polyOp.setEdgeSelection e_Poly lenght_edges
                select e_Poly

                setCommandPanelTaskMode mode:#modify
                subObjectLevel = 2
                completeRedraw()
            )
            SplineShape:
            (
                local e_Spline = selection[1]

                clearSelection()

                local min_length = spnMinLength.value
                local max_length = spnMaxLength.value
                local num_splines = e_Spline.numSplines

                setCommandPanelTaskMode mode:#create
                
                if rbSpline.state == 1 then
                (
                    local lenght_splines

                    case of
                    (
                        (spnMinLength.enabled AND spnMaxLength.enabled): lenght_splines = for i = 1 to num_splines where (local lengths = (local all_segs = getSegLengths e_Spline i)[all_segs.count]) > min_length AND lengths < max_length collect i
                        (spnMinLength.enabled): lenght_splines = for i = 1 to num_splines where (local all_segs = getSegLengths e_Spline i)[all_segs.count] > min_length collect i
                        (spnMaxLength.enabled): lenght_splines = for i = 1 to num_splines where (local all_segs = getSegLengths e_Spline i)[all_segs.count] < max_length collect i
                    )
                    setSplineSelection e_Spline lenght_splines
                    select e_Spline

                    setCommandPanelTaskMode mode:#modify
                    subObjectLevel = 3
                )
                else
                (
                    local lenght_segments

                    case of
                    (
                        (spnMinLength.enabled AND spnMaxLength.enabled): lenght_segments = for i = 1 to num_splines collect
                        (
                            local sub_segs = getSegLengths e_Spline i
                            local sub_segs_count_min = ((sub_segs.count - 1)/2 + 1)
                            local sub_segs_count_max = (sub_segs.count - 1)

                            for sub_i = sub_segs_count_min to sub_segs_count_max where (local sub_length = sub_segs[sub_i]) > min_length AND sub_length < max_length collect (sub_i - sub_segs_count_min + 1)
                        )
                        (spnMinLength.enabled):lenght_segments = for i = 1 to num_splines collect
                        (
                            local sub_segs = getSegLengths e_Spline i
                            local sub_segs_count_min = ((sub_segs.count - 1)/2 + 1)
                            local sub_segs_count_max = (sub_segs.count - 1)

                            for sub_i = sub_segs_count_min to sub_segs_count_max where sub_segs[sub_i] > min_length collect (sub_i - sub_segs_count_min + 1)
                        )
                        (spnMaxLength.enabled): lenght_segments = for i = 1 to num_splines collect
                        (
                            local sub_segs = getSegLengths e_Spline i
                            local sub_segs_count_min = ((sub_segs.count - 1)/2 + 1)
                            local sub_segs_count_max = (sub_segs.count - 1)

                            for sub_i = sub_segs_count_min to sub_segs_count_max where sub_segs[sub_i] < max_length collect (sub_i - sub_segs_count_min + 1)
                        )
                    )
                    setSegSelection e_Spline 1 lenght_segments[1]

                    for spline_index = 2 to num_splines do setSegSelection e_Spline spline_index lenght_segments[spline_index]
                    select e_Spline

                    setCommandPanelTaskMode mode:#modify
                    subObjectLevel = 2
                )
                completeRedraw()
            )
            default: messageBox "Not a valid selection!" title: " Error!"
        )
    )
)
createDialog segmentsSelectByLength width:175 height:100
USAGE: Upon execution you can choose if you want to specify the minimal threshold for edge/segment/spline lenght, the maximal one, or you want to use them both. The radio buttons control the script behaviour when used on editable spline, allowing you to choose whether you want to select by lenght whole splines or just their segments.

Select by length interface

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