Parameters not being enable when they should

hstewarth

New member
I been working on a Node Plugin and oddly enough half of the plugins are disable in the xPanel when I see know reason why they are.

One thing is interesting, it appears half of them are enable and other half are disable.

I have 5 groups in the panel, the 1st group has 4 FLOAT inputs and the first two are disable and last two are disable.

I also have 4 other groups each with seperate output. Each group is very similar with 2 inputs. Oddly enough the 1st 2 groups ( 4 inputs ) are disable
and 2nd 2 groups are enable.

I am curious what is going on with plugin. this is pretty strange.
 

hstewarth

New member
I clone the code from a color example code I assume you mean these
functions which call packs are call in describe function


I am going to remodel my get and set functions based on specular_node example, from what you impliing it could be a problem.
I wish there was a good example out there so there is so much guess work.

void *ui_get(iMultiRand *inst, unsigned long vid)
{
switch(vid)
{
case ID_SEED1:
return inst->vSeed1;
case ID_SEED2:
return inst->vSeed2;
case ID_SEEDINT:
return inst->vSeedInt;
case ID_SEEDFACTOR:
return inst->vSeedFactor;
case ID_LOWRANGE1:
return inst->vLowRange1;
case ID_HIGHRANGE1:
return inst->vHighRange1;
case ID_LOWRANGE2:
return inst->vLowRange2;
case ID_HIGHRANGE2:
return inst->vHighRange2;
case ID_LOWRANGE3:
return inst->vLowRange3;
case ID_HIGHRANGE3:
return inst->vHighRange3;
case ID_LOWRANGE4:
return inst->vLowRange4;
case ID_HIGHRANGE4:
return inst->vHighRange4;

default:
return NULL;
}
}


int ui_set(iMultiRand *inst, unsigned long vid, void *value)
{
switch (vid)
{
case ID_SEED1:
case ID_SEED2:
case ID_SEEDINT:
case ID_SEEDFACTOR:
case ID_LOWRANGE1:
case ID_HIGHRANGE1:
case ID_LOWRANGE2:
case ID_HIGHRANGE2:
case ID_LOWRANGE3:
case ID_HIGHRANGE3:
case ID_LOWRANGE4:
case ID_HIGHRANGE4:
return 1;

default:
return 0;
}
}
 
Last edited:

Sensei

TrueArt Support
How inst->vSeed1 and others are defined? They're all LWVParmID?

Can you show also procedure that create XPanelID?

BTW, XPanel_Set() returns LWXPRefreshCode and LWXPRC_NONE/LWXPRC_### values.. Always use includes, no direct types and values..
 

hstewarth

New member
I model the function base off the code in specular_node.c and had the same result. It would very nice to have a full example, especially since I model part of code from LW SDK.

I did clone the get and set methods from specular_node.c and had the same results.

Yes inst->vSeed1 is LWVParamID.

