Notifications
Clear all

[Closed] nodeLayerChanged event returns wrong layer after detachFaces

I really hope that this is the result of me doing something wrong, and not yet another issue in the layers system…
I’m trying to track the layer detached nodes are added to. To do this, I use the nodeLayerChanged event callback. When detaching this event is raised, but the layer in the notificationParam is always the active layer. However, after the detach operation has completed, the new node’s layer is not necessarily the active layer, but the layer the object it was detached from is on.

To illustrate the issue, here’s a bit of test code:

(
 resetMaxFile #noPrompt
	
 (LayerManager.newLayer()).current = true
 t = sphere()
 convertTo t Editable_Poly
 (LayerManager.getLayer 0).current = true

 global changedEventLayer, addedEventLayer
 callbacks.removeScripts id:#test
 callbacks.addScript #nodeLayerChanged "changedEventLayer = (callbacks.notificationParam())[3]" id:#test
 callbacks.addScript #sceneNodeAdded "addedEventLayer =  (callbacks.notificationParam()).layer.layerAsRefTarg" id:#test

 polyOp.detachFaces t #{1} asNode:true
	
 local actualLayer = objects[objects.count].layer.layerAsRefTarg
 format "%, %, %
" actualLayer.name changedEventLayer.name addedEventLayer.name;
 assert (actualLayer == changedEventLayer)
 assert (actualLayer == addedEventLayer)
)

The result of which is:

Layer01, 0, 0
Maxscript Assert Failed:  (line 17)
Maxscript Assert Failed:  (line 18)
4 Replies

I’m getting exactly the same error. It seems both callbacks are fired when the object is on layer 0, and then after it is moved to the ‘correct’ layer.

Is there any reason why you arn’t using nodeEventCallback? This always fires after everything has completed, and gives you an array of all modified nodes rather than firing the callback on every individual node:


global nodeCallback

function printInfo s e = (
	for a in e do (
		theNode = getAnimByHandle a
		print (theNode.name + " is on layer " + theNode.layer.name)
	)
)

nodeCallback = nodeEventCallback added:printInfo


(LayerManager.newLayer()).current = true
t = sphere()
convertTo t Editable_Poly
(LayerManager.getLayer 0).current = true
polyOp.detachFaces t #{1} asNode:true
	
/*
	nodeCallback = undefined
	gc light:true
/*

Thanks for reminding me about the NodeEventCallback! The reason I am using the general event is to be able to support max2008, and partially for ‘historical’ reasons. However, this is a good enough reason to stop doing that. Only a handful of people use 2008 nowadays anyway.

I still consider the general event example a defect, but now that there is an alternative, it’s not so bad. Thanks!

No problem, glad to help

Just a warning though, it’s not without it’s own problems. I’ve still yet to find a solution to this particular problem: http://forums.cgsociety.org/showthread.php?f=98&t=1016004

I guess I will have to use one of the other callbacks to detect a target camera node delete, but it’s messy and really shouldn’t be required. Let me know if you ever figure out a good solution!

Thanks for the heads up. That is an annoying little problem indeed…
I have often wondered whether it would be fair to blame the Autodesk people for issues like this. It must be very difficult to make this kind of functionality work properly under all circumstances, since so many different things make use of it (or should make use of it!). On the other hand, a solid, well designed architecture and a policy of “hacking things in” should take care of that… I’m undecided…