HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DOP_Node.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: DOP_Node.h ( DOP Library, C++)
7  *
8  * COMMENTS: Dynamics OPs. These are nodes which are used for setting
9  * up and controlling dynamic simulations.
10  */
11 
12 #ifndef __DOP_Node__
13 #define __DOP_Node__
14 
15 #include "DOP_API.h"
16 #include "DOP_Error.h"
17 #include <OP/OP_Network.h>
18 #include <OP/OP_OperatorPair.h>
19 #include <OP/OP_PreDefRules.h>
20 #include <SIM/SIM_Utils.h>
21 
22 
23 class OP_Operator;
24 class OP_OperatorTable;
25 class SIM_Data;
26 class SIM_Object;
27 class SIM_ObjectArray;
28 class SIM_RootData;
29 class SIM_Options;
30 class SIM_Relationship;
31 class DOP_InOutInfo;
32 class DOP_Output;
33 class DOP_Engine;
34 
35 /// This declaration allows HDK users to write custom DOP operators.
36 extern "C" {
38 };
39 
40 /// This enumeration contains all the standard DOP local variables.
41 /// Any DOPs which create their own variables must start their variable
42 /// indices at NUM_DOP_VARS. They must also call the
43 /// DOP_Node::evalVariableValue() in their own override of this function.
44 enum {
74 };
75 
76 /// This is the base class for all DOP nodes.
77 class DOP_API DOP_Node : public OP_Network
78 {
79 public:
80  /// Constructor to allocate a new DOP_Node.
81  DOP_Node(OP_Network *dad, const char *name,
82  OP_Operator *entry);
83  /// Destructor.
84  ~DOP_Node() override;
85 
86  /// The standard DOP local variables. These get added to all DOP nodes
87  /// automatically by the DOP_Operator constructor.
89  static CH_LocalVariable theVariables[];
90 
91  /// This function builds a menu of all the rules in the
92  /// DOPActivationRules file.
93  static void buildActivationRules(void *data,
94  PRM_Name* menu,
95  int maxSize,
96  const PRM_SpareData*,
97  const PRM_Parm *);
98  /// This function responds to a selection of the adtivation rule menu
99  /// by setting the activation parameter.
100  static int setActivationCallback(void *data,
101  int index,
102  fpreal t,
103  const PRM_Template *);
104 
105  /// This function applies SIM_Data from one of our inputs to some
106  /// parent data. This is done by calling applyOutputData() for the
107  /// DOP_Node that is connected to the specfiied input index.
108  void applyDataFromInput(fpreal time, int inputidx,
109  int inputidxforsuffix,
110  SIM_RootData &rootdata,
111  const char *parentdataname,
112  DOP_Engine &engine,
113  UT_StringArray *datanames,
114  bool changeuniquenamesuffix);
115 
116  /// Returns information about which DOP_Node outputs are required
117  /// to process this node. This function calls getRequiredOutputsSubclass()
118  /// to do the real work.
119  void getRequiredOutputs(fpreal time, int foroutputidx,
120  UT_Array<DOP_Output> &outputs,
121  const DOP_Engine &engine);
122  /// Divides incoming objects among the various outputs from this node.
123  /// This function calls partitionObjectSubclass() to do the real work.
124  void partitionObjects(fpreal time,
125  const SIM_ObjectArray &objects,
127  const DOP_Engine &engine);
128  /// Processes incoming objects by adding, removing, or modifying data.
129  /// This function calls processObjectSubclass() to do the real work.
130  void processObjects(fpreal time, int foroutputidx,
131  const SIM_ObjectArray &objects,
132  DOP_Engine &engine);
133  /// Adds the data corresponding to the specified output to the object.
134  /// This function calls applyOutputDataSubclass() to do real
135  /// work.
136  void applyOutputData(fpreal time, int outputidx,
137  SIM_RootData &rootdata,
138  const char *parentdataname,
139  DOP_Engine &engine,
140  UT_StringArray *datanames);
141  /// Gets information about the specified input.
142  /// This function calls getInputInfoSubclass() to do the real work.
143  void getInputInfo(int inputidx, DOP_InOutInfo &info) const;
144  /// Gets information about the specified output.
145  /// This function calls getOutputInfoSubclass() to do the real work.
146  void getOutputInfo(int outputidx, DOP_InOutInfo &info) const;
147 
148  /// Adds an error from the DOP error file.
149  void addError(int code, const char *msg = 0)
150  { UTaddError("DOP", code, msg);}
151  /// Adds a message from the DOP error file.
152  void addMessage(DOP_ErrorCode code, const char *msg = 0)
153  { UTaddMessage("DOP", code, msg);}
154  /// Adds a warning from the DOP error file.
155  void addWarning(DOP_ErrorCode code, const char *msg = 0)
156  { UTaddWarning("DOP", code, msg);}
157  /// Adds a fatal error from the DOP error file.
158  void addFatal(DOP_ErrorCode code, const char *msg = 0)
159  { UTaddFatal("DOP", code, msg);}
160 
161  static const char *theChildTableName;
162  /// Returns "DOP" because our child nodes will be DOP_Nodes.
163  const char *getChildType() const override;
164  /// Returns "DOP" because we are a DOP_Node.
165  const char *getOpType() const override;
166 
167  /// Returns DOP_OPTYPE_ID because our child nodes will be DOP_Nodes.
168  OP_OpTypeId getChildTypeID() const override;
169  /// Returns DOP_OPTYPE_ID because we are a DOP_Node.
170  OP_OpTypeId getOpTypeID() const override;
171 
172  /// Override this method to always return null.
173  /// DOP_Nodes are only interested in the display node, not the render
174  /// node.
175  OP_Node *getRenderNodePtr() override;
176 
177  /// REturn text describing a particular input.
178  const char *inputLabel(unsigned idx) const override;
179 
180  /// Override the opChanged method. Whenever a DOP node parameter changes,
181  /// we need to notify the simulation engine that it needs to recook the
182  /// last timestep to reflect the changed DOP values.
183  void opChanged(OP_EventType reason, void *data=0) override;
184 
185  /// Handle changes to a parameter that is referenced by one of our
186  /// parameters. DOP Nodes want to treat this the same as a parm change.
187  void referencedParmChanged(int pi) override;
188 
189  /// Handle the evaluation of standard local variables.
190  bool evalVariableValue(fpreal &v, int index,
191  int thread) override;
192  /// Handle the evaluation of standards string local variables.
193  bool evalVariableValue(UT_String &v, int index,
194  int thread) override;
195 
196  /// Adds DOP_Operators to teh DOP operator table.
197  static void buildOperatorTable(OP_OperatorTable &table);
198  /// Adds the DOP specific expression functions.
199  static void initializeExpressions();
200  /// Adss Dop specific hscript commands.
201  static void installCommands();
202 
203  /// Return the absolute width of the tile for this node.
204  fpreal getW() const override;
205  /// Return the absolute height of the tile for this node.
206  fpreal getH() const override;
207 
208  /// The display and render ops of a DOP Network are always equal.
209  int getDandROpsEqual() override;
210  int updateDandROpsEqual(int check_inputs = 1) override;
211 
212  // Override clearInterrupted so that we don't invalidate the whole cache
213  // when the user interrupts a cook.
214  void clearInterrupted() override;
215 
216  /// Get the MMB info text for this node.
217  void getNodeSpecificInfoText(OP_Context &context,
218  OP_NodeInfoParms &iparms) override;
219  /// Get the info tree specific to this node.
221  const OP_NodeInfoTreeParms &parms) override;
222 
223  /// Return the DOP_Parent pointer associated with this node.
224  /// To cast a DOP_Node to a DOP_Parent, just cast our creator node.
225  DOP_Parent *castToDOPParent() override;
226  /// Return the const DOP_Parent pointer associated with this node.
227  /// To cast a DOP_Node to a DOP_Parent, just cast our creator node.
228  const DOP_Parent *castToDOPParent() const override;
229 
230  /// Return the number of ordered inputs by looking at our DOP_InOutInfo.
231  unsigned orderedInputs() const override;
232 
233  /// Override the setInput functions so that we can send notification to
234  /// the nodes that are our inputs when we disconnect from them. This lets
235  /// then adjust their tile UI if necessary.
236  OP_ERROR setInput(unsigned idx, OP_Node *op,
237  unsigned outputIdx = 0) override;
238  OP_ERROR setInputReference(unsigned idx, const char *label,
239  int keeppos, unsigned outputIdx = 0) override;
240 
241  OP_ERROR setNamedInput(const OP_ConnectorId& input_name,
242  OP_Node *op,
243  const OP_ConnectorId* output_name = NULL
244  ) override;
245 
247  const OP_ConnectorId& input_name,
248  const char *label, int,
249  const OP_ConnectorId* output_name = NULL
250  ) override;
251 
252  bool hasDifferentMultiInputs() const override;
253 
254  /// This functions sets the evaluation object index and the current
255  /// object pointer that is used for local variable evaluation.
256  /// It clears the current relationship information.
257  void setCurrentObject(int objectindex,
258  int objectcount,
259  const SIM_Object *object);
260  /// This functions sets the evaluation relationship index and the current
261  /// relationship pointer that is used for local variable evaluation.
262  /// It clears the current object information.
263  void setCurrentRel(const SIM_Relationship *rel);
264  /// This function copies the current object information from this
265  /// node into another destination node.
266  void copyCurrentObjectAndRelInto(DOP_Node *dest) const;
267  /// Clears the current object and relationship information.
268  void clearCurrentObjectAndRel();
269 
270 protected:
271  /// Cooking a DOP_Node just performs some basic error checks.
272  OP_ERROR cookMe(OP_Context &) override;
273  /// Bypassing a DOP_Node does nothing.
274  OP_ERROR bypassMe(OP_Context &, int &) override;
275  /// Returns the file extension to use for opsave commands on a DOP_Node.
276  const char *getFileExtension(int binary) const override;
277  /// Handle changes to our child node display and render flags.
278  void childFlagChange(OP_Node *) override;
279  /// Checks that the input types match the output types connected to them.
280  OP_ERROR checkInputValidity();
281 
282  /// A DOP_Node has no data, so do nothing.
283  OP_DataType getCookedDataType() const override;
284  /// A DOP_Node has no data, so do nothing.
285  void deleteCookedData() override;
286  /// A DOP_Node has no data, so do nothing.
287  int saveCookedData(const char *, OP_Context &) override;
288  /// A DOP_Node has no data, so do nothing.
289  int saveCookedData(std::ostream &, OP_Context &,
290  int) override;
291 
292  /// DOP Nodes always return their parent's transform, making it
293  /// easy to do stuff like optransform() from within a dopnetwork.
294  bool getWorldTransform(UT_DMatrix4 &xform,
295  OP_Context &context) override;
296  bool getIWorldTransform(UT_DMatrix4 &xform,
297  OP_Context &context) override;
299  OP_Context &context) override;
300 
301  /// Returns whether the DOP should do any processing. This function
302  /// checks the bypass flag and the "activation" parameter if there is
303  /// one. This function should only be called from
304  /// getRequiredOutputsSubclass(), partitionObjectsSubclass(),
305  /// processObjectsSubclass(), and applyOutputDataSubclass().
306  bool isActive(fpreal time);
307 
308  /// This default implementation indicates that all inputs are required.
309  virtual void getRequiredOutputsSubclass(fpreal time,
310  int foroutputidx,
311  UT_Array<DOP_Output> &outputs,
312  const DOP_Engine &engine);
313  /// This default implementation sends all objects to the first output.
314  virtual void partitionObjectsSubclass(fpreal time,
315  const SIM_ObjectArray &objects,
317  const DOP_Engine &engine);
318  /// This default implementation does not affect incoming objects.
319  virtual void processObjectsSubclass(fpreal time,
320  int foroutputidx,
321  const SIM_ObjectArray &objects,
322  DOP_Engine &engine);
323  /// This default implementation does nothing because DOP_Node doesn't
324  /// have any data outputs.
325  virtual void applyOutputDataSubclass(fpreal time, int outputidx,
326  SIM_RootData &rootdata,
327  const char *parentdataname,
328  DOP_Engine &engine,
329  UT_StringArray *datanames);
330  /// This default implementation specifies the input accepts objects.
331  virtual void getInputInfoSubclass(int inputidx,
332  DOP_InOutInfo &info) const;
333  /// This default implementation specifies the output sends out objects.
334  virtual void getOutputInfoSubclass(int outputidx,
335  DOP_InOutInfo &info) const;
336 
337  /// Prefixes the supplied data name with the root name. This utility
338  /// function is often used to concatenate data paths.
339  void makeFullDataName(const char *root,
340  UT_String &name) const;
341  /// Prefixes & suffixes the data name to form a aunique name.
342  void makeUniqueDataName(UT_String &dataname,
343  const char *parentdataname,
344  bool uniquename,
345  bool usenodepath) const;
346  /// Appends the name and index number of the node that is applying data.
347  /// This is used to generate a unique data name.
348  void appendUniqueDataNameSuffix(UT_WorkBuffer &dataname,
349  bool usenodepath) const;
350 
351  /// Steals the global errors, applies them to this node to set
352  /// the local error severity, and then passes it on to the DOP_Engine
353  /// that will be able to re-apply these errors in future cook()
354  /// calls.
355  void moveGlobalErrorsToEngine();
356 
357  /// Called in cookMe() to clear any cached data that is no longer valid
358  /// (e.g. due to a reset / resim, or just from advancing the timestep).
359  virtual void ensureCachedDataIsValid(const DOP_Engine &engine);
360 
361  /// The value of SIM_Engine::getModVersion() from the last cook. This can
362  /// be used to determine if cached data should be cleared out due to a
363  /// reset or resimulating a frame.
364  /// The version is updated after DOP_Node::updateCachedData(), which should
365  /// be called during cookMe().
366  int64 getLastSimVersion() const { return myLastSimVersion; }
367 
368 private:
369  class DOP_CookData
370  {
371  public:
372  UT_WorkBuffer myUniqueNamePrefix;
373  };
374 
375  DOP_CookData &getCookData() const;
376  void handleNodeChange(OP_EventType reason, void *data);
377 
378  const SIM_ObjectArray *myCurrentObjects;
379  int myCurrentObjectIndex;
380  int myCurrentObjectCount;
381  const SIM_Object *myCurrentObject;
382  const SIM_Relationship *myCurrentRel;
383  bool myIsBusy;
384  mutable UT_StringHolder myUnderscorePathCache;
385  int64 myLastSimVersion;
386  SIM_Time myLastCookTime;
387  static UT_String theApplyingDataToInput;
388 
389  friend class DOP_Parent;
390 };
391 
392 #endif
virtual int saveCookedData(std::ostream &os, OP_Context &, int binary=0)=0
int64 getLastSimVersion() const
Definition: DOP_Node.h:366
fpreal getH() const override
Node position/scale is used by the UI.
GLuint GLsizei const GLchar * label
Definition: glcorearb.h:2545
fpreal getW() const override
Node position/scale is used by the UI.
virtual bool getWorldTransform(UT_Matrix4D &xform, OP_Context &)
#define SYS_VISIBILITY_EXPORT
GT_API const UT_StringHolder time
const GLdouble * v
Definition: glcorearb.h:837
virtual bool getTransform(TransformMode mode, UT_Matrix4D &xform, OP_Context &)
UT_API UT_ErrorSeverity UTaddFatal(const char *type, int code, const char *msg=0, const UT_SourceLocation *loc=0)
const GLuint GLenum const void * binary
Definition: glcorearb.h:1924
virtual const char * inputLabel(unsigned idx) const
UT_ErrorSeverity
Definition: UT_Error.h:25
Parameters for OP_Node::getInfoText()/OP_Node::getNodeSpecificInfoText()
virtual DOP_Parent * castToDOPParent()
Definition: OP_Node.h:2685
int getDandROpsEqual() override
virtual void getNodeSpecificInfoText(OP_Context &context, OP_NodeInfoParms &parms)
UT_API UT_ErrorSeverity UTaddMessage(const char *type, int code, const char *msg=0, const UT_SourceLocation *loc=0)
virtual OP_ERROR cookMe(OP_Context &context)=0
virtual void childFlagChange(OP_Node *)
void addWarning(DOP_ErrorCode code, const char *msg=0)
Adds a warning from the DOP error file.
Definition: DOP_Node.h:155
virtual void clearInterrupted()
Definition: OP_Node.h:2477
#define DOP_API
Definition: DOP_API.h:10
virtual OP_ERROR setInput(unsigned idx, OP_Node *op, unsigned outputIdx=0)
Sets a given input to connect to an output of a particular node.
Holds pointers to a number of SIM_Object objects.
virtual bool hasDifferentMultiInputs() const
virtual OP_ERROR setNamedInput(const OP_ConnectorId &input_name, OP_Node *op, const OP_ConnectorId *output_name=nullptr)
New input functions that use names instead of indices.
void opChanged(OP_EventType reason, void *data=0) override
virtual bool getIWorldTransform(UT_Matrix4D &xform, OP_Context &)
virtual unsigned orderedInputs() const
long long int64
Definition: SYS_Types.h:116
int updateDandROpsEqual(int check_inputs=1) override
OP_OpTypeId
Definition: OP_OpTypeId.h:18
virtual OP_Node * getRenderNodePtr()
GLuint const GLchar * name
Definition: glcorearb.h:786
virtual OP_DataType getCookedDataType() const =0
GLenum GLenum GLsizei void * table
Definition: glad.h:5129
virtual OP_OpTypeId getOpTypeID() const
Definition: OP_Node.h:525
GLdouble t
Definition: glad.h:2397
GLenum mode
Definition: glcorearb.h:99
static const char * theChildTableName
Definition: DOP_Node.h:161
virtual OP_ERROR setNamedInputReference(const OP_ConnectorId &input_name, const char *label, int, const OP_ConnectorId *output_name=nullptr)
virtual const char * getChildType() const
**Note that the tasks the is the thread number *for the or if it s being executed by a non pool thread(this *can happen in cases where the whole pool is occupied and the calling *thread contributes to running the work load).**Thread pool.Have fun
virtual const char * getFileExtension(int binary) const =0
Parameters for OP_Node::fillInfoTree()/OP_Node::fillInfoTreeNodeSpecific()
virtual void fillInfoTreeNodeSpecific(UT_InfoTree &tree, const OP_NodeInfoTreeParms &parms)
void addFatal(DOP_ErrorCode code, const char *msg=0)
Adds a fatal error from the DOP error file.
Definition: DOP_Node.h:158
fpreal64 fpreal
Definition: SYS_Types.h:277
DOP_ErrorCode
Definition: DOP_Error.h:13
GLuint index
Definition: glcorearb.h:786
virtual void referencedParmChanged(int pi)
virtual const char * getOpType() const
UT_API UT_ErrorSeverity UTaddWarning(const char *type, int code, const char *msg=0, const UT_SourceLocation *loc=0)
TransformMode
Definition: OP_Node.h:1117
OP_EventType
Definition: OP_Value.h:22
OP_DataType
Definition: OP_DataTypes.h:28
virtual OP_OpTypeId getChildTypeID() const =0
virtual bool evalVariableValue(UT_String &val, int index, int thread)
constexpr T pi()
Pi constant taken from Boost to match old behaviour.
Definition: Math.h:119
void addMessage(DOP_ErrorCode code, const char *msg=0)
Adds a message from the DOP error file.
Definition: DOP_Node.h:152
This is the base class for all DOP nodes.
Definition: DOP_Node.h:77
void addError(int code, const char *msg=0)
Adds an error from the DOP error file.
Definition: DOP_Node.h:149
SYS_VISIBILITY_EXPORT void newDopOperator(OP_OperatorTable *table)
This declaration allows HDK users to write custom DOP operators.
virtual OP_ERROR bypassMe(OP_Context &context, int &copied_input)=0
Definition: format.h:895
UT_API UT_ErrorSeverity UTaddError(const char *type, int code, const char *msg=0, const UT_SourceLocation *loc=0)
virtual void deleteCookedData()=0
static OP_VariablePair theVariablePair
Definition: DOP_Node.h:88
virtual OP_ERROR setInputReference(unsigned idx, const char *label, int keeppos, unsigned outputIdx=0)
Connects an input to particular node by name in the network.