LWXPanelID get_xPanel(iMultiRand *inst)
{
static LWXPanelControl xctl[] =
{
{ ID_SEED1, "Seed1", "float-env", },
{ ID_SEED2, "Seed2", "float-env", },
{ ID_SEEDINT, "SeedInt", "float-env", },
{ ID_SEEDFACTOR, "SeedFactor", "float-env", },
{ ID_LOWRANGE1, "LowRange1", "float-env", },
{ ID_HIGHRANGE1, "HighRange1", "float-env", },
{ ID_LOWRANGE2, "LowRange2", "float-env", },
{ ID_HIGHRANGE2, "HighRange2", "float-env", },
{ ID_LOWRANGE3, "LowRange3", "float-env", },
{ ID_HIGHRANGE3, "HighRange3", "float-env", },
{ ID_LOWRANGE4, "LowRange4", "float-env", },
{ ID_HIGHRANGE4, "HighRange4", "float-env", },
{ 0 }
};
static LWXPanelDataDesc xdata[] =
{
{ ID_SEED1, "Seed1", "float-env", },
{ ID_SEED2, "Seed2", "float-env", },
{ ID_SEEDINT, "SeedInt", "float-env", },
{ ID_SEEDFACTOR, "SeedFactor", "float-env", },
{ ID_LOWRANGE1, "LowRange1", "float-env", },
{ ID_HIGHRANGE1, "HighRange1", "float-env", },
{ ID_LOWRANGE2, "LowRange2", "float-env", },
{ ID_HIGHRANGE2, "HighRange2", "float-env", },
{ ID_LOWRANGE3, "LowRange3", "float-env", },
{ ID_HIGHRANGE3, "HighRange3", "float-env", },
{ ID_LOWRANGE4, "LowRange4", "float-env", },
{ ID_HIGHRANGE4, "HighRange4", "float-env", },
{ 0 }
};
static LWXPanelHint xhint[] =
{
XpLABEL(ID_SEED1, "Seed1"),
XpRANGE(ID_SEED1, 0, 255, 1 ),
XpLABEL(ID_SEED2, "Seed2"),
XpRANGE(ID_SEED2, 0, 255, 1 ),
XpLABEL(ID_SEEDINT, "SeedInt"),
XpRANGE(ID_SEEDINT, 0, 255, 1 ),
XpLABEL(ID_SEEDFACTOR, "SeedFactor"),
XpRANGE(ID_SEEDFACTOR, 0, 255, 1 ),
XpLABEL(ID_LOWRANGE1, "LowRange1"),
XpLABEL(ID_HIGHRANGE1, "HighRange1"),
XpLABEL(ID_LOWRANGE2, "LowRange2"),
XpLABEL(ID_HIGHRANGE4, "HighRange2"),
XpLABEL(ID_LOWRANGE3, "LowRange3"),
XpLABEL(ID_HIGHRANGE3, "HighRange3"),
XpLABEL(ID_LOWRANGE4, "LowRange4"),
XpLABEL(ID_HIGHRANGE4, "HighRange4"),

XpGROUP_(TG_SEED),
XpH(ID_SEED1),
XpH(ID_SEED2),
XpH(ID_SEEDINT),
XpH(ID_SEEDFACTOR),
XpH(0),
XpGROUP_(TG_RAN1),
XpH(ID_LOWRANGE1),
XpH(ID_HIGHRANGE1),
XpH(0),
XpGROUP_(TG_RAN2),
XpH(ID_LOWRANGE2),
XpH(ID_HIGHRANGE2),
XpH(0),
XpGROUP_(TG_RAN3),
XpH(ID_LOWRANGE3),
XpH(ID_HIGHRANGE3),
XpH(0),
XpGROUP_(TG_RAN4),
XpH(ID_LOWRANGE4),
XpH(ID_HIGHRANGE4),
XpH(0),

XpCHGNOTIFY(ui_chgnotify),
XpDESTROYNOTIFY(ui_destroynotify),
XpEND
};

LWXPanelID panel;

if(panel = xpanf->create(LWXP_VIEW, xctl))
{
xpanf->hint(panel, 0, xhint);
xpanf->describe(panel, xdata, ui_get, ui_set);
xpanf->viewInst(panel, inst);
xpanf->setData(panel, 0, inst);
}

return panel;
}
 
Last edited:

hstewarth

New member
Addition note:

I did change so that Get Node function uses includes and same problem.

One thing that is interesting if you first load it all are enable, but disable when I select the Node in the node editor. So what gets called when you select the node in editor.
 

Sensei

TrueArt Support
I see nothing wrong with it to be honest..

It doesn't make sense to use XpLABEL() for already named controls in LWXPanelHint list..

Make sure that inst->v### are not null..

f.e. in Create() add

if( inst->vHighRange4 == NULL ) MessageBox( NULL, "error!", "", MB_OK );
(if vHighRange4 is one that causes problems..)
just for debugging..
 

Sensei

TrueArt Support
hstewarth said:
Addition note:

I did change so that Get Node function uses includes and same problem.

One thing that is interesting if you first load it all are enable, but disable when I select the Node in the node editor. So what gets called when you select the node in editor.

Greate info! Thanks!
I know what is the problem - you didn't double-buffer LWPanelID in instance data for later reusing! Panel() function is called each time you click on panel, and you must create LWXPanelID only once if( inst->xpanelid == NULL ) otherwise return what was previously created..
 

hstewarth

New member
Sensei said:
Greate info! Thanks!
I know what is the problem - you didn't double-buffer LWPanelID in instance data for later reusing! Panel() function is called each time you click on panel, and you must create LWXPanelID only once if( inst->xpanelid == NULL ) otherwise return what was previously created..

I really thought that this would work - but it didn't. I even change the change notifity function so its like that in specular_node.c

I might try attaching the debugger to Lightwave and place a break point on get_xPanel routine to see what possibly is wrong.

Thanks.. I think you at least put me in right direction.

By the way the code was clone from the following tutorial which obviously has some errors in it.

http://www.auroragrafx.com/Tutorials/Prog_ColorNodeDemo/ColorNodeDemo.shtml
 

hstewarth

New member
I debug it and found that the Panel was only being created once - even though the routine was being called every time I click on it.

I did notice that the v values for ones that are disable have a value of 0.0.

But I think its something related to these functions..
 

