29 #include "SOP_VolumeProject.proto.h" 
   43 using namespace UT::Literal;
 
   44 using namespace HDK_Sample;
 
   51         SOP_VolumeProject::myConstructor,
 
   52         SOP_VolumeProject::buildTemplates(),
 
   57 static const char *theDsFile = R
"THEDSFILE( 
   62         label   "Velocity Volumes" 
   65         parmtag { "script_action" "import soputils\nkwargs['geometrytype'] = (hou.geometryType.Primitives,)\nkwargs['inputindex'] = 0\nsoputils.selectGroupParm(kwargs)" } 
   66         parmtag { "script_action_help" "Select geometry from an available viewport.\nShift-click to turn on Select Groups." } 
   67         parmtag { "script_action_icon" "BUTTONS_reselect" } 
   72         label   "Divergence Volume" 
   75         parmtag { "script_action" "import soputils\nkwargs['geometrytype'] = (hou.geometryType.Primitives,)\nkwargs['inputindex'] = 1\nsoputils.selectGroupParm(kwargs)" } 
   76         parmtag { "script_action_help" "Select geometry from an available viewport.\nShift-click to turn on Select Groups." } 
   77         parmtag { "script_action_icon" "BUTTONS_reselect" } 
   85         parmtag { "script_action" "import soputils\nkwargs['geometrytype'] = (hou.geometryType.Primitives,)\nkwargs['inputindex'] = 2\nsoputils.selectGroupParm(kwargs)" } 
   86         parmtag { "script_action_help" "Select geometry from an available viewport.\nShift-click to turn on Select Groups." } 
   87         parmtag { "script_action_icon" "BUTTONS_reselect" } 
   95         parmtag { "script_action" "import soputils\nkwargs['geometrytype'] = (hou.geometryType.Primitives,)\nkwargs['inputindex'] = 3\nsoputils.selectGroupParm(kwargs)" } 
   96         parmtag { "script_action_help" "Select geometry from an available viewport.\nShift-click to turn on Select Groups." } 
   97         parmtag { "script_action_icon" "BUTTONS_reselect" } 
  122         label   "LUT Round Pattern" 
  151         label   "Zero Inactive" 
  160 SOP_VolumeProject::buildTemplates() 
  206     virtual void        cook(
const CookParms &cookparms) 
const;
 
  215     return theSOPVolumeProjectVerb.get();
 
  226     auto                &&sopparms = cookparms.
parms<SOP_VolumeProjectParms>();
 
  227     bool                doround = sopparms.getLUTRound();
 
  233     if (sopparms.getLUTCenter() - sopparms.getLUTRad() < 0)
 
  243     if (sopparms.getLUTCenter() - sopparms.getLUTRad() < 0)
 
  258     float       lutmagic = sopparms.getLUTMagic();
 
  260     lutmagic /= voxelsize.
x();
 
  266         exint                           curtile = 
r.begin();
 
  272             int         rad = sopparms.getLUTRad();
 
  276                 if (active->
getValue(vit.
x(), vit.
y(), vit.
z()) < 0.5)
 
  278                     if (sopparms.getZeroInactive())
 
  289                 if ( (vit.
z() - rad) & 1 )
 
  291                 if ( !( (vit.
z() + rad) & 1 ) )
 
  295             for (
int z = radzmin; 
z <= radzmax; 
z++)
 
  299                 if (vit.
z() + 
z >= divzres)
 
  307                     if ( (vit.
y() - rad) & 1 )
 
  309                     if ( !( (vit.
y() + rad) & 1 ) )
 
  313                 for (
int y = radymin; 
y <= radymax; 
y++)
 
  317                     if (vit.
y() + 
y >= divyres)
 
  325                         if ( (vit.
x() - rad) & 1 )
 
  327                         if ( !( (vit.
x() + rad) & 1 ) )
 
  331                     for (
int x = radxmin; 
x <= radxmax; 
x++)
 
  335                         if (vit.
x() + 
x >= divxres)
 
  339                         float val = (*div)(vit.
x()+
x, vit.
y()+
y, vit.
z()+
z);
 
  342                         val *= (*lut)(sopparms.getLUTCenter() - 
x,
 
  343                                       sopparms.getLUTCenter() - 
y,
 
  344                                       sopparms.getLUTCenter() - 
z);
 
  399         exint                           curtile = 
r.begin();
 
  409             for (
int dz = 0; dz <= 1; dz++)
 
  411                 int z = vit.
z() * 2 + dz;
 
  414                 for (
int dy = 0; dy <= 1; dy++)
 
  416                     int y = vit.
y() * 2 + dy;
 
  419                     for (
int dx = 0; dx <= 1; dx++)
 
  421                         int x = vit.
x() * 2 + dx;
 
  425                         float   div_v = (*div_vox)(
x, 
y, 
z);
 
  461         old_pos = pos_mip.
last();
 
  462         old_neg = neg_mip.
last();
 
  474         pos = pos_mip.
last();
 
  475         neg = neg_mip.
last();
 
  491             for (
int dz = 0; dz <= 1; dz++)
 
  493                 int z = vit.
z() * 2 + dz;
 
  496                 for (
int dy = 0; dy <= 1; dy++)
 
  498                     int y = vit.
y() * 2 + dy;
 
  501                     for (
int dx = 0; dx <= 1; dx++)
 
  503                         int x = vit.
x() * 2 + dx;
 
  510                         pos_v += (*old_pos)(
x, 
y, 
z);
 
  511                         neg_v += (*old_neg)(
x, 
y, 
z);
 
  533     auto                &&sopparms = cookparms.
parms<SOP_VolumeProjectParms>();
 
  540     float               mipmagic = sopparms.getMIPMagic();
 
  541     mipmagic = 1 / mipmagic;
 
  546     mipmagic *= voxelsize.
x();
 
  547     mipmagic /= 4 * 
M_PI;
 
  552         exint                           curtile = 
r.begin();
 
  559                 if (active->
getValue(vit.
x(), vit.
y(), vit.
z()) < 0.5)
 
  567             bool                inspect = 
false;
 
  580             minvalid.
x() = vit.
x() - sopparms.getLUTRad();
 
  581             maxvalid.
x() = vit.
x() + sopparms.getLUTRad();
 
  582             minvalid.
y() = vit.
y() - sopparms.getLUTRad();
 
  583             maxvalid.
y() = vit.
y() + sopparms.getLUTRad();
 
  584             minvalid.
z() = vit.
z() - sopparms.getLUTRad();
 
  585             maxvalid.
z() = vit.
z() + sopparms.getLUTRad();
 
  606             for (
int pass = 0; pass < pos_mip.
entries(); pass++)
 
  608                 auto && pos = pos_mip(pass);
 
  609                 auto && neg = neg_mip(pass);
 
  626                 mingoal.
x() = (vit.
x() >> (pass+2)) - 1;
 
  627                 mingoal.
y() = (vit.
y() >> (pass+2)) - 1;
 
  628                 mingoal.
z() = (vit.
z() >> (pass+2)) - 1;
 
  629                 maxgoal.
x() = (vit.
x() >> (pass+2)) + 1;
 
  630                 maxgoal.
y() = (vit.
y() >> (pass+2)) + 1;
 
  631                 maxgoal.
z() = (vit.
z() >> (pass+2)) + 1;
 
  641                 mingoal.
x() = 
SYSmax(mingoal.
x(), 0);
 
  642                 mingoal.
y() = 
SYSmax(mingoal.
y(), 0);
 
  643                 mingoal.
z() = 
SYSmax(mingoal.
z(), 0);
 
  644                 maxgoal.
x() = 
SYSmin(maxgoal.
x(), pos->getXRes()-1);
 
  645                 maxgoal.
y() = 
SYSmin(maxgoal.
y(), pos->getYRes()-1);
 
  646                 maxgoal.
z() = 
SYSmin(maxgoal.
z(), pos->getZRes()-1);
 
  649                 if (pass == pos_mip.
entries()-1)
 
  654                     maxgoal.
x() = pos->getXRes()-1;
 
  655                     maxgoal.
y() = pos->getYRes()-1;
 
  656                     maxgoal.
z() = pos->getZRes()-1;
 
  663                 for (
int z = mingoal.
z(); 
z <= maxgoal.
z(); 
z++)
 
  665                     bool        ztest = (
z >= minvalid.
z() && 
z <= maxvalid.
z());
 
  667                     for (
int y = mingoal.
y(); 
y <= maxgoal.
y(); 
y++)
 
  669                         bool    ytest = (
y >= minvalid.
y() && 
y <= maxvalid.
y());
 
  670                         for (
int x = mingoal.
x(); 
x <= maxgoal.
x(); 
x++)
 
  672                             bool        xtest = (
x >= minvalid.
x() && 
x <= maxvalid.
x());
 
  674                             if (ztest && ytest && xtest)
 
  697                                 float   displen = p.
length();
 
  698                                 float   paxis = p(axis);
 
  702                                 paxis /= (displen*displen*displen);
 
  706                                 delta += pos_v.
w() * paxis;
 
  721                                 float   displen = p.
length();
 
  722                                 float   paxis = p(axis);
 
  726                                 paxis /= (displen*displen*displen);
 
  730                                 delta -= neg_v.
w() * paxis;
 
  767     auto                &&sopparms = cookparms.
parms<SOP_VolumeProjectParms>();
 
  771     float               mipmagic = sopparms.getMIPMagic();
 
  772     mipmagic = 1 / mipmagic;
 
  782     mipmagic *= voxelsize.
x();
 
  785     mipmagic /= 4 * 
M_PI;
 
  793         exint                           curtile = 
r.begin();
 
  800                 if (active->
getValue(vit.
x(), vit.
y(), vit.
z()) < 0.5)
 
  808             bool                inspect = 
false;
 
  821             minvalid.
x() = vit.
x() - sopparms.getLUTRad();
 
  822             maxvalid.
x() = vit.
x() + sopparms.getLUTRad();
 
  823             minvalid.
y() = vit.
y() - sopparms.getLUTRad();
 
  824             maxvalid.
y() = vit.
y() + sopparms.getLUTRad();
 
  825             minvalid.
z() = vit.
z() - sopparms.getLUTRad();
 
  826             maxvalid.
z() = vit.
z() + sopparms.getLUTRad();
 
  847             for (
int pass = 0; pass < pos_mip.
entries(); pass++)
 
  849                 auto && pos = pos_mip(pass);
 
  850                 auto && neg = neg_mip(pass);
 
  867                 mingoal.
x() = (vit.
x() >> (pass+2)) - 1;
 
  868                 mingoal.
y() = (vit.
y() >> (pass+2)) - 1;
 
  869                 mingoal.
z() = (vit.
z() >> (pass+2)) - 1;
 
  870                 maxgoal.
x() = (vit.
x() >> (pass+2));
 
  871                 maxgoal.
y() = (vit.
y() >> (pass+2));
 
  872                 maxgoal.
z() = (vit.
z() >> (pass+2));
 
  873                 if ( (vit.
x() >> (pass+1)) & 1)
 
  879                 if ( (vit.
y() >> (pass+1)) & 1)
 
  885                 if ( (vit.
z() >> (pass+1)) & 1)
 
  900                 mingoal.
x() = 
SYSmax(mingoal.
x(), 0);
 
  901                 mingoal.
y() = 
SYSmax(mingoal.
y(), 0);
 
  902                 mingoal.
z() = 
SYSmax(mingoal.
z(), 0);
 
  903                 maxgoal.
x() = 
SYSmin(maxgoal.
x(), pos->getXRes()-1);
 
  904                 maxgoal.
y() = 
SYSmin(maxgoal.
y(), pos->getYRes()-1);
 
  905                 maxgoal.
z() = 
SYSmin(maxgoal.
z(), pos->getZRes()-1);
 
  908                 if (pass == pos_mip.
entries()-1)
 
  913                     maxgoal.
x() = pos->getXRes()-1;
 
  914                     maxgoal.
y() = pos->getYRes()-1;
 
  915                     maxgoal.
z() = pos->getZRes()-1;
 
  922                 for (
int z = mingoal.
z(); 
z <= maxgoal.
z(); 
z++)
 
  924                     bool        ztest = (
z >= minvalid.
z() && 
z <= maxvalid.
z());
 
  926                     for (
int y = mingoal.
y(); y <= maxgoal.
y(); y++)
 
  928                         bool    ytest = (y >= minvalid.
y() && y <= maxvalid.
y());
 
  929                         for (
int x = mingoal.
x(); x <= maxgoal.
x(); x++)
 
  931                             bool        xtest = (x >= minvalid.
x() && x <= maxvalid.
x());
 
  933                             if (ztest && ytest && xtest)
 
  956                                 float   displen = p.
length();
 
  957                                 float   paxis = p(axis);
 
  961                                 paxis /= (displen*displen*displen);
 
  965                                 delta += pos_v.
w() * paxis;
 
  980                                 float   displen = p.
length();
 
  981                                 float   paxis = p(axis);
 
  985                                 paxis /= (displen*displen*displen);
 
  989                                 delta -= neg_v.
w() * paxis;
 
 1022     auto                &&sopparms = cookparms.
parms<SOP_VolumeProjectParms>();
 
 1036     if (sopparms.getGroup().isstring())
 
 1048     notifyGroupParmListeners(cookparms.
getNode(), 0, -1, gdp, velgrp);
 
 1052     if (sopparms.getDivGroup().isstring())
 
 1066     if (sopparms.getLUTGroup().isstring())
 
 1080     if (sopparms.getActiveGroup().isstring())
 
 1118         cookparms.
sopAddWarning(
SOP_MESSAGE, 
"Unmatched veloicty volume ignored; provide matching triples of velocity volumes.");
 
 1162         cookparms.
sopAddWarning(
SOP_MESSAGE, 
"Unmatched sets of velocity and divergence volumes specified.  Unmatched ignored.");
 
 1168         cookparms.
sopAddError(
SOP_MESSAGE, 
"Unmatched sets of divergence and active volumes specified.  Abandoning.");
 
 1175     for (
int pass = 0; pass < npass; pass++)
 
 1191         if (pass < active.
size())
 
 1193             activeh = 
active(pass)->getVoxelHandle();
 
 1194             activev = &*activeh;
 
 1198         sop_applyVelLUT(cookparms, &*vxh, &*divh, activev, &*lutxh, velx(pass)->getVoxelSize());
 
 1199         sop_applyVelLUT(cookparms, &*vyh, &*divh, activev, &*lutyh, vely(pass)->getVoxelSize());
 
 1200         sop_applyVelLUT(cookparms, &*vzh, &*divh, activev, &*lutzh, velz(pass)->getVoxelSize());
 
 1202         if (sopparms.getDoMIP())
 
 1206             sop_buildMipMap(pos_mip, neg_mip, 
div(pass));
 
 1208             if (sopparms.getMipBy4())
 
 1210                 sop_applyMipMap4(cookparms, 0,
 
 1211                                            velx(pass), &*vxh, activev,
 
 1213                 sop_applyMipMap4(cookparms, 1,
 
 1214                                            vely(pass), &*vyh, activev,
 
 1216                 sop_applyMipMap4(cookparms, 2,
 
 1217                                            velz(pass), &*vzh, activev,
 
 1222                 sop_applyMipMap(cookparms, 0,
 
 1223                                            velx(pass), &*vxh, activev,
 
 1225                 sop_applyMipMap(cookparms, 1,
 
 1226                                            vely(pass), &*vyh, activev,
 
 1228                 sop_applyMipMap(cookparms, 2,
 
 1229                                            velz(pass), &*vzh, activev,
 
 1233             for (
auto && map : pos_mip)
 
 1235             for (
auto && map : neg_mip)
 
 1239     gdp->bumpAllDataIds();
 
static PRM_ChoiceList primGroupMenu
 
int x() const 
Retrieve the current location of the iterator. 
 
GA_API const UT_StringHolder div
 
SOP_Node * getNode() const 
 
#define UTdebugPrintCd(...)
 
bool atEnd() const 
Returns true if we have iterated over all of the voxels. 
 
void setChoiceListPtr(const UT_StringRef &name, PRM_ChoiceList *list)
 
UT_ErrorSeverity sopAddWarning(int code, const char *msg=0, const UT_SourceLocation *loc=0) const 
 
GOP_GroupParse::GroupCreator GroupCreator
 
void setValue(UT_Vector3I index, T value)
 
virtual ~SOP_VolumeProjectVerb()
 
constexpr SYS_FORCE_INLINE T & y() noexcept
 
void UTparallelForEachNumber(IntType nitems, const Body &body, const bool force_use_task_scope=true)
 
UT_Vector3T< float > UT_Vector3
 
GLdouble GLdouble GLdouble z
 
constexpr SYS_FORCE_INLINE T & z() noexcept
 
SYS_FORCE_INLINE const GA_PrimitiveTypeId & getTypeId() const 
 
UT_VoxelArray< UT_Vector4 > UT_VoxelArrayV4
 
GEO_PrimVolumeXform getIndexSpaceTransform() const 
 
constexpr SYS_FORCE_INLINE T length() const noexcept
 
bool addOperator(OP_Operator *op, std::ostream *err=nullptr)
 
bool atEnd() const 
Returns true if we have iterated over all of the voxels. 
 
void size(int xres, int yres, int zres, bool reset=true)
 
#define GA_FOR_ALL_OPT_GROUP_PRIMITIVES(gdp, grp, prim)
 
constexpr SYS_FORCE_INLINE T & x() noexcept
 
UT_ErrorSeverity sopAddError(int code, const char *msg=0, const UT_SourceLocation *loc=0) const 
 
void rewind()
Resets the iterator to point to the first voxel. 
 
const SOP_NodeVerb * cookVerb() const overridefinal
 
virtual CookMode cookMode(const SOP_NodeParms *parms) const 
 
int opInterrupt(int percent=-1)
 
Constructs a PRM_Template list from an embedded .ds file or an istream. 
 
void advance()
Advances the iterator to point to the next voxel. 
 
void setValue(T t) const 
Sets the voxel we are currently pointing to the given value. 
 
void rewind()
Resets the iterator to point to the first voxel. 
 
constexpr SYS_FORCE_INLINE T & z() noexcept
 
PRM_Template * templates() const 
 
const GA_PrimitiveGroup * parsePrimitiveGroups(const char *pat, const GroupCreator &creator, bool numok=true, bool ordered=false, bool strict=false, GA_Index prim_offset=GA_Index(0), ParseInfo *info=0)
 
OP_ERROR cookMyselfAsVerb(OP_Context &context)
 
void selectInputGroup(const GA_Group *group, GA_GroupType grouptype) const 
 
GLuint const GLchar * name
 
GLenum GLenum GLsizei void * table
 
that also have some descendant prim *whose name begins with which in turn has a child named baz where *the predicate active
 
void newSopOperator(OP_OperatorTable *table)
 
exint entries() const 
Alias of size(). size() is preferred. 
 
void setLinearTile(exint lineartilenum, UT_VoxelArray< T > *array)
 
GA_API const UT_StringHolder parms
 
T getValue(int x, int y, int z) const 
 
virtual SOP_NodeParms * allocParms() const 
 
UT_API UT_Interrupt * UTgetInterrupt()
Obtain global UT_Interrupt singleton. 
 
constexpr SYS_FORCE_INLINE T & w() noexcept
 
const GU_Detail * inputGeo(exint idx) const 
 
UT_Vector3 getVoxelSize() const 
Returns the length of the voxel when you take an x, y, and z step. 
 
OP_ERROR cookMySop(OP_Context &context) overridefinal
 
virtual UT_StringHolder name() const 
 
UT_VoxelArrayHandleF getVoxelHandle() const 
 
constexpr SYS_FORCE_INLINE T & y() noexcept
 
~SOP_VolumeProject() override
 
GU_DetailHandle & gdh() const 
The initial state of gdh depends on the cookMode() 
 
virtual void cook(const CookParms &cookparms) const 
Compute the output geometry. 
 
void advance()
Advances the iterator to point to the next voxel. 
 
constexpr SYS_FORCE_INLINE T & x() noexcept