Graph View Data Format (XPresso) Manual
Currently there are two ways to store data of variable type. The first one is
GeData
, the class that is used in most of the SDK for example in
BaseContainer
. The second one is the
void*
data that is used in Graph View. This document describes how the Graph View data type system works.
注意: Types registered with CustomDataTypeClass are automatically included in the Graph View type system as well.
The actual format of the data stored in the
void*
pointer is determined by its value, described by a GvValueID. This is all you need to know to be able to perform calculations with the data or convert it to other types.
Similar kinds of data can share a common value. The combination of a symbol/name and a value is called a data , described by a GvDataID. For example both the normal 和 color data types could be implemented as a vector 值。
The different data types are grouped in value groups . However, currently there is only one group, so you can ignore this feature most of the time.
For the common built-in types (Int32, Float, Vector, Matrix,
BaseTime
and
String
) the
void*
pointer simply points to the data type in question. For custom data types it instead points to the
GvHelper
structure. Please observe that generally these pointers are to an array that you should index with the current CPU ID.
GvDynamicData
is a convenience structure that stores both the
void*
data pointer and a
GvDataInfo
structure with the handlers. There are several ways to get a dynamic data structure:
Many of these functions are implemented in clear code in c4d_graphview.h and c4d_graphview.cpp , so you can see how they work.
Getting a GeData from a calculated port:
GeData GvGetPortGeData( GvNode * node, GvPort * port, GvRun * run, Bool * success) { if (success) *success = false ;Setting the port data from a GeData :
Bool GvSetPortGeData( const GeData & ge_data, GvNode * node, GvPort * port, GvRun * run) { if (!node || !port || !run) return false ; GvPortDescription pd; if (!node-> GetPortDescription (port-> GetIO (), port-> GetMainID (), &pd)) return false ; GvDataInfo * info = GvGetWorld ()-> GetDataTypeInfo (pd. data_id ); if (info== nullptr ) return false ; GvDynamicData data; GvAllocDynamicData (node, data, info); CUSTOMDATATYPEPLUGIN* pl = FindCustomDataTypePlugin (data. info -> data_handler -> data_id ); if (pl== nullptr ) return false ; if (!CallCustomDataType(pl, ConvertGeDataToGv)(ge_data, data. data , 0)) return false ; if (!port-> SetData (data. data , data. info -> value_handler -> value_id , run)) return false GvFreeDynamicData (data); return true ; }Getting a Thinking Particles particle ID from a port:
Int32 GvGetParticleID( GvNode * node, GvPort * port, GvRun * run) { if (!port || !node || !run) return NOTOK ; GeData p = GvGetPortGeData(node, port, run); if (p. GetType () != ID_TP_DATA_TYPE_PARTICLE ) return NOTOK ; struct GvParticleHelper : public CustomDataType { Int32 * pid; }* helper = static_cast< GvParticleHelper* > (p. GetCustomDataType ( ID_TP_DATA_TYPE_PARTICLE )); if (!helper || !helper->pid) return NOTOK ; return *(helper->pid); } Setting a Thinking Particles particle ID in a port: Bool GvSetParticleID( Int32 pid, GvNode * node, GvPort * port, GvRun * run) { if (!port || !node || !run) return NOTOK ; struct GvParticleHelper : public CustomDataType { Int32 * pid; } helper; helper.pid = &pid; GeData p( ID_TP_DATA_TYPE_PARTICLE , helper); return GvSetPortGeData(p, node, port, run); }