Sensei

TrueArt Support
I am confused..

If your panel creating routine looks like:

Code:
LWXPanelID get_xPanel(iColor *inst)
{
  static LWXPanelControl xctl[] = 
  {
    { ID_COLOR, "Color", "color-env", },
    { 0 }
  };
  static LWXPanelDataDesc xdata[] = 
  {
    { ID_COLOR, "Color", "color-env", },
    { 0 }
  };
  static LWXPanelHint xhint[] = 
  {
    XpLABEL(0, "Color"),
    XpCHGNOTIFY(ui_chgnotify),
    XpDESTROYNOTIFY(ui_destroynotify),
    XpEND
  };

  LWXPanelID panel;

  //Create our xPanel interface
  if(panel = xpanf->create(LWXP_VIEW, xctl)) 
  {
    xpanf->hint(panel, 0, xhint);
    xpanf->describe(panel, xdata, ui_get, ui_set);
    xpanf->viewInst(panel, inst);
    xpanf->setData(panel, 0, inst);
  }

   return panel;
}

Each time LW will call get_xPanel() new LWXPanelID will be returned..

But if you change it to:

Code:
LWXPanelID get_xPanel(iColor *inst)
{
  static LWXPanelControl xctl[] = 
  {
    { ID_COLOR, "Color", "color-env", },
    { 0 }
  };
  static LWXPanelDataDesc xdata[] = 
  {
    { ID_COLOR, "Color", "color-env", },
    { 0 }
  };
  static LWXPanelHint xhint[] = 
  {
    XpLABEL(0, "Color"),
    XpCHGNOTIFY(ui_chgnotify),
    XpDESTROYNOTIFY(ui_destroynotify),
    XpEND
  };

  //Create our xPanel interface
 LWXPanelID panel = inst->panel;
if( panel == NULL )
{
  if(panel = xpanf->create(LWXP_VIEW, xctl)) 
  {
    xpanf->hint(panel, 0, xhint);
    xpanf->describe(panel, xdata, ui_get, ui_set);
    xpanf->viewInst(panel, inst);
    xpanf->setData(panel, 0, inst);
  }
 inst->panel = panel;
   return panel;
}

It should create just one LWXPanelID and for the rest get_xPanel() return just stored value..

I had very similar issue as you and this step fixed this.. But I was doing Surface Node, not Displacement..
 

hstewarth

New member
I found out my main problem, but I still have it crashing..

Basic in my Get routines I was accessing LWVParmID and not the actual values. The v Values in my get routines were change to double values.

All 12 of input are available but I select one - it crashs..

Looks like my code has a confusiion between envolope Paramaters and actual values. There is not much good doc on this stuff - so I a lot is guess work.
 

Sensei

TrueArt Support
Try changing order in which XPanelFuncs functions are called:

- create
- setdata (if any)
- describe
- hint
- viewInst (if any)

But call-backs MUST check whether void *inst parameter passed to them is not NULL..

When I the 1st time developed XPanel plug-in I noticied that using them in wrong order was crashing LW, but it was LW 6.5/7.0.. From that moment it can be fixed..
 

hstewarth

New member
The crash is actually when I enter value in Paramter.. not when executing.. I thinking of debugging why.

It happens after I connect it to output. I bet it could be inst is NULL.

NewTek if you are listening:

Please Update you logic in Lightwave so that when it calls a Callback in Plugin that it has exception handling arround it. This is so that when a plugin crashes it will not crash Lightwave itself. Also put the information in some log so that developers can figured it out.

It would be nice to know what the call back is, plugin be called and parameters being past.
 
Last edited:

hstewarth

New member
I think it might be related to the Time Variant paramter - do they support single double values.. which I believe is SCALAR. The color demo had this in it. Maybe its is causing my plugin to crash now.

The following function is in it

Code:
 LWVParmID vp;
 
  if(vp = vparmf->create(type, LWVPDT_NOTXTR)) 
  {
    vparmf->setup(vp, name, group, NULL, NULL, NULL, NULL);
    vparmf->setVal(vp, ival);
  }
  return vp;

and called with the following in Create

Code:
 //Create VParms for our controls                             
  inst->vSeed1      = create_vpenv( LWVP_FLOAT,   "Seed1",      inst->cgroups, &inst->dblSeed1 );
  inst->vSeed2      = create_vpenv( LWVP_FLOAT,   "Seed2",      inst->cgroups, &inst->dblSeed2 );
  inst->vSeedInt    = create_vpenv( LWVP_FLOAT,   "SeedInt",    inst->cgroups, &inst->dblSeedInt );
  inst->vSeedFactor = create_vpenv( LWVP_FLOAT,   "SeedFactor", inst->cgroups, &inst->dblSeedFactor );
  inst->vLowRange1  = create_vpenv( LWVP_FLOAT,   "LowRange1",  inst->cgroup1, &inst->dblLowRange1 );
  inst->vHighRange1 = create_vpenv( LWVP_FLOAT,   "HighRange1", inst->cgroup1, &inst->dblHighRange1 );
  inst->vLowRange2  = create_vpenv( LWVP_FLOAT,   "LowRange2",  inst->cgroup2, &inst->dblLowRange2 );
  inst->vHighRange2 = create_vpenv( LWVP_FLOAT,   "HighRange2", inst->cgroup2, &inst->dblHighRange2 );
  inst->vLowRange3  = create_vpenv( LWVP_FLOAT,   "LowRange3",  inst->cgroup3, &inst->dblLowRange3 );
  inst->vHighRange3 = create_vpenv( LWVP_FLOAT,   "HighRange3", inst->cgroup3, &inst->dblHighRange3 );
  inst->vLowRange4  = create_vpenv( LWVP_FLOAT,   "LowRange4",  inst->cgroup4, &inst->dblLowRange4 );
  inst->vHighRange4 = create_vpenv( LWVP_FLOAT,   "HighRange4", inst->cgroup4, &inst->dblHighRange4 );
 

Sensei

TrueArt Support
Are you sure that they're not NULL?

In one displacement plug-in I used single double vparm and there was no problem..

Try setting 2nd from right parameter to something meaningful..
vparmf->setup(vp, name, group, NULL, NULL, "blah", NULL);

You gave so much from your node, so you can pack it in one ZIP and send it here to compile by me whole plug-in.. ;)
 

