Notifications
Clear all

[Closed] Modifiers unique ID???

Is there something like a modifiers ID??

I’m writing a modifier that creates an image plane for a camera.
You could put multiple modifiers to get multiple image planes, but then I need to determine for a callback script, which modifier was deleted so that the callback deletes the apropriate image plane.

I was thinking about storing the modifiers id in user properties inside the plane and then after modifier deleted event, go throught all the planes and delete the one with a stored id of the deleted modifier – but I need the id in the first place

Or maybe there is a onDelete event for the modifier that works?
(on deleted doesn’t really work – waits for the Undo cache to clear???)
On enabled and On disabled events would also be nice, but I can’t seem to find anything like it

And another thing:
I’m using a weak reference to store the camera object – it works well, except when I try to save a scene state – I get an error at the first line with the variable storing the object saying that it is undefined?

10 Replies
1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

see mxs help -> AnimHandle System

but you have to understand that AnimHadle is unique just for current scene. Any merged or xreffed node gets new handle – different then it was created with.

You could generate your own unique ID when the Modifier is created, and then store that ID in the plane’s AppData or someplace like that. I use this approach in the Krakatoa Channels Modifiers, since each modifier needs a set of tracks in Trackview that has a unique name. So I added a parameter to the paramblock to store the ID and use it to track the relationships between tracks and modifiers.

Hmm, yes, already generating my own ID.
Hoped there’s a more “profesional” way

Any ideas regarding the scene state problem?
It’s as if the maxObject parameter loses it’s data during the process

 PEN

If Bobo said that is the way he does it then that would be the most professional way.

You could also store the image plane as a weak reference in the modifier.

1 Reply
(@bobo)
Joined: 11 months ago

Posts: 0

Thanks for the flowes, but no, just because I do something doesn’t make it professional
I have done a bunch of stupid things over the years, and there is still much I have to learn about MAXScript… We are all perpetual learners.

The modifier has an ‘on Deleted do()’ handler, so if the paramblock of the modifier has the image plane stored, it should be possible to delete the plane when the modifier is deleted without having a unique ID. But I might be missing some details…

The thing is the on delete doesn’t work.
The manual explains it is because the event gets called when the modifier gets deleted from the scene.
Problem is, it doesn’t get deleted from the scene when you delete it in the modifier stack – it’s still in the undo buffer, in case you want to… well… undo.
You have to wait for the undo list to overflow or clean the undo cache – then the event gets called – not really usefull in real life I’m afraid

But still, here is the simplest code, any ideas why the save scene state (with cameras checked) throws an error?

 
(
 
plugin modifier efx_ImagePlane name:"efx_ImagePlane" classID:#(0x56ccee81, 0x20e0fc2b) extends:EmptyModifier replaceUI:true version:1 silentErrors:false initialRollupState:0
(
local obj=undefined
local pl=undefined
 
parameters basicParameters rollout:BasicRollout
(
dist type:#float animatable:true ui:spn_dist
objbase type:#maxObject
plbase type:#maxObject
 
objname type:#String
plname type:#String
)
 
fn updatePlug = (
-- retrieve objects after scene open
if obj==undefined then obj=objbase.node
if pl==undefined AND plbase!=undefined then pl=plbase.node
 
 
-- if an object wasn't retrieved (it has been deleted) - create it
if pl==undefined or isvalidnode pl==false then (
	pl=Plane name:(uniquename (obj.name+"_ImagePlane")) lengthsegs:1 widthsegs:1
	pl.transform=obj.transform
	pl.parent=obj
	pl.pos=[0,0,-20]
	plname=pl.name
	setUserProp pl "EFX_ImagePlane" true 
	plbase=nodeTransformMonitor node:pl forwardTransformChangeMsgs:false
)
 
-- plane transforms
pl.transform=obj.transform
in coordsys parent pl.pos=[0,0,-dist]
r_aspect=(renderWidth as float)/renderHeight*renderPixelAspect
vfov = atan(tan(obj.fov/2.0)/r_aspect)*2
pl.width=2*dist*tan(obj.fov/2)
pl.length=2*dist*tan(vfov/2)
)
 
 
rollout BasicRollout "Basic setup" width:160 height:184
(
label lbl1 "Label" pos:[8,8] width:144 height:16
spinner spn_dist "distance:" pos:[32,32] width:120 height:16 range:[0.001,100000,40] type:#worldunits
groupBox grp1 "Image" pos:[2,72] width:156 height:104
 
 
on spn_dist changed arg do (
updatePlug()
)
)
 
on attachedToNode obj do
(
-- get all the nodes on which this modifier has been added
theNodes=(refs.dependentNodes this)
 
-- if the modifier is instanced, make it unique
if theNodes.count >1 then
(
	for i = 2 to theNodes.count do
	(
		deleteModifier theNodes[i] this
	)
)
 
-- if the modifier is added on something else than a camera, remove it
if theNodes[1]!=undefined and (superClassOf theNodes[1])!=camera then 
(
	 deleteModifier theNodes[1] this
	 Messagebox("Not a supported object for this modifier. Applies only to cameras.")
) else -- if good object, enable modifier
( 
	 objbase=nodeTransformMonitor node:theNodes[1] forwardTransformChangeMsgs:false
	 dist=40
	 updatePlug()
)
)
 
on deleted do (
delete pl
)
 
) -- plugin
)
 
 

2 Replies
(@denist)
Joined: 11 months ago

Posts: 0

try to use when <modifier> deleted construct. it might work.

(@denist)
Joined: 11 months ago

Posts: 0

nope… it’s not working.

but when geometry <modifier> change (or topology, or parameters) construct works. The event fires on delete from modifiers stack (on detach from node). Of course this event will be sent for many other reasons but all that you need is to check if the modifier is still assigned to any node. With dependency test it shouldn’t take a long time. The good thing is that the event fires on undo/redo as well. So you have a chance to keep the relation “modifier-plane” in order.

Hmm interesting approach.

when parameters this changes obj do (
if obj.enabled==true AND obj.plbase.node!=undefined then unhide obj.plbase.node
if obj.enabled==false AND obj.plbase.node!=undefined then hide obj.plbase.node
if (refs.dependentnodes obj).count<1 then delete obj.plbase.node – not working
)

//seems that after modifier deletion the obj.plbase is undefined

Hard to use with deletion of the modifier (the event gets fired, but you can’t supply it with internal variables, and since it’s after deletion you can’t access paramblock of the modifier – will have to think of a way to supply it with the plane object to delete), but I can do a modifier state lookup this way and hide or show the image plane

Any ideas on the save scene state issue?

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

that’s unlikely. The deleting from stack doesn’t mean the deleting of the modifier. The modifier stays all the time alive as well as all its param blocks (parameters).