How to make Expressions work in referenced scenes?

Become a member of the CGSociety

Connect, Share, and Learn with our Large Growing CG Art Community. It's Free!

THREAD CLOSED
 
Thread Tools Search this Thread Display Modes
Old 01 January 2013   #1
How to make Expressions work in referenced scenes?

This is something that's bothered me over a number of scripts I've done.

Is there a way to make expressions able to pick up namespaces so they work in referenced files?

Previously I had a bit of a search and replace that would find the missing attribute's namespace and tack it on to what I was trying to do but ths seems like a really irritating waste of time, surely there must be a way around this?

For example, I have:


 global proc warn(){     
float $followingHead = `getAttr mySphere.followHead`;
 
      if ( $followingHead == 1 ){
 
          setAttr -lock true "mySphere.tx";
 
          setAttr -lock true "mySphere.ty";
 
          setAttr -lock true "mySphere.tz";
 
      }//end if
 
      else if ( $followingHead < 1) {
 
 setAttr -lock false "mySphere.tx";
 
          setAttr -lock false "mySphere.ty";
 
          setAttr -lock false "mySphere.tz";
 
     }
 
  }// end proc
 
  scriptJob -attributeChange mySphere.followHead warn;
 
 


I have this stored in a script node, as an expression which runs on maya open/close. It all works fine.

Until I reference the scene in. In the new file, it doesn't realise that mySphere is now called REF:mySphere and the script ceases to work completely.

My previous fix was to do a search through the name of the script node, copy the text before the colon and tack it on to the attributes I'm trying to affect. But this seems overly heavy handed for what is essentially a simple namespace repathing.

Does anyone know of a solution?

Cheers.

Last edited by Taunise : 01 January 2013 at 04:35 AM.
 
Old 01 January 2013   #2
Add this to the beginning of your script:

$sphereList = `ls -r 1 "mySphere"`;
$sphere = $sphereList[0];

Then modify your script, replacing each occurent of "mySphere" with "$sphere", e.g.


