Notifications
Clear all

[Closed] morpher: addind progressives via maxscript problem

hey guys,

I did a very simple script ( with the help of Jonathan de  Blok, thanks man!)to add targets to a morpher modifier. The way it works  is simple, it reads the name of the objects you want to add and  whenever 2 objects have the same name, adds them to the same channel, it  reads the sufix of the object and gets the value from there to set the %  of each target. For example: smile_100, smile_025, smile_050. you can  run the script, select the 3 objects and those will be added to the same  channel, each with its own correct value of % BUT i've hit a problem (  maybe a bug ) when doing that, the targets get the right value, but the  little listbox with the targets is in the wrong order, almost if it  doesn't update properly when adding the values via maxscript. Could  anyone have a look and see if I'm just getting crazy or this is indeed a  bug? thanks, here is the code and the usage

 

usage:

1) select your object that has an empty ’Morpher’ modifier applied
2) run script
3) it ask to to pick targets  where name = "chn_percentage" ( ie: smile_100, smile_050, smile_025)

    
    mainObject=selection[1]
    
    trgs=selectByName  prompt:"Pick objects" single:false
    
    --Setup main channels for item with 100%
    channels = #()
    for item in trgs do
    (
    
    	chop=filterString item.name "_"
    	
    	if (chop.count==2) do
    	(
    		chn=chop[1]
    		prc=chop[2] as float
    		 
    		appendIfUnique channels chn   --store channels in an array
    	 
    		chn_index= findItem channels  chn
    		
    		if (prc==100) do
    		( print "aa"
    			WM3_MC_BuildFromNode mainObject.Morpher  chn_index item
    				WM3_SetProgressiveMorphWeight mainObject.Morpher chn_index  item  prc 
    		)
    	)
    	
    )
    
    
    --Setup item with <100% as Prog targets
    
    for item in trgs do
    (
    	chop=filterString item.name "_"
    	
    	if (chop.count==2) do
    	(
    		chn=chop[1]
    		prc=chop[2] as float
    		
    		chn_index= findItem channels  chn
    		 if (prc<100) do
    		(
    			WM3_AddProgressiveMorphNode mainObject.Morpher chn_index item
    			WM3_SetProgressiveMorphWeight mainObject.Morpher chn_index  item  prc 
  
  
  
  for i in 1 to 100 do
   (
   	if WM3_MC_HasData $.morpher i then
   	(
   	numMorph = WM3_NumberOfProgressiveMorphs $.morpher i
   	--append info numMorph
   		for m in 1 to numMorph do
   		(
   			nameProg = WM3_GetProgressiveMorphNode  $.morpher i m
   			print nameProg
   			chop=filterString nameProg.name "_"
   			print chop
   			value = chop[2] as float
   			print value
   			WM3_SetProgressiveMorphWeight $.morpher i nameProg value 
  
  
    		)
    	)
    )
 
 
   
   
    
    
    
21 Replies

single-line code … or maybe it needs formating

sh**iiit, how did that happen?

edited the content again, should be ok now!, thanks

Bumping to see if anyone knows about this issue? thanks!

I have made some modifications to the script. It still needs improvements and clean up, but I hope it does what you need.

(
 	
 	struct morphTarget (node, channel, value)
 	
 	fn SortByName n1 n2 =
 	(
 		if n1.name < n2.name then 1
 			else if n1.name > n2.name then -1
 				else 0
 	)
 	
 	fn GetMorphChannels mMod =
 	(
 		usedChannels = for j = 1 to 100 where WM3_MC_HasData mMod j collect #(j, WM3_MC_GetName mMod j)
 		if usedChannels.count > 0 do
 		(
 			answer = querybox "Would you like to delete existing Morph Channels?"
 			if answer do
 			(
 				for j in usedChannels do WM3_MC_Delete mMod j[1]
 				usedChannels = #()
 			)
 		)
 		usedChannels = for j in usedChannels collect (filterString j[2] "_")[1]
 		return usedChannels
 	)
 	
 	fn AddMorphTargets node =
 	(
 		morpherMod = modPanel.getCurrentObject()
 		if classof morpherMod != Morpher do return undefined
 		
 		channels = GetMorphChannels morpherMod
 		
 		trgs = selectByName single:false
 		if trgs == undefined do return undefined
 		
 		qsort trgs SortByName
 
 		targets = for i in trgs collect
 		(
 			chop=filterString i.name "_"
 			
 			if (chop.count==2) then
 			(
 				chn = chop[1]
 				appendIfUnique channels chn
 				chnIdx = findItem channels chn
 				morphTarget node:i channel:chnIdx value:(chop[2] as float)
 			)else(
 				dontcollect
 			)
 		)
 		
 		for i in targets do
 		(
 			if (i.value==100.0) then
 			(
 				WM3_MC_BuildFromNode morpherMod i.channel i.node
 			)else(
 				WM3_AddProgressiveMorphNode morpherMod i.channel i.node
 			)
 		)
 		
 		for i in targets do WM3_SetProgressiveMorphWeight morpherMod i.channel i.node i.value
 		
 	)
 	
 	AddMorphTargets selection[1]
 	
 )

Hey Jorge! Thanks a lot! I’ll give that a try later on today and I’ll let you know! I’ll see if i can understand your changes as I’m quite a newbie with scripting!

Gracias por la ayuda!

You are welcome Alex.

The code is very similar to the original script, I just removed a few lines and reorganized it a little, but nothing too fancy, so I am sure you will catch up very quick.

The most important change was to sort the array of nodes in order to properly assign to the Weight percentage.

Note that in order to properly sort the nodes, their names must have the same format for the numeric part (3 digits), as in the examples you have. Names like “smile_1” will not be correctly sorted, contrary to “smile_001”.

This issue can be fixed, as Rotem showed in another thread, but I personally prefer to use a fixed number of digits.

Other than that I just added a function GetMorphChannels() (should probably be GetUsedMorphChannels()), to get the used channels if any and to delete all existing used channels if you want, which was useful for testing. It also allows you to add more channels in case you need. For example if you have “smile”, “leg”, “arm” and you just add “smile”, you can later on add the “leg” and “arm” channels.

As it is now you can’t add more targets to an existing channel with their proper Weights. But with some modification it could be done.

If you need me to clarify anything or if the script does not work please let me know.

hey Jorge,

again thanks for the help on this. Unfortunately I’m having the same problem I was having with the previous version of the script, and I think that is just a bug in morpher:
When you add a few targets in the same channel, you have a target list, and the targets show there. Whenever you modify the weight of each target manually, that list updates, and shows the targets with smaller value on top, and as you move your way down the list the target% goes higher according. When you do that via script, the targets get the right value as for the naming convention BUT this target list doesn’t update so even if they have the right values, the position of the targets in that list is wrong, and makes the morphs go crazy ( i believe that only happens if you have more than 2 targets on the same channel…)
I’m uploading a file where shows the 3 targets and according to their values it shoudl read:
a_025
a_050
a_100

BUT it reads:
a_050
a_100
a_025

I’m not sure i’m being clear on where the bug/problem is…?

edit: I cant seem to upload the img file…

I was testing it in Max 2011 and it works well. I now tested it on Max 2012 and 2015 and I have the problem as you. The list does not update correctly. So I think perhaps this is a bug in the modifier.

 I've added a workaround that seems to work in Max 2012+. I hope it works for you too. 
(
 	 
 	 struct morphTarget (node, channel, value)
 	 
 	 fn SortByName n1 n2 =
 	 (
 		 if n1.name < n2.name then 1
 			 else if n1.name > n2.name then -1
 				 else 0
 	 )
 	 
 	 fn GetMorphChannels mMod =
 	 (
 		 usedChannels = for j = 1 to 100 where WM3_MC_HasData mMod j collect #(j, WM3_MC_GetName mMod j)
 		 if usedChannels.count > 0 do
 		 (
 			 answer = querybox "Would you like to delete existing Morph Channels?"
 			 if answer do
 			 (
 				 for j in usedChannels do WM3_MC_Delete mMod j[1]
 				 usedChannels = #()
 			 )
 		 )
 		 usedChannels = for j in usedChannels collect (filterString j[2] "_")[1]
 		 return usedChannels
 	 )
 	 
 	 fn AddMorphTargets node =
 	 (
 		 morpherMod = modPanel.getCurrentObject()
 		 if classof morpherMod != Morpher do return undefined
 		 
 		 channels = GetMorphChannels morpherMod
 		 
 		 trgs = selectByName single:false
 		 if trgs == undefined do return undefined
 		 
 		 qsort trgs SortByName
  
 		 targets = for i in trgs collect
 		 (
 			 chop=filterString i.name "_"
 			 
 			 if (chop.count==2) then
 			 (
 				 chn = chop[1]
 				 appendIfUnique channels chn
 				 chnIdx = findItem channels chn
 				 morphTarget node:i channel:chnIdx value:(chop[2] as float)
 			 )else(
 				 dontcollect
 			 )
 		 )
 		 
 		 for i in targets do
 		 (
 			print i
 			 if (i.value==100.0) then
 			 (
 				 WM3_MC_BuildFromNode morpherMod i.channel i.node
 			 )else(
 				 WM3_AddProgressiveMorphNode morpherMod i.channel i.node
 			 )
 		 )
 		 
 		 for i in targets do WM3_SetProgressiveMorphWeight morpherMod i.channel i.node 0.0
 		for i in targets do WM3_SetProgressiveMorphWeight morpherMod i.channel i.node i.value
 		 
 	 )
 	 
 	 AddMorphTargets selection[1]
 	 
  )

you have to add targets in ‘weight ascending’ order if you want to get them finally in this loading order:

delete objects
 
 fn getTargetWeight node = 
 (
 	prefix = trimright node.name "0123456789"
 	(substring node.name (prefix.count + 1) -1) as float
 )
 fn sortByTargetWeight n1 n2 = 
 (
 	(getTargetWeight n1) - (getTargetWeight n2) 
 )
 
 numtargets = 4
 
 b0 = converttomesh (box name:#source width:10 length:10 height:10 wirecolor:brown)
 targets = for k=1 to numtargets collect
 (
 	name = "target_" + formattedprint (random 0 100) format:"03d"
 	converttomesh (box name:name width:(random 5 20) length:(random 5 20) height:(random 2 40) pos:[30*k,0,0] wirecolor:orange)
 )
 qsort targets sortByTargetWeight
 
 _morpher = Morpher()
 addmodifier b0 _morpher
 
 for k=1 to targets.count do
 (
 	target = targets[k]
 	(if k==1 then WM3_MC_BuildFromNode else WM3_AddProgressiveMorphNode) _morpher 1 target
 )
 for k=1 to targets.count do
 (
 	target = targets[k]
 	weight = getTargetWeight target
 	WM3_SetProgressiveMorphWeight _morpher 1 target weight
 )
 select b0

all other is not really important

Page 1 / 3