THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 16/12/2002 at 03:43, xxxxxxxx wrote:
User Information:
Cinema 4D Version: 8.012
Platform: Mac OSX ;
Language(s) : C++ ; XPRESSO ;
---------
I made an Expresso node based on Mikael Sterner's example in "Topic: Nodes that Iterate",
and some of his other examples.
(my node is not suppose to iterate).
It works, but I have no idea if I did it right...
Also, it has one problem: When nothing is connected to the inport,
i want to get the value directly from the inport, but the ...->Calculate(bn,r,c) returns NULL!
So, how do I get the import values without having to connect them to something?
BTW: Life would be easier if all of Maxon's own nodes where available in source.
Thanks!
kris
Complete source code follows: (with some more questions).
////////////////////////////////////////////////////
////////////////////////////////////////////////////
#include "c4d.h"
#include "c4d_operatordata.h"
#include "Kaaref1.h"
// forward declarations for functions from Mikael Sterner's post in "Topic: from port->SetData".
// I use these because port->GetData and ->SetData cause Cinema to crash.
GeData GvGetPortGeData(GvNode* node, GvPort* port, GvRun* run);
Bool GvSetPortGeData(const GeData& ge_data, GvNode* node, GvPort* port, GvRun* run);
const GvOperatorID KAAGETTAG1_ID = 10983430; // just random
static LONG input_ids[] = { 0 };
class KaaGvRef1 : public GvOperatorData
{
private:
GvCalcTable* table; // not used... What is it for?
public:
LONG mode;
LONG steps;
KaaGvRef1(void) : table(NULL) {}
Bool Init(GeListNode *node)
{
// Use iCreateOperator instead!
return TRUE;
}
virtual Bool iCreateOperator(GvNode *bn)
{
BaseContainer* data = bn->GetOpContainerInstance();
if (!data) return FALSE;
data->SetLong(STEPS, 3);
//return SUPER::iCreateOperator(bn); // SUPER undefined...
return GvOperatorData::iCreateOperator(bn);
}
Bool InitCalculation(GvNode *bn, GvCalc *c, GvRun *r)
{
BaseContainer *data = bn->GetOpContainerInstance();
steps = data->GetLong(STEPS);
mode = data->GetLong(MODE_ID);
return TRUE;
}
void FreeCalculation(GvNode *bn, GvCalc *c)
{
}
Bool Calculate(GvNode *bn, GvPort *port, GvRun *r, GvCalc *c)
{
if (!port) return TRUE;
// Calculate inport
GvPort* inport = bn->GetInPortFirstMainID(INPORT_LINK);
if (!inport) return FALSE; // never happens?
inport = inport->Calculate(bn, r, c); // link
if (!inport) return FALSE; // hapens when the inport is not connected
// this is where I want to get data from the node itself!
// Get the data from the inport
BaseList2D * mylist2D = NULL; // can't use AutoAlloc
GeData linkdata = GvGetPortGeData(bn, inport, r);
BaseLink* test = linkdata.GetBaseLink();
if (test && test->GetLink(bn->GetNodeMaster()->GetDocument()))
{
mylist2D = test->GetLink(bn->GetNodeMaster()->GetDocument());
GePrint(mylist2D->GetName());
}
else {
GePrint("no link");
}
// do I have to get the inport data for each outport i wish to calculate?
// or is it a bette way?
switch(port->GetMainID()) // maby not needet for one outport?
{
// is this the right way, when you have many outports? What is most efficient?
case OUTPORT_LINK:
{
BaseObject * b = (BaseObject* )mylist2D;
for (LONG i = 0; i<steps; i++){
switch(mode){
case GETDOWN:
b = b->GetDown(); break;
case GETUP:
b = b->GetUp(); break;
case GETPRED:
b = b->GetPred(); break;
case GETNEXT:
b = b->GetNext(); break;
}
if (!b) break;
}
AutoAlloc<BaseLink> bl;
bl->SetLink(b);
GvSetPortGeData(GeData(bl), bn, port, r); // returns bool
break;
}
}
return TRUE;
}
static NodeData* Alloc(void) { return gNew KaaGvRef1; }
};
Bool RegisterKaaref1()
{
return GvRegisterOperatorPlugin(
KAAGETTAG1_ID, "Kaaref1", 0,
KaaGvRef1::Alloc, "Kaaref1", 0,
ID_GV_OPCLASS_TYPE_GENERAL, ID_GV_OPGROUP_TYPE_GENERAL, 0, NULL);
}
/*
// Kaaref1.res
CONTAINER Kaaref1
{
NAME Kaaref1;
INCLUDE GVbase;
GROUP ID_GVPROPERTIES
{
LONG MODE_ID
{
CYCLE
{
GETDOWN;
GETUP;
GETPRED;
GETNEXT;
}
}
LONG STEPS { MIN 0; }
}
GROUP ID_GVPORTS
{
LINK INPORT_LINK {INPORT; STATICPORT; CREATEPORT;}
LINK OUTPORT_LINK {OUTPORT; STATICPORT; CREATEPORT;}
}
}
// Kaaref1.h
#ifndef _Kaaref1_H_
#define _Kaaref1_H_
enum
{
MODE_ID = 1000,
GETDOWN = 0,
GETUP,
GETPRED,
GETNEXT,
STEPS = 2000,
INPORT_LINK = 3000,
OUTPORT_LINK = 4000
};
#endif
// Kaaref1.str
STRINGTABLE Kaaref1
{
Kaaref1 "Kaaref1";
MODE_ID "Mode";
GETDOWN "GetDown()";
GETUP "GetUp()";
GETPRED "GetPrev()";
GETNEXT "GetNext()";
STEPS "Steps";
INPORT_LINK "in";
OUTPORT_LINK "out";
}
*/