Custom Properties Persistent Layout

February 2nd, 2007 by Daniele Niero - Viewed 19424 times -




From a rigger’s point of view, I think Softimage|XSI is one of the best software around, and as character TD, I really love proxy parameters. The possibility to expose to animators every channel we want can make our rigs definitely cleaner, more understandable and easier to use. On the other hand a simple list of parameters can be long and hard to read.

Fortunately XSI gives us the possibility to customize a custom property’s layout with groups, tabs, by changing the parameter’s aspect, and replicating them as many times as we wish.

Unfortunately these layout informations are not persisted with the scene which means they are forgotten from one XSI session to another.

The idea

To bypass this problem I wrote a self installing custom property in JScript. The property has a string parameter where I can write my layout code and the property can read it and change itself. Because this code is actually a parameter’s value it is saved in the scene which means we are not going to loose the layout.

A look at the code

The first thing we need to create is a plugin that registers a new property. We can use the wizard in XSI to do this and call the new property whatever we want. I called it GenericProperty because, well, it’s generic.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function XSILoadPlugin(in_reg)
{
	in_reg.Author = "Daniele Niero";
	in_reg.Name = "GenericProperty_Plugin";
	in_reg.Major = 1;
	in_reg.Minor = 0;
	in_reg.RegisterProperty("GenericProperty");
	return true;
}
 
function GenericProperty_Define(io_Context)
{
	var oCustomProperty;
	oCustomProperty = io_Context.Source;
	oCustomProperty.AddParameter2("PropertyCode",siString,"",null,null,null,null,0,siPersistable);
	oCustomProperty.AddParameter2("PropertyPPGTab", siBool, true);
}

The trick is performed in the OnInit function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function GenericProperty_OnInit()
{
	var oLayout = PPG.PPGLayout;
	var startCode = "function ChangeProperty(){\r\n" + "oLayout.Clear();\r\n";
	var userCode = PPG.PropertyCode.Value + "\r\n";
 
	if (PPG.PropertyPPGTab.Value == true)
	{
		var endCode = "oLayout.AddTab(\"PPG\");\r\n" + "oLayout.AddItem(\"PropertyPPGTab\");\r\n" + "oLayout.AddString(\"PropertyCode\",\"PropertyCode\", true, 500);\r\n" + "}";
	}
	else if (PPG.PropertyPPGTab.Value == false)
	{
		var endCode = "}";
	}
 
	var code = startCode + userCode + endCode;
	eval(code);
	ChangeProperty();
	PPG.Refresh();
}

There are three important variables in this code startCode, endCode and especially userCode. They are strings that define the layout code.

startCode is a constant and it will never change. As you can see it defines a function called ChangeProperty(), all the rest of the code is part of this function.

userCode defines the code that creates a tab called PropertyPPGTab with a parameter called PropertyCode and then closes the ChangeProperty function. The tab is defined only if PropertyPPGTab is true, allowing us to hide PropertyCode Errors are thus prevented as the custom property is left perfectly clean and animators aren’t scared with strange code they normally don’t want to see.

userCode is the variable we are interested in. It is filled with the value of the PropertyCode parameter and in this parameter we can write our layout code directly from the property in XSI.

At the end all these three variables are connected together in a single one called code and evaluated with the eval function. If code doesn’t contain any syntax errors eval will evaluate it successfully and we can then call the ChangeProperty() function to have it create our layout.

Final touch, PPG.Refresh() ensures a correct layout refresh.

How use it

Very simple, just load the plugin in XSI and apply this property on an object, open it and create some custom parameters or proxy parameters as usual and start to write your layout.

For example imagine you have two parameters (custom or proxy doesn’t make any difference) named Param1 and Param2.

We can write a layout like this:

1
2
3
4
5
6
7
8
9
10
oLayout.AddGroup("First Parameter");
	oLayout.AddItem("Param1");
oLayout.EndGroup();
oLayout.AddGroup("Second Parameter");
	oLayout.AddItem("Param2");
oLayout.EndGroup();
 
