美文网首页
3dmax 顶点法线软边工具

3dmax 顶点法线软边工具

作者: Rayson | 来源:发表于2021-02-09 10:21 被阅读0次

    3dmax 顶点法线软边工具
    初始网址:http://www.bytehazard.com/articles/wnormals.html

    image.png
    -- 3DSMAX bugs encountered:
    -- 1) .modifiers[#Edit_Normals] doesn't work on renamed modifiers for no
    --     apparant reason
    -- 2) We can only ever modify the topmost Edit_Normals modifier, even if we
    --    properly access it through its handle. So if there's another Edit_Normals
    --    modifier on the stack, we add a new modifier, so the user won't have his
    --    changes overwritten.
    -- 3) During testing, the script twice crashed on some geometry lacking
    --    smoothing groups. Unable to reproduce.
    
    global wnmodname = "Weighted Normals"
    
    
    -- returns angle between two vectors
    fn AngleBetweenVectors v1 v2 =
    (
     return (acos (dot (normalize v1) (normalize v2) ) )
    )
    
    
    -- get weighted normals modifier
    fn wnGetModifier obj =
    (
     for i=1 to obj.modifiers.count do
     (
      local mf = obj.modifiers[i]
      if (classof mf) == Edit_Normals do
      (
       if (mf.name == wnmodname) then (
        return mf
       ) else (
        return undefined
       )
      )
     )
     return undefined
    )
    
    
    -- generates weighted normals
    fn GenWeightedNormals obj =
    (
     -- filter
     if (superClassOf obj) != GeometryClass do return false
     
     -- add mesh modifier
     if (classOf obj) != Editable_Mesh do
     (
      addModifier obj (Edit_Mesh())
     )
     
     -- detect existing modifier
     local mf = wnGetModifier obj
     
     -- modifier not found, create one
     if mf == undefined do
     (
      addModifier obj (Edit_Normals())
      mf = obj.modifiers[#Edit_Normals]
      mf.name = wnmodname
     )
     
     -- workaround for 3dsmax bug
     select obj
     max modify mode
      
     -- build face area array
     local facearea = #()
     facearea.count = obj.numFaces
     for i=1 to obj.numFaces do
     (
      facearea[i] = (meshop.getFaceArea obj i)
     )
     
     -- build face angle array
     local faceangle = #()
     faceangle.count = obj.numFaces
     for i=1 to obj.numFaces do
     (
      local f = getFace obj i
      local v1 = getVert obj f[1]
      local v2 = getVert obj f[2]
      local v3 = getVert obj f[3]
      local a1 = AngleBetweenVectors (v2-v1) (v3-v1) -- todo: optimize
      local a2 = AngleBetweenVectors (v1-v2) (v3-v2)
      local a3 = AngleBetweenVectors (v1-v3) (v2-v3)
      faceangle[i] = [a1,a2,a3]
     )
     
     -- get number of normals
     local normNum = mf.GetNumNormals()
     
     -- allocate array
     local norms = #()
     norms.count = normNum
     for i=1 to normNum do
     (
      norms[i] = [0,0,0]
     )
     
     -- loop faces
     for i=1 to obj.numFaces do
     (
      -- get face normal
      in coordsys local n = getFaceNormal obj i
      
      -- accumulate
      for j=1 to 3 do
      (
       local id = mf.GetNormalID i j
       norms[id] = norms[id] + (n * facearea[i] * faceangle[i][j])
      )
     )
     
     -- set normals
     for i=1 to normNum do
     (
      -- make explicit
      mf.SetNormalExplicit i explicit:true
      
      -- set normal vector
      mf.SetNormal i (normalize norms[i])
     )
    )
    
    
    --- GUI ------------------------------------------------------------------------
    
    
    -- close existing floater
    if WeightedNormals != undefined do
    (
     closeRolloutFloater WeightedNormals
    )
    
    -- create floater
    WeightedNormals = newRolloutFloater "Weighted Normals" 180 150
    
    
    -- generate rollout
    rollout rWNGenerate "Weighted Normals"
    (
     button cmdCreate "Generate" width:140
     
     on cmdCreate pressed do
     (
      -- copy selection (can't copy arrays in 3dsmax)
      local sel = #()
      for i=1 to selection.count do
      (
       sel[i] = selection[i]
      )
      
      -- create selection list
      for i=1 to sel.count do
      (
       GenWeightedNormals sel[i]
      )
      
      -- restore selection
      selection = sel
     )
    )
    addRollout rWNGenerate WeightedNormals
    
    
    -- about rollout
    rollout rWNAbout "About"
    (
     label lab1 "Weighted Normals 1.0.0"
     label lab2 "by Martijn Buijs"
     label lab3 "www.bytehazard.com"
    )
    addRollout rWNAbout WeightedNormals
    
    
    -- END OF FILE
    

    相关文章

      网友评论

          本文标题:3dmax 顶点法线软边工具

          本文链接:https://www.haomeiwen.com/subject/uqiqxltx.html