HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GU_Detail.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_Detail.h (GU Library, C++)
7  *
8  * COMMENTS:
9  * Header file for GU_Detail class...
10  *
11  */
12 
13 #pragma once
14 
15 #ifndef __GU_Detail_h__
16 #define __GU_Detail_h__
17 
18 #include "GU_API.h"
19 #include "GU_Error.h"
20 #include "GU_PrimitiveFactory.h"
21 #include "GU_SelectType.h"
22 #include "GU_Types.h"
23 
24 #include <GEO/GEO_Detail.h>
25 #include <GEO/GEO_PrimType.h>
26 #include <GEO/GEO_Primitive.h>
27 #include <GEO/GEO_SurfaceType.h>
28 #include <GEO/GEO_HedgeInterface.h>
29 
30 #include <GA/GA_GroupTypeTraits.h>
31 
32 #include <UT/UT_Array.h>
33 #include <UT/UT_BitArray.h>
34 #include <UT/UT_ErrorManager.h> // for UTgetErrorManager()
35 #include <UT/UT_Matrix.h>
36 #include <UT/UT_Matrix3.h>
37 #include <UT/UT_OBBox.h>
38 #include <UT/UT_ValArray.h>
39 #include <UT/UT_RefMatrix.h>
40 #include <UT/UT_StringArray.h>
41 
42 #include <stddef.h>
43 
44 
45 class IMG_Raster;
46 class UT_Interrupt;
47 class UT_MemoryCounter;
48 template<typename K,typename H,typename P> class UT_Set;
49 
50 class GA_BreakpointGroup;
51 class GA_EdgeGroup;
52 class GA_VertexGroup;
53 class GA_NUBBasis;
55 class GA_OffsetMatrix;
56 class GEO_ConvertParms;
57 class GEO_Curve;
58 class GEO_Face;
60 class GEO_PolySoupParms;
61 class GEO_PrimMesh;
62 class GEO_PrimPoly;
63 class GEO_PrimPolySoup;
65 class GEO_TPSurf;
66 class GEO_Hull;
67 class GEO_IOTranslator;
68 
69 class GU_EdgeDiv;
70 class GU_SplitLoc;
71 class GU_Selection;
72 
73 class GU_PrimPoly;
74 class GU_PrimMesh;
75 class GU_PrimPart;
76 class GU_PrimSphere;
77 class GU_PrimTube;
78 class GU_PrimBlob;
79 class GU_PrimNURBCurve;
80 class GU_PrimNURBSurf;
81 class GU_PrimPolySoup;
82 class GU_PrimRBezSurf;
83 
84 // Parameter classes for methods
85 class GU_AlignParms;
86 class GU_CameraParms;
87 class GU_CapParms;
88 class GU_CapOptions;
89 class GU_CreepParms;
90 class GU_CurveClayParms;
92 class GU_EdgeCreaseParms;
93 class GU_ExtrudeParms;
94 class GU_FilletParms;
95 class GU_GridParms;
96 class GU_JoinParms;
97 class GU_LoftParms;
98 class GU_LSystemParms;
99 class GU_MagnetParms;
100 class GU_ClothMatchSeamsParms;
101 class GU_OffsetParms;
102 class GU_PolyExtrudeParms;
103 class GU_PolypatchParms;
104 class GU_PolyReduceParms;
105 class GU_PolysplineParms;
106 class GU_RailParms;
107 class GU_RevolveParms;
108 class GU_RoundFilletParms;
109 class GU_RuledParms;
110 class GU_SkinParms;
111 class GU_SkinCache;
112 class GU_StitchParms;
113 class GU_SuperQuadParms;
114 class GU_SweepParms;
115 class GU_TorusParms;
116 class GU_TraceParms;
117 class GU_TrimFilletParms;
118 class GU_TwistParms;
120 
121 
122 
124 
125 extern "C" {
126  SYS_VISIBILITY_EXPORT extern void newGeometryIO(void *);
128 }
129 
130 class gu_ValueLookupCache;
131 
133 {
134 public:
135  /// NOTE: Need an explicit default constructor to work around internal
136  /// compiler error in Visual Studio 2015 Update 3.
137  /// See: https://connect.microsoft.com/VisualStudio/feedback/details/2869531
138  GU_Detail() : GU_Detail(true) {}
139  explicit GU_Detail(bool full_topology)
140  : GEO_Detail(GUgetFactory(), full_topology)
141  {
142  construct();
143  }
144  /// See GEO_Detail::merge() for documentation of the data_id_strategy
145  /// argument.
146  explicit GU_Detail(const GU_Detail *src, GA_PrimitiveGroup *primGroup,
147  GA_DataIdStrategy data_id_strategy = GA_DATA_ID_BUMP)
149  {
150  construct();
151  merge(*src, primGroup,
152  /*mergePrimGroup*/1, /*insertPrimsAtHead*/0,
153  /*dest_to_src_ptarray*/0,
154  /*keep_internal_groups*/true,
155  data_id_strategy);
156  }
157  /// See GEO_Detail::copy() for documentation of the data_id_strategy
158  /// argument.
159  explicit GU_Detail(const GU_Detail *src,
160  GA_DataIdStrategy data_id_strategy = GA_DATA_ID_BUMP)
162  {
163  construct();
164  copy(*src, GEO_COPY_ONCE,
165  /*collapse_on_end*/false,
166  /*keep_internal_groups*/true,
167  data_id_strategy);
168  }
169 
170  virtual ~GU_Detail();
171 
172  /// Compute memory usage (includes all shared memory)
173  virtual int64 getMemoryUsage(bool inclusive) const;
174 
175  /// Count memory usage using a UT_MemoryCounter in order to count
176  /// shared memory correctly.
177  /// If inclusive is true, the size of this object is counted,
178  /// else only memory owned by this object is counted.
179  /// If this is pointed to by the calling object, inclusive should be true.
180  /// If this is contained in the calling object, inclusive should be false.
181  /// (Its memory was already counted in the size of the calling object.)
182  virtual void countMemory(UT_MemoryCounter &counter, bool inclusive) const;
183 
184  /// This clears any caches that subclasses of GA_Detail may have, so that
185  /// replacing the content of the detail doesn't cause crashes.
186  virtual void clearCaches();
187 
188  void duplicate(const GU_Detail& gdp, int = 0,
189  GA_DataIdStrategy data_id_strategy = GA_DATA_ID_BUMP);
190 
191  /// Create a new detail that has all the same attributes, groups, etc. but
192  /// has no elements.
193  /// Subclasses should look at: cloneCopyGroupsAndAttributes()
194  virtual GA_Detail *cloneEmptyDetail(bool clone_attributes) const;
195 
196  class RingRef
197  {
198  public:
200  const UT_IntArray &ringvalence)
201  : myRingZero(ringzero)
202  , myRingValence(ringvalence)
203  {
204  }
205 
207  { return myRingZero; }
208  const UT_IntArray & ringValence() const
209  { return myRingValence; }
210 
211  public:
214  };
215 
216  /// This initializes the passed in int array so it is 0 where
217  /// points are a boundary and 1 where they are not a boundary.
218  /// This handles meshes, etc, properly. It doesn't handle non-manifold
219  /// properly. The checkuv flag determines if it should check uv
220  /// boundaries, if set, it will mark as 1 any points which have
221  /// differing UV texture coordinates in their vertices.
222  /// For efficiency, you may call buildRingZero() once and pass the built
223  /// data structures to it.
224  void findBoundaryPoints(
225  UT_BitArray &isboundary,
226  bool checkuv,
227  const RingRef *ringref = nullptr,
228  const UT_StringHolder &uvattribname = "uv"_UTsh) const;
229 
230  /// This takes an array which should be the same size as the number
231  /// of points, and has 1 wherever a point is to be considered
232  /// selected. It then initializes & sets 1 in the isboundary array
233  /// any point which is on the 8-way boundary of the selection.
234  void findSelectionBoundaryPoints(
235  const UT_BitArray &pointselection,
236  UT_BitArray &isboundary) const;
237 
238  /// Fills the ringzero array, (which is indexed by point GA_Index,
239  /// not GA_Offset), with the GA_Offsets of each point's neighbours,
240  /// (i.e. they share an edge in some primitive). It avoids
241  /// duplicates within each point's list of neighbours.
242  /// If ringvalence is non-NULL, it is filled with the number of
243  /// half-edges each point is part of, i.e. including duplicates
244  /// and both directions.
245  void buildRingZeroPoints(
246  UT_Array<GA_OffsetArray> &ringzero,
247  UT_IntArray *ringvalence = 0) const;
248 
249  /// Fills the ringzero array, (which is indexed by point GA_Index,
250  /// not GA_Offset), with the GA_Offsets of each point's neighbours,
251  /// (i.e. they share an edge in some primitive). It avoids
252  /// duplicates within each point's list of neighbours.
253  /// If ringvalence is non-NULL, it is filled with the number of
254  /// half-edges each point is part of, i.e. including duplicates
255  /// and both directions.
256  ///
257  /// In this version, an edge is only counted if it is in a primitive
258  /// in primgroup (if non-NULL). Although only entries for
259  /// points in ptgroup (if non-NULL) are written-to in ringzero
260  /// and ringvalence (if non-NULL), neighbours outside of ptgroup
261  /// will be listed.
262  void buildRingZeroPoints(
263  const GA_PointGroup *ptgroup,
264  UT_Array<GA_OffsetArray> &ringzero,
265  UT_IntArray *ringvalence = 0,
266  const GA_PrimitiveGroup *primgroup = 0) const;
267 
268  /// NOTE: Unlike buildRingZeroPoints, the array in buildRingZeroVertices
269  /// is indexed by GA_Offset, not GA_Index, for simplicity.
270  void buildRingZeroVertices(
271  UT_Array<GA_OffsetArray> &ringzero,
272  const GA_PrimitiveGroup *prims=0) const;
273 
274  void buildRingZeroPrimitives(
275  UT_Array<GA_OffsetArray> &ringzero) const;
276 
277  //
278  // Build various geometries. Returns the first primitive of the new
279  // geometry.
280  //
281 
282  /// Creates a polygon cube in this detail.
283  /// NOTE: Set doConsolidatePoints to true in order to have
284  /// correctly connected polygons. The default behaviour
285  /// produces disconnected sides!
286  GU_PrimPoly *cube(float xmin = -1, float xmax = 1,
287  float ymin = -1, float ymax = 1,
288  float zmin = -1, float zmax = 1,
289  int xdiv = 0, int ydiv = 0, int zdiv = 0,
290  int enforcementBars = 0,
291  int doConsolidatePoints = 0);
292 
293  GU_PrimNURBSurf *nurbCube(int xdiv, int ydiv, int zdiv,
294  int orderx = 4, int ordery = 4, int orderz=4,
295  float xmin = -0.5F, float xmax = 0.5F,
296  float ymin = -0.5F, float ymax = 0.5F,
297  float zmin = -0.5F, float zmax = 0.5F,
299  bool consolidate = false);
300 
301  GU_PrimRBezSurf *bezCube(int xdiv, int ydiv, int zdiv,
302  int orderx = 4, int ordery = 4, int orderz=4,
303  float xmin = -0.5F, float xmax = 0.5F,
304  float ymin = -0.5F, float ymax = 0.5F,
305  float zmin = -0.5F, float zmax = 0.5F,
307  bool consolidate = false);
308 
309  GU_PrimMesh *meshCube(int xdiv, int ydiv, int zdiv,
310  float xmin = -0.5F, float xmax = 0.5F,
311  float ymin = -0.5F, float ymax = 0.5F,
312  float zmin = -0.5F, float zmax = 0.5F,
314  bool consolidate = false);
315 
316  GU_PrimPoly *polymeshCube(int xdiv, int ydiv, int zdiv,
317  float xmin = -0.5F, float xmax = 0.5F,
318  float ymin = -0.5F, float ymax = 0.5F,
319  float zmin = -0.5F, float zmax = 0.5F,
321  bool consolidate = false);
322 
323  /// Creates a grid in this detail based on parms.
324  /// Returns the offset of the first polygon primitive.
327 
328  /// Creates a grid of points in this detail.
329  /// NOTE: If startpoint is valid, it must refer to a *contiguous*
330  /// block of rows*cols point offsets, in which case, this
331  /// just sets point positions, so can be used on polygon
332  /// or polysoup grids with a consistent point order too.
333  /// NOTE: When plane is GU_PLANE_XY, cols corresponds with x, and
334  /// rows corresponds with y.
335  GA_Offset pointGrid(int rows, int cols,
336  float xsize=1, float ysize=1,
337  float xc = 0, float yc = 0, float zc = 0,
339  GA_Offset startpoint=GA_INVALID_OFFSET);
340  /// Creates a grid of polygons in this detail.
341  /// Returns the offset of the first polygon primitive.
342  GA_Offset polyGrid(int rows, int cols,
343  float xsize=1, float ysize=1,
344  float xc = 0, float yc = 0, float zc = 0,
347  /// Creates a grid that is a single polygon soup in this detail.
348  GU_PrimPolySoup *polySoupGrid(int rows, int cols,
349  float xsize=1, float ysize=1,
350  float xc = 0, float yc = 0, float zc = 0,
353  GU_PrimMesh *meshGrid(int rows, int cols,
354  float xsize=1, float ysize=1,
355  float xc = 0, float yc = 0, float zc = 0,
358  int wrapu = 0, int wrapv = 0);
359  GU_PrimNURBSurf *nurbGrid(int rows, int cols,
360  int orderu = 4, int orderv = 4,
361  int interpEndsU = 1, int interpEndsV = 1,
362  float xsize=1, float ysize=1,
363  float xc = 0, float yc = 0, float zc = 0,
366  int wrapu = 0, int wrapv = 0);
367  GU_PrimRBezSurf *bezGrid(int rows, int cols,
368  int orderu = 4, int orderv = 4,
369  float xsize=1, float ysize=1,
370  float xc = 0, float yc = 0, float zc = 0,
373  int wrapu = 0, int wrapv = 0);
374 
375  /// Creates a torus in this detail, based on parms.
376  /// type is one of the values in the enum in GA_PrimitiveTypes.h .
377  /// GA_PRIMPOLY, GA_PRIMPOLYSOUP, GA_PRIMMESH, GA_PRIMBEZSURF,
378  /// and GA_PRIMNURBSURF are supported.
379  void torus(unsigned type, GU_TorusParms &parms);
380 
381  /// poly-iso surfaces
382  /// To find the primitives created, place
383  /// GA_IndexMap::Marker marker(gdp->getPrimitiveMap());
384  /// before the call, and call marker.getRange() afterward.
385  void polyIsoSurface(
386  float (*ptOutside)(const UT_Vector3 &, void *),
387  void *data,
388  const UT_BoundingBox &bbox,
389  int xdiv, int ydiv, int zdiv,
390  bool makepolysoup = false);
391 
392  /// When building a meta-surface, the new surface is built in this
393  /// gdp. If desired, src can be "this" as well...
394  void buildMetaSurface(const GU_Detail *src, float lod,
395  const GA_PrimitiveGroup *primGroup = 0,
396  bool makepolysoup = false);
397 
398  void buildMetaSurface(const GU_Detail *src,
399  int divx, int divy, int divz,
400  const GA_PrimitiveGroup *primGroup = 0,
401  bool makepolysoup = false);
402 
403  /// A faster way of conversion is to build cross sections. However, this
404  /// doesn't build real surfaces
405  void buildMetaXsection(const GU_Detail *src, int nsections,
406  int axis = 2, int maxdepth = 4,
407  const GA_PrimitiveGroup *primGroup = NULL);
408 
409  //
410  // Geometry filters
411  //
412 
413 
414  /// orient all the polygonal faces to have the same winding direction
415  void orient(const GA_PrimitiveGroup *group = 0);
416 
417  /// inset and extrude a face
418  void extrude(GU_ExtrudeParms &parms);
419 
420  /// create a weighted sum of two source inputs
421  /// This bumps data IDs of any attributes that are modified, and of
422  /// the primitive list, if any primitives are modified.
423  void blend(const GU_Detail *source, float weight,
424  bool doPos, bool doClr, bool doNml, bool doTxt,
425  bool doVoxels, bool doSlerp,
426  const char *ptidattr, const char *primidattr);
427 
428 
429  /// create a weighted sum of size source inputs
430  /// Return 1 if at least one pasted surface was involved in the blend,
431  /// else 0.
432  /// This bumps data IDs of any attributes that are modified, and of
433  /// the primitive list, if any primitives are modified.
434  int blend(const GU_Detail *gdps[], const float weights[],
435  int size, bool doPos, bool doClr,
436  bool doNml, bool doTxt,
437  bool doVoxels, bool doSlerp,
438  const char *ptidattr, const char *primidattr,
439  const GA_PointGroup *ptGroup);
440 
441  /// Transform points to follow surface of path input
442  void creep(GU_CreepParms &parms);
443 
444  /// Consolidate points within a specified distance (returns num done)
445  /// If a point group is specified, then, only points in that
446  /// group are consolidated. If the forceConsAll flag is set then
447  /// all points will be consolidated in a greedy fashion using a
448  /// branch and bound algorithm.
449  GA_Size consolidatePoints(fpreal distance,
450  const GA_PointGroup *ptGrp = 0,
451  bool forceConsAll = false,
452  bool mark = false,
453  bool accurate = false);
454 
455  /// Performs fast consolidation by calling onlyConsolidatePoints.
456  /// By default, calls removeUnused when done to remove any unused points
457  /// When deleteConsOnly is set, then only consolidated points are removed.
458  GA_Size fastConsolidatePoints(fpreal distance,
459  const GA_PointGroup *ptGrp=0,
460  bool mark = false,
461  bool accurate = false);
462 
463  /// Specifies methods by which points after consolidation will
464  /// get their group names. ONLYCONS_GRP_PROP_LEAST means that the
465  /// points will belong to the same group as the original point
466  /// with least point number. ONLYCONS_GRP_PROP_UNION means that the
467  /// points will belong to the full set of groups represented
468  /// by the original points (so if orig. point 1 is in group A, B and
469  /// orig. point 2 is in group B, C, the final point will be in A B C).
470  /// INTERSECT means the point will only belong in groups that are common
471  /// to all original points. With the example above, it will belong in
472  /// B.
474  {
475  ONLYCONS_GRP_PROP_LEAST = 0,
477  ONLYCONS_GRP_PROP_INTERSECT
478  };
479  /// This does fast consolidation but does *not* call removeUnused when
480  /// done. This means that degenerate primitives will be left along
481  /// with orphaned points. If deleteconsolidated is set, the consolidated
482  /// points only will be deleted. grouppropagate controls which groups
483  /// the new points will belong to.
484  GA_Size onlyConsolidatePoints(fpreal distance,
485  const GA_PointGroup *ptgrp = 0,
486  bool mark = false,
487  bool deleteconsolidated = false,
488  OnlyConsGroupPropagateType
489  grouppropagate =
490  ONLYCONS_GRP_PROP_LEAST,
491  bool accurate = false);
492 
493  GA_Size consolidateNormals(fpreal distance,
494  const GA_PointGroup *ptGrp = 0,
495  bool forceConsAll = false,
496  bool accurate = false);
497  GA_Size fastConsolidateNormals(fpreal distance,
498  const GA_PointGroup *ptGrp = 0,
499  bool accurate = false);
500  /// Consolidate UV attributes within a specified distance.
501  /// This distance can be in UV space or XYZ space.
502  /// There are various methods of placing the consolidated UVs.
503  ///
504  /// metric: 0 => UV space
505  /// 1 => XYZ space
506  ///
507  /// method: 0 => Average
508  /// 1 => First in Group
509  /// 2 => Specify uvw coordinate
510  int fastConsolidatePointUVs(float distance,
511  const GA_PointGroup &ptGrp,
512  const GU_MetricType metric,
513  int method,
514  UT_Vector3 &uvw);
515  int fastConsolidatePointUVs(const GA_RWHandleV3 &uvattrib,
516  float distance,
517  const GA_PointGroup &ptGrp,
518  const GU_MetricType metric,
519  int method,
520  UT_Vector3 &uvw);
521  int fastConsolidateVertexUVs(float distance,
522  const GA_VertexGroup &vtxGrp,
523  const GU_MetricType metric,
524  int method,
525  UT_Vector3 &uvw);
526  int fastConsolidateVertexUVs(const GA_RWHandleV3 &uvattrib,
527  float distance,
528  const GA_VertexGroup &vtxGrp,
529  const GU_MetricType metric,
530  int method,
531  UT_Vector3 &uvw);
532 
533  /// Snap points within a specified distance (returns num done)
534  /// If a point group is specified, then, only points in that
535  /// group are consolidated.
536  /// Snapping doesn't fuse the points together, just makes their
537  /// positions match.
538  /// The type is 0 for average, 1 for round to lowest point number
539  /// and 2 for highest point number.
540  /// snappointpos controls whether the point positions will be
541  /// snapped.
542  /// snapptattribs can be set to indicate that point attributes
543  /// are to be snapped.
544  /// ptattribhandles is a list of attribute handles for the
545  /// attributes that will be snapped.
546  GA_Size snapPoints(int type, fpreal distance,
547  const GA_PointGroup *ptgrp=0,
548  bool snapptpos = true,
549  UT_Array<GA_Attribute *> *ptattribs = 0,
550  bool accurate = true);
551 
552  /// Methods for snapping attributes (for use with snapAttributes).
553  /// SNAP_ATTRIBUTE_AVERAGE averages the attributes together.
554  /// SNAP_ATTRIBUTE_INDEX tells snapAttributes to use an index
555  /// into the list of snapped points to set the attributes for
556  /// other points.
558  {
559  SNAP_ATTRIBUTES_AVERAGE = 0,
560  SNAP_ATTRIBUTES_INDEX
561  };
562 
563  /// This version of snapping snaps onto grid coordinates. You specify
564  /// the number of lines per HUnit, so "2" for example will snap to 0.5
565  /// boundaries.
566  /// type is 0 for round nearest, 1 for round down, 2 for round up.
567  /// 0.5 rounds up in nearest.
568  void snapGrid(int type,
569  float xlines, float ylines, float zlines,
570  float xoff, float yoff, float zoff,
571  float tol,
572  const GA_PointGroup *ptGrp=0);
573  /// Same as above, but with UVs...
574  void snapGridPointUVs(int type,
575  float xlines, float ylines, float zlines,
576  float xoff, float yoff, float zoff,
577  float tol,
578  const GA_PointGroup *ptGrp=0);
579  void snapGridPointUVs(
580  const GA_RWHandleV3 &uvattrib, int type,
581  float xlines, float ylines, float zlines,
582  float xoff, float yoff, float zoff,
583  float tol,
584  const GA_PointGroup *ptGrp=0);
585  void snapGridVertexUVs(int type,
586  float xlines, float ylines, float zlines,
587  float xoff, float yoff, float zoff,
588  float tol,
589  const GA_VertexGroup *vtxGrp=0);
590  void snapGridVertexUVs(
591  const GA_RWHandleV3 &uvattrib, int type,
592  float xlines, float ylines, float zlines,
593  float xoff, float yoff, float zoff,
594  float tol,
595  const GA_VertexGroup *vtxGrp=0);
596 
597  /// Build holes in the geometry by bridging the holes to their outlines
598  /// The angle should be specified as the angle (in degrees) between
599  /// the normals.
600  int buildHoles(float dist = 0.001F, float angle = 0.2F,
601  int snapFace=0,
602  const GA_PrimitiveGroup *primGroup=0);
603 
604  /// Remove bridged holes from other than polygons
605  void unHole(const GA_PrimitiveGroup *primGroup=0);
606 
607  /// Unique all points in the detail. If a point group is specified,
608  /// then only points in that group are uniqued
609  /// If a primitive group is specified, only those primitives will
610  /// have their points uniqued.
611  void uniquePoints(const GA_PointGroup *group=0);
612 
613  /// Unique all the points that are in this primitive, even if referenced
614  /// by other primitives.
615  void uniquePrimitive(GEO_Primitive *prim);
616 
617  /// Remove repeated references of vertices in the faces, then remove all
618  /// degenerate primitives regardless of their type.
619  /// Set removeRepPoints flag to remove the repeat points as well and
620  /// the deletePoints flag to delete the points that were part of the
621  /// degenerate primitive.
622  GA_Size cleanData (const GA_PrimitiveGroup *primGrp=0,
623  bool removeRepPoints = false,
624  float tol = 0.001F,
625  bool deleteDegenPrimPoints = false,
626  bool deleteOrphanedPoints = false);
627 
628  /// Identify dirty data, which is the degenerate primitives that would
629  /// be deleted by cleanData. Return them in the returnGrp, and return
630  /// the number of dirty primitives. If returnGrp is NULL then only
631  /// return the count.
632  GA_Size getDirtyData (GA_PrimitiveGroup *returnGrp,
633  const GA_PrimitiveGroup *primGrp=0,
634  bool checkRepPoints = false,
635  float tol = 0.001F);
636 
637  /// If the applyToVertex is less than 0, the "natural" place will be use,
638  /// otherwise 0 = point attrib, 1 = vertex attrib
639  /// Returns false if the attribute failed to be created, else true.
640  bool applyTexture(GU_TextureType type, GU_AxisType axis,
641  const GA_PrimitiveGroup *primGroup=0,
642  int applyToVertex = -1, int fixPolySeams = 0,
643  const GU_CameraParms *userData = 0);
644  /// If the applyToVertex is less than 0, the "natural" place will be use,
645  /// otherwise 0 = point attrib, 1 = vertex attrib
646  /// Returns false if the attribute failed to be created, else true.
647  bool applyTexture(const UT_StringRef &uvattribname,
649  const GA_PrimitiveGroup *primGroup=0,
650  int applyToVertex = -1, int fixPolySeams = 0,
651  const GU_CameraParms *userData = 0);
652  /// The scaleTexture() and rotateTexture() methods are depreciated. Please
653  /// use the GU_MODIFY_TEX projection and simply create the approprate
654  /// post-transform.
655  /// Returns false if the attribute failed to be created, else true.
656  bool scaleTexture(float umult = 1, float uoff = 0,
657  float vmult = 1, float voff = 0,
658  float wmult = 1, float woff = 0,
659  const GA_PrimitiveGroup *primGroup=0);
660  bool scaleTexture(const UT_StringRef &uvattribname,
661  float umult = 1, float uoff = 0,
662  float vmult = 1, float voff = 0,
663  float wmult = 1, float woff = 0,
664  const GA_PrimitiveGroup *primGroup=0);
665  bool rotateTexture(float angle,
666  const GA_PrimitiveGroup *primGroup=0);
667  bool rotateTexture(const UT_StringRef &uvattribname,
668  float angle,
669  const GA_PrimitiveGroup *primGroup=0);
670 
671  /// Methods for transforming point and vertex texture attributes:
672  void transformPointTexture(const UT_Matrix4& mat,
673  const GA_PointGroup *ptGroup=nullptr,
674  GEO_Delta *geodelta=0);
675 
676  void transformPointTexture(
677  const GA_RWHandleV3 &pth,
678  const UT_Matrix4& mat,
679  const GA_PointGroup *ptGroup=nullptr,
680  GEO_Delta *geodelta=0);
681 
682  /// Precompute a list of points to soft transform, along with
683  /// the distance (squared) to the closest "hard" point.
684  /// The metric specifies how distance is measured in space.
685  void computeSoftTransformPointTextureCache(
686  GEO_SoftTransformCache &cache,
687  const GA_PointGroup *ptgroup,
688  const GEO_Rolloff &rolloff,
689  const GU_MetricType metric) const;
690 
691  /// Precompute a list of points to soft transform, along with
692  /// the distance (squared) to the closest "hard" point.
693  /// The metric specifies how distance is measured in space.
694  void computeSoftTransformPointTextureCache(
695  const GA_ROHandleV3 &pttxth,
696  GEO_SoftTransformCache &cache,
697  const GA_PointGroup *ptgroup,
698  const GEO_Rolloff &rolloff,
699  const GU_MetricType metric) const;
700 
701  /// falloff_output - any non-zero falloffs used during this call will be
702  /// written to this attribute when provided
703  /// falloff_written - will be set to true when provided if falloff_output
704  /// is provided, and this call did not skip processing
705  /// any non-zero falloffs. If not set, you must call
706  /// computeSoftPointFalloff() to obtain the falloffs.
707  void softTransformPointTexture(
708  const UT_XformOrder &order,
709  float tx, float ty, float tz,
710  float rx, float ry, float rz,
711  float sx, float sy, float sz,
712  float s_xy, float s_xz, float s_yz,
713  float px, float py, float pz,
714  const GEO_SoftTransformCache &cache,
715  const GEO_Rolloff &rolloff,
716  GEO_Delta *geodelta = 0,
717  const GA_RWHandleF *falloff_output = NULL,
718  bool *falloff_written = NULL);
719 
720  /// falloff_output - any non-zero falloffs used during this call will be
721  /// written to this attribute when provided
722  /// falloff_written - will be set to true when provided if falloff_output
723  /// is provided, and this call did not skip processing
724  /// any non-zero falloffs. If not set, you must call
725  /// computeSoftPointFalloff() to obtain the falloffs.
726  void softTransformPointTexture(
727  const GA_RWHandleV3 &ptattr,
728  const UT_XformOrder &order,
729  float tx, float ty, float tz,
730  float rx, float ry, float rz,
731  float sx, float sy, float sz,
732  float s_xy, float s_xz, float s_yz,
733  float px, float py, float pz,
734  const GEO_SoftTransformCache &cache,
735  const GEO_Rolloff &rolloff,
736  GEO_Delta *geodelta = 0,
737  const GA_RWHandleF *falloff_output = NULL,
738  bool *falloff_written = NULL);
739 
740  void transformVertexTexture(const UT_Matrix4& mat,
741  const GA_VertexGroup *vertexGroup=nullptr,
742  GEO_Delta *geodelta=0);
743 
744  void transformVertexTexture(
745  const GA_RWHandleV3 &vtxh,
746  const UT_Matrix4& mat,
747  const GA_VertexGroup *vertexGroup=nullptr,
748  GEO_Delta *geodelta=0);
749 
750  /// Precompute a list of vertices to soft transform, along with
751  /// the distance (squared) to the closest "hard" point.
752  /// The metric specifies how distance is measured in space.
753  /// ignore_uv_connectivity controls whether we affect vertices
754  /// which are not in the same uvw-wise connected component.
755  void computeSoftTransformVertexTextureCache(
756  GEO_SoftTransformCache &cache,
757  const GA_VertexGroup *vtxgroup,
758  const GEO_Rolloff &rolloff,
759  const GU_MetricType metric,
760  bool ignore_uv_connectivity) const;
761 
762  /// Precompute a list of vertices to soft transform, along with
763  /// the distance (squared) to the closest "hard" point.
764  /// The metric specifies how distance is measured in space.
765  /// ignore_uv_connectivity controls whether we affect vertices
766  /// which are not in the same uvw-wise connected component.
767  void computeSoftTransformVertexTextureCache(
768  const GA_ROHandleV3 &vtxh,
769  GEO_SoftTransformCache &cache,
770  const GA_VertexGroup *vtxgroup,
771  const GEO_Rolloff &rolloff,
772  const GU_MetricType metric,
773  bool ignore_uv_connectivity) const;
774 
775  /// falloff_output - any non-zero falloffs used during this call will be
776  /// written to this attribute when provided
777  /// falloff_written - will be set to true when provided if falloff_output
778  /// is provided, and this call did not skip processing
779  /// any non-zero falloffs. If not set, you must call
780  /// computeSoftPointFalloff() to obtain the falloffs.
781  void softTransformVertexTexture(
782  const UT_XformOrder &order,
783  float tx, float ty, float tz,
784  float rx, float ry, float rz,
785  float sx, float sy, float sz,
786  float s_xy, float s_xz, float s_yz,
787  float px, float py, float pz,
788  const GEO_SoftTransformCache &cache,
789  const GEO_Rolloff &rolloff,
790  GEO_Delta *geodelta = 0,
791  const GA_RWHandleF *falloff_output = NULL,
792  bool *falloff_written = NULL);
793 
794  /// falloff_output - any non-zero falloffs used during this call will be
795  /// written to this attribute when provided
796  /// falloff_written - will be set to true when provided if falloff_output
797  /// is provided, and this call did not skip processing
798  /// any non-zero falloffs. If not set, you must call
799  /// computeSoftPointFalloff() to obtain the falloffs.
800  void softTransformVertexTexture(
801  const GA_RWHandleV3 &vtxh,
802  const UT_XformOrder &order,
803  float tx, float ty, float tz,
804  float rx, float ry, float rz,
805  float sx, float sy, float sz,
806  float s_xy, float s_xz, float s_yz,
807  float px, float py, float pz,
808  const GEO_SoftTransformCache &cache,
809  const GEO_Rolloff &rolloff,
810  GEO_Delta *geodelta = 0,
811  const GA_RWHandleF *falloff_output = NULL,
812  bool *falloff_written = NULL);
813 
814  /// This routine will compute the average normal of a group of points.
815  /// Returns true on success and false on failure.
816  /// NOTE: The version that doesn't take a point normal attribute handle
817  /// will temporarily create a detached point normal attribute if a point N
818  /// doesn't already exist. The caller may or may not want to cache
819  /// a detached attribute and pass it in, instead.
820  /// @{
821  bool computeAvgNormal(
822  const GA_PointGroup *group,
823  const GA_ROHandleV3 &normals,
824  UT_Vector3 &avg_normal) const;
825  bool computeAvgNormal(
826  const GA_PointGroup *group,
827  UT_Vector3 &avg_normal) const;
828  /// @}
829 
830  /// Reverse polygons
831  void reversePolys(const GA_PrimitiveGroup *prmGrp=0);
832 
833  /// Conversion Routines - to convert from one primitive to another
834  /// @{
835  void convert(GEO_ConvertParms &parms);
836  void convertNew(GEO_ConvertParms &parms);
837  /// @}
838 
839  /// This routine only converts metaballs using a more comprehensive set
840  /// of parameters.
841  void convertMetaballs(GEO_MetaConvertParms& parms, const GA_PrimitiveGroup* prim_grp = NULL);
842 
843  //
844  // SORTING
845  //
846 
847  /// Sort by the specified dominant axis
848  /// @{
849  void sortPoints(GA_IndexMap &array,
850  GU_AxisType axis = GU_XAXIS);
851  void sortPoints(GA_OffsetArray &array,
852  GU_AxisType axis = GU_XAXIS);
853  void sortPrims(GA_IndexMap &array,
854  GU_AxisType axis = GU_XAXIS);
856  { sortPoints(getIndexMap(GA_ATTRIB_POINT), axis); }
858  { sortPrims(getIndexMap(GA_ATTRIB_PRIMITIVE), axis); }
859  /// @}
860 
861  /// Sorting by spatial locality. The points and primitives will be
862  /// sorted in a way that tries to assign nearby primitives closer
863  /// primitive ids.
864  /// @{
865  void sortPointsSpatial();
866  void sortPrimsSpatial();
867  /// @}
868 
869  /// Sort along an arbitrary vector
870  /// @{
871  void sortPoints(GA_IndexMap &array,
872  const UT_Vector3 &o, const UT_Vector3 &d);
873  void sortPrims(GA_IndexMap &array,
874  const UT_Vector3 &o, const UT_Vector3 &d);
875  void sortPointList(const UT_Vector3 &o, const UT_Vector3 &d)
876  { sortPoints(getIndexMap(GA_ATTRIB_POINT), o, d); }
878  const UT_Vector3 &d)
879  { sortPrims(getIndexMap(GA_ATTRIB_PRIMITIVE), o, d); }
880  /// @}
881 
882  /// Sort in random order
883  /// @{
884  void sortPoints(GA_IndexMap &array, int seed);
885  void sortPrims(GA_IndexMap &array, int seed);
886  void sortPointList(int seed)
887  { sortPoints(getIndexMap(GA_ATTRIB_POINT), seed); }
888  void sortPrimitiveList(int seed)
889  { sortPrims(getIndexMap(GA_ATTRIB_PRIMITIVE), seed); }
890  /// @}
891 
892  /// Sorting according to a provided value list
893  /// @{
894  void sortElements(GA_IndexMap &array, fpreal *order);
895  void sortPointList(fpreal *order)
896  { sortElements(getIndexMap(GA_ATTRIB_POINT), order); }
898  { sortElements(getIndexMap(GA_ATTRIB_PRIMITIVE), order); }
899  /// @}
900 
901  /// "Rotate" (cycle) the order of vertices for all primitives in the group,
902  /// by the specified number of places.
903  void shift(int uoffset, int voffset,
904  const GA_PrimitiveGroup *group=NULL);
905 
906  /// "Rotate" (cycle) the order of points or primitives in the detail, by the
907  /// specified number of places.
908  /// @{
909  void shiftPoints(GA_IndexMap &, GA_Size offset);
910  void shiftPrims(GA_IndexMap &, GA_Size offset);
911  void shiftPointList(GA_Size aoffset)
912  { shiftPoints(getIndexMap(GA_ATTRIB_POINT), aoffset); }
914  { shiftPrims(getIndexMap(GA_ATTRIB_PRIMITIVE), aoffset); }
915  /// @}
916 
917  /// Reverse vertices for all primitives in the group
918  void reverse(const GA_PrimitiveGroup *group=NULL);
919 
920  /// Reverse order of points or primitives in the detail.
921  /// @{
922  void reversePoints(GA_IndexMap &map);
923  void reversePrims(GA_IndexMap &map);
925  { reversePoints(getIndexMap(GA_ATTRIB_POINT)); }
927  { reversePrims(getIndexMap(GA_ATTRIB_PRIMITIVE)); }
928  /// @}
929 
930  /// Sort points or primitives by proximity to a position
931  /// @{
932  void proximityPoints(GA_IndexMap &points,
933  const UT_Vector3 &point);
934  void proximityPrims(GA_IndexMap &primitives,
935  const UT_Vector3 &point);
936  void proximityToPointList(const UT_Vector3 &point)
937  { proximityPoints(getIndexMap(GA_ATTRIB_POINT), point); }
939  { proximityPrims(getIndexMap(GA_ATTRIB_PRIMITIVE), point); }
940  /// @}
941 
942  /// Sort points by the order in which they are first referred-to by
943  /// vertices.
944  /// @{
945  void vertexOrder(GA_IndexMap &points);
947  { vertexOrder(getIndexMap(GA_ATTRIB_POINT)); }
948  /// @}
949 
950  /// Create a mesh primitive or polygon primitives representing a
951  /// super-quadric surface specified by parms.
952  void superEllipsoid(const GU_SuperQuadParms &parms);
953 
954  /// Split the specified polygon into convex polygons with at most
955  /// maxpts vertices each. By default, this triangulates the polygon.
956  /// If flipedges is true, it will flip edges to get the Delaunay
957  /// triangulation, avoiding small angles where possible.
958  /// If avoiddegeneracy is true, degenerate triangles will not be generated;
959  /// note that this means that the mesh may not be watertight or even
960  /// connected.
961  void convexPoly(GEO_PrimPoly *pp, GA_ElementWranglerCache &wranglers,
962  GA_Size maxpts = 3, const GA_Detail *restgdp=0,
963  bool flipedges = false, bool avoiddegeneracy = false);
964  /// Split polygons in the specified polygon soup into convex polygons
965  /// with at most maxpts vertices each. By default, this triangulates the
966  /// polygon. If flipedges is true, it will flip edges to get the Delaunay
967  /// triangulation, avoiding small angles where possible.
968  /// If avoiddegeneracy is true, degenerate triangles will not be generated;
969  /// note that this means that the mesh may not be watertight or even
970  /// connected.
971  void convexPolySoup(GEO_PrimPolySoup *polysoup,
972  GA_Size maxpts = 3, const GA_Detail*restgdp=0,
973  bool flipedges = false,
974  bool avoiddegeneracy = false);
975  /// Split polygons (including in polygon soups) in the detail into convex
976  /// polygons with at most maxpts vertices each. By default, this
977  /// triangulates the polygon. If flipedges is true, it will flip edges to
978  /// get the Delaunay triangulation, avoiding small angles where possible.
979  /// If avoiddegeneracy is true, degenerate triangles will not be generated;
980  /// note that this means that the mesh may not be watertight or even
981  /// connected.
982  void convex(GA_Size maxpts=3, GA_PrimitiveGroup *primGroup=0,
983  const GA_Detail *restgdp=0, bool flipedges = false,
984  bool avoiddegeneracy = false);
985 
986  /// Add non-planar polygon primitives to nonplanargroup.
987  GA_Size findNonPlanar(GA_PrimitiveGroup *nonplanargroup, float tol = 0.0001F,
988  const GA_PrimitiveGroup *searchprimgroup = NULL);
989 
990  /// Clip primitives, keeping everything where dot(normal, P) >= d.
991  /// If clippts is true, disconnected points are also clipped.
992  void clip(UT_Vector3 &normal, float d = 0, int normlize = 0,
993  const GA_PrimitiveGroup *primGroup = 0,
994  bool clippts = false);
995 
996 //
997 // Polygon creasing
998  void crease(UT_Vector3 &normal, float d = 0,
999  int normlize = 0, int outputGroups = 0,
1000  GA_PrimitiveGroup *above = 0,
1001  GA_PrimitiveGroup *below = 0,
1002  const GA_PrimitiveGroup *creaseGroup = 0);
1003 //
1004 // fractals
1005  void fractalize(int seed = 1, float roughness = 0.6F,
1006  float scaleby=1, int divs=1,
1007  int fixedBoundry = 1, int useVtxNorms = 0,
1008  float nx = 0, float ny = 0, float nz = 1,
1009  const GA_PrimitiveGroup *fractalGroup = 0);
1010 
1011  //
1012  // Shrink Wrap and tools
1013 
1014  /// This routine is originally developed for the Bullet RBD solver to adjust
1015  /// the geometry of a convex 3D polygon to remove the space around the geometry
1016  /// caused by the collision margin required for the Bullet solver.
1017  void shrink( fpreal distance,
1018  fpreal clip_tolerance = 0.0001,
1019  fpreal consilidate_tolerance = 0.001);
1020 
1021  /// preliminary routine to setup the gdp to be shrunk by the shrink routine
1022  bool tetrahedralizeForShrink( const GA_PointGroup *ptGroup = 0,
1023  GU_Detail *gdp = 0 );
1024 
1025 
1026  /// Twist operations. The method returns 0 if everything goes OK, else -1.
1027  /// "pasted" returns 1 if at least one pasted surface was involved in
1028  /// the deformation, else 0.
1029  int nonLinearDeform(GU_DeformType type,const GU_TwistParms &parms,
1030  int &pasted);
1031 
1032  /// NOTE: This is something specific to NURBS surfaces and it uses
1033  /// pasted surface primitives, so it's probably not what you want!!!
1034  /// Creates an offset surface from the specified surface & radius.
1035  GEO_Hull *offset(const GU_OffsetParms &parms);
1036 
1037  /// Create a Gordon surface out of the given bi-linear network of faces.
1038  /// The faces don't have to be the same type or order or anything.
1039  /// We return the surface if OK and 0 otherwise. If the u or v faces
1040  /// contain only one face, we automatically generate a final curve. If
1041  /// both u faces and vfaces have 1 curve or one has 2 and the other 1,
1042  /// we generate a Coons surface. "accurate" is used when the curves do not
1043  /// intersect (i.e. when we must compute their min distances).
1044  /// @{
1045  GEO_Hull *gordon(GEO_SurfaceType surftype, int accurate,
1046  const GA_PrimitiveGroup &ufaces,
1047  const GA_PrimitiveGroup &vfaces,
1048  int reparameterize = 0);
1049  GEO_Hull *gordon(GEO_SurfaceType surftype, int accurate,
1050  const UT_Array<GEO_Primitive*> &uprims_in,
1051  const UT_Array<GEO_Primitive*> &vprims_in,
1052  GU_SkinCache& skin_cache,
1053  int reparameterize = 0);
1054  /// @}
1055 
1056  /// Generate a Coons surface out of up to 4 boundary curves. Return a
1057  /// pointer to the surface if successful and 0 otherwise. The faces do
1058  /// not have to have the same type or order.
1059  GEO_Hull *coons(GEO_SurfaceType surftype,
1060  const GEO_Face &uface1, const GEO_Face &vface1,
1061  const GEO_Face *uface2 = 0, const GEO_Face *vface2 = 0);
1062 
1063  /// Generate a skinned surface out of a set of cross-sections. The faces
1064  /// don't have to be the same type or order. We return the surface is OK
1065  /// and 0 otherwise. Specifying a vorder of 0 tells the method to
1066  /// come up with a legal default value for the surface. If "doskin" is
1067  /// true, the cross-sections will be right on the surface; otherwise, we
1068  /// build a ruled surface, which simply steals the curves' CVs and assigns
1069  /// them to the surface.
1070  GEO_Hull *skin(GU_SkinParms &parms, GU_SkinCache& skin_cache);
1071 
1072  /// This restrictive skinning method assumes the faces are of the same type
1073  /// and have the same number of CVs. order 0 means pick most suitable one.
1074  /// If doskin is false, we build a ruled surface. nprims is the number
1075  /// of faces in the group; we compute it if -1. We return the resulting
1076  /// surface and do not delete the input faces. We also assume that if
1077  /// nprims > 2 and vorder != 2 and doskin, all the faces are nonrational.
1078  /// Finally, the provided vParmValues if given specifies what v coordinate
1079  /// each of the provided faces should interpolate.
1080  /// @{
1081  GEO_Hull *skin(const GA_PrimitiveGroup &ucfaces,
1082  GEO_SurfaceType surftype = GEO_PATCH_QUADS,
1083  unsigned vorder = 0, int vwrap = 0,
1084  int doskin = 1, int nprims = -1,
1085  const UT_Vector *vParmValues = 0);
1086  GEO_Hull *skin(const UT_Array<GEO_Primitive*> & prims_in,
1087  GU_SkinCache& skin_cache,
1088  GEO_SurfaceType surftype = GEO_PATCH_QUADS,
1089  unsigned vorder = 0, int vwrap = 0,
1090  int doskin = 1, int nprims = -1,
1091  const UT_Vector *vParmValues = 0);
1092  /// @}
1093 
1094  /// See GU_Ruled.h for the various closure and interpolation types
1095  /// which are valid. Specifying an orderv of 0 makes the routine
1096  /// come up with a legal default value for the surface.
1097  int ruled( GEO_Hull *&surface, const GU_RuledParms &p,
1098  const GU_CapOptions &caps);
1099 
1100  /// This is what the Skin SOP and Sweep SOP use for skinning
1101  /// cross-sections.
1102  /// See GU_CurveNetwork.h for parameter types. This method generates
1103  /// a skinned surface, a Coons surface, or a Gordon surface depending on
1104  /// the primitive groups it is given. Specifying an orderv of 0 makes the
1105  /// routine come up with a legal default value for the surface.
1106  int curveNetwork(GEO_Hull *&hull, GU_CurveNetworkParms &p,
1107  int &count, GU_SkinCache& skin_cache);
1108 
1109  GU_ERROR sweep( GU_SweepParms parms );
1110  void rails( GU_RailParms parms );
1111 
1112  /// Join more faces or surfaces together.
1113  GEO_Primitive *join( GU_JoinParms &p, int &count);
1114 
1115  /// Generate a fillet between two curves on surfaces:
1116  GEO_Hull *filletTrims(GU_TrimFilletParms &parms, int &count);
1117 
1118  /// Generate a rounded fillet:
1119  GEO_Hull *filletRound(GU_RoundFilletParms &parms);
1120  /// NOTE: The first 5 columns of the matrix must be GEO_Curve*,
1121  /// and the other 2 columns of the matrix must be GEO_TPSurf*.
1122  void filletRoundNetwork(UT_RefMatrix<GEO_Primitive *>,
1123  GU_RoundFilletParms &parms);
1124 
1125  /// Fillet a set of faces/hulls
1126  /// Return 0 if OK, -1 otherwise (non face/hull types)
1127  int fillet(GU_FilletParms &parms, int &count);
1128 
1129  /// Loft (stitch) a number of polygons together without changing the number
1130  /// of points in the detail.
1131  /// @{
1132  void loft(GU_LoftParms &p, const GA_PointGroup &g1,
1133  const GA_PointGroup &g2);
1134  void loft(GU_LoftParms &p,
1135  const GA_PrimitiveGroup *group = 0);
1136  /// @}
1137 
1138  /// Revolves all curves in the given gdp (or only curves in the
1139  /// group if the group is given) around a line given by the center
1140  /// and axis. Only polygonal curves use the divisions. NURBS and
1141  /// Bezier curves are revolved a special way to create a perfectly
1142  /// round surface with a minimum number of revolution copies.
1143  int revolve( const GU_RevolveParms &parms,
1144  const GU_CapOptions &caps, int &count);
1145 
1146  /// Warp curves or surfaces. Return 0 if successful and -1 otherwise.
1147  int warp(GU_WarpParms &parms);
1148 
1149  /// Curve Clay it!
1150  GU_ERROR curveClay(const GU_CurveClayParms &ccparm);
1151 
1152  /// This puts endcaps on the specified hull
1153  int endCap(GEO_Hull &hull, const GU_CapParms &parms);
1154  int endCap(GEO_Face &face, const GU_CapParms &parms);
1155 
1156  /// This places all caps on the hull
1157  int setCaps(GEO_Hull &hull, const GU_CapOptions &parms, int &count);
1158  int setCaps(GEO_Face &face, const GU_CapOptions &parms, int &count);
1159 
1160  /// Creates a deformed copy of a source detail given a pair of
1161  /// rest and deform details. Return 1 if a pasted surface was deformed,
1162  /// else 0. If 'deform_history' is passed in, every time we deform a point
1163  /// from our source, we mark this by setting the bit in 'deform_history'
1164  /// whose index corresponds to the point's number to 1. Useful if you want
1165  /// to know which points we deformed.
1166  int lattice(const GU_Detail *source, const GU_Detail *rest,
1167  const GU_Detail *deform, int xdiv, int ydiv, int zdiv,
1168  const GA_PointGroup *ptgroup = 0,
1169  UT_BitArray *deform_history = NULL,
1171 
1172  /// All points of the gdp are deformed according to the meta source
1173  /// field that surrounds it. The deformation is controlled by a
1174  /// transformation matrix.
1175  int magnet( const GU_MagnetParms &parms );
1176 
1177  /// trace a raster image to form closed polygons
1178  float trace(GU_TraceParms *parms);
1179 
1180  /// add point texture attributes to traced geometry
1181  void applyTraceTexture(float xres, float yres, float resolution);
1182 
1183 
1184  /// fit a sequence of discrete points to a series of bezier curves
1185  void fit2DCurve(const GU_Detail *source, float error_squared,
1186  GA_PrimitiveGroup *primGroup = 0);
1187 
1188  /// Fit a curve through its breakpoints
1189  /// @{
1190  GEO_Curve *interpCurveBreakpoints(const GEO_Face &face,
1192  int order=4,
1194  GEO_Curve *interpCurveBreakpoints(const GA_OffsetList &point_offsets,
1196  int order=4, int wrapped=0,
1198  GEO_Curve *interpCurveBreakpoints(const UT_Vector4Array &v4Data,
1200  int order=4, int wrapped=0,
1202  /// @}
1203 
1204  /// interpolation data points
1205  /// @{
1206  GEO_Curve *interpCurveGlobal(const GEO_Face &face,
1208  int order=4,
1211  GEO_Curve *interpCurveGlobal(const GA_OffsetList &point_offsets,
1213  int order=4, int wrapped=0,
1216  GEO_Curve *interpCurveGlobal(const GA_Range &point_range,
1218  int order=4, int wrapped=0,
1221  GEO_Curve *interpCurveGlobal(const UT_Vector4Array &v4Data,
1223  int order=4, int wrapped=0,
1226  GEO_Curve *interpCurveLocal(const GEO_Face &face,
1228  int order = 4, int corner=0);
1229  GEO_Curve *interpCurveLocal(const UT_Array<GA_Offset> &goData,
1231  int order = 4, int wrapped=0, int corner=0);
1232  GEO_Curve *interpCurveLocal(const UT_Vector4Array &v4Data,
1234  int order = 4, int wrapped=0, int corner=0);
1235 
1236  GEO_TPSurf *interpSurfGlobal(const GEO_Hull &mesh,
1238  int uOrder=4, int vOrder=4,
1244  const UT_Vector *uParmValues = 0,
1245  const UT_Vector *vParmValues = 0);
1246 
1247  GEO_TPSurf *interpSurfGlobal(const GA_OffsetMatrix &goMesh,
1249  int uOrder=4, int vOrder=4,
1250  bool uWrapped=false, bool vWrapped=false,
1256  const UT_Vector *uParmValues = 0,
1257  const UT_Vector *vParmValues = 0);
1258 
1259  GEO_TPSurf *interpSurfBreakpoints(const GEO_Hull &mesh,
1261  int uOrder=4, int vOrder=4,
1267  const UT_Vector *uParmValues = 0,
1268  const UT_Vector *vParmValues = 0);
1269 
1270  GEO_TPSurf *interpSurfBreakpoints(const GA_OffsetMatrix &goMesh,
1272  int uOrder=4, int vOrder=4,
1273  bool uWrapped=false, bool vWrapped=false,
1279  const UT_Vector *uParmValues = 0,
1280  const UT_Vector *vParmValues = 0);
1281  /// @}
1282 
1283  /// Approximate data points given a tolerance.
1284  /// Only for open endinterpolated surface.
1285  /// @{
1286  GEO_Curve *approxCurveGlobal(const GEO_Face &face,
1288  int order=4,
1289  float tol=1e-1F, float smooth=0.0F,
1290  int noMultipleKnots=1);
1291  GEO_Curve *approxCurveGlobal(const UT_Vector4Array &v4Data,
1293  int order=4, int wrapped=0,
1294  float tol=1e-1F, float smooth=0.0F,
1295  int noMultipleKnots=1);
1296 
1297  GEO_TPSurf *approxSurfGlobal(const GEO_Hull &mesh,
1299  int uOrder=4, int vOrder=4,
1301  float tol=1e-1F, float smooth=0.0F,
1302  int uNoMultipleKnots=1,
1303  int vNoMultipleKnots=1);
1304  GEO_TPSurf *approxSurfGlobal(const GA_OffsetMatrix &gpMesh,
1306  int uOrder=4, int vOrder=4,
1307  int uWrapped=0, int vWrapped=0,
1309  float tol=1e-1F, float smooth=0.0F,
1310  int uNoMultipleKnots=1,
1311  int vNoMultipleKnots=1);
1312  /// @}
1313 
1314  /// methods to refine face and hull types
1315  /// @{
1316  void refine(float *uunit, int ulen,
1317  float *vunit, int vlen,
1318  int countu=1, int countv=1,
1319  int arcspacing = 0,
1320  const GA_PrimitiveGroup *primGroup = 0);
1321 
1322  void unrefine(float umin, float umax,
1323  float vmin, float vmax,
1324  int countu=1, int countv=1,
1325  float utol=0.001F, float vtol=0.001F,
1326  const GA_PrimitiveGroup *primGroup = 0);
1327 
1328  void subdivide(float *uunit, int ulen,
1329  float *vunit, int vlen,
1330  int arcspacing = 0,
1331  const GA_PrimitiveGroup *primGroup = 0);
1332 
1333  /// op = {0 = isoparms, 1 = points, 2 = profiles}
1334  int extract(float *uunit, int ulen,
1335  float *vunit, int vlen,
1336  const GA_PrimitiveGroup *primGroup = 0,
1337  GA_PointGroup *newPoints = 0,
1338  int op = 0, int keepOriginal = 0,
1339  int atbreakpoints = 0, int use_arc_length = 0);
1340 
1341  void extractIsoParms(float *uunit, int ulen,
1342  float *vunit, int vlen,
1343  GA_PrimitiveGroup *newPrims = 0,
1344  const GA_PrimitiveGroup *primGroup = 0);
1345 
1346  void extractPoints(float *uunit, int ulen,
1347  float *vunit, int vlen,
1348  GA_PointGroup *newPoints = 0,
1349  const GA_PrimitiveGroup *primGroup = 0);
1350 
1351  void extractProfiles(float *uunit, int ulen,
1352  float *vunit, int vlen,
1353  const GA_PrimitiveGroup *primGroup = 0);
1354 
1355  void extractIsoParmsAtBreak(float *uunit, int ulen,
1356  float *vunit, int vlen,
1357  GA_PrimitiveGroup *newPrims = 0,
1358  const GA_PrimitiveGroup *primGroup = 0);
1359 
1360  void extractPointsAtBreak(float *uunit, int ulen,
1361  float *vunit, int vlen,
1362  GA_PointGroup *newPoints = 0,
1363  const GA_PrimitiveGroup *primGroup = 0);
1364 
1365  void extractProfilesAtBreak(float *uunit, int ulen,
1366  float *vunit, int vlen,
1367  const GA_PrimitiveGroup *primGroup = 0);
1368 
1369 
1370  int cut(float *uunit, int ulen,
1371  float *vunit, int vlen,
1372  const GA_PrimitiveGroup *primGroup = 0,
1373  int keepin=1, int keepout=0, int atbreakpoints = 0,
1374  int allU = 0, int allV = 0, int use_arc_length = 0);
1375  /// @}
1376 
1377 
1378  /// approximate a spline by using polygonal hull inputs
1379  /// deletes existing polygons if deleteAll is true
1380  void polySpline(GU_PolysplineParms &parms,
1381  const GA_PrimitiveGroup *primGroup = 0,
1382  bool deleteAll = true);
1383 
1384  /// approximate a patch by using polygonal or mesh hull inputs
1385  /// Returns true on success, else false if an error occurred.
1386  bool polyPatch(GU_PolypatchParms &parms,
1387  const GA_PrimitiveGroup *primGroup = 0);
1388 
1389  /// reduce the number of polygons in a detail:
1390  int polyReduce(GU_PolyReduceParms &parms,
1391  const GA_PrimitiveGroup *primGroup = 0,
1392  int *pointIndexTable = 0);
1393 
1394  /// Create polygon soup(s), i.e. GU_PrimPolySoup, where possible in this detail
1395  void polySoup(const GEO_PolySoupParms &parms , const GU_Detail *srcdetail);
1396 
1397  /// Create geometry through premise and rule substitution
1398  void lsystem(GU_LSystemParms &lp);
1399 
1400  /// Get information about a GU_Detail
1401  /// If maxlines < 0, there will be no limit to the number of groups
1402  /// If overridememusage is positive, it will be used rather than the
1403  /// getMemoryUsage().
1404  int info(std::ostream &os,
1405  int max_group_lines=15,
1406  bool pretty=false,
1407  const UT_Set<const void *> *dontcounttheseblocks = 0,
1408  bool instanced=false) const;
1409  /// Get information text for the geometry. This will @b append to the work
1410  /// buffer.
1411  void info(UT_WorkBuffer &wbuf,
1412  int max_group_lines=15,
1413  bool pretty=false,
1414  const UT_Set<const void *> *dontcounttheseblocks = 0,
1415  bool instanced=false) const;
1416 
1417  /// Fills in a stat structure with the volume information.
1418  virtual void statVolumes(GA_Stat &stat, uint level/*=0xffff*/) const;
1419 
1420  /// @c intersectRay will find the closest intersection with a primitive
1421  /// in the detail. If the dist pointer is nil, then the first intersection
1422  /// found will be returned (instead of the closest). The nml will contain
1423  /// the normal for the primitive at the point of intersection.
1424  /// Accuracy of 0 is inaccurate, 1 is normal, 2 engages Algebraic pruning
1425  /// where available.
1426  ///
1427  /// @param o The ray origin
1428  /// @param d The ray directin
1429  /// @param tmax This can be used to limit the ray to intersections within
1430  /// the given radius.
1431  /// @param tol Intersection tolerance
1432  /// @param dist Return the distance from the origin to the hit
1433  /// @param pos Return the hit position (i.e. <tt>o + dist*d</tt>)
1434  /// @param nml Return the normal of the primitive at the hit position
1435  /// @param accurate Determine primitive intersection algorithms for NURBS
1436  /// @param u The u parametric coordinate of the hit surface
1437  /// @param v The v parametric coordinate of the hit surface
1438  /// @param ignoretrim Ignore trim inside/out tests for trimmed surfaces.
1439  ///
1440  /// @warning If the @c dist parameter is 0 the first hit found will be
1441  /// returned. This may @b not be the closest hit. This can be used to
1442  /// perform a quick check to see if @b any primitives intersect the ray
1443  /// (i.e. for shadow casting).
1444  ///
1445  /// @warning This function iterates over all primitives without any
1446  /// acceleration structure. If you need to send multiple rays, please see
1447  /// GU_RayIntersect.
1448  SYS_DEPRECATED_HDK(16.0)
1449  GEO_Primitive *intersectRay(const UT_Vector3 &o, const UT_Vector3 &d,
1450  float tmax = 1E17F, float tol = 1E-12F,
1451  float *dist = 0, UT_Vector3 *pos = 0,
1452  UT_Vector3 *nml = 0, int accurate = 0,
1453  float *u = 0, float *v = 0,
1454  int ignoretrim = 1) const;
1455 
1456  /// Figure out the parameters of the face/surface that all the given
1457  /// faces/surfaces should have in order to be fully compatible with one
1458  /// another. Return 0 if all the primitive types are faces/surfaces,
1459  /// and -1 otherwise.
1460  /// @{
1461  int commonFaceConfig(
1462  const GA_PrimitiveGroup &faceGroup,
1463  GA_PrimCompat::TypeMask &type, int &order,
1464  bool &open, bool &ends) const;
1465  int commonFaceConfig(
1466  const UT_Array<GEO_Primitive*> &faces_in,
1467  GA_PrimCompat::TypeMask &type, int &order,
1468  bool &open, bool &ends) const;
1469  int commonSurfaceConfig(const GA_PrimitiveGroup &surfs,
1470  GA_PrimCompat::TypeMask &type,
1471  int &orderu, int &orderv,
1472  bool &openu, bool &openv,
1473  bool &endsu, bool &endsv) const;
1474  /// @}
1475 
1476  /// Incompatible faces in infaces are made compatible and set in outfaces.
1477  /// Return 0 of OK, -1 otherwise. If extratype is not nil and the highest
1478  /// face type of the infaces is less than *extratype, replace the common
1479  /// type by *extratype. In the method that takes 2 input groups, we make
1480  /// sure that the primitives in the 2 groups have the same type. Set
1481  /// equalcvs to true make them all have the same number of CVs too.
1482  /// @{
1483  int makeFacesCompatible(
1484  const GA_PrimitiveGroup &infaces,
1485  GA_PrimitiveGroup &outfaces,
1486  bool mustopen = false,
1487  bool mustends = false,
1488  bool nonrational = false,
1489  GA_PrimCompat::TypeMask *extratype = 0,
1490  bool equalcvs = true);
1491  int makeFacesCompatible(
1492  const UT_Array<GEO_Primitive*> &prims_in,
1493  UT_Array<GEO_Primitive*>& prims_out,
1494  bool mustopen = false,
1495  bool mustends = false,
1496  bool nonrational = false,
1497  GA_PrimCompat::TypeMask *extratype = 0,
1498  bool equalcvs = true);
1499  int makeFacesCompatible(
1500  const GA_PrimitiveGroup &infacesU,
1501  const GA_PrimitiveGroup &infacesV,
1502  GA_PrimitiveGroup &outfacesU,
1503  GA_PrimitiveGroup &outfacesV,
1504  bool mustopen = false,
1505  bool mustends = false,
1506  bool nonrational = false,
1507  GA_PrimCompat::TypeMask *extratype = 0,
1508  bool equalcvs = true);
1509  int makeFacesCompatible(
1510  const UT_Array<GEO_Primitive*> &ufaces_array,
1511  const UT_Array<GEO_Primitive*> &vfaces_array,
1512  UT_Array<GEO_Primitive*> &ucfaces_array,
1513  UT_Array<GEO_Primitive*> &vcfaces_array,
1514  bool mustopen = false,
1515  bool mustends = false,
1516  bool nonrational = false,
1517  GA_PrimCompat::TypeMask *extratype = 0,
1518  bool equalcvs = true);
1519  /// @}
1520 
1521  /// Loft a subsection of each hull and update the vertex indices where
1522  /// the subsection occurs. Does partial nurb merging if the bases is given
1523  /// Assumes the two hulls have been properly reconfigured.
1524  static int loftHulls(GEO_Hull *left, GEO_Hull *right,
1525  float lwidth1, float lwidth2,
1526  float rwidth1, float rwidth2,
1527  int sharp, int &lstart, int &rstart,
1528  int &lmax, int &rmax,
1529  int loftU, GA_NUBBasis *nubbasis);
1530 
1531  /// Refine the hull at the unit domain value and return the
1532  /// row/col index where it occurs
1533  /// @{
1534  static int getSubdividedCV(GEO_Hull *hull, int udir, float unit);
1535  static int getSubdividedCV(GEO_Face *face, float unit);
1536  /// @}
1537 
1538  /// Methods for registering and unregistering geometry io converters.
1539  /// @{
1540  static void registerIOTranslator(GEO_IOTranslator *trans);
1541  static void unregisterIOTranslator(GEO_IOTranslator *trans);
1542  static exint getIOTranslatorCount();
1543  static const GEO_IOTranslator *getIOTranslator(exint i);
1544  /// @}
1545 
1546  GA_Detail::IOStatus saveH9File(const char *filename,
1547  const GA_SaveOptions *options) const;
1548  static GA_Detail::IOStatus statH9File(const char *filename,
1549  GA_Stat &sbuf, uint level);
1550 
1551  /// Returns true if filename is a recognized extension.
1552  static bool isFormatSupported(const char *filename);
1553 
1554  /// Allocate an IO handler for a filename, or return NULL if the handler is
1555  /// the classic format. The returned translator must be deleted. The
1556  /// easiest way to do this is with a UT_UniquePtr: @code
1557  /// UT_UniquePtr<GEO_IOTranslator> xlate(getSupportedFormat(filename));
1558  /// if (xlate)
1559  /// xlate->fileSave(gdp, ...);
1560  /// @endcode
1561  static GEO_IOTranslator *getSupportedFormat(const char *filename);
1562 
1563  /// Align a set of primitives by rotation and translation
1564  void align(GU_AlignParms &parms);
1565 
1566  /// Align a set of faces/hulls at optional levels of continuity.
1567  /// face/hull pre/posttranslate + row stitching + row tangent
1568  /// Faces are aligned with faces, hulls with hulls.
1569  /// Return 0 if OK, -1 otherwise (non face/hull types)
1570  int stitch(GU_StitchParms &parms);
1571 
1572  /// Incompatible surfaces in insurfs are made compatible and set in outsurfs.
1573  /// Return 0 of OK, -1 otherwise. If extratype is not nil and the highest
1574  /// surface type of the insurfs is less than *extratype, replace the common
1575  /// type by *extratype. Set equalcvs to true make them all have the same number
1576  /// of CVs too.
1577  int makeSurfacesCompatible(
1578  const GA_PrimitiveGroup &insurfs,
1579  GA_PrimitiveGroup &outsurfs,
1580  bool mustopenu=false, bool mustopenv=false,
1581  bool mustendsu=false, bool mustendsv=false,
1582  bool equalcvsu=true, bool equalcvsv=true,
1583  GA_PrimCompat::TypeMask *extratype = 0);
1584 
1585  /// NOTE: These functions only apply to pasted surface primitives,
1586  /// so they're probably not what you want!
1587  /// Convenience wrappers for several common pasting operations. The last
1588  /// method destroys both groups:
1589  /// @{
1590  GA_PrimitiveGroup *getPastedSurfaces(const char *n = "__gu_all_pasted__");
1591  GA_PrimitiveGroup *getPastedSurfaces(GA_PrimitiveGroup *&used,
1592  const char *n = "__gu_all_pasted__",
1593  const char *u = "__gu_used_pasted__");
1594  void updatePastedDisplacement(GA_Offset ptoff,
1595  const GA_PrimitiveGroup *all,
1596  GA_PrimitiveGroup *used);
1597  int updatePastedDisplacements(void);
1598  int updatePastedDependents(GA_PrimitiveGroup *all,
1599  GA_PrimitiveGroup *used);
1600  /// @}
1601 
1602  /// Error Routines
1603  /// @{
1604  GU_ERROR error() const
1605  {
1606  return UTgetErrorManager()->getSeverity();
1607  }
1608 
1610  const char *msg = 0) const
1611  {
1612  UTgetErrorManager()->addMessage("GU", code, msg);
1613  }
1615  const char *msg = 0) const
1616  {
1617  UTgetErrorManager()->addWarning("GU", code, msg);
1618  }
1619  void addError(GU_ErrorCodes code, const char *msg = 0) const
1620  {
1621  UTgetErrorManager()->addError("GU", code, msg);
1622  }
1623  /// @}
1624 
1625  /// Returns a cook selection to fill in. If an already existing cook
1626  /// selection exists, of the wrong type, it is removed, and a new one
1627  /// created. Otherwise the existing cook selection is optionally cleared
1628  /// and returned.
1629  ///
1630  /// The cook selection is the selection being manipulated and displayed
1631  /// by a node.
1632  GU_SelectionHandle getOrCreateCookSelection(GA_GroupType group_type,
1633  bool ordered = false,
1634  bool clear_matching = false);
1635 
1636  /// Returns the group type of the current cook selection, or
1637  /// GA_GROUP_INVALID if there isn't one.
1638  GA_GroupType getCookSelectionGroupType() const;
1639 
1640  /// Creates a cook selection that directly references the supplied group.
1641  /// Any changes to the cook selection later will copy this group and use
1642  /// that copy.
1643  ///
1644  /// You must call removeCookSelection() if this group is later destroyed
1645  /// and the cook selection is still referencing it, which can be checked
1646  /// by calling hasShallowCookSelectionReference(group).
1647  ///
1648  /// NB: Only use this method if you know what you're doing. Any gains in
1649  /// performance are likely not to be worth the management pain.
1650  GU_SelectionHandle createShallowCookSelection(GA_Group *group);
1651 
1652  /// Returns whether this detail has a shallow cook selection referencing
1653  /// the specified group.
1654  bool hasShallowCookSelectionReference(
1655  const GA_Group *group) const;
1656 
1657  /// Returns the current user selection;
1658  SYS_DEPRECATED(16.0)
1659  GU_SelectionHandle userSelection() const;
1660 
1661  /// Set the current user selection. This is the selection being manipulated
1662  /// and displayed by the user. Used by the interactive tools.
1663  SYS_DEPRECATED(16.0)
1664  void setUserSelection(GU_SelectionHandle user_sel);
1665 
1666  /// Removes the current user selection from this detail. Since the selection
1667  /// is a shared object, there's no guarantee that it will be immediately
1668  /// destroyed, but only that this detail is no longer associated with it.
1669  SYS_DEPRECATED(16.0)
1670  void removeUserSelection();
1671 
1672  /// Returns the current cook selection;
1673  GU_SelectionHandle cookSelection() const;
1674 
1675  /// Removes the current cook selection from this detail. Since the selection
1676  /// is a shared object, there's no guarantee that it will be immediately
1677  /// destroyed, but only that this detail is no longer associated with it.
1678  void removeCookSelection();
1679 
1680  /// Do not use this method unless you know EXACTLY what you are doing. It
1681  /// forces the use of the supplied cook selection.
1682  void forceCookSelection(GU_SelectionHandle sel);
1683 
1684  /// Do not use this method unless you know EXACTLY what you are doing. It
1685  /// removes the cook selection from the detail without orphaning it so the
1686  /// only safe thing to do is to return it later using forceCookSelection().
1687  GU_SelectionHandle stealCookSelection();
1688 
1689  /// Remove points from polygons if they lie on (within a tolerance)
1690  /// the line connecting the previous and next points.
1691  void removeInlinePoints(float tol,
1692  const GA_PrimitiveGroup *prims);
1693 
1694  /// Remove zero area polygons
1695  /// Returns number of polygons removed
1696  /// @{
1697  GA_Size removeZeroAreaFaces(GA_PrimitiveGroup *grp,
1698  bool ignoreOpenFaces = false,
1699  float tolerance = 0.001F,
1700  bool onlyPolys = true);
1701  GA_Size removeZeroAreaFaces(const UT_IntArray &primlist,
1702  bool ignoreOpenFaces = false,
1703  float tolerance = 0.001F,
1704  bool onlyPolys = true);
1705  /// @}
1706 
1707  /// Deletes the geometry in the given group, unlike deleteEdges,
1708  /// it doesn't repair the holes left behind.
1709  void deleteGroupGeometry(const GA_Group &group);
1710 
1711  /// Deletes edge geometry
1712  SYS_DEPRECATED_HDK(16.0)
1713  void deleteEdges(GA_EdgeGroup &edgegroup,
1714  bool del_inline_points,
1715  float inlinetol,
1716  bool del_unused_points = true,
1717  bool del_bridges = true);
1718 
1719  /// There are three different ways of handling situations where all edges
1720  /// that connect polygon boundaries are dissolved.
1721  /// - GU_BRIDGEMODE_BRIDGE @n
1722  /// Insert bridge edges to connect the boundary loops.
1723  /// - GU_BRIDGEMODE_DISJOINT @n
1724  /// Create a separate polygon for each boundary loop.
1725  /// - GU_BRIDGEMODE_DELETE @n
1726  /// Delete the polygons.
1728  {
1731  GU_BRIDGEMODE_DELETE
1732  };
1733  void dissolveEdges(const GA_EdgeGroup &edgegroup,
1734  bool del_inline_points,
1735  fpreal inlinetol,
1736  bool del_unused_points,
1737  BridgeMode bridge_mode,
1738  bool del_degenerate_bridges,
1739  bool boundary_curves);
1740 
1741  /// Flips edges
1742  void flipEdges(const GA_EdgeGroup &edgegroup,
1743  int rotations = 1,
1744  bool rotattribs = false,
1745  GA_EdgeGroup *outedges = 0);
1746  /// Splits edges
1747  /// This is the main method for the PolySplit SOP. The splitlocs are
1748  /// the positions along which you wish to split polygons. When quadcut
1749  /// is false, the Shortest Path algorithm is used, otherwise the Quad Cut
1750  /// algorithm is used. The forcecut flag is used with the Shortest Path
1751  /// algorithm to force it to perform cuts where the initial cut has failed.
1752  /// To form a complete path of edges, supply the first location again as
1753  /// the last location in the splitlocs array. If quadcomplete is true and
1754  /// quadcut is false, then in certain cases extra edges will be inserted so
1755  /// that faces which began as quads get split into faces which are quads. If
1756  /// outPositions is set, it will be filled with a list of points in the path
1757  /// in RE_PRIM_LINES fashion. If fixEnds is set, either end of the path that
1758  /// is on a face will be given an extra segment to connect it to the nearest
1759  /// point to ensure that the resulting polygons don't self-intersect.
1760  void edgeSplit(const GU_SplitLocArray &splitlocs,
1761  bool quadcut = false,
1762  bool forcecut = true,
1763  GA_EdgeGroup *outedges = 0,
1764  float tolerance = SYS_FTOLERANCE,
1765  bool quadcomplete = false,
1766  bool modifyGdp = true,
1767  UT_Fpreal32Array *outPositions = NULL,
1768  bool fixEnds = false);
1769 
1770  /// Inserts points on edges
1771  /// @{
1772  void divideEdges(const GA_EdgeGroup &edgegroup, int numdivs = 1,
1773  bool applytoall = true,
1774  bool use_shared_points = false,
1775  GA_EdgeGroup *outedges = 0,
1776  UT_Array<GA_Offset> *new_points = 0,
1777  bool preserve_edge_dir = false);
1778  void divideEdges(const GA_EdgeGroup &edgegroup,
1779  int numdivs,
1780  bool applytoall,
1781  bool use_shared_points,
1782  GA_EdgeGroup *outedges,
1783  UT_Array<GA_Offset> *new_points,
1784  bool preserve_edge_dir,
1785  float fraction);
1786  /// @}
1787 
1788  /// Inserts points on edges, with a different fraction and number of
1789  /// divisions per edge.
1790  void divideEdges(const UT_Array<GU_EdgeDiv *> &divlocs,
1791  GA_PointGroup &outgrp);
1792 
1793  /// Transform breakpoints
1794  void transformBreakpoints(const UT_Matrix4 &mat,
1795  const GA_BreakpointGroup *grp = 0,
1796  int quickxform = 0);
1797 
1798 
1799  /// Extrude faces, uses local face spaces and tries to mirror extrusions.
1800  void polyExtrude(const GU_PolyExtrudeParms &parms);
1801 
1802  /// Collapse Edges
1803  void edgeCollapse(const GA_EdgeGroup &edgegroup,
1804  bool removedegen = true,
1805  bool updatenmls = true,
1806  GA_PointGroup *outpoints = 0);
1807 
1808  /// Adds crease weights to edges
1809  void edgeCrease(const GU_EdgeCreaseParms &parms);
1810 
1811  /// Insets points
1812  void pointInset(const GA_PointGroup *ptgroup,
1813  float insetdist, float nmldist);
1814 
1815  /// Find the oriented bounding box that contains the given primitives.
1816  /// The box is returned as a rotate+translate matrix to the box's
1817  /// orientation and centre, and a vector containing the boxes extents
1818  /// along its primary axes. The extents are radii, ie, one-half
1819  /// of what a bounding box size() would be.
1820  ///
1821  /// Returns zero radii if the group contains no primitives.
1822  void getOBBox(const GA_PrimitiveGroup *grp,
1824  UT_Vector3 &radii) const;
1825  /// Return the oriented bounding box that contains the given points,
1826  /// returning a UT_OBBox, which contains translation and rotation information
1827  void getOBBoxForPoints(const GA_PointGroup *grp,
1828  UT_OBBoxD &obb) const;
1829 
1830  /// Get cached bounding box. This uses the meta cache count and the data
1831  /// id on P to determine whether the bounds need to be recomputed.
1832  ///
1833  /// It's possible that the cached bounds might be invalid in some cases
1834  /// (where the geometry is modified without updates to the meta cache count
1835  /// or the data id on P.
1836  bool getCachedBounds(UT_BoundingBox &box) const;
1837  /// Forcibly clear the cached bounds without having to update the meta
1838  /// cache count or data ID on P.
1839  void clearCachedBounds();
1840 
1841  /// Make each primitive planar, returns the number of primitives xformed
1842  GA_Size makePrimsPlanar(const GA_PrimitiveGroup *grp = 0);
1843 
1844  static void loadIODSOs();
1845 
1846  /// Create a list of all internal file extensions
1847  static void getFileExtensions(UT_StringArray &result);
1848 
1849  /// Check to see whether the file extension matches a known binary file
1850  /// extension. The argument is the full filename.
1851  static bool matchBinaryFileExtension(const UT_StringRef &filename);
1852 
1853  /// Check to see whether the file extension matches a known ASCII file
1854  /// extension. The argument is the full filename.
1855  static bool matchASCIIFileExtension(const UT_StringRef &filename);
1856 
1857 
1858  /// These methods assume no changes have been made to the geometry since the
1859  /// last call to incrementMetaCacheCount(). "attrib" should refer to a string
1860  /// or integer attribute.
1861  int getUniqueValueCount(const GA_Attribute *attrib) const;
1862  int getUniqueIntegerValue(const GA_Attribute *attrib, int idx) const;
1863  const char *getUniqueStringValue(const GA_Attribute *attrib, int idx) const;
1864  GA_Range getRangeByValue(const GA_Attribute *attrib, int v) const;
1865  GA_Range getRangeByValue(const GA_Attribute *attrib, const char *v) const;
1866 
1867 
1868  class AttribValueLookupTable;
1869  class AttribSingleValueLookupTable;
1870 
1871  const AttribValueLookupTable *getLookupTable(const GA_Attribute *attrib) const;
1872  const AttribSingleValueLookupTable *getSingleLookupTable(const GA_Attribute *attrib) const;
1874  {
1875  public:
1876  AttribValueLookupTable(const GA_Attribute *attrib);
1877 
1879 
1880  void appendInt(int idx, GA_Offset offset);
1881  void appendString(const char *str, GA_Offset offset);
1882 
1883  int entries() const { return SYSmax((exint)myIntTable.size(), myStringTable.size()); }
1884 
1885  int getIntValue(int idx) const
1886  {
1887  if (idx < 0 || idx >= myIntValues.size())
1888  return -1;
1889  return myIntValues(idx);
1890  }
1891  const UT_StringHolder &getStringHolder(int idx) const
1892  {
1893  if (idx < 0 || idx >= myStringValues.size())
1895  return myStringValues(idx);
1896  }
1897  const GA_OffsetList *getIntOffsets(int v) const
1898  {
1900 
1901  if (it == myIntTable.end())
1902  return 0;
1903  return it->second;
1904  }
1906  {
1907  GA_OffsetList *list = 0;
1908  if (!myStringTable.findSymbol(v, &list))
1909  return 0;
1910  return list;
1911  }
1912 
1913  int64 getMemoryUsage(bool inclusive) const
1914  {
1915  int64 mem = inclusive ? sizeof(*this) : 0;
1916 
1917  mem += myStringValues.getMemoryUsage(false);
1918  mem += myIntValues.getMemoryUsage(false);
1919 
1920  mem += myStringTable.getMemoryUsage(false);
1921  for (UT_SymbolMap<GA_OffsetList *>::const_map_iterator it = myStringTable.map_begin(); it != myStringTable.map_end(); ++it)
1922  mem += it->second->getMemoryUsage(true);
1923 
1924  mem += UTgetMemoryUsage(myIntTable, false);
1925  for (UT_Map<int, GA_OffsetList *>::const_iterator it = myIntTable.begin(); it != myIntTable.end(); ++it)
1926  mem += it->second->getMemoryUsage(true);
1927 
1928  return mem;
1929  }
1930 
1931  private:
1932 
1933  UT_SymbolMap<GA_OffsetList *> myStringTable;
1934  UT_Map<int, GA_OffsetList *> myIntTable;
1935  UT_StringArray myStringValues;
1936  UT_IntArray myIntValues;
1937  };
1938 
1940  {
1941  public:
1943 
1945 
1946  void setInt(int idx, GA_Offset offset);
1947  void setString(const char *str, GA_Offset offset);
1948 
1949  int entries() const { return SYSmax((exint)myIntTable.size(), myStringTable.size()); }
1950 
1952  {
1953  UT_Map<int, GA_Offset>::const_iterator it = myIntTable.find(v);
1954 
1955  if (it == myIntTable.end())
1956  return GA_INVALID_OFFSET;
1957  return it->second;
1958  }
1960  {
1962  if (!myStringTable.findSymbol(v, &off))
1963  return GA_INVALID_OFFSET;
1964  return off;
1965  }
1966 
1967  int64 getMemoryUsage(bool inclusive) const
1968  {
1969  int64 mem = inclusive ? sizeof(*this) : 0;
1970 
1971  mem += myStringTable.getMemoryUsage(false);
1972  mem += UTgetMemoryUsage(myIntTable, false);
1973 
1974  return mem;
1975  }
1976 
1977  private:
1978 
1979  UT_SymbolMap<GA_Offset> myStringTable;
1980  UT_Map<int, GA_Offset> myIntTable;
1981  };
1982 
1983 protected:
1984  /// Register intrinsic attributes
1987 
1988 private:
1989  int twist (const GU_TwistParms &parms, int &p);
1990  int bend (const GU_TwistParms &parms, int &p);
1991  int squashStretch (const GU_TwistParms &parms, int &p);
1992  int shear (const GU_TwistParms &parms, int &p);
1993  int taper (const GU_TwistParms &parms, int &p);
1994  int linearTaper (const GU_TwistParms &parms, int &p);
1995 
1996  template <typename ArrayType>
1997  GEO_Curve * privateInterpCurveGlobal(
1998  const ArrayType &gpData,
1999  const GA_PrimitiveTypeId &type,
2000  int order, int wrapped,
2001  GA_ParameterizationType parmType,
2002  GA_KnotSpaceType knotSpaceType);
2003 
2004  void fillGrid(GEO_Hull &hull, int rows, int cols,
2005  float x_size, float y_size,
2006  float x_center, float y_center,
2007  float z_center,
2008  GU_OrientationType plane);
2009 
2010  void convertPolysToHull(
2011  GEO_ConvertParms &parms,
2012  bool keep_original);
2013  void convertToSoups(
2014  GEO_ConvertParms &parms,
2015  bool keep_original);
2016  void convertVolumesToVDBs(
2017  GEO_ConvertParms &parms,
2018  bool keep_original);
2019  void convertVDBsToVolumes(
2020  GEO_ConvertParms &parms,
2021  bool keep_original);
2022  void convertVolumesToPolys(
2023  GEO_ConvertParms &parms,
2024  bool keep_original);
2025  void convertMetasToPolys(
2026  GEO_ConvertParms &parms,
2027  bool keep_original);
2028  void convertTetsToPolys(
2029  GEO_ConvertParms &parms,
2030  bool keep_original);
2031  void doConversion(
2032  GEO_ConvertParms &parms,
2033  bool keep_original);
2034 
2035  void orientPoly(GEO_PrimPoly *poly,
2036  UT_BitArray &process,
2037  UT_BitArray &reverse);
2038 
2039  GEO_Primitive *surfCube(int xdiv, int ydiv, int zdiv,
2040  int orderx, int ordery, int orderz,
2041  float xmin, float xmax,
2042  float ymin, float ymax,
2043  float zmin, float zmax,
2044  GEO_SurfaceType type, int kind,
2045  bool consolidate);
2046 
2047  // Checks if a single primitive is dirty (see getDirtyData).
2048  bool isDirtySinglePrimitive(GA_Primitive *prim,
2049  bool checkRepPoints,
2050  float tol);
2051 
2052  void lodConvert(GA_PrimitiveGroup *grp,
2053  UT_BoundingBox &box, int cluster, float lod,
2054  bool makepolysoup = false);
2055  void divisionConvert(GA_PrimitiveGroup *grp, int adjust,
2056  UT_BoundingBox &box, int divx,int divy,int divz,
2057  const UT_Array<GA_PrimitiveGroup *> &groups,
2058  bool makepolysoup = false);
2059  int adjustStepBox(float &min, float &max, float step);
2060  void stepSizeConvert(GA_PrimitiveGroup *grp, int adjust,
2061  UT_BoundingBox &box, float sx,float sy,float sz,
2062  const UT_Array<GA_PrimitiveGroup *> &groups,
2063  bool makepolysoup = false);
2064 
2065  /// makes a single primitive planar (see makePrimsPlanar)
2066  bool primToPlane(GEO_Primitive *pprim,
2067  UT_Set<GA_Offset> *fixedPoints = 0);
2068 
2069  /// Prohibited to avoid accidentally passing by value.
2070  /// Use constructor that takes a const GU_Detail * if you
2071  /// really need to construct a copied detail.
2072  GU_Detail(const GU_Detail &src);
2073 
2074  friend class GU_PrimitiveFactory; // For intrinsic registration
2075 
2076  void construct()
2077  {
2078  myBoundingCache = NULL;
2079  myValueLookupCache = NULL;
2080  }
2081 
2082  /// The sole user selection associated with this detail. This is stored
2083  /// here as a convenience for the drawing code.
2084  GU_SelectionHandle myUserSelection;
2085 
2086  /// The sole cook selection associated with this detail.
2087  GU_SelectionHandle myCookSelection;
2088 
2089  class BoundingCache; // Forward declare
2090  BoundingCache *myBoundingCache;
2091 
2092  mutable gu_ValueLookupCache *myValueLookupCache;
2093 };
2094 
2095 #endif
virtual void clearCaches()
Definition: GA_Detail.h:1794
const GA_OffsetList * getStringOffsets(const UT_StringRef &v) const
Definition: GU_Detail.h:1905
A class to manage an ordered array which has fixed offset handles.
Definition: GA_IndexMap.h:63
#define SYSmax(a, b)
Definition: SYS_Math.h:1365
UT_ErrorSeverity getSeverity()
GA_API const UT_StringHolder dist
Definition of a geometry attribute.
Definition: GA_Attribute.h:189
SYS_VISIBILITY_EXPORT void newGeometryIO(void *)
int getIntValue(int idx) const
Definition: GU_Detail.h:1885
GU_MetricType
Definition: GU_Types.h:87
#define SYS_DEPRECATED(__V__)
Unsorted map container.
Definition: UT_Map.h:83
FromType find(ToType value, FromType s=FromType(0)) const
GU_DeformType
Definition: GU_Types.h:58
void merge(const GEO_Detail &src, const GA_PrimitiveGroup *primGrp=0, int mergePrimGroup=1, int insertPrimsAtHead=0, GA_GBPointRedirectArray *dest_to_src_ptarray=0, bool keep_internal_groups=true, GA_DataIdStrategy data_id_strategy=GA_DATA_ID_BUMP)
MatType shear(Axis axis0, Axis axis1, typename MatType::value_type shear)
Set the matrix to a shear along axis0 by a fraction of axis1.
Definition: Mat.h:683
const hboost::disable_if_c< VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:128
#define SYS_VISIBILITY_EXPORT
GLint left
Definition: glcorearb.h:2004
GA_DataIdStrategy
Definition: GA_Types.h:186
const GLdouble * v
Definition: glcorearb.h:836
png_infop int * unit
Definition: png.h:2536
const UT_IntArray & ringValence() const
Definition: GU_Detail.h:208
virtual GA_Detail * cloneEmptyDetail(bool clone_attributes) const =0
SYS_VISIBILITY_EXPORT void newGeometryPrim(GA_PrimitiveFactory *factory)
void reversePrimitiveList()
Definition: GU_Detail.h:926
Arbitrarily Oriented Bounding (OBB)
Definition: UT_OBBox.h:25
GLint level
Definition: glcorearb.h:107
A soup of polygons.
void reversePointList()
Definition: GU_Detail.h:924
OnlyConsGroupPropagateType
Definition: GU_Detail.h:473
UT_ErrorSeverity
Definition: UT_Error.h:25
GA_Offset getStringOffset(const UT_StringRef &v) const
Definition: GU_Detail.h:1959
void shiftPrimitiveList(GA_Size aoffset)
Definition: GU_Detail.h:913
int64 getMemoryUsage(bool inclusive) const
Definition: GU_Detail.h:1967
UT_API UT_ErrorManager * UTgetErrorManager()
void addWarning(GU_ErrorCodes code, const char *msg=0) const
Definition: GU_Detail.h:1614
Structure for the PolySouping code.
png_uint_32 i
Definition: png.h:2877
UT_ErrorSeverity addError(const char *type, int code, const char *msg=0, const UT_SourceLocation *loc=0)
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:211
SnapAttributesType
Definition: GU_Detail.h:557
GLsizeiptr size
Definition: glcorearb.h:663
GU_GridType
Definition: GU_Types.h:70
const UT_Array< GA_OffsetArray > & myRingZero
Definition: GU_Detail.h:212
#define GA_INVALID_OFFSET
Definition: GA_Types.h:654
MapType::const_iterator const_map_iterator
png_infop png_bytep * trans
Definition: png.h:2520
A range of elements in an index-map.
Definition: GA_Range.h:42
GA_ParameterizationType
Definition: GA_Types.h:173
GU_LatticeType
Definition: GU_Types.h:109
const hboost::disable_if_c< VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:132
int divs(int x, int y)
Definition: ImathFun.h:180
GU_AxisType
Definition: GU_Types.h:24
GA_Size GA_Offset
Definition: GA_Types.h:617
long long int64
Definition: SYS_Types.h:106
GLdouble n
Definition: glcorearb.h:2007
GR_API RE_Geometry * buildGrid(RE_Render *r, UT_Vector3F center, UT_Vector2F size, Orientation orient, const char *cache_name=NULL)
GU_Detail(const GU_Detail *src, GA_DataIdStrategy data_id_strategy=GA_DATA_ID_BUMP)
Definition: GU_Detail.h:159
T distance(const UT_Vector4T< T > &v1, const UT_Vector4T< T > &v2)
Definition: UT_Vector4.h:634
int64 exint
Definition: SYS_Types.h:115
virtual void countMemory(UT_MemoryCounter &counter, bool inclusive) const
static const UT_StringHolder theEmptyString
int method
Definition: png.h:1924
GLsizei GLsizei GLchar * source
Definition: glcorearb.h:802
GLintptr offset
Definition: glcorearb.h:664
const GA_IndexMap & getIndexMap(GA_AttributeOwner owner) const
NURBS basis classes which maintain knot vectors.
Definition: GA_NUBBasis.h:44
void shiftPointList(GA_Size aoffset)
Definition: GU_Detail.h:911
virtual void statVolumes(GA_Stat &stat, uint level=0xffff) const
Fill out only the volume information.
T angle(const Vec2< T > &v1, const Vec2< T > &v2)
Definition: Vec2.h:480
void sortPointList(fpreal *order)
Definition: GU_Detail.h:895
void sortPointList(int seed)
Definition: GU_Detail.h:886
#define GU_API
Definition: GU_API.h:11
int64 UTgetMemoryUsage(const UT_ConcurrentHashMap< K, V, H, A > &map, const bool inclusive)
GLboolean * data
Definition: glcorearb.h:130
#define SYS_DEPRECATED_HDK(__V__)
void sortPrimitiveList(const UT_Vector3 &o, const UT_Vector3 &d)
Definition: GU_Detail.h:877
void sortPointList(const UT_Vector3 &o, const UT_Vector3 &d)
Definition: GU_Detail.h:875
UT_Array< GU_SplitLoc * > GU_SplitLocArray
Definition: GU_Detail.h:119
virtual int open(float queuesize)
GA_API const UT_StringHolder transform
bool copy(const GEO_Detail &src, GEO_CopyMethod method=GEO_COPY_ONCE, bool this_parameter_is_ignored=true, bool keep_internal_groups=true, GA_DataIdStrategy data_id_strategy=GA_DATA_ID_BUMP)
GA_API const UT_StringHolder orient
unsigned int uint
Definition: SYS_Types.h:39
GU_OrientationType
Definition: GU_Types.h:32
GLint GLsizei count
Definition: glcorearb.h:404
GU_Detail(bool full_topology)
Definition: GU_Detail.h:139
void addMessage(GU_ErrorCodes code, const char *msg=0) const
Definition: GU_Detail.h:1609
IFDmantra py
Definition: HDK_Image.dox:266
double fpreal
Definition: SYS_Types.h:269
Class to return information about a GA_Detail.
Definition: GA_Stat.h:50
virtual bool smooth(GA_AttributeOperand &d, GA_AttributeOperand &min, GA_AttributeOperand &max, GA_AttributeOperand &t) const
d = SYSsmooth(min, max, t);
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER T clip(const T &p, const Box< T > &box)
Definition: ImathBoxAlgo.h:89
const UT_IntArray & myRingValence
Definition: GU_Detail.h:213
void sortPrimitiveList(int seed)
Definition: GU_Detail.h:888
UT_ErrorSeverity addWarning(const char *type, int code, const char *msg=0, const UT_SourceLocation *loc=0)
virtual int64 getMemoryUsage(bool inclusive) const
Compute memory usage (includes all shared memory)
GA_GroupType
An ordinal enum for the different types of groups in GA.
Definition: GA_Types.h:138
RingRef(const UT_Array< GA_OffsetArray > &ringzero, const UT_IntArray &ringvalence)
Definition: GU_Detail.h:199
void proximityToPointList(const UT_Vector3 &point)
Definition: GU_Detail.h:936
void transformBreakpoints(const UT_Matrix4T< FLOAT_T > &mat, const GA_BreakpointGroup *grp=0, bool just_P=false, bool update_ptnormals=false, GEO_Delta *geodelta=0, bool updateaffectednormals=false, const char *attribpattern=NULL)
static GA_IntrinsicManager::Registrar registerIntrinsics(GA_PrimitiveFactory &factory)
GU_API GA_PrimitiveFactory & GUgetFactory()
void sortPrimitiveList(GU_AxisType axis)
Definition: GU_Detail.h:857
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
GEO_SurfaceType
Container class for all geometry.
Definition: GA_Detail.h:96
const UT_Array< GA_OffsetArray > & ringZero() const
Definition: GU_Detail.h:206
#define SYS_FTOLERANCE
Definition: SYS_Types.h:202
const UT_StringHolder & getStringHolder(int idx) const
Definition: GU_Detail.h:1891
void proximityToPrimitiveList(const UT_Vector3 &point)
Definition: GU_Detail.h:938
void sortPointList(GU_AxisType axis)
Definition: GU_Detail.h:855
GU_TextureType
Definition: GU_Types.h:94
#define const
Definition: zconf.h:214
void sortByVertexOrder()
Definition: GU_Detail.h:946
GU_Detail(const GU_Detail *src, GA_PrimitiveGroup *primGroup, GA_DataIdStrategy data_id_strategy=GA_DATA_ID_BUMP)
Definition: GU_Detail.h:146
int64 getMemoryUsage(bool inclusive) const
Definition: GU_Detail.h:1913
void sortPrimitiveList(fpreal *order)
Definition: GU_Detail.h:897
GA_Offset getIntOffset(int v) const
Definition: GU_Detail.h:1951
GA_API const UT_StringHolder rest
GA_KnotSpaceType
Definition: GA_Types.h:166
Base::const_iterator const_iterator
Definition: UT_Map.h:94
GLint lod
Definition: glcorearb.h:2764
GU_ErrorCodes
Definition: GU_Error.h:20
void addError(GU_ErrorCodes code, const char *msg=0) const
Definition: GU_Detail.h:1619
UT_ErrorSeverity addMessage(const char *type, int code, const char *msg=0, const UT_SourceLocation *loc=0)
const GA_OffsetList * getIntOffsets(int v) const
Definition: GU_Detail.h:1897
GLenum src
Definition: glcorearb.h:1792