hstewarth

New member
Sensei said:
Are you sure that they're not NULL?

In one displacement plug-in I used single double vparm and there was no problem..

Try setting 2nd from right parameter to something meaningful..
vparmf->setup(vp, name, group, NULL, NULL, "blah", NULL);

You gave so much from your node, so you can pack it in one ZIP and send it here to compile by me whole plug-in.. ;)

Ok I tried out the 2nd parameter and other things - like return early from set function - which disable everything. One thing that happens that is interesting is that it crash in lwtools9.dll. I think I might have found a bug

Ok I place a zip file with source code of plugin. The project that it actually is in contain other things that I experiement - so I included only two source file.

http://home.puffinsoft.com/hstewarth/lwplug/multirand.zip

Hopefully Newtek, will also compile it and fix Lightwave so it does not crash.

I did email Newtek technical support about this issue.. There is at least one software bug in the code, it should not crash in my opinion. Exception handling needs to be done - but there might be performance issue with doing that.
 
Last edited:

Lightwolf

obfuscated SDK hacker
I found the culprit:
Code:
    case ID_SEED1:
      if( nodeInputFunc->check( inst->nodeSeed1 ) )
         return NULL;
      return &inst->dblSeed1;
should be
Code:
    case ID_SEED1:
      if( nodeInputFunc->check( inst->nodeSeed1 ) )
         return NULL;
      return inst->vSeed1;
I.e. return the VParm ID, since your control is of the "*-env" type. There is also no need for querying the control in your "ui_set" callback, since (once LW knows which VParm to link to which control), it keeps the VParm in sync.

Cheers,
Mike
 

hstewarth

New member
Lightwolf said:
I found the culprit:
Code:
    case ID_SEED1:
      if( nodeInputFunc->check( inst->nodeSeed1 ) )
         return NULL;
      return &inst->dblSeed1;
should be
Code:
    case ID_SEED1:
      if( nodeInputFunc->check( inst->nodeSeed1 ) )
         return NULL;
      return inst->vSeed1;
I.e. return the VParm ID, since your control is of the "*-env" type. There is also no need for querying the control in your "ui_set" callback, since (once LW knows which VParm to link to which control), it keeps the VParm in sync.

Cheers,
Mike


That is very interesting if you look earlier in the discussion, I orginally had this way and change it dblSeed1. But I had issue where not all would showed. Only once I change it to dblSeed did it work correctly.

But I will switch it back and investigate it more. Thanks anyway.
 

Lightwolf

obfuscated SDK hacker
hstewarth said:
That is very interesting if you look earlier in the discussion, I orginally had this way and change it dblSeed1.
Hah, you're right, sorry for only looking at the end of the thread.

However, returning the VParm is the correct way of handling it, so it must be another part o your code that is breaking... maybe you overlooked a case or break?

Cheers,
Mike
 
Top Bottom