How do I start the debugger from a .p file?

I've some trouble understanding how and what NewTime does. Is it possible with NewTime to get input values from my node at a different frame than the current one?
I thought if I would feed a value in LWFrame it evaluates a different frame than the current one but this doesn't seem to be the case? Is it even possible to read the input value of a node at a different time?
If not I think the best way would be storing the triggered time/value while playing the sequence in openGL.

XCALL_(static LWError)
NewTime(LWInstance instance, LWFrame f, LWTime t)
{

Trigger_p inst = (Trigger_p)instance;
int switz = inst->v_swi; // input of node

inputfuncs->evaluate(inst->swi, instance, &switz);

}

This code above doesn't give me the value of time f does it?
 

Sensei

TrueArt Support
LWNodeInputFuncs doesn't have time as argument.

Channels and Envelopes do take it as argument.

If parameter is dynamically generated by plugin,
then there is needed first baking them to envelope/channel.
 
Ah to bad! It's like you say. The parameter is generated dynamically. If I understand it correctly: there is no way I can generate an envelope while rendering (I mean like a pre-process)? This has to be a separate process or can it be done?
I'm thinking of a way of storing a cache point (frame number). This is the easiest way I think. If I press play in Layout it the trigger works perfectly fine so if I would store the frame number it switches I'm there but it isn't a rock solid method because if you don't play the animation or if you scrub to fast the cached point differs. My goal is to have it working rock solid on LWSN as well.
To make my question shorter. Is it possible to bake the input of a node to an envelope before the actual render starts but after you press f10 or the specific frame starts rendering on a renderfarm?
 
Last edited:
I'm again running into an issue. Here's what I'm doing:

I'm storing a value while playing an animation. I made an inputfield in the nodes interface so I can see there is actually a value stored. This seem to work fine.
Than I'm saving the scene. The values are saved. I checked the .lws in notepad++ and the values are there. But here's the problem. The 2 values that I add during the "openGL scanning" won't load. All 4 values that I'm saving are of the same type and similar. To detect whether I was overwriting the values during loading I removed the openGL scanning code so no new values would be saved or detected but the values the are clearly there in the .lws file won't show up in my node.
Am I missing something or what am I doing wrong?

The values that don't load are inst->v_storedValue; and inst->v_switchedAtFrame;



Here is some of the code:

XCALL_(static void)
Evaluate(void *data, LWNodalAccess *na, NodeOutputID out, NodeValue Value)
{
Trigger_p inst = (Trigger_p)data;

LWDVector triggeredv;
double trigger = inst->v_trigg;
double switz = inst->v_swi;
double storedValueLocal = inst->v_storedValue;
double switchedAtFrame = inst->v_switchedAtFrame;

// evaluate node inputs
//inputfuncs->evaluate(inst->trigg, na, &trigger); //works fine
//inputfuncs->evaluate(inst->swi, na, &switz); //works fine
//inputfuncs->evaluate(inst->storedValue, na, &storedValueLocal); // check value

if (sceneinfo->rendermode == lwrm_None) {

inputfuncs->evaluate(inst->trigg, na, &trigger); //works fine
inputfuncs->evaluate(inst->swi, na, &switz); //works fine


if (switz == 1 && inst->v_swbool == false) {

//switchedAtFrame = timeinfo->frame;
inst->v_switchedAtFrame = timeinfo->frame;
inst->v_swbool = 1; // seems not to work

inst->v_storedValue = trigger; // This updates the value used for F10 renders and LWSN an openGL
storedValueLocal = trigger; // updates for F10 and LWSN only and should be saved

triggeredv[0] = inst->v_storedValue;
triggeredv[1] = inst->v_storedValue;
triggeredv[2] = inst->v_storedValue;
outputfuncs->setValue(Value, triggeredv);

//char mess[32];
//sprintf(mess, "%d ", inst->v_trigg);
//Log(mess);

}
else if (switz == 0 && inst->v_swbool == false) {

triggeredv[0] = trigger;
triggeredv[1] = trigger;
triggeredv[2] = trigger; // true on start of anim not triggered and while loading?

outputfuncs->setValue(Value, triggeredv);
}
else if (inst->v_swbool == true) { // when triggered
triggeredv[0] = inst->v_storedValue;
triggeredv[1] = inst->v_storedValue;
triggeredv[2] = inst->v_storedValue;

outputfuncs->setValue(Value, triggeredv);
}

if (timeinfo->frame < inst->v_switchedAtFrame || timeinfo->frame == 0) {

inst->v_swbool = false; //reset trigger
}
}

if (sceneinfo->rendermode == lwrm_Scene || sceneinfo->rendermode == lwrm_Frame) {

if (timeinfo->frame >= switchedAtFrame) {
// triggered
triggeredv[0] = storedValueLocal;
triggeredv[1] = storedValueLocal;
triggeredv[2] = storedValueLocal;
outputfuncs->setValue(Value, triggeredv); // set output while rendering
}
else if (timeinfo->frame < switchedAtFrame) {
// not triggered
inputfuncs->evaluate(inst->trigg, na, &trigger);

triggeredv[0] = trigger;
triggeredv[1] = trigger;
triggeredv[2] = trigger;
outputfuncs->setValue(Value, triggeredv);
}

}

}
 
