using weak refence and custome attribute to solve Illigal self-refrence in controlle


#1

Hi everybody

I have some problem about ( Illigal self-refrence in controller script ) in a script controller.
I’ve searched and one of the suggesting solution was using nodeTransformMonitor to avoid this. don’t know maybe i do all wrong or what i’m looking for is sth else so i do my best to show what i’m looking for with an example.
I’m looking for " Releative transform " but in a script controller.
Here the Releative transform but in script window

A= teapot name:"parent" wirecolor:[255,84,0] radius:10
B= Box name:"child" height:5 width:5 length:5 wirecolor:[888,144,225] pos:[15,0,12]
--here the releative transform
--Keep the offset transform from teapot
reTrans = B.transform * inverse A.transform
--testing
A.rotation = EulerAngles 0 90 0 
B.transform = reTrans * A.transform

it works fine but when i want to use this in a script controller my problem begins .and if i try above script in script controller i’ll face Illigal cycle or “Illigal self-refrence in controller script”.
what is my problem when using weak refrence or nodtransform monitor to overcome this problem. here i go

--get back to the original position
A.rotation = EulerAngles 0 0 0 ; B.transform = reTrans * A.transform
--add transform script
Btransscr = B.Transform.controller = transform_script ()
-- i use custome attribute in script controller and maxobject tab in parameter block

ca = Attributes nodestore
(
 parameters nodePar
	(	mycanode type:#maxobject )	 
)
con = B.transform.controller
custAttributes.add con ca
con.mycanode = (nodeTransformMonitor node:B forwardTransformChangeMsgs:false)
con.mycanode.node  --- it turns $Box:child @ [15.000000,0.000000,12.000000]
crtrans = (B.transform) as string
scrText = "
myobjheight = this.mycanode.node.height
print myobjheight
"+ crtrans
Btransscr.script = scrText

it is ok and the script knows the object’s height ,but when i try to get the transform of the box again it complain from Illigal self-refrence in controller script

scrText = "
myobjheight = this.mycanode.node.height
print myobjheight
myobjtrans = this.mycanode.node.transform
print myobjtrans
"+ crtrans
Btransscr.script = scrText

where is my problem even i use type:#maxObjectTab instead of type:#maxobject again the same thing happen the difrence is the first one is in an array form.
or is it possible to do this in script controller?

Thanks in advance


#2

in custom attribute you put weak reference - nodetransformmonitor . it’s OK
but when you ask its transform it’s not weak anymore. you ask the controller inside this controller. it’s self- referencing for sure.

you have to store probably original matrix as constant … and you can do it without CA

delete objects
p = point name:#child size:40 wirecolor:orange

init_tm = p.transform
c = p.transform.controller = transform_script()
c.addconstant "init_tm" init_tm
c.setexpression "print init_tm; translate init_tm [0,0,F]"

#3

now is example #2

delete objects
p = box name:#child

init_tm = p.transform
c = p.transform.controller = transform_script()
c.addconstant "init_tm" init_tm
c.addnode "owner" p
c.setexpression "translate init_tm [0,0,-owner.height]"

here is weak referencing to itself. it works… but if you change time. it’s because “weak-referencing” suppresses all messages from this reference

so you need normal reference but not to the node itself but “height” subanim:

delete objects
p = box name:#child

init_tm = p.transform
c = p.transform.controller = transform_script()
c.addconstant "init_tm" init_tm
c.addtarget "owner_height" p.baseobject[#height]
c.setexpression "translate init_tm [0,0,-owner_height]"  

now it works as expected


#4

Thank you so much for your reply Denis

For adding an object’s transform as constant i did that befor but i couldn’t get what i was looking for, maybe for my bad scripting here my try of Releative trans in script controller before this post

A= teapot name:"parent" wirecolor:[255,84,0] radius:10
B= Box name:"child" height:5 width:5 length:5 wirecolor:[888,144,225] pos:[15,0,12]
init_tm = B.transform
c = B.transform.controller = transform_script()
c.addconstant "init_tm" init_tm
c.addnode "parentt" A

scr = "
reTrans = init_tm * inverse parentt.transform
reTrans * parentt.transform
"
c.script = scr

But it doesn’t work for me, that was why i try that way.


#5

Sorry if i didn’t understand well finally :

Can we do that in a script controller? i mean referring a node or its transform or position by itself not the height or …


#6

no, we can’t. we can store it with controller, but can’t call it.

but as i see from your code above you are saving another node transform (a la parent). it’s legal.

delete objects
d = dummy name:#parent boxsize:[10,10,10]
p = box name:#child wirecolor:orange

c = p.transform.controller = transform_script()
c.addnode "parent" d
c.addtarget "owner_height" p.baseobject[#height]
c.setexpression "(transmatrix [0,0,-owner_height]) * parent.transform"

#7

My goal is to change environment map at render time for certain frames and that’s what I got.


resetMaxFile #noprompt
out = output()

def = vraycolor color:black
r   = vraycolor color:red
g   = vraycolor color:green
b   = vraycolor color:blue

out.map1enabled = true
out.map1 = def

out.output.rgb_offset.controller = float_script()
out.output.rgb_offset.controller.script = "

    self = ::out        --(refs.dependents this)[3]
    dependson self
    
    case F of (
    
        1: self.map1 = ::r
        2: self.map1 = ::g
        3: self.map1 = ::b
        default: self.map1 = ::def    
    
    )

0.0
"

environmentMap    = out
meditMaterials[1] = out  

And now the question is how can I get a reference of textureMap that is owner of this particular script controller without using global variable?
If I use (refs.dependents this)[3] it seems to work fine when I put this output map in simple materialEditor but fails in SME (throws circular-selfreference error)


#8

out = output()
s = out.output.rgb_offset.controller = float_script()
s.addobject "owner" (reftargmonitor reftarg:out)
s.script = "print owner.reftarg; 0"


#9

Thanks, Denis. Works great.