HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SOP_ArrayAttrib.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  * ArrayAttrib SOP
27  */
28 
29 #include "SOP_ArrayAttrib.h"
30 
31 #include <GU/GU_Detail.h>
32 #include <GA/GA_Handle.h>
33 #include <OP/OP_AutoLockInputs.h>
34 #include <OP/OP_Operator.h>
35 #include <OP/OP_OperatorTable.h>
36 #include <PRM/PRM_Include.h>
37 #include <UT/UT_DSOVersion.h>
38 
39 using namespace HDK_Sample;
40 void
42 {
43  table->addOperator(new OP_Operator(
44  "hdk_arrayattrib",
45  "Array Attribute",
48  1,
49  1));
50 }
51 
52 
53 static PRM_Name sop_names[] = {
54  PRM_Name("attribname", "Attribute"),
55  PRM_Name("value", "Value"),
56 };
57 
58 static PRM_Default sop_valueDefault(0.1);
59 static PRM_Range sop_valueRange(PRM_RANGE_RESTRICTED,0,PRM_RANGE_UI,1);
60 
63 {
64  PRM_Template(PRM_STRING, 1, &sop_names[0], 0),
65  PRM_Template()
66 };
67 
68 
69 OP_Node *
71 {
72  return new SOP_ArrayAttrib(net, name, entry);
73 }
74 
75 
77  : SOP_Node(net, name, entry)
78 {
79  // This indicates that this SOP manually manages its data IDs,
80  // so that Houdini can identify what attributes may have changed,
81  // e.g. to reduce work for the viewport, or other SOPs that
82  // check whether data IDs have changed.
83  // By default, (i.e. if this line weren't here), all data IDs
84  // would be bumped after the SOP cook, to indicate that
85  // everything might have changed.
86  // If some data IDs don't get bumped properly, the viewport
87  // may not update, or SOPs that check data IDs
88  // may not cook correctly, so be *very* careful!
90 }
91 
93 {
94 }
95 
96 
99 {
100  fpreal t = context.getTime();
101 
102  // We must lock our inputs before we try to access their geometry.
103  // OP_AutoLockInputs will automatically unlock our inputs when we return.
104  // NOTE: Don't call unlockInputs yourself when using this!
105  OP_AutoLockInputs inputs(this);
106  if (inputs.lock(context) >= UT_ERROR_ABORT)
107  return error();
108 
109  duplicateSource(0, context);
110 
111  UT_String aname;
112  ATTRIBNAME(aname, t);
113 
115  aname,
116  // Allow any tuple size to match
117  -1, -1);
118  if (!attrib)
119  {
120  attrib = gdp->addIntArray(GA_ATTRIB_POINT,
121  aname,
122  // Tuple size one means we group the array into
123  // logical groups of 1. It does *NOT* affect
124  // the length of the arrays, which are always
125  // measured in ints.
126  1);
127  }
128 
129  // See if we failed to make the array.
130  if (!attrib)
131  {
133  buf.sprintf("Failed to create array attributes \"%s\"",
134  (const char *) aname);
135  addError(SOP_MESSAGE, buf.buffer());
136  return error();
137  }
138 
139  // Make sure we are an array. Note tuples do not match to this,
140  // nor do GA_*Handle* match!
141  // We will match both int and float here, however.
142  // (For string, getAIFSharedStringArray)
143  const GA_AIFNumericArray *aif = attrib->getAIFNumericArray();
144  if (!aif)
145  {
147  buf.sprintf("Attribute \"%s\" not a numeric array!",
148  (const char *) aname);
149  addError(SOP_MESSAGE, buf.buffer());
150  return error();
151  }
152 
153  // We keep our read/write array outside of the inner loop.
154  // This allows this to grow to the maximum size encountered
155  // and avoid reallocations.
157 
158  GA_Offset ptoff;
159  GA_FOR_ALL_PTOFF(gdp, ptoff)
160  {
161  // Fetch array value
162  aif->get(attrib, ptoff, data);
163 
164  // Append our point number if the current length
165  // is less than the point number.
166  GA_Index ptidx = gdp->pointIndex(ptoff);
167  if (data.entries() < ptidx)
168  data.append(ptidx);
169 
170  // Write back
171  aif->set(attrib, ptoff, data);
172  }
173 
174 
175  // Mark as modified.
176  attrib->bumpDataId();
177 
178  return error();
179 }
180 
SYS_FORCE_INLINE void bumpDataId()
Definition: GA_Attribute.h:306
Definition of a geometry attribute.
Definition: GA_Attribute.h:198
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2540
Generic Attribute Interface class to access an attribute as a array.
static OP_Node * myConstructor(OP_Network *net, const char *name, OP_Operator *entry)
virtual OP_ERROR error()
PRM_API const PRM_Type PRM_STRING
OP_ERROR lock(OP_Context &context)
Locks all inputs.
GLboolean * data
Definition: glcorearb.h:131
fpreal getTime() const
Definition: OP_Context.h:62
SYS_FORCE_INLINE const char * buffer() const
UT_ErrorSeverity
Definition: UT_Error.h:25
bool addOperator(OP_Operator *op, std::ostream *err=nullptr)
void addError(int code, const char *msg=0)
Definition: SOP_Node.h:1161
const GA_Attribute * findIntArray(GA_AttributeOwner owner, GA_AttributeScope scope, const UT_StringRef &name, int min_size=1, int max_size=-1) const
void ATTRIBNAME(UT_String &str, fpreal t)
GA_Size GA_Offset
Definition: GA_Types.h:646
GA_Attribute * addIntArray(GA_AttributeOwner owner, GA_AttributeScope scope, const UT_StringHolder &name, int tuple_size=1, const UT_Options *creation_args=0, const GA_AttributeOptions *attribute_options=0, GA_Storage storage=GA_STORE_INT32, const GA_ReuseStrategy &reuse=GA_ReuseStrategy())
OP_ERROR cookMySop(OP_Context &context) override
SOP_NodeFlags mySopFlags
Definition: SOP_Node.h:1628
static PRM_Template myTemplateList[]
GLuint const GLchar * name
Definition: glcorearb.h:786
#define GA_FOR_ALL_PTOFF(gdp, ptoff)
Definition: GA_GBMacros.h:88
GA_Size GA_Index
Define the strictness of GA_Offset/GA_Index.
Definition: GA_Types.h:640
GLenum GLenum GLsizei void * table
Definition: glad.h:5129
void setManagesDataIDs(bool onOff)
Definition: SOP_NodeFlags.h:36
exint append()
Definition: UT_Array.h:142
GLdouble t
Definition: glad.h:2397
int sprintf(const char *fmt,...) SYS_PRINTF_CHECK_ATTRIBUTE(2
GU_Detail * gdp
Definition: SOP_Node.h:1625
exint entries() const
Alias of size(). size() is preferred.
Definition: UT_Array.h:648
SYS_FORCE_INLINE GA_Index pointIndex(GA_Offset offset) const
Given a point's data offset, return its index.
Definition: GA_Detail.h:349
virtual bool get(const GA_Attribute *attrib, GA_Offset ai, UT_Array< fpreal16 > &data) const =0
fpreal64 fpreal
Definition: SYS_Types.h:277
void newSopOperator(OP_OperatorTable *table)
virtual bool set(GA_Attribute *attrib, GA_Offset ai, const UT_Span< const fpreal16 > &data) const =0
SOP_ArrayAttrib(OP_Network *net, const char *, OP_Operator *entry)
OP_ERROR duplicateSource(unsigned index, OP_Context &context, GU_Detail *gdp, bool clean=true)
virtual const GA_AIFNumericArray * getAIFNumericArray() const
Return the attribute's arraydata interface or NULL.