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
Bounding Object in expressios
7302 8 0- ericgd
- Member
- 6 posts
- Joined: July 2005
- Offline
- edward
- Member
- 7899 posts
- Joined: July 2005
- Offline
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.
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.
- wolfwood
- Member
- 4271 posts
- Joined: July 2005
- Offline
- wolfwood
- Member
- 4271 posts
- Joined: July 2005
- Offline
ugh….
having code helps
#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);
}
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)
- ericgd
- 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
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
- wolfwood
- Member
- 4271 posts
- Joined: July 2005
- Offline
- ericgd
- Member
- 6 posts
- Joined: July 2005
- Offline
- wolfwood
- Member
- 4271 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.)
(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)
- edward
- Member
- 7899 posts
- Joined: July 2005
- Offline
-
- Quick Links