HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PI_OpHandleLink.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: PI_OpHandleLink.h (PI Library, C++)
7  *
8  * COMMENTS:
9  *
10  * PI base class.
11  */
12 
13 #ifndef __PI_OpHandleLink__
14 #define __PI_OpHandleLink__
15 
16 #include "PI_API.h"
17 #include <OP/OP_Value.h>
18 #include <PRM/PRM_ChanState.h>
19 #include <PRM/PRM_Value.h>
20 #include <CH/CH_ExprLanguage.h>
21 
22 #include <UT/UT_Color.h>
23 #include <UT/UT_Function.h>
24 #include <UT/UT_IntArray.h>
25 #include <UT/UT_String.h>
26 #include <UT/UT_StringArray.h>
27 #include <UT/UT_SymbolTable.h>
28 #include <UT/UT_UndoManager.h>
29 #include <UT/UT_ValArray.h>
30 #include <UT/UT_VectorTypes.h>
31 
32 #include <hboost/any.hpp>
33 #include <iosfwd>
34 
35 
36 #define PI_SETTING_SHOWOPPATH "showoppath"
37 #define PI_SETTING_COLOR "color"
38 #define PI_SETTING_OWNEROP "ownerop"
39 #define PI_SETTING_OWNEROPGROUP "owneropgroup"
40 
41 class OP_Node;
42 class OP_Operator;
43 class CMD_Args;
44 class PI_SettingList;
45 class PI_PITemplate;
46 
48 {
49 public:
52 
53  struct LateBinding
54  {
55  // Interface to define the protocol for implementing handle late bindings
56  LateBinding() = default;
57  virtual ~LateBinding() = default;
58 
59  // Called when a handle change has started
60  virtual void beginHandleChange(PI_OpHandleLink const* pi, void* ui_event)
61  {
62  }
63 
64  // Called when a handle change has ended
65  virtual void endHandleChange(PI_OpHandleLink const* pi, void* ui_event)
66  {
67  }
68 
69  // read/write parm values
70  virtual bool toStateValues(PI_OpHandleLink*, void* ui_event) = 0;
71  virtual bool toHandleValues(PI_OpHandleLink*) = 0;
72 
73  // data accessors
74  virtual int getParmValue(PI_OpHandleLink const* pi, int pindex, int &val, int d=0) const = 0;
75  virtual int getParmValue(PI_OpHandleLink const* pi, int pindex, fpreal &val, fpreal d) const = 0;
76  virtual int getParmValue(PI_OpHandleLink const* pi, int pindex, UT_String &val, UT_String d=0) const = 0;
77  virtual int setParmValue(PI_OpHandleLink const* pi, int pindex, fpreal value, bool setkey) = 0;
78  virtual int setParmValue(PI_OpHandleLink const* pi, int pindex, int value, bool setkey) = 0;
79  virtual int setParmValue(PI_OpHandleLink const* pi, int pindex, UT_StringRef const& value) = 0;
80 
81  // Return true if the parm id refers to an enabled parm. False otherwise.
82  virtual bool isParmEnabled(PI_OpHandleLink const* pi, int pindex) const = 0;
83  };
84 
85  PI_OpHandleLink(const PI_PITemplate &templ);
86  virtual ~PI_OpHandleLink();
87 
88  // Methods to link a handle's parameter with an op's parameter.
89  // Return 1 on success, 0 if parm name is invalid. op_type_name tells the
90  // type of operator. Do not call these methods from the class c-tor.
91  int linkOpParmToHandleParm(const char *op_type,
92  const char *handle_parm_name,
93  const char *op_parm_name);
94 
95  // Activate the underlying handle parm, typically used when dynamic handle
96  // binding is in effect (see PI_OpHandleLink::HandleBinding)
97  int activateHandleParm(int pindex);
98 
99  // Disable the underlying handle parm
100  void disableHandleParm(int pindex);
101 
102  virtual int attach(OP_Node &node);
103  virtual int detach(OP_Node &node);
104  virtual void detachAll();
105 
106  void attachForKeyframe(OP_Node &node);
107  void detachForKeyframe(OP_Node &node);
108  void detachAllForKeyframe();
109 
110  // Hide all handle parameter parts except for the ones from handle_parms
111  // (starting from index `beg`).
112  void isolateHandleParms(int beg,
113  const UT_StringArray& handle_parms);
114 
115  void setShowOpPath(bool onoff);
116  virtual bool getShowOpPath() const;
117 
118  // The root description is the description for the PI that is set
119  // in the binding. Then the name of the first attached operator may
120  // be appended by the buildDecription function (which calls
121  // the virtual descriptionChanged in case a subclass needs to do
122  // something in responds to a description change).
123  void setRootDescription(const char *description);
124  const char *getRootDescription() const;
125  void buildDescription();
126  const char *getDescription() const;
127  virtual void descriptionChanged(const char* old_description);
128 
129  // The time overrides are used by the Motion Path PI to manipulate other PIs
130  // to modify parm values at a given time instead of at the current time
131  // in the animation timeline.
132  void setIsTimeOverride(bool is_time_override);
133  void setTimeOverrideTime(fpreal t);
134 
135  bool getIsTimeOverride() const
136  { return myIsTimeOverride; }
138  { return myTimeOverrideTime; }
139 
140  // Does this PI allow saving/loading from the per-op and/or last settings
141  // tables? By default, it allows using both tables.
143  { return myAllowUsingPerOpSettingsTable; }
145  { return myAllowUsingLastSettingsTable; }
147  { return myAllowUsingOpTypeSettings; }
149  { return myAllowUsingLastVisibilitySetting; }
150 
151  // When saving settings for this PI to the last settings table, we
152  // often only want PI's of this type to use these settings when they're
153  // attached to a specific type of operator. For example, the "xform"
154  // PI can be attached to many different types of sops. However, we
155  // don't want the last "xform" settings for the "copy" sop to be used
156  // the next time we put down an "xform" sop. This method returns that
157  // type of operator, if there are any restrictions, or null if there are
158  // no restrictions. The PI must be attached to at least one op when
159  // this method is called. By default, it returns null if this PI is
160  // attached to more than one op, or the type of the op if it is attached
161  // to exactly one. This method will also always return null if the
162  // myAllowUsingOpTypeSettings flag is false.
163  OP_Operator *lastSettingsOperatorTypeRestriction() const;
164 
165  // Return the op to which we're attached, or nil if we're detached.
166  OP_Node *getOpNode(int opnum = 0) const;
167  int getNumOps() const;
168  OP_Node *getKeyframeOpNode(int opnum = 0) const;
169  int getKeyframeNumOps() const;
170 
171  // Find out if we contain this node:
172  int hasOpNode(const OP_Node &node) const;
173  int hasKeyframeOpNode(const OP_Node &node) const;
174  OP_Node *findOpNode(int op_type, const char *op_name) const;
175 
176  // Update ourselves (and our handles) based on our ops parm values.
177  void doUpdateFromOpParms();
178  virtual void forceUpdateFromOpParms();
179  virtual void updateOpParms();
180 
181  // Respond to a parameter change in the op. Called from the above
182  // function.
183  virtual void handleOpNodeChange(OP_Node &node);
184  virtual void handleOpUIChange(OP_Node & /*node*/)
185  { }
186  virtual int wantsOpNodeChange(const OP_Node & /*node*/) const
187  { return 0; }
188  virtual bool flagOpNodeChangeNeeded(OP_Node & /*node*/)
189  { return false; }
190 
191  // The user can dynamically change the bindings from the textport.
192  // We need to refresh the current handle link in the viewports
193  // because it could be affected. Return 0 if this handle has no bindings
194  // left.
195  virtual int refreshBindings(int op_type, const char *op_name);
196 
197  // These id values are used by the linking mechanism to determine if
198  // the pi for a particular linked parm exists already or not.
199  void id(int i);
200  int id() const;
201 
202  bool hasLinkedParms() const
203  { return myParmNames.entries() > 0; }
204 
205  // Returns a list of all parms bound to this handle.
206  const UT_StringArray &linkedParmNames(int opnum) const
207  { return *myParmNames(opnum); }
208  // These virtuals are similar to the linked... functions below.
209  // The difference is that these versions are used by the Key
210  // functions above. By ovrriding these, subclasses can make the
211  // above functions work for OP parms that are not linked to
212  // PI parms.
213  virtual const UT_StringArray &allParmNames(int opnum) const
214  { return *myParmNames(opnum); }
215 
216  // This gets the index of the operator that is actually bound
217  // to the specified index. If none is bound, -1 is returned.
218  int getOpnumForHandleParmIndex(int idx) const;
219 
220  // Query or set the active color of the PI:
221  const UT_Color &getActiveColor() const;
222  virtual void setActiveColor(const UT_Color &c);
223 
224  // Set accessibility state of the binding
225  void setBindingState(const bool active);
226 
227  virtual int isEqual(const PI_OpHandleLink &pi) const;
228  virtual int setEqual(const PI_OpHandleLink &pi);
229 
230  // An ethereal handle link is one that is invisible by nature.
231  bool ethereal() const;
232  const PI_PITemplate &getTemplate() const;
233  PI_PITemplate &getTemplate();
234 
235  int writeOptions(std::ostream &os, const char *baseCommand);
236  int runBindCommand(CMD_Args &args);
237  int runUnbindCommand(CMD_Args &args);
238 
239  // Functions used to handle menu functionality
240  void editChannels(int append_channels, int opnum=-1);
241  void findKey(int direction, int opnum=-1);
242  void setKeys(int opnum = -1,
243  int pindex_start = -1,
244  int pined_stop = -1,
245  const char *undo_str = 0);
246  void removeKeys(int opnum=-1);
247  void deleteChannels(int opnum=-1);
248  void lockParms(int opnum=-1);
249  void revertToDefaults(int opnum=-1);
250  void revertToFactoryDefaults(int opnum=-1);
251  void overwriteDefaults(int opnum=-1);
252 
253  // Load or save the settings for this PI. If specific_to_op is true
254  // in saveSettings() then the PI's settings will be saved in the per-op
255  // settings table instead of the last settings table.
256  virtual void loadSettings(const PI_SettingList &settings);
257  virtual void saveSettings(PI_SettingList &settings,
258  bool specific_to_op) const;
259 
260  // Save the settings for this PI.
261  virtual void saveSettingsToAppropriateLocation();
262 
263  // Load the settings for this PI from the per-op or last setting table.
264  // The PI _must_ be attached to its nodes when this method is called.
265  void loadSettingsFromTables(bool okay_to_use_last_settings);
266 
267  // Remove any settings this PI may have stored from the per-op and
268  // last setting tables.
269  void removeSettingsFromTables();
270 
272  {
273  public:
274  int myIndex;
276  };
277 
278  // This extracts the projection associated with this binding, if any,
279  // from the parmname. channel is set to the name of the channel
280  // which is bound.
281  static void extractProjection(UT_String &channel,
282  const char *parmname, fpreal &a, fpreal &b,
283  fpreal &c, fpreal &d);
284  static void extractChannelName(UT_String &channel,
285  const char *parmname)
286  {
287  fpreal dummy;
288  extractProjection(channel, parmname,
289  dummy, dummy,
290  dummy, dummy);
291  }
292 
293  void setLateBinding(LateBinding * binding);
294  bool hasLateBinding() const;
295  bool hasLateBinding(LateBinding const * binding) const;
296 
297  // Map a handle parm name to an index, or retrieve the index by the name.
298  // Indices must be non-negative. If the parm has not been mapped,
299  // findHandleParmIndex returns -1.
300  int findHandleParmIndex(const char *h_parm_name) const;
301 
302  // Allows the PI to react before being deleted.
303  virtual void onDeletion();
304 
305  // Returns the proxy pointer id that is used by other classes if they need
306  // to hold a pointer to an instance PI_OpHandleLink.
307  // (e.g. Use of BM_OpHandleLink by MPI_MotionPath)
308  int getProxyIndex() const { return myProxyIndex; }
309 
310  // Allow derived classea to detach and move a handle from its
311  // default position.
312  virtual bool handleDetach();
313  virtual bool handleIsDetached() const;
314  virtual bool handleIsDetachable() const;
315 
316  // Update the PI settings with a new set of setting values
317  void updateSettings(char const* setting_string);
318  virtual bool getSettingValue(char const* setting_name, hboost::any& out_value) const;
319 
320  // Call these methods to customize how their settings are saved.
322  { myAllowUsingPerOpSettingsTable = onoff; }
324  { myAllowUsingLastSettingsTable = onoff; }
326  { myAllowUsingOpTypeSettings = onoff; }
328  { myAllowUsingLastVisibilitySetting = onoff; }
329 
330  // Iterate over all parms
331  int iterateParms(int opnum, ReadParmFunc func) const;
332  int iterateParms(int opnum, ModifyParmFunc func, bool modify_locked=false);
333 
334 protected:
335 
336  // Update ourselves (and our handles) based on our ops parm values.
337  virtual void updateFromOpParms();
338 
339  // Override this function to help decide which handles should be
340  // active when this PI is attached to an operator. This will be
341  // called if we successfully link to the given pindex.
342  //
343  // You should call the base class first and only proceed if it
344  // returns 1. I don't know the semantics of that - it's just how
345  // the old linkOpParm worked.
346  virtual int justLinked(int pindex);
347  virtual void justUnlinked(int pindex);
348 
349  virtual PI_Interest *getInputGroupInterests() const;
350 
351  // These methods add/remove interests in all of a PI's input group
352  // parameters. These methods are called when a node is attached or
353  // detached from the PI. They use the array of PI_Interests
354  // returned by getInputGroupInterests().
355  void addAllInputGroupInterests(int opnum);
356  void removeAllInputGroupInterests(int opnum);
357 
358  // Convenience method for descendants to get the current time.
359  virtual fpreal getTime() const;
360 
361  // Methods to get/set the op's parameter values. If the parameter has
362  // not been linked to an op parameter, these methods return 0. Otherwise,
363  // they return 1.
364  int getParmValue(int pindex, int &val, int d=0) const;
365  int getParmValue(int pindex, fpreal &val, fpreal d=0) const;
366  int getParmValue(int pindex, UT_String &val,
367  UT_String d=0) const;
368  // Get the [pindex, pindex+3) parm values into a UT_Vector3R
369  void getParmVector3(int pindex, UT_Vector3R &v,
370  fpreal def = 0.0) const;
371 
372  int getParmInstValue(int pindex, const int *inst,
373  int &val, int d=0,
374  int nestlevel=1) const;
375  int getParmInstValue(int pindex, const int *inst,
376  fpreal &val, fpreal d=0,
377  int nestlevel=1) const;
378  int getParmInstValue(int pindex, const int *inst,
379  UT_String &val, UT_String d=0,
380  int nestlevel=1) const;
381  // Get the [pindex, pindex+3) parm values into a UT_Vector3R
382  void getParmInstVector3(int pindex, const int *inst,
383  UT_Vector3R &v,
384  fpreal def = 0.0) const;
385 
386  int setParmValue(int pindex, int val, bool addkey=false);
387  int setParmValue(int pindex, fpreal val, bool addkey=false);
388  int setParmValue(int pindex, const UT_String &val,
389  CH_StringMeaning meaning);
390  // Get the [pindex, pindex+3) parm values into a UT_Vector3R
391  void setParmVector3(int pindex, const UT_Vector3R &v);
392 
393  int setParmInstValue(int pindex, const int *inst,
394  int val, bool addkey=false,
395  int nestlevel=1);
396  int setParmInstValue(int pindex, const int *inst,
397  fpreal val, bool addkey=false,
398  int nestlevel=1);
399  int setParmInstValue(int pindex, const int *inst,
400  const UT_String &val,
401  CH_StringMeaning meaning,
402  int nestlevel=1);
403  void setParmInstVector3(int pindex, const int *inst,
404  const UT_Vector3R &v);
405 
406  int performParmCallback(int pindex, int theitem);
407 
408  int setOpParmValue(OP_Node *op, PRM_Parm *parm, int vecidx,
409  int val, bool addkey=false);
410  int setOpParmValue(OP_Node *op, PRM_Parm *parm, int vecidx,
411  fpreal val, bool addkey=false);
412  int setOpParmValue(OP_Node *op, PRM_Parm *parm, int vecidx,
413  const UT_String &val,
414  CH_StringMeaning meaning);
415 
416  // Methods to read or modify parm values given a pindex without adding keys
417  // Returns true if parm is read/modified, otherwise false
418  bool readParm(int pindex, ReadParmFunc f) const;
419  bool modifyParm(int pindex, ModifyParmFunc f, bool modify_locked=false);
420 
421  // copies the keyframe structure of pindex_from to pindex_dest, while
422  // leaving the value of pindex_dest constant.
423  void copyKeyStructure(int pindex_dest, int pindex_from);
424 
425  // returns true if the parameter is enabled (a la disableParms())
426  bool isParmEnabled(int pindex, int opnum = 0) const;
427 
428  // returns the parameter animation state.
429  PRM_ChanState getParmState(int pindex, int opnum = 0) const;
430 
431  // Functions to access the parameter index arrays.
432  int getLinkedParmCount() const
433  { return myParmNames.entries(); }
434 
435  // This function determines whether or not we should do an
436  // updateFromOpParms when the time changes.
437  // Returns true unless we have an input group interest, in which
438  // case the input group interest is enough to force the update,
439  // so we return false.
440  virtual int hasTimeInterest() const;
441  virtual void handleTimeChange();
442 
443  // These two functions are provided for all the PI based operations
444  // that need to manage an undo block that begins in one function
445  // but ends in another function (or another instance of the same
446  // function).
447  //
448  // However, they can only handle ONE block at a time. No nesting
449  // of calls to beginDistributedUndo!
450  void beginDistributedUndoBlock(const char *operation,
451  UT_UndoBlockType blocktype);
452  void endDistributedUndoBlock();
453 
454  // Returns true if we have called beginDistributedUndoBlock but have
455  // not yet called endDistributedUndoBlock; returns false otherwise.
456  bool inDistributedUndoBlock();
457 
458  // This virtual callback is called whenever one of our attached
459  // or attached-for-keyframe nodes is changed.
460  virtual void handleOpChange(OP_Node *op,
461  OP_EventType etype,
462  void *data);
463 
464  // Some functions for getting and setting our owner operator information.
465  // The owner operator is the operator that defines what space our handles
466  // should appear in and what SOP/group field we should be interested in.
467  virtual void setOwnerOp(const char *owner_op);
468  const UT_String &getOwnerOp() const;
469  OP_Node *getOwnerOpRelativeTo(OP_Node *node) const;
470  virtual void setOwnerOpGroup(const char *owner_op_group);
471  const UT_String &getOwnerOpGroup() const;
472 
473  // Return the channel name for our first input group interest.
474  const UT_StringHolder &getFirstInputGroupInterestName() const;
475 
476  // This helper function returns true if the parm channel_name is locked and
477  // false otherwise. This function will follow any channel references that
478  // this parm might have to determine the "true" locked status.
479  static bool isOpParmLocked(
480  const char *channel_name, OP_Node &op, fpreal time,
481  const PRM_Parm **ret_parm = NULL,
482  const OP_Node **ret_node = NULL);
483 
484  // Called by derived class to update the state values bind to a handle
485  void updateStateValues(void* ui_event);
486 
487  // Called when a handle change has started
488  void beginHandleChange(void* ui_event);
489 
490  // Called when a handle change has ended
491  void endHandleChange(void* ui_event);
492 
493  // Typically called from a derived class to allocate a proxy
494  void allocProxy(void* ptr);
495 
496  // Called from a derived class to free the PI proxy previously allocated
497  // with allocProxy().
498  void freeProxy();
499 
500  // Return the op parm label linked to pi_index
501  UT_StringHolder getOpParmLabel(int pi_index) const;
502 
503 private:
504  int linkOpParm(const char *op_type,
505  int pindex, const char *parmname);
506  void updateParmLockStatus( OP_Node &op );
507  UT_StringArray &opParmNames(const char *op_type);
508  void addParmNames(int opnum);
509  void removeParmNames(int opnum);
510 
511  void setKeysSingleOp(int opnum, int pindex = -1,
512  UT_String *names = NULL,
513  const char *name_prefix = NULL);
514  void removeKeysSingleOp(int opnum);
515  void deleteChannelsSingleOp(int opnum);
516  void lockParmsSingleOp(int opnum);
517  void revertToDefaultsSingleOp(int opnum);
518  void revertToFactoryDefaultsSingleOp(int opnum);
519  void overwriteDefaultsSingleOp(int opnum);
520 
521  // For a given pindex, add/remove interest's in the corresponding
522  // parameter's PRM_Value.
523  int addInputGroupInterest(int pindex,
524  PRM_ValueCallback callback,
525  int opnum);
526  int removeInputGroupInterest(int pindex,
527  PRM_ValueCallback callback,
528  int opnum);
529 
530  // Callback function to make sure we always know when one of our
531  // nodes is being deleted.
532  static void handleOpChangeCallback(OP_Node *op, void *callee,
533  OP_EventType etype, void *data);
534 
535  void clearOpTypeParmNamesMap();
536 
537  // used for updating handle values from a dynamic handle binding
538  void updateHandleValues();
539 
540  const PI_PITemplate &myTemplate;
541  // This symbol table has as it's index the optype name, and as it's
542  // contents the cached UT_StringArrays which would correspond to that
543  // op's ParmNames.
544  UT_SymbolMap<UT_StringArray *> myOpTypeParmNames;
545 
546  // This is a translation from our PI parm index into the opnum.
547  UT_IntArray myOpnumForParmIndex;
548 
549  // This is indexed by the opnum and has the string array of op parms
550  // that correspond to that opnum. The index on the string array is
551  // the index into our PI parms.
552  UT_ValArray<UT_StringArray *> myParmNames;
553  UT_ValArray<OP_Node *> myOpNodes;
554  UT_ValArray<OP_Node *> myKeyframeOpNodes;
555  UT_StringArray myInputGroupInterests;
556  int myId;
557  const PI_Interest *myInterests;
558  UT_String myRootDescription;
559  UT_String myDescription;
560  UT_String myOwnerOp;
561  UT_String myOwnerOpGroup;
562 
563  UT_Color myActiveColor;
564 
565  int myDistributedUndoBlockLevel;
566  bool myAllowUsingPerOpSettingsTable;
567  bool myAllowUsingLastSettingsTable;
568  bool myAllowUsingOpTypeSettings;
569  bool myAllowUsingLastVisibilitySetting;
570  bool myShowOpPath;
571 
572  bool myIsTimeOverride;
573  fpreal myTimeOverrideTime;
574  LateBinding* myLateBinding;
575  int myProxyIndex;
576 };
577 
578 #endif
579 
PXL_API const char * getDescription(const ColorSpace *space)
Return the description of the color space.
CH_StringMeaning
GT_API const UT_StringHolder time
const GLdouble * v
Definition: glcorearb.h:837
IMF_EXPORT IMATH_NAMESPACE::V3f direction(const IMATH_NAMESPACE::Box2i &dataWindow, const IMATH_NAMESPACE::V2f &pixelPosition)
GLsizei const GLfloat * value
Definition: glcorearb.h:824
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
#define PI_API
Definition: PI_API.h:10
GLfloat f
Definition: glcorearb.h:1926
bool any(const vbool4 &v)
Definition: simd.h:3600
PRM_ChanState
Definition: PRM_ChanState.h:14
UT_UndoBlockType
constexpr enabler dummy
An instance to use in EnableIf.
Definition: CLI11.h:985
GLuint id
Definition: glcorearb.h:655
std::function< T > UT_Function
Definition: UT_Function.h:37
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
void(* PRM_ValueCallback)(void *callee, void *value)
Definition: PRM_Value.h:22
that also have some descendant prim *whose name begins with which in turn has a child named baz where *the predicate active
GLdouble t
Definition: glad.h:2397
GLenum func
Definition: glcorearb.h:783
__hostdev__ constexpr T pi()
Pi constant taken from Boost to match old behaviour.
Definition: NanoVDB.h:976
fpreal64 fpreal
Definition: SYS_Types.h:278
auto ptr(T p) -> const void *
Definition: format.h:4331
GLuint GLfloat * val
Definition: glcorearb.h:1608
OP_EventType
Definition: OP_Value.h:22
**If you just want to fire and args
Definition: thread.h:618
Definition: format.h:1821