HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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, context.getContextOptionsStack(),
181  context.getContextOptions());
182 
183  // Actually process the vex function
184  executeVex(argc, argv, t, caller);
185 
186  return error();
187 }
188 
189 void
190 SOP_PrimVOP::executeVex(int argc, char **argv,
191  fpreal t,
192  OP_Caller &opcaller)
193 {
194  CVEX_Context context;
195  CVEX_RunData rundata;
196 
197  // Note that this is a reasonable level to multithread at.
198  // Each thread will build its own VEX Context independently
199  // and thus, provided the read/write code is properly threadsafe
200  // be threadsafe.
201 
202  // Set the eval collection scope
204  getChannels(), opcaller.getContextOptionsStack(),
205  opcaller.getContextOptions());
206 
207  // The vex processing is block based. We first marshall a block
208  // of parameters from our primitive information. We then bind
209  // those parameters to vex. Then we process vex, and read out
210  // the new values.
211  const int chunksize = 1024;
212  UT_Array<int> primid(chunksize, chunksize);
213  UT_Array<exint> procid(chunksize, chunksize);
214 
215  // Set the callback.
216  rundata.setOpCaller(&opcaller);
217 
218  // If multithreading, each thread should allocate its own
219  // geocmd queue.
221 
222  // In order to sort the resulting queue edits, we have to have
223  // a global order for all vex processors.
224  rundata.setProcId(procid.array());
225 
226  // These numbers are to seed the queue so it knows where to put
227  // newly created primitive/point numbers.
228  geocmd.myNumPrim = gdp->getNumPrimitives();
229  geocmd.myNumVertex = gdp->getNumVertices();
230  geocmd.myNumPoint = gdp->getNumPoints();
231 
232  rundata.setGeoCommandQueue(&geocmd);
233 
234  int n = 0;
235  GEO_Primitive *prim;
237  {
238  primid(n) = (int)prim->getMapIndex();
239  procid(n) = (exint)prim->getMapIndex();
240 
241  n++;
242 
243  if (n >= chunksize)
244  {
245  processVexBlock(context, rundata, argc, argv, primid.array(), n, t);
246  n = 0;
247  }
248  }
249 
250  // Handle any trailing values.
251  if (n)
252  processVexBlock(context, rundata, argc, argv, primid.array(), n, t);
253 
254  // If multithreaded, the following is done *after*
255  // all threads have joined.
256  // One does a fast merge like this:
257 /*
258  GVEX_GeoCommand allcmd;
259  for (int i = 0; i < numthreads; i++)
260  {
261  allcmd.appendQueue( threadcmds[i] );
262  }
263  allcmd.apply(gdp);
264 */
265  // Note that merging will steal data from the various thread queues,
266  // so the thread queues must be kept around until the application
267  // is complete.
268 
269  // In this example we are just doing single threading so we
270  // have but a single queue:
272  allcmd.appendQueue(geocmd);
273 
274  // NOTE: This manages data IDs for any modifications it does.
275  allcmd.apply(gdp);
276 
277  if (context.getVexErrors().isstring())
278  addError(SOP_VEX_ERROR, (const char *)context.getVexErrors());
279  if (context.getVexWarnings().isstring())
280  addWarning(SOP_VEX_ERROR, (const char *)context.getVexWarnings());
281 }
282 
283 namespace HDK_Sample {
285 {
286 public:
287  const static int NUM_BUFFERS = 2;
288  const static int INPUT_BUFFER = 0;
289  const static int OUTPUT_BUFFER = 1;
290 
292  {
293  clear();
294  }
296  {
297  clear();
298  myName.harden(name);
299  myType = type;
300  }
302  {
303  clear();
304  *this = src;
305  }
306 
307  void clear()
308  {
309  myType = CVEX_TYPE_INVALID;
310  for (int i = 0; i < NUM_BUFFERS; i++)
311  {
312  myBuffer[i] = 0;
313  myBufLen[i] = 0;
314  }
315  }
316 
318  {
319  myName.harden(src.name());
320  myType = src.type();
321 
322  for (int i = 0; i < NUM_BUFFERS; i++)
323  {
324  delete [] myBuffer[i];
325  myBufLen[i] = src.myBufLen[i];
326  myBuffer[i] = 0;
327  if (src.buffer(i) && src.myBufLen[i])
328  {
329  myBuffer[i] = new char[myBufLen[i]];
330  memcpy(myBuffer[i], src.buffer(i), src.myBufLen[i]);
331  }
332  }
333 
334  return *this;
335  }
336 
338  {
339  for (int i = 0; i < NUM_BUFFERS; i++)
340  {
341  delete [] myBuffer[i];
342  }
343  }
344 
345  void allocateBuffer(int bufnum, int n)
346  {
347  delete [] myBuffer[bufnum];
348  switch (myType)
349  {
350  case CVEX_TYPE_INTEGER:
351  myBuffer[bufnum] = new char [sizeof(int) * n];
352  break;
353  case CVEX_TYPE_FLOAT:
354  myBuffer[bufnum] = new char [sizeof(float) * n];
355  break;
356  case CVEX_TYPE_VECTOR3:
357  myBuffer[bufnum] = new char [3*sizeof(float) * n];
358  break;
359  case CVEX_TYPE_VECTOR4:
360  myBuffer[bufnum] = new char [4*sizeof(float) * n];
361  break;
362  default:
363  UT_ASSERT(0);
364  break;
365  }
366  myBufLen[bufnum] = n;
367  }
368 
369  void marshallIntoBuffer(int bufnum, GU_Detail *gdp, int *primid, int n)
370  {
371  allocateBuffer(bufnum, n);
372 
373  const GA_Attribute *attrib = gdp->findPrimitiveAttribute(name());
374  if (attrib)
375  {
376  switch (myType)
377  {
378  case CVEX_TYPE_INTEGER:
379  {
380  GA_ROHandleI handle(attrib);
381  for (int i = 0; i < n; i++)
382  {
383  GA_Offset primoff = gdp->primitiveOffset(GA_Index(primid[i]));
384  ((int *)myBuffer[bufnum])[i] = handle.get(primoff);
385  }
386  break;
387  }
388  case CVEX_TYPE_FLOAT:
389  {
390  GA_ROHandleF handle(attrib);
391  for (int i = 0; i < n; i++)
392  {
393  GA_Offset primoff = gdp->primitiveOffset(GA_Index(primid[i]));
394  ((float *)myBuffer[bufnum])[i] = handle.get(primoff);
395  }
396  break;
397  }
398  case CVEX_TYPE_VECTOR3:
399  {
400  GA_ROHandleV3 handle(attrib);
401  for (int i = 0; i < n; i++)
402  {
403  GA_Offset primoff = gdp->primitiveOffset(GA_Index(primid[i]));
404  ((UT_Vector3 *)myBuffer[bufnum])[i] = handle.get(primoff);
405  }
406  break;
407  }
408  case CVEX_TYPE_VECTOR4:
409  {
410  GA_ROHandleV4 handle(attrib);
411  for (int i = 0; i < n; i++)
412  {
413  GA_Offset primoff = gdp->primitiveOffset(GA_Index(primid[i]));
414  ((UT_Vector4 *)myBuffer[bufnum])[i] = handle.get(primoff);
415  }
416  break;
417  }
418  default:
419  {
420  UT_ASSERT(0);
421  break;
422  }
423  }
424  }
425  }
426 
427  void marshallDataToGdp(int bufnum, GU_Detail *gdp, int *primid, int n, int inc)
428  {
429  GA_Attribute *attrib = gdp->findPrimitiveAttribute(name());
430  if (attrib)
431  {
432  switch (myType)
433  {
434  case CVEX_TYPE_INTEGER:
435  {
436  GA_RWHandleI handle(attrib);
437  for (int i = 0, src = 0; i < n; i++, src += inc)
438  {
439  GA_Offset primoff = gdp->primitiveOffset(GA_Index(primid[i]));
440  handle.set(primoff, ((int *)myBuffer[bufnum])[src]);
441  }
442  break;
443  }
444  case CVEX_TYPE_FLOAT:
445  {
446  GA_RWHandleF handle(attrib);
447  for (int i = 0, src = 0; i < n; i++, src += inc)
448  {
449  GA_Offset primoff = gdp->primitiveOffset(GA_Index(primid[i]));
450  handle.set(primoff, ((float *)myBuffer[bufnum])[src]);
451  }
452  break;
453  }
454  case CVEX_TYPE_VECTOR3:
455  {
456  GA_RWHandleV3 handle(attrib);
457  for (int i = 0, src = 0; i < n; i++, src += inc)
458  {
459  GA_Offset primoff = gdp->primitiveOffset(GA_Index(primid[i]));
460  handle.set(primoff, ((UT_Vector3 *)myBuffer[bufnum])[src]);
461  }
462  break;
463  }
464  case CVEX_TYPE_VECTOR4:
465  {
466  GA_RWHandleV4 handle(attrib);
467  for (int i = 0, src = 0; i < n; i++, src += inc)
468  {
469  GA_Offset primoff = gdp->primitiveOffset(GA_Index(primid[i]));
470  handle.set(primoff, ((UT_Vector4 *)myBuffer[bufnum])[src]);
471  }
472  break;
473  }
474  default:
475  {
476  UT_ASSERT(0);
477  break;
478  }
479  }
480  // We've modified the attribute, so its data ID should be bumped.
481  attrib->bumpDataId();
482  }
483  }
484 
485  const char *name() const { return myName; };
486  CVEX_Type type() const { return myType; }
487  const char *buffer(int bufnum) const { return myBuffer[bufnum]; }
488  char *buffer(int bufnum) { return myBuffer[bufnum]; }
489 
490 private:
491  UT_String myName;
492  CVEX_Type myType;
493  char *myBuffer[NUM_BUFFERS];
494  int myBufLen[NUM_BUFFERS];
495 };
496 }
497 
498 void
500  CVEX_RunData &rundata,
501  int argc, char **argv,
502  int *primid, int n,
503  fpreal t)
504 {
505  // We always export our primitive ids, so bind as integer.
506  context.addInput("primid", CVEX_TYPE_INTEGER, primid, n);
507 
508  // These are lazy evaluated since we don't want to pay
509  // the cost if not needed.
510  context.addInput("P", // Name of parameter
511  CVEX_TYPE_VECTOR3, // VEX Type
512  true); // Is varying?
513 
514  // We lazy add our time dependent inputs as we only want to
515  // flag time dependent if they are used.
516  context.addInput("Time", CVEX_TYPE_FLOAT, false);
517  context.addInput("TimeInc", CVEX_TYPE_FLOAT, false);
518  context.addInput("Frame", CVEX_TYPE_FLOAT, false);
519 
520  // Lazily bind all of our primitive attributes.
521  UT_Array<sop_bindparms> bindlist;
523  !it.atEnd();
524  ++it)
525  {
527 
528  GA_Attribute *attrib = it.attrib();
529  if( attrib->getStorageClass() == GA_STORECLASS_FLOAT &&
530  attrib->getTupleSize() < 3 )
531  {
532  type = CVEX_TYPE_FLOAT;
533  }
534  else if( attrib->getStorageClass() == GA_STORECLASS_FLOAT &&
535  attrib->getTupleSize() < 4 )
536  {
537  type = CVEX_TYPE_VECTOR3;
538  }
539  else if( attrib->getStorageClass() == GA_STORECLASS_FLOAT )
540  {
541  type = CVEX_TYPE_VECTOR4;
542  }
543  else if( attrib->getStorageClass() == GA_STORECLASS_INT )
544  {
545  type = CVEX_TYPE_INTEGER;
546  }
547  else
548  {
549  type = CVEX_TYPE_INVALID;
550  }
551 
552  if (type == CVEX_TYPE_INVALID)
553  continue;
554 
555  context.addInput(attrib->getName(), type, true);
556 
557  bindlist.append( sop_bindparms(attrib->getName(),
558  type) );
559  }
560 
561  // We want to evaluate at the context time, not at what
562  // the global frame time happens to be.
563  rundata.setTime(t);
564 
565  // Load our array.
566  if (!context.load(argc, argv))
567  return;
568 
569  // Check for lazily bound inputs
571  CVEX_Value *var;
572  var = context.findInput("P", CVEX_TYPE_VECTOR3);
573  if (var)
574  {
575  P.setSize(n);
576  for (int i = 0; i < n; i++)
577  {
578  GA_Offset primoff = gdp->primitiveOffset(GA_Index(primid[i]));
579  P(i) = gdp->getGEOPrimitive(primoff)->baryCenter();
580  }
581  var->setTypedData(P.array(), n);
582  }
583 
584  // Check if any of our parameters exist as either inputs or outputs.
585  for (exint j = 0; j < bindlist.entries(); j++)
586  {
587  var = context.findInput(bindlist(j).name(), bindlist(j).type());
588  if (var)
589  {
590  // This exists as an input, we have to marshall it.
591  bindlist(j).marshallIntoBuffer(sop_bindparms::INPUT_BUFFER,
592  gdp, primid, n);
593  void *buf = (void *)bindlist(j).buffer(sop_bindparms::INPUT_BUFFER);
594  var->setRawData(bindlist(j).type(), VEX_32, buf, n);
595  }
596 
597  // The same attribute may be both an input and an output
598  // This results in different CVEX_Values so requires two
599  // buffers in the bindings.
600  if ((var = context.findOutput(bindlist(j).name(), bindlist(j).type())))
601  {
602  bindlist(j).allocateBuffer(sop_bindparms::OUTPUT_BUFFER, n);
603  void *buf = (void *)bindlist(j).buffer(sop_bindparms::OUTPUT_BUFFER);
604  if (var->isVarying())
605  var->setRawData(bindlist(j).type(), VEX_32, buf, n);
606  else
607  var->setRawData(bindlist(j).type(), VEX_32, buf, 1);
608  }
609 
610  }
611 
612  // Compute the time dependent inputs.
613  fpreal32 curtime, curtimeinc, curframe;
614 
615  var = context.findInput("Time", CVEX_TYPE_FLOAT);
616  if (var)
617  {
618  OP_Node::flags().timeDep = true;
619 
620  curtime = t;
621 
622  var->setTypedData(&curtime, 1);
623  }
624  var = context.findInput("TimeInc", CVEX_TYPE_FLOAT);
625  if (var)
626  {
627  OP_Node::flags().timeDep = true;
628 
629  curtimeinc = 1.0f/OPgetDirector()->getChannelManager()->getSamplesPerSec();
630 
631  var->setTypedData(&curtimeinc, 1);
632  }
633  var = context.findInput("Frame", CVEX_TYPE_FLOAT);
634  if (var)
635  {
636  OP_Node::flags().timeDep = true;
637 
638  curframe = OPgetDirector()->getChannelManager()->getSample(t);
639 
640  var->setTypedData(&curframe, 1);
641  }
642 
643  // clear flag to detect time dependence of ch expressions.
644  rundata.setTimeDependent(false);
645 
646  // Actually execute the vex code!
647  // Allow interrupts.
648  context.run(n, true, &rundata);
649 
650  // Update our timedependency based on the flag
651  if (rundata.isTimeDependent())
652  OP_Node::flags().timeDep = 1;
653 
654  // Write out all bound parameters.
655  for (exint j = 0; j < bindlist.entries(); j++)
656  {
657  var = context.findOutput(bindlist(j).name(), bindlist(j).type());
658  if (var)
659  {
660  bindlist(j).marshallDataToGdp(sop_bindparms::OUTPUT_BUFFER, gdp, primid, n, (var->isVarying() ? 1 : 0));
661  }
662  }
663 }
664 
665 void
667 {
668  UT_String shoppath;
669  int vexsrc = VEXSRC(t);
670 
671  script = "";
672 
673  switch (vexsrc)
674  {
675  case 0:
676  {
677  getFullPath(shoppath);
678  script = "op:";
679  script += shoppath;
680  // buildVexCommand appends to our script variable.
682  break;
683  }
684 
685  case 2:
686  // Straightforward, use the explicit script
687  SCRIPT(script, t);
688  break;
689 
690  case 1:
691  {
692  SHOPPATH(shoppath, t);
693 
694  // Use the referenced shop network.
695  SHOP_Node *shop;
696  shop = findSHOPNode(shoppath);
697  if (shop)
698  {
699  shop->buildVexCommand(script, shop->getSpareParmTemplates(), t);
701 
702  // It is possible that we are dealing with a multi-context
703  // shader (ie, shop). In that case, we need to specify the
704  // shader context which we want to interpret it as. This is done
705  // by passing it as an argument. Since this operator invokes
706  // CVEX shader, we specify that type. Single-context shaders
707  // will ignore it.
708  shop->buildShaderString(script, t, 0, 0, 0, SHOP_CVEX);
709  }
710  break;
711  }
712  }
713 }
714 
715 bool
717 {
718  if (myCodeGenerator.getVariableString(index, value))
719  return true;
720  // else delegate to base class
721  return SOP_Node::evalVariableValue(value, index, thread);
722 }
723 
726 {
728 }
729 
732 {
733  return &myCodeGenerator;
734 }
735 
736 bool
738 {
739  return myCodeGenerator.hasShaderParameter(parm_name);
740 }
741 
742 const char *
744 {
745  return VOP_OPTYPE_NAME;
746 }
747 
750 {
751  return VOP_OPTYPE_ID;
752 }
753 
754 void
756 {
757  int update_id = myCodeGenerator.beginUpdate();
758  SOP_Node::opChanged(reason, data);
759  myCodeGenerator.ownerChanged(reason, data);
760  myCodeGenerator.endUpdate(update_id);
761 }
762 
763 void
765 {
767  SOP_Node::finishedLoadingNetwork(is_child_call);
768 }
769 
770 void
771 SOP_PrimVOP::addNode(OP_Node *node, int notify, int explicitly)
772 {
774  SOP_Node::addNode(node, notify, explicitly);
776 }
777 
778 void
780  OP_NodeInfoParms &iparms)
781 {
782  SOP_Node::getNodeSpecificInfoText(context, iparms);
783 
784 #if 0
785  // Compile errors should be already automatically reported in the
786  // node specific info. Still, here is an example of how that can be done
787  // explicitly.
788  UT_String errors;
789  if( myCodeGenerator.getCompilerErrors( errors ))
790  {
791  iparms.appendSeparator();
792  iparms.append(errors);
793  }
794 #endif
795 }
796 
void endUpdate(int update_level)
virtual void getNodeSpecificInfoText(OP_Context &context, OP_NodeInfoParms &parms)
Definition: SOP_PrimVOP.C:779
static PRM_Name theVopCompilerName
SYS_FORCE_INLINE void bumpDataId()
Definition: GA_Attribute.h:274
static PRM_SpareData shopCVEX
bool isTimeDependent() const
Definition: CVEX_Context.h:81
Definition of a geometry attribute.
Definition: GA_Attribute.h:190
void afterAddNode(OP_Node *node)
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:771
void setTime(fpreal time)
Definition: CVEX_Context.h:47
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:1339
DEP_ContextOptionsReadHandle getContextOptions() const
Definition: OP_Context.h:127
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:60
void beforeAddNode(OP_Node *node)
void setOpCaller(UT_OpCaller *caller)
Definition: CVEX_Context.h:71
const UT_String & getVexWarnings() const
virtual OP_OperatorFilter * getOperatorFilter()
Overriding these are what allow us to contain VOPs.
Definition: SOP_PrimVOP.C:725
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:731
virtual void finishedLoadingNetwork(bool is_child_call=false)
UT_ErrorSeverity
Definition: UT_Error.h:25
T * array()
Definition: UT_Array.h:614
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:251
bool getVariableString(int index, UT_String &value)
void addError(int code, const char *msg=0)
Definition: SOP_Node.h:1133
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:469
OP_Channels * getChannels(void) const
static bool forceCompile(OP_Node *node)
const char * buffer(int bufnum) const
Definition: SOP_PrimVOP.C:487
Call VEX from C++.
Definition: CVEX_Context.h:151
CH_Manager * getChannelManager()
Definition: OP_Director.h:97
SYS_FORCE_INLINE GEO_Primitive * getGEOPrimitive(GA_Offset primoff)
Definition: GEO_Detail.h:1119
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:486
CH_Manager * CHgetManager()
Definition: CH_Manager.h:1705
const CVEX_Value * findOutput(const UT_StringRef &name, CVEX_Type type) const
Find an output by name/type.
Definition: CVEX_Context.h:307
fpreal getSample(fpreal t) const
Definition: CH_Manager.h:1011
bool isVarying() const
Query whether the VEX value is uniform or varying.
Definition: CVEX_Value.h:68
void SCRIPT(UT_String &s, fpreal t)
Definition: SOP_PrimVOP.h:87
void allocateBuffer(int bufnum, int n)
Definition: SOP_PrimVOP.C:345
void addWarning(SOP_ErrorCodes code, const char *msg=0)
Definition: SOP_Node.h:1139
void setGeoCommandQueue(VEX_GeoCommandQueue< PREC > *geocmd)
Sets the command queue for this context.
Definition: CVEX_Context.h:101
int64 exint
Definition: SYS_Types.h:116
fpreal getSamplesPerSec() const
Definition: CH_Manager.h:979
GA_StorageClass getStorageClass() const
Returns the approximate type of the attribute.
const DEP_ContextOptionsStack * getContextOptionsStack() const
Return the options associated with the calling context.
Definition: OP_Caller.h:42
void SHOPPATH(UT_String &path, fpreal t)
Definition: SOP_PrimVOP.h:90
virtual const char * getChildType() const
Definition: SOP_PrimVOP.C:743
char * buffer(int bufnum)
Definition: SOP_PrimVOP.C:488
sop_bindparms(const sop_bindparms &src)
Definition: SOP_PrimVOP.C:301
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)
bool setTypedData(int32 *data, int array_size)
SOP_NodeFlags mySopFlags
Definition: SOP_Node.h:1598
constexpr VEX_Precision VEX_32
Definition: VEX_PodTypes.h:30
#define GA_FOR_ALL_PRIMITIVES(gdp, prim)
Definition: GA_GBMacros.h:36
OP_OpTypeId
Definition: OP_OpTypeId.h:15
SYS_FORCE_INLINE T get(GA_Offset off, int comp=0) const
Definition: GA_Handle.h:191
UT_StringHolder getFullPath() const
Definition: PRM_ParmOwner.h:60
bool load(int argc, const char *const argv[])
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:25
PRM_API const PRM_Type PRM_COMMAND
void executeVex(int argc, char **argv, fpreal t, OP_Caller &opcaller)
Definition: SOP_PrimVOP.C:190
void setManagesDataIDs(bool onOff)
Definition: SOP_NodeFlags.h:34
virtual OP_OpTypeId getChildTypeID() const
Definition: SOP_PrimVOP.C:749
A class representing a VEX value.
Definition: CVEX_Value.h:52
virtual void opChanged(OP_EventType reason, void *data=0)
We need special alerts now that we contain VOPs.
Definition: SOP_PrimVOP.C:755
Per-run data for CVEX execution.
Definition: CVEX_Context.h:35
int buildVexCommand(UT_String &result, const PRM_Template *templatelist, fpreal now, int start_parm=0, int end_parm=INT_MAX, bool use_parmvop_tag=true)
GU_Detail * gdp
Definition: SOP_Node.h:1595
SYS_FORCE_INLINE const GA_Attribute * findPrimitiveAttribute(GA_AttributeScope s, const UT_StringRef &name) const
Definition: GA_Detail.h:984
sop_bindparms & operator=(const sop_bindparms &src)
Definition: SOP_PrimVOP.C:317
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2539
exint entries() const
Alias of size(). size() is preferred.
Definition: UT_Array.h:453
virtual bool evalVariableValue(UT_String &value, int index, int thread)
Code generation variables.
Definition: SOP_PrimVOP.C:716
bool addInput(const UT_StringHolder &name, CVEX_Type type, VEX_Precision, bool varying)
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:448
bool run(int array_size, bool interruptable, CVEX_RunData *rundata=nullptr)
void setTimeDependent(bool v)
Definition: CVEX_Context.h:131
GLsizei const GLfloat * value
Definition: glcorearb.h:823
double fpreal
Definition: SYS_Types.h:270
SYS_FORCE_INLINE GA_Index getMapIndex() const
Gets the index of this primitive in the detail containing it.
Definition: GA_Primitive.h:143
#define VOP_TABLE_NAME
Definition: OP_Node.h:208
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:1588
const char * name() const
Definition: SOP_PrimVOP.C:485
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:1597
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:285
SYS_FORCE_INLINE void set(GA_Offset off, const T &val) const
Definition: GA_Handle.h:320
void marshallDataToGdp(int bufnum, GU_Detail *gdp, int *primid, int n, int inc)
Definition: SOP_PrimVOP.C:427
#define VOP_OPTYPE_NAME
Definition: OP_Node.h:254
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:363
SYS_FORCE_INLINE const GA_AttributeDict & primitiveAttribs() const
Definition: GEO_Detail.h:1855
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:295
SYS_FORCE_INLINE GA_Size getNumPrimitives() const
Return the number of primitives.
Definition: GA_Detail.h:352
bool setRawData(CVEX_Type type, VEX_Precision, void *data, int array_size)
Type unsafe way of setting VEX data. Avoid using if possible.
const DEP_ContextOptionsStack * getContextOptionsStack() const
Definition: OP_Context.h:125
OP_EventType
Definition: OP_Value.h:22
exint append(void)
Definition: UT_Array.h:95
DEP_ContextOptionsReadHandle getContextOptions() const
Return the options associated with the calling context.
Definition: OP_Caller.h:46
SHOP_Node * findSHOPNode(const char *path) const
Definition: OP_Node.h:555
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
static const int INPUT_BUFFER
Definition: SOP_PrimVOP.C:288
virtual void finishedLoadingNetwork(bool is_child_call=false)
VOP and VEX functions.
Definition: SOP_PrimVOP.C:764
bool isstring() const
Definition: UT_String.h:689
void append(const char *string)
Append a string to the text buffer.
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:126
void marshallIntoBuffer(int bufnum, GU_Detail *gdp, int *primid, int n)
Definition: SOP_PrimVOP.C:369
void ownerFinishedLoadingNetwork()
void setProcId(exint *procid)
Definition: CVEX_Context.h:93
void processVexBlock(CVEX_Context &context, CVEX_RunData &rundata, int argc, char **argv, int *primid, int n, fpreal t)
Definition: SOP_PrimVOP.C:499
static PRM_Default theVopCompilerVexDefault
float fpreal32
Definition: SYS_Types.h:191
VOP_CodeGenerator myCodeGenerator
Definition: SOP_PrimVOP.h:123
virtual bool hasVexShaderParameter(const char *parm_name)
Definition: SOP_PrimVOP.C:737
int VEXSRC(fpreal t)
Definition: SOP_PrimVOP.h:85
static const int NUM_BUFFERS
Definition: SOP_PrimVOP.C:287
int parse(char *argv[], int maxArgs, const char *quotes="\"'", bool keep_quotes=false)
Definition: UT_String.h:790
static const int OUTPUT_BUFFER
Definition: SOP_PrimVOP.C:289
void buildScript(UT_String &script, fpreal t)
Definition: SOP_PrimVOP.C:666
void appendQueue(VEX_GeoCommandQueue< PREC > &geocmd)
SYS_FORCE_INLINE GA_Size getNumPoints() const
Return the number of points.
Definition: GA_Detail.h:285
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