oLayout.AddTab("A Tab");
	oLayout.AddItem("Param1");
	oLayout.AddItem("Param2");

Refresh or just reopen the property and you should be able to see your layout.

Limitation

I have been using this solution from almost two years now and it has worked really well so far. Recently I wanted to improve it a little bit and I tried to implement the possibility to write a logic session as well.

Unfortunately it seemed impossible to make the logic as dynamic as the layout. I had problems flushing and regenerating the Logic even if using oLayout.Delete() instead of just Clear().

12 Responses to “Custom Properties Persistent Layout”

  1. SolaGratia77 says:

    Thanks Daniele !!!

    I wanted SOFTIMAGE to do something like this in user friendly drag and drop maner.
    (eg. dragging properties from explorer view, just like how a toolbar or shelf is created)

    But now that I tried your plug-in, my thirst for those is gone.

    Thank you so much for sharing this awesome plug-in.

    One question>
    Is there anyway to add all properties created under GenericProperty to PropertyCode automatically?
    What I mean is, let say I have following custom properties created under GenericProperty.

    smile1
    smile2
    smile3
    smile4
    smile5

    is there any way to Automatically generate a basic script looks
    like this under PropertyCode?

    oLayout.AddItem(“smile1″);
    oLayout.AddItem(“smile2″);
    oLayout.AddItem(“smile3″);
    oLayout.AddItem(“smile4″);
    oLayout.AddItem(“smile5″);

    Then it would be much eaiser to customize the script from there.
    (or am I just too lazy?)

    I guess it would involve some scripting but I haven’t got a clue how….

    Anyway thanks again for the great plug-in

    -J
    SolaGratia

  2. Daniele Niero says:

    Hi,

    I’m glad you found ths plugin useful.

    About your question, yes, with basic scripting knowledge you can do almost everything

    for example a very fast script could be this:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    // start code
    oProp = Selection(0);
    oParams = oProp.Parameters;
    layoutString = "";
     
    // if you are in XSI 6...
    i = 5
    // otherwise...
    //i = 3
    for (i; i < oParams.Count; i++)
    {
        layoutString += "oLayout.AddItem(\"" + oParams(i).ScriptName + "\");\r\n"
    }
    oProp.PropertyCode.Value = layoutString
  3. Daniele Niero says:

    still not working… the post will be cutted at the “less then” character… strange. I’ll put on internet a zip file with this simple script as soon as I can, or you can mail me to daniele@daniele.niero.name

    sorry about that

  4. Serguei Kalentchouk says:

    Interesting idea, I had to use similar way of making dynamic UI in maxscript using strings and executing them, not for same reasons but the process was very much the same.

  5. Derek Jenson says:

    Nice. Very clever.

  6. Daniele, the < character in your comment was being interpreted as the beginning of an html tag. Fixed it.

  7. SolaGratia77 says:

    Thanks Patrick, script works great.
    And thanks again to Daniele for such a wonderful script

    And…. I am sorry but I have one more question>>

    What would be the best way to move already existing parameters?

    Let’s say I have 20 shape sliders (Custom Parameters) setup on my character
    and now I want to move those to GenericProperty.
    Should I just drag and drop in the explorer?
    (and when I do that, cursor icon indicates that I am making shortcuts)

    Then I have same parameters under both CustomProperty and GenericProperty.
    By doing this am I making the rig slower?
    or should I just not worry about such thing and do it anyway?

    Thank you.

  8. Daniele Niero says:

    Hi Solagratia,

    That’s not easy to say; I guess proxy parameters, the parameters you create when you drag and drop one to a different custom property, are slower then normals, but I’m not really sure. What I can say is that I’m using almost only proxy parameters, and the rig are ok.

    P.S. Thank you Patrick

  9. Ahmidou says:

    Exellent, thank you for this!

  10. Mal says:

    Just got round to trying this out. Fantastic, love it. Thank you for sharing.

  11. [...] Softimage Blog » Blog Archive » Custom Properties Persistent Layout [...]

  12. [...] Softimage Blog » Blog Archive » Custom Properties Persistent Layout [...]