Hi There, I'm doing a custom ICE node with four outputports, two scalar and two vectors, all per point data. It's compiling fine, the last output port is working, but I'm getting those error with the three previous ones: # ERROR : 2427 - Access to a custom ICE node output port failed. This can occur when accessing the port from the BeginEvaluate or EndEvaluate callback. # ERROR : 2429 - Access to a custom ICE node index set failed. This can occur when accessing an index set from the BeginEvaluate or EndEvaluate callback. # ERROR : 2389 - This custom ICENode is in an invalid state and will stop evaluating:
There are no Begin or End evaluate at all, and once this appenend, disconnecting and reconnecting any output port of this node is crashing SI. I also tried in single threaded mode with and without direct indexing and got the same result. Finally If I have only one output port it's working fine If someone have an experience with this, here is simple example source code: enum IDs { ID_IN_geo = 0, ID_IN_pos = 1, ID_IN_norm = 2, ID_G_100 = 100, ID_POS = 101, ID_OUT_A = 200, ID_OUT_B = 201, ID_OUT_C = 202, ID_OUT_D = 203, ID_TYPE_CNS = 400, ID_STRUCT_CNS, ID_CTXT_CNS, ID_UNDEF = ULONG_MAX }; CStatus RegisterMyCustomICENode( PluginRegistrar& in_reg ) { ICENodeDef nodeDef; nodeDef = Application().GetFactory().CreateICENodeDef(L"MyCustomICENode",L"My Custom ICENode"); CStatus st; st = nodeDef.PutColor(154,188,102); st.AssertSucceeded( ) ; //st = nodeDef.PutThreadingModel(XSI::siICENodeSingleThreading); //st.AssertSucceeded( ) ; // Add input ports and groups. st = nodeDef.AddPortGroup(ID_G_100); st.AssertSucceeded( ) ; st = nodeDef.AddInputPort(ID_POS,ID_G_100,siICENodeDataVector3,siICENodeStructureSingle,siICENodeContextComponent0D,L"PointPosition",L"PointPosition",MATH::CVector3f(1.0,1.0,1.0),ID_UNDEF,ID_UNDEF,ID_CTXT_CNS); st.AssertSucceeded( ) ; // Add output ports. st = nodeDef.AddOutputPort(ID_OUT_A,siICENodeDataFloat,siICENodeStructureSingle,siICENodeContextComponent0D,L"A",L"A",ID_UNDEF,ID_STRUCT_CNS,ID_CTXT_CNS); st.AssertSucceeded( ) ; st = nodeDef.AddOutputPort(ID_OUT_B,siICENodeDataFloat,siICENodeStructureSingle,siICENodeContextComponent0D,L"B",L"B",ID_UNDEF,ID_STRUCT_CNS,ID_CTXT_CNS); st.AssertSucceeded( ) ; st = nodeDef.AddOutputPort(ID_OUT_C,siICENodeDataVector3,siICENodeStructureSingle,siICENodeContextComponent0D,L"C",L"C",ID_UNDEF,ID_STRUCT_CNS,ID_CTXT_CNS); st.AssertSucceeded( ) ; st = nodeDef.AddOutputPort(ID_OUT_D,siICENodeDataVector3,siICENodeStructureSingle,siICENodeContextComponent0D,L"D",L"D",ID_UNDEF,ID_STRUCT_CNS,ID_CTXT_CNS); st.AssertSucceeded( ) ; PluginItem nodeItem = in_reg.RegisterICENode(nodeDef); nodeItem.PutCategories(L"Custom ICENode"); return CStatus::OK; } SICALLBACK MyCustomICENode_Evaluate( ICENodeContext& in_ctxt ) { // The current output port being evaluated... ULONG out_portID = in_ctxt.GetEvaluatedOutputPortID( ); CDataArrayVector3f pos( in_ctxt, ID_POS ); switch( out_portID ) { case ID_OUT_A : { // Note: for the sake of this example, the code requires an output port defined as CDataArrayVector3f CDataArrayFloat outData( in_ctxt ); // Get the geometry vectors saved in MyCustomICENode_BeginEvaluate CIndexSet indexSet( in_ctxt ); for(CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next()) { // Note: The output buffer is relative to the 'batch' data therefore we can index the batch with the iterator directly. // On the other hand pPointVector has to be indexed with the 'batch' global index i.e. CIndexSet::Iterator::GetAbsoluteIndex() outData[it] = pos[it].GetX(); } } case ID_OUT_B : { // Note: for the sake of this example, the code requires an output port defined as CDataArrayVector3f CDataArrayFloat outData( in_ctxt ); // Get the geometry vectors saved in MyCustomICENode_BeginEvaluate CIndexSet indexSet( in_ctxt ); for(CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next()) { // Note: The output buffer is relative to the 'batch' data therefore we can index the batch with the iterator directly. // On the other hand pPointVector has to be indexed with the 'batch' global index i.e. CIndexSet::Iterator::GetAbsoluteIndex() outData[it] = pos[it].GetY();; } } case ID_OUT_C : { // Note: for the sake of this example, the code requires an output port defined as CDataArrayVector3f CDataArrayVector3f outData( in_ctxt ); CIndexSet indexSet( in_ctxt ); for(CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next()) { // Note: The output buffer is relative to the 'batch' data therefore we can index the batch with the iterator directly. // On the other hand pPointVector has to be indexed with the 'batch' global index i.e. CIndexSet::Iterator::GetAbsoluteIndex() outData[it] = pos[it]; } } case ID_OUT_D : { // Note: for the sake of this example, the code requires an output port defined as CDataArrayVector3f CDataArrayVector3f outData( in_ctxt ); // Get the geometry vectors saved in MyCustomICENode_BeginEvaluate CIndexSet indexSet( in_ctxt ); for(CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next()) { // Note: The output buffer is relative to the 'batch' data therefore we can index the batch with the iterator directly. // On the other hand pPointVector has to be indexed with the 'batch' global index i.e. CIndexSet::Iterator::GetAbsoluteIndex() outData[it] = pos[it]; } } break; // Other output ports... }; return CStatus::OK; } Thanks ----------------------------------------------- Ahmidou Lyazidi Director | TD | CG artist http://vimeo.com/ahmidou/videos http://www.cappuccino-films.com