//
// This example shows how FCurves can be stored inside a UserDataMap,
// and edited via a Custom Property. It demonstrates: (a) how to create
// a single script plug-in; (b) how to use a templated UserDataMap object
// to store data on points; (c) how to use CustomProperty.BinaryData to
// store and retrieve FCurves represented as strings; and (d) how to use
// the PPGLayout to build dynamic user interfaces (with no SPDL).
//
BuildSampleScene() ;
function BuildSampleScene()
{
NewScene(null, false);
var oGrid = ActiveSceneRoot.AddGeometry("Grid", "MeshSurface", "GridWithUserData");
oGrid.subdivu = 1;
oGrid.subdivv = 1;
var oCluster = oGrid.ActivePrimitive.Geometry.AddCluster("pnt");
var oUserDataMap = oCluster.AddProperty("UserDataMap", false, "FCurveData");
var oCustomProperty = CreateUserDataTemplate(oCluster);
oUserDataMap.Template = oCustomProperty;
InspectObj(oCustomProperty);
SelectObj(oGrid, null, true);
SetSelFilter("Point");
}
function CreateUserDataTemplate( in_oCluster )
{
var oCustomProperty = in_oCluster.AddProperty("CustomProperty", false, "DataTemplate");
oCustomProperty.AddFCurveParameter("CurveData");
var oLayout = oCustomProperty.PPGLayout;
var oLayoutItem = oLayout.AddFCurve("CurveData", 150);
oLayout.AddRow();
oLayout.AddButton("ReadFromSelection", "Read from selected Point");
oLayout.AddButton("SaveFromSelection", "Save on selected Point(s)");
oLayout.AddButton("Instructions");
oLayout.EndRow() ;
oLayout.Language = "JScript";
oLayout.Logic = ReadFromSelection_OnClicked.toString() +
SaveFromSelection_OnClicked.toString() +
Instructions_OnClicked.toString() +
GetSelectedPoints.toString() +
GetUserDataMap.toString();
return oCustomProperty;
}
//
// The following code is Logic code for the Property Page
//
function GetSelectedPoints()
{
// Find out what points are selected. They are returned as an array of
// Cluster Indices (-1 is returned in the array if the selected point
// is not part of the cluster)
var oSubComp = null;
for ( var i=0; i<Selection.Count; i++) {
var oObj = Selection(i);
if (oObj.Type == "pntSubComponent") {
oSubComp = oObj.SubComponent;
break;
}
}
if (oSubComp == null) {
Application.LogMessage("Please select a point");
return null;
}
// (We could also double check that the points are selected on the
// right object using the parent property!)
var aVBSelectedElements = new VBArray(oSubComp.ElementArray);
var aGeometryIndices = aVBSelectedElements.toArray();
// Index on a cluster is not necessarily identical to a
// geometry index. Use the Cluster object to do a lookup
var oThisCustomProperty = PSet.Inspected.Item(0);
var oCluster = oThisCustomProperty.Parent;
for ( var j=0; j<aGeometryIndices.length; j++) {
aGeometryIndices[j] = oCluster.FindIndex(aGeometryIndices[j]);
}
return aGeometryIndices;
}
function GetUserDataMap()
{
// Find the UserDataMap associated with this Custom Property
// We know they are both nested under the same Cluster
// and what the name of the User Data Map is
var oThisCustomProperty = PSet.Inspected.Item(0);
var oCluster = oThisCustomProperty.Parent;
return oCluster.Properties.Item("FCurveData");
}
function ReadFromSelection_OnClicked()
{
var aSelectedElements = GetSelectedPoints();
if (aSelectedElements == null || aSelectedElements.length == 0) {
return;
}
// If more than one item is selected we only look at the first one
var clusterIndex = aSelectedElements[0];
if (clusterIndex == -1) {
Application.LogMessage("The selected index is not part of the cluster");
return;
}
var oUserDataMap = GetUserDataMap();
if ( oUserDataMap.IsEmpty(clusterIndex) ) {
Application.LogMessage("There is no user data stored on this item yet");
return;
}
// Transfer the data from the UserDataMap
// to the ClusterProperty
var oThisCustomProperty = PSet.Inspected.Item(0);
oThisCustomProperty.BinaryData = oUserDataMap.ItemValue(clusterIndex);
}
function SaveFromSelection_OnClicked()
{
var aSelectedElements = GetSelectedPoints();
if (!aSelectedElements || !aSelectedElements.length) {
Application.LogMessage("You must select at least one point in order to save this fcurve");
return;
}
var oThisCustomProperty = PSet.Inspected.Item(0);
binarySnapShotOfCustomProperty = oThisCustomProperty.BinaryData;
var oUserDataMap = GetUserDataMap() ;
for ( var k=0; k<aSelectedElements.length; k++) {
if (aSelectedElements[k] != -1) {
oUserDataMap.ItemValue(aSelectedElements[k]) = binarySnapShotOfCustomProperty;
}
}
}
function Instructions_OnClicked()
{
// There are lots of different ways to show information to a user, for example popping
// up netview, showing a message box, or putting static text right on the dialog.
//
// For demonstration purposes we create a temporary custom pset with a multiline edit
// box, which we fill with text. This doesn't have ideal usability but shows some of
// the potential for doing totally dynamic UI
var oInfoPSet = ActiveSceneRoot.AddProperty("CustomProperty", false, "Info");
var oParameter = oInfoPSet.AddParameter3("Info", siString);
oParameter.ReadOnly = true;
oParameter.Value = "Plug-in Instructions\r\n\r\n" +
"This example demonstrates how to store FCurves as User Data.\r\n" +
"Each of the 4 vertices of the Grid can store a different Curve\r\n\r\n" +
"To view the FCurve on a vertex, select it and press the \r\n" +
"'Read from Selected Point' button.\r\n\r\n" +
"To set the fcurve, change the fcurve in the view, " +
"select one or more points\r\n" +
"and then press the 'Save on selected Point(s)' button"
var oLayoutItem = oInfoPSet.PPGLayout.AddString("Info", "", true, 300);
oLayoutItem.SetAttribute("ValueOnly", true);
InspectObj(oInfoPSet, null, null, siModal, false);
DeleteObj(oInfoPSet);
} |