10 #ifndef __GU_Feather_h__
11 #define __GU_Feather_h__
24 #include <type_traits>
36 using is_int = std::is_integral<V>;
39 using is_flt = std::is_floating_point<V>;
60 template<
typename ValueType>
79 if (attrib !=
nullptr)
89 if (attrib !=
nullptr)
115 return myAttrib !=
nullptr;
139 if (value_tuple_size == 0)
142 return myTupleSize / value_tuple_size;
146 template<
class V = ValueType>
151 array.bumpSize(numBarbPoints());
152 V *
data =
reinterpret_cast<V*
>(array.data());
153 myTuple->get(myAttrib,
offset, data, myTupleSize);
157 template<
class V = ValueType>
163 array.bumpSize(numBarbPoints());
164 ScalarType *
data =
reinterpret_cast<ScalarType*
>(array.data());
165 myTuple->get(myAttrib,
offset, data, myTupleSize);
180 barb = orient.
rotate(barb);
199 barb = orient.
rotate(barb);
243 return myOrient.get(offset);
254 myTuple->get(myAttrib, ptoff, reinterpret_cast<fpreal32*>(data.
data()), 3, myTupleSize-3);
268 myAttrib->bumpDataId();
285 return myDetail->findFloatTuple(
300 template<
typename ValueType>
314 :
Base(gdp, pos, orient, name)
337 template<
class V = ValueType>
343 const ScalarType *
data =
reinterpret_cast<const ScalarType*
>(array);
344 myTuple->set(myAttrib, offset, data, myTupleSize);
348 template<
class V = ValueType>
354 const ScalarType *
data =
reinterpret_cast<const ScalarType*
>(array);
358 myTuple->get(myAttrib, offset, value, i);
360 value =
SYSlerp(value, data[i], alpha);
361 myTuple->set(myAttrib, offset, value, i);
366 template<
class V = ValueType>
371 const V *
data =
reinterpret_cast<const V*
>(array);
372 myTuple->set(myAttrib, offset, data, myTupleSize);
376 using Base::myTupleSize;
378 using Base::myAttrib;
398 myBarbSegs = barbsegs;
399 myData.setSize(ptcount * barbsegs);
405 myBarbSegs = barbsegs;
406 myData.bumpSize(ptcount * barbsegs);
413 return myData[flatIndex(
index, segindex)];
420 return &myData[flatIndex(index, 0)];
427 myData[flatIndex(index, segindex)] =
value;
435 for (
int seg=0; seg <
segs; ++seg)
437 myData[flatIndex(index, seg)] = value[seg];
445 myData[flatIndex(index, segindex)] +=
value;
457 for (
int i=0; i<myData.size()/myBarbSegs; ++i)
459 for (
int j=0;
j<myBarbSegs; ++
j)
470 flatIndex(
int index,
int segindex)
const
472 return index * myBarbSegs + segindex;
502 UT_ASSERT(myDetail.getNumPrimitives() == 0 || myCurveLengths.size() > 0);
504 return myCurveLengths;
510 UT_ASSERT(myDetail.getNumPrimitives() == 0 || myEdgeLengths.size() > 0);
512 return myEdgeLengths;
519 const TemplateOffsetMap&
523 UT_ASSERT(myDetail.getNumPrimitives() == 0 || myTemplateOffsetMap.size() > 0);
525 return myTemplateOffsetMap;
529 storeFirstBarbAttrib();
534 return myFirstBarbAttrib.
get();
563 : myTemplateDetail(templategdp)
564 , myTemplateSet(templateinterp)
566 myTemplateIdentifierAttrib =
569 if (myTemplateIdentifierAttrib !=
nullptr)
575 myTemplateIdentifierAttrib =
578 if (myTemplateIdentifierAttrib !=
nullptr)
582 myTemplateWeightsAttrib =
585 if (myTemplateWeightsAttrib !=
nullptr)
594 : myTemplateDetail(gdp)
595 , myTemplateSet(templateinterp)
596 , myTemplateIdentifierAttrib(&templatenamesattrib)
597 , myTemplateWeightsAttrib(&templateweightattrib)
607 (myTemplateNamesArray !=
nullptr ||
608 myTemplateIndicesArray !=
nullptr)
609 && myTemplateWeightArray !=
nullptr;
614 return myTemplateNamesArray !=
nullptr;
619 return myTemplateIndicesArray !=
nullptr;
625 return myTemplateDetail;
632 myTemplateNamesArray->get(myTemplateIdentifierAttrib, primoff, templatenames);
639 myTemplateIndicesArray->get(myTemplateIdentifierAttrib, primoff, templateindices);
646 myTemplateWeightArray->get(myTemplateWeightsAttrib, primoff, templateweights);
656 auto &templatemap = myTemplateSet.getTemplateOffsetMap();
658 for (
int i=0; i<templateoffsets.
size(); ++i)
660 auto templateiter = templatemap.find(templatenames[i]);
662 if (templateiter == templatemap.end())
665 templateoffsets[i] = templateiter->second;
676 for (
int i=0; i<templateindices.
size(); ++i)
680 if (index >= 0 && index < myTemplateDetail.getNumPrimitives())
681 templateoffsets[i] = myTemplateDetail.primitiveOffset(index);
701 templatemap[templatenameattrib.
get(primoff)] = primoff;
714 for (
int i=0; i<templatecount; ++i)
717 wsum += templateweights[i];
719 templateweights[i] = 0.0;
725 float invwsum = SYSsaferecip(wsum);
727 for (
int i=0; i<templatecount; ++i)
728 templateweights[i] *= invwsum;
737 if (hasTemplateNames())
746 else if (hasTemplateIndices())
762 getWeights(primoff, weights);
764 filterInvalid(offsets, weights);
766 normalizeWeights(offsets, weights);
780 float u =
float(i) / (vtxcount-1);
783 const GU_Detail &gdp = myTemplateSet.getDetail();
785 auto &
lengths = myTemplateSet.getCurveLengths();
786 auto &edgelengths = myTemplateSet.getEdgeLengths();
788 for (
int j=0;
j<templateoffsets.
size(); ++
j)
791 float w = templateweights[
j];
793 int tplfirstbarb = template_firstbarb_handle.
get(tploffset);
798 tmpu =
float(i) * tplfirstbarb / shaftsegs;
800 tmpu = (tplvtxcount-tplfirstbarb-1) *
float(i - shaftsegs) / (vtxcount-shaftsegs-1) + tplfirstbarb;
802 tmpu /= tplvtxcount - 1;
806 lengths[tplindex], edgelengths[tplindex], tmpu);
808 source_u += w * tmpu;
820 for (
int i=0; i<offsets.
size(); ++i)
826 offsets[
index] = offsets[i];
827 weights[
index] = weights[i];
841 const GA_Attribute *myTemplateIdentifierAttrib =
nullptr;
866 , from(from_detail, name)
875 : fromName(from_name)
877 , from(from_detail, from_name)
878 , to(detail, to_attrib)
886 : fromName(from_attrib.
getName())
888 , from(from_detail, from_attrib)
889 , to(detail, to_attrib)
918 if (barbside == BarbSide::LEFT)
920 else if (barbside == BarbSide::RIGHT)
930 buffer.
format(
"{}_barb{}", basename, getBarbSideString(barbside));
945 barbpts * value_tuplesize);
958 barbpts * value_tuplesize);
1012 populateBarbAttribMap(
1019 createDestBarbAttributes(
1027 createDestBarbAttributes(
1031 static void expandTemplateBarbAttribs(
1035 int shaft_base_segs,
1038 static void expandTemplateBarbAttribs(
1043 int shaft_base_segs,
1046 static void zeroBarbValues(
1088 template<
typename WVEC,
typename IVEC>
1102 if (firstindexhandle.
isValid())
1119 interpolateBarbAttribs(
1125 int shaft_base_segs,
1134 interpolateBarbAttribs(
1136 BarbAttribInterpolateTemp &temp,
1145 int shaft_base_segs,
1150 template<
typename T>
1151 static void interpolateVSubD(
1181 template<
typename T,
typename WVEC,
typename IVEC>
1182 static void interpolateV(
1220 template<
typename T>
1221 static void interpolateUSubD(
1225 const BarbInterpCoeffs &barb_coeffs,
1229 template<
typename WVEC,
typename IVEC>
1230 static void computeShaftCoeffs(
1234 int to_firstbarbindex,
1236 int from_firstbarbpt,
1239 static void computeBarbInterpCoeffs(
1242 BarbInterpCoeffs &interpdata);
1244 static void computeBarbInterpCoeffs(
1248 template<
typename T,
typename WVEC,
typename IVEC>
1249 static void interpolate(
1258 const BarbInterpCoeffs &barb_coeffs,
1262 template<
typename T>
1263 static void setBarbs(
1268 template<
typename T>
1269 static void blendBarbs(
1283 , myPos(myDetail.getP())
1284 , myOrient(
GU_GroomUtils::findNamedOrient(myDetail, orientname))
1285 , myBarbL(myDetail, myPos, myOrient,
GU_Feather::BarbLAttrib)
1286 , myBarbR(myDetail, myPos, myOrient,
GU_Feather::BarbRAttrib)
1295 &myDetail, primoff, myDetail.getPrimitiveVertexList(primoff));
1297 int vtxcount(poly.getFastVertexCount());
1305 for (
int i=0; i<vtxcount; ++i)
1312 GA_Offset ptoff = poly.getPointOffset(i);
1313 pos = myPos.get(ptoff);
1322 myBarbL.boundingRadius(ptoff),
1325 if (radius > maxradius)
1337 if (i > 1 && i < vtxcount)
1338 addedrad =
SYSmax(seglength, lastseglength);
1340 addedrad = seglength;
1341 else if (i==vtxcount)
1342 addedrad = lastseglength;
1345 myBarbL.boundingRadius(lastptoff) + addedrad,
1346 myBarbL.boundingRadius(lastptoff) + addedrad);
1348 if (radius > maxradius)
1356 lastseglength = seglength;
1425 , myTangent(tangent)
1426 , myBitangent(bitangent)
1434 TempData &tempdata);
1438 TempData &tempdata);
void normalizeWeights(GA_OffsetArray &templateoffsets, UT_FloatArray &templateweights) const
Definition of a geometry attribute.
static const UT_StringHolder BarbUVRAttrib
static const UT_StringHolder BarbUVLAttrib
GA_Attribute * getAttribute()
GU_FeatherBarbRWHandle< UT_Vector3 > to
SYS_FORCE_INLINE GA_Offset getPointOffset(GA_Size i) const
GLsizei GLenum const void * indices
static int valueTupleSize()
Generic Attribute Interface class to access an attribute as a array.
static GA_Attribute * createBarbAttrib(GU_Detail &detail, const UT_StringRef &name, int value_tuplesize, int barbpts)
const GA_Attribute * getAttribute() const
void bumpDimensions(int ptcount, int barbsegs)
void getTemplateOffsets(GA_OffsetArray &templateoffsets, const UT_StringArray &templatenames, GA_Offset primoff) const
getFileOption("OpenEXR:storage") storage
GA_Attribute * addFloatTuple(GA_AttributeOwner owner, GA_AttributeScope scope, const UT_StringHolder &name, int tuple_size, const GA_Defaults &defaults=GA_Defaults(0.0), const UT_Options *creation_args=0, const GA_AttributeOptions *attribute_options=0, GA_Storage storage=GA_STORE_REAL32, const GA_ReuseStrategy &reuse=GA_ReuseStrategy())
void bind(const GU_Detail *gdp, const GA_Attribute *attrib)
GLsizei const GLfloat * value
const UT_FloatArray & getCurveLengths() const
void setSizeNoInit(exint newsize)
GU_FeatherBarbFlat< UT_Vector3 > from_v_values
UT_Array< UT_Vector3 > temp_values
GA_Attribute * operator->() const
UT_StringArray templatenames
SYS_FORCE_INLINE T * SYSconst_cast(const T *foo)
GU_FeatherBarbROHandle(const GU_Detail &gdp, const GA_Attribute &attrib)
GA_Attribute * getP()
Convenience method to access the P attribute.
SYS_FORCE_INLINE const HOLDER & get(GA_Offset off, int comp=0) const
Get the string at the given offset.
virtual const GA_AIFTuple * getAIFTuple() const
Return the attribute's tuple interface or NULL.
bool hasTemplateNames() const
const GU_Detail & getTemplateDetail() const
SYS_FORCE_INLINE void xformToObjectNonZero(GA_Offset ptoff, UT_Array< UT_Vector3T< T >> &array) const
static const UT_StringHolder SideLeft
std::tuple< Types...> UT_Tuple
void addAttrib(const UT_StringRef &name)
static const UT_StringHolder BarbLAttrib
virtual int getTupleSize(const GA_Attribute *attrib) const =0
constexpr SYS_FORCE_INLINE T length() const noexcept
UT_Matrix2T< T > SYSlerp(const UT_Matrix2T< T > &v1, const UT_Matrix2T< T > &v2, S t)
GU_FeatherBarbROHandle(const GU_Detail &gdp, const UT_StringRef &name)
SYS_FORCE_INLINE const T * getBarbPtr(int index) const
void setSize(exint newsize)
exint GA_Size
Defines the bit width for index and offset types in GA.
void getTemplateOffsetsAndWeights(GA_Offset primoff, GA_OffsetArray &offsets, UT_FloatArray &weights, TempData &temp) const
constexpr SYS_FORCE_INLINE const T * data() const noexcept
UT_FloatArray templateweights
#define GA_INVALID_OFFSET
void bumpSize(exint newsize)
void getWeights(GA_Offset primoff, UT_FloatArray &templateweights) const
GLuint GLsizei const GLuint const GLintptr * offsets
const GA_Attribute * findIntArray(GA_AttributeOwner owner, GA_AttributeScope scope, const UT_StringRef &name, int min_size=1, int max_size=-1) const
static const UT_StringHolder TemplateNamesAttrib
static UT_StringHolder getBarbAttribName(const UT_StringRef &basename, BarbSide barbside)
UT_ValArray< bool > templateflips
SYS_FORCE_INLINE std::enable_if<!std::is_integral< V >::value &&!std::is_floating_point< V >::value, void >::type blend(GA_Offset offset, const ValueType *array, float alpha) const
SYS_FORCE_INLINE GA_Index primitiveIndex(GA_Offset offset) const
Given a primitive's data offset, return its index.
void getNames(GA_Offset primoff, UT_StringArray &templatenames) const
static void addFeatherAttribsToCurveSampler(GU_GroomCurveAttribSampler &sampler)
GU_FeatherTemplateSet(const GU_Detail &gdp)
const GA_Attribute * findStringArray(GA_AttributeOwner owner, GA_AttributeScope scope, const UT_StringRef &name, int min_size=1, int max_size=-1) const
void addLengthScaledAttrib(const UT_StringRef &name)
SYS_FORCE_INLINE void set(int index, int segindex, const T &value)
IMATH_NAMESPACE::V2f float
UT_Vector3T< T > rotateInverse(const UT_Vector3T< T > &) const
void getIndices(GA_Offset primoff, UT_Int64Array &templateindices) const
SYS_FORCE_INLINE void xformToLocal(GA_Offset ptoff, UT_Array< UT_Vector3T< T >> &array) const
SYS_FORCE_INLINE void add(int index, int segindex, const T &value)
UT_Vector2Array s_coeffs_linear
PXL_API const char * getName(const ColorSpace *space)
Return the name of the color space.
GU_FeatherTemplateInterpolate(const GU_Detail &gdp, const GU_Detail &templategdp, const GU_FeatherTemplateSet &templateinterp, const UT_StringHolder &indices_attrib_name, const UT_StringHolder &weights_attrib_name)
SYS_FORCE_INLINE void forEachPrimitive(FUNCTOR &&functor) const
static void populateShaftData(const GEO_PrimPoly &poly, int firstbarbindex, const GA_ROHandleI &firstindexhandle, ShaftData &shaftdata)
GU_FeatherROhandle(const GU_Detail &gdp, const UT_StringRef &orientname)
static const UT_StringHolder theEmptyString
void getTemplateOffsets(GA_OffsetArray &templateoffsets, const UT_Int64Array &templateindices, GA_Offset primoff) const
UT_Array< GU_FeatherBarbFlat< UT_Vector3 > > attrib_outvalues
const UT_Array< UT_FloatArray > & getEdgeLengths() const
GU_FeatherRWHandle(GU_Detail &gdp, const UT_StringRef &orientname)
static constexpr std::enable_if< is_int< V >::value||is_flt< V >::value, int >::type tupleSize()
A specialization of GA_AIFStringArray to access "shared strings".
AttribMap(const GU_Detail &from_detail, GU_Detail &detail, const UT_StringRef &from_name, GA_Attribute &to_attrib)
const GU_FeatherBarbRWHandle< UT_Vector3F > & barbL() const
SYS_FORCE_INLINE GA_ATINumericUPtr createDetachedTupleAttribute(GA_AttributeOwner owner, GA_Storage storage, int tuple_size, const GA_Defaults &defaults=GA_Defaults(0.0f), const GA_AttributeOptions *attribute_options=nullptr) const
bool hasTemplateIndices() const
GU_FeatherBarbRWHandle(const GU_Detail &gdp, const GA_Attribute &attrib)
UT_Vector4iArray s_indices
GLfloat GLfloat GLfloat alpha
static const UT_StringHolder TemplateWeightsAttrib
virtual const GA_AIFSharedStringArray * getAIFSharedStringArray() const
Return the attribute's shared string array interface or NULL.
GU_FeatherBarbRWHandle(GU_Detail &gdp, GA_ROHandleT< ValueType > &pos, GA_ROHandleQ &orient, const UT_StringRef &name)
static const UT_StringHolder SideRight
void setDimensions(int ptcount, int barbsegs)
SYS_FORCE_INLINE T get(GA_Offset off, int comp=0) const
static const UT_StringHolder & getBarbSideString(BarbSide barbside)
GLuint const GLchar * name
AttribMap(const GU_Detail &from_detail, GU_Detail &detail, const UT_StringRef &name)
GU_FeatherBarbFlat< UT_Vector3 > myBarbFlat
GA_Size GA_Index
Define the strictness of GA_Offset/GA_Index.
GU_FeatherTemplateInterpolate(const GU_Detail &gdp, const GU_FeatherTemplateSet &templateinterp, const GA_Attribute &templatenamesattrib, const GA_Attribute &templateweightattrib)
const GA_ROHandleI getFirstBarbAttrib() const
GA_API const UT_StringHolder orient
int numBarbPoints() const
UT_UniquePtr< GA_Attribute > GA_AttributeUPtr
SYS_FORCE_INLINE bool isValid() const
ImageBuf OIIO_API flip(const ImageBuf &src, ROI roi={}, int nthreads=0)
SYS_FORCE_INLINE std::enable_if<!std::is_integral< V >::value &&!std::is_floating_point< V >::value, void >::type set(GA_Offset offset, const ValueType *array) const
GU_FeatherBarbROHandle< UT_Vector3 > from
SYS_FORCE_INLINE fpreal boundingRadius(GA_Offset primoff) const
SYS_FORCE_INLINE void xformToLocalNonZero(GA_Offset ptoff, UT_Array< UT_Vector3T< T >> &array) const
GA_OffsetArray templateoffsets
GU_FeatherDerivatives(const GU_FeatherBarbROHandle< UT_Vector3 > &barb, const GU_FeatherBarbRWHandle< UT_Vector3 > &tangent, const GU_FeatherBarbRWHandle< UT_Vector3 > &bitangent)
static const UT_StringHolder SideCenter
size_t format(const char *fmt, const Args &...args)
SYS_FORCE_INLINE void set(int index, const UT_Array< T > &value)
static float unitLengthToUnitDomain(const UT_Vector3Array &pos, float perimeter, const UT_FloatArray &edgelengths, float ulength)
SYS_FORCE_INLINE std::enable_if< std::is_integral< V >::value||std::is_floating_point< V >::value, void >::type set(GA_Offset offset, const ValueType *array) const
GU_FeatherTemplateInterpolate::TempData interptemp
SYS_FORCE_INLINE void xformToObject(GA_Offset ptoff, UT_Array< UT_Vector3T< T >> &array) const
const UT_Quaternion getOrient(GA_Offset offset) const
GU_FeatherBarbFlat(int ptcount, int barbsegs)
static GA_ATINumericUPtr createDetachedBarbAttrib(const GU_Detail &detail, GA_Storage storage, int value_tuplesize, int barbpts)
GU_FeatherBarbROHandle(const GU_Detail &gdp, GA_ROHandleT< ValueType > &pos, GA_ROHandleQ &orient, const UT_StringRef &name)
SYS_FORCE_INLINE GA_Offset getMapOffset() const
Gets the offset of this primitive in the detail containing it.
SYS_FORCE_INLINE GA_Size getNumPrimitives() const
Return the number of primitives.
const GU_FeatherBarbRWHandle< UT_Vector3F > & barbR() const
const GA_Attribute * findFloatArray(GA_AttributeOwner owner, GA_AttributeScope scope, const UT_StringRef &name, int min_size=1, int max_size=-1) const
static const UT_StringHolder BarbRAttrib
constexpr SYS_FORCE_INLINE T distance(const UT_Vector3T &b) const noexcept
static const UT_StringArray FeatherAttribsLengthScaled
AttribMap(const GU_Detail &from_detail, GU_Detail &detail, const GA_Attribute &from_attrib, GA_Attribute &to_attrib)
UT_Array< UT_Vector3 > myTempVecs
static const UT_StringHolder SideAttrib
UT_Int64Array templateindices
GU_FeatherBarbRWHandle< UT_Vector3F > myBarbR
UT_Vector2iArray s_indices_linear
GLubyte GLubyte GLubyte GLubyte w
void startPrim(const GU_Detail &detail, const GEO_PrimPoly &poly, int firstindex, TempData &tempdata)
SYS_FORCE_INLINE GA_Size getFastVertexCount() const
const GU_Detail & getDetail() const
SYS_FORCE_INLINE GA_Size getPrimitiveVertexCount(GA_Offset primoff) const
void computeForPoint(GA_Size i, TempData &tempdata)
UT_Array< bool > myBarbFetched
GU_FeatherBarbRWHandle(const GU_Detail &gdp, const UT_StringRef &name)
const GU_FeatherBarbROHandle< UT_Vector3F > & barbL() const
GA_API const UT_StringHolder segs
UT_Vector3T< T > rotate(const UT_Vector3T< T > &) const
GU_FeatherBarbRWHandle< UT_Vector3F > myBarbL
Generic Attribute Interface class to access an attribute as a tuple.
const TemplateOffsetMap & getTemplateOffsetMap() const
SYS_FORCE_INLINE fpreal boundingRadius(GA_Offset ptoff) const
static constexpr std::enable_if<!(is_int< V >::value||is_flt< V >::value), int >::type tupleSize()
const GU_FeatherBarbROHandle< UT_Vector3F > & barbR() const
void makeTemplateOffsetMap(UT_Map< UT_StringHolder, GA_Offset > &templatemap, const GU_Detail *templategdp, GA_ROHandleS &templatenameattrib)
UT_UniquePtr< GA_ATINumeric > GA_ATINumericUPtr
float computeBlendedCurveParam(int i, int vtxcount, GA_OffsetArray &templateoffsets, UT_FloatArray &templateweights, GA_ROHandleI &template_firstbarb_handle, int shaftsegs, fpreal curvelength, UT_FloatArray &curveedgelengths)
GA_ROHandleT< ValueType > myPos
static const UT_StringHolder BarbOrientAttrib
static const UT_StringArray FeatherAttribs
GLsizei GLenum GLenum GLuint GLenum GLsizei * lengths
static float unitToUnitLengthDomain(float perimeter, const UT_FloatArray &edgelengths, float uparm)
virtual const GA_AIFNumericArray * getAIFNumericArray() const
Return the attribute's arraydata interface or NULL.