HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SOP_DualStar.C
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018
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 Dual Star SOP
27  */
28 
29 #include "SOP_DualStar.h"
30 
31 #include <GU/GU_Detail.h>
32 #include <GEO/GEO_PrimPoly.h>
33 #include <OP/OP_Operator.h>
34 #include <OP/OP_OperatorTable.h>
35 #include <OP/OP_AutoLockInputs.h>
36 #include <PRM/PRM_Include.h>
37 #include <CH/CH_LocalVariable.h>
38 #include <UT/UT_DSOVersion.h>
39 #include <UT/UT_Interrupt.h>
40 #include <SYS/SYS_Math.h>
41 #include <limits.h>
42 
43 using namespace HDK_Sample;
44 
45 //
46 // Help is stored in a "wiki" style text file. This text file should be copied
47 // to $HOUDINI_PATH/help/nodes/sop/star.txt
48 //
49 // See the sample_install.sh file for an example.
50 //
51 
52 
53 ///
54 /// newSopOperator is the hook that Houdini grabs from this dll
55 /// and invokes to register the SOP. In this case we add ourselves
56 /// to the specified operator table.
57 ///
58 void
60 {
61  table->addOperator(new OP_Operator(
62  "hdk_dualstar", // Internal name
63  "Dual Star", // UI name
64  SOP_DualStar::myConstructor, // How to build the SOP
65  SOP_DualStar::myTemplateList, // My parameters
66  1, // Min # of sources
67  1, // Max # of sources
68  0, // Local variables
69  OP_FLAG_GENERATOR, // Flag it as generator
70  0, // labels
71  2)); // Outputs.
72 }
73 
74 static PRM_Name negativeName("nradius", "Negative Radius");
75 // ^^^^^^^^ ^^^^^^^^^^^^^^^
76 // internal descriptive version
77 
78 static PRM_Default fiveDefault(5); // Default to 5 divisions
79 static PRM_Default radiiDefaults[] = {
80  PRM_Default(1), // Outside radius
81  PRM_Default(0.3) // Inside radius
82  };
83 
86  PRM_Template(PRM_INT, // Integer parameter.
87  PRM_Template::PRM_EXPORT_TBX, // Export to top of viewer
88  // when user selects this node
89  1, // One integer in this row/parameter
90  &PRMdivName, // Name of this parameter - must be static
91  &fiveDefault, // Default for this parameter - ditto
92  0, // Menu for this parameter
93  &PRMdivision2Range // Valid range
94  ),
95  PRM_Template(PRM_XYZ, 2, &PRMradiusName, radiiDefaults),
96  PRM_Template(PRM_TOGGLE, 1, &negativeName),
99  PRM_Template()
100 };
101 
102 
103 OP_Node *
105 {
106  return new SOP_DualStar(net, name, op);
107 }
108 
110  : SOP_Node(net, name, op)
111 {
112  // We do not manage our ids, so do not set the flag.
113 }
114 
116 
117 OP_ERROR
119 {
120  // We must lock our inputs before we try to access their geometry.
121  // OP_AutoLockInputs will automatically unlock our inputs when we return.
122  // NOTE: Don't call unlockInputs yourself when using this!
123  OP_AutoLockInputs inputs(this);
124  if (inputs.lock(context) >= UT_ERROR_ABORT)
125  return error();
126 
127  duplicateSource(0, context);
128 
129  // Start the interrupt server
130  buildStar(gdp, context);
131 
132  return error();
133 }
134 
135 void
137 {
138  fpreal now = context.getTime();
139  int divisions = DIVISIONS(now)*2; // We need twice our divisions of points
140 
141  int plane = ORIENT();
142  int negradius = NEGRADIUS();
143  float tx = CENTERX(now);
144  float ty = CENTERY(now);
145  float tz = CENTERZ(now);
146 
147  int xcoord, ycoord, zcoord;
148  switch (plane)
149  {
150  case 0: // XY Plane
151  xcoord = 0;
152  ycoord = 1;
153  zcoord = 2;
154  break;
155  case 1: // YZ Plane
156  xcoord = 1;
157  ycoord = 2;
158  zcoord = 0;
159  break;
160  case 2: // XZ Plane
161  xcoord = 0;
162  ycoord = 2;
163  zcoord = 1;
164  break;
165  }
166 
167  if (divisions < 4)
168  {
169  // With the range restriction we have on the divisions, this
170  // is actually impossible, but it shows how to add an error
171  // message or warning to the SOP.
172  addWarning(SOP_MESSAGE, "Invalid divisions");
173  divisions = 4;
174  }
175 
176  // Start the interrupt server
177  UT_AutoInterrupt boss("Building Star");
178  if (boss.wasInterrupted())
179  {
180  return;
181  }
182 
183  // Build a polygon
184  GEO_PrimPoly *poly = GEO_PrimPoly::build(dst, divisions, GU_POLY_CLOSED);
185  float tinc = M_PI*2 / (float)divisions;
186 
187  // Now, set all the points of the polygon
188  for (int i = 0; i < divisions; i++)
189  {
190  // Check to see if the user has interrupted us...
191  if (boss.wasInterrupted())
192  break;
193 
194  // Since we expect the local variables to be used in specifying
195  // the radii, we have to evaluate the channels INSIDE the loop
196  // through the points...
197 
198  float tmp = (float)i * tinc;
199  float rad = (i & 1) ? XRADIUS(now) : YRADIUS(now);
200  if (!negradius && rad < 0)
201  rad = 0;
202 
203  UT_Vector3 pos;
204  pos(xcoord) = SYScos(tmp) * rad + tx;
205  pos(ycoord) = SYSsin(tmp) * rad + ty;
206  pos(zcoord) = 0 + tz;
207 
208  GA_Offset ptoff = poly->getPointOffset(i);
209  dst->setPos3(ptoff, pos);
210  }
211 
212 }
213 
215 SOP_DualStar::cookMySopOutput(OP_Context &context, int outputidx, SOP_Node *interests)
216 {
217  GU_DetailHandle result;
218  GU_Detail *dst = new GU_Detail();
219 
220  result.allocateAndSet(dst);
221 
222  buildStar(dst, context);
223 
224  return result;
225 }
SYS_FORCE_INLINE void setPos3(GA_Offset ptoff, const UT_Vector3 &P)
Set P from a UT_Vector3.
Definition: GA_Detail.h:207
virtual OP_ERROR error()
OP_ERROR lock(OP_Context &context)
Locks all inputs.
fpreal getTime() const
Definition: OP_Context.h:60
PRM_API const PRM_Type PRM_ORD
PRM_API PRM_Name PRMradiusName
#define OP_FLAG_GENERATOR
Definition: OP_Operator.h:68
UT_ErrorSeverity
Definition: UT_Error.h:25
bool addOperator(OP_Operator *op, std::ostream *err=nullptr)
png_uint_32 i
Definition: png.h:2877
#define M_PI
Definition: ImathPlatform.h:51
PRM_API const PRM_Type PRM_INT
void allocateAndSet(GU_Detail *gdp, bool own=true)
GA_Size GA_Offset
Definition: GA_Types.h:617
SOP_DualStar(OP_Network *net, const char *name, OP_Operator *op)
Definition: SOP_DualStar.C:109
PRM_API PRM_Name PRMorientName
static OP_Node * myConstructor(OP_Network *, const char *, OP_Operator *)
Definition: SOP_DualStar.C:104
void addWarning(SOP_ErrorCodes code, const char *msg=0)
Definition: SOP_Node.h:1139
PRM_API PRM_Range PRMdivision2Range
PRM_API const PRM_Type PRM_XYZ
static PRM_Template myTemplateList[]
Definition: SOP_DualStar.h:43
SYS_FORCE_INLINE GA_Offset getPointOffset(GA_Size i) const
Definition: GEO_TriMesh.h:164
void newSopOperator(OP_OperatorTable *table)
Definition: SOP_DualStar.C:59
PRM_API PRM_Name PRMdivName
GLuint const GLchar * name
Definition: glcorearb.h:785
GU_Detail * gdp
Definition: SOP_Node.h:1595
GLenum GLenum dst
Definition: glcorearb.h:1792
double fpreal
Definition: SYS_Types.h:270
virtual OP_ERROR cookMySop(OP_Context &context)
Definition: SOP_DualStar.C:118
PRM_API const PRM_Type PRM_TOGGLE
virtual GU_DetailHandle cookMySopOutput(OP_Context &context, int outputidx, SOP_Node *interest)
Definition: SOP_DualStar.C:215
void buildStar(GU_Detail *dst, OP_Context &context)
Actually build a star in the given geometry.
Definition: SOP_DualStar.C:136
PRM_API PRM_Name PRMcenterName
PRM_API PRM_ChoiceList PRMplaneMenu
static GEO_PrimPoly * build(GA_Detail *gdp, GA_Size nvertices, bool open=false, bool appendpts=true)
#define GU_POLY_CLOSED
Definition: GU_Types.h:119
OP_ERROR duplicateSource(unsigned index, OP_Context &context, GU_Detail *gdp, bool clean=true)