HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SOP_PrimVOP.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  * PrimVOP SOP
27  */
28 
29 #include "SOP_PrimVOP.h"
30 
31 #include <SHOP/SHOP_Node.h>
34 #include <GVEX/GVEX_GeoCommand.h>
35 #include <GU/GU_Detail.h>
36 #include <OP/OP_AutoLockInputs.h>
37 #include <OP/OP_Channels.h>
38 #include <OP/OP_Operator.h>
39 #include <OP/OP_Director.h>
40 #include <OP/OP_OperatorTable.h>
41 #include <OP/OP_Caller.h>
42 #include <OP/OP_NodeInfoParms.h>
43 #include <OP/OP_VexFunction.h>
44 #include <PRM/PRM_DialogScript.h>
45 #include <PRM/PRM_Include.h>
46 #include <PRM/PRM_SpareData.h>
47 #include <CVEX/CVEX_Context.h>
48 #include <CVEX/CVEX_Value.h>
49 #include <VEX/VEX_Error.h>
50 #include <UT/UT_Array.h>
51 #include <UT/UT_DSOVersion.h>
52 #include <UT/UT_Interrupt.h>
53 
54 using namespace HDK_Sample;
55 void
57 {
58  table->addOperator(new OP_Operator(
59  "hdk_primvop",
60  "PrimVOP",
64  1,
65  1,
67 }
68 
69 static PRM_Default scriptDefault(PRM_DialogSopVex, "null");
70 
71 
72 static PRM_Name names[] = {
73  PRM_Name("script", "Script"),
74  PRM_Name("clear", "Re-load VEX Functions"),
75  PRM_Name("autobind", "Autobind by Name"),
76  PRM_Name("bindings", "Number of Bindings"),
77  PRM_Name("shoppath", "Shop Path"),
78  PRM_Name("vexsrc", "Vex Source"),
79 };
80 
81 static PRM_Name vexsrcNames[] =
82 {
83  PRM_Name("myself", "Myself"),
84  PRM_Name("shop", "Shop"),
85  PRM_Name("script", "Script"),
86  PRM_Name(0)
87 };
88 static PRM_ChoiceList vexsrcMenu(PRM_CHOICELIST_SINGLE, vexsrcNames);
89 
91 
94 {
96  &names[5], 0, &vexsrcMenu),
99  &names[4], 0, 0, 0, 0,
102  1, &names[0], &scriptDefault),
107  PRM_Template()
108 };
109 
110 
111 OP_Node *
113 {
114  return new SOP_PrimVOP(net, name, entry);
115 }
116 
117 
119  : SOP_Node(net, name, entry),
120  // Set up our code generator for CVEX
121  myCodeGenerator(this,
123  1, 1)
124 {
125  // This indicates that this SOP manually manages its data IDs,
126  // so that Houdini can identify what attributes may have changed,
127  // e.g. to reduce work for the viewport, or other SOPs that
128  // check whether data IDs have changed.
129  // By default, (i.e. if this line weren't here), all data IDs
130  // would be bumped after the SOP cook, to indicate that
131  // everything might have changed.
132  // If some data IDs don't get bumped properly, the viewport
133  // may not update, or SOPs that check data IDs
134  // may not cook correctly, so be *very* careful!
136 }
137 
139 {
140 }
141 
142 
143 OP_ERROR
145 {
146  fpreal t = context.getTime();
147 
148  // We must lock our inputs before we try to access their geometry.
149  // OP_AutoLockInputs will automatically unlock our inputs when we return.
150  // NOTE: Don't call unlockInputs yourself when using this!
151  OP_AutoLockInputs inputs(this);
152  if (inputs.lock(context) >= UT_ERROR_ABORT)
153  return error();
154 
155  duplicateSource(0, context);
156 
157  // Build our VEX script, either from the .vex file, or
158  // from the SHOP, or from the contained VOPs.
159  UT_String script;
160  buildScript(script, context.getTime());
161 
162  // If script is null, default to null script.
163  if (!script.isstring())
164  {
165  script = "null";
167  "No script specified. Using null.");
168  }
169 
170  // Parse the script's parameters.
171  char *argv[4096];
172  int argc = script.parse(argv, 4096);
173 
174  UT_AutoInterrupt boss("Executing Volume VEX");
175 
176  // This op caller is what allows op: style paths inside
177  // the CVEX context to properly set up dependencies to ourselves
178  // Ie, if you refer to a point cloud on another SOP, this
179  // SOP needs to recook when the referred to SOP is coooked.
180  OP_Caller caller(this);
181 
182  // Actually process the vex function
183  executeVex(argc, argv, t, caller);
184 
185  return error();
186 }
187 
188 void
189 SOP_PrimVOP::executeVex(int argc, char **argv,
190  fpreal t,
191  OP_Caller &opcaller)
192 {
193  CVEX_Context context;
194  CVEX_RunData rundata;
195 
196  // Note that this is a reasonable level to multithread at.
197  // Each thread will build its own VEX Context independently
198  // and thus, provided the read/write code is properly threadsafe
199  // be threadsafe.
200 
201  // Set the eval collection scope
203 
204  // The vex processing is block based. We first marshall a block
205  // of parameters from our primitive information. We then bind
206  // those parameters to vex. Then we process vex, and read out
207  // the new values.
208  const int chunksize = 1024;
209  UT_Array<int> primid(chunksize, chunksize);
210  UT_Array<exint> procid(chunksize, chunksize);
211 
212  // Set the callback.
213  rundata.setOpCaller(&opcaller);
214 
215  // If multithreading, each thread should allocate its own
216  // geocmd queue.
217  VEX_GeoCommandQueue geocmd;
218 
219  // In order to sort the resulting queue edits, we have to have
220  // a global order for all vex processors.
221  rundata.setProcId(procid.array());
222 
223  // These numbers are to seed the queue so it knows where to put
224  // newly created primitive/point numbers.
225  geocmd.myNumPrim = gdp->getNumPrimitives();
226  geocmd.myNumVertex = gdp->getNumVertices();
227  geocmd.myNumPoint = gdp->getNumPoints();
228 
229  rundata.setGeoCommandQueue(&geocmd);
230 
231  int n = 0;
232  GEO_Primitive *prim;
234  {
235  primid(n) = (int)prim->getMapIndex();
236  procid(n) = (exint)prim->getMapIndex();
237 
238  n++;
239 
240  if (n >= chunksize)
241  {
242  processVexBlock(context, rundata, argc, argv, primid.array(), n, t);
243  n = 0;
244  }
245  }
246 
247  // Handle any trailing values.
248  if (n)
249  processVexBlock(context, rundata, argc, argv, primid.array(), n, t);
250 
251  // If multithreaded, the following is done *after*
252  // all threads have joined.
253  // One does a fast merge like this:
254 /*
255  GVEX_GeoCommand allcmd;
256  for (int i = 0; i < numthreads; i++)
257  {
258  allcmd.appendQueue( threadcmds[i] );
259  }
260  allcmd.apply(gdp);
261 */
262  // Note that merging will steal data from the various thread queues,
263  // so the thread queues must be kept around until the application
264  // is complete.
265 
266  // In this example we are just doing single threading so we
267  // have but a single queue:
268  GVEX_GeoCommand allcmd;
269  allcmd.appendQueue(geocmd);
270 
271  // NOTE: This manages data IDs for any modifications it does.
272  allcmd.apply(gdp);
273 
274  if (context.getVexErrors().isstring())
275  addError(SOP_VEX_ERROR, (const char *)context.getVexErrors());
276  if (context.getVexWarnings().isstring())
277  addWarning(SOP_VEX_ERROR, (const char *)context.getVexWarnings());
278 }
279 
280 namespace HDK_Sample {
282 {
283 public:
284  const static int NUM_BUFFERS = 2;
285  const static int INPUT_BUFFER = 0;
286  const static int OUTPUT_BUFFER = 1;
287 
289  {
290  clear();
291  }
293  {
294  clear();
295  myName.harden(name);
296  myType = type;
297  }
299  {
300  clear();
301  *this = src;
302  }
303 
304  void clear()
305  {
306  myType = CVEX_TYPE_INVALID;
307  for (int i = 0; i < NUM_BUFFERS; i++)
308  {
309  myBuffer[i] = 0;
310  myBufLen[i] = 0;
311  }
312  }
313 
315  {
316  myName.harden(src.name());
317  myType = src.type();
318 
319  for (int i = 0; i < NUM_BUFFERS; i++)
320  {
321  delete [] myBuffer[i];
322  myBufLen[i] = src.myBufLen[i];
323  myBuffer[i] = 0;
324  if (src.buffer(i) && src.myBufLen[i])
325  {
326  myBuffer[i] = new char[myBufLen[i]];
327  memcpy(myBuffer[i], src.buffer(i), src.myBufLen[i]);
328  }
329  }
330 
331  return *this;
332  }
333 
335  {
336  for (int i = 0; i < NUM_BUFFERS; i++)
337  {
338  delete [] myBuffer[i];
339  }
340  }
341 
342  void allocateBuffer(int bufnum, int n)
343  {
344  delete [] myBuffer[bufnum];
345  switch (myType)
346  {
347  case CVEX_TYPE_INTEGER:
348  myBuffer[bufnum] = new char [sizeof(int) * n];
349  break;
350  case CVEX_TYPE_FLOAT:
351  myBuffer[bufnum] = new char [sizeof(float) * n];
352  break;
353  case CVEX_TYPE_VECTOR3:
354  myBuffer[bufnum] = new char [3*sizeof(float) * n];
355  break;
356  case CVEX_TYPE_VECTOR4:
357  myBuffer[bufnum] = new char [4*sizeof(float) * n];
358  break;
359  default:
360  UT_ASSERT(0);
361  break;
362  }
363  myBufLen[bufnum] = n;
364  }
365 
366  void marshallIntoBuffer(int bufnum, GU_Detail *gdp, int *primid, int n)
367  {
368  allocateBuffer(bufnum, n);
369 
370  const GA_Attribute *attrib = gdp->findPrimitiveAttribute(name());
371  if (attrib)
372  {
373  switch (myType)
374  {
375  case CVEX_TYPE_INTEGER:
376  {
377  GA_ROHandleI handle(attrib);
378  for (int i = 0; i < n; i++)
379  {
380  GA_Offset primoff = gdp->primitiveOffset(GA_Index(primid[i]));
381  ((int *)myBuffer[bufnum])[i] = handle.get(primoff);
382  }
383  break;
384  }
385  case CVEX_TYPE_FLOAT:
386  {
387  GA_ROHandleF handle(attrib);
388  for (int i = 0; i < n; i++)
389  {
390  GA_Offset primoff = gdp->primitiveOffset(GA_Index(primid[i]));
391  ((float *)myBuffer[bufnum])[i] = handle.get(primoff);
392  }
393  break;
394  }
395  case CVEX_TYPE_VECTOR3:
396  {
397  GA_ROHandleV3 handle(attrib);
398  for (int i = 0; i < n; i++)
399  {
400  GA_Offset primoff = gdp->primitiveOffset(GA_Index(primid[i]));
401  ((UT_Vector3 *)myBuffer[bufnum])[i] = handle.get(primoff);
402  }
403  break;
404  }
405  case CVEX_TYPE_VECTOR4:
406  {
407  GA_ROHandleV4 handle(attrib);
408  for (int i = 0; i < n; i++)
409  {
410  GA_Offset primoff = gdp->primitiveOffset(GA_Index(primid[i]));
411  ((UT_Vector4 *)myBuffer[bufnum])[i] = handle.get(primoff);
412  }
413  break;
414  }
415  default:
416  {
417  UT_ASSERT(0);
418  break;
419  }
420  }
421  }
422  }
423 
424  void marshallDataToGdp(int bufnum, GU_Detail *gdp, int *primid, int n, int inc)
425  {
426  GA_Attribute *attrib = gdp->findPrimitiveAttribute(name());
427  if (attrib)
428  {
429  switch (myType)
430  {
431  case CVEX_TYPE_INTEGER:
432  {
433  GA_RWHandleI handle(attrib);
434  for (int i = 0, src = 0; i < n; i++, src += inc)
435  {
436  GA_Offset primoff = gdp->primitiveOffset(GA_Index(primid[i]));
437  handle.set(primoff, ((int *)myBuffer[bufnum])[src]);
438  }
439  break;
440  }
441  case CVEX_TYPE_FLOAT:
442  {
443  GA_RWHandleF handle(attrib);
444  for (int i = 0, src = 0; i < n; i++, src += inc)
445  {
446  GA_Offset primoff = gdp->primitiveOffset(GA_Index(primid[i]));
447  handle.set(primoff, ((float *)myBuffer[bufnum])[src]);
448  }
449  break;
450  }
451  case CVEX_TYPE_VECTOR3:
452  {
453  GA_RWHandleV3 handle(attrib);
454  for (int i = 0, src = 0; i < n; i++, src += inc)
455  {
456  GA_Offset primoff = gdp->primitiveOffset(GA_Index(primid[i]));
457  handle.set(primoff, ((UT_Vector3 *)myBuffer[bufnum])[src]);
458  }
459  break;
460  }
461  case CVEX_TYPE_VECTOR4:
462  {
463  GA_RWHandleV4 handle(attrib);
464  for (int i = 0, src = 0; i < n; i++, src += inc)
465  {
466  GA_Offset primoff = gdp->primitiveOffset(GA_Index(primid[i]));
467  handle.set(primoff, ((UT_Vector4 *)myBuffer[bufnum])[src]);
468  }
469  break;
470  }
471  default:
472  {
473  UT_ASSERT(0);
474  break;
475  }
476  }
477  // We've modified the attribute, so its data ID should be bumped.
478  attrib->bumpDataId();
479  }
480  }
481 
482  const char *name() const { return myName; };
483  CVEX_Type type() const { return myType; }
484  const char *buffer(int bufnum) const { return myBuffer[bufnum]; }
485  char *buffer(int bufnum) { return myBuffer[bufnum]; }
486 
487 private:
488  UT_String myName;
489  CVEX_Type myType;
490  char *myBuffer[NUM_BUFFERS];
491  int myBufLen[NUM_BUFFERS];
492 };
493 }
494 
495 void
497  CVEX_RunData &rundata,
498  int argc, char **argv,
499  int *primid, int n,
500  fpreal t)
501 {
502  // We always export our primitive ids, so bind as integer.
503  context.addInput("primid", CVEX_TYPE_INTEGER, primid, n);
504 
505  // These are lazy evaluated since we don't want to pay
506  // the cost if not needed.
507  context.addInput("P", // Name of parameter
508  CVEX_TYPE_VECTOR3, // VEX Type
509  true); // Is varying?
510 
511  // We lazy add our time dependent inputs as we only want to
512  // flag time dependent if they are used.
513  context.addInput("Time", CVEX_TYPE_FLOAT, false);
514  context.addInput("TimeInc", CVEX_TYPE_FLOAT, false);
515  context.addInput("Frame", CVEX_TYPE_FLOAT, false);
516 
517  // Lazily bind all of our primitive attributes.
518  UT_Array<sop_bindparms> bindlist;
520  !it.atEnd();
521  ++it)
522  {
524 
525  GA_Attribute *attrib = it.attrib();
526  if( attrib->getStorageClass() == GA_STORECLASS_FLOAT &&
527  attrib->getTupleSize() < 3 )
528  {
529  type = CVEX_TYPE_FLOAT;
530  }
531  else if( attrib->getStorageClass() == GA_STORECLASS_FLOAT &&
532  attrib->getTupleSize() < 4 )
533  {
534  type = CVEX_TYPE_VECTOR3;
535  }
536  else if( attrib->getStorageClass() == GA_STORECLASS_FLOAT )
537  {
538  type = CVEX_TYPE_VECTOR4;
539  }
540  else if( attrib->getStorageClass() == GA_STORECLASS_INT )
541  {
542  type = CVEX_TYPE_INTEGER;
543  }
544  else
545  {
546  type = CVEX_TYPE_INVALID;
547  }
548 
549  if (type == CVEX_TYPE_INVALID)
550  continue;
551 
552  context.addInput(attrib->getName(), type, true);
553 
554  bindlist.append( sop_bindparms(attrib->getName(),
555  type) );
556  }
557 
558  // We want to evaluate at the context time, not at what
559  // the global frame time happens to be.
560  rundata.setTime(t);
561 
562  // Load our array.
563  if (!context.load(argc, argv))
564  return;
565 
566  // Check for lazily bound inputs
568  CVEX_Value *var;
569  var = context.findInput("P", CVEX_TYPE_VECTOR3);
570  if (var)
571  {
572  P.setSize(n);
573  for (int i = 0; i < n; i++)
574  {
575  GA_Offset primoff = gdp->primitiveOffset(GA_Index(primid[i]));
576  P(i) = gdp->getGEOPrimitive(primoff)->baryCenter();
577  }
578  var->setTypedData(P.array(), n);
579  }
580 
581  // Check if any of our parameters exist as either inputs or outputs.
582  for (exint j = 0; j < bindlist.entries(); j++)
583  {
584  var = context.findInput(bindlist(j).name(), bindlist(j).type());
585  if (var)
586  {
587  // This exists as an input, we have to marshall it.
588  bindlist(j).marshallIntoBuffer(sop_bindparms::INPUT_BUFFER,
589  gdp, primid, n);
590  void *buf = (void *)bindlist(j).buffer(sop_bindparms::INPUT_BUFFER);
591  var->setRawData(bindlist(j).type(), buf, n);
592  }
593 
594  // The same attribute may be both an input and an output
595  // This results in different CVEX_Values so requires two
596  // buffers in the bindings.
597  if ((var = context.findOutput(bindlist(j).name(), bindlist(j).type())))
598  {
599  bindlist(j).allocateBuffer(sop_bindparms::OUTPUT_BUFFER, n);
600  void *buf = (void *)bindlist(j).buffer(sop_bindparms::OUTPUT_BUFFER);
601  if (var->isVarying())
602  var->setRawData(bindlist(j).type(), buf, n);
603  else
604  var->setRawData(bindlist(j).type(), buf, 1);
605  }
606 
607  }
608 
609  // Compute the time dependent inputs.
610  fpreal32 curtime, curtimeinc, curframe;
611 
612  var = context.findInput("Time", CVEX_TYPE_FLOAT);
613  if (var)
614  {
615  OP_Node::flags().timeDep = true;
616 
617  curtime = t;
618 
619  var->setTypedData(&curtime, 1);
620  }
621  var = context.findInput("TimeInc", CVEX_TYPE_FLOAT);
622  if (var)
623  {
624  OP_Node::flags().timeDep = true;
625 
626  curtimeinc = 1.0f/OPgetDirector()->getChannelManager()->getSamplesPerSec();
627 
628  var->setTypedData(&curtimeinc, 1);
629  }
630  var = context.findInput("Frame", CVEX_TYPE_FLOAT);
631  if (var)
632  {
633  OP_Node::flags().timeDep = true;
634 
635  curframe = OPgetDirector()->getChannelManager()->getSample(t);
636 
637  var->setTypedData(&curframe, 1);
638  }
639 
640  // clear flag to detect time dependence of ch expressions.
641  rundata.setTimeDependent(false);
642 
643  // Actually execute the vex code!
644  // Allow interrupts.
645  context.run(n, true, &rundata);
646 
647  // Update our timedependency based on the flag
648  if (rundata.isTimeDependent())
649  OP_Node::flags().timeDep = 1;
650 
651  // Write out all bound parameters.
652  for (exint j = 0; j < bindlist.entries(); j++)
653  {
654  var = context.findOutput(bindlist(j).name(), bindlist(j).type());
655  if (var)
656  {
657  bindlist(j).marshallDataToGdp(sop_bindparms::OUTPUT_BUFFER, gdp, primid, n, (var->isVarying() ? 1 : 0));
658  }
659  }
660 }
661 
662 void
664 {
665  UT_String shoppath;
666  int vexsrc = VEXSRC(t);
667 
668  script = "";
669 
670  switch (vexsrc)
671  {
672  case 0:
673  {
674  getFullPath(shoppath);
675  script = "op:";
676  script += shoppath;
677  // buildVexCommand appends to our script variable.
679  break;
680  }
681 
682  case 2:
683  // Straightforward, use the explicit script
684  SCRIPT(script, t);
685  break;
686 
687  case 1:
688  {
689  SHOPPATH(shoppath, t);
690 
691  // Use the referenced shop network.
692  SHOP_Node *shop;
693  shop = findSHOPNode(shoppath);
694  if (shop)
695  {
696  shop->buildVexCommand(script, shop->getSpareParmTemplates(), t);
698 
699  // It is possible that we are dealing with a multi-context
700  // shader (ie, shop). In that case, we need to specify the
701  // shader context which we want to interpret it as. This is done
702  // by passing it as an argument. Since this operator invokes
703  // CVEX shader, we specify that type. Single-context shaders
704  // will ignore it.
705  shop->buildShaderString(script, t, 0, 0, 0, SHOP_CVEX);
706  }
707  break;
708  }
709  }
710 }
711 
712 bool
714 {
715  if (myCodeGenerator.getVariableString(index, value))
716  return true;
717  // else delegate to base class
718  return SOP_Node::evalVariableValue(value, index, thread);
719 }
720 
723 {
725 }
726 
729 {
730  return &myCodeGenerator;
731 }
732 
733 bool
735 {
736  return myCodeGenerator.hasShaderParameter(parm_name);
737 }
738 
739 const char *
741 {
742  return VOP_OPTYPE_NAME;
743 }
744 
747 {
748  return VOP_OPTYPE_ID;
749 }
750 
751 void
753 {
754  int update_id = myCodeGenerator.beginUpdate();
755  SOP_Node::opChanged(reason, data);
756  myCodeGenerator.ownerChanged(reason, data);
757  myCodeGenerator.endUpdate(update_id);
758 }
759 
760 void
762 {
764  SOP_Node::finishedLoadingNetwork(is_child_call);
765 }
766 
767 void
768 SOP_PrimVOP::addNode(OP_Node *node, int notify, int explicitly)
769 {
771  SOP_Node::addNode(node, notify, explicitly);
773 }
774 
775 void
777  OP_NodeInfoParms &iparms)
778 {
779  SOP_Node::getNodeSpecificInfoText(context, iparms);
780 
781 #if 0
782  // Compile errors should be already automatically reported in the
783  // node specific info. Still, here is an example of how that can be done
784  // explicitly.
785  UT_String errors;
786  if( myCodeGenerator.getCompilerErrors( errors ))
787  {
788  iparms.appendSeparator();
789  iparms.append(errors);
790  }
791 #endif
792 }
793 
void endUpdate(int update_level)
virtual void getNodeSpecificInfoText(OP_Context &context, OP_NodeInfoParms &parms)
Definition: SOP_PrimVOP.C:776
static PRM_Name theVopCompilerName
SYS_FORCE_INLINE void bumpDataId()
Definition: GA_Attribute.h:277
static PRM_SpareData shopCVEX
bool isTimeDependent() const
Definition: CVEX_Context.h:82
Definition of a geometry attribute.
Definition: GA_Attribute.h:189
void afterAddNode(OP_Node *node)
bool setTypedData(int *data, int array_size)
PRM_API const PRM_Type PRM_CALLBACK
virtual UT_Vector3 baryCenter() const
virtual void addNode(OP_Node *node, int notify=1, int explicitly=1)
Definition: SOP_PrimVOP.C:768
void setTime(fpreal time)
Definition: CVEX_Context.h:48
virtual OP_ERROR error()
iterator begin(GA_AttributeScope scope=GA_SCOPE_INVALID) const
PRM_API const PRM_Type PRM_STRING
const OP_NodeFlags & flags() const
Definition: OP_Node.h:1325
OP_ERROR lock(OP_Context &context)
Locks all inputs.
int getTupleSize() const
Size of the AIFTuple, if it exists. If it doesn't, 1.
const PRM_Template * getSpareParmTemplates() const
fpreal getTime() const
Definition: OP_Context.h:34
void beforeAddNode(OP_Node *node)
void setOpCaller(UT_OpCaller *caller)
Definition: CVEX_Context.h:72
void appendQueue(VEX_GeoCommandQueue &geocmd)
const UT_String & getVexWarnings() const
virtual OP_OperatorFilter * getOperatorFilter()
Overriding these are what allow us to contain VOPs.
Definition: SOP_PrimVOP.C:722
PRM_API const PRM_Type PRM_ORD
SOP_PrimVOP(OP_Network *net, const char *, OP_Operator *entry)
Definition: SOP_PrimVOP.C:118
virtual VOP_CodeGenerator * getVopCodeGenerator()
Definition: SOP_PrimVOP.C:728
virtual void finishedLoadingNetwork(bool is_child_call=false)
UT_ErrorSeverity
Definition: UT_Error.h:25
T * array()
Definition: UT_Array.h:607
Parameters for OP_Node::getInfoText()/OP_Node::getNodeSpecificInfoText()
static PRM_Name theVopForceCompileName
virtual bool hasShaderParameter(const char *parm_name)
bool addOperator(OP_Operator *op, std::ostream *err=nullptr)
static const char * theChildTableName
Definition: SOP_PrimVOP.h:71
int void appendSeparator()
Append a section separator.
virtual OP_ERROR cookMySop(OP_Context &context)
Definition: SOP_PrimVOP.C:144
const UT_StringHolder & getName() const
Definition: GA_Attribute.h:250
bool addInput(const UT_StringHolder &name, CVEX_Type type, bool varying)
bool getVariableString(int index, UT_String &value)
void addError(int code, const char *msg=0)
Definition: SOP_Node.h:1145
virtual bool evalVariableValue(fpreal &val, int index, int thread) override
png_uint_32 i
Definition: png.h:2877
void setSize(exint newsize)
Definition: UT_Array.h:462
OP_Channels * getChannels(void) const
static bool forceCompile(OP_Node *node)
const char * buffer(int bufnum) const
Definition: SOP_PrimVOP.C:484
Call VEX from C++.
Definition: CVEX_Context.h:147
CH_Manager * getChannelManager()
Definition: OP_Director.h:98
SYS_FORCE_INLINE GEO_Primitive * getGEOPrimitive(GA_Offset primoff)
Definition: GEO_Detail.h:1089
bool run(int array_size, bool interruptable, CVEX_RunData *rundata=nullptr)
GA_Size GA_Offset
Definition: GA_Types.h:617
static PRM_Template myTemplateList[]
Definition: SOP_PrimVOP.h:49
OP_OperatorFilter * getOperatorFilter()
GLdouble n
Definition: glcorearb.h:2007
CVEX_Type type() const
Definition: SOP_PrimVOP.C:483
CH_Manager * CHgetManager()
Definition: CH_Manager.h:1594
const CVEX_Value * findOutput(const UT_StringRef &name, CVEX_Type type) const
Find an output by name/type.
Definition: CVEX_Context.h:272
fpreal getSample(fpreal t) const
Definition: CH_Manager.h:993
bool isVarying() const
Query whether the VEX value is uniform or varying.
Definition: CVEX_Value.h:63
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:102
void SCRIPT(UT_String &s, fpreal t)
Definition: SOP_PrimVOP.h:87
void allocateBuffer(int bufnum, int n)
Definition: SOP_PrimVOP.C:342
void addWarning(SOP_ErrorCodes code, const char *msg=0)
Definition: SOP_Node.h:1151
int64 exint
Definition: SYS_Types.h:109
fpreal getSamplesPerSec() const
Definition: CH_Manager.h:961
GA_StorageClass getStorageClass() const
Returns the approximate type of the attribute.
void SHOPPATH(UT_String &path, fpreal t)
Definition: SOP_PrimVOP.h:90
virtual const char * getChildType() const
Definition: SOP_PrimVOP.C:740
char * buffer(int bufnum)
Definition: SOP_PrimVOP.C:485
sop_bindparms(const sop_bindparms &src)
Definition: SOP_PrimVOP.C:298
void harden()
Take shallow copy and make it deep.
Definition: UT_String.h:213
virtual bool buildShaderString(UT_String &result, fpreal now, const UT_Options *options, OP_Node *obj=0, OP_Node *sop=0, SHOP_TYPE interpret_type=SHOP_INVALID)
void ownerChanged(OP_EventType reason, void *data)
SOP_NodeFlags mySopFlags
Definition: SOP_Node.h:1601
#define GA_FOR_ALL_PRIMITIVES(gdp, prim)
Definition: GA_GBMacros.h:36
SYS_FORCE_INLINE T get(GA_Offset off, int comp=0) const
Definition: GA_Handle.h:194
UT_StringHolder getFullPath() const
Definition: PRM_ParmOwner.h:59
GLboolean * data
Definition: glcorearb.h:130
GLuint const GLchar * name
Definition: glcorearb.h:785
GA_Size GA_Index
Define the strictness of GA_Offset/GA_Index.
Definition: GA_Types.h:611
CVEX_Type
The CVEX_Type enum defines the VEX types available to CVEX.
Definition: CVEX_Value.h:23
PRM_API const PRM_Type PRM_COMMAND
void executeVex(int argc, char **argv, fpreal t, OP_Caller &opcaller)
Definition: SOP_PrimVOP.C:189
void setManagesDataIDs(bool onOff)
Definition: SOP_NodeFlags.h:34
virtual OP_OpTypeId getChildTypeID() const
Definition: SOP_PrimVOP.C:746
OP_OpTypeId
Definition: OP_Node.h:263
A class representing a VEX value.
Definition: CVEX_Value.h:50
virtual void opChanged(OP_EventType reason, void *data=0)
We need special alerts now that we contain VOPs.
Definition: SOP_PrimVOP.C:752
Per-run data for CVEX execution.
Definition: CVEX_Context.h:36
void setGeoCommandQueue(VEX_GeoCommandQueue *geocmd)
Sets the command queue for this context.
Definition: CVEX_Context.h:101
GU_Detail * gdp
Definition: SOP_Node.h:1598
SYS_FORCE_INLINE const GA_Attribute * findPrimitiveAttribute(GA_AttributeScope s, const UT_StringRef &name) const
Definition: GA_Detail.h:971
sop_bindparms & operator=(const sop_bindparms &src)
Definition: SOP_PrimVOP.C:314
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2539
exint entries() const
Alias of size(). size() is preferred.
Definition: UT_Array.h:446
virtual bool evalVariableValue(UT_String &value, int index, int thread)
Code generation variables.
Definition: SOP_PrimVOP.C:713
static CH_LocalVariable theLocalVariables[]
static OP_Node * myConstructor(OP_Network *net, const char *name, OP_Operator *entry)
Definition: SOP_PrimVOP.C:112
SYS_FORCE_INLINE GA_Size getNumVertices() const
Return the number verticies in the entire detail.
Definition: GA_Detail.h:444
void setTimeDependent(bool v)
Definition: CVEX_Context.h:127
GLsizei const GLfloat * value
Definition: glcorearb.h:823
double fpreal
Definition: SYS_Types.h:263
SYS_FORCE_INLINE GA_Index getMapIndex() const
Gets the index of this primitive in the detail containing it.
Definition: GA_Primitive.h:142
#define VOP_TABLE_NAME
Definition: OP_Node.h:210
virtual void addNode(OP_Node *node, int notify=1, int explicitly=1)
Push & restore the evaluation time (and optionally a channel collection)
Definition: CH_Manager.h:1504
const char * name() const
Definition: SOP_PrimVOP.C:482
SYS_API int SYSgetSTID()
virtual void opChanged(OP_EventType reason, void *data=0) override
typedef int
Definition: png.h:1175
virtual void addExtraInput(OP_Node *op, OP_InterestType type)
Definition: OP_Node.h:1573
virtual void getNodeSpecificInfoText(OP_Context &context, OP_NodeInfoParms &iparms) override
const CVEX_Value * findInput(const UT_StringRef &name, CVEX_Type type) const
Find an input by name/type.
Definition: CVEX_Context.h:250
SYS_FORCE_INLINE void set(GA_Offset off, const T &val) const
Definition: GA_Handle.h:351
void marshallDataToGdp(int bufnum, GU_Detail *gdp, int *primid, int n, int inc)
Definition: SOP_PrimVOP.C:424
#define VOP_OPTYPE_NAME
Definition: OP_Node.h:252
SYS_FORCE_INLINE GA_Offset primitiveOffset(GA_Index index) const
Given a primitive's index (in append order), return its data offset.
Definition: GA_Detail.h:359
SYS_FORCE_INLINE const GA_AttributeDict & primitiveAttribs() const
Definition: GEO_Detail.h:1825
OP_API OP_Director * OPgetDirector()
GLuint index
Definition: glcorearb.h:785
void newSopOperator(OP_OperatorTable *table)
Definition: SOP_PrimVOP.C:56
sop_bindparms(const char *name, CVEX_Type type)
Definition: SOP_PrimVOP.C:292
int buildVexCommand(UT_String &result, const PRM_Template *templatelist, fpreal now, int start_parm=0, int end_parm=INT_MAX)
SYS_FORCE_INLINE GA_Size getNumPrimitives() const
Return the number of primitives.
Definition: GA_Detail.h:348
OP_EventType
Definition: OP_Value.h:22
bool setRawData(CVEX_Type type, void *data, int array_size)
Type unsafe way of setting VEX data. Avoid using if possible.
exint append(void)
Definition: UT_Array.h:95
SHOP_Node * findSHOPNode(const char *path) const
Definition: OP_Node.h:564
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
static const int INPUT_BUFFER
Definition: SOP_PrimVOP.C:285
virtual void finishedLoadingNetwork(bool is_child_call=false)
VOP and VEX functions.
Definition: SOP_PrimVOP.C:761
bool isstring() const
Definition: UT_String.h:689
void append(const char *string)
Append a string to the text buffer.
void marshallIntoBuffer(int bufnum, GU_Detail *gdp, int *primid, int n)
Definition: SOP_PrimVOP.C:366
void ownerFinishedLoadingNetwork()
void setProcId(exint *procid)
Definition: CVEX_Context.h:94
void processVexBlock(CVEX_Context &context, CVEX_RunData &rundata, int argc, char **argv, int *primid, int n, fpreal t)
Definition: SOP_PrimVOP.C:496
static PRM_Default theVopCompilerVexDefault
float fpreal32
Definition: SYS_Types.h:184
VOP_CodeGenerator myCodeGenerator
Definition: SOP_PrimVOP.h:123
virtual bool hasVexShaderParameter(const char *parm_name)
Definition: SOP_PrimVOP.C:734
int parse(char *argv[], int maxArgs)
Definition: UT_String.h:790
bool load(int argc, const char *const argv[])
int VEXSRC(fpreal t)
Definition: SOP_PrimVOP.h:85
static const int NUM_BUFFERS
Definition: SOP_PrimVOP.C:284
static const int OUTPUT_BUFFER
Definition: SOP_PrimVOP.C:286
void buildScript(UT_String &script, fpreal t)
Definition: SOP_PrimVOP.C:663
SYS_FORCE_INLINE GA_Size getNumPoints() const
Return the number of points.
Definition: GA_Detail.h:281
GLenum src
Definition: glcorearb.h:1792
OP_ERROR duplicateSource(unsigned index, OP_Context &context, GU_Detail *gdp, bool clean=true)
const UT_String & getVexErrors() const