Jump to content

Mean Value Coordinates


Recommended Posts

Ok so I've put together my first HDK sop but for some reason that I'm yet to fathom it doesn't work the same as the vex version.

By which I mean the vex version is 100% fine and seems to work in all situations whereas the HDK version works 90% of the time but in some situations sends random points off to infinity. I can only assume there is a bug in the code but for the life of me I can't see it. So I thought I'd post it up here and see if anyone can spot some obvious blooper. Maybe after taking a break I'll see it myself. But it might be related to either a C++ thing I'm doing wrong or an HDK thing, since I'm not 100% confident in either of these disciplines at the mo.

Warp.zip

To see the problem open the hip file in the attached and display odWarp_beta1.

To see it working display odWarp_beta2.

To see that it should work display warpmesh_hda1.

Link to comment
Share on other sites

  • Replies 51
  • Created
  • Last Reply

Top Posters In This Topic

Ok it's fixed. Of course it was the old classic division by zero. Should have checked this straight away but since vex handles it I assumed (wrongly) that the way I'd implimented the actual code was already correct. Typical the bug wasn't in the HDK or the C++ stuff..... :P

I'll post a fully compiled version once I have it all fully optimised and I have a capture and then deform mode working. But if anyone wants the code as is let me know.

Link to comment
Share on other sites

Great work chief! :)

Just took a quick look and....

  //assume rest is already triangulated

    //TODO work out a way to convex input or check for convex tris

You might be able to get away with this by just calling

GU_Detail::convex(unsigned maxpts=3, GB_PrimitiveGroup *primGroup=0);

on your rest and deform details. Which will convert any polygon primitives into triangles.

oh and another little thing check out GB/GB_ExtraMacros.h it has a ton of macros so you don't have to type for ( i = 0; i < gdp->points().entries(); i++ ) all the time. :)

Link to comment
Share on other sites

Since you have multiple inputs you can set each input's description with

const char *
SOP_odWarp::inputLabel( unsigned int input) const
{
  switch (input) {
    case 0:
      return "Geometry To Deform";
      break;
    case 1:
      return "Rest Mesh";
      break;
    case 2:
      return "Deformed Mesh";
      break;
    default:
      return "WTF?";
      break;
  } 
}

Link to comment
Share on other sites

Cool, thanks for all the pointers :D , I'll look at adding that stuff in. There's a lot of methods to wade through so any help is greatly apprieciated. It's coming together slowly. I have one outstanding big issue though. I'm now storing the capture attributes for speed but I can't find a way to read them back in :P , for some reason findPointAttrib just returns a null pointer all the time. Any ideas?

Here's the current incarnation of the code. It's line 376 that I'm having trouble with.

Warp.zip

Link to comment
Share on other sites

Here's the current incarnation of the code. It's line 376 that I'm having trouble with.

Warp.zip

19233[/snapback]

The first thing that jumps out is

    attrib = gdp-&gt;findPointAttrib("warpCapt",GB_ATTRIB_FLOAT);
   // cout&lt;&lt;"attrib "&lt;&lt;attrib&lt;&lt;endl;
    if( attrib &gt; 0 )

findPointAttrib returns an integer in the attribute index list. (Which starts at 0).

