HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DOP/DOP_GroupAndApply.C
/*
* Copyright (c) 2024
* Side Effects Software Inc. All rights reserved.
*
* Redistribution and use of Houdini Development Kit samples in source and
* binary forms, with or without modification, are permitted provided that the
* following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. The name of Side Effects Software may not be used to endorse or
* promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY SIDE EFFECTS SOFTWARE `AS IS' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL SIDE EFFECTS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*----------------------------------------------------------------------------
*/
#include <DOP/DOP_Engine.h>
using namespace HDK_Sample;
void
{
// Create a new DOP_Operator which describes the operator we are
// building. The parameters to this function are similar to the
// OP_Operator constructor except for the last parameter, which
// specifies the number of outputs (up to 4) from this operator.
op = new DOP_Operator("hdk_groupandapply", "Group and Apply",
0, 1);
table->addOperator(op);
}
static PRM_Name theInputIndexName("inputindex", "Input Index");
// Standard activation parameter.
// Standard group parameter with group menu.
// The input index that determines which data will be attached to
// each object.
PRM_Template(PRM_INT_J, 1, &theInputIndexName, PRMzeroDefaults),
};
{
return new DOP_GroupAndApply(net, name, op);
}
: DOP_Node(net, name, op)
{
}
DOP_GroupAndApply::~DOP_GroupAndApply()
{
}
void
const SIM_ObjectArray &objects,
DOP_Engine &engine)
{
SIM_ObjectArray filtered;
UT_String group;
int i, inputindex;
// Grab the group string and filter our incoming objects using that
// string. This narrows down the set of objects that we actually want
// to operate on. The filtered array will contain only those objects
// from the original objects array that match the supplied string.
GROUP(group, time);
objects.filter(filter, filtered);
// Loop through all the objects that passed the filter.
for( i = 0; i < filtered.entries(); i++ )
{
// Set information about the object we are going to process.
// The first argument is the index of the current object within the
// full list of objects we are going to process. The second
// argument is the total number of objects we are going to process.
// The last argument is a pointer to the actual object we are
// processing.
setCurrentObject(i, filtered.entries(), filtered(i));
// The isActive function checks both the bypass flag and the
// activation parameter on the node (if there is one, which there
// is in this case). We call this function after calling
// setCurrentObject and we call it for each object in case the
// activation parameter uses some object-specific variables
// like OBJID in an expression.
if( isActive(time) )
{
// Evaluate the input index. Also called after setCurrentObject
// to properly evaluate objects specific local variables. Then
// make sure there is something connected to the requested input.
// We add one to the returned value to skip over the object
// input.
inputindex = INPUTINDEX(time) + 1;
if( inputindex != 0 && getInput(inputindex) )
{
SIM_Relationship *relationship;
UT_String addtogroup;
char numstr[UT_NUMBUF];
// This function attaches the data connected to input
// number inputindex to the current object.
applyDataFromInput(time, inputindex, inputindex,
*filtered(i),
0, engine, 0, true);
// Create a group name based on the input index.
UT_String::itoa(numstr, inputindex);
addtogroup = "applygroup_";
addtogroup += numstr;
// Create the relationship if it doesn't already exist,
// and add the object to the group.
relationship = engine.addRelationship(addtogroup,
if( relationship )
{
relationship->addGroup(filtered(i));
}
else
}
}
}
}
void
DOP_InOutInfo &info) const
{
// Our first input is an object input.
// Our remaining inputs are data inputs.
if( inputidx == 0 )
else
}
void
DOP_InOutInfo &info) const
{
// Our single output is an object output.
}
void
DOP_GroupAndApply::GROUP(UT_String &str, fpreal t)
{
evalString(str, DOPgroupName, 0, t);
}
int
DOP_GroupAndApply::INPUTINDEX(fpreal t)
{
return evalInt(theInputIndexName, 0, t);
}