微信公众号 小红书 抖音 B站
小黑屋 渝ICP备2023015870号-1
网信算备88888888号
生成式人工智能服务管理暂行办法
备案号:88888888-20240226
首页 插件专区 Max插件 编辑 regularizeedgeloop V2.01 正则化边循环MS源码
regularizeedgeloop V2.01 正则化边循环MS源码
查看 7 下载 1 收藏 纠错
  • 应用平台: Windows XP , Windows 7 , Windows 8 , Windows 10 , Windows 11
  • 软件支持: 32位/64位
  • 界面语言: 英语


macroScript EditPoly_RegularizeEdgeLoop buttonText:"Regularize(EditPoly)" category:"rapidTools" toolTip:"Regularize Edge Loop (EditPoly)" (

        

        global theObj

        global theObject

        global theEdges

        global theLoops

        global baseSubLevel

        global currentMod

        global currentModIndex

               

        --on IsEnabled return Filters.Is_EditPolySpecifyLevel #{3..5}

        --on IsVisible return Filters.Is_EditPolySpecifyLevel #{3..5}

               

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

               

---------------------------------------------------------------------------------------------------------------- EDITABLE POLY ----------------------------------------------------------------------------------------------------------------------

                --check for validity / build one vertex array per loop

        function buildTheLoops = (

                --shorthands/optimization

                local v2e = polyOp.getEdgesUsingVert

                local e2v = polyOp.getVertsUsingEdge

               

                while not theEdges.isEmpty do

                (

                        local theEdge = (theEdges as array)[1]

                        local theVerts = polyOp.getEdgeVerts theObject theEdge

                        theEdges -= #{theEdge}

                        local vertA = theVerts[1]

                        local vertB = theVerts[2]

                        

                        while true do

                        (

                                vertA = vertB

                                local theConnected = (v2e theObject vertA) * theEdges

                                local cnt = theConnected.numberSet

                                if cnt > 1 do return 1  --branching edges

                                if cnt == 0 then

                                (

                                        if theVerts[1] != theVerts[theVerts.count] do return 2  --open loop

                                        deleteItem theVerts theVerts.count

                                        exit

                                )

                                else theEdge = (theConnected as array)[1]

                                vertB = (((e2v theObject theEdge) - #{vertA}) as array)[1]

                                append theVerts vertB

                                theEdges -= #{theEdge}

                                

                        )--end while true

                        

                        append theLoops theVerts

                        

                )--end while not theEdges.isEmpty

               

                return 0  --edge loops valid

               

        )-- end function buildTheVerts

        

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

        

        --make edge loops regular

        function makeRegular = (

                --shorthands/optimization

                local getPos = polyOp.getVert

                local setPos = polyOp.setVert

               

                for theLoop in theLoops do

                (

                        local theCount = theLoop.count

                        if theCount < 3 do return 1  --no need to rearrange 2 edges


                        --average position of all vertices

                        local theCenter = [0,0,0]

                        for i = 1 to theCount do theCenter += getPos theObject theLoop

                        theCenter /= theCount


                        --triangles formed by each edge in loop and theCenter

                        --average of their normals, weighted by their surfaces

                        local theDir = [0,0,0]

                        for i = 1 to theCount do

                                theDir += cross (getPos theObject theLoop - theCenter) (getPos theObject theLoop[mod i theCount + 1] - theCenter)

                        

                        --coordinate system local to the loop

                        local theLocalTM = matrixFromNormal (normalize theDir)

                        theLocalTM.translation = theCenter


                        in coordSys theLocalTM

                        (

                                local theCoords = for i = 1 to theCount collect

                                        (getPos theObject theLoop) * [1,1,0]  --make planar in theLocalTM (z = 0)


                                local theRadius = 0  --average distance from theCenter

                                local theDelta = 360.0 / theCount  --average angle variation

                                local theOffset = 0  --average variations of ith vector from i * theDelta

                                

                                for i = 1 to theCount do

                                (

                                        local p = theCoords

                                        theRadius += length p

                                        local theAngle = atan2 p.y p.x

                                        theOffset += mod (720 + theAngle - theDelta * i) 360  --needs to be positive

                                )

                                

                                theRadius /= theCount

                                theOffset /= theCount

                                

                                for i = 1 to theCount do

                                (

                                        local theAngle = theOffset + theDelta * i

                                        setPos theObject theLoop ((theRadius * [cos theAngle, sin theAngle, 0]))

                                )

                                

                        )--end in coordSys theLocalTM

                        

                )--end for theLoop in theLoops

               

        )--end function makeRegular()

        

---------------------------------------------------------------------------------------------------------------- EDITABLE POLY ----------------------------------------------------------------------------------------------------------------------


-------------------------------------------------------------------------------------------------------------------- EDIT POLY --------------------------------------------------------------------------------------------------------------------------

        

-------------------------------------------------------------------------------------------------- BASE FUNCTIONS FOR EDIT POLY -------------------------------------------------------------------------------------------------------

        

        function getVertEdgesEP theVertex theObj = ( -- Egy Vertex 閘eit adja vissza, sorrendben

                if         theVertex != undefined then (

                        edgeArrayEP = #()

                        getVertEdge = theObj.modifiers[currentModIndex].GetVertexEdge

                        i = 1

                        do (

                                edgeIndex = getVertEdge theVertex i

                                append edgeArrayEP edgeIndex

                                i=i+1

                        )

                        while (edgeIndex != 0)

                        deleteItem edgeArrayEP (edgeArrayEP.count)

                        return edgeArrayEP

                        )

                else return undefined

        )

        

        function getEdgeVertsEP theEdge theObj = ( -- Egy Vertex 閘eit adja vissza, sorrendben

                if         theEdge != undefined then (

                        vertArrayEP = #()

                        getEdgeVert = theObj.modifiers[currentModIndex].GetEdgeVertex

                        i = 1

                        do (

                                edgeIndex = getEdgeVert theEdge i

                                append vertArrayEP edgeIndex

                                i=i+1

                        )

                        while (edgeIndex != 0)

                        deleteItem vertArrayEP (vertArrayEP.count)

                        return vertArrayEP

                        )

                else return undefined

        )

        

        function getVertsUsingEdgeEP theEdges theObj = (

        theVertices = #()

        theEdges = theEdges as array

        theEdgesCount = theEdges.count

                for i = 1 to theEdgesCount do (

                        theVertices = theVertices + (getEdgeVertsEP theEdges theObj)

                )

                return theVertices as bitarray

        )

        

        function getEdgesUsingVertEP theVerts theObj = (

        theEdges = #()

        theVerts = theVerts as array

        theVertsCount = theVerts.count

                for i = 1 to  theVertsCount do (

                        theEdges = theEdges + (getVertEdgesEP theVerts theObj)

                )

                return theEdges as bitarray

        )

        

        function setVertEP theVertex destination theObject  = ( -- this one generates an offset array from the actual and destination position -- returns into an array

               

                theMod = $.modifiers[currentModIndex]

               

                theMod.select #Vertex #{theVertex}

                actual = theObject.modifiers[currentModIndex].getVertex theVertex

                newPos = destination - actual

                theMod.MoveSelection newPos

                theMod.Commit()

                theMod.setSelection #Vertex #{}

               

                --return newPos

        )

        

        function getVertEP theVertex theObject = (

        

                actual = theObject.modifiers[currentModIndex].getVertex theVertex

                return actual

        )

        


-------------------------------------------------------------------------------------------------- BASE FUNCTIONS FOR EDIT POLY -------------------------------------------------------------------------------------------------------

        

                        --check for validity / build one vertex array per loop

        function buildTheLoopsEP = (


                while not theEdges.isEmpty do

                (

                        local theEdge = (theEdges as array)[1]

                        local theVerts = getEdgeVertsEP theEdge theObject

                        theEdges -= #{theEdge}

                        local vertA = theVerts[1]

                        local vertB = theVerts[2]

                        

                        while true do

                        (

                                vertA = vertB

                                local theConnected = ((getVertEdgesEP vertA theObject) as bitarray) * (theEdges as bitarray)

                                local cnt = theConnected.numberSet

                                if cnt > 1 do return 1  --branching edges

                                if cnt == 0 then

                                (

                                        if theVerts[1] != theVerts[theVerts.count] do return 2  --open loop

                                        deleteItem theVerts theVerts.count

                                        exit

                                )

                                else theEdge = (theConnected as array)[1]

                                vertB = ((((getEdgeVertsEP theEdge theObject as bitarray)) - #{vertA}) as array)[1]

                                append theVerts vertB

                                theEdges -= #{theEdge}

                                

                        )--end while true

                        

                        append theLoops theVerts

                        

                )--end while not theEdges.isEmpty

               

                return 0  --edge loops valid

               

        )-- end function buildTheVerts

               

        --make edge loops regular

        function makeRegularEP = (

                --shorthands/optimization

               

                theObject.modifiers[currentModIndex].enabled = false

                with redraw off (

                subobjectlevel = 1

                for theLoop in theLoops do

                (

               

                        local theCount = theLoop.count

                        if theCount < 3 do return 1  --no need to rearrange 2 edges

                                

                        --average position of all vertices

                        local theCenter = [0,0,0]

                        for i = 1 to theCount do theCenter += getVertEP theLoop theObject

                        theCenter /= theCount


                        --triangles formed by each edge in loop and theCenter

                        --average of their normals, weighted by their surfaces

                        local theDir = [0,0,0]

                        for i = 1 to theCount do

                                theDir += cross ((getVertEP theLoop theObject) - theCenter) ((getVertEP (theLoop[(mod i theCount) + 1]) theObject) - theCenter)


                        --coordinate system local to the loop

                        local theLocalTM = matrixFromNormal (normalize theDir)

                        (theLocalTM.translation = theCenter)


                        ---------------> in coordSys theLocalTM <--------------- doing it manually


                                local theCoords = for i = 1 to theCount collect (getVertEP theLoop theObject) * (inverse thelocalTM) * [1,1,0]  --make planar in theLocalTM (z = 0)

                                local theRadius = 0  --average distance from theCenter

                                local theDelta = 360.0 / theCount  --average angle variation

                                local theOffset = 0  --average variations of ith vector from i * theDelta

                                

                                for i = 1 to theCount do

                                (

                                        local p = theCoords

                                        theRadius += length p

                                        local theAngle = atan2 p.y p.x

                                        theOffset += mod (720 + theAngle - theDelta * i) 360  --needs to be positive

                                )

                                

                                theRadius /= theCount

                                theOffset /= theCount

                                

                                for i = 1 to theCount do

                                (

                                        local theAngle = theOffset + theDelta * i

                                        setVertEP theLoop ((theRadius * [cos theAngle, sin theAngle, 0]) * (thelocalTM)) theObject --tm:theLocalTM

                                )

                        ---------------> in coordSys theLocalTM <--------------- doing it manually

                                

                )--end for theLoop in theLoops

        )

        theObject.modifiers[currentModIndex].enabled = true

        

        )--end function makeRegular()

        

-------------------------------------------------------------------------------------------------------------------- EDIT POLY --------------------------------------------------------------------------------------------------------------------------

        

-------------------------------------------------------------------------------------------------------- MAIN EXECUTION CONTROL -----------------------------------------------------------------------------------------------------------

        

        -- macro body

        ts = timestamp()

        setCommandPanelTaskMode #modify

        global currentMod = modpanel.getCurrentObject()

        

        if classOf currentMod == Editable_Poly then (

                theLoops =#()

                theObject = $

                if subobjectLevel == 4 do theObject.editablePoly.convertSelectionToBorder #face #edge

                if (theEdges = polyOp.getEdgeSelection theObject).isEmpty then (

                        MessageBox "Selection is Empty" Title:"Poly Editing" )

                else if (polyOp.getVertsUsingEdge theObject theEdges).numberSet != theEdges.numberSet then (

                        MessageBox "Invalid Edge Loop(s)" Title:"Poly Editing" )

                else case buildTheLoops() of (

                        1: MessageBox "Branching Edge Loop(s)" Title:"Poly Editing"

                        2: MessageBox "Open Edge Loop(s)" Title:"Poly Editing"

                        0: makeRegular()

                )

                print ("Time to solve: " + ((((timestamp() - ts) as float)/1000) as string) + " sec")

        )

               

        if classOf currentMod == Edit_Poly then (

                theLoops =#()

                theObject = $

                currentModIndex = modPanel.getModifierIndex $ (modPanel.getCurrentObject())

               

                ---------------------- STORE SELECTION STATE ----------------------

                        

                baseSubLevel = subobjectlevel -- storeing the base subobject level

                baseVertSelection = theObject.modifiers[currentModIndex].getSelection #Vertex

                theObject.modifiers[currentModIndex].setSelection #Vertex #{}

                        

                ---------------------- STORE SELECTION STATE ----------------------

                        

                        if subobjectLevel == 4 do theObject.modifiers[currentModIndex].convertSelectionToBorder #face #edge

                theEdges = (theObject.modifiers[currentModIndex].getSelection #edge)

                if theEdges.isEmpty then (

                        MessageBox "Selection is Empty" Title:"Poly Editing" )

                else if (getVertsUsingEdgeEP theEdges theObject).numberSet != theEdges.numberSet then (

                        MessageBox "Invalid Edge Loop(s)" Title:"Poly Editing" )

                else case buildTheLoopsEP() of (

                        1: MessageBox "Branching Edge Loop(s)" Title:"Poly Editing"

                        2: MessageBox "Open Edge Loop(s)" Title:"Poly Editing"

                        0: makeRegularEP()

                )

        theObject.modifiers[currentModIndex].select #Vertex baseVertSelection

        subobjectlevel = baseSubLevel -- restore the base subobject level

        print ("Time to solve: " + ((((timestamp() - ts) as float)/1000) as string) + " sec")

        )

)--end script


发表评论
  • 顺带评个分
提交
  • 834544123 在线客服

  • 周一至周五:9:00-21:00

    周末及节日:9:00-18:00

  • QQ&微信:
    834544123
    QQ群:
    16538234