HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OP3D_InputSelectorBase.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: OP3D_InputSelectorBase.h
7  *
8  * COMMENTS:
9  * This descendant of DM_InputSelector knows about the viewer. It uses
10  * the viewer to find out display/current sop and to use the viewer's
11  * selection type buttons.
12  */
13 
14 #ifndef __OP3D_InputSelectorBase_h__
15 #define __OP3D_InputSelectorBase_h__
16 
17 #include "OP3D_API.h"
18 
19 #include <DM/DM_InputSelector.h>
20 #include <DM/DM_Defines.h>
21 #include <GR/GR_PickRecord.h>
22 #include <GU/GU_SelectType.h>
23 #include <GU/GU_DetailHandle.h>
24 #include <UI/UI_Value.h>
25 #include <UT/UT_String.h>
26 #include <UT/UT_IntrusivePtr.h>
27 #include <SYS/SYS_AtomicInt.h>
28 #include <GA/GA_Types.h>
29 #include <RE/RE_RenderContext.h>
30 
31 class SIM_Data;
32 class SIM_Object;
33 class GU_Detail;
34 class OP_Node;
36 class RE_Render;
37 class UI_Menu;
38 class UI_Feel;
39 class UI_Event;
40 class SI_RubberBox;
41 class SI_Lasso;
42 class SI_Brush;
43 class DM_Viewport;
44 class DM_Workbench;
45 class DM_HeldHotkeyCache;
46 class GUI_DetailLook;
47 class OP3D_View;
48 
50 {
54 };
55 
57 {
58 public:
59  OP3D_PickId();
60  OP3D_PickId(int lookindex, int detailindex);
61  ~OP3D_PickId();
62 
63  bool operator==(const OP3D_PickId &cmp) const;
64  bool operator!=(const OP3D_PickId &cmp) const;
65  static int compare(const OP3D_PickId *id1, const OP3D_PickId *id2);
66 
69 };
70 
73 
75 {
76 public:
77  OP3D_InputSelectorBase(OP3D_View &viewer,
78  PI_SelectorTemplate &templ);
79  ~OP3D_InputSelectorBase() override;
80 
81  // This method allows the resource manager can set the workbench to
82  // something different if a selector is reused. It should not be used
83  // otherwise. A nil pointer is allowed so the select can remove any
84  // of its interests. However, methods of the selector should never be
85  // called when its workbench is nil. The method is virtual so
86  // descendants can also have a chance to clean up.
87  //
88  // Note that setSelectionUIValues must be called after calling setViewer()
89  void setViewer(BM_View *viewer) override;
90 
91  // The selector needs to be notified when it starts/stops selecting
92  // so it can add/remove interests (the selection type, etc.).
93  void startSelecting() override;
94  void stopSelecting() override;
95 
96  // Use this opportunity to render prior object selections.
97  void doRender(RE_RenderContext r, int x, int y,
98  int ghost) override;
99 
100  // This UI value changes when the selector has finished selecting. The
101  // state that owns the selector adds an interest in this event to know
102  // when the selector is finished.
104  { return *myFinishedValue; }
105  const UI_Value &finishedValue() const
106  { return *myFinishedValue; }
107 
108  UI_Feel *getCustomToolbox() const override;
109 
111  { myPreferredSelectMode = selmode; }
113  { return myPreferredSelectMode; }
114 
115  // If the selector allows dragging, then it must wrap up and give up
116  // control when the user starts dragging. This enables us to implement
117  // the pick and drag functionality frequently used in modeling.
118  bool allowDragging() const
119  { return myAllowDragging; }
120  void setAllowDragging(bool on)
121  { myAllowDragging = on; }
122 
123  // Some states (like the select state) don't ever want their selector
124  // to finish.
125  bool allowFinishing() const
126  { return myAllowFinishingFlag; }
127  void setAllowFinishing(bool allow_finishing)
128  { myAllowFinishingFlag = allow_finishing;}
129 
130  // Some selector can finish with whatever selection exists already.
131  bool allowFinishWithExistingSelection() const;
132  void setAllowFinishWithExistingSelection(bool allow);
133 
134  // If quick select is on, then the selection is immediately finished
135  // if we have secure selection off
136  bool allowQuickSelect() const
137  { return myAllowQuickSelect; }
138  void setAllowQuickSelect(bool on)
139  { myAllowQuickSelect = on; }
140 
142  { return myAllowEmptyQuickSelect; }
144  { myAllowEmptyQuickSelect = on; }
145 
146  /// Tells the selector about previous selection information that we still
147  /// want to display in the viewport, but which is not part of the current
148  /// selection operation.
149  void setPriorSelections(const UT_StringArray &paths,
150  const UT_StringArray &ids,
151  const OP3D_SelectionHandles &selections);
152 
153  // Did the selector just change the display flag? The selector sets
154  // this flag when it creates a sop (eg. a hide or a group sop) and
155  // sets its display flag. The state will check this flag when the state
156  // controller asks it if it just changed the display flag. This way,
157  // the selector can change the display flag without exiting the current
158  // state.
159  bool justDisplayedOp() const
160  { return myJustDisplayedOpFlag; }
161  void setJustDisplayedOp(bool on)
162  { myJustDisplayedOpFlag = on; }
163 
164  // Selectors resize the brush radius with the mouse wheel when appropriate.
165  int handleMouseWheelEvent(UI_Event *event) override;
166 
167  // Handle transitory keys to change the mouse cursor according to our
168  // selection mode.
169  bool handleTransitoryKey(const UI_Event &event,
170  int hotkey_id) override;
171 
172  const char *cursor() const override;
173 
174  void handleSelectionStyleChange(UI_Event *event);
175 
176  // Methods for setting user preferences
177  static bool getPickingMenuOn() { return thePickingMenuOn; }
178  static void setPickingMenuOn(bool val) { thePickingMenuOn = val; }
180  { return theAllowUseExistingSelection; }
182  { theAllowUseExistingSelection = val; }
183  static bool getSelectFullLoops()
184  { return theSelectFullLoops; }
185  static void setSelectFullLoops(bool val)
186  { theSelectFullLoops = val; }
187 
188 
189  // Converts a string to a GU_Detail pointer. The string will either be
190  // an object or sop path, or a path to a specific DOP simulation data.
191  static GU_ConstDetailHandle getGeometryFromPath(const char *path);
192  static OP_Node *getNodeFromPath(const char *path);
193  static const SIM_Object *getSimObjectFromPath(const char *path);
194  static const SIM_Data *getSimModifierFromPath(const char *path);
195 
196  // A utility method to get the string representation of a reference to
197  // the flood fill selection hotkey, for replacement by the bound keys.
198  static const char *getFloodFillSelectionHotkeyStringRef(
200  // A utility method to get the string representation of a refernce to
201  // the loop selection hotkey, for replacement by the bound keys.
202  static const char *getLoopSelectionHotkeyStringRef(
204 
205  // A utility method to determine if a particular transitory key is bound
206  // as a loop selection hotkey. The optional hotkey_id parameter is to
207  // allow it to be used transparently if using preemptive resolved events.
208  static bool isTransitoryLoopSelectionHotkey(
209  const UI_DeviceEvent &state,
210  int hotkey_id = 0);
211 
212  // A utility method to determine if the loop selection hotkey is pressed
213  // in the specified viewport.
214  static bool isTransitoryLoopSelectionHotkeyPressed(
215  DM_Viewport *viewport,
217 
218  // A utility method to show the loop selection hotkey message in the given
219  // workbench.
220  static void showLoopSelectionMessage(
221  DM_Workbench &workbench);
222 
223  static void showSelectionHintsMessage(
224  DM_Workbench &workbench);
225 
226  bool getStateParmNames(
227  UT_StringArray &ret,
228  const char* prefix = nullptr) override;
229  bool evalStateParm(
230  const char *name,
231  UT_StringHolder &ret) override;
232  bool setStateParm(
233  const char *name,
234  const UT_StringHolder &val) override;
235  bool pressStateButton(const char *name) override;
236 
237  class Proxy;
240 
241  // Drawable selection
242  bool canSelectDrawables() const override;
243 
244  void enableDrawableSelection(bool select_drawables);
245  void setDrawableMask(UT_StringArray const& drawable_mask);
246 
247 protected:
248  OP3D_View &viewer() { return (OP3D_View &)baseViewer(); }
249  const OP3D_View &viewer() const { return (OP3D_View &)baseViewer(); }
250 
251  DM_Workbench &workbench() { return *myWorkbench; }
252  const DM_Workbench &workbench() const { return *myWorkbench; }
253 
254  void setFinishedValuePtr(UI_Value *new_value)
255  { myFinishedValue = new_value; }
257  { return myFinishedValue; }
258 
259  void setLocatedValuePtr(UI_Value *new_value)
260  { myLocatedValue = new_value; }
262  { return myLocatedValue; }
263 
265  { mySelectionStyle = new_value; }
267  { return mySelectionStyle; }
269  {
270  if (mySelectionStyle)
271  return (DM_SelectionStyle)
272  (int)*mySelectionStyle;
273  else
274  return DM_STYLE_UNKNOWN;
275  }
276  void setVisiblePickPtr(UI_Value *new_value)
277  { myVisiblePickValue = new_value; }
279  { return myVisiblePickValue; }
280  bool getVisiblePick() const
281  {
282  if(myVisiblePickValue)
283  return (bool) *myVisiblePickValue;
284  return true;
285  }
286 
287  void setContainedPickPtr(UI_Value *new_value)
288  { myContainedPickValue = new_value; }
290  { return myContainedPickValue; }
291  bool getContainedPick() const
292  {
293  if(myContainedPickValue)
294  return (bool) *myContainedPickValue;
295  return false;
296  }
297 
298  void setSelectionRulePtr(UI_Value *new_value)
299  { mySelectionRule = new_value; }
301  { return mySelectionRule; }
303  {
304  if (mySelectionRule)
305  return (GU_SelectionRule)
306  (int)*mySelectionRule;
307  else
308  return GU_ReplaceSelect;
309  }
311  {
312  if (mySelectionRule)
313  *mySelectionRule = (int)srule;
314  }
315 
316  SI_Brush * getPickBrushPtr() const { return myPickBrush; }
317  SI_Brush * getPickLaserPtr() const { return myPickLaser; }
318  SI_Lasso * getPickLassoPtr() const { return myPickLasso; }
319 
320 
321  // returns true if box, lasso or paint selection is active.
322  bool isDragSelectActive() const;
323 
324  // Returns true if the selector needs to make an object selection because
325  // the viewer isn't currently pointed at the right network level.
326  virtual bool needObjectPick() const;
327 
328  // Checks whether our selector knows how to handle selections in the
329  // context of the current chosen op.
330  bool selectModeMatchesTemplateType();
331 
332  // Given a pick buffer (where the first entry of each pick is an op
333  // node id), set the viewer chosen op to the first picked node.
334  bool pickChosenOp(UT_Array<GR_PickRecord> &pick_records,
335  bool *changed = nullptr);
336 
337  // Given a pick record, return the GU_Detail that it refers to, and
338  // (optionally), the corresponding detail look.
339  GU_ConstDetailHandle getGeometryFromPickRecord(const GR_PickRecord &pick,
340  GUI_DetailLook **detail_look = nullptr);
341 
342  // Make the specified node into the chosen op for the viewer. Used by
343  // pickChosenOp. Made the function virtual so subclasses can do extra
344  // work once the switch is complete. Returns the new chosen op.
345  // Sets @c changed to @c true if the operator chosen is different from
346  // the one that was selected going in.
347  virtual OP_Node *switchToChosenOp(OP_Node *parent,
348  bool *changed = nullptr);
349 
350  // Save our state for undo.
351  virtual void saveForUndo();
352 
353  // Given a pick number (the first number in a pick buffer), return
354  // the name in name. Returns true if the pick number was able to
355  // be associated with a name, false otherwise.
356  virtual bool getPickName(const OP3D_PickId &pickid,
357  UT_String &name,
358  bool descriptivename) const = 0;
359 
360  // Enable box picking or lasso picking, depending on what's currently
361  // selected.
362  void enablePicker(UI_Event *event);
363  void disablePicker();
364 
365  void disableActivePicking() { myActivePicking = false; }
366  bool isActivePicking() const { return myActivePicking; }
367 
368  virtual void handleBoxPick(UI_Event *event);
369  virtual void activeBoxPick(UI_Event *event);
370  virtual void handleLassoPick(UI_Event *event);
371  virtual void activeLassoPick(UI_Event *event);
372  virtual void handleBrushPick(UI_Event *event);
373  virtual void activeBrushPick(UI_Event *event);
374  virtual void handleLaserPick(UI_Event *event);
375  virtual void activeLaserPick(UI_Event *event);
376  bool visibleSelectToggle(UI_Event *event,
377  const char *echo_hotkey);
378  bool containedSelectToggle(UI_Event *event,
379  const char *echo_hotkey);
380 
381  // Gets the current time from the OP_Director.
382  static fpreal getTime();
383 
384  /// @{
385  /// Obtains the proxy representative used as a reference holder to this
386  /// selector. This proxy gets invalidated when the selector gets deleted.
387  /// Invalidation clears the proxy's pointer to NULL, but the proxy's memory
388  /// stays valid, unlike the memory of this selector object.
389  ///
390  /// Sample usage:
391  /// void Subclass::method()
392  /// {
393  /// ProxyHandle this_proxy(getProxy());
394  /// methodThatMayDeleteThis();
395  /// if( !this_proxy->isValid() )
396  /// return; // abort
397  /// }
398  ProxyHandle getProxy() { return ProxyHandle(myProxy); }
399  ConstProxyHandle getProxy() const { return ConstProxyHandle(myProxy); }
400  /// @}
401 
402  // Drawable selection
403  const UT_StringArray& drawableMask() const override;
404  void onLocateDrawableSelection() override;
405 
406  unsigned drawablePickMask(unsigned pick_mask) const;
407  bool filterDrawable(const char* drawable_name) const;
408 
409 private:
410  Proxy *myProxy;
411  DM_Workbench *myWorkbench;
412 
413  UI_Value *myFinishedValue;
414  UI_Value *myLocatedValue;
415  UI_Value *mySelectionStyle;
416  UI_Value *myVisiblePickValue;
417  UI_Value *myContainedPickValue;
418  UI_Value *mySelectionRule;
419 
420  SI_RubberBox *myPickBox; // for box selection
421  SI_Lasso *myPickLasso; // for lasso selection
422  SI_Brush *myPickBrush; // for brush selection
423  SI_Brush *myPickLaser; // for laser selection
424 
425  DM_SelectMode myPreferredSelectMode;
426  bool myAllowDragging;
427  bool myAllowFinishingFlag;
428  bool myAllowFinishWithExistingSelection;
429  bool myAllowQuickSelect;
430  bool myAllowEmptyQuickSelect;
431  bool myJustDisplayedOpFlag;
432  bool myActivePicking;
433 
434  UT_StringMap<UT_IntArray> myPriorObjSelections;
435  bool myCreatedPriorSelections;
436 
437  static bool thePickingMenuOn;
438  static bool theAllowUseExistingSelection;
439  static bool theSelectFullLoops;
440 
441  // Drawable selection
442  bool myDrawableSelectableFlag;
443  UT_StringArray myDrawableMask;
444 };
445 
446 /// This reference counted proxy class allows code to check whether a
447 /// particular selector has been destroyed.
448 ///
449 /// See OP3D_InputSelectorBase::getProxy() for usage details.
450 class OP3D_API OP3D_InputSelectorBase::Proxy
451 {
452 public:
453  /// Returns true if the proxy is still pointing to a valid selector.
454  bool isValid() const
455  { return mySelector != NULL; }
456 
457  /// @private
458  /// This interface should only be used by the intrusive pointer handles
459  inline void intrusive_ptr_add_ref() const { incref(); }
460  inline void intrusive_ptr_release() const { decref(); }
461  /// @}
462 private:
463  explicit Proxy(OP3D_InputSelectorBase *selector);
464  ~Proxy();
465 
466  /// Makes the selector reference invalid. This is necessary to do when the
467  /// selector gets deleted.
468  void invalidate(); // only GA_AttributeSet calls it
469  /// Ask the proxy to register a new reference, which essentially
470  /// increments the reference counter.
471  void incref() const;
472  /// Ask the proxy to unregister a reference, which essentially
473  /// decrements the reference counter. When the reference decreases to
474  /// zero the proxy object gets deleted.
475  void decref() const;
476 
477  OP3D_InputSelectorBase *mySelector;
478  mutable SYS_AtomicInt32 myReferenceCount;
479 
481 };
482 
483 /// @{
484 /// Boost function callbacks for referencing and unreferencing the proxy.
485 static inline void
486 intrusive_ptr_add_ref(const OP3D_InputSelectorBase::Proxy *proxy)
487 {
488  proxy->intrusive_ptr_add_ref();
489 }
490 
491 static inline void
492 intrusive_ptr_release(const OP3D_InputSelectorBase::Proxy *proxy)
493 {
494  proxy->intrusive_ptr_release();
495 }
496 /// @}
497 
498 #endif
BM_View & baseViewer()
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
static int compare(const OP3D_PickId *id1, const OP3D_PickId *id2)
void setSelectionStylePtr(UI_Value *new_value)
virtual void setViewer(BM_View *viewer)
UT_Array< GU_SelectionHandle > OP3D_SelectionHandles
UI_Value * getSelectionRulePtr() const
UI_Value * getVisiblePickPtr() const
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
OP3D_SelectionAction
UI_Value * getFinishedValuePtr() const
DM_SelectMode getPreferredSelectMode() const
void setAllowFinishing(bool allow_finishing)
GLint y
Definition: glcorearb.h:103
virtual const UT_StringArray & drawableMask() const
virtual bool handleTransitoryKey(const UI_Event &event, int)
virtual bool getStateParmNames(UT_StringArray &ret, const char *prefix=nullptr)
GLuint buffer
Definition: glcorearb.h:660
Temporary container for either a RV_Render and an RE_Render.
const UI_Value & finishedValue() const
const OP3D_View & viewer() const
UT_Array< OP3D_PickId > OP3D_PickIdArray
ConstProxyHandle getProxy() const
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
IMATH_HOSTDEVICE constexpr int cmp(T a, T b) IMATH_NOEXCEPT
Definition: ImathFun.h:84
bool isValid() const
Returns true if the proxy is still pointing to a valid selector.
struct _cl_event * event
Definition: glcorearb.h:2961
virtual bool setStateParm(const char *name, const UT_StringHolder &val)
virtual bool canSelectDrawables() const
void setFinishedValuePtr(UI_Value *new_value)
void setPreferredSelectMode(DM_SelectMode selmode)
GU_SelectionRule
Definition: GU_SelectType.h:40
UI_Value * getContainedPickPtr() const
Wrapper around hboost::intrusive_ptr.
static void setPickingMenuOn(bool val)
DM_SelectMode
Definition: DM_Defines.h:113
static void setAllowUseExistingSelection(bool val)
GLuint const GLchar * name
Definition: glcorearb.h:786
bool operator==(const OP3D_PickId &cmp) const
SI_Brush * getPickBrushPtr() const
virtual int handleMouseWheelEvent(UI_Event *event)
GLint GLenum GLint x
Definition: glcorearb.h:409
const DM_Workbench & workbench() const
void setContainedPickPtr(UI_Value *new_value)
bool operator!=(const OP3D_PickId &cmp) const
DM_SelectionStyle selectionStyle() const
virtual void doRender(RE_RenderContext r, int x, int y, int ghost)
void setVisiblePickPtr(UI_Value *new_value)
UI_Value * getSelectionStylePtr() const
void selectionRule(GU_SelectionRule srule)
SI_Lasso * getPickLassoPtr() const
fpreal64 fpreal
Definition: SYS_Types.h:283
GU_SelectionRule selectionRule() const
virtual void onLocateDrawableSelection()
GLuint GLfloat * val
Definition: glcorearb.h:1608
#define OP3D_API
Definition: OP3D_API.h:10
virtual void startSelecting()
UT_IntrusivePtr< Proxy > ProxyHandle
virtual UI_Feel * getCustomToolbox() const
GLboolean r
Definition: glcorearb.h:1222
virtual void stopSelecting()
static bool getAllowUseExistingSelection()
void setSelectionRulePtr(UI_Value *new_value)
GLuint * ids
Definition: glcorearb.h:652
virtual bool evalStateParm(const char *name, UT_StringHolder &ret)
SI_Brush * getPickLaserPtr() const
state
Definition: core.h:2289
UI_Value * getLocatedValuePtr() const
static void setSelectFullLoops(bool val)
UT_IntrusivePtr< const Proxy > ConstProxyHandle
DM_SelectionStyle
Definition: DM_Defines.h:54
void setLocatedValuePtr(UI_Value *new_value)
virtual bool pressStateButton(const char *name)
virtual const char * cursor() const