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