Last edited:

creacon

creacon
So the values in your instance are saved in the lws.
When you load the scene, you put the values that are read from the file in a new instance?
If you place a breakpoint right after you read the values, are they there?

creacon.

Does anyone see what wrong with this? If I did a lot of stupid stuff please tell me.
 
I just added breakpoints in the load method and I think I'm doing something working here, but I not sure what it is. Should I break; after each case? Could it be the problem that if it finds a value in the first case it breaks out of the while loop and stops reading the rest of the code?
Edit: I removed the break; command and now it does finally read in a value but it's something like -12958942 is stead of 73 and all the values are the same so there's still something wrong.

Load(LWInstance instance, const LWLoadState *load)
{
Trigger_p inst = (Trigger_p)instance;
LWID id;

// Find the data blocks
while ((id = LWLOAD_FIND(load, Trigg_Block)))
{
switch (id)
{

case ID_TR_TRIGG:
{
float fval;
LWLOAD_FP(load, &fval, 1);
inst->v_trigg = fval;
}
break;

case ID_TR_SWI:
{
float fval;
LWLOAD_FP(load, &fval, 1);
inst->v_swi = fval;
}
break;

case ID_TR_SWIAT:
{
float fval;
LWLOAD_FP(load, &fval, 1);
inst->v_switchedAtFrame = fval;
}
break;

case ID_TR_SLV:
{
float fval;
LWLOAD_FP(load, &fval, 1);
inst->v_storedValue = fval;
}
break;
}

LWLOAD_END(load);
}
return NULL;
}
 
Last edited:

Sensei

TrueArt Support
You are using break; outside of context...

Instead of f.e.:


case ID_TR_SLV:
{
float fval;
LWLOAD_FP(load, &fval, 1);
inst->v_storedValue = fval;
}
break;

You should have:

case ID_TR_SLV:
{
float fval = 0.0; // CLEAR IT!!! Just in case...
LWLOAD_FP(load, &fval, 1);
inst->v_storedValue = fval;
break;
}

Don't see other obvious issues. Show Save() implementation..
 
In the specular_node example that I'm using as a template the load function looks like that with the break; outside of it. I moved it inside like you said but than it stops reading all values like it did before. It just reads the first one and jumps to the bottom.
If I search in the lws file the correct values are there.
When I write float fval = 0,0; the value is 0 after loading so it seem there is something wrong with the way I load things.

This is the save function:

XCALL_(static LWError)
Save(LWInstance instance, const LWSaveState *save)
{
Trigger_p inst = (Trigger_p)instance;


LWSAVE_BEGIN(save, &Trigg_Block[0], 1);
{
float fval = (float)inst->v_trigg;
LWSAVE_FP(save, &fval, 1);
}
LWSAVE_END(save);

LWSAVE_BEGIN(save, &Trigg_Block[1], 1);
{
float fval = (float)inst->v_swi;
LWSAVE_FP(save, &fval, 1);
}
LWSAVE_END(save);

LWSAVE_BEGIN(save, &Trigg_Block[2], 1);
{
float fval = (float)inst->v_switchedAtFrame;
LWSAVE_FP(save, &fval, 1);
}
LWSAVE_END(save);

LWSAVE_BEGIN(save, &Trigg_Block[3], 1);
{
float fval = (float)inst->v_storedValue;
LWSAVE_FP(save, &fval, 1);
}
LWSAVE_END(save);

return NULL;
}
 
