Wednesday, 3 April 2013

Splay Normals

Foliage models often require edited normals. There are already normal-splaying scripts out there but I wanted to be able to set a position and use a strength value to effectively splay them partly from the centre of the "bush", and partly from the branch or trunk. I also wanted to be able to splay only the selected verts. This is the result.

USAGE
  • Position the working pivot
  • optionally select some of the verts (if none selected, will select all)
  • optionally set strength to a value like 0.4
  • run script



  
-- MixeScript snippet: SplayNormals
-- Splays selected normals away from the working pivot

--USAGE
-- Position the working pivot
-- select some or all of the verts (if none selected, will select all)
-- optionally set strength to a value like 0.4
-- run script
 
--SETTINGS
Strength = 1.0 -- when set to 1.0, entirely replaces existing normal direction. at 0.0, does not adjust normal at all.

max modify mode
obj = $
modPanel.setCurrentObject obj
enMods = (for m in obj.modifiers where classof m == editnormals collect m)
enMod = enMods[1]
 
subobjectLevel = 1 --verts 
vertarray = #{}
vertarray = polyop.getVertSelection obj
if vertarray.numberSet == 0 then -- no selection, select all
(
 polyop.setVertSelection obj #all
 vertarray = polyop.getVertSelection obj
)


if enMod == undefined then
(
 enMod = editnormals()
 modPanel.addModToSelection (enMod) ui:on
)

 
WPTM = WorkingPivot.getTM()
splayfrom = (WPTM[4])
modPanel.setCurrentObject obj

normarray = enMod.GetSelection()
--enMod.MakeExplicit ()
objpos = obj.pos

modPanel.setCurrentObject enMod
  
for vert in vertarray do (
 vertpos = (enMod.GetVertex vert node:obj) + objpos
 newnormangle = normalize (vertpos - splayfrom)
 tempbitarray = #{vert}
 norms = #{}
 enMod.ConvertVertexSelection tempbitarray norms
 enMod.MakeExplicit selection:norms
 for norm in norms do 
 (  
  existingnormangle = normalize (enMod.GetNormal (norm))
  finalangle = normalize ( newnormangle * Strength + existingnormangle * (1 - Strength))
  enMod.SetNormal norm finalangle
 )
)