Jump to content

GU_SDF and GU_SDFParms


Recommended Posts

Hello everyone,
 
Came across a couple (probably) very simple questions regarding the use of GU_SDF and GU_SDFParms today that I'd be grateful if anyone could shine a light on.
 
The first issue I had was in thinking that the SDFParms::setOffset() method would behave similarly to the corresponding parameter on the IsoOffset SOP.  In my attempts to use it, however, it doesn't seem to alter my volume.  In the most basic situation of creating a single SDF from geometry, my assumption is that I would just need to set the desired properties (including the offset) using the GU_SDFParms class, and they would be respected during the GU_SDF::build and/or getFunction() calls.  For example:
gdp->getBBox(&bbox);
 
GU_SDF sdfVol;
GU_SDFParms sdfParms;
 
sdfParms.setMode( GU_SDFParms::RAY_INTERSECT );
sdfParms.setDivisions( 60, 60, 60 );
sdfParms.setBBox( bbox );
sdfParms.setLaserScan( true );
sdfParms.setFixSigns( true );
sdfParms.setOffset( -0.25f );    // This line doesn't seem to matter, but I wish it would!
sdfParms.setSweepCount( 3 );
sdfParms.setSweepThreshold( 2.0f );
sdfVol.build( gdp, sdfParms );
 
gdp->clearAndDestroy();

GU_PrimVolume   *volumePtr = (GU_PrimVolume *)GU_PrimVolume::build( gdp );
volumePtr->setVoxels( sdfVol.getFunction() );

This works as I expected with many of the parameters, but regardless of what I drop in the setOffset method my iso contour is still displayed at 0 in Houdini.  Any idea why this would be the case?

 

On the subject of setOffset(), I'd be curious to know the difference (if any) between GU_SDF::setOffset() vs GU_SDFParm::setOffset().  Is it just as a convenience to allow for sharing GU_SDFParm objects but overriding particular GU_SDFs?

 

And a bonus question!  There are three modes for converting volumes to SDFs.  GU_SDFParms::VOLUMESAMPLE and GU_SDFParms::VOLUMESAMPLEANDREBUILD are outlined on the IsoOffset help card, but does anyone know what GU_SDFParms::VOLUME mode is expected to do? 

 

Thanks in advance, and sorry if it's something obvious... stumbling through bit by bit!  :)

Link to comment
Share on other sites

For anyone curious, SESI was kind enough to clarify some things for me:

 

GU_SDFParms()::setOffset() just is used as the initial offset value of the GU_SDF that is built. So,

GU_SDF::build(gdp, parms)
{
      setOffset(parms.getOffset());
      ... rest of code ...
}

The missing part of the workflow is that GU_SDF predates the existence of volume primitives. The original workflow is to then use sdfVol.getDistance(), etc, which do properly account for getOffset(). The thing is they do so by adding it just in time, it isn't baked into the actual voxels. That is why when you invoke getFunction() you get a UT_VoxelArray that lacks it.

 

As for the role of GU_SDFParm, it is a solution to the C++ lack of key-word arguments for functions. As soon as a function like build() gets too many parms, it often is nicer to just make a wrapper to hold them all. You can then do proper testing, create defaults, etc, a lot easier. I think it even became useful for when we do the delayed sdf generation to multithread many sdf building - we can stash the parms and build later on separate threads.

 

 

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...