global proc warn(){     
float $followingHead = `getAttr ($sphere + ".followHead")`;
 
      if ( $followingHead == 1 ){
 
          setAttr -lock true ($sphere + ".tx");

// etc.
// etc.
 
Old 01 January 2013   #3
you have to think of some way you can discover the node without knowing it's name at all. Easiest it seems would be linking your sphere to your script node via message (adding new attribute to script node first). Then, script node queries it's own attribute (`getAttr .sphereLinkedMessage`), gets object's name via that link, stores that in a variable and you can do pretty much anything you want at this point.
__________________
Victor
ngskintools.com - skinning plugin for Autodesk Maya
 
Old 01 January 2013   #4
Originally Posted by Nyro: Add this to the beginning of your script:

$sphereList = `ls -r 1 "mySphere"`;
   $sphere = $sphereList[0];

Then modify your script, replacing each occurent of "mySphere" with "$sphere", e.g.


global proc warn(){     
   float $followingHead = `getAttr ($sphere + ".followHead")`;
    
         if ( $followingHead == 1 ){
    
             setAttr -lock true ($sphere + ".tx");
   
   // etc.
   // etc.


This is a clever solution, but after trying and fiddling with it for a wee bit, i dont think it works.

in your example, $sphere would need to exist as its correct value when you open the scene, because the script job needs to know what object's attribute change property to run on. The ls won't work at this point however, because nothing is selected. The scene has only just been loaded.

Originally Posted by uiron: you have to think of some way you can discover the node without knowing it's name at all. Easiest it seems would be linking your sphere to your script node via message (adding new attribute to script node first). Then, script node queries it's own attribute (`getAttr .sphereLinkedMessage`), gets object's name via that link, stores that in a variable and you can do pretty much anything you want at this point.


Yeah, this approach does work, and it's similar to what I've used it on previous scripts, but it's very heavy handed when all I'm trying to do is lock and unlock attributes. I was looking for a slightly more elegant way to go about it.

Referenced files are a pain :(
 
Old 01 January 2013   #5
Quote: in your example, $sphere would need to exist as its correct value when you open the scene


Yes, it would have to exists. But since the whole issue here is that you're referencing it in, I simply assume that it existed along with the scriptNode in the original (referenced) scene.

That said, the other solution is more robust as there is less chance of accidentally referring to the wrong object.
 
Old 01 January 2013   #6
Originally Posted by Nyro: Yes, it would have to exists. But since the whole issue here is that you're referencing it in, I simply assume that it existed along with the scriptNode in the original (referenced) scene.

That said, the other solution is more robust as there is less chance of accidentally referring to the wrong object.


No my point was that $sphere has to be defined when the scene opens.

So when the scene opens you would be running the ls command.

But ls only works on selected things. When a maya scene opens, nothing is selected. So even though the sphere itself exists, it won't be able to find it and assign its name to $sphere...or am I missing something?
 
Old 01 January 2013   #7
use `node` in your expression to get the namespaced name of the node

string $name=node;
__________________
blah blah blah
 
Old 01 January 2013   #8
Quote: But ls only works on selected things. When a maya scene opens, nothing is selected. So even though the sphere itself exists, it won't be able to find it and assign its name to $sphere...or am I missing something?


No. You're mistaken, which isn't all that surprising given that by far the most common usage of the ls command is:

ls -sl

The 'ls' command itself simply lists objects in the scene. You can specify what objects you want to list via the command's flags, e.g.

ls -sl // list selected objects
ls -type "transform" // list all transform nodes in the scene
ls "pCube1" // list all objects called 'pCube1'
ls -recursive "sphere" // list all objects named 'sphere', but look in all namespaces for them (as opposed to merely in the implied ':' (root) namespace)

When dealing with scripts and expressions, it is very important not to get too hung up on the idea that commands need something to be selected to work. 98% of all commands don't. Using the selection is just the default way most commands handle the non-existence of object arguments when they are called.
 
Old 01 January 2013   #9
Yeah ls is great but the tip I just gave in my previous post is far better for this particular issue
__________________
blah blah blah
 
Old 01 January 2013   #10
Originally Posted by gmask: Yeah ls is great but the tip I just gave in my previous post is far better for this particular issue


Agreed. Much less chance of accidentally referring to the wrong object with your method, unless you can be reasonably sure that your particular sphere is uniquely named.
 
Old 01 January 2013   #11
Originally Posted by Nyro: Agreed. Much less chance of accidentally referring to the wrong object with your method, unless you can be reasonably sure that your particular sphere is uniquely named.



Generally speaking.. I always avoid non unique names in any referenced asset. The only reason you need `node` however is to get the namespace that the expression is in and then you can add the name space to the full path of whatever object in your reference hierarchy you are running the script on.

string $node=node;

string $namespace=substitute(":.*$",$node,"");

string $path=$namespace+":myobject";

or

string $path=$namespace+":mygroup|"+$namespace+":myobject;
__________________
blah blah blah
 
Old 01 January 2013   #12
or use a regex
 
Old 01 January 2013   #13
Originally Posted by Nyro: or use a regex


whatever floats your boat.. if you're willing to fish for node names using ls then using substitute shouldn't be a stretch.
__________________
blah blah blah
 
Old 01 January 2013   #14
By the way, this just occured to me because I'm currently working on a script that has to deal with referenced objects:

It is still possible to reference a scene without using a namespace; the alternative option is using a string Prefix.

If the user chooses this option, then the nodes in question will not have a namespace and thus no colon ":" to identify the prefix (or namespace) by.

In such a case, there really is no way around identifying the node via its unique name (or at least a unique substring in its name). If there is, I'd love to hear it.
 
Old 01 January 2013   #15
Originally Posted by Nyro: By the way, this just occured to me because I'm currently working on a script that has to deal with referenced objects:

It is still possible to reference a scene without using a namespace; the alternative option is using a string Prefix.

If the user chooses this option, then the nodes in question will not have a namespace and thus no colon ":" to identify the prefix (or namespace) by.

In such a case, there really is no way around identifying the node via its unique name (or at least a unique substring in its name). If there is, I'd love to hear it.


Oh I thought that option had been removed for references? In any case you could prefix the names of an imported asset.

There's a number of ways you could handle this.. you could make a rule about how the prefix is formatted so that it can be pattern matched. You could require that no name has an underscore in the name and use the underscore as a delimiter. You could try to presume that the first string before an underscore is the prefix. You could use two underscores in a row as the delimiter.. you could use "_ns_" as a delimiter. When you import or reference the asset the first time you could set a string attribute on the asset or perhaps on the expression or create an expression that has the prefix stored in it.
__________________
blah blah blah
 
Thread Closed share thread



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
CGSociety
Society of Digital Artists
www.cgsociety.org

Powered by vBulletin
Copyright 2000 - 2006,
Jelsoft Enterprises Ltd.
Minimize Ads
Forum Jump
Miscellaneous

All times are GMT. The time now is 02:23 AM.


Powered by vBulletin
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.