HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
field3d/ROP_Field3D.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 <OP/OP_Director.h>
#include <SOP/SOP_Node.h>
#include <ROP/ROP_Error.h>
#include <UT/UT_IOTable.h>
#include "ROP_Field3D.h"
#include "f3d_io.h"
#include <Field3D/InitIO.h>
using namespace HDK_Sample;
static PRM_Name sopPathName("soppath", "SOP Path");
static PRM_Name theFileName("file", "Output File");
static PRM_Default theFileDefault(0, "$HIP/$F.f3d");
static PRM_Name alfprogressName("alfprogress", "Alfred Style Progress");
static PRM_Name theGridTypes[] =
{
PRM_Name("dense", "Dense"),
PRM_Name("sparse", "Sparse"),
};
static PRM_ChoiceList theGridTypeMenu(PRM_CHOICELIST_SINGLE, theGridTypes);
static PRM_Name gridtypeName("gridtype", "Grid Type");
static PRM_Name theBitDepths[] =
{
PRM_Name("auto", "Auto Detect"),
PRM_Name("fp16", "16bit Float"),
PRM_Name("fp32", "Float"),
PRM_Name("fp64", "Double"),
};
static PRM_ChoiceList theBitDepthMenu(PRM_CHOICELIST_SINGLE, theBitDepths);
static PRM_Name bitdepthName("bitdepth", "Bit Depth");
static PRM_Name collateName("collatevector", "Collate Vector Fields");
static PRM_Template f3dTemplates[] = {
0, 0, 0, 0, &PRM_SpareData::sopPath),
PRM_Template(PRM_FILE, 1, &theFileName, &theFileDefault,0,
PRM_Template(PRM_TOGGLE, 1, &alfprogressName, PRMzeroDefaults),
PRM_Template(PRM_ORD, 1, &gridtypeName, PRMoneDefaults,
&theGridTypeMenu),
PRM_Template(PRM_ORD, 1, &bitdepthName, 0,
&theBitDepthMenu),
};
static PRM_Template *
getTemplates()
{
static PRM_Template *theTemplate = 0;
if (theTemplate)
return theTemplate;
theTemplate = new PRM_Template[ROP_F3D_MAXPARMS+1];
theTemplate[ROP_F3D_RENDER] = theRopTemplates[ROP_RENDER_TPLATE];
theTemplate[ROP_F3D_RENDER_CTRL] = theRopTemplates[ROP_RENDERDIALOG_TPLATE];
theTemplate[ROP_F3D_TRANGE] = theRopTemplates[ROP_TRANGE_TPLATE];
theTemplate[ROP_F3D_FRANGE] = theRopTemplates[ROP_FRAMERANGE_TPLATE];
theTemplate[ROP_F3D_TAKE] = theRopTemplates[ROP_TAKENAME_TPLATE];
theTemplate[ROP_F3D_SOPPATH] = f3dTemplates[0];
theTemplate[ROP_F3D_SOPOUTPUT] = f3dTemplates[1];
theTemplate[ROP_F3D_GRIDTYPE] = f3dTemplates[3];
theTemplate[ROP_F3D_BITDEPTH] = f3dTemplates[4];
theTemplate[ROP_F3D_COLLATE] = f3dTemplates[5];
theTemplate[ROP_F3D_INITSIM] = theRopTemplates[ROP_INITSIM_TPLATE];
theTemplate[ROP_F3D_ALFPROGRESS] = f3dTemplates[2];
theTemplate[ROP_F3D_TPRERENDER] = theRopTemplates[ROP_TPRERENDER_TPLATE];
theTemplate[ROP_F3D_PRERENDER] = theRopTemplates[ROP_PRERENDER_TPLATE];
theTemplate[ROP_F3D_LPRERENDER] = theRopTemplates[ROP_LPRERENDER_TPLATE];
theTemplate[ROP_F3D_TPREFRAME] = theRopTemplates[ROP_TPREFRAME_TPLATE];
theTemplate[ROP_F3D_PREFRAME] = theRopTemplates[ROP_PREFRAME_TPLATE];
theTemplate[ROP_F3D_LPREFRAME] = theRopTemplates[ROP_LPREFRAME_TPLATE];
theTemplate[ROP_F3D_TPOSTFRAME] = theRopTemplates[ROP_TPOSTFRAME_TPLATE];
theTemplate[ROP_F3D_POSTFRAME] = theRopTemplates[ROP_POSTFRAME_TPLATE];
theTemplate[ROP_F3D_LPOSTFRAME] = theRopTemplates[ROP_LPOSTFRAME_TPLATE];
theTemplate[ROP_F3D_TPOSTRENDER] = theRopTemplates[ROP_TPOSTRENDER_TPLATE];
theTemplate[ROP_F3D_POSTRENDER] = theRopTemplates[ROP_POSTRENDER_TPLATE];
theTemplate[ROP_F3D_LPOSTRENDER] = theRopTemplates[ROP_LPOSTRENDER_TPLATE];
theTemplate[ROP_F3D_MAXPARMS] = PRM_Template();
UT_ASSERT(PRM_Template::countTemplates(theTemplate) == ROP_F3D_MAXPARMS);
return theTemplate;
}
ROP_Field3D::getTemplatePair()
{
static OP_TemplatePair *ropPair = 0;
if (!ropPair)
{
ropPair = new OP_TemplatePair(getTemplates());
}
return ropPair;
}
ROP_Field3D::getVariablePair()
{
static OP_VariablePair *pair = 0;
if (!pair)
return pair;
}
ROP_Field3D::myConstructor(OP_Network *net, const char *name, OP_Operator *op)
{
return new ROP_Field3D(net, name, op);
}
ROP_Field3D::ROP_Field3D(OP_Network *net, const char *name, OP_Operator *entry)
: ROP_Node(net, name, entry)
{
}
ROP_Field3D::~ROP_Field3D()
{
}
//------------------------------------------------------------------------------
// The startRender(), renderFrame(), and endRender() render methods are
// invoked by Houdini when the ROP runs.
int
ROP_Field3D::startRender(int /*nframes*/, fpreal tstart, fpreal tend)
{
int rcode = 1;
myEndTime = tend;
myStartTime = tstart;
if (INITSIM())
{
initSimulationOPs();
}
{
if( !executePreRenderScript(tstart) )
return 0;
}
return rcode;
}
ROP_Field3D::renderFrame(fpreal time, UT_Interrupt *)
{
SOP_Node *sop;
UT_String soppath, savepath;
if( !executePreFrameScript(time) )
// From here, establish the SOP that will be rendered, if it cannot
// be found, return 0.
// This is needed to be done here as the SOPPATH may be time
// dependent (ie: OUT$F) or the perframe script may have
// rewired the input to this node.
sop = CAST_SOPNODE(getInput(0));
if( sop )
{
// If we have an input, get the full path to that SOP.
sop->getFullPath(soppath);
}
else
{
// Otherwise get the SOP Path from our parameter.
SOPPATH(soppath, time);
}
if( !soppath.isstring() )
{
addError(ROP_MESSAGE, "Invalid SOP path");
}
sop = getSOPNode(soppath, 1);
if (!sop)
{
addError(ROP_COOK_ERROR, (const char *)soppath);
}
OP_Context context(time);
gdh = sop->getCookedGeoHandle(context);
const GU_Detail *gdp = gdl.getGdp();
if (!gdp)
{
addError(ROP_COOK_ERROR, (const char *)soppath);
}
OUTPUT(savepath, time);
f3d_fileSave(gdp, (const char *) savepath,
(F3D_BitDepth) BITDEPTH(time),
(F3D_GridType) GRIDTYPE(time),
COLLATE(time));
if (ALFPROGRESS() && (myEndTime != myStartTime))
{
fpreal fpercent = (time - myStartTime) / (myEndTime - myStartTime);
int percent = (int)SYSrint(fpercent * 100);
percent = SYSclamp(percent, 0, 100);
fprintf(stdout, "ALF_PROGRESS %d%%\n", percent);
fflush(stdout);
}
{
if( !executePostFrameScript(time) )
}
}
ROP_Field3D::endRender()
{
if (INITSIM())
{
if( !executePostRenderScript(myEndTime) )
}
}
void
{
Field3D::initIO();
table->addOperator(new OP_Operator("hdk_field3d",
"Field 3D",
ROP_Field3D::myConstructor,
ROP_Field3D::getTemplatePair(),
0,
0,
ROP_Field3D::getVariablePair(),
}