10 #ifndef __GU_GroomUtils_h__
11 #define __GU_GroomUtils_h__
34 findOrCreateFloatAttribute(
43 findOrCreateIntAttribute(
52 findOrCreateStringAttribute(
113 static void getPrimPointPositions(
120 static void setPrimPointPositions(
128 static float unitLengthToUnitDomain(
134 static float unitToUnitLengthDomain(
139 static float unitLengthToUnitDomain(
147 if (n <= 0 || !u_unit)
return 0.0f;
149 if (u_unit < 0.0
f) u_unit = 0.0f;
150 else if (u_unit > 1.0
f) u_unit = 1.0f;
152 return u_unit *
float(n-1);
160 return { {0.0f, 0.0f}, {-1, -1} };
165 return { {1.0f, 0.0f}, {0, -1} };
168 u = openCurveUnitToReal(n, u);
173 if (rem == 0 || vcrt == vseq) {
174 return { {1.0f, 0.0f}, {vcrt, -1} };
190 const T defaultvalue=
T(0.0
f));
216 void setDim(
int pointcount,
int attribcount,
int guidecount)
218 myPointCount = pointcount;
219 myAttribCount = attribcount;
220 myGuideCount = guidecount;
221 myQuats.setSize(attribcount * pointcount * guidecount);
227 int index = pointindex * (myAttribCount * myGuideCount)
228 + attribindex * myGuideCount
238 int index = getLinearIndex(pointindex, attribindex, guideindex);
240 return myQuats[
index];
247 int index = getLinearIndex(pointindex, attribindex, guideindex);
249 myQuats[
index] = quat;
260 int myPointCount = 0;
261 int myAttribCount = 0;
262 int myGuideCount = 0;
273 const int guideindex,
274 const float guideweight,
285 const bool uniformguidesegments,
296 QuatInterpTempStorage &quattemp,
300 removeNonGuidesFromGroup(
305 removeHiddenPrimitivesFromGroup(
310 setGuideGroupMembers(
333 if (mode == SetLengthMode::SETMIN)
335 return SYSmin(prevlength, value);
337 else if (mode == SetLengthMode::SETMAX)
339 return SYSmax(prevlength, value);
341 else if (mode == SetLengthMode::ADD)
343 return (prevlength+value);
345 else if (mode == SetLengthMode::SUBTRACT)
347 return (prevlength-value);
349 else if (mode == SetLengthMode::SET)
385 circlePackRootPoints(
411 computeTangentFrames(
438 for(
GA_PageNum pagenum(0); pagenum < numpages; ++pagenum)
451 bool skinprimfail =
false;
453 ? constgdp.getPointRange(dynamic_cast<const GA_PointGroup*>(group))
454 : constgdp.getPrimitiveRange(dynamic_cast<const GA_PrimitiveGroup*>(group));
466 for (
GA_Offset off = startoff; off < endoff; ++off)
469 if (skinprimindex < 0 ||
479 return !skinprimfail;
489 GA_Attribute* keyattrib = findOrCreateStringArrayAttribute(
490 gdp, owner, name_attrib_name, 1);
492 GA_Attribute* weightattrib = findOrCreateFloatArrayAttribute(
493 gdp, owner, weight_attrib_name, 1);
505 GA_Attribute* keyattrib = findOrCreateIntArrayAttribute(
506 gdp, owner, name_attrib_name, 1);
508 GA_Attribute* weightattrib = findOrCreateFloatArrayAttribute(
509 gdp, owner, weight_attrib_name, 1);
526 return myAttribMissing;
531 return myAttribMissingWarning;
540 bool myAttribMissing =
false;
559 : myRayIntersect(rayintersect)
560 , mySkinGdp(*rayintersect.detail())
561 , mySkinP(mySkinGdp.getP())
567 : myRayIntersect(rayintersect)
568 , mySkinGdp(*rayintersect.detail())
569 , mySkinP(mySkinGdp.getP())
582 return myRayIntersect;
591 int hitcount = myRayIntersect.minimumPoint(pos, mininfo);
597 hitcount = myRayIntersect.minimumPoint(pos, mininfo);
606 int hits = myRayIntersect.sendRay(pos, dir, info);
653 return interpAttrib(mySkinP, interpcoords);
662 UT_Vector3 normal = interpAttrib(mySkinN, interpcoords);
676 if (!closestPointInfo(pos, mininfo))
679 computeVertWeights(mininfo, interpcoords);
681 pos = interpAttrib(mySkinP, interpcoords);
701 dist2s.setSize(size);
711 : myMaxPartLines(maxpartlines)
715 unsigned int maxpartlines,
717 : myMaxPartLines(maxpartlines)
750 computePartingWeight(
754 PerThreadData &threadvalues,
759 return myLineOffsets(2 *
id);
764 return myLineOffsets(2 *
id + 1);
769 int64 size(inclusive ?
sizeof(*
this) : 0);
771 size += myLineOffsets.getMemoryUsage(
true);
780 const unsigned int myMaxPartLines;
792 , mySrcGdp(srcgdp != nullptr ? *srcgdp : dstgdp)
793 , myAttribMap(myDstGdp, &mySrcGdp)
794 , myLengthScaledAttribMap(myDstGdp, &mySrcGdp)
801 addAttribToMap(myAttribMap, name);
807 addAttribToMap(myLengthScaledAttribMap, name);
829 srcpoly =
static_cast<const GEO_PrimPoly *
>(srcgeoprim);
831 sampleAttribs(dstprimpoly, *srcpoly, blend);
861 bool enable_multithreading=
true);
867 bool enable_multithreading=
true)
876 bool enable_multithreading=
true)
886 : myNumSamples(numsamples)
891 return mySamples == ramp.mySamples
892 && myNumSamples == ramp.myNumSamples
893 && myIsConstant == ramp.myIsConstant;
898 return !(*
this == ramp);
901 bool update(
const UT_Ramp *widthramp);
911 float us = u * (mySamples.size()-1);
913 if (indexA == mySamples.size()-1)
914 return mySamples(indexA);
915 int indexB = indexA + 1;
916 return SYSlerp(mySamples(indexA), mySamples(indexB), us - indexA);
923 exint(u * (mySamples.size()-1) + 0.5),
926 return mySamples(index);
934 bool myIsConstant =
false;
946 , destowner(destowner)
951 void addSourceAttribs(
953 const char *matchpattern,
981 mapAndCreateAttribs(map,
nullptr);
985 void mapAndCreateAttrib(
997 for (
int i = 0; i < sourceattribs.size(); ++i)
998 mapAndCreateAttrib(map, changes, i);
1009 for (
int i = 0; i < sourceattribs.size(); ++i)
1010 if (
filter(*sourceattribs[i]))
1011 mapAndCreateAttrib(map, changes, i);
1019 static auto &&theFilter = [](
const GA_Attribute &attrib)
1024 mapAndCreateAttribs(map, changes, theFilter);
1032 static auto &&theFilter = [](
const GA_Attribute &attrib)
1037 mapAndCreateAttribs(map, changes, theFilter);
1045 CacheData* getCacheData()
const;
1064 bind(detail, attrib_owner, key_attrib_name, weight_attrib_name);
1155 if (!key_attrib || !weight_attrib)
1194 bind(detail, attrib_owner, key_attrib_name, weight_attrib_name);
1203 return bindImpl(detail, attrib_owner, key_attrib_name, weight_attrib_name);
1210 bindImpl(key_attrib, weight_attrib);
1265 : myWeightGeo(weightgeo)
1274 : myWeightGeo(weightgeo)
1276 myInputAttribs.
bind(
1280 weight_attrib_name);
1287 : myWeightGeo(weightgeo)
1289 myInputAttribs.
bind(
1299 return myInputAttribs.
bind(
1303 weight_attrib_name);
1327 return myInputAttribs;
1335 bool key_is_string =
false;
1352 gdp, owner, key_name, weight_name);
1358 gdp, owner, key_name, weight_name);
1361 myOutputAttribs.
bind(keyattrib, weightattrib);
1370 bool success =
false;
1371 if (myInputAttribs.
nameArray() !=
nullptr)
1407 template<
typename C>
1418 blended_weights_set.
clear();
1422 for (
int i=0; i<offsets.
size(); ++i)
1425 float pw = weights[i];
1430 if constexpr(SYS_IsSame_v<C, UT_StringArray>)
1441 T key = out_keys[
j];
1442 float w = out_weights[
j];
1444 blended_weights_set[key] =
1445 blended_weights_set.
get(key, 0.0
f) + pw *
w;
1451 float inv_pw_sum = SYSsaferecip(pw_sum);
1453 out_keys.setSize(0);
1455 for (
auto &wpair : blended_weights_set)
1457 out_keys.append(wpair.first);
1458 out_weights.
append(inv_pw_sum * wpair.second);
1505 for (
GA_Offset elemoff = startoff; elemoff < endoff; ++elemoff)
1507 GA_Index skinprimindex = prim_handle.
get(elemoff);
1509 if (skinprimindex < 0 || skinprimindex >= num_weight_prims)
1517 pt_offsets, pt_weights,
1523 for (
int i=0; i<pt_offsets.
size(); ++i)
1524 pt_offsets[i] = myWeightGeo.
vertexPoint(pt_offsets[i]);
1528 pt_offsets, pt_weights,
1531 index_array->
set(&key_attrib, elemoff, indices);
1532 weight_array->
set(&weight_attrib, elemoff, weights);
GU_GroomCurveAttribSampler(GU_Detail &dstgdp, const GU_Detail *srcgdp=nullptr)
GA_Attribute * myWeightAttrib
SYS_FORCE_INLINE void bumpDataId()
SYS_FORCE_INLINE const GA_Detail & getDetail() const
void interpolate(const GA_OffsetArray &offsets, const UT_FloatArray &weights, GA_Offset &out_offset, TempData &tempdata) const
SYS_FORCE_INLINE const GA_PrimitiveGroup * findPrimitiveGroup(const UT_StringRef &name) const
Definition of a geometry attribute.
void UTparallelFor(const Range &range, const Body &body, const int subscribe_ratio=2, const int min_grain_size=1, const bool force_use_task_scope=true)
SYS_FORCE_INLINE GA_Offset getPrimitiveVertexOffset(GA_Offset primoff, GA_Size i) const
GU_GroomSourceAttribList(GU_Detail *dest, const GU_Detail *source, const GA_AttributeOwner destowner)
bool set(GA_Attribute *attrib, GA_Offset o, const UT_StringArray &v) const
UT_Map< GA_Size, float > tempindexset
GU_WeightArrayInterpolate(const GEO_Detail &weightgeo, GA_AttributeOwner attrib_owner, const UT_StringRef &key_attrib_name, const UT_StringRef &weight_attrib_name)
GLsizei GLenum const void * indices
Generic Attribute Interface class to access an attribute as a array.
GA_Range getVertexRange(const GA_VertexGroup *group=0) const
Get a range of all vertices in the detail.
const GA_AIFNumericArray * weightArray() const
GA_Attribute * keyAttrib() const
Iteration over a range of elements.
bool bindInputAttribs(GA_AttributeOwner attrib_owner, const UT_StringRef &key_attrib_name, const UT_StringRef &weight_attrib_name)
static GA_Attribute * findOrCreateIntArrayAttribute(GU_Detail &gdp, GA_AttributeOwner owner, const UT_StringRef &name, int tsize, GA_Storage storage=GA_STORE_INT32)
Class which stores the default values for a GA_Attribute.
GU_GroomSkinIntersect(const GU_RayIntersect &rayintersect, const GA_Attribute &normal)
void bindImpl(GA_Attribute *key_attrib, GA_Attribute *weight_attrib)
virtual void computeInteriorPointWeights(UT_Array< GA_Offset > &vtxlist, UT_Array< float > &weightlist, fpreal u, fpreal v, fpreal w) const
getFileOption("OpenEXR:storage") storage
const DataType & getData() const
static GA_PrimitiveGroup * findGroup(GU_Detail &gdp)
GA_Offset getLineOffset1(int id) const
SYS_FORCE_INLINE const GA_IndexMap & getIndexMap() const
bool blockAdvance(GA_Offset &start, GA_Offset &end)
GLsizei const GLfloat * value
SYS_FORCE_INLINE bool closestPos(UT_Vector3 &pos, GU_MinInfo &mininfo, GU_GroomInterpCoords &interpcoords)
void mapAndCreateNonRealAttribs(GA_AttributeRefMap &map, const UT_ValArray< AttribChange > *changes) const
SYS_FORCE_INLINE T * SYSconst_cast(const T *foo)
SYS_FORCE_INLINE UT_Vector3 interpP(const GU_GroomInterpCoords &interpcoords) const
SYS_FORCE_INLINE bool isConstant()
GU_GroomPartingLineLookup(unsigned int maxpartlines, GU_GroomSkinIntersect *skinintersect)
SYS_FORCE_INLINE void setValue(int pointindex, int attribindex, int guideindex, UT_QuaternionF &quat)
GU_WeightArrayInterpolate(const GEO_Detail &weightgeo, const GA_Attribute &keyattrib, const GA_Attribute &weightattrib)
void build(const GEO_Detail *gdp, const GA_PointGroup *ptgroup=NULL, bool enable_multithreading=true)
std::pair< GA_AttributeOwner, UT_StringHolder > AttribMatchTuple
SYS_FORCE_INLINE void setDim(int pointcount, int attribcount, int guidecount)
SYS_FORCE_INLINE const GA_PrimitiveTypeId & getTypeId() const
void setPageConstant(GA_PageNum pagenum, const BASETYPE *values) const
GEO_ConstPrimitiveP myPrim
static UT_Tuple< GA_Attribute *, GA_Attribute * > createNameAndWeightArrayAttributes(GU_Detail &gdp, GA_AttributeOwner owner, const UT_StringHolder &name_attrib_name, const UT_StringHolder &weight_attrib_name)
static GA_PrimitiveGroup & findOrCreateGroup(GU_Detail &gdp)
const GU_RayIntersect & rayIntersect()
void createOutputAttribs(GU_Detail &gdp, GA_AttributeOwner owner)
const GA_Attribute * weightAttrib() const
GA_Attribute * addStringArray(GA_AttributeOwner owner, GA_AttributeScope scope, const UT_StringHolder &name, int tuple_size=1, const UT_Options *creation_args=0, const GA_AttributeOptions *attribute_options=0, GA_Storage storage=GA_STORE_STRING, const GA_ReuseStrategy &reuse=GA_ReuseStrategy())
GA_Offset getLineOffset2(int id) const
SYS_FORCE_INLINE const UT_QuaternionFArray & getData()
std::tuple< Types...> UT_Tuple
void addAttrib(const UT_StringRef &name)
void mapAndCreateAttribs(GA_AttributeRefMap &map) const
bool bind(const GEO_Detail &detail, GA_AttributeOwner attrib_owner, const UT_StringHolder &key_attrib_name, const UT_StringHolder &weight_attrib_name)
UT_Matrix2T< T > SYSlerp(const UT_Matrix2T< T > &v1, const UT_Matrix2T< T > &v2, S t)
const GA_Attribute * weightAttrib() const
UT_UniquePtr< GU_GroomPartingLineAttribs > gu_PartingLineAttribsUPtr
V get(const key_type &key, const V &defval) const
GU_RWWeightArrayPairHandle()=default
static SYS_FORCE_INLINE void computeVertWeights(const GU_MinInfo &mininfo, GU_GroomInterpCoords &interpcoords)
void setSize(exint newsize)
exint GA_Size
Defines the bit width for index and offset types in GA.
#define GA_INVALID_OFFSET
A range of elements in an index-map.
bool bindImpl(GEO_Detail &detail, GA_AttributeOwner attrib_owner, const UT_StringHolder &key_attrib_name, const UT_StringHolder &weight_attrib_name)
GA_PrimitiveGroup * newPrimitiveGroup(const UT_StringHolder &name)
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
void mapAndCreateAttribs(GA_AttributeRefMap &map, const UT_ValArray< AttribChange > *changes) const
GLuint GLsizei const GLuint const GLintptr * offsets
SYS_FORCE_INLINE const UT_StringHolder & getName() const
const GA_AIFNumericArray * myIndexArray
const GA_Attribute * findIntArray(GA_AttributeOwner owner, GA_AttributeScope scope, const UT_StringRef &name, int min_size=1, int max_size=-1) const
SYS_FORCE_INLINE GEO_Primitive * getGEOPrimitive(GA_Offset primoff)
GA_Attribute * addFloatArray(GA_AttributeOwner owner, GA_AttributeScope scope, const UT_StringHolder &name, int tuple_size=1, const UT_Options *creation_args=0, const GA_AttributeOptions *attribute_options=0, GA_Storage storage=GA_STORE_REAL32, const GA_ReuseStrategy &reuse=GA_ReuseStrategy())
const GA_ATINumeric * getAttribute() const
constexpr SYS_FORCE_INLINE T & x() noexcept
void mapAndCreateAttribs(GA_AttributeRefMap &map, const UT_ValArray< AttribChange > *changes, const std::function< bool(const GA_Attribute &)> &filter) const
static bool checkSkinPrimIndices(const GA_ROHandleI &skinprimattrib, const GU_Detail &skingdp, const GA_ElementGroup *group=nullptr)
vint4 blend(const vint4 &a, const vint4 &b, const vbool4 &mask)
static SYS_FORCE_INLINE GA_Offset primVertexOffset(const GU_Detail &gdp, GA_Offset primoff, GA_Size index=0)
static SYS_FORCE_INLINE void computeVertWeights(const GU_RayInfo &hitinfo, GU_GroomInterpCoords &interpcoords)
GA_Attribute * addIntArray(GA_AttributeOwner owner, GA_AttributeScope scope, const UT_StringHolder &name, int tuple_size=1, const UT_Options *creation_args=0, const GA_AttributeOptions *attribute_options=0, GA_Storage storage=GA_STORE_INT32, const GA_ReuseStrategy &reuse=GA_ReuseStrategy())
GU_ROWeightArrayPairHandle(const GEO_Detail &detail, GA_AttributeOwner attrib_owner, const UT_StringHolder &key_attrib_name, const UT_StringHolder &weight_attrib_name)
const GA_Attribute * findStringArray(GA_AttributeOwner owner, GA_AttributeScope scope, const UT_StringRef &name, int min_size=1, int max_size=-1) const
GA_Range getPointRange(const GA_PointGroup *group=0) const
Get a range of all points in the detail.
void addLengthScaledAttrib(const UT_StringRef &name)
GA_Range getGlobalRange() const
Get a range representing the global (detail) data.
IMATH_NAMESPACE::V2f float
const GU_ROWeightArrayPairHandle & getWeightArrayPairHandle() const
bool operator!=(const GU_GroomFastRamp &ramp) const
void sampleAttribs(const GEO_PrimPoly &dstprimpoly, GA_Offset sourceprimoff, float blend)
static SYS_FORCE_INLINE UT_PageNum numPages(IDX_T nelements)
const GA_Attribute * keyAttrib() const
const GA_Attribute * keyAttrib() const
SYS_FORCE_INLINE const UT_QuaternionF & getValue(int pointindex, int attribindex, int guideindex)
UT_Vector3T< T > SYSclamp(const UT_Vector3T< T > &v, const UT_Vector3T< T > &min, const UT_Vector3T< T > &max)
GLsizei GLsizei GLchar * source
GA_API const UT_StringHolder perimeter
A specialization of GA_AIFStringArray to access "shared strings".
A handle to simplify manipulation of multiple attributes.
static float openCurveUnitToReal(int n, float u_unit)
virtual const GA_AIFSharedStringArray * getAIFSharedStringArray() const
Return the attribute's shared string array interface or NULL.
SYS_FORCE_INLINE int getLinearIndex(int pointindex, int attribindex, int guideindex)
GU_GroomInterpCoords interpcoords
SYS_FORCE_INLINE T get(GA_Offset off, int comp=0) const
SYS_FORCE_INLINE GA_Offset vertexPoint(GA_Offset vertex) const
Given a vertex, return the point it references.
UT_Map< UT_StringHolder, float > tempnameset
T interpAttrib(const GA_ROHandleT< T > &attrib, const GU_GroomInterpCoords &interpcoords) const
GLuint const GLchar * name
void build(const GEO_Detail *gdp, const GA_PointGroup *ptgroup, bool enable_multithreading=true)
void interpolate(const GU_Detail &geo, const GA_Attribute &prim_attrib, const GA_Attribute &primuv_attrib, GA_Attribute &key_attrib, GA_Attribute &weight_attrib) const
GA_Size GA_Index
Define the strictness of GA_Offset/GA_Index.
static fpreal computeNewLength(fpreal prevlength, SetLengthMode mode, fpreal value)
void setArraySize(unsigned int size)
SYS_FORCE_INLINE UT_Vector3 interpN(const GU_GroomInterpCoords &interpcoords) const
bool bind(GEO_Detail &detail, GA_AttributeOwner attrib_owner, const UT_StringHolder &key_attrib_name, const UT_StringHolder &weight_attrib_name)
void interpolate(C &out_keys, UT_Array< float > &out_weights, const GA_OffsetArray &offsets, const UT_FloatArray &weights, UT_Map< typename C::value_type, float > &blended_weights_set) const
static UT_Tuple< UT_Vector2, UT_Vector2i > openCurvePointWeights(int n, fpreal u)
SYS_FORCE_INLINE const GU_Detail & detail()
GU_GroomPartingLineLookup(unsigned int maxpartlines)
GU_GroomFastRamp(int numsamples=1000)
const GA_AIFSharedStringArray * nameArray() const
int64 getMemoryUsage(bool inclusive) const
GA_Attribute * myKeyAttrib
const GA_AIFNumericArray * myWeightArray
void build(const GEO_Detail *gdp, const GA_PointGroup *ptgroup, const char *attrib, bool enable_multithreading=true)
GU_RWWeightArrayPairHandle(GEO_Detail &detail, GA_AttributeOwner attrib_owner, const UT_StringHolder &key_attrib_name, const UT_StringHolder &weight_attrib_name)
virtual bool get(const GA_Attribute *attrib, GA_Offset ai, UT_Array< fpreal16 > &data) const =0
static SYS_FORCE_INLINE GA_Offset primPointOffset(const GU_Detail &gdp, GA_Offset primoff, GA_Size index=0)
GLenum GLsizei GLsizei GLint * values
const UT_StringHolder & attribMissingWarning()
bool operator==(const GU_GroomFastRamp &ramp) const
GA_Attribute * weightAttrib() const
GU_ROWeightArrayPairHandle()=default
SYS_FORCE_INLINE GA_Offset primitiveOffset(GA_Index index) const
Given a primitive's index (in append order), return its data offset.
Utility class for containing a color ramp.
virtual bool set(GA_Attribute *attrib, GA_Offset ai, const UT_Span< const fpreal16 > &data) const =0
const GA_AIFNumericArray * indexArray() const
bool get(const GA_Attribute *attrib, GA_Offset o, UT_StringArray &v) const
UT_ValArray< GA_Size > outindices
SYS_FORCE_INLINE GA_Size getNumPrimitives() const
Return the number of primitives.
SYS_FORCE_INLINE float lookup(float u) const
const GA_Attribute * findFloatArray(GA_AttributeOwner owner, GA_AttributeScope scope, const UT_StringRef &name, int min_size=1, int max_size=-1) const
SYS_FORCE_INLINE GA_AttributeOwner getOwner() const
const GA_AIFSharedStringArray * myNameArray
static fpreal getIndices(fpreal c, int &c1, int &c2, int max_index, int wrap)
GLubyte GLubyte GLubyte GLubyte w
static T interpAttrib(const GA_ROHandleT< T > &attrib, const GA_Offset &primoff, const GA_OffsetArray &vertoffsets, const UT_FloatArray &vertweights, const T defaultvalue=T(0.0f))
static GA_Attribute * findOrCreateStringArrayAttribute(GU_Detail &gdp, GA_AttributeOwner owner, const UT_StringRef &name, int tsize)
static const GA_PrimitiveGroup * findGroup(const GU_Detail &gdp)
void set(GA_Offset primoff, const UT_StringArray &names, const UT_FloatArray &weights)
static void setPagesConstant(GA_RWHandleF attribhandle, float value)
GA_Range getPrimitiveRange(const GA_PrimitiveGroup *group=0) const
Get a range of all primitives in the detail.
void mapAndCreateRealAttribs(GA_AttributeRefMap &map, const UT_ValArray< AttribChange > *changes) const
static UT_Tuple< GA_Attribute *, GA_Attribute * > createIndexAndWeightArrayAttributes(GU_Detail &gdp, GA_AttributeOwner owner, const UT_StringHolder &name_attrib_name, const UT_StringHolder &weight_attrib_name)
static GA_Attribute * findOrCreateFloatArrayAttribute(GU_Detail &gdp, GA_AttributeOwner owner, const UT_StringRef &name, int tsize, GA_Storage storage=GA_STORE_REAL32)
constexpr SYS_FORCE_INLINE T & y() noexcept
GU_WeightArrayInterpolate(const GEO_Detail &weightgeo)
SYS_FORCE_INLINE bool hitPointInfo(UT_Vector3 pos, UT_Vector3 dir, GU_RayInfo &info)
SYS_FORCE_INLINE GA_Offset offsetSize() const
SYS_FORCE_INLINE bool closestPointInfo(const UT_Vector3 &pos, GU_MinInfo &mininfo) const
void bind(GA_Attribute *key_attrib, GA_Attribute *weight_attrib)
SYS_FORCE_INLINE float lookupNearest(float u) const
GU_GroomSkinIntersect(const GU_RayIntersect &rayintersect)
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
void bind(const GA_Attribute *key_attrib, const GA_Attribute *weight_attrib)
virtual const GA_AIFNumericArray * getAIFNumericArray() const
Return the attribute's arraydata interface or NULL.