HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OP3D_InputSelector.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_InputSelector.h
7  *
8  * COMMENTS:
9  * This descendant of BM_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_InputSelector_h__
15 #define __OP3D_InputSelector_h__
16 
17 #include "OP3D_API.h"
18 #include "OP3D_InputSelectorBase.h"
19 #include "OP3D_SelectionManager.h"
20 #include "OP3D_GUSelectionSet.h"
21 #include <UI/UI_HotkeyHelper.h>
22 #include <OP/OP_DataTypes.h>
23 #include <PI/PI_ClassManager.h>
24 #include <GEO/GEO_PrimTypeCompat.h>
25 #include <GU/GU_SelectionSet.h>
27 #include <UT/UT_Rect.h>
28 #include <UT/UT_Map.h>
29 #include <RE/RE_RenderContext.h>
30 
31 class GU_SelectResult;
32 class GUI_DisplayOption;
33 class OP_Network;
34 class DM_HeldHotkeyCache;
35 class OP3D_InputSelectorUndoWorker;
36 class OP3D_EdgeLoopHelper;
37 class OP3D_PatternSelectHelper;
38 class SOP_Node;
39 class GA_Attribute;
40 class GR_DisplayOption;
41 
43 
45 {
50 };
51 
53 {
55  myGeoIndex(-1), myOpId(-1),
56  myIsSelectionSetOwner(false),
57  myIsSelected(false), myIsLocalScope(true) {}
58 
60  { return mySelectionSet->selection(myActiveType); }
62  { return myActiveType; }
63 
64  void updateProxy(GU_SelectionHandle sel, bool create);
65  GUI_DetailLook *getLook() const;
66 
67 
69  int myOpId;
70  // The index within the geolook.
71  // TODO: The DOP data name is probably more useful.
73 
76 
77  // The auto converted selection is set if we had to convert to an allowed
78  // selection type in selectorFinished() and should be cleared whenever we
79  // respond to a selection type change event.
81 
84 
85  // Proxy which represents the binding between the GUI_DetailLook and
86  // our selection. Manages our reference to the GUI_DetailLook, and
87  // the look's reference to the active selection.
89 
91  // A flag tracking whether this selection info is part of the active
92  // selection. The selector holds onto existing selection infos when
93  // the associated node geometry stops being displayed so that it can
94  // pick up where it left off if the geometry is displayed again, but
95  // these are not part of the active selection.
98 };
99 
101 {
102 public:
103 
104  OP3D_InputSelector(OP3D_View &viewer, PI_SelectorTemplate &templ);
105  ~OP3D_InputSelector() override;
106 
107  const char *className() const override;
108 
109  // This selector has the ability to locate components.
110  int hasLocates() const override
111  { return 1; }
112 
113  // The selector handles mouse events and modifies the selection
114  // accordingly. Return 1 if the event was consumed and 0 otherwise.
115  int handleMouseEvent(UI_Event *event) override;
116 
117  // Handle double-click events. Returns true if handled.
118  bool handleDoubleClickEvent(UI_Event *event) override;
119 
120  void getKeyResolveInfo(UI_KeyResolveInfo &info) override;
121 
122  // Selectors respond to keyboard events to know when to finish a selection
123  // stage and possibly enter the next.
124  int handleKeyEvent(int key, UI_Event *event,
125  DM_Viewport &viewport) override;
126  bool handleTransitoryKey(const UI_Event &event,
127  int hotkey_id) override;
128  bool willHandleKeyEvent(int key, UI_Event *event);
129 
130  // Is the selector required to attach an input node to the current
131  // node? If it is but nothing was selected, an empty model sop will
132  // be attached. By default, an input is not required.
133  bool inputRequired() const { return myInputRequiredFlag; }
134  void setInputRequired(bool onoff)
135  { myInputRequiredFlag = onoff; }
136 
137  // Some sops (eg. group and delete) need a '*' in the input field if
138  // everything is selected. Other sops will operate on everything if
139  // the input field is blank.
141  { return myUseAsteriskToSelectAll; }
142  void setUseAsteriskToSelectAll(bool onoff)
143  { myUseAsteriskToSelectAll = onoff;}
144 
145  // Specifies whether or not to use primitive id's when selecting edges.
146  // This setting allows the selector to distinguish between a general edge
147  // (e.g p0-1) and an edge on a primitive (e.g. 0e1)
148  void setUsePrimsInEdgeSelections(bool use_prims)
149  { myUsePrimsInEdgeSelectionFlag = use_prims; }
150 
151  // Specifies whether the selector can guess and return edge rings based
152  // on the choice of end elements or should always stick to edge loops.
153  void setAllowEdgeRingSelection(bool allow)
154  { myAllowEdgeRingSelection = allow; }
155 
156  // Specifies whether the selector can guess and return edge rings based
157  // on the choice of end elements or should always stick to edge loops.
159  { myOffsetVertexMarkersOverride = offset; }
160 
161  // Get or set the primitive mask used for picking. The virtual primMask
162  // overrides DM_InputSelector which allows DM_Viewport to access the
163  // primitive mask for pre-selection highlighting.
165  primMask() const override
166  { return myPrimMask; }
168  { myPrimMask = primmask; }
169 
170  // A selector can optionally be "sloppy" whereby the user can initially
171  // pick any of the component types allowed by getSelectionAllowedTypes(),
172  // regardless of the selection type UI value. Once a component has been
173  // picked in this mode, only components of that type can be picked until
174  // the selections are cleared or a pick occurs as a GU_ReplaceSelect.
175  //
176  // The component type of area select operations when a component has not
177  // yet been picked is determined by the selection type UI value.
178  //
179  // The selection type UI values can be used in this mode to convert the
180  // current selection and are also automatically updated by the selector
181  // as the user picks different component types.
182  //
183  // NB: setSloppy() should be called after setSelectionAllowedTypes().
184  void setSloppyPick(bool on);
185  bool getSloppyPick() const
186  { return mySloppyPick; }
187 
188  // Restrict sloppy picks to a subset of getSelectionAllowedTypes(). Must
189  // be called after setSloppyPick(true) in order to have an effect.
190  //
191  // Note that this only restricts the subset of component types allowed for
192  // sloppy picks and will not affect the current selection, even when it is
193  // of a type we're excluding.
194  bool restrictSloppyAllowedTypesToSubset(
195  const PI_GeometryTypeArray &types);
196 
197  // Some selectors allow picking components at the object level.
198  void setPickAtObjLevel(bool flag)
199  { myPickAtObjLevelFlag = flag; }
200  bool getPickAtObjLevel() const
201  { return myPickAtObjLevelFlag; }
202 
203  // The selector needs to be notified when it starts/stops selecting
204  // so it can add/remove interests (the selection type, etc.).
205  void startSelecting() override;
206  void stopSelecting() override;
207  void restartWithStashedSelection();
208 
209  // Commit the pre-selection in the viewport to a geometry selection.
211  GU_SelectionRule sel_rule) override;
212 
213  // Return a list of looks from which we can select.
214  void getSelectableLooks(GUI_DetailList &looklist) override;
215 
216  // Add the cook selection, if any, from the specified SOP to our current
217  // selection.
218  bool addCookedSelection(SOP_Node *sop);
219 
220  // The selector needs to know the node for which it is reselecting so that
221  // it can properly place visibility operators.
222  void nodeIdForReselecting(int node_id)
223  { myNodeIdForReselecting = node_id; }
224 
225  // Clear the selections of the selection. This method is called when,
226  // for example, the selection stages are aborted.
227  virtual void clearSelections();
228 
229  // Consume the user selections made for this selector by clearing any
230  // correponding selections stashed in the selection manager/cache and
231  // clear our selection infos.
232  virtual void consumeSelections();
233 
234  // Remove the selections we assigned to detail looks.
235  void removeSelectionsFromDetailLooks();
236 
237  // NB: This method is normally called automatically in stopSelecting().
238  // You should be careful calling it explicitly. The stash shares
239  // pointers with this selector instance, so it's not a good idea to
240  // call this method if you expect to continue to use this instance
241  // without restarting it.
242  void stashPendingSelection();
243 
244  // This method allows the resource manager can set the workbench to
245  // something different if a selector is reused. It should not be used
246  // otherwise. A nil pointer is allowed so the select can remove any
247  // of its interests. However, methods of the selector should never be
248  // called when its workbench is nil. The method is virtual so
249  // descendants can also have a chance to clean up.
250  void setViewer(BM_View *viewer) override;
251 
252  // This method must be called after retrieving a new/recycled selector
253  // from the resource manager.
254  void setSelectionUIValues(UI_Value *sel_type,
255  UI_Value *sel_rule,
256  UI_Value *sel_style,
257  UI_Value *sel_visible,
258  UI_Value *sel_contained,
259  UI_Value *sel_full,
260  UI_Value *locate_always,
261  UI_Value *finished,
262  UI_Value *located=nullptr);
263 
264  // Any nodes created by this selector are tagged with the creator state's
265  // name.
266  void setCreatorStateName(const char *state_name)
267  { myCreatorStateName.harden(state_name); }
269  { return myCreatorStateName; }
270 
271  // Can this selector use a box or lasso for picking, or just click picks?
272  void setAllowDragSelect(bool allow_drag)
273  { myAllowDragSelFlag = allow_drag; }
274 
275  // Should this selector only select the full geometry?
276  void setSelectFullGeometry(bool select_full)
277  { myFullSelFlag = select_full; }
278 
279  // Should this selector start with the existing selection, if any? The
280  // cook group will be used for the chosen SOP if true and there is no
281  // applicable pending temporary selection. In some cases, you'll want
282  // to control whether we use existing temp or cook selections separately.
283  void setUseExistingSelection(bool use_existing)
284  {
285  setUseExistingTempSelection(use_existing);
286  setUseExistingCookSelection(use_existing);
287  }
288  bool useExistingSelection() const
289  {
290  return useExistingTempSelection() ||
291  useExistingCookSelection();
292  }
293 
294  // Should this selector start with the existing temporary selection,
295  // if any?
296  void setUseExistingTempSelection(bool use_existing)
297  { myUseExistingTempSelection = use_existing; }
299  { return myUseExistingTempSelection; }
300 
301  // Should this selector start with the cook selection for the chosen SOP
302  // either if useExistTempSelection() is false or there was no applicable
303  // pending temporary selection.
304  void setUseExistingCookSelection(bool use_existing)
305  { myUseExistingCookSelection = use_existing; }
307  { return myUseExistingCookSelection; }
308 
309  // TODO: Rename to setExportUserSelectionOnFinish().
310  void setStashSelectionOnFinish(bool stash)
311  { myStashSelectionOnFinish = stash; }
313  { return myStashSelectionOnFinish; }
314 
315  void setAllowMultiPickLoopStart(bool allow)
316  { myAllowMultiPickLoopStart = allow; }
317 
318  // Set an initial selection for the given op path.
319  //
320  // If useExistingTempSelection() or useExistingCookSelection() is true,
321  // then this initial selection will be in addition to those selections,
322  // and may even overwrite them entirely. Any number of op paths can be
323  // set. Only the op paths that exist within the selector context will
324  // have their initial selection set.
325  void setInitialSelection(const char *op_path,
327  const char *selection_string);
328 
329  // Should this selector save undo information?
330  void setSaveUndos(bool yesno) { mySaveUndosFlag = yesno; }
331  bool saveUndos() const { return mySaveUndosFlag; }
332 
333  // Generate merge(s) and connect them to the given op, filling in the
334  // specified input parm with the selection. If there is a menu in the
335  // op that needs to be set and menu_idx is not null, the value menu_idx
336  // points to will be set to a non-negative index into the menu. If menu_idx
337  // is not null but there is no menu, *menu_idx = -1.
338  // If the selection consists of the entire gdp, the group field
339  // is filled with an empty string. To force it to be filled
340  // with a string (even for the entire gdp), use force_selection_string.
341  // An array of the previous input nodes may optionally be provided to
342  // suppress the automatic repositioning of new_node when it is simply
343  // reconnected to the same inputs.
344  bool connectOps(OP_Node &new_node, int op_input_index,
345  const UT_String &input_parm,
346  int *menu_idx = 0,
347  bool branch_off = false,
348  bool multi_input = false,
349  bool force_selection_string = false,
350  bool force_numeric = false,
351  const UT_IntArray *prev_input_nodes = 0);
352 
353  /// Some convenience methods for managing mySelectedInfoIndices.
354  void addSelectedInfo(int info_i, bool set_pick_order=true);
355  void removeSelectedInfo(int info_i);
356 
357  /// Update our internal selection cache and the detail look, if any, with
358  /// the provided selection.
359  int updateSelection(const char *path, OP_Node *node,
360  GUI_DetailLook *look, int geo_idx,
362  const GU_Detail &gdp);
363 
364  /// Returns the current set of ops that have selections on them using this
365  /// selector. The size of the array matches that of the array returned by
366  /// \c selectedselections and \c selectedAutoConvertedSelections.
367  UT_StringArray selectedOpPaths() const;
368 
369  /// Returns the current set of selection objects used to mark the
370  /// component selection for each op used for selection. The size of this
371  /// array matches that of the array returned by \c selectedOpPaths.
372  ///
373  /// In many cases you should use \c selectedAutoConvertedSelections
374  /// instead of this method.
375  OP3D_SelectionHandles selectedSelections() const;
376 
377  /// Returns the current set of auto converted (to the best allowed
378  /// selection type) selection objects for each op used for selection.
379  /// The size of this array matches that of the array returned by
380  /// \c selectedOpPaths.
381  //
382  /// The conversion is done in selectorFinished(), so if this method is
383  /// called before this it is identical to calling selectedSelections().
384  /// Typically you'll want to use this method wherever you call either
385  /// getGeometryTypeAtFinish() or getGroupTypeMenuValAtFinish(). Unlike
386  /// selectedSelections(), entries may be empty or even NULL.
387  OP3D_SelectionHandles selectedAutoConvertedSelections() const;
388 
389  /// Returns a selection handle, given an op path. If the selector is not
390  /// holding a matching op path, then an empty handle is returned.
391  GU_SelectionHandle selectionFromOpPath(UT_StringRef path,
392  bool only_selected=true) const;
393 
394  /// Returns a selection handle, given an info key. If the selector is not
395  /// holding a matching info, then an empty handle is returned.
396  class InfoKey;
397  GU_SelectionHandle selectionFromInfoKey(const InfoKey &key,
398  bool only_selected=true) const;
399 
400  // Returns whether this selector has a non-empty selection instance.
401  bool hasNonEmptySelection() const;
402 
403  // Return the stored selection for the specified geometry, or, if none,
404  // return the selection of the specified type passed in new_selection,
405  // if any, or return an entirely new selection of the specified type
406  // and set new_selection to point to it.
407  GU_SelectionHandle getOrCreateSelection(int node_id, int detail_index,
408  int &info_i,
409  GU_SelectionHandle &new_selection,
410  GA_GroupType sel_type);
411  GU_SelectionHandle getExistingSelection(int node_id, int detail_index,
412  int &info_i,
413  GA_GroupType sel_type);
414 
415  // The state needs to be able to get the current prompt and set the default
416  // prompt. The custom message is for the selector, and the default message
417  // is displayed by the state. The default prompt is passed on by the state
418  // and should not be changed. If you make the const versions public and
419  // the non-const versions private it won't compile, so they're all public.
420  const UT_String &currentPrompt() const { return myCurrentPrompt; }
421  UT_String &currentPrompt() { return myCurrentPrompt; }
422  const UT_String &defaultPrompt() const { return myDefaultPrompt; }
423  UT_String &defaultPrompt() { return myDefaultPrompt; }
424 
425  // Clean up when selector is about to transmit done event. If drag is
426  // true, the selector indicates to the state that the selection should
427  // be dragged right away.
428  void selectorFinished(bool drag = false);
429 
430  // Create an object merge for the given object-sop combination, or combine
431  // the given path into the network if do_combine is true. In that case,
432  // the sop path and selection instance is updated to point to the moved
433  // sop.
434  static SOP_Node *createObjectMerge(OP_Network *network,
435  UT_String &path,
437  const UT_String &creator_state_name,
438  bool keep_original_objects,
439  bool display_origina_objects);
440 
441  // Override the undo worker that gets used for undos. Pass in NULL to use
442  // a default worker.
443  void setUndoWorker(OP3D_InputSelectorUndoWorker *worker=0);
444  // Sets and returns a default undo worker.
445  OP3D_InputSelectorUndoWorker *getDefaultUndoWorker();
446 
447  // Return the feel containing the RMB menu.
448  UI_Menu *getSelectorMenu() const override;
449  UI_Menu *getSelectorHotkeyMenu() const override;
450 
451  void setValidForPickFilter(void *data,
453 
454  // Get or set the current selection type or selection rule explicitly.
455  // Setting the selection type will change the selection type for all
456  // displayed geometry and all geometry that has been selected.
457  void setGeometryType(PI_GeometryType geo_type,
458  bool update_buttons);
459  GA_GroupType selectionType() const;
460 
461  // Get the component type as it was set when the selection was completed.
462  PI_GeometryType getGeometryTypeAtFinish() const;
463  int getGroupTypeMenuValAtFinish() const;
464  bool getKeepOriginalObjects() const;
465 
466  // Query if the selector is currently updating the geometry selection
467  // type button. This can be useful in determining if the selector is
468  // responsible for a given selection type change notification sent by
469  // the workbench.
470  bool currentlyUpdatingGeometryTypeButtons() const;
471 
472  const PI_GeometryTypeArray &getSelectionAllowedTypes() const;
473  void setSelectionAllowedTypes(
474  const PI_GeometryTypeArray &allowedtypes);
475 
476  // Call this method to query the next best allowed selection type when the
477  // given type is not allowed. Returns PI_GEOTYPE_INVALID when we have no
478  // explicit preference among the allowed selection types.
479  PI_GeometryType getNextBestAllowedType(
480  PI_GeometryType disallowed_type) const;
481 
482  // Call this method to query the allowed selection type to use for the
483  // given type. The failure_type is returned if there are no preferred
484  // allowed selection types for the given type.
485  PI_GeometryType mapToAllowedType(
487  PI_GeometryType failure_type
488  = PI_GEOTYPE_INVALID) const;
489 
490  // This function uses the below static function to generate a single
491  // selection string for all selections merged into a single detail.
492  //
493  // If consume_selections is true, the selections will be removed from
494  // this selector and the viewer's selection cache.
495  void generateAllSelectionStrings(UT_String &sel_string,
496  bool only_one_gdp,
497  bool force_numeric,
498  bool consume_selections) override;
499  static void generateMergedSelectionString(UT_String &sel_string,
500  UT_StringArray &paths,
501  OP3D_SelectionHandles &selections,
502  bool ordered,
503  bool collapse,
504  bool use_ast_to_select_all,
505  bool force_numeric);
506 
507  // A utility method to get a pick record representing the current loop
508  // start pick with the component indices mapped into a detail composed
509  // by merging all the selected details. Returns true on success, false
510  // otherwise. The record will be cleared on failure. The look ID and
511  // detail index returned in the GR_PickRecord are meaningless. We are
512  // unable to export the component info when myLoopStartPickPath is not
513  // in the list of selected paths.
514  bool getPostMergeLoopStart(GR_PickRecord &pick);
515 
516  // A method for bootstrapping the current loop start pick, typically with
517  // a pick derived from an earlier selector. Only the geometry component
518  // data is relevant in the supplied GR_PickRecord.
519  void bootstrapLoopStart(const char *path,
520  const GR_PickRecord &pick,
521  bool only_selected_path);
522 
523  // This method is used by HOM to replace the current selection for a
524  // particular component type.
525  void scriptReplaceSelection(
526  PI_GeometryType geo_type,
527  const UT_StringArray &paths,
528  OP3D_SelectionHandles &selections);
529 
530  // Convert to a particular geometry selection from the given list of
531  // objects
532  static bool createSelectionFromObjects(
533  const OP_NodeList &objects,
534  DM_Viewport &viewport,
535  PI_GeometryType geo_type,
536  UT_StringArray &paths,
537  OP3D_SelectionHandles &selections);
538 
539  bool getStateParmNames(
540  UT_StringArray &ret,
541  const char* prefix = nullptr) override;
542  bool evalStateParm(
543  const char *name,
544  UT_StringHolder &ret) override;
545  bool setStateParm(
546  const char *name,
547  const UT_StringHolder &val) override;
548  bool pressStateButton(const char *name) override;
549 
550  // Override to allow rendering widgets.
551  void doRender(RE_RenderContext r, int x, int y,
552  int ghost) override;
553 
554 
556  {
557  public:
558  InfoKey(int node_id, int detail_index)
559  : myNodeId(node_id), myDetailIndex(detail_index)
560  {
561  }
562  bool operator==(const InfoKey &key) const
563  {
564  return myNodeId == key.myNodeId &&
565  myDetailIndex == key.myDetailIndex;
566  }
567  int getNodeId() const { return myNodeId; }
568  int getDetailIndex() const { return myDetailIndex; }
569 
570  private:
571  int myNodeId;
572  int myDetailIndex;
573  };
574 
575  using LocateFilter = std::function<bool(DM_Viewport *)>;
577  { myLocateFilter = filter; }
578 
580  HeldHotkeyCacheUPtr &getHeldHotkeyCache() { return myHeldHotkeyCache; }
581 
582 protected:
583  // React to the user pressing a button to change the component type.
584  virtual void handleSelectionTypeChange(UI_Event *event);
585 
586  /// Called when selection finishes and we need to stash away the group
587  /// menu index that gets set for the target operator of this selector.
588  virtual void updateGroupMenuValue(PI_GeometryType geo_type,
589  int &group_menu_type) = 0;
590 
591  // Called when the selection changes and nothing is removed. Added_geo is
592  // a pointer to the added geometry, allowing derived classes to process it
593  // if they so wish.
595  const char *path,
596  GU_SelectionHandle sel,
597  GU_SelectResult &added_geo)
598  { }
599 
600  // Handle a pick during which nothing was selected. Return true if
601  // any changes were made to the existing selections.
602  virtual bool handleNoPick(UI_Event *event);
603 
604  // Insert additional nodes between the last created node and the
605  // state's node.
606  virtual void appendToLastNode(SOP_Node *&/*input_node*/,
607  const UT_String &/*creator_state_name*/,
608  bool /*branch_off*/) {}
609 
610  // Add additional input nodes for the new node.
611  virtual void generateAdditionalInputNodes(SOP_Node & /*new_node*/,
612  SOP_Node * /*last_selected_node */,
613  const UT_String & /*sel_string*/,
614  const UT_String & /*creator_state_name*/) {}
615 
616  // Modify default parameters if necessary.
617  virtual void setNodeParameters(OP_Node &) {}
618 
619  // Return the pick masks to be used for single or area picks. These masks
620  // are a function of the current selection type for all non-sloppy (normal)
621  // selectors, and both the current selection type and the current selection
622  // state for sloppy selectors. These are the masks used to select entities
623  // that the selection knows how to handle.
624  int singlePickMask(GU_SelectionRule sel_rule) const;
625  int areaPickMask(GU_SelectionRule sel_rule) const;
626 
627  // Return the pick mask to be set in the workbench to control the automatic
628  // display of useful visual markers.
629  int displayPickMask() const;
630 
631  // THESE TWO METHODS ARE DEPRECATED.
632  // Overriding selection type in this manner is dangerous as there
633  // is no guarantee the button bar will remain disabled.
634  // If you find yourself wanting to use this (ie: MSS_JoinSelector)
635  // your selector is likely a state in disguise.
636 
637  // This method is called to overwrite UI values. Disables the
638  // toolbox which allows the user to change the values.
639  void overrideSelectionValues(int sel_type, int sel_rule,
640  int sel_style, int sel_full,
641  int locate);
642  // Restore the values indicated by the UI.
643  void restoreSelectionValues();
644 
645  // Save the contents of the selector so later changes can be undone/redone.
646  void saveForUndo() override;
647 
648  // Implements the getPickName function to return the string representation
649  // of a pick id.
650  bool getPickName(const OP3D_PickId &pickid,
651  UT_String &name,
652  bool descriptivename) const override;
653 
654  // Override the base class needObjectPick() method to add support for our
655  // getPickAtObjLevel() flag.
656  bool needObjectPick() const override;
657 
658  // Clear the selections of all the gdp's with selections in them.
659  // This method is called when failing to select something at all.
660  bool emptySelections(const char *path_to_skip = 0,
661  bool refresh = true);
662 
663  // Delay the selection dirty opChanged calls
665  {
666  public:
667  virtual ~DirtySelectionScope();
668  void delayDirtySelection(SOP_Node *s);
669 
670  private:
672  };
673  // Mark this selection as dirty so that the SOP node and the viewport
674  // will be properly refreshed with the new selection state.
675  void dirtySelection(SOP_Node *sop_node, DirtySelectionScope *scope);
676  void dirtySelection(const GUI_DetailLook &geo_look, int geo_idx, DirtySelectionScope *scope);
677  void dirtySelection(const OP3D_SelectionInfo &sel_info, DirtySelectionScope *scope);
678 
679 
680 
681  // Clear mySelectionInfos as well as mySelectedInfoIndices.
682  void clearSelectionInfos();
683 
684  // Clear mySelectedInfoIndices, but keep mySelectionInfos.
685  void clearSelectedInfoIndices();
686 
687  // Utility method to compute the next unused pick order from our current
688  // selections.
689  int computeNextPickOrder(GA_GroupType sel_type) const;
690 
691  int findInfo(int node_id, int detail_index) const;
692  int findInfo(const char *path) const;
693 
694 
695 private:
696  void handleStartSelecting(UI_Event *event);
697 
698  // Rather than putting the undo code in this file, it's in a friend class.
699  friend class OP3D_InputSelectorUndo;
700 
701  void getPickableGeometry(GUI_DetailList &geos,
702  bool objects_only) const;
703 
704  // Return true if the selection has changed and false otherwise.
705  bool singleSelectGeometry(UI_Event *event,
706  bool save_undo,
707  bool selecting_loop,
709  bool boxSelectGeometry(UI_Event *event,
710  int xcenter, int ycenter,
711  int xsize, int ysize);
712  bool lassoSelectGeometry(UI_Event *event,
713  int *lasso_points);
714  bool brushSelectGeometry(UI_Event *event,
715  uint8 *enablemap,
716  int minx, int miny,
717  int maxx, int maxy,
718  bool visible_only,
719  bool contained_only);
720  bool singleSelectObject(UI_Event *event,
721  UT_Array<GR_PickRecord> &pick_records);
722 
723  // Use the contents of the pick buffer to modify the selections. Return
724  // true if the selection has changed and false otherwise.
725  bool modifySelections(UI_Event *event,
726  const UT_Array<GR_PickRecord> &pick_records,
727  GU_SelectionRule sel_rule);
728 
729  /// Handles a toggle from the "Select Whole Geometry" menu option
730  void fullSelectionChanged(UI_Event *);
731 
732  // Select everything that's visible in the viewport, select nothing, or
733  // toggle the selections of everything in the viewport.
734  void selectAllOrNoneOrToggle(OP3D_SelectionAction action,
735  DM_Viewport &viewport);
736 
737  // Revert the current selection to only the cook selection on the current
738  // node.
739  void revertToCookSelection(DM_Viewport &viewport);
740 
741  // Select the boundary of the current selection. This means
742  // everything which is selected and has a neighbour which is
743  // unselected.
744  void selectBoundary(DM_Viewport &viewport);
745  void selectEdgeBoundary(DM_Viewport &viewport);
746  void shrinkSelection(DM_Viewport &viewport);
747  void growSelection(DM_Viewport &viewport);
748  void selectPrimitivesWithVertexCount(
749  DM_Viewport &viewport,
750  const char *command_name,
751  GA_Size min_vtx, GA_Size max_vtx);
752 
753  using PatternExpandFunc = bool (OP3D_PatternSelectHelper::*)
754  (const GU_Detail &,
757  void patternSet(DM_Viewport &viewport);
758  void patternExpand(DM_Viewport &viewport,
759  PatternExpandFunc func,
761 
762  // Select everything that's visible in the uv viewport, but only if the
763  // face has a specific winding (orientation).
764  void uvSelectAllByWinding(DM_Viewport &viewport,
765  bool front_facing,
766  bool back_facing);
767 
768  void convertSelection(DM_Viewport &viewport,
769  GA_GroupType target_type);
770 
771  bool handlePick(UI_Event *event,
772  const UT_Array<GR_PickRecord> &in_pick_records,
773  GU_SelectionRule sel_rule,
774  bool &added_something);
775 
776  void handleBoxPick(UI_Event *event) override;
777  void activeBoxPick(UI_Event *event) override;
778  void handleLassoPick(UI_Event *event) override;
779  void activeLassoPick(UI_Event *event) override;
780  void handleBrushPick(UI_Event *event) override;
781  void activeBrushPick(UI_Event *event) override;
782  void handleLaserPick(UI_Event *event) override;
783  void activeLaserPick(UI_Event *event) override;
784 
785  // Respond to the user using the selection visibility menu in the toolbar.
786  void handleSelectionHideOrExpose(UI_Event *event);
787 
788  // Should we allow picking from this GUI_DetailLook? (eg. Templates
789  // can't be picked from, and ordered selectors need to pick from the
790  // merges, even if the inputs of the merges are displayed.)
791  bool validForPickRender(GUI_DetailLook *detail,
792  const GUI_DisplayOption &dopt) const;
793 
794  // A higher level method than validForPickRender(), used to consolidate
795  // additional common restrictions.
796  //
797  // TODO: Merge with validForPickRender().
798  bool allowPickOperation(GUI_DetailLook *detail,
799  const GUI_DisplayOption &dopt) const;
800 
801  UT_Array<const OP3D_SelectionInfo *> getNonEmptySelectedInfos() const;
802 
803  // Is any of the geometry visible on the screen selected?
804  bool isAnythingSelected();
805 
806  // Create and connect a visibility sop to modify the visibility of geometry
807  // in the specified sop. Returns the newly created sop, if any, and a flag
808  // indicating whether the visibility sop was inserted above the specified
809  // sop instead of below.
810  SOP_Node *createAndConnectVisibilitySop(SOP_Node *sop,
811  bool *inserted_above);
812 
813  // Set the parameters in the visibility sop to match the action being
814  // performed.
815  void setVisibilitySopParameters(SOP_Node &visibility_sop,
816  bool exposing,
817  bool applying_to_selection,
818  bool cumulative,
819  const UT_String &sel_string);
820 
821  OP3D_EdgeLoopHelper &getEdgeLoopHelper();
822 
823  OP3D_PatternSelectHelper &getPatternSelectHelper(int sop_node_id,
824  int geo_idx);
825 
826  SOP_Node *getChosenSOP() const;
827 
828  SOP_Node * findChosenSop(bool &need_object_pick);
829  void handleSwitchToChosenOp(UI_Event *event);
830 
831  void doneNormalSelection();
832 
833  bool areaSelectGeometry(UI_Event *e,
834  const UT_DimRect &area,
835  uint8 *mask,
836  unsigned pick_mask,
838  bool visible_only,
839  bool contained,
840  bool add_to_existing_picks);
841 
842  // A wrapper around DM_Viewport::adoptLocatedItems() that also handles any
843  // necessary communication with DM_GroupInfo.
844  //
845  // Returns if the viewport located items have changed.
846  bool adoptLocatedItems(DM_Viewport *viewport,
848  UT_Array<GR_PickRecord> &faded_items,
849  bool force_locate = false);
850 
851  // Add any pending (i.e. saved temporary selections) for visible (and
852  // pickable) geometry in the viewer. Returns whether any non-empty
853  // selections were added. We also set have_chosen_sop_temp_sel flag
854  // to indicate if we found any non-null pending selection for the chosen
855  // SOP, including an empty one.
856  bool initWithPendingSelectionForVisibleOps(
857  SOP_Node *chosen_sop,
858  bool &have_chosen_sop_temp_sel);
859 
860  void autoConvertToFinishGeometryType();
861 
862  void addInitialSelections();
863 
864  void handleGeoChanged(UI_Event *event);
865 
866  void updateSelectMask();
867 
868  // Reset mySloppyPickMask from myAllowedTypes.
869  void resetSloppyPickMask();
870 
871  // Update the set sloppy selection type, if any, to the specified type.
872  void updateExistingSloppySelectionType(
873  GA_GroupType sel_type);
874 
875  // Initialize an unset sloppy selection type from the given pick records
876  // and selection rule.
877  void initSloppySelectionType(
878  const UT_Array<GR_PickRecord> &pick_records,
879  GU_SelectionRule sel_rule);
880 
881  // Set the sloppy selection type to the specified type along with any
882  // extra book-keeping.
883  void setSloppySelectionType(
884  GA_GroupType sel_type);
885 
886  static OP_Node * mergeViaCombine(fpreal t,
887  OP_Network *network,
888  UT_String &path,
890  const UT_String &creator_state_name);
891 
892  bool acceptKey(int key, UI_Event *event);
893  bool fullSelectionKey(int key, UI_Event *event);
894  bool selectByNormalKey(int key, UI_Event *event);
895  bool keepOriginalObjKey(int key, UI_Event *event);
896  bool locateKey(int key, UI_Event *event);
897  bool selectAllKey(int key, UI_Event *event);
898  bool invertSelectionKey(int key, UI_Event *event);
899  bool selectNoneKey(int key, UI_Event *event);
900  bool revertToCookSelectionKey(int key, UI_Event *event);
901  bool selectBoundaryKey(int key, UI_Event *event);
902  bool selectEdgeBoundaryKey(int key, UI_Event *event);
903  bool shrinkSelectionKey(int key, UI_Event *event);
904  bool growSelectionKey(int key, UI_Event *event);
905  bool patternSetKey(int key, UI_Event *event);
906  bool patternForwardKey(int key, UI_Event *event);
907  bool patternBackwardKey(int key, UI_Event *event);
908  bool patternLeftKey(int key, UI_Event *event);
909  bool patternRightKey(int key, UI_Event *event);
910  bool patternForwardToEndKey(int key, UI_Event *event);
911  bool patternBackwardToEndKey(int key, UI_Event *event);
912  bool patternLeftToEndKey(int key, UI_Event *event);
913  bool patternRightToEndKey(int key, UI_Event *event);
914  bool selectUVSelectAllFrontKey(int key, UI_Event *event);
915  bool selectUVSelectAllBackKey(int key, UI_Event *event);
916  bool visibleSelectToggleKey(int key, UI_Event *event);
917  bool containedSelectToggleKey(int key, UI_Event *event);
918  bool doubleClickJumpToObjectKey(int key, UI_Event *event);
919  bool redoSelectionKey(int key, UI_Event *event);
920  bool selectNextGroupKey(int key, UI_Event *event);
921  bool selectPrevGroupKey(int key, UI_Event *event);
922  bool copyCurrentGroupNameKey(int key, UI_Event *event);
923  bool copyCurrentSelectionKey(int key, UI_Event *event);
924 
925  bool selectionConvertPointKey(int key, UI_Event *event);
926  bool selectionConvertEdgeKey(int key, UI_Event *event);
927  bool selectionConvertPrimitiveKey(int key, UI_Event *event);
928  bool selectionConvertVertexKey(int key, UI_Event *event);
929  bool selectionConvertBreakpointKey(int key,
930  UI_Event *event);
931 
932  bool selectPrimitiveTrianglesKey(int key, UI_Event *event);
933  bool selectPrimitiveQuadsKey(int key, UI_Event *event);
934  bool selectPrimitiveNgonsKey(int key, UI_Event *event);
935 
936  void handleLocatedPickComplete(UI_Event *event);
937  void handleMouseActionComplete();
938 
939  // Use a seed pick to expand to new picks by normal. Adds new
940  // components to the pick if its normal is within the spread angle
941  // tolerance from the normal of the base pick.
942  void expandPickByNormal(
943  UT_Array<GR_PickRecord> &new_picks,
944  const GR_PickRecord &base_pick,
945  const GU_Detail &gdp,
946  fpreal spread_angle,
947  bool pick_all_matching_normals,
948  bool use_static_reference_normal,
949  const GU_SelectionHandle & prev_selection);
950 
951  // Use a seed pick to expand to new picks by flood filling. Finds
952  // islands of unselected geometry for selection, and/or islands of
953  // selected geometry for deselection.
954  void expandPickByFloodFill(
955  UT_Array<GR_PickRecord> &new_picks,
956  const UT_Array<GR_PickRecord> &seed_picks,
957  const GU_Detail &gdp,
959  GU_SelectionRule rule);
960 
961  // Utility method to update myLoopStartPick to refer to the detail look
962  // corresponding to myLoopStartPickPath when necessary, and, optionally,
963  // note the fact that we've done this in myLoopStartPickRecordMatchesPath
964  // when we expect it to remain synchronized over an extended operation.
965  void updateLoopStartPickRecordFromPath(
966  bool record_match_state);
967 
968  bool selectFromSingleRecord(UI_Event *event,
969  const GR_PickRecord &pick,
970  GU_SelectionRule sel_rule);
971 
972  void addInfoLookup(const OP3D_SelectionInfo &sel_info,
973  int sel_info_index);
974 
975  const GA_Attribute *getUVAttrib(const GU_Detail *gdp);
976  bool areVerticesOfSamePoint(
977  const UT_Array<GR_PickRecord> &pick_records);
978 
979  void extendVertexPickRecords(
980  const UT_Array<GR_PickRecord> &pick_records,
981  UT_Array<GR_PickRecord> &extended_pick_records);
982 
983  // Drawable selection related methods
984  void pickRender(
985  RE_RenderContext rc,
986  const GR_DisplayOption * /*opt*/,
987  unsigned int /*pick_type*/,
988  GR_PickStyle /*pick_style*/,
989  bool /*has_pick_map*/,
990  UT_Array<GR_PickRecord> * /*records*/);
991 
992  // Hotkey methods
993  static UI_HotkeyHelper::Entry theHotkeyList[];
994 
995  UI_HotkeyHelper myHotkeyHelper;
996  DM_Viewport *myHotkeyViewport;
997 
998  UT_String myCurrentPrompt;
999  UT_String myDefaultPrompt;
1000 
1001  UT_String myCreatorStateName;
1002 
1003  UI_Value *myGeoChangedValue;
1004  UI_Value *mySelectionTypeValue; // prims, points, etc.
1005  UI_Value *myFullSelection; // select whole gdp
1006  UI_Value *myAlwaysLocate; // always do locating
1007 
1008  // A selector can optionally be "sloppy" as described in the comment for
1009  // setSloppyPick(), whereby the user can pick any of the component types
1010  // allowed by mySloppyPickMask (automatically built from myAllowedTypes).
1011  // Once a component is picked in this mode, mySloppySelectionType will be
1012  // set and only components of that type can be selected until selections
1013  // are cleared.
1014  unsigned mySloppyPickMask;
1015  GA_GroupType mySloppySelectionType;
1016  GA_GroupType mySloppyFallbackSelectionType;
1017  bool mySloppyPick;
1018  bool mySloppySelectionTypeIsSet;
1019 
1020  // When overriding the values indicated by the UI buttons for the
1021  // above, keep previous values so we can restore.
1022  bool myCustomSelValFlag;
1023  int mySavedSelType;
1024  int mySavedSelRule;
1025  int mySavedSelStyle;
1026  int mySavedFullSel;
1027  int mySavedAlwaysLocate;
1028 
1029  GEO_PrimTypeCompat::TypeMask myPrimMask; // polygon, nurbs, etc.
1030 
1031  // NB: The relative order of the selection infos only matters when the
1032  // individual selections have the same pick order set.
1033  UT_Array<OP3D_SelectionInfo> mySelectionInfos;
1034  UT_Map<InfoKey, int> mySelectionInfoLookup;
1035 
1036  UT_IntArray mySelectedInfoIndices;
1037  int myNextPickOrder;
1038 
1040  ScopeKey myScope;
1041 
1042  int myLastMouseDown; // needed for changed events
1043  int myLastMouseStartX; // " " " "
1044  int myLastMouseStartY; // " " " "
1045 
1046  bool myResizingCursor; // Cursor resize drag active.
1047 
1048  int myNodeIdForReselecting;// reselecting for this node
1049 
1050  bool myUseExistingTempSelection;
1051  bool myUseExistingCookSelection;
1052  bool myStashSelectionOnFinish;
1053  bool myInputRequiredFlag; // is an input op required?
1054  bool myAllowDragSelFlag; // allow box/lasso selecting?
1055  bool myFullSelFlag; // do only full selections?
1056  bool mySaveUndosFlag; // save undo information?
1057  bool myUseAsteriskToSelectAll; // use '*' to select all?
1058  bool myUsePrimsInEdgeSelectionFlag; // use primitives when
1059  // selecting edges (e.g. 0e1)
1060  bool myPickAtObjLevelFlag; // pick geo at OBJ level
1061  bool myAllowEdgeRingSelection;
1062  int myOffsetVertexMarkersOverride;
1063  int myOffsetVertexMarkersSaved;
1064 
1065  // Flag to track whether the auto converted selections stored in the
1066  // selection info have been set.
1067  bool myAutoConvertedSelectionsFlag;
1068 
1069  // After we finish selecting we must remember our type.
1070  PI_GeometryType myFinishGeometryType;
1071  int myFinishGroupTypeMenuVal;
1072 
1073  // Component type of current selection.
1074  PI_GeometryType myCurrentComponentType;
1075 
1076  // A flag to track whether this selector is currently updating the geometry
1077  // type buttons in setGeometryType().
1078  bool myUpdatingGeometryTypeButtons;
1079 
1080  bool myHadDoubleClick;
1081 
1082  struct InitialSelection
1083  {
1085  int index;
1086  UT_StringHolder selection_string;
1087  };
1088  UT_StringMap<InitialSelection> myInitialSelections;
1089 
1090  OP3D_InputSelectorUndoWorker *myUndoWorker;
1091  bool myOwnUndoWorker;
1092  PI_GeometryTypeArray myAllowedTypes;
1093 
1094  HeldHotkeyCacheUPtr myHeldHotkeyCache;
1095 
1096  // Utility for edge loops. The loop start pick is persistent across
1097  // multiple locate events, and so myLoopStartPickPath should be used
1098  // to identify the geometry to use with myLoopStartPick instead of
1099  // myLoopStartPick.getLookId() and myLoopStartPick.getDetailIndex().
1100  // To help avoid unnecessary lookups using the path, we track when
1101  // we've already updated the myLoopStartPick record to match the path
1102  // across extended operations in myLoopStartPickRecordMatchesPath.
1103  OP3D_EdgeLoopHelper *myEdgeLoopHelper;
1104  UT_String myLoopStartPickPath;
1105  GR_PickRecord myLoopStartPick;
1106  GR_PickRecord myLoopPrevPick;
1107  bool myLoopStartPickOnlyLocated;
1108  bool myLoopStartPickRecordMatchesPath;
1109  OP3D_ValidForPickFilter myValidForPickFilter;
1110  void *myValidForPickFilterData;
1111 
1112  LocateFilter myLocateFilter = nullptr;
1113  bool myAllowMultiPickLoopStart = false;
1114 
1115  // A map from SOP node ID and detail handle index to a helper class for
1116  // pattern selections.
1117  UT_Map<std::pair<int, int>, OP3D_PatternSelectHelper*> myPatternHelpers;
1118 
1119  // Drawable selection
1120  GUI_DetailLookPtr myDrawablePicker;
1121 };
1122 
1123 #endif
type
Definition: core.h:556
GT_API const UT_StringHolder selection
const UT_String & creatorStateName()
Definition of a geometry attribute.
Definition: GA_Attribute.h:203
UT_StringHolder myOpPath
myNodes
Definition: UT_RTreeImpl.h:708
GUI_GUSelectionProxyHandle myProxy
Unsorted map container.
Definition: UT_Map.h:114
bool operator==(const InfoKey &key) const
GU_SelectionHandle selection() const
virtual void generateAllSelectionStrings(UT_String &sel_string, bool only_one_gdp, bool force_numeric, bool consume_selections)
void startSelecting() override
virtual UI_Menu * getSelectorHotkeyMenu() const
UT_SharedPtr< GUI_GUSelectionProxy > GUI_GUSelectionProxyHandle
GLboolean * data
Definition: glcorearb.h:131
std::function< bool(DM_Viewport *)> LocateFilter
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
virtual bool handleDoubleClickEvent(UI_Event *event)
OP3D_SelectionAction
bool useExistingTempSelection() const
HeldHotkeyCacheUPtr & getHeldHotkeyCache()
void setAllowEdgeRingSelection(bool allow)
GLdouble s
Definition: glad.h:3009
void setUseAsteriskToSelectAll(bool onoff)
PI_GeometryType
GLint y
Definition: glcorearb.h:103
void stopSelecting() override
bool handleTransitoryKey(const UI_Event &event, int hotkey_id) override
void setSaveUndos(bool yesno)
Temporary container for either a RV_Render and an RE_Render.
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:243
void updateProxy(GU_SelectionHandle sel, bool create)
virtual int handleMouseEvent(UI_Event *event)
OutGridT const XformOp bool bool
GA_GroupType myActiveType
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
struct _cl_event * event
Definition: glcorearb.h:2961
bool inputRequired() const
unsigned char uint8
Definition: SYS_Types.h:36
void setInputRequired(bool onoff)
virtual void generateAdditionalInputNodes(SOP_Node &, SOP_Node *, const UT_String &, const UT_String &)
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
virtual int handleKeyEvent(int key, UI_Event *event, DM_Viewport &viewport)=0
void nodeIdForReselecting(int node_id)
GLintptr offset
Definition: glcorearb.h:665
bool setStateParm(const char *name, const UT_StringHolder &val) override
GU_SelectionRule
Definition: GU_SelectType.h:40
void setPrimMask(GEO_PrimTypeCompat::TypeMask primmask)
void setViewer(BM_View *viewer) override
void setUseExistingTempSelection(bool use_existing)
GLint GLuint mask
Definition: glcorearb.h:124
UT_String & currentPrompt()
UT_String & defaultPrompt()
virtual UI_Menu * getSelectorMenu() const =0
GA_API const UT_StringHolder drag
GLuint const GLchar * name
Definition: glcorearb.h:786
int hasLocates() const override
void doRender(RE_RenderContext r, int x, int y, int ghost) override
void setStashSelectionOnFinish(bool stash)
void setPickAtObjLevel(bool flag)
GLint GLenum GLint x
Definition: glcorearb.h:409
UT_SharedPtr< GU_Selection > GU_SelectionHandle
InfoKey(int node_id, int detail_index)
GLdouble t
Definition: glad.h:2397
void setUseExistingCookSelection(bool use_existing)
void setUseExistingSelection(bool use_existing)
Contains transitional objects to provide some backward compatibility for code that references old GEO...
GUI_DetailLook * getLook() const
virtual void addToSelection(UI_Event *event, const char *path, GU_SelectionHandle sel, GU_SelectResult &added_geo)
GLenum func
Definition: glcorearb.h:783
bool pressStateButton(const char *name) override
fpreal64 fpreal
Definition: SYS_Types.h:283
GA_GroupType
An ordinal enum for the different types of groups in GA.
Definition: GA_Types.h:167
GLuint index
Definition: glcorearb.h:786
OP3D_PatternDirection
void setOffsetVertexMarkersOverride(bool offset)
virtual void commitViewportPreSelection(UI_Event *event, GU_SelectionRule sel_rule)
bool getStashSelectionOnFinish() const
const UT_String & currentPrompt() const
void setUsePrimsInEdgeSelections(bool use_prims)
GLuint GLfloat * val
Definition: glcorearb.h:1608
GA_GroupType selectionType() const
UT_UniquePtr< DM_HeldHotkeyCache > HeldHotkeyCacheUPtr
bool getPickAtObjLevel() const
virtual void appendToLastNode(SOP_Node *&, const UT_String &, bool)
#define OP3D_API
Definition: OP3D_API.h:10
OP3D_SelectionManager::ComponentScopeKey ScopeKey
UT_SharedPtr< OP3D_GUSelectionSet > OP3D_GUSelectionSetHandle
const char * className() const override
virtual void setNodeParameters(OP_Node &)
void setAllowDragSelect(bool allow_drag)
GEO_PrimTypeCompat::TypeMask primMask() const override
GLsizei GLenum GLenum * types
Definition: glcorearb.h:2542
GLboolean r
Definition: glcorearb.h:1222
const UT_String & defaultPrompt() const
GU_SelectionHandle myAutoConvertedSelection
void setLocateFilter(LocateFilter filter)
virtual void getKeyResolveInfo(UI_KeyResolveInfo &info)=0
virtual void getSelectableLooks(GUI_DetailList &look_list)
bool useExistingSelection() const
OP3D_GUSelectionSetHandle mySelectionSet
bool getSloppyPick() const
void setCreatorStateName(const char *state_name)
bool evalStateParm(const char *name, UT_StringHolder &ret) override
void setAllowMultiPickLoopStart(bool allow)
Definition: format.h:1821
GA_API const UT_StringHolder area
bool useAsteriskToSelectAll() const
bool getStateParmNames(UT_StringArray &ret, const char *prefix=nullptr) override
bool(* OP3D_ValidForPickFilter)(void *data, GUI_DetailLook *look)
bool useExistingCookSelection() const
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glcorearb.h:1297
GR_PickStyle
Definition: GR_Defines.h:257
void setSelectFullGeometry(bool select_full)