Last edited:
I found the error :D.
In the names below I had used spaces and it turns out that's not allowed. I thought it was just a string so I could use spaces. Now the values read correctly.
static LWBlockIdent Trigg_Block[] = {

ID_TR_TRIGG, "Trigger",
ID_TR_SWI, "Switch",
ID_TR_SLV, "Stored value",
ID_TR_SWIAT, "Switched at frame",
0
};
 
I've got a new problem YAY! I've got my node that has one output. Now I want to add an other output that puts out a second value. How do I do that. It tried :

outputfuncs->next;
outputfuncs->setValue(Value, frameOffsetArr);
outputfuncs->first;

This doesn't work because now all the outputs share the same value.
I've created 2 NodeOutputID's called output and output2. That correct right?
Like this:
inst->output = outputfuncs->create(node, NOT_VECTOR, "Triggered");
inst->output2 = outputfuncs->create(node, NOT_SCALAR, "Frame Offset");

What happens exactly when you do outputfuncs->next;? Does the whole evaluate function start over? Why can't a just assign a value to my output variable in this case output2?

I shouldn't do this should I? (I mean adding "NodeValue Value2"):
XCALL_(static void)
Evaluate(void *data, LWNodalAccess *na, NodeOutputID out, NodeValue Value, NodeValue Value2)
{

No matter what I do both outputs share the same value. What am I doing wrong?
Should I create an evaluate function for every output?

EDIT: I think I get it. That last thing worked.

I do have an other question: Both my output are putting out a value but one of them only works when the node editor is open. What could that be?
 
Last edited:
Both my outputs are putting out a value but my second one only works when the node editor is open or when the first one is connected as well. What could that be?
 

Sensei

TrueArt Support
If I have more than one output:
Code:
XCALL_( void )
Evaluate(
 LWInstance instance,
 LWNodalAccess *nodalaccess,
 NodeOutputID nodeoutputid,
 NodeValue nodevalue )
{
	Data *data = (Data *) instance;
	if( nodeoutputid == data->m_NodeOutputID_1 )
	{
                int result = 1;
		data->m_NodeOutputFuncs->setValue( nodevalue, &result );
	}
	else if( nodeoutputid == data->m_NodeOutputID_2 )
	{
                int result = 2;
		data->m_NodeOutputFuncs->setValue( nodevalue, &result );
	}
	else if( nodeoutputid == data->m_NodeOutputID_3 )
	{
                int result = 3;
		data->m_NodeOutputFuncs->setValue( nodevalue, &result );
	}
}
(all scalars in example)
 
Last edited:
Thanks Sensei! That works even better! I now added an option that enables you to trigger animation curves. It's really fun to play with :D
 
I've got a new one for you! I'm trying to make my expanded node work on LWSN. I stored some values in an LWS file but when I load them back in they are overwritten by something in the evaluate function. I tried to use if(sceneinfo->loadInProgress == 0) and if (sceneinfo->rendermode == lwrm_None) but this doesn's seem to change anything. Everything below these if statements gets executed even when LW loads the scene. Is there a better way that works so I'm able to keep my values?

An other question derived from this problem.
Why is LW executing the evaluate function so many times on load? It seem to read every thing at least twice?
 

Sensei

TrueArt Support
Evaluate() of which node "type".. ?

If node is used in Surface Node Editor, it's called by preview area, when Surface Editor is turned on, and there is displayed preview..
Also it'll be called by VPR, if VPR is enabled.

In Evalute() you cannot change instance data, without good reason.
It's called from multi-threads.
So, if you really really have to, you must surround it by mutex lock/unlock. This could be serious issue for speed of execution or even future source of deadlocks.
I doubt you really have to do it..
I never had to in any my node store data from Evaluate() in instance data, AFAIR.

LWSceneInfo must be acquired every time you need it read from it by GlobalFunc, AFAIK.
 
Last edited:
Top Bottom