HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GU_Selection.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: GU_Selection (C++)
7  *
8  * COMMENTS:
9  * Base class of a gdp selection. This clas hides the actual type
10  * of selection (point, edge, primitive, etc)
11  *
12  */
13 
14 #ifndef __GU_Selection_h__
15 #define __GU_Selection_h__
16 
17 #include "GU_API.h"
18 #include "GU_SelectType.h"
19 #include "GU_Detail.h"
20 
21 #include <GA/GA_Breakpoint.h>
22 #include <GA/GA_Edge.h>
23 #include <GA/GA_GroupTypeTraits.h>
24 #include <GA/GA_Types.h>
25 
26 class GA_BreakpointGroup;
27 class GEO_Primitive;
28 class GU_Detail;
29 class GU_Selection;
30 class UT_JSONWriter;
31 class UT_JSONParser;
32 
34 {
35 public:
37  : myPrimitive(0),
38  myPoint(GA_INVALID_OFFSET),
39  myVertex(GA_INVALID_OFFSET),
40  myDetail(0),
41  myGroupType(GA_GROUP_INVALID),
42  mySelectedNormal(false)
43  {}
45 
46  void setSelectedNormal(bool selected_normal)
47  { mySelectedNormal = selected_normal; }
48 
50  { return myBreakpoint; }
51  const GA_Edge &getEdge() const
52  { return myEdge; }
53  const GA_Primitive *getPrimitive() const
54  { return myPrimitive; }
55 
56  const GU_Detail *getDetail() const
57  { return myDetail; }
59  { return myPoint; }
60 
62  { return myVertex; }
63 
64  bool isSet() const
65  { return myGroupType != GA_GROUP_INVALID; }
67  { return myGroupType; }
68  bool getSelectedNormal() const
69  { return mySelectedNormal; }
70 
71  void clear()
72  {
73  myGroupType = GA_GROUP_INVALID;
74  mySelectedNormal = false;
75  }
76 
77 protected:
78  friend class GU_BreakpointSelection;
79  friend class GU_EdgeSelection;
80  friend class GU_PointSelection;
81  friend class GU_PrimSelection;
82  friend class GU_VertexSelection;
83  friend class GU_CookSelection;
84 
85  void set(const GA_Breakpoint &b, const GU_Detail *gdp)
86  {
87  myBreakpoint = b;
88  myDetail = gdp;
89  myGroupType = GA_GROUP_BREAKPOINT;
90  }
91  void set(const GA_Edge &e, const GA_Primitive *prim,
92  const GU_Detail *gdp)
93  {
94  myEdge = e;
95  myPrimitive = prim;
96  myDetail = gdp;
97  myGroupType = GA_GROUP_EDGE;
98  }
99  void set(const GA_Primitive *prim, const GU_Detail *gdp)
100  {
101  myPrimitive = prim;
102  myDetail = gdp;
103  myGroupType = GA_GROUP_PRIMITIVE;
104  }
105  void setPoint(GA_Offset ptoff, const GU_Detail *gdp)
106  {
107  myPoint = ptoff;
108  myDetail = gdp;
109  myGroupType = GA_GROUP_POINT;
110  }
111  void setVertex(GA_Offset vtxoff, const GU_Detail *gdp)
112  {
113  myVertex = vtxoff;
114  myDetail = gdp;
115  myGroupType = GA_GROUP_VERTEX;
116  }
117 
118 private:
119  GA_Breakpoint myBreakpoint;
120  GA_Edge myEdge;
121  const GA_Primitive *myPrimitive;
122  GA_Offset myPoint;
123  const GU_Detail *myDetail;
124  GA_Offset myVertex;
125  GA_GroupType myGroupType;
126  bool mySelectedNormal;
127 };
128 
130 {
131 public:
133  { }
135  { }
136 };
137 
139 {
140 public:
141  virtual ~GU_Selection();
142 
143  // Return a new selection of the specified type. The creator prefix and
144  // the suffix are used in naming the primitive and point groups of the
145  // selection.
146  // FIXME: Rename to 'create'
148  static GU_SelectionHandle newSelection(GU_SelectionType stype);
150  static GU_SelectionHandle newSelection(GA_GroupType type);
151  static GU_SelectionHandle newSelection(const GU_Detail &dst_gdp,
152  const GU_Detail &src_gdp,
153  const GU_Selection &src_sel);
154 
155  // NB: Intended for use by GU_Detail only.
156  //
157  // Return a handle to a new GU_CookSelection of the specified type in the
158  // supplied detail.
159  // NB: This selection must be orphaned if still around when this detail
160  // is deleted.
161  static GU_SelectionHandle newCookSelection(GU_Detail &gdp,
162  GA_GroupType type,
163  bool ordered);
164 
165  // NB: Intended for use by GU_Detail only.
166  //
167  // Return a handle to a new GU_CookSelection that references the supplied
168  // group instead of creating one itself. No changes will be made to this
169  // group by the selection. If any changes are necessary to the selection,
170  // it will create a copy of this group first.
171  // NB: This selection must be orphaned if still around when this detail
172  // or group is deleted, so be very careful.
173  static GU_SelectionHandle newCookSelection(GU_Detail &gdp,
174  GA_Group &group);
175 
176  // Copy the contents of one selection to another, doing any conversions
177  // that are necessary. This assumes that they are from the same gdp.
178  virtual void assign(const GU_Detail &src_gd,
179  const GU_Selection &src_sel) = 0;
180 
181  // Called by GR_PickSelection to modify this selection based on user
182  // selected components in the viewport. The first edge to be added to us
183  // (if any), is returned in 'added', and so is the pickid unless the
184  // pointer to is is zero.
185  virtual bool select(const GU_Detail &gd,
186  uint id1, uint id2, uint id3,
187  GU_SelectionRule rule,
188  GU_SelectResult &added,
189  GU_SelectFinishData *&finish_data) = 0;
190  // After one or more calls to select(), GR_PickSelection will call
191  // selectFinish to give the selection a change to apply any changes
192  // it stored in the finish_data parameter.
193  virtual bool selectFinish(const GU_Detail &gd,
194  GU_SelectionRule rule,
195  GU_SelectResult &added,
196  GU_SelectFinishData *finish_data)
197  { UT_ASSERT(!finish_data); return 0; }
198 
199  // Determines if the supplied ids represent a valid component within
200  // the existing selection, or that could be added to the selection.
201  virtual bool testSelect(const GU_Detail &gd,
202  uint id1, uint id2, uint id3,
203  bool accept_existing,
204  bool accept_new,
205  GU_SelectResult &result) const = 0;
206 
207  // Find the actual point picked in the selection: this could be a GEO
208  // point, a point on a normal, curve, edge, etc. 'added' indicates
209  // what has been picked. 'pickid' is the type of hit that generated the
210  // pick, and 'xsect' is the picked point (to be found). The methods return
211  // 1 if xsect can be determined and 0 otherwise. If the 'xsect' is not
212  // found, the 2nd method computes the bounding box of 'added' and returns
213  // that one instead.
214  virtual bool selectionPoint(const GU_SelectResult &added,
215  UT_Vector3 &xsect) const = 0;
216  virtual bool selectionPoint(const GU_SelectResult &added,
217  UT_Vector3 rayorig,
218  UT_Vector3 &raydir,
219  UT_Vector3 &xsect,
220  bool &normal,
221  UT_Vector3 &vector,
222  bool accurate,
223  float *u, float *v) const = 0;
224 
225  // Select the contents of the group even if the group type does not
226  // match our type. Return 1 if the selection has changed, 0 otherwise.
227  // Subclasses should implement overrides that intelligently handle
228  // groups that match our selection type.
229  bool modifyGroup(const GU_Detail &gd,
230  const GA_Group &group,
231  GU_SelectionRule rule);
232  // Fairly direct access to the group token list. Use with caution or
233  // you'll end up with a group token list that doesn't match your actual
234  // selection.
235  void modifyGroupToken(const char *token,
236  GU_SelectionRule rule);
237  // Initialize this selection to a combination of groups (named in the
238  // group_string) which have already been combined into a group. This
239  // is used when reselecting a SOP with a group parm containing only
240  // group names.
241  void initGroupString(const GU_Detail &gd,
242  const GA_Group &group,
243  const char *group_string);
244  // Get or control the use of group tokens in this selection.
245  bool getGroupTokenString(UT_WorkBuffer &buf) const;
246  bool getGroupTokensValid() const
247  { return myGroupTokensValid; }
248  // Force the selection to maintain its group token list and valid flag.
249  // This should always be a temporary setting for the duration of one or
250  // more selection changes that are known to preserve the group token
251  // validity.
252  void setGroupTokensLock(bool lock);
253 
254  // Modify a geometric entity on this selection. If the type being modified
255  // does not correspond to the selection type, the selection will
256  // interpret the modification to the best of its abilities (e.g. removing
257  // a point from a primitive selection will remove all primitives that share
258  // that point; adding a point to a primitive selection, will select all
259  // primitives that shared that point; and so forth).
260  virtual bool modifyPoint(const GU_Detail &gd, GA_Offset ptoff,
261  GU_ModifyType type) = 0;
262  virtual bool modifyVertex(const GU_Detail &gd, GA_Offset vtxoff,
263  GU_ModifyType type) = 0;
264  virtual bool modifyPrimitive(const GU_Detail &gd, GA_Offset primoff,
265  GU_ModifyType type) = 0;
266 
267  virtual bool modifyEdge(const GU_Detail &gd, const GA_Edge &edge,
268  const GEO_Primitive *prim,
269  GU_ModifyType type) = 0;
270  virtual bool modifyBreakpoint(const GU_Detail &gd,
271  const GA_Breakpoint &bkp,
272  GU_ModifyType type) = 0;
273 
274  /// Call this method once mass-modifications are finished with the above
275  // modify* methods, but only if any of them returned \c true.
276  void modifyDone(const GU_Detail &gd);
277 
278  // Select all the points in the gdp. Return 1 if the selection has changed
279  // and 0 otherwise.
280  virtual bool selectAll(const GU_Detail &gd) = 0;
281 
282  // Toggle the selection. Return true if something has been toggled and 0
283  // otherwise.
284  virtual bool toggleAll(const GU_Detail &gd) = 0;
285 
286  /// This method is used to select the boundary. Not valid for all selection
287  /// types.
288  virtual bool selectBoundary(const GU_Detail &gd, bool checkuv, const UT_StringHolder &uvattribname = "uv"_UTsh) = 0;
289  virtual bool growSelection(const GU_Detail &gd, bool checkuv, const UT_StringHolder &uvattribname = "uv"_UTsh) = 0;
290  virtual bool shrinkSelection(const GU_Detail &gd, bool checkuv, const UT_StringHolder &uvattribname = "uv"_UTsh) = 0;
291 
292  // Filter the selection based on primitive coverage.
293  virtual bool filterByPrimitiveMask(const GU_Detail &gd,
294  const GA_PrimitiveTypeMask &mask) = 0;
295 
296  // The following methods are used for selected front/back facing faces
297  // (in the UV sense).
298  bool uvSelectAllFrontFace(const GU_Detail &gd, const UT_StringHolder &uvattribname = "uv"_UTsh)
299  { return uvSelectAllByWindingUsingClosure(gd, true, false, uvattribname); }
300  bool uvSelectAllBackFace(const GU_Detail &gd, const UT_StringHolder &uvattribname = "uv"_UTsh)
301  { return uvSelectAllByWindingUsingClosure(gd, false, true, uvattribname); }
302 
303  // Return a group for the current selection.
304  virtual const GA_PointGroup *points(const GU_Detail &gd) const = 0;
305  virtual const GA_PrimitiveGroup *primitives(const GU_Detail &gd) const = 0;
306  virtual const GA_VertexGroup *vertices(const GU_Detail &gd) const = 0;
307  virtual const GA_EdgeGroup *edges(const GU_Detail &gd) const = 0;
308  virtual const GA_BreakpointGroup *breakpoints(const GU_Detail &gd) const = 0;
309 
310  /// These functions provide a fast path to check for existence. They only
311  /// work for the selection type their name indicates they should work for.
312  /// No translation is done for other types and those will return \c false.
313  virtual bool hasPointIndex(GA_Index index) const { return false; }
314  virtual bool hasPrimitiveIndex(GA_Index index) const { return false; }
315  virtual bool hasVertexIndex(GA_Index index) const { return false; }
316  virtual bool hasEdgeIndexPair(GA_Index p0, GA_Index p1) const
317  { return false; }
318  virtual bool hasBreakpointIndexSet(GA_Index prim_index, int u_index,
319  int v_index = -1) const { return false; }
320 
321  // Returns the group containing the selection.
322  virtual const GA_Group *mainGroup(const GU_Detail &gd) const = 0;
323 
324  /// Returns a group for this selection, of the given group type. If the
325  /// selection is not of that type, then the selection will return a
326  /// best-case conversion of the selection from the original type.
327  const GA_Group *group(const GU_Detail &gd,
328  GA_GroupType type);
329 
330  // Just clear the bits of the groups, or destroy the internal groups and
331  // arrays too.
332  virtual void clear();
333  virtual void clearAndDestroy();
334 
335  // How many entries does the selection contain?
336  virtual GA_Size entries() const = 0;
337 
338  // Compute the bounding box of the selection, and return \c false if the box
339  // is empty and \c true otherwise.
340  virtual bool getBoundingBox(const GU_Detail &gd,
341  UT_BoundingBox &bbox) const = 0;
342  virtual bool getBoundingBox(const GU_Detail &gd,
343  UT_BoundingBox &bbox,
344  const UT_Matrix4R &transform) const = 0;
345 
346  // Compute the UV bounding box of the selection, and return \c false if the
347  // box is empty.
348  virtual bool getBoundingBoxUV(const GU_Detail &gd,
349  UT_BoundingBox &bbox,
350  const char *name,
351  int isvertex) const = 0;
352 
353  /// Save/load the contents of the selection
354  bool save(UT_JSONWriter &w) const;
355  bool load(UT_JSONParser &p, bool restore_id_and_rev = true);
356 
357  // Human-readable output of the selection for debugging purposes
358  void dump(std::ostream &os) const;
359 
360  // Query the type of selection:
361  virtual GA_GroupType classType() const = 0;
362 
363  // Creates a duplicate selection identical to this one in the passed in
364  // gdp.
365  virtual GU_Selection *clone() = 0;
366 
367  // Generate a string to represent the selection. This string is formatted
368  // for use in SOP Group parameters. If the selection was built using
369  // group or attribute tokens, those tokesn will be returned unless the
370  // force_numeric field is set to true.
371  bool generateSelectionString(UT_String &sel_string,
372  const GU_Detail &gdp,
373  bool ordered,
374  bool collapse_where_possible,
375  bool use_ast_to_select_all,
376  bool force_numeric,
377  GA_Index prim_offset = 0,
378  GA_Index point_offset = 0) const;
379 
380  // Flags that control edge selections and whether or not they should include
381  // primitive ids. These are only handled by Edge selectors.
382  virtual void setUsePrimEdges(bool /*use_prim_edges*/) { }
383  virtual bool getUsePrimEdges() const { return false; }
384 
385  void setPickPath(const UT_StringHolder &p) { myPickPath = p; }
386  UT_StringHolder pickPath() const { return myPickPath; }
387 
388  void setPickOrder(int pick_order) { myPickOrder = pick_order; }
389  int pickOrder() const { return myPickOrder; }
390  void resetPickOrder() { myPickOrder = -1; }
391 
392  /// Selection id and revision
393  int getId() const { return myId; }
394  int getRevision() const { return myRevision; }
395 
396  /// Return an approximation of how much memory we use
397  virtual int64 getMemoryUsage(bool inclusive) const
398  {
399  int64 mem = inclusive ? sizeof(*this) : 0;
400  mem += myGroupTokens.getMemoryUsage(true);
401  return mem;
402  }
403 
404 protected:
405  /// Validate the current selection against the given detail. This will
406  /// prune out any selection components that are invalid against the detail
407  /// given. Call this prior to, or after, a mass modification via calls to
408  /// modify*(). Those calls do not do any verification of the current
409  /// selection, for performance reasons. Returns \c true if the selection
410  /// was already valid and no entries were eliminated.
411  virtual bool validate(const GU_Detail &gd) = 0;
412 
413  /// Convenience method to make/clear ordered status of a group
414  static inline void setOrdered(GA_ElementGroup &g, bool ordered)
415  {
416  if (ordered)
417  g.makeOrdered();
418  else
419  g.clearOrdered();
420  }
421 
422  GU_Selection(const GU_Selection &s);
423 
424  virtual bool uvSelectAllByWindingUsingClosure(
425  const GU_Detail &gd,
426  bool front_facing,
427  bool back_facing,
428  const UT_StringHolder &uvattribname);
429 
430  virtual bool modifyMatchingGroup(const GU_Detail &gd,
431  const GA_Group &group,
432  GU_SelectionRule rule) = 0;
433 
434  static const GA_PrimitiveGroup *hiddenPrimitives(const GU_Detail &gd);
435 
437  {
438  myRevision++;
439  if (!myGroupTokensLock && myGroupTokensValid)
440  {
441  myGroupTokensValid = false;
442  myGroupTokens.clear();
443  }
444  }
445 
446 protected:
447  // Class constructor and destructor. The prefix is used for naming the
448  // two internal groups, myPoints, myPrims.
449  GU_Selection();
450 
451  /// @}
452  /// @{
453  /// Save/load class specific data elements.
454  virtual bool saveElements(UT_JSONWriter &w) const = 0;
455  virtual bool loadElements(UT_JSONParser &p) = 0;
456  /// @}
457 
458  template<typename T>
459  inline T &getGroup(const GU_Detail &gd, bool &needs_update) const
460  {
461  return static_cast<T &>(getGroup(gd,
463  needs_update));
464  }
465 
466  UT_Lock &updateLock() const { return myUpdateLock; }
467 
468  static GU_Selection *allocSelection(GA_GroupType type);
469 
470 private:
471  GA_Group &getGroup(const GU_Detail &gd,
472  GA_GroupType type, bool &needs_update) const;
473 
474  UT_StringArray myGroupTokens;
475  bool myGroupTokensValid;
476  bool myGroupTokensLock;
477 
478  UT_StringHolder myPickPath;
479  int myPickOrder;
480 
481  int myId;
482  int myRevision;
483 
484  struct GroupCacheEntry
485  {
486  GroupCacheEntry() : myDetailId(-1), myRevision(-1), myElementCount(-1) {}
487  exint myDetailId;
488  int myRevision;
489  GA_Size myElementCount;
490  UT_SharedPtr<GA_Group> myGroup;
491  };
492  typedef UT_Map<GA_GroupType, GroupCacheEntry> GroupCache;
493  mutable GroupCache myGroupCache;
494 
495  mutable UT_Lock myUpdateLock;
496  static SYS_AtomicInt32 theUniqueSelectionId;
497 };
498 
499 #endif
void setSelectedNormal(bool selected_normal)
Definition: GU_Selection.h:46
void resetPickOrder()
Definition: GU_Selection.h:390
bool getSelectedNormal() const
Definition: GU_Selection.h:68
#define SYS_DEPRECATED_PUSH_DISABLE()
const GLdouble * v
Definition: glcorearb.h:836
#define SYS_DEPRECATED_POP_DISABLE()
const GU_Detail * getDetail() const
Definition: GU_Selection.h:56
GLboolean GLboolean g
Definition: glcorearb.h:1221
GLint GLuint mask
Definition: glcorearb.h:123
void clearOrdered()
Clear all order information, including any mixed entries.
JSON reader class which handles parsing of JSON or bJSON files.
Definition: UT_JSONParser.h:72
virtual bool hasBreakpointIndexSet(GA_Index prim_index, int u_index, int v_index=-1) const
Definition: GU_Selection.h:318
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:32
3D Vector class.
GA_Offset getVertexOffset() const
Definition: GU_Selection.h:61
static void setOrdered(GA_ElementGroup &g, bool ordered)
Convenience method to make/clear ordered status of a group.
Definition: GU_Selection.h:414
int getRevision() const
Definition: GU_Selection.h:394
UT_Lock & updateLock() const
Definition: GU_Selection.h:466
UT_StringHolder pickPath() const
Definition: GU_Selection.h:386
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:211
#define GA_INVALID_OFFSET
Definition: GA_Types.h:654
virtual ~GU_SelectFinishData()
Definition: GU_Selection.h:134
GA_Offset getPointOffset() const
Definition: GU_Selection.h:58
GA_Size GA_Offset
Definition: GA_Types.h:617
long long int64
Definition: SYS_Types.h:106
virtual void setUsePrimEdges(bool)
Definition: GU_Selection.h:382
virtual bool hasPointIndex(GA_Index index) const
Definition: GU_Selection.h:313
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:102
GU_SelectionRule
Definition: GU_SelectType.h:40
int64 exint
Definition: SYS_Types.h:115
void set(const GA_Breakpoint &b, const GU_Detail *gdp)
Definition: GU_Selection.h:85
const GA_Edge & getEdge() const
Definition: GU_Selection.h:51
Type traits base class for group type traits.
const GA_Breakpoint & getBreakpoint() const
Definition: GU_Selection.h:49
void setVertex(GA_Offset vtxoff, const GU_Detail *gdp)
Definition: GU_Selection.h:111
bool uvSelectAllFrontFace(const GU_Detail &gd, const UT_StringHolder &uvattribname="uv"_UTsh)
Definition: GU_Selection.h:298
#define GU_API
Definition: GU_API.h:11
GLuint const GLchar * name
Definition: glcorearb.h:785
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1221
GA_Size GA_Index
Define the strictness of GA_Offset/GA_Index.
Definition: GA_Types.h:611
GA_API const UT_StringHolder transform
virtual bool hasPrimitiveIndex(GA_Index index) const
Definition: GU_Selection.h:314
unsigned int uint
Definition: SYS_Types.h:39
T & getGroup(const GU_Detail &gd, bool &needs_update) const
Definition: GU_Selection.h:459
GU_SelectionType
Definition: GU_SelectType.h:29
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2539
bool getGroupTokensValid() const
Definition: GU_Selection.h:246
const GA_Primitive * getPrimitive() const
Definition: GU_Selection.h:53
void updateRevision()
Definition: GU_Selection.h:436
void set(const GA_Edge &e, const GA_Primitive *prim, const GU_Detail *gdp)
Definition: GU_Selection.h:91
png_infop png_sPLT_tpp entries
Definition: png.h:2481
virtual int64 getMemoryUsage(bool inclusive) const
Return an approximation of how much memory we use.
Definition: GU_Selection.h:397
virtual bool hasEdgeIndexPair(GA_Index p0, GA_Index p1) const
Definition: GU_Selection.h:316
void set(const GA_Primitive *prim, const GU_Detail *gdp)
Definition: GU_Selection.h:99
virtual bool getUsePrimEdges() const
Definition: GU_Selection.h:383
GA_GroupType
An ordinal enum for the different types of groups in GA.
Definition: GA_Types.h:138
int getId() const
Selection id and revision.
Definition: GU_Selection.h:393
GLuint index
Definition: glcorearb.h:785
virtual bool hasVertexIndex(GA_Index index) const
Definition: GU_Selection.h:315
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
bool isSet() const
Definition: GU_Selection.h:64
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:856
int pickOrder() const
Definition: GU_Selection.h:389
GU_ModifyType
Definition: GU_SelectType.h:59
GA_GroupType getSelectType() const
Definition: GU_Selection.h:66
void setPickPath(const UT_StringHolder &p)
Definition: GU_Selection.h:385
void setPoint(GA_Offset ptoff, const GU_Detail *gdp)
Definition: GU_Selection.h:105
void setPickOrder(int pick_order)
Definition: GU_Selection.h:388
virtual bool selectFinish(const GU_Detail &gd, GU_SelectionRule rule, GU_SelectResult &added, GU_SelectFinishData *finish_data)
Definition: GU_Selection.h:193
bool uvSelectAllBackFace(const GU_Detail &gd, const UT_StringHolder &uvattribname="uv"_UTsh)
Definition: GU_Selection.h:300