HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PDG/PDG_ProcessorRandom.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.
*
*----------------------------------------------------------------------------
* The Random Processor node, which generates a random number of work items
* for each input work item, and optionally adds attributes to the work items
* to identify their position within the list of random generations
*/
#include "PDG_ProcessorRandom.h"
#include <SYS/SYS_Math.h>
{
PDG_NodeInterface processor("randomprocessor");
// Random seed integer parameter
processor.addParameter(
PDGT_Value::eInteger, "seed", "Seed");
// Random work item count min and max range parameter
auto&& port = processor.addParameter(
PDGT_Value::eInteger, "range", "Range", UT_StringArray(), 2);
port->value(0)->setValue(1);
port->value(1)->setValue(10);
// Joined toggle to control whether or not the node should set an
// integer attribute per-item that tracks the original random index
port = processor.addParameter(
PDGT_Value::eInteger, "setattrib", "Set Index Attrib");
port->addDisplayType(PDG_PortDisplayType::eJoin);
port->addDisplayType(PDG_PortDisplayType::eNoLabel);
// The name of the random index int atribute
port = processor.addParameter(
PDGT_Value::eString, "attrib", "Index Attrib");
port->value(0)->setValue("randomindex");
port->setDisableCondition("{ setattrib == 0 }");
registry->registerProcessor<HDK_Sample::PDG_ProcessorRandom>(
"workitemrandomize", "Work Item Randomize", "Processors", processor);
}
using namespace HDK_Sample;
PDG_ProcessorRandom::onConfigureNode(PDG_NodeOptions* node_options)
{
}
PDG_ProcessorRandom::onGenerate(
PDG_WorkItemHolder* item_holder,
const PDG_WorkItemArray& upstream_items,
GenerationType generate_type)
{
uint seed = evaluateI("seed");
if (!upstream_items.size())
{
if (!_generate(nullptr, item_holder, seed))
}
else
{
for (auto&& upstream_item : upstream_items)
{
seed += upstream_item->index();
if (!_generate(upstream_item, item_holder, seed))
}
}
}
bool
PDG_ProcessorRandom::_generate(
PDG_WorkItem* parent,
PDG_WorkItemHolder* item_holder,
uint& seed) const
{
// Generate the number of random work items to create, based on the seed
// and the min/max values defined by the "range" paramter
exint min = evaluateI("range", parent, 0);
exint max = evaluateI("range", parent, 1);
exint num = SYSrandom(seed)*(max-min) + min;
options.myCloneOutputFiles = true;
options.myPreserveDataType = true;
options.myParent = parent;
UT_WorkBuffer errors;
// Reserve `num` unique work item indices
exint index = myNode->reserveIndexBlock(num);
// Generate `num` new work items, and optionally set an attribute on the
// new work item to track the original random index value
for (int i = 0; i < num; i++)
{
options.myIndex = index++;
PDG_WorkItem* new_item = item_holder->addWorkItem(
result, options, errors);
if (!new_item)
{
myNode->addError(errors.buffer());
return false;
}
if (!evaluateB("setattrib", new_item))
continue;
UT_StringHolder attrib_name = evaluateS("attrib", new_item);
attrib_name, i, 0, true);
}
return true;
}