HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RAY/RAY_DemoStamp.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.
*
*----------------------------------------------------------------------------
* This is a sample procedural DSO
*/
#include <GU/GU_Detail.h>
#include "RAY_DemoStamp.h"
// The ray_ChildBox is a "private" procedural.
// The user can't allocate one of these directly.
namespace HDK_Sample {
/// @brief Procedural used in @ref RAY/RAY_DemoStamp.C to render a box
/// @see @ref RAY/RAY_DemoBox.C
class ray_ChildBox : public RAY_Procedural
{
public:
: myCenter(center),
mySize(size)
{}
~ray_ChildBox() override {}
const char *className() const override
{ return "ray_ChildBox"; }
/// Since the procedural is generated by stamp, this
/// method will never be called.
int initialize(const UT_BoundingBox *) override
{
return 0;
}
void getBoundingBox(UT_BoundingBox &box) override
{
box.initBounds(myCenter);
box.expandBounds(0, mySize);
}
void render() override
{
geo->cube(
myCenter.x()-mySize, myCenter.x()+mySize,
myCenter.y()-mySize, myCenter.y()+mySize,
myCenter.z()-mySize, myCenter.z()+mySize);
child->addGeometry(geo);
}
private:
UT_Vector3 myCenter;
fpreal mySize;
};
} // End HDK_Sample namespace
using namespace HDK_Sample;
// Arguments for the stamp procedural
static RAY_ProceduralArg theArgs[] = {
RAY_ProceduralArg("minbound", "real", "-1 -1 -1"),
RAY_ProceduralArg("maxbound", "real", "1 1 1"),
RAY_ProceduralArg("size", "real", ".1"),
RAY_ProceduralArg("npoints", "int", "10"),
RAY_ProceduralArg("seed", "int", "1"),
};
{
public:
: RAY_ProceduralFactory::ProcDefinition("demostamp")
{
}
RAY_Procedural *create() const override { return new RAY_DemoStamp(); }
RAY_ProceduralArg *arguments() const override { return theArgs; }
};
void
{
factory->insert(new ProcDef);
}
{
myBox.initBounds(0, 0, 0);
}
{
}
const char *
{
return "RAY_DemoStamp";
}
int
{
fpreal val[3];
// Evaluate parameters and store the information
val[0] = val[1] = val[2] = -1;
import("minbound", val, 3);
myBox.initBounds(val[0], val[1], val[2]);
val[0] = val[1] = val[2] = 1;
import("maxbound", val, 3);
myBox.enlargeBounds(val[0], val[1], val[2]);
if (!import("size", &mySize, 1))
mySize = 0.1;
if (!import("npoints", &myCount, 1))
myCount = 10;
if (!import("seed", &mySeed, 1))
mySeed = 1;
mySize = SYSabs(mySize);
return 1;
}
void
{
// Initialize with the bounding box of the stamp procedural
box = myBox;
// Each child box can also enlarge the bounds by the size of the child
box.expandBounds(0, mySize);
}
void
{
int i;
unsigned int seed;
float cx, cy, cz;
seed = mySeed;
for (i = 0; i < myCount; i++)
{
// Compute random numbers deterministically. If they were computed in
// the assign operation, compilers could compute them in a different
// order.
cx = SYSfastRandom(seed);
cy = SYSfastRandom(seed);
cz = SYSfastRandom(seed);
c.assign( SYSfit(cx, 0.0f, 1.0f, myBox.xmin(), myBox.xmax()),
SYSfit(cy, 0.0f, 1.0f, myBox.ymin(), myBox.ymax()),
SYSfit(cz, 0.0f, 1.0f, myBox.zmin(), myBox.zmax()) );
// Create a new procedural object
// We create the procedural ourselves.
// Alternatively, it's also possible to create a procedural by
// passing arguments. This would allow the user to control which
// procedural gets built.
obj->addProcedural( new ray_ChildBox(c, mySize) );
}
}