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