Maxscript: add Modifier via Callback #sceneNodeAdded

polycounter lvl 11
Offline / Send Message
SimonT polycounter lvl 11
Hi guys. I want to add a modifier right after an object was created. Getting this done via callback seems impossible since Max crashes every time i try to add a modifier.

Any ideas why?

Example works until you comment in the "addModifier" line.
callbacks.removeScripts id:#addMatToObject

fn addMatToObject = (
myNode = callbacks.notificationParam();

print myNode;
--addModifier myNode (Unwrap_UVW ());
)

callbacks.addScript #sceneNodeAdded "addMatToObject()" id:#addMatToObject;

Replies

  • LoTekK
    Offline / Send Message
    LoTekK polycounter lvl 11
    Off the top of my head, you'll probably need to stick this in before the addModifier call:
    max modify mode
    

    Max is really retarded about stuff like that, where you need to explicitly switch to the appropriate mode, otherwise you get a crash and an entirely-unhelpful error message.
  • SimonT
    Offline / Send Message
    SimonT polycounter lvl 11
    Already tried this. Even of you delete all and only let him switch to the mod panel: Crash :(
  • monster
    Offline / Send Message
    monster Polycount Sponsor
    Works for me if I add Box() to the end of the script. It doesn't work with creating primitives in the viewport.

    You can try using NodeEventCallback and use the delay parameter. The only problem is that if another node is added before the unwrap is created it won't add the unwrap to the previous node.
    if callbackItem != undefined do (callbackItem = undefined)
    gc light:true
    
    fn addMatToObject ev AnimHandle =
    (
    	obj = GetAnimByHandle AnimHandle[1]
    	print obj
    	
    	if superclassof obj == geometryclass do
    	(
    		myUVW = Unwrap_UVW()
    		
    		if validModifier obj myUVW do
    		(
    			addModifier obj myUVW
    		)
    	)
    )
    
    callbackItem = NodeEventCallback added:addMatToObject delay:3000
    
  • monster
    Offline / Send Message
    monster Polycount Sponsor
    Another terrible idea is to use your original callback to start a dotNET timer control, with a function that keeps pinging isCreatingObject(). Once it's false it adds the modifier and removes the timer.
  • SimonT
    Offline / Send Message
    SimonT polycounter lvl 11
    Thanks Monster!! I did it like you said via a dotnet timer and it works great! The only thing i miss, is a function to show all active dotnet eventhandler currently running. Because i'm not 100% sure if the timer is deleted completely. Anyway, it works! Here is the code. If you are interested why i do this: i use a script which adds the current selected material to new created objects. Really useful if you create new geometry often which needs the same material. Problem: if it's a multi mat and you want a specified mat id assigned you're f**ked because at this time the box/sphere/... isn't a poly object so you can't use editable poly functions and adding a MATERIAL modifier wasn't possible. UNTIL NOW :)

    Here is my code for adding the uvw mod:
    [COLOR="DarkSlateGray"]--remove all old versions of the event handler[/COLOR]
    callbacks.removeScripts id:#addMatToObject;
    [COLOR="DarkSlateGray"]--make the object variable accessible also for the dot net timer function. the created object will be stored here[/COLOR]
    newNode = "";
    
    [COLOR="DarkSlateGray"]--this function is called until the object creating process is done[/COLOR]
    fn watchCreationProcess sender e = (
    	[COLOR="DarkSlateGray"]--when the creation process of the new object is done, this loop will be executed[/COLOR]
    	if (not isCreatingObject()) do (
    		[COLOR="DarkSlateGray"]--add a modifier which wasn't possible during the creation process: max crash[/COLOR]
    		addModifier newNode (Unwrap_UVW ());
    		[COLOR="DarkSlateGray"]--Stop Timer and remove callbacks[/COLOR]
    		sender.stop();
    		dotnet.removeAllEventHandlers theTimer;
    		sender.Dispose()
    	)
    )
    
    [COLOR="DarkSlateGray"]--this function is called as soon as you create a new object in 3ds max[/COLOR]
    fn addMatToObject = (
    	[COLOR="DarkSlateGray"]--receive the new created object[/COLOR]
    	newNode = callbacks.notificationParam();
    	[COLOR="DarkSlateGray"]--create, setup and start the timer which will start the "watchCreationProcess" function[/COLOR]
    	theTimer = dotNetObject "System.Windows.Forms.Timer";
    	dotnet.addEventHandler theTimer "tick" watchCreationProcess
    	theTimer.interval = 100; --ms
    	theTimer.start()
    )
    
    [COLOR="DarkSlateGray"]--create the callback which makes it possible the react to creating an object[/COLOR]
    callbacks.addScript #sceneNodeAdded "addMatToObject()" id:#addMatToObject;
    
  • monster
    Offline / Send Message
    monster Polycount Sponsor
    Holy Crap Awesome! I just saved it to my MaxScript reference folder.

    removeAllEventHandlers should remove all functions from the timer. Even if Dispose isn't killing the timer it would get removed on the next garbage collection if it has no functions. (Unless you set the life time parameter, which you didn't.)
  • SimonT
    Offline / Send Message
    SimonT polycounter lvl 11
    OFFTOPIC

    oh btw i checked your website and you did a lot cool scripts but maybe some gifs or videos for explanation would be good :) e.g. "key tools" sounds awesome since the built in stuff isnt that good. but i have no idwa what they're doing :D
  • monster
    Offline / Send Message
    monster Polycount Sponsor
    Info on KeyTools
    http://www.polycount.com/forum/showthread.php?t=57061

    I'm working on a KeyTools 2.0 as well as a system called coolRIG. http://www.coolrig.com/

    I'm trying to get them out before the end of the year.
  • SimonT
    Offline / Send Message
    SimonT polycounter lvl 11
Sign In or Register to comment.