So change the if to if( attrib >= 0 ). (if it can't find the attrib it will return -1)

Link to comment
Share on other sites

I compiled it and gave it a whirl after changing attrib > 0 to a >= but it dumped. Turns out ppt was never set in deform mode so I just added ppt = gdp->points()( i )

    attrib = gdp-&gt;findPointAttrib("warpCapt",GB_ATTRIB_FLOAT);
   // cout&lt;&lt;"attrib "&lt;&lt;attrib&lt;&lt;endl;
    if( attrib &gt;= 0 )
    {
      for ( i = 0; i &lt; gdp-&gt;points().entries(); i++ )
      {
        ppt = gdp-&gt;points()( i );
        captatt = (float*)ppt-&gt;getAttribData(attrib);
        total_function = (0,0,0);
        for ( j = 0; j &lt; deform-&gt;points().entries(); j++ )

Link to comment
Share on other sites

Cheers, knew it would be something dumb. :lol:

Couple of other fixes required, otherwise the stored capture attributes are wrong

if (FUNC()!=2)

primd = deform->primitives()(j);

.

.

.

case 1 : // Capture

total_weight += w;

captatt = (float*)ppt->getAttribData(attrib);

vtx = &primd->getVertex(k);

Link to comment
Share on other sites

Just took a quick look and....

You might be able to get away with this by just calling

GU_Detail::convex(unsigned maxpts=3, GB_PrimitiveGroup *primGroup=0);

on your rest and deform details.  Which will convert any polygon primitives into triangles.

19225[/snapback]

Don't think this is going to work because inputGeo(1,context) returns a const pointer, so i don't think you can modify the gdp's inputs other than 0. Could be wrong but that's what i'm thinking.

Link to comment
Share on other sites

Ok so here's a working version of the code. I need to break this up into two sops and add some error trapping and an icon :P maybe add some help. I think i'll leave the triangulating to the divide sop for now. The perfermance is pretty good with the weights stored and then just used as a lookup in the deform version. I'm very pleased. :)

Warp.zip

And a precompiled version - H7.0 windows

Warp_win_compile.zip

Link to comment
Share on other sites

Don't think this is going to work because inputGeo(1,context) returns a const pointer, so i don't think you can modify the gdp's inputs other than 0. Could be wrong but that's what i'm thinking.

19246[/snapback]

I'm guessing the inputGeo is for the more memory friendly sops that just need to reference data. If you want/need to modify the other inputs (for convexing or general pimping) you can use SOP_Node::duplicateSource()

    GU_Detail *restMesh;
    GU_Detail *deformMesh;
    duplicateSource(0, context);
    duplicateSource(1,context,restMesh);
    duplicateSource(2,context,deformMesh);
    restMesh-&gt;convex();
    deformMesh-&gt;convex();
    FOR_ALL_POINTS(gdp,point) {
    FOR_ALL_PRIMITIVES(restMesh,prim){

Disclaimer: Don't take anything I say as authority, I admittedly know nothing and if I happen to say something right it means I was just lucky.

Link to comment
Share on other sites

Ok so here's a working version of the code. I need to break this up into two sops and add some error trapping and an icon  :P maybe add some help. I think i'll leave the triangulating to the divide sop for now. The perfermance is pretty good with the weights stored and then just used as a lookup in the deform version. I'm very pleased.  :)

Warp.zip

And a precompiled version - H7.0 windows

Warp_win_compile.zip

19247[/snapback]

Thanks again for the awesome work. :)

I'll take a peek after I get done getting my butt kicked in GTA.

Link to comment
Share on other sites

Excellent I'll give it a go, actually I only need to convex input 1 since once stored all the weights are relative to points not triangles, you just need the triangles to do the calc. Maybe we should start putting some of this up on the wiki. Haven't really gotten into that yet.

GU_Detail *restMesh;
duplicateSource(1,context,restMesh);

Must be something else missing here, adding this causes Houdini to seg fault. It certainly looks like it should work, any ideas?

Edited by sibarrick
Link to comment
Share on other sites

Must be something else missing here, adding this causes Houdini to seg fault. It certainly looks like it should work, any ideas?

19265[/snapback]

Bah I suck....

Passing a null pointer into duplicateSource() when it expects a respectable memory address would cause a crash I guess. ;)

Either...

GU_Detail *rest;
rest = new GU_Detail();
if (rest == NULL)
  return error():
duplicateSource(1,context,rest);
...
unlockInputs();
delete rest;

or I guess this would work too....

GU_Detail rest;
duplicateSource(1,context,&amp;rest);

but you'll need to change your rest ->'s to .'s

Link to comment
Share on other sites

One thing that you might want to do is add a detail attribute in Capture mode with the number of points that were used to capture. That way later down the chain if a user modifies the point count of the deform mesh you can just error out. Otherwise you are on the road to a Stephen King novel. :)

(Your attribute array has 8 points but your deform mesh now has 11. :o )

Link to comment
Share on other sites

Ok, you got me, again :P

I can set a detail attribute easy enough but I can't read it back in. Sounds familiar. It seems there is a different method for reading in detail attributes and I can't get my head round it.

Anyway, everything else is pretty much in place now I think. I've split it into 2 sops and knocked a few bugs out of it, plus added some error trapping.

Still needs help, which I can't get working either. And I need to add the option to check if points are coincident with the control mesh.

I assume at some point this all gets a lot easier, but I'm not feelin' it at the moment. Bah!

In answer to your much early question about speed versus Vex, it's way quicker, like realtime, once the mesh is captured, but the capturing is only about twice as quick, which I thought would be better. Just goes to show how good vex actually is. With a dual proc there's not much in it capturing wise.

Oops posted the wrong zip file again, so I've removed it.

Edited by sibarrick
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...