PDA

View Full Version : Modifiers unique ID???


kaczorefx
11-11-2010, 08:42 PM
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?

Bobo
11-11-2010, 09:03 PM
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.

denisT
11-11-2010, 10:53 PM
Is there something like a modifiers ID??


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.

kaczorefx
11-12-2010, 11:34 AM
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
11-12-2010, 06:39 PM
Hoped there's a more "profesional" way ;)


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.

Bobo
11-12-2010, 07:24 PM
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.

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...

kaczorefx
11-12-2010, 07:59 PM
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
)

denisT
11-12-2010, 09:27 PM
The thing is the on delete doesn't work.


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

denisT
11-13-2010, 12:25 PM
try to use when <modifier> deleted construct. it might work.

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.

kaczorefx
11-15-2010, 02:23 PM
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?

denisT
11-15-2010, 03:24 PM
//seems that after modifier deletion the obj.plbase is undefined


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).

CGTalk Moderation
11-15-2010, 03:24 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.