PDA

View Full Version : passing to and returning arguments


em3
07-25-2011, 05:21 PM
I have been sort of struggling to understand passing arguments to functions lately. Just when I think I have it, I get tripped up.

here is some code for a very basic script that gets an objects bounding box


fn getBBounds theBB theObject =
(
local c
local myBB = theBB
local theU
(
c = snapshot theObject
c.transform = matrix3 1
myBB = c.max - c.min
theBB = myBB
bb = theBB
print theBB as string
--b = box width:bb[1] length:bb[2] height:bb[3]
delete c
)
)

Rollout TheMinMaxChecker "MinMaxChecker"
(
button btnOK "Check it"
checkbox chkAll "All"
edittext txtValue width:200 height: 25
on btnOK pressed do
(

bb = [0.0,0.0,0.0]
getBBounds bb $
txtValue.text = bb as string
)

)
createDialog TheMinMaxChecker width:250 height:150

This works which is great. However I thought it should have worked when it was this


fn getBBounds theBB theObject =
(
local c
(
c = snapshot theObject
c.transform = matrix3 1
theBB = c.max - c.min
delete c
)
)

getBBounds bb $


I guess my question is, why do I have have to turn theBB into another variable to get it to work?

Thanks!

Panayot
07-25-2011, 05:43 PM
I see only one case where has sense to assign value to function argument (from inside) - fn foo inArg &outArg = (
outArg = inArg - pi -- assign val to outArg
outArg > 0 -- return result from the func.
)

Maybe someone with more patience can translate this for you.

TheGrak
07-25-2011, 08:05 PM
I guess my question is, why do I have have to turn theBB into another variable to get it to work?
If I understand you correctly, you don't need to do this.

You can assign the results of a function to another variable, as long as the function 'returns' the value you want. So, for example:

fn myFN =
(
--does some stuff
return "complete"
)
myFNresult = myFN()
print myFNresult

This will print "complete".

So, for your boundingBox function I would suggest:
fn getBBounds theObject =
(
local c = snapshot theObject
c.transform = matrix3 1
local myBB = c.max - c.min
delete c
return myBB
)
myFnBB = getBBounds $
print myFnBB

Hope this helps! :)

em3
07-25-2011, 08:17 PM
Thank you, TheGrak, it does.

I was under the impression that using "return" was somewhat frowned upon so I was trying to avoid it. Perhaps I am misunderstanding it's use. Time to read up on that.

Thanks!

em3
07-25-2011, 08:28 PM
so would this be the optimal way to execute getting the bb x,y,and z?


fn getBBounds theObject =
(
local c = snapshot theObject
c.transform = matrix3 1
local myBB = c.max - c.min
delete c
return myBB
)

fn xBounds bb =
(
local x = bb[1]
return x
)
fn yBounds bb =
(
local y = bb[2]
return y
)
fn zBounds bb =
(
local z = bb[3]
return z
)

myFnBB = getBBounds $
x = xBounds myFnBB
y = yBounds myFnBB
z = zBounds myFnBB

TheGrak
07-25-2011, 08:49 PM
so would this be the optimal way to execute getting the bb x,y,and z?
"Optimal" is a very subjective term. If it works for you, then it's as optimal as it needs to be. I'm sure Bobo or denisT could optimize this code further, so there are many ways to do what you're referring to.

I was under the impression that using "return" was somewhat frowned upon so I was trying to avoid it. Perhaps I am misunderstanding it's use. Time to read up on that.
I've read using return slows down functions a little bit, but the function you are working on isn't time sensitive so I don't see why using return would be problematic or frowned upon. You also don't need to type "return something". You can just type "something", and the fn will return it automatically.

For example, you don't need return:
fn getBBounds theObject =
(
local c = snapshot theObject
c.transform = matrix3 1
local myBB = c.max - c.min
delete c
myBB
)
myFnBB = getBBounds $
print myFnBB
Works the same as above code.
I'll attempt to optimize your code and post that in a second.

TheGrak
07-25-2011, 08:55 PM
Here is an attempt at optimizing that code:

fn getBBounds theObject =
(
local c = snapshot theObject
c.transform = matrix3 1
local myBB = c.max - c.min
delete c
return myBB
)
myFnBB = getBBounds $
myx = myFnBB[1]
myy = myFnBB[2]
myz = myFnBB[3]

The boundingBox values that are returned are returned in a 3 element array (a point3). you can access an element in the myFnBB array by it's index. you don't need a function to do this.

Hope that helps!

miauu
07-25-2011, 09:06 PM
One of the advise in maxscript reference is not to use return because it is slow. I don't know how slow it is, but...
So, instead return you can use this:

fn getBBounds theObject = ( local c = snapshot theObject c.transform = matrix3 1 local myBB = c.max - c.min delete c myBB ) myFnBB = getBBounds $ myx = myFnBB[1] myy = myFnBB[2] myz = myFnBB[3]
The function will return the last expression. :)

em3
07-25-2011, 09:07 PM
Awesome dude, thanks for the explanation on the return - I really appreciate it!

miauu
07-25-2011, 09:09 PM
I can't understand why the code is so ... unreadable formated. :(

denisT
07-25-2011, 09:13 PM
so would this be the optimal way to execute getting the bb x,y,and z?


fn getBBounds theObject =
(
local c = snapshot theObject
c.transform = matrix3 1
local myBB = c.max - c.min
delete c
return myBB
)

fn xBounds bb =
(
local x = bb[1]
return x
)
fn yBounds bb =
(
local y = bb[2]
return y
)
fn zBounds bb =
(
local z = bb[3]
return z
)

myFnBB = getBBounds $
x = xBounds myFnBB
y = yBounds myFnBB
z = zBounds myFnBB


the optimal way is:

fn getBBounds node &x &y &z =
(
bb = nodeGetBoundingBox node node.objecttransform
dd = bb[2] - bb[1]
x = dd.x
y = dd.y
z = dd.z
dd
)


but i don't see a reason to return value to x, y, and z variables. i would stay with final point3...

fn getBBounds node =
(
bb = nodeGetBoundingBox node node.objecttransform
bb[2] - bb[1]
)
bbox = getBBounds node
/* bbox.x, bbox.y, bbox.z */


use return expression only at the end of a function. see mxs help
The Return Expression and Do not use return, break, exit or continue

denisT
07-25-2011, 09:18 PM
One of the advise in maxscript reference is not to use return because it is slow. I don't know how slow it is, but...


if return expression used to break the function it makes the function VERY slow.

fn testA = (return 0)
fn testB = (return 0; return 1)

t1 = timestamp()
for k=1 to 100000 do testA()
format "test time A:%\n" (timestamp() - t1)

t1 = timestamp()
for k=1 to 100000 do testB()
format "test time B:%\n" (timestamp() - t1)

CGTalk Moderation
07-25-2011, 09:18 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.