HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SOP_Tetra.C
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2024
3  * Side Effects Software Inc. All rights reserved.
4  *
5  * Redistribution and use of Houdini Development Kit samples in source and
6  * binary forms, with or without modification, are permitted provided that the
7  * following conditions are met:
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * 2. The name of Side Effects Software may not be used to endorse or
11  * promote products derived from this software without specific prior
12  * written permission.
13  *
14  * THIS SOFTWARE IS PROVIDED BY SIDE EFFECTS SOFTWARE `AS IS' AND ANY EXPRESS
15  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
17  * NO EVENT SHALL SIDE EFFECTS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  *----------------------------------------------------------------------------
26  * The Tetra SOP
27  */
28 
29 #include "SOP_Tetra.h"
30 #include "GEO_PrimTetra.h"
31 
32 #include <GU/GU_Detail.h>
33 #include <OP/OP_Operator.h>
34 #include <OP/OP_OperatorTable.h>
35 #include <CH/CH_LocalVariable.h>
36 #include <PRM/PRM_Include.h>
37 #include <UT/UT_DSOVersion.h>
38 #include <UT/UT_Interrupt.h>
39 #include <UT/UT_Vector3.h>
40 #include <SYS/SYS_Types.h>
41 #include <limits.h>
42 #include <stddef.h>
43 
44 using namespace HDK_Sample;
45 
46 //
47 // Help is stored in a "wiki" style text file. The text file should be copied
48 // to $HOUDINI_PATH/help/nodes/sop/tetra.txt
49 //
50 // See the sample_install.sh file for an example.
51 //
52 
53 
54 ///
55 /// newSopOperator is the hook that Houdini grabs from this dll
56 /// and invokes to register the SOP. In this case we add ourselves
57 /// to the specified operator table.
58 ///
59 void
61 {
62  table->addOperator(new OP_Operator(
63  "hdk_tetra", // Internal name
64  "Tetra", // UI name
65  SOP_Tetra::myConstructor, // How to build the SOP
66  SOP_Tetra::myTemplateList, // My parameters
67  0, // Min # of sources
68  0, // Max # of sources
69  0, // Local variables
70  OP_FLAG_GENERATOR)); // Flag it as generator
71 }
72 
77  PRM_Template()
78 };
79 
80 
81 OP_Node *
83 {
84  return new SOP_Tetra(net, name, op);
85 }
86 
88  : SOP_Node(net, name, op)
89 {
90  // This indicates that this SOP manually manages its data IDs,
91  // so that Houdini can identify what attributes may have changed,
92  // e.g. to reduce work for the viewport, or other SOPs that
93  // check whether data IDs have changed.
94  // By default, (i.e. if this line weren't here), all data IDs
95  // would be bumped after the SOP cook, to indicate that
96  // everything might have changed.
97  // If some data IDs don't get bumped properly, the viewport
98  // may not update, or SOPs that check data IDs
99  // may not cook correctly, so be *very* careful!
101 }
102 
104 
105 OP_ERROR
107 {
108  fpreal now = context.getTime();
109 
110  // Since we don't have inputs, we don't need to lock them.
111 
112  float rad = RADIUS(now);
113  UT_Vector3 translate(CENTERX(now), CENTERY(now), CENTERZ(now));
114 
115  // Try to reuse the existing tetrahedron, if the detail
116  // hasn't been cleared.
117  GEO_PrimTetra *tet = NULL;
118  if (gdp->getNumPrimitives() == 1)
119  {
121 
122  // This type check is not strictly necessary, since
123  // this SOP only ever makes a GEO_PrimTetra, but it's
124  // here just in case, and as an example.
125  if (prim->getTypeId() == GEO_PrimTetra::theTypeId())
126  tet = (GEO_PrimTetra *)prim;
127  }
128 
129  if (tet == NULL)
130  {
131  // In addition to destroying everything except the empty P
132  // and topology attributes, this bumps the data IDs for
133  // those remaining attributes, as well as the primitive list
134  // data ID.
135  gdp->clearAndDestroy();
136 
137  // Build a tetrahedron
138  tet = GEO_PrimTetra::build(gdp, true);
139  }
140 
141  for (int i = 0; i < 4; i++)
142  {
143  UT_Vector3 pos(i == 1, i == 2, i == 3);
144  pos *= rad;
145  pos += translate;
146  GA_Offset ptoff = tet->getPointOffset(i);
147  gdp->setPos3(ptoff, pos);
148  }
149 
150  // We've modified P, so we need to bump the data ID,
151  // (though in the case where we did clearAndDestroy(), it's
152  // redundant, because that already bumped it).
153  gdp->getP()->bumpDataId();
154 
155  // Note that we have NOT bumped the primitive list id.
156  // This is because our primtive has no private data. This stops
157  // Houdini from copying it because it can re-use old versions.
158  // If you have private data in your primitive you expect to copy,
159  // you must ALSO bump the primitive list id everytime you modify
160  // the internal data.
161  //
162  // gdp->getPrimitiveList().bumpDataId();
163 
164  // Set the node selection for this primitive. This will highlight all
165  // the tets generated by the node, but only if the highlight flag for this
166  // node is on and the node is selected.
168 
169  return error();
170 }
SYS_FORCE_INLINE void bumpDataId()
Definition: GA_Attribute.h:306
SYS_FORCE_INLINE GA_Offset getPointOffset(GA_Size i) const
Definition: GA_Primitive.h:254
static GEO_PrimTetra * build(GA_Detail *gdp, bool appendpts=true)
Optional build function.
GA_Primitive * getPrimitiveByIndex(GA_Index prim_idx)
Definition: GA_Detail.h:438
virtual OP_ERROR error()
PRM_API const PRM_Type PRM_FLT
fpreal getTime() const
Definition: OP_Context.h:62
void clearAndDestroy()
Clear all the points/primitives out of this detail.
Definition: GEO_Detail.h:267
GA_Attribute * getP()
Convenience method to access the P attribute.
Definition: GA_Detail.h:164
#define OP_FLAG_GENERATOR
Definition: OP_Operator.h:82
UT_ErrorSeverity
Definition: UT_Error.h:25
SYS_FORCE_INLINE const GA_PrimitiveTypeId & getTypeId() const
Definition: GA_Primitive.h:177
bool addOperator(OP_Operator *op, std::ostream *err=nullptr)
GA_Size GA_Offset
Definition: GA_Types.h:641
PRM_API const PRM_Type PRM_XYZ
SOP_NodeFlags mySopFlags
Definition: SOP_Node.h:1625
static PRM_Template myTemplateList[]
Definition: SOP_Tetra.h:42
static const GA_PrimitiveTypeId & theTypeId()
Allows you to find out what this primitive type was named.
SOP_Tetra(OP_Network *net, const char *name, OP_Operator *op)
Definition: SOP_Tetra.C:87
GLuint const GLchar * name
Definition: glcorearb.h:786
GLenum GLenum GLsizei void * table
Definition: glad.h:5129
void setManagesDataIDs(bool onOff)
Definition: SOP_NodeFlags.h:36
GU_Detail * gdp
Definition: SOP_Node.h:1622
OP_ERROR cookMySop(OP_Context &context) override
Definition: SOP_Tetra.C:106
PRM_API PRM_Default PRMoneDefaults[]
SYS_FORCE_INLINE void setPos3(GA_Offset ptoff, const UT_Vector3 &pos)
Set P from a UT_Vector3.
Definition: GA_Detail.h:237
fpreal64 fpreal
Definition: SYS_Types.h:277
SYS_FORCE_INLINE GA_Size getNumPrimitives() const
Return the number of primitives.
Definition: GA_Detail.h:408
void newSopOperator(OP_OperatorTable *table)
Definition: SOP_Tetra.C:60
void select(GU_SelectionType stype)
PUGI__FN char_t * translate(char_t *buffer, const char_t *from, const char_t *to, size_t to_length)
Definition: pugixml.cpp:8352
PRM_API PRM_Name PRMradiusName
static OP_Node * myConstructor(OP_Network *, const char *, OP_Operator *)
Definition: SOP_Tetra.C:82
~SOP_Tetra() override
Definition: SOP_Tetra.C:103
PRM_API PRM_Name PRMcenterName