From: owner-xsi(at)Softimage.COM
[mailto:owner-xsi(at)Softimage.COM] On Behalf Of Matt Lind
Sent:
April-13-08 3:31 PM
To: xsi(at)Softimage.COM
Subject:
CClusterPropertyBuilder make XSI go boom!
I've been saddled with a technical question from
our realtime shader dev:
Using the C++ API, how do you make and assign
a vertex color property to a specific cluster on a polygon mesh?
Using
the CClusterPropertyBuilder causes XSI to crash (6.01, 6.5) using either
method shown in the docs (ie: with no arguments, or with 2 arguments). I
jumped into the problem myself to verify, and sure enough it's true. So,
I tried the technique I normally use in scripting which is to create a
cluster, then use Cluster.AddProperty() to create the vertex color property on
the cluster. Works fine, but the problem is the C++ SDK docs state only
ClusterProperties created using the CClusterPropertyBuilder can have their
values changed and set using the ClusterProperty.SetValues() method.
Sooo, what good is that?
[mab] ClusterProperty.SetValues
uses a cache created by the builder to map geometry elements to cluster
indices. This cache is not available for non-builder cluster properties which
makes ClusterProperty.SetValues
unusable.
----------------start code
example
(C++)------------------------
//===============================================================================================
//
ML_VertexColorCreate v1.0 (c)2008 Matt Lind
//
// Simple demonstration
of how to create a vertex color property on a selected polygon mesh
object.
//===============================================================================================
#include
<xsi_application.h>
#include <xsi_context.h>
#include
<xsi_pluginregistrar.h>
#include <xsi_status.h>
#include
<xsi_argument.h>
#include <xsi_command.h>
#include
<xsi_selection.h>
#include <xsi_model.h>
#include
<xsi_x3dobject.h>
#include <xsi_siobject.h>
#include
<xsi_primitive.h>
#include <xsi_geometry.h>
#include
<xsi_cluster.h>
#include <xsi_clusterproperty.h>
#include
<xsi_clusterpropertybuilder.h>
#include
<xsi_vertexcolor.h>
#include <xsi_polygonmesh.h>
using
namespace XSI;
//===========================================================================
//
XSILoadPlugin()
//
//===========================================================================
XSIPLUGINCALLBACK
CStatus XSILoadPlugin( PluginRegistrar& oPluginRegistrar
)
{
oPluginRegistrar.PutAuthor( L"Matt Lind"
);
oPluginRegistrar.PutName(
L"ML_VertexColorCreate" );
oPluginRegistrar.PutEmail( L"" );
oPluginRegistrar.PutURL( L"" );
oPluginRegistrar.PutVersion( 1, 0 );
oPluginRegistrar.RegisterCommand( L"ML_VertexColorCreate",
L"ML_VertexColorCreate" );
return( CStatus::OK
);
}
//===========================================================================
//
XSIUnloadPlugin()
//
//===========================================================================
XSIPLUGINCALLBACK
CStatus XSIUnloadPlugin( const PluginRegistrar& in_reg
)
{
CString strPluginName =
in_reg.GetName();
Application().LogMessage(
strPluginName + L" has been unloaded.", siVerboseMsg );
return( CStatus::OK
);
}
//===========================================================================
//
Init()
//
//===========================================================================
XSIPLUGINCALLBACK
CStatus ML_VertexColorCreate_Init( CRef& in_ctxt
)
{
Context oContext( in_ctxt
);
Command oCommand =
oContext.GetSource();
oCommand.PutDescription( L""
);
oCommand.EnableReturnValue( true
);
ArgumentArray oArguments =
oCommand.GetArguments();
oArguments.AddWithHandler(
L"oSelection", L"Collection" );
return( CStatus::OK
);
}
//===========================================================================
//
Execute()
//
//===========================================================================
XSIPLUGINCALLBACK
CStatus ML_VertexColorCreate_Execute( CRef& in_ctxt
)
{
Context oContext( in_ctxt
);
//CValueArray oArguments =
oContext.GetAttribute( L"Arguments" );
//CValue
oSelection =
oArguments[0];
// Get hook to the XSI
Application
Application
oApplication;
// Check
selection
Selection oSelection(
oApplication.GetSelection() );
LONG Count =
oSelection.GetCount();
if ( Count <= 0 )
{
oApplication.LogMessage( L"Nothing
selected", siErrorMsg );
return(
CStatus::Fail );
}
//
Get 1st element in selection
SIObject oElement(
oSelection[0] );
X3DObject
oObject;
if ( oElement.IsA( siX3DObjectID ) )
{
// We only care about X3DObjects
with geometry
oObject =
oElement;
}
// Get object's
geometry primitive at frame zero.
PolygonMesh oGeometry(
oObject.GetActivePrimitive().GetGeometry() );
//---------------------------------------------
//
Vertex Color via AddProperty()
//---------------------------------------------
// Add a
cluster to the geometry
Cluster
oCluster;
CLongArray indices; // define empty
index array to let XSI know we want an 'always complete'
cluster,
oGeometry.AddCluster(
siSampledPointCluster, L"VertexData", indices, oCluster
);
// Add a vertex color property to the cluster
(Notice the space in 1st argument)
ClusterProperty
oPrimaryVertexColor;
oCluster.AddProperty( L"Vertex
Color", false, L"PrimaryColor", oPrimaryVertexColor
);
//-------------------------------------------
// Vertex
Color via AddVertexColor()
//-------------------------------------------
// This
call reuses the cluster created in the previous steps
//
If cluster didn't exist, AddVertexColor() would create the cluster
automatically with a name like "UV_Cluster_AUTO" or
similar.
ClusterProperty oSecondaryVertexColor =
oGeometry.AddVertexColor( L"SecondaryColor" );
//-------------------------------------------
// Vertex
Color via ClusterPropertyBuilder()
//-------------------------------------------
CClusterPropertyBuilder oClusterPropertyBuilder =
oGeometry.GetClusterPropertyBuilder();
// *** both
of these 2 invocations of ClusterPropertyBuilder.AddVertexColor() will cause
XSI to crash: ***
// Option 1
// ClusterProperty oTertiaryVertexColor =
oClusterPropertyBuilder.AddVertexColor();
// Option
2
// CString VertexColorName =
L"TertiaryColor";
// CString
ClusterName = L"VertexData";
//
ClusterProperty oTertiaryVertexColor = oClusterPropertyBuilder.AddVertexColor(
VertexColorName, ClusterName );
// Return a value by
setting this attribute:
oContext.PutAttribute(
L"ReturnValue", true );
return( CStatus::OK
);
}
---------------end code
example--------------------------
------------------------------
Matt Lind
Animator / Technical
Director
SOFTIMAGE certified instructor:
SOFTIMAGE|3D
SOFTIMAGE|XSI
Matt.Lind(at)Mantom(dot)net