Editable Poly sub objects selection and conversion

Get Current Selection as Vertices / Edges / Faces <BitArray vertList> getSelectionAsVerts <Poly poly>
<BitArray edgeList> getSelectionAsEdges <Poly poly>
<BitArray faceList> getSelectionAsFaces <Poly poly>
Gets the current sub-objects level and selection and returns it converted to vertices, edges or faces.
function getSelectionAsVerts oPoly =
(
    if ((classOf oPoly) == Editable_Poly) then
    (
        local iSubObjLev = subObjectLevel
        local baVertSet = #{}

        case iSubObjLev of
        (
            0: (baVertSet = #{1..(polyOp.getNumVerts oPoly)});
            1: (baVertSet = polyOp.getVertSelection oPoly);
            2: (baVertSet = polyOp.getVertsUsingEdge oPoly (polyOp.getEdgeSelection oPoly));
            3: (baVertSet = polyOp.getVertsUsingEdge oPoly (polyOp.getEdgeSelection oPoly));
            4: (baVertSet = polyOp.getVertsUsingFace oPoly (polyOp.getFaceSelection oPoly));
            5: (baVertSet = polyOp.getVertsUsingFace oPoly (polyOp.getFaceSelection oPoly));
        )
        return baVertSet
    )
    else
    (
        throw "Wrong input in function getSelectionAsVerts()"
    )
)

--------------------------------------------------------------------------------

function getSelectionAsEdges oPoly =
(
    if ((classOf oPoly) == Editable_Poly) then
    (
        local iSubObjLev = subObjectLevel
        local baEdgeSet = #{}

        case iSubObjLev of
        (
            0: (baEdgeSet = #{1..(polyOp.getNumEdges oPoly)});
            1: (baEdgeSet = polyOp.getEdgesUsingVert oPoly (polyOp.getVertSelection oPoly));
            2: (baEdgeSet = polyOp.getEdgeSelection oPoly);
            3: (baEdgeSet = polyOp.getEdgeSelection oPoly);
            4: (baEdgeSet = polyOp.getEdgesUsingFace oPoly (polyOp.getFaceSelection oPoly));
            5: (baEdgeSet = polyOp.getEdgesUsingFace oPoly (polyOp.getFaceSelection oPoly));
        )
        return baEdgeSet
    )
    else
    (
        throw "Wrong input in function getSelectionAsEdges()"
    )
)

--------------------------------------------------------------------------------

function getSelectionAsFaces oPoly =
(
    if ((classOf oPoly) == Editable_Poly) then
    (
        local iSubObjLev = subObjectLevel
        local baFaceSet = #{}

        case iSubObjLev of
        (
            0: (baFaceSet = #{1..(polyOp.getNumfaces oPoly)});
            1: (baFaceSet = polyOp.getFacesUsingVert oPoly (polyOp.getVertSelection oPoly));
            2: (baFaceSet = polyOp.getFacesUsingEdge oPoly (polyOp.getEdgeSelection oPoly));
            3: (baFaceSet = polyOp.getFacesUsingEdge oPoly (polyOp.getEdgeSelection oPoly));
            4: (baFaceSet = polyOp.getFaceSelection oPoly);
            5: (baFaceSet = polyOp.getFaceSelection oPoly);
        )
        return baFaceSet
    )
    else
    (
        throw "Wrong input in function getSelectionAsFaces()"
    )
)

Get Inner / Outer Edges using Vertices <BitArray edgeList> getInEdgesUsingVert <Poly poly> <BitArray vertList>
<BitArray edgeList> getOutEdgesUsingVert <Poly poly> <BitArray vertList>
Return a list of all the edges included or along the perimeter of a space defined by the provided list of vertices.
Source Selection Standard Conversion Inner Edges Outer Edges
function getInEdgesUsingVert oPoly baVert =
(
    if ( ((classOf oPoly) == Editable_Poly) and ((classOf baVert) == BitArray) ) then
    (
        if (baVert.isEmpty == true) then ( return #{} )

        local baVertSet01 = #{1..(polyOp.getNumVerts oPoly)} - baVert
        local baEdgeSet01 = polyOp.getEdgesUsingVert oPoly baVertSet01
        local baEdgeSet02 = #{1..(polyOp.getNumEdges oPoly)} - baEdgeSet01

        return baEdgeSet02
    )
    else
    (
        throw "Wrong input in function getInEdgesUsingVert()"
    )
)

--------------------------------------------------------------------------------

function getOutEdgesUsingVert oPoly baVert =
(
    if ( ((classOf oPoly) == Editable_Poly) and ((classOf baVert) == BitArray) ) then
    (
        if (baVert.isEmpty == true) then ( return #{} )

        local baVertSet01 = #{1..(polyOp.getNumVerts oPoly)} - baVert
        local baEdgeSet01 = polyOp.getEdgesUsingVert oPoly baVertSet01

        local baFaceSet01 = polyOp.getFacesUsingVert oPoly baVertSet01
        local baVertSet02 = polyOp.getVertsUsingFace oPoly baFaceSet01
        local baEdgeSet02 = polyOp.getEdgesUsingFace oPoly baFaceSet01

        local baVertSet03 = (baVert - baVertSet02)
        local baEdgeSet03 = polyOp.getEdgesUsingVert oPoly baVertSet03

        local baEdgeSet04 = polyOp.getEdgesUsingVert oPoly baVert

        local baEdgeSet05 = (baEdgeSet04 - baEdgeSet01 - baEdgeSet03) * baEdgeSet02

        return baEdgeSet05
    )
    else
    (
        throw "Wrong input in function getOutEdgesUsingVert()"
    )
)


Get Inner / Outer Faces using Vertices <BitArray faceList> getInFacesUsingVert <Poly poly> <BitArray vertList>
<BitArray faceList> getOutFacesUsingVert <Poly poly> <BitArray vertList>
Return a list of all the faces included or along the perimeter of a space defined by the provided list of vertices.
Source Selection Standard Conversion Inner Faces Outer Faces
function getInFacesUsingVert oPoly baVert =
(
    if ( ((classOf oPoly) == Editable_Poly) and ((classOf baVert) == BitArray) ) then
    (
        if (baVert.isEmpty == true) then ( return #{} )

        local baFaceSet01 = polyOp.getFacesUsingVert oPoly baVert
        local baVertSet01 = #{1..(polyOp.getNumVerts oPoly)} - baVert
        local baFaceSet02 = polyOp.getFacesUsingVert oPoly baVertSet01

        return (baFaceSet01 - baFaceSet02)
    )
    else
    (
        throw "Wrong input in function getInFacesUsingVert()"
    )
)

--------------------------------------------------------------------------------

function getOutFacesUsingVert oPoly baVert =
(
    if ( ((classOf oPoly) == Editable_Poly) and ((classOf baVert) == BitArray) ) then
    (
        if (baVert.isEmpty == true) then ( return #{} )

        local baFaceSet01 = polyOp.getFacesUsingVert oPoly baVert
        local baVertSet01 = #{1..(polyOp.getNumVerts oPoly)} - baVert
        local baFaceSet02 = polyOp.getFacesUsingVert oPoly baVertSet01

        return (baFaceSet01 * baFaceSet02)
    )
    else
    (
        throw "Wrong input in function getOutFacesUsingVert()"
    )
)


Get Inner / Outer Vertices using Edges <BitArray vertList> getInVertsUsingEdge <Poly poly> <BitArray edgeList>
<BitArray vertList> getOutVertsUsingEdge <Poly poly> <BitArray edgeList>
Return a list of all the vertices included or along the perimeter of a space defined by the provided list of edges.
Source Selection Standard Conversion Inner vertices Outer Vertices
function getInVertsUsingEdge oPoly baEdge =
(
    if ( ((classOf oPoly) == Editable_Poly) and ((classOf baEdge) == BitArray) ) then
    (
        if (baEdge.isEmpty == true) then ( return #{} )

        local baVertSet01 = polyOp.getVertsUsingEdge oPoly baEdge
        local baVertSet02 = #{1..(polyOp.getNumVerts oPoly)} - baVertSet01
        local baFaceSet01 = polyOp.getFacesUsingVert oPoly baVertSet02
        local baVertSet03 = polyOp.getVertsUsingFace oPoly baFaceSet01

        return (baVertSet01 - baVertSet03)
    )
    else
    (
        throw "Wrong input in function getInVertsUsingEdge()"
    )
)

--------------------------------------------------------------------------------

function getOutVertsUsingEdge oPoly baEdge =
(
    if ( ((classOf oPoly) == Editable_Poly) and ((classOf baEdge) == BitArray) ) then
    (
        if (baEdge.isEmpty == true) then ( return #{} )

        local baVertSet01 = polyOp.getVertsUsingEdge oPoly baEdge
        local baVertSet02 = #{1..(polyOp.getNumVerts oPoly)} - baVertSet01
        local baFaceSet01 = polyOp.getFacesUsingVert oPoly baVertSet02
        local baVertSet03 = polyOp.getVertsUsingFace oPoly baFaceSet01

        return (baVertSet01 * baVertSet03)
    )
    else
    (
        throw "Wrong input in function getOutVertsUsingEdge()"
    )
)


Get Inner / Outer Faces using Edges <BitArray faceList> getInFacesUsingEdge <Poly poly> <BitArray egdeList>
<BitArray faceList> getOutFacesUsingEdge <Poly poly> <BitArray edgeList>
Return a list of all the faces included or along the perimeter of a space defined by the provided list of edges.
Source Selection Standard Conversion Inner Faces Outer Faces
function getInFacesUsingEdge oPoly baEdge =
(
    if ( ((classOf oPoly) == Editable_Poly) and ((classOf baEdge) == BitArray) ) then
    (
        if (baEdge.isEmpty == true) then ( return #{} )

        local baVertSet01 = polyOp.getVertsUsingEdge oPoly baEdge
        local baFaceSet01 = polyOp.getFacesUsingVert oPoly baVertSet01
        local baVertSet02 = #{1..(polyOp.getNumVerts oPoly)} - baVertSet01
        local baFaceSet02 = polyOp.getFacesUsingVert oPoly baVertSet02

        return (baFaceSet01 - baFaceSet02)
    )
    else
    (
        throw "Wrong input in function getInFacesUsingEdge()"
    )
)

--------------------------------------------------------------------------------

function getOutFacesUsingEdge oPoly baEdge =
(
    if ( ((classOf oPoly) == Editable_Poly) and ((classOf baEdge) == BitArray) ) then
    (
        if (baEdge.isEmpty == true) then ( return #{} )

        local baVertSet01 = polyOp.getVertsUsingEdge oPoly baEdge
        local baFaceSet01 = polyOp.getFacesUsingVert oPoly baVertSet01
        local baVertSet02 = #{1..(polyOp.getNumVerts oPoly)} - baVertSet01
        local baFaceSet02 = polyOp.getFacesUsingVert oPoly baVertSet02

        return (baFaceSet01 * baFaceSet02)
    )
    else
    (
        throw "Wrong input in function getOutFacesUsingEdge()"
    )
)


Get Inner / Outer Vertices using Faces <BitArray vertList> getInVertsUsingFace <Poly poly> <BitArray faceList>
<BitArray vertList> getOutVertsUsingFace <Poly poly> <BitArray faceList>
Return a list of all the vertices included or along the perimeter of a space defined by the provided list of faces.
Source Selection Standard Conversion Inner Vertices Outer Vertices
function getInVertsUsingFace oPoly baFace =
(
    if ( ((classOf oPoly) == Editable_Poly) and ((classOf baFace) == BitArray) ) then
    (
        if (baFace.isEmpty == true) then ( return #{} )

        local baVertSet01 = polyOp.getVertsUsedOnlyByFaces oPoly baFace

        return baVertSet01
    )
    else
    (
        throw "Wrong input in function getInVertsUsingFace()"
    )
)

--------------------------------------------------------------------------------

function getOutVertsUsingFace oPoly baFace =
(
    if ( ((classOf oPoly) == Editable_Poly) and ((classOf baFace) == BitArray) ) then
    (
        if (baFace.isEmpty == true) then ( return #{} )

        local baVertSet01 = polyOp.getVertsUsingFace oPoly baFace
        local baVertSet02 = polyOp.getVertsUsedOnlyByFaces oPoly baFace

        return (baVertSet01 - baVertSet02)
    )
    else
    (
        throw "Wrong input in function getOutVertsUsingFace()"
    )
)


Get Inner / Outer Edges using Faces <BitArray edgeList> getInEdgesUsingFace <Poly poly> <BitArray faceList>
<BitArray edgeList> getOutEdgesUsingFace <Poly poly> <BitArray faceList>
Return a list of all the edges included or along the perimeter of a space defined by the provided list of faces.
Source Selection Standard Conversion Inner Egdes Outer Edges
function getInEdgesUsingFace oPoly baFace =
(
    if ( ((classOf oPoly) == Editable_Poly) and ((classOf baFace) == BitArray) ) then
    (
        if (baFace.isEmpty == true) then ( return #{} )

        local baEdgeSet01 = polyOp.getEdgesUsingFace oPoly baFace
        local baFaceSet01 = #{1..(polyOp.getNumFaces)} - baFace
        local baEdgeSet02 = polyOp.getEdgesUsingFace oPoly baFaceSet01

        local baEdgeSet03 = polyOp.getOpenEdges oPoly

        return (baEdgeSet01 - baEdgeSet02 - baEdgeSet03)
    )
    else
    (
        throw "Wrong input in function getInEdgesUsingFace()"
    )
)

--------------------------------------------------------------------------------

function getOutEdgesUsingFace oPoly baFace =
(
    if ( ((classOf oPoly) == Editable_Poly) and ((classOf baFace) == BitArray) ) then
    (
        if (baFace.isEmpty == true) then ( return #{} )

        local baEdgeSet01 = polyOp.getEdgesUsingFace oPoly baFace
        local baFaceSet01 = #{1..(polyOp.getNumFaces oPoly)} - baFace
        local baEdgeSet02 = polyOp.getEdgesUsingFace oPoly baFaceSet01

        return (baEdgeSet01 * baEdgeSet02)
    )
    else
    (
        throw "Wrong input in function getOutEdgesUsingFace()"
    )
)

Store / Fetch / erase Sub Objects Selections <void> markSubSel <Poly poly> <BitArray subObjectLevels> <Integer bit>
<void> readSubSel <Poly poly> <BitArray subObjectLevels> <Integer bit>
<void> wipeSubSel <Poly poly> <BitArray subObjectLevels> <Integer bit>
Group of functions to store and retrieve sub-object selections regardless of topology modifications.

markSubSel() set a specific flag in the current vertices / edges / faces selection
readSubSel() read the flag set by markSubSel() in vertices / edges / faces selection
wipeSubSel() erase the flag set by markSubSel() in vertices / edges / faces selection

These functions must be used in conjunction, with consistent parameters, in example: store the current vertices selection by setting a flag on bit 32, fetch the vertices selection by getting vertex flagged by bit 32 and erase the selection on vertices by erasing flag on bit 32.
function markSubSel oPoly baLevel iBit =
(
    if ( ((classOf oPoly) == Editable_Poly) and ((classOf baLevel) == BitArray) and \
         ((classOf iBit) == Integer) ) then
    (
        if ( (iBit >= 25) and (iBit <= 32) ) then
        (
            local iFlag = (bit.set 0 iBit true)

            if (baLevel[1] == true) then
                polyOp.setVertFlags oPoly (polyOp.getVertSelection oPoly) iFlag mask:iFlag undoable:true

            if ( (baLevel[2] == true) or (baLevel[3] == true) ) then
                polyOp.setEdgeFlags oPoly (polyOp.getEdgeSelection oPoly) iFlag mask:iFlag undoable:true

            if ( (baLevel[4] == true) or (baLevel[5] == true) ) then
                polyOp.setFaceFlags oPoly (polyOp.getFaceSelection oPoly) iFlag mask:iFlag undoable:true
        )
        else
        (
            throw "Wrong input in function markSubSel(): iBit out of allowed range"
        )
    )
    else
    (
        throw "Wrong input in function markSubSel()"
    )
)

--------------------------------------------------------------------------------

function readSubSel oPoly baLevel iBit =
(
    if ( ((classOf oPoly) == Editable_Poly) and ((classOf baLevel) == BitArray) and \
         ((classOf iBit) == Integer) ) then
    (
        if ( (iBit >= 25) and (iBit <= 32) ) then
        (
            local iFlag = (bit.set 0 iBit true)

            if (baLevel[1] == true) then
                polyOp.setVertSelection oPoly (polyOp.getVertsByFlag oPoly iFlag mask:iFlag)

            if ( (baLevel[2] == true) or (baLevel[3] == true) ) then
                polyOp.setEdgeSelection oPoly (polyOp.getEdgesByFlag oPoly iFlag mask:iFlag)

            if ( (baLevel[4] == true) or (baLevel[5] == true) ) then
                polyOp.setFaceSelection oPoly (polyOp.getFacesByFlag oPoly iFlag mask:iFlag)
        )
        else
        (
            throw "Wrong input in function readSubSel(): iBit out of allowed range"
        )
    )
    else
    (
        throw "Wrong input in function readSubSel()"
    )
)

--------------------------------------------------------------------------------

function wipeSubSel oPoly baLevel iBit =
(
    if ( ((classOf oPoly) == Editable_Poly) and ((classOf baLevel) == BitArray) and \
         ((classOf iBit) == Integer) ) then
    (
        if ( (iBit >= 25) and (iBit <= 32) ) then
        (
            local iFlag = (bit.set 0 iBit true)

            if (baLevel[1] == true) then
                polyOp.setVertFlags oPoly #{} iFlag mask:iFlag undoable:true

            if ( (baLevel[2] == true) or (baLevel[3] == true) ) then
                polyOp.setEdgeFlags oPoly #{} iFlag mask:iFlag undoable:true

            if ( (baLevel[4] == true) or (baLevel[5] == true) ) then
                polyOp.setFaceFlags oPoly #{} iFlag mask:iFlag undoable:true
        )
        else
        (
            throw "Wrong input in function wipeSubSel(): iBit out of allowed range"
        )
    )
    else
    (
        throw "Wrong input in function wipeSubSel()"
    )
)


Get Vertex / Edge / Face Ring <BitArray vertList> getVertRing <Poly poly> <BitArray vertList>
<BitArray edgeList> getEdgeRing <Poly poly> <BitArray edgeList>
<BitArray faceList> getFaceRing <Poly poly> <BitArray faceList>
These functions return a list of vertices / edges / faces forming a selection ring determined by the provided vertices / edges / faces list. In order to work with vertices and faces, at least two contiguous elements must be selected.

Required functions: getInEdgesUsingFace(); markSubSel(); readSubSel(); wipeSubSel();
function getVertRing oPoly baVert =
(
    if ( ((classOf oPoly) == Editable_Poly) and ((classOf baVert) == BitArray) ) then
    (
        undo on
        (
            with redraw off
            (
                markSubSel oPoly #{1..5} 32

                polyOp.setVertSelection oPoly baVert

                oPoly.convertSelection #Vertex #Edge
                oPoly.shrinkSelection selLevel:#Edge
                oPoly.selectEdgeRing()
                oPoly.convertSelection #Edge #Vertex

                local baVertRing = polyOp.getVertSelection oPoly

                readSubSel oPoly #{1..5} 32
                wipeSubSel oPoly #{1..5} 32

                return baVertRing
            )
        )
    )
    else
    (
        throw "Wrong input in function getVertRing()"
    )
)

--------------------------------------------------------------------------------

function getEdgeRing oPoly baEdge =
(
    if ( ((classOf oPoly) == Editable_Poly) and ((classOf baEdge) == BitArray) ) then
    (
        undo on
        (
            with redraw off
            (
                markSubSel oPoly #{1..5} 32

                polyOp.setEdgeSelection oPoly baEdge

                oPoly.selectEdgeRing()

                local baEdgeRing = polyOp.getEdgeSelection oPoly

                readSubSel oPoly #{1..5} 32
                wipeSubSel oPoly #{1..5} 32

                return baEdgeRing
            )
        )
    )
    else
    (
        throw "Wrong input in function getEdgeRing()"
    )
)

--------------------------------------------------------------------------------

function getFaceRing oPoly baFace =
(
    if ( ((classOf oPoly) == Editable_Poly) and ((classOf baFace) == BitArray) ) then
    (
        undo on
        (
            with redraw off
            (
                markSubSel oPoly #{1..5} 32

                local baInputEdge = polyOp.getEdgesUsingFace oPoly baFace

                local baEdgeSet01 = getInEdgesUsingFace oPoly baInputPoly

                local baVertSet01 = polyOp.getVertsUsingEdge oPoly baEdgeSet01
                local baEdgeSet02 = polyOp.getEdgesUsingVert oPoly baVertSet01
                local baEdgeSet03 = (baEdgeSet02 * baInputEdge) - baEdgeSet01

                polyOp.setEdgeSelection oPoly baEdgeSet03
                oPoly.selectEdgeRing()

                local baEdgeSet04 = polyOp.getEdgeSelection oPoly
                local baFaceRing = polyOp.getFacesUsingEdge oPoly baEdgeSet04

                readSubSel oPoly #{1..5} 32
                wipeSubSel oPoly #{1..5} 32

                return baFaceRing
            )
        )
    )
    else
    (
        throw "Wrong input in function getFaceRing()"
    )
)


Get Vertex / Edge / Face Loop <BitArray vertList> getVertLoop <Poly poly> <BitArray vertList>
<BitArray edgeList> getEdgeLoop <Poly poly> <BitArray edgeList>
<BitArray faceList> getFaceLoop <Poly poly> <BitArray faceList>
These functions return a list of vertices / edges / faces forming a selection loop determined by the provided vertices / edges / faces list. In order to work with vertices and faces, at least two contiguous elements must be selected.

Required functions: getInEdgesUsingFace(); markSubSel(); readSubSel(); wipeSubSel();
function getVertLoop oPoly baVert =
(
    if ( ((classOf oPoly) == Editable_Poly) and ((classOf baVert) == BitArray) ) then
    (
        undo on
        (
            with redraw off
            (
                markSubSel oPoly #{1..5} 32

                polyOp.setVertSelection oPoly baVert

                oPoly.convertSelection #Vertex #Edge
                oPoly.shrinkSelection selLevel:#Edge
                oPoly.selectEdgeLoop()
                oPoly.convertSelection #Edge #Vertex

                local baVertLoop = polyOp.getVertSelection oPoly

                readSubSel oPoly #{1..5} 32
                wipeSubSel oPoly #{1..5} 32

                return baVertLoop
            )
        )
    )
    else
    (
        throw "Wrong input in function getVertLoop()"
    )
)

--------------------------------------------------------------------------------

function getEdgeLoop oPoly baEdge =
(
    if ( ((classOf oPoly) == Editable_Poly) and ((classOf baEdge) == BitArray) ) then
    (
        undo on
        (
            with redraw off
            (
                markSubSel oPoly #{1..5} 32

                polyOp.setEdgeSelection oPoly baEdge

                oPoly.selectEdgeLoop()

                local baEdgeLoop = polyOp.getEdgeSelection oPoly

                readSubSel oPoly #{1..5} 32
                wipeSubSel oPoly #{1..5} 32

                return baEdgeLoop
            )
        )
    )
    else
    (
        throw "Wrong input in function getEdgeLoop()"
    )
)

--------------------------------------------------------------------------------

function getFaceLoop oPoly baFace =
(
    if ( ((classOf oPoly) == Editable_Poly) and ((classOf baFace) == BitArray) ) then
    (
        undo on
        (
            with redraw off
            (
                markSubSel oPoly #{1..5} 32

                local baEdgeSet01 = getInEdgesUsingFace oPoly baFace

                polyOp.setEdgeSelection oPoly baEdgeSet01
                oPoly.selectEdgeRing()

                local baEdgeSet02 = polyOp.getEdgeSelection oPoly
                local baFaceLoop = polyOp.getFacesUsingEdge oPoly baEdgeSet02

                readSubSel oPoly #{1..5} 32
                wipeSubSel oPoly #{1..5} 32

                return baFaceLoop
            )
        )
    )
    else
    (
        throw "Wrong input in function getFaceLoop()"
    )
)

Get n-Gon <BitArray faceList> getNgon <Poly poly> <Integer numEdges> [inverse:<Boolean default:false>] Collects all polygons matching the number of edges specified. If "inverse:" optional parameter is set to true, collects all the polygons with number of edges different from the one specified.
function getNgon oPoly iNumEdges inverse:false =
(
    if ( ((classOf oPoly) == Editable_Poly) and ((classOf iNumEdges) == Integer) and \
         ((classOf inverse) == BooleanClass) ) then
    (
        local baAllFace = #{1..(polyOp.getNumFaces oPoly)}
        local baSelFace = #{}

        if (inverse == false) then
        (
            for iFace in baAllFace do
            (
                if ((polyOp.getFaceDeg oPoly iFace) == iNumEdges) then
                (
                    baSelFace[iFace] = true
                )
            )
        )
        else
        (
            for iFace in baAllFace do
            (
                if ((polyOp.getFaceDeg oPoly iFace) != iNumEdges) then
                (
                    baSelFace[iFace] = true
                )
            )
        )

        return baSelFace
    )
    else
    (
        throw "Wrong input in function getNgon()"
    )
)


Get Similar Faces <BitArray faceList> getSimilarFaces <Poly poly> <BitArray faceList> [tolerance:<Float default:2e-5>] Collects all the polygons sharing the same number of edges, surface extension and perimeter with the provided list of faces. "tolerance:" optional parameter, allows to loosen or tighten matching value ranges.
function getSimilarFaces oPoly baInputFace tolerance:2e-5 =
(
    if ( ((classOf oPoly) == Editable_Poly) and ((classOf baInputFace) == BitArray) and \
         ((classOf tolerance) == Float) ) then
    (
        local fThresh = tolerance * 0.5

        local baTestFace = #{1..(polyOp.getNumFaces oPoly)} - baInputFace
        local baSelFace = #{}

        local aaFaceData = #()
        local iNumInputFace = baInputFace.numberSet

        local iFaceDeg = 0
        local fFaceArea = 0.0
        local aiFaceVerts = #()
        local ap3VertPos = #()
        local fAvgEdgeLen = 0.0

        for iFace in baInputFace do
        (
            iFaceDeg = polyOp.getFaceDeg oPoly iFace
            fFaceArea = polyOp.getFaceArea oPoly iFace
            aiFaceVerts = polyOp.getFaceVerts oPoly iFace

            ap3VertPos = #()
            for i = 1 to iFaceDeg do
            (
                ap3VertPos[i] = polyOp.getVert oPoly aiFaceVerts[i]
            )
            ap3VertPos[iFaceDeg+1] = ap3VertPos[1]

            fAvgEdgeLen = 0.0
            for i = 1 to iFaceDeg do
            (
                fAvgEdgeLen += distance ap3VertPos[i] ap3VertPos[i+1]
            )
            fAvgEdgeLen /= iFaceDeg

            append aaFaceData #(iFaceDeg, fFaceArea, fAvgEdgeLen)
        )

        for iFace in baTestFace do
        (
            iFaceDeg = polyOp.getFaceDeg oPoly iFace
            for i = 1 to iNumInputFace do
            (
                if (iFaceDeg != aaFaceData[i][1]) then
                    baTestFace[iFace] = false
            )
        )

        for iFace in baTestFace do
        (
            fFaceArea = polyOp.getFaceArea oPoly iFace

            for i = 1 to iNumInputFace do
            (
                if ( (fFaceArea >= (aaFaceData[i][2] - fThresh)) and \
                     (fFaceArea <= (aaFaceData[i][2] + fThresh)) ) then
                (
                    iFaceDeg = aaFaceData[i][1]
                    aiFaceVerts = polyOp.getFaceVerts oPoly iFace

                    ap3VertPos = #()
                    for j = 1 to iFaceDeg do
                    (
                        ap3VertPos[j] = polyOp.getVert oPoly aiFaceVerts[j]
                    )
                    ap3VertPos[iFaceDeg+1] = ap3VertPos[1]

                    fAvgEdgeLen = 0.0
                    for j = 1 to iFaceDeg do
                    (
                        fAvgEdgeLen += distance ap3VertPos[j] ap3VertPos[j+1]
                    )
                    fAvgEdgeLen /= iFaceDeg

                    if ( (fAvgEdgeLen >= (aaFaceData[i][3] - fThresh)) and \
                         (fAvgEdgeLen <= (aaFaceData[i][3] + fThresh)) ) then
                    (
                        baSelFace[iFace] = true
                    )
                )
            )
        )

        return baSelFace
    )
    else
    (
        throw "Wrong input in function getSimilarFaces()"
    )
)

Get Faces By Angle <BitArray faceList> getFacesByAngle <Poly poly> <Integer startFace> <Float angleDegThreshold> [contig:#none] Collects all the polygons having normal within the specified angle expressed in degrees relative to the start face normal. Contiguity can be specified to limit selection.#none - no contiguity limits
#byVert - faces must be contiguous for at least a vertex
#byEdge - faces must be contiguous for at least an edge
function getFacesByAngle oPoly iFace fDegThresh contig:#none =
(
    if ((classOf oPoly) != Editable_Poly) then
        throw "Wrong input in function getFacesByAngle() - Editable Poly"

    if ((classOf iFace) != Integer) then
        throw "Wrong input in function getFacesByAngle() - Face Index"

    if ( (iFace <= 0) or (iFace > (polyOp.getNumFaces oPoly)) ) then
        throw "Wrong input in function getFacesByAngle() - Face Index out of boundaries"

    if ( (classOf fDegThresh != Float) and (classOf fDegThresh != Integer) ) then
        throw "Wrong input in function getFacesByAngle() - Angle Threshold"

    if ( (fDegThresh < 0) or (fDegThresh > 180) ) then
        throw "Wrong input in function getFacesByAngle() - Angle Threshold out of boundaries"

    -- remove all previous tests if not necessary

    local p3FaceNormal = polyOp.getFaceNormal oPoly iFace
    local fTestDot = cos fDegThresh

    local iNumFaces = polyOp.getNumFaces oPoly
    local p3ItemNormal = [0,0,0]

    if (contig == #none) then
    (
        local baSelFaces = #{1..iNumFaces}

        for i = 1 to iNumFaces do
        (
            p3ItemNormal = polyOp.getFaceNormal oPoly i

            if ((dot p3FaceNormal p3ItemNormal) < fTestDot) then
                baSelFaces[i] = false
        )
    )
    else if (contig == #byVert) then
    (
        local baLimitVerts = #{}
        local baLimitFaces = #{iFace}

        local baSelFaces = #{iFace}
        local baUnselFaces = #{}

        while (baLimitFaces.isEmpty == false) do
        (
            baLimitVerts = (polyOp.getVertsUsingFace oPoly baSelFaces) - (polyOp.getVertsUsedOnlyByFaces oPoly baSelFaces)
            baLimitFaces = (polyOp.getFacesUsingVert oPoly baLimitVerts) - baSelFaces - baUnselFaces

            for item in baLimitFaces do
            (
                p3ItemNormal = polyOp.getFaceNormal oPoly item

                if ((dot p3FaceNormal p3ItemNormal) >= fTestDot) then
                (
                    baSelFaces[item] = true
                )
                else
                (
                    baUnselFaces[item] = true
                )
            )
        )
    )
    else if (contig == #byEdge) then
    (
        local iNumFaces = polyOp.getNumFaces oPoly

        local baLimitVerts = #{}
        local baLimitFaces = #{iFace}

        local baSelFaces = #{iFace}
        local baUnselFaces = #{}

        local baEdgeSet01 = #{}
        local baFaceSet01 = #{}
        local baEdgeSet02 = #{}

        while (baLimitFaces.isEmpty == false) do
        (
            baEdgeSet01 = polyOp.getEdgesUsingFace oPoly baSelFaces
            baFaceSet01 = #{1..iNumFaces} - baSelFaces
            baEdgeSet02 = polyOp.getEdgesUsingFace oPoly baFaceSet01

            baLimitEdges = baEdgeSet01 * baEdgeSet02
            baLimitFaces = (polyOp.getFacesUsingEdge oPoly baLimitEdges) - baSelFaces - baUnselFaces

            for item in baLimitFaces do
            (
                p3ItemNormal = polyOp.getFaceNormal oPoly item

                if ((dot p3FaceNormal p3ItemNormal) >= fTestDot) then
                (
                    baSelFaces[item] = true
                )
                else
                (
                    baUnselFaces[item] = true
                )
            )
        )
    )
    return baSelFaces
)