HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
COP_ApexProgram.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  */
7 
8 #pragma once
9 
10 #include "COP_API.h"
11 
12 #include "COP_Signature.h"
13 
14 #include <DEP/DEP_TimedMicroNode.h>
15 #include <IMX/IMX_Layer.h>
16 #include <IMX/IMX_VDB.h>
17 #include <UT/UT_StringMap.h>
18 
19 class COP_ApexNodeDependencies;
20 class COP_Block;
21 class COP_CableStructure;
22 class COP_GraphProxyDirect;
23 class COP_Node;
24 class COP_Request;
26 class GU_Detail;
27 class GU_DetailHandle;
28 class OP_Context;
29 class UT_ErrorManager;
30 class UT_StringRef;
31 
32 namespace apex
33 {
34  class APEX_Graph;
35 };
36 
37 /// This micronode can invoke a callback when it becomes dirty. It's used by
38 /// COP_ApexProgram's callback registration, to make sure a function runs when
39 /// the program's results are changed.
41 {
42 public:
44  DEP_TimedMicroNode(), myCallback(nullptr), myEnabled(false)
45  {
46  }
47 
48  /// Controls whether or not the callback runs when the micronode is dirtied.
49  void enableCallback(bool enable)
50  {
51  myEnabled = enable;
52  }
53 
54  /// Returns true if the callback is enabled (even if not set).
55  bool callbackEnabled() const
56  {
57  return myEnabled;
58  }
59 
60  /// Set the callback to run when the micronode is dirtied. The callback will
61  /// only be invoked if enableCallback(true) was previously called. The data
62  /// pointer is passed to the callback function when it's executed.
63  void setCallback(void (*callback)(void*), void* data)
64  {
65  myCallback = callback;
66  myData = data;
67  }
68 
69  void becameDirty(DEP_MicroNode& src, const DEP_PropagateData& propdata)
70  override;
71 
72 private:
73  void (*myCallback)(void*);
74  void* myData;
75  bool myEnabled;
76 };
77 
78 /// This class creates an executable program out of a COP block. All parameters
79 /// are evaluated and hardened in the graph.
81 {
82 public:
84  {
85  FAIL = 0,
86  REBUILD_NOT_NEEDED,
87  SUCCESS
88  };
89 
90  /// This tag can be used with setOutputBlock() and buildFromBlock() methods
91  /// to indicate what the block begin's input states are (i.e. which ports
92  /// are actually connected).
93  enum class BeginBindingsMode
94  {
95  /// Will assume all inputs are connected non-null data.
96  ALL_INPUTS_BOUND,
97  /// Will use the network's connections.
98  NETWORK_STATE
99  };
100 
101 public:
102  /// If harden_parms is true, the parameters will be evaluated and baked into
103  /// the built graphs.
104  COP_ApexProgram(bool harden_parms = true);
105  ~COP_ApexProgram();
106 
107  /// Set the block end node for this program, without trying to rebuild.
108  /// Returns false if output is a block begin node, in which case the output
109  /// node (and the program as a whole) is unchanged. If sigs and input_cables
110  /// are provided, they will be used as the authoritative state of inputs to
111  /// the block (on the begin side); if one is given, the other must be as
112  /// well. If these arguments are nullptr, then the built program will
113  /// reflect state of the network.
114  bool setOutputBlock(COP_Block* output,
115  const UT_Array<COP_Signature>* sigs,
116  const UT_Array<COP_CableStructure>* input_cables);
117  /// This version of the method assumes that all inputs to the block are
118  /// properly bound non-null data when the program gets built.
119  bool setOutputBlock(COP_Block* output, BeginBindingsMode mode);
120  /// Builds an executable out of the block end node, containing everything up
121  /// to its begin node.
122  bool buildFromBlock(COP_Block* output, const UT_Array<COP_Signature>* sigs,
123  const UT_Array<COP_CableStructure>* cables,
124  const OP_Context& context, UT_ErrorManager& error);
125  /// This version of the method assumes that all inputs to the block are
126  /// properly bound non-null data when the program gets built.
127  bool buildFromBlock(COP_Block* output, BeginBindingsMode mode,
128  const OP_Context& context, UT_ErrorManager& error);
129 
130  /// Builds a program that cooks the specified outputs of a single node. The
131  /// node can be a subnetwork or an atomic node.
132  bool buildFromSingleNode(COP_Node* output,
133  const UT_Array<COP_Request>& requests,
134  const COP_Signature& signature,
135  const OP_Context& context, UT_ErrorManager& error);
136 
137  /// Returns the cable structure of an output of the block this is built
138  /// from.
139  COP_CableStructure getBlockOutputCableStructure(OP_OutputIdx port) const;
140 
141  /// Saves the graph as geometry.
142  void saveToGeometry(GU_Detail* gdp) const;
143  /// Loads a graph from geometry.
144  bool loadFromGeometry(const GU_Detail* gdp);
145 
146  /// Saves the graph to a (geometry) file.
147  bool saveToFile(const char* filename) const;
148  /// Loads the graph from a geometry file.
149  bool loadFromFile(const char* filename);
150 
151  /// Binds an input to the program.
152  bool setInputLayer(const UT_StringRef& name,
153  const IMX_LayerConstPtr& layer);
154  bool setInputGeometry(const UT_StringRef& name,
155  const GU_ConstDetailHandle& geo);
156  bool setInputVDB(const UT_StringRef& name,
157  const IMX_VDBConstPtr& vdb);
158  /// If as_cable is true, all fields from the port are bound as inputs (based
159  /// on the field names).
160  bool setInput(const UT_StringRef& name, const COP_PortData& input,
161  bool as_cable = false);
162  /// If as_cable is true, all inputs that match name.* are cleared.
163  bool clearInput(const UT_StringRef& name, bool as_cable = false);
164 
165  /// Runs the program after the inputs have been bound.
166  void runProgram(const OP_Context& context, UT_ErrorManager& error);
167 
168  /// Extracts results after the program has executed.
169  IMX_LayerPtr getOutputLayer(const UT_StringRef& name) const;
170  GU_ConstDetailHandle getOutputGeometry(const UT_StringRef& name) const;
171  IMX_VDBPtr getOutputVDB(const UT_StringRef& name) const;
172  COP_PortData getOutput(const UT_StringRef& name) const;
173  /// Extracts the port data for a single cable output of the given name. The
174  /// incoming cable structure is assumed to be correct.
175  COP_PortData getOutputCable(const UT_StringRef& name,
176  const COP_CableStructure& cable) const;
177 
178  /// Clears all the graph inputs, letting go of the held references.
179  void clearInputs();
180 
181  /// clears all the graph outputs, letting go of the held references.
182  void clearOutputs();
183 
184  /// Returns a map of all COP inputs to the program. Key of an input is its
185  /// name, while the value is its expected type in the program.
187  {
188  return myProgramInputs;
189  }
190  /// Returns a map of all COP outputs of the program. Key of an output is its
191  /// name, while the value is its type in the program.
194  {
195  return myProgramOutputs;
196  }
197  /// Returns type of the given output.
198  COP_Type getOutputType(const UT_StringRef& output) const;
199 
200  /// Returns true if the input of the given name exists but is not used.
201  bool isUnusedInput(const UT_StringRef& name) const;
202  /// Returns true if the input of the given name exists and is used by the
203  /// program. If as_cable is true, this program is scanned for inputs that
204  /// match name.*.
205  bool isUsedInput(const UT_StringRef& name, bool as_cable = false) const;
206 
207  /// Returns the micronode that captures all dependencies for the program.
209  {
210  return myGraphDep;
211  }
212  /// Returns the micronode that captures all dynamic runtime dependencies
213  /// from the previous program execution.
215  {
216  return myResultsDep;
217  }
218 
219  /// When enabled, the registered callback is invoked whenever the program's
220  /// results become out of date.
221  /// Note that the callback may be invoked more than once when the results
222  /// are dirtied!!!
223  void enableCallback(bool enable)
224  {
225  myGraphDep.enableCallback(enable);
226  myResultsDep.enableCallback(enable);
227  }
228  /// Registers the callback that is to run when the program's results become
229  /// out of date. Use enableCallback() to control whether or not the callback
230  /// is forced to run. The data pointer is passed to the callback function
231  /// when it executes.
232  /// Note that the callback may be invoked more than once when the results
233  /// are dirtied!!!
234  void setCallback(void (*callback)(void*), void* data)
235  {
236  myGraphDep.setCallback(callback, data);
237  myResultsDep.setCallback(callback, data);
238  myErroredMonitor.setCallback(callback, data);
239  }
240 
241  /// Rebuilds the APEX graph if necessary and returns one of the above status
242  /// codes.
243  SlapcompBuildStatus rebuildIfNeeded(const OP_Context& context,
245 
246  /// Returns true if the user should bind input layers that have correct
247  /// camera metadata. If this is false, then the input layers are expected to
248  /// use the default transformation.
249  bool expectsLayerCameras() const
250  {
251  return myExpectInputCameras;
252  }
253 
254  /// Signature evaluation context override ID seen by this program.
255  int getGraphProxyOverrideId() const;
256 
257  /// Returns the Block End node this program is built for; if the program was
258  /// built for a single node, this returns nullptr.
259  COP_Block *getOutputBlock() const;
260  /// Returns the id of the node this program was built from, if it was built
261  /// from a block or a single node.
262  int getOutputNodeId() const;
263  /// Returns the node this program was built from, if it was built from a
264  /// block or a single node, and if that node still exists.
265  COP_Node *getOutputNode() const;
266  /// Returns if this program is for a block that is registered for slap comp.
267  bool isOutputBlockSlapComp() const;
268 
269 protected:
270  /// What the program is built for.
271  enum class BuildTarget
272  {
273  BLOCK,
274  SINGLE_NODE,
275  INVALID
276  };
277 
278 protected:
279  /// Helper function to register dependencies on the signature and port names
280  /// of the block nodes.
281  void addBlockDeps(DEP_MicroNode& dep, COP_Block* begin, COP_Block* end);
282  /// Sets the target output node for the program, possibly marking the graph
283  /// dirty if it's different from a built program's.
284  void setOutputNodeInternal(COP_Node* output, BuildTarget target,
285  const UT_Array<COP_Signature>* sigs,
286  const UT_Array<COP_CableStructure>* cables,
287  const UT_Array<COP_Request>* requests);
288  /// Returns this program's graph proxy, allocating it if it's not yet
289  /// created.
290  COP_GraphProxyDirect* getGraphProxy();
291 
292 protected:
294  /// Map of all inputs used by the program.
297  /// Map of all inputs that are not used by the program. These are saved as
298  /// they are part of the program's signature.
303  /// Mapping of bound passthrough outputs (by their name) to the bound input
304  /// that they correspond to.
306  int myOutputNodeId = -1;
307  BuildTarget myBuildTarget = BuildTarget::INVALID;
309 
312  /// This micronode is used only when the build fails. It gets notified when
313  /// a relevant node is rewired or changed.
315 
316  /// Contains all the dependency-tracking data for node parameters (if built
317  /// from a node).
320 
321  /// This program's graph proxy that might have registered overrides (if
322  /// building from a node).
325 
326  /// This flag controls how the graph is built from a node. If true, all
327  /// parameters are evaluated and baked into the graph; otherwise, they're
328  /// made into graph inputs.
330  /// This flag indicates to the user whether they should place the input
331  /// layers at the correct 3D locations or use default transforms.
332  bool myExpectInputCameras = true;
333 };
334 
335 // Not trivially movable because tbb::concurrent_vector
336 // DEP_MicroNode::myExplicitOutputs is not trivially movable
const UT_StringMap< std::pair< COP_Type, bool > > & getProgramInputs() const
GT_API const UT_StringHolder filename
UT_UniquePtr< COP_ApexNodeDependencies > myParameterDep
virtual void becameDirty(DEP_MicroNode &src, const DEP_PropagateData &propdata)
void enableCallback(bool enable)
void
Definition: png.h:1083
void setCallback(void(*callback)(void *), void *data)
GLboolean * data
Definition: glcorearb.h:131
UT_StringMap< std::pair< COP_Type, bool > > myUnusedInputs
UT_Array< COP_Request > myOutputRequests
BuildTarget
What the program is built for.
const UT_StringMap< std::pair< COP_Type, UT_StringHolder > > & getProgramOutputs() const
bool expectsLayerCameras() const
COP_MicroNodeWithCallback myErroredMonitor
GLenum GLuint GLint GLint layer
Definition: glcorearb.h:1299
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
< returns > If no error
Definition: snippets.dox:2
UT_SharedPtr< const IMX_Layer > IMX_LayerConstPtr
Definition: IMX_Layer.h:27
GLuint GLuint end
Definition: glcorearb.h:475
UT_SharedPtr< const IMX_VDB > IMX_VDBConstPtr
Definition: IMX_VDB.h:34
UT_StringMap< std::pair< COP_Type, bool > > myProgramInputs
Map of all inputs used by the program.
bool callbackEnabled() const
Returns true if the callback is enabled (even if not set).
GLenum target
Definition: glcorearb.h:1667
#define SYS_DECLARE_IS_NOT_TR(T)
Declare that that trivial relocation with type T is not guaranteed to be safe.
COP_MicroNodeWithCallback myGraphDep
GLuint const GLchar * name
Definition: glcorearb.h:786
COP_MicroNodeWithCallback myResultsDep
GLenum mode
Definition: glcorearb.h:99
DEP_TimedMicroNode & getGraphDep()
Returns the micronode that captures all dependencies for the program.
COP_Type
Types of basic data that are passed around a COP network.
Definition: COP_Signature.h:17
UT_StringMap< COP_PortData > myPassthroughOutputs
UT_UniquePtr< COP_GraphProxyDirect > myGraphProxy
UT_UniquePtr< apex::APEX_Graph > myGraph
void enableCallback(bool enable)
Controls whether or not the callback runs when the micronode is dirtied.
A global error manager scope.
#define COP_API
Definition: COP_API.h:8
int OP_OutputIdx
Definition: OP_DataTypes.h:185
Propagation info for a dep micro node.
Definition: DEP_MicroNode.h:36
void setCallback(void(*callback)(void *), void *data)
UT_SharedPtr< IMX_VDB > IMX_VDBPtr
Definition: IMX_VDB.h:33
UT_StringMap< std::pair< COP_Type, UT_StringHolder > > myProgramOutputs
DEP_TimedMicroNode & getResultsDep()
UT_SharedPtr< IMX_Layer > IMX_LayerPtr
Definition: IMX_Layer.h:26
Definition: format.h:1821
GLenum src
Definition: glcorearb.h:1793
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.
Definition: node.h:566