Bounding Object in expressios

   6829   8   0
User Avatar
Member
6 posts
Joined: July 2005
Offline
Greetings,
I LOVE the Group by bounding object option in the Group Sop.
However, to make things more efficient, I would like to see if I could use an expression to find out if a xyz position is within an object.

Is there such an expression? (I can't find it).
If it doesn't exist, I think it would be a great addition, since the algorithm already exists in the Group Sop, right?

EricGD
User Avatar
Member
7726 posts
Joined: July 2005
Online
Hi Eric,

I'm not quite sure what you're looking for. In the Group SOP's parameters under the Number > Enable tab, one can change the Operation parameter from Group by Pattern to Group by Expression. So then say you want all points which are within the unit sphere, you can put this in the Filter Expression parameter: length($TX, $TY, $TZ) <= 1. This is of course just a contrived expression that does the same thing as Bounding Sphere. Note that there's also the Bounding Object option which uses the Group SOP's second input as the bounding geometry.
User Avatar
Member
4262 posts
Joined: July 2005
Offline
I think he is looking for an expression that he can use anywhere….

like
float isInside(float x, float y, float z, string sopPath)

eg)

if(isInside(0,0,0,“/obj/model/sphere1”)==1,42,8)
if(coffees<2,round(float),float)
User Avatar
Member
4262 posts
Joined: July 2005
Offline
ugh….
having code helps

float isInside(float x, float y, float z, string sopPath)


#include <UT/UT_DSOVersion.h>
#include <CMD/CMD_Manager.h>
#include <CMD/CMD_Args.h>
#include <CH/CH_Support.h>
#include <OP/OP_Channels.h>
#include <EXPR/EXPR.h>
#include <OP/OP_Director.h>
#include <SOP/SOP_Node.h>
#include <GU/GU_RayIntersect.h>


////////////////////// FUNCTIONS //////////////////////
//
// This is a utility function to get the current operator which
// is being evaluated.
//
static OP_Node *
getCwd(float &time)
{
OP_Channels *chp;
CH_Manager *chman;

chman = OPgetDirector()->getChannelManager();
time = chman->getEvaluateTime();
chp = (OP_Channels *)chman->getEvalCollection();
if (!chp) chp = OPgetDirector()->getCwd()->getChannels();

return (chp) ? chp->getNode() : 0;
}


//
// This is a function which will find a node from our current node's
// location.
//
static OP_Node *
findOp(const char *object, OP_InterestType interest_type = OP_INTEREST_NAME)
{
OP_Node *cwd; // Where to search from
OP_Node *here; // Where I currently am
OP_Node *src;
OP_Context context;

// Find our current evaluation node
here = getCwd(context.myTime);
if (!here) return 0;

// If there's a full path specification, search from the top
cwd = (*object == ‘/’) ? OPgetDirector() : here;

if (*object == ‘\0’ || !strcmp(object, “.”))
src = (OP_Node *)cwd;
else src = (OP_Node *)cwd->findNode(object);

// Check to make sure we found the node.
if (!src) return 0;

here->addExtraInput(src, interest_type);

return src;
}

static void
fn_isInside(EV_FUNCTION *, EV_SYMBOL *result, EV_SYMBOL **argv, int) {
CH_Manager *chmgr = OPgetDirector()->getChannelManager();
OP_Node *node = findOp(argv->value.sval,OP_INTEREST_NAMEDATA);
if (node == NULL ) {
result->value.fval = 0.0f;
return;
}
SOP_Node *sop = CAST_SOPNODE(node);
if (sop == NULL ) {
result->value.fval = 0.0f;
return;
}
float time = chmgr->getEvaluateTime();
const GU_Detail *gdp = NULL;
GU_RayIntersect rayTree;
OP_Context context(time);
UT_Vector3 point(argv->value.fval,
argv->value.fval,
argv->value.fval);

gdp = sop->getCookedGeo(context);
if (gdp == NULL ) {
result->value.fval = 0.0f;
return;
}
rayTree.init(gdp);
result->value.fval = rayTree.isInside(point);
return;
}

static int float3StringArgs = { EV_TYPEFLOAT,
EV_TYPEFLOAT,
EV_TYPEFLOAT,
EV_TYPESTRING };

static EV_FUNCTION funcTable = {
EV_FUNCTION(0, “isInside”, 4, EV_TYPEFLOAT, float3StringArgs, fn_isInside),
EV_FUNCTION(),
};

void
CMDextendLibrary( CMD_Manager *)
{
int i;
for (i = 0; funcTable.getName(); i++)
ev_AddFunction(&funcTable);
}

Edited by - Sept. 12, 2005 12:38:22
if(coffees<2,round(float),float)
User Avatar
Member
6 posts
Joined: July 2005
Offline
Hi Edward,
Maybe I was not clear enough.
I have zillion of objects, and I want to see if the centroid of each object is inside a complex geometry (not a sphere).

I would use it in something like this
if(isInbound(centroid(“../foo”, D_X), centroid(“../foo”, D_Y), centroid(“../foo”, D_Z), “../myBoundObject”) == 1, 1, 0)


Does it make sense?

Right now, I have to do a hack with groups, copies, xyzdist expressions, etc…

EricGD
User Avatar
Member
4262 posts
Joined: July 2005
Offline
ericgd
if(isInbound(centroid(“../foo”, D_X), centroid(“../foo”, D_Y), centroid(“../foo”, D_Z), “../myBoundObject”) == 1, 1, 0)

That horrible mess of text above should do just that. (Compiles fine in 7 and 8)
if(coffees<2,round(float),float)
User Avatar
Member
6 posts
Joined: July 2005
Offline
Thanks for the code.
That should do the job.
Now I just need to find someone to compile this for me at my studio…
Thanks again.
EricGD
User Avatar
Member
4262 posts
Joined: July 2005
Offline
If you are using houdini 8 you can just use hcustom and it will copy the dso to your $HOME. That way you can test to see if it works or not….if it does what you need then you can bug the studio people

(Oh….make sure you grab code as of this posting….there were a couple of bugs… i forgot some return statements and I added an OP_Interest to the Data of the sop too.)
if(coffees<2,round(float),float)
User Avatar
Member
7726 posts
Joined: July 2005
Online
Wouldn't it be easier to just use Bounding Object option?
  • Quick Links