64 #define QUADS_AS_BILINEAR_PATCHES 1
67 using namespace UT::Literal;
68 using namespace HDK_Sample;
80 sopAccumulateTriangles(
87 sopAccumulateSegments(
94 using namespace SOP_WindingNumberEnums;
101 #define GA_INVALID_DATAID GA_DataId(-1)
110 , mySubtendedAngleTree()
119 , myMetaCacheCount(-1)
128 const bool has_group = (prim_group !=
nullptr);
129 if (mySubtendedAngleTree.isClear() &&
130 topology_data_id == myTopologyDataID &&
131 primitive_list_data_id == myPrimitiveListDataID &&
132 P_data_id == myPDataID &&
133 approx_order == myApproxOrder &&
134 has_group == myHadGroup &&
136 group_string == myGroupString &&
142 mySubtendedAngleTree.clear();
143 myPositions2D.clear();
147 myTopologyDataID = topology_data_id;
148 myPrimitiveListDataID = primitive_list_data_id;
149 myPDataID = P_data_id;
150 myApproxOrder = approx_order;
151 myHadGroup = has_group;
152 myGroupString = group_string;
157 myTrianglePoints.setSize(0);
158 myTrianglePoints.setCapacity(3*nprimitives);
159 myPositions3D.setSize(0);
160 myPositions3D.setCapacity(0);
171 mesh_ptgroup.
combine(prim_group);
172 myPositions3D.setSizeNoInit(mesh_ptgroup.
entries());
177 ptmap[ptoff] = ptnum;
178 myPositions3D[ptnum] = mesh_geo.
getPos3(ptoff);
187 for (
GA_Offset primoff = start; primoff <
end; ++primoff)
189 sopAccumulateTriangles(&mesh_geo, primoff, ptmap, myTrianglePoints);
193 mySolidAngleTree.init(myTrianglePoints.size()/3, myTrianglePoints.array(), myPositions3D.size(), myPositions3D.array(), approx_order);
200 const int approx_order,
201 const int axis0,
const int axis1)
206 const bool has_group = (prim_group !=
nullptr);
207 if (mySolidAngleTree.isClear() &&
208 topology_data_id == myTopologyDataID &&
209 primitive_list_data_id == myPrimitiveListDataID &&
210 P_data_id == myPDataID &&
211 approx_order == myApproxOrder &&
213 has_group == myHadGroup &&
215 group_string == myGroupString &&
221 mySolidAngleTree.clear();
222 myPositions3D.clear();
226 myTopologyDataID = topology_data_id;
227 myPrimitiveListDataID = primitive_list_data_id;
228 myPDataID = P_data_id;
229 myApproxOrder = approx_order;
231 myHadGroup = has_group;
232 myGroupString = group_string;
238 myTrianglePoints.setSize(0);
239 myTrianglePoints.setCapacity(2*nprimitives);
240 myPositions2D.setSize(0);
241 myPositions2D.setCapacity(0);
251 myPositions2D[ptnum] =
UT_Vector2(pos[axis0],pos[axis1]);
259 mesh_ptgroup.
combine(prim_group);
260 myPositions2D.setSizeNoInit(mesh_ptgroup.
entries());
263 mesh_geo.
forEachPoint(&mesh_ptgroup, [&mesh_geo,
this,&ptmap,&ptnum,axis0,axis1](
const GA_Offset ptoff)
265 ptmap[ptoff] = ptnum;
267 myPositions2D[ptnum] =
UT_Vector2(pos[axis0],pos[axis1]);
276 for (
GA_Offset primoff = start; primoff <
end; ++primoff)
278 sopAccumulateSegments(&mesh_geo, primoff, ptmap, myTrianglePoints);
282 mySubtendedAngleTree.init(myTrianglePoints.size()/2, myTrianglePoints.array(), myPositions2D.size(), myPositions2D.array(), approx_order);
287 mySolidAngleTree.clear();
288 mySubtendedAngleTree.clear();
289 myTrianglePoints.setCapacity(0);
290 myPositions2D.setCapacity(0);
291 myPositions3D.setCapacity(0);
297 myGroupString.clear();
299 myMetaCacheCount = -1;
336 virtual void cook(
const CookParms &cookparms)
const;
379 SOP_WindingNumber::myConstructor,
380 SOP_WindingNumber::buildTemplates(),
397 cppname "QueryPoints"
401 parmtag { "script_action" "import soputils\nkwargs['geometrytype'] = (hou.geometryType.Points,)\nkwargs['inputindex'] = 0\nsoputils.selectGroupParm(kwargs)" }
402 parmtag { "script_action_help" "Select geometry from an available viewport.\nShift-click to turn on Select Groups." }
403 parmtag { "script_action_icon" "BUTTONS_reselect" }
408 label "Mesh Primitives"
411 parmtag { "script_action" "import soputils\nkwargs['geometrytype'] = (hou.geometryType.Primitives,)\nkwargs['inputindex'] = 1\nsoputils.selectGroupParm(kwargs)" }
412 parmtag { "script_action_help" "Select geometry from an available viewport.\nShift-click to turn on Select Groups." }
413 parmtag { "script_action_icon" "BUTTONS_reselect" }
414 parmtag { "sop_input" "1" }
418 label "Winding Number Type"
423 "xy" "2D in XY Plane"
424 "yz" "2D in YZ Plane"
425 "zx" "2D in ZX Plane"
430 label "Attribute Name"
432 default { "winding_number" }
436 cppname "AsSolidAngle"
437 label "Scale to Solid Angle"
445 label "Negate Value (Reverse)"
451 cppname "FullAccuracy"
452 label "Full Accuracy (Slow)"
458 cppname "AccuracyScale"
459 label "Accuracy Scale"
463 disablewhen "{ fullaccuracy == 1 }"
473 sopSumContributions3D(
480 if (end-start > 1024)
486 sopSumContributions3D(&sum0, query_point, mesh_geo, primoffs, start, mid);
488 sopSumContributions3D(&sum1, query_point, mesh_geo, primoffs, mid, end);
494 double local_sum = 0;
495 for (
exint arrayi = start; arrayi <
end; ++arrayi)
504 if (n < 3 || !closed)
516 local_sum += poly_sum;
531 #if QUADS_AS_BILINEAR_PATCHES
534 const double poly_sum =
538 local_sum += poly_sum;
554 local_sum += poly_sum;
562 for (
int i = 0; i < 4; ++i)
565 if (tet.isFaceShared(i))
578 local_sum += tet_sum;
596 local_sum += poly_sum;
607 #if QUADS_AS_BILINEAR_PATCHES
610 const double poly_sum =
614 local_sum += poly_sum;
630 soup_sum += poly_sum;
632 local_sum += soup_sum;
640 for (
int row = 0;
row < nquadrows; ++
row)
642 for (
int col = 0; col < nquadcols; ++col)
649 #if QUADS_AS_BILINEAR_PATCHES
652 const double poly_sum =
656 mesh_sum += poly_sum;
659 local_sum += mesh_sum;
666 if (nquadcols <= 0 || nquadrows <= 0)
682 for (
int row = 0;
row < nquadrows; ++
row)
684 for (
int col = 0; col < nquadcols; ++col)
698 #if QUADS_AS_BILINEAR_PATCHES
701 const double poly_sum =
705 surf_sum += poly_sum;
708 local_sum += surf_sum;
722 double determinant = transform.determinant();
723 if (determinant == 0)
726 int failed = transform.invert();
730 query_minus_centre.rowVecMult(transform);
731 float length2 = query_minus_centre.length2();
733 double sphere_sum = 0;
736 else if (length2 == 1)
740 sphere_sum = -sphere_sum;
742 local_sum += sphere_sum;
749 sopSumContributions2D(
755 const int axis0,
const int axis1)
757 if (end-start > 1024)
763 sopSumContributions2D(&sum0, query_point, mesh_geo, primoffs, start, mid, axis0, axis1);
765 sopSumContributions2D(&sum1, query_point, mesh_geo, primoffs, mid, end, axis0, axis1);
771 double local_sum = 0;
772 for (
exint arrayi = start; arrayi <
end; ++arrayi)
781 if (n < 2+
int(closed))
798 local_sum += poly_sum;
821 pos = poly.getPos3(i);
827 soup_sum += poly_sum;
829 local_sum += soup_sum;
837 for (
int row = 0;
row < nquadrows; ++
row)
839 for (
int col = 0; col < nquadcols; ++col)
846 for (
GA_Size i = 1; i < 4; ++i)
848 pos = poly.getPos3(i);
854 mesh_sum += poly_sum;
857 local_sum += mesh_sum;
864 if (nquadcols <= 0 || nquadrows <= 0)
880 for (
int row = 0;
row < nquadrows; ++
row)
882 for (
int col = 0; col < nquadcols; ++col)
901 surf_sum += poly_sum;
904 local_sum += surf_sum;
915 double curve_sum = 0;
920 grevilles.
append(grevilles[0]);
922 UT_Vector2D prev(grevilles[0].getCVImage()[axis0], grevilles[0].getCVImage()[axis1]);
923 for (
int i = 0; i < nedges; ++i)
925 const UT_Vector2D next(grevilles[i].getCVImage()[axis0], grevilles[i].getCVImage()[axis1]);
928 local_sum += curve_sum;
935 sopAccumulateTriangles(
941 const bool has_ptmap = !ptmap.
isEmpty();
948 if (n < 3 || !closed)
956 const int p0i = has_ptmap ? ptmap[p0] :
int(mesh_geo->
pointIndex(p0));
958 int previ = has_ptmap ? ptmap[prev] :
int(mesh_geo->
pointIndex(prev));
962 const int nexti = has_ptmap ? ptmap[next] :
int(mesh_geo->
pointIndex(next));
963 triangle_points.
append(p0i);
964 triangle_points.
append(previ);
965 triangle_points.
append(nexti);
974 for (
int i = 0; i < 4; ++i)
977 if (tet.isFaceShared(i))
984 const int ai = has_ptmap ? ptmap[
a] :
int(mesh_geo->
pointIndex(a));
985 const int bi = has_ptmap ? ptmap[
b] :
int(mesh_geo->
pointIndex(b));
986 const int ci = has_ptmap ? ptmap[
c] :
int(mesh_geo->
pointIndex(c));
987 triangle_points.
append(ai);
988 triangle_points.
append(bi);
989 triangle_points.
append(ci);
1006 const int p0i = has_ptmap ? ptmap[p0] :
int(mesh_geo->
pointIndex(p0));
1007 GA_Offset prev = poly.getPointOffset(1);
1008 int previ = has_ptmap ? ptmap[prev] :
int(mesh_geo->
pointIndex(prev));
1011 const GA_Offset next = poly.getPointOffset(i);
1012 const int nexti = has_ptmap ? ptmap[next] :
int(mesh_geo->
pointIndex(next));
1013 triangle_points.
append(p0i);
1014 triangle_points.
append(previ);
1015 triangle_points.
append(nexti);
1026 for (
int row = 0;
row < nquadrows; ++
row)
1028 for (
int col = 0; col < nquadcols; ++col)
1031 const GA_Offset a = poly.getPointOffset(0);
1032 const GA_Offset b = poly.getPointOffset(1);
1033 const GA_Offset c = poly.getPointOffset(2);
1034 const GA_Offset d = poly.getPointOffset(3);
1035 const int ai = has_ptmap ? ptmap[
a] :
int(mesh_geo->
pointIndex(a));
1036 const int bi = has_ptmap ? ptmap[
b] :
int(mesh_geo->
pointIndex(b));
1037 const int ci = has_ptmap ? ptmap[
c] :
int(mesh_geo->
pointIndex(c));
1038 const int di = has_ptmap ? ptmap[d] :
int(mesh_geo->
pointIndex(d));
1039 triangle_points.
append(ai);
1040 triangle_points.
append(bi);
1041 triangle_points.
append(ci);
1042 triangle_points.
append(ai);
1043 triangle_points.
append(ci);
1044 triangle_points.
append(di);
1051 sopAccumulateSegments(
1057 const bool has_ptmap = !ptmap.
isEmpty();
1064 if (n < 2+
int(closed))
1068 int previ = has_ptmap ? ptmap[prev] :
int(mesh_geo->
pointIndex(prev));
1069 const int pt0i = previ;
1073 const int nexti = has_ptmap ? ptmap[next] :
int(mesh_geo->
pointIndex(next));
1074 segment_points.
append(previ);
1075 segment_points.
append(nexti);
1080 segment_points.
append(previ);
1081 segment_points.
append(pt0i);
1099 int previ = has_ptmap ? ptmap[prev] :
int(mesh_geo->
pointIndex(prev));
1100 const int pt0i = previ;
1103 const GA_Offset next = poly.getPointOffset(i);
1104 const int nexti = has_ptmap ? ptmap[next] :
int(mesh_geo->
pointIndex(next));
1105 segment_points.
append(previ);
1106 segment_points.
append(nexti);
1109 segment_points.
append(previ);
1110 segment_points.
append(pt0i);
1119 for (
int row = 0;
row < nquadrows; ++
row)
1121 for (
int col = 0; col < nquadcols; ++col)
1124 const GA_Offset a = poly.getPointOffset(0);
1125 const GA_Offset b = poly.getPointOffset(1);
1126 const GA_Offset c = poly.getPointOffset(2);
1127 const GA_Offset d = poly.getPointOffset(3);
1128 const int ai = has_ptmap ? ptmap[
a] :
int(mesh_geo->
pointIndex(a));
1129 const int bi = has_ptmap ? ptmap[
b] :
int(mesh_geo->
pointIndex(b));
1130 const int ci = has_ptmap ? ptmap[
c] :
int(mesh_geo->
pointIndex(c));
1131 const int di = has_ptmap ? ptmap[d] :
int(mesh_geo->
pointIndex(d));
1132 segment_points.
append(ai);
1133 segment_points.
append(bi);
1134 segment_points.
append(bi);
1135 segment_points.
append(ci);
1136 segment_points.
append(ci);
1137 segment_points.
append(di);
1138 segment_points.
append(di);
1139 segment_points.
append(ai);
1152 const bool as_solid_angle,
1181 if (boss.wasInterrupted())
1194 sopSumContributions3D(&sum, query_point, mesh_geo, primoffs, 0, primoffs.
size());
1196 if (!as_solid_angle)
1201 winding_number_attrib.
set(ptoff, sum);
1214 const bool as_solid_angle,
1237 UTparallelFor(point_range, [query_points,mesh_geo,winding_number_attrib,&primoffs,as_solid_angle,negate,&boss,axis0,axis1](
const GA_SplittableRange &r)
1245 if (boss.wasInterrupted())
1249 const UT_Vector2D query_point(query_point_3d[axis0], query_point_3d[axis1]);
1259 sopSumContributions2D(&sum, query_point, mesh_geo, primoffs, 0, primoffs.
size(), axis0, axis1);
1261 if (!as_solid_angle)
1266 winding_number_attrib.
set(ptoff, sum);
1277 const double accuracy_scale,
1279 const bool as_solid_angle,
1284 UTparallelFor(point_range, [query_points,&winding_number_attrib,&solid_angle_tree,as_solid_angle,negate,accuracy_scale,&boss](
const GA_SplittableRange &r)
1290 if (boss.wasInterrupted())
1299 if (!as_solid_angle)
1304 winding_number_attrib.
set(ptoff, sum);
1315 const double accuracy_scale,
1317 const bool as_angle,
1324 UTparallelFor(point_range, [query_points,&winding_number_attrib,&subtended_angle_tree,as_angle,negate,accuracy_scale,&boss,axis0,axis1](
const GA_SplittableRange &r)
1330 if (boss.wasInterrupted())
1336 const UT_Vector2D query_point(query_point_3d[axis0], query_point_3d[axis1]);
1338 double sum = subtended_angle_tree.
computeAngle(query_point, accuracy_scale);
1345 winding_number_attrib.
set(ptoff, sum);
1364 if (!winding_number_attrib.
isValid())
1367 if (!winding_number_attrib.
isValid())
1380 const UT_StringHolder &mesh_prim_group_string = sopparms.getMeshPrims();
1382 if (mesh_prim_group_string.
isstring())
1386 mesh_prim_group_string.
c_str(),
1387 mesh_geo,
true, success);
1391 const UT_StringHolder &query_point_group_string = sopparms.getQueryPoints();
1393 if (query_point_group_string.
isstring())
1397 query_point_group_string.
c_str(),
1398 query_points,
true, success);
1403 const bool full_accuracy = sopparms.getFullAccuracy();
1404 const bool as_solid_angle = sopparms.getAsSolidAngle();
1406 Type winding_number_type = sopparms.getType();
1408 if (winding_number_type == Type::XYZ)
1413 const bool negate = !sopparms.getNegate();
1419 query_points, point_range,
1420 mesh_geo, mesh_prim_group,
1421 winding_number_attrib,
1422 as_solid_angle, negate);
1426 sopcache->update3D(*mesh_geo, mesh_prim_group, mesh_prim_group_string, 2);
1432 query_points, point_range,
1433 solid_angle_tree, accuracy_scale,
1434 winding_number_attrib,
1435 as_solid_angle, negate);
1440 int axis0 =
int(winding_number_type)-1;
1441 int axis1 = (axis0 == 2) ? 0 : (axis0+1);
1443 const bool negate = sopparms.getNegate();
1449 query_points, point_range,
1450 mesh_geo, mesh_prim_group,
1451 winding_number_attrib,
1452 as_solid_angle, negate,
1457 sopcache->update2D(*mesh_geo, mesh_prim_group, mesh_prim_group_string, 2, axis0, axis1);
1463 query_points, point_range,
1464 subtended_angle_tree, accuracy_scale,
1465 winding_number_attrib,
1466 as_solid_angle, negate,
static PRM_ChoiceList primGroupMenu
GA_DataId myPrimitiveListDataID
SYS_FORCE_INLINE void bumpDataId()
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
virtual void cook(const CookParms &cookparms) const
This is the function that does the actual work.
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)
UT_Array< UT_Vector3 > myPositions3D
SYS_FORCE_INLINE GA_Offset getPointOffset(GA_Size i) const
SYS_FORCE_INLINE GA_Primitive * getPrimitive(GA_Offset prim_off)
fpreal64 getAccuracyScale() const
virtual UT_StringHolder name() const
void getVGrevilles(UT_Array< float > &vgrevilles) const
UT_StringHolder myGroupString
const GA_IndexMap & getPrimitiveMap() const
SYS_FORCE_INLINE GA_Size getVertexCount() const
Return the number of vertices used by this primitive.
virtual CookMode cookMode(const SOP_NodeParms *parms) const
GA_DataId getDataId() const
Iteration over a range of elements.
void setChoiceListPtr(const UT_StringRef &name, PRM_ChoiceList *list)
SYS_FORCE_INLINE int getPrimitiveTypeId(GA_Offset primoff) const
UT_Vector2T< float > UT_Vector2
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 update3D(const GA_Detail &mesh_geo, const GA_PrimitiveGroup *prim_group, const UT_StringHolder &group_string, const int approx_order)
#define GA_INVALID_DATAID
bool blockAdvance(GA_Offset &start, GA_Offset &end)
GA_Size entries() const overridefinal
Will return the number of primary elements.
void setSizeNoInit(exint newsize)
bool getAttributeAsArray(const GA_Attribute *atr, const GA_Range &range, UT_Array< T > &result) const
Get/set all the point attribute data from/to a contiguous array.
bool evaluateInteriorPoint(GA_Offset result_vtx, GA_AttributeRefMap &map, fpreal u, fpreal v, fpreal w=0) const
SYS_FORCE_INLINE T * SYSconst_cast(const T *foo)
SYS_FORCE_INLINE bool getExtraFlag() const
Synonym for isClosed()
GA_DataId getDataId() const
Return the data ID for the topology attributes.
GA_Attribute * getP()
Convenience method to access the P attribute.
void setTrivial(ToType startvalue, GA_Size size)
Makes the list a trivial list with the specified start value and size.
GLboolean GLboolean GLboolean GLboolean a
void setTrivialRange(FromType startindex, ToType startvalue, GA_Size nelements)
void setCapacity(exint new_capacity)
static const SOP_NodeVerb::Register< SOP_WindingNumberVerb > theVerb
SYS_FORCE_INLINE TO_T UTverify_cast(FROM_T from)
bool addOperator(OP_Operator *op, std::ostream *err=nullptr)
SYS_FORCE_INLINE UT_Vector3 getPos3(GA_Offset ptoff) const
The ptoff passed is the point offset.
static const UT_StringHolder theSOPTypeName
SYS_FORCE_INLINE bool isClosed() const
static PRM_ChoiceList pointGroupMenu
exint GA_Size
Defines the bit width for index and offset types in GA.
UT_ErrorSeverity sopAddError(int code, const char *msg=0, const UT_SourceLocation *loc=0) const
bool combine(const GA_Group *src) overridefinal
UT_SolidAngle< float, float > mySolidAngleTree
T UTsignedSolidAngleTri(const UT_Vector3T< T > &a, const UT_Vector3T< T > &b, const UT_Vector3T< T > &c, const UT_Vector3T< T > &query)
void getLocalTransform(UT_Matrix3D &x) const override
GA_Range getPointRange(const GA_PointGroup *group=0) const
Get a range of all points in the detail.
Constructs a PRM_Template list from an embedded .ds file or an istream.
virtual SOP_NodeParms * allocParms() const
SYS_FORCE_INLINE void forEachPoint(FUNCTOR &&functor) const
PRM_Template * templates() const
SYS_FORCE_INLINE GA_OffsetListRef getPrimitiveVertexList(GA_Offset primoff) const
SYS_FORCE_INLINE int getNumRows() const
T computeSolidAngle(const UT_Vector3T< T > &query_point, const T accuracy_scale=T(2.0)) const
SYS_FORCE_INLINE GA_Offset getNumPointOffsets() const
virtual SOP_NodeCache * allocCache() const
SYS_FORCE_INLINE const char * c_str() const
UT_Vector3T< fpreal64 > UT_Vector3D
SYS_FORCE_INLINE GA_Offset vertexPoint(GA_Offset vertex) const
Given a vertex, return the point it references.
SYS_FORCE_INLINE GA_DataId getDataId() const
GLboolean GLboolean GLboolean b
GA_API const UT_StringHolder transform
GLenum GLenum GLsizei void * table
SYS_FORCE_INLINE bool atEnd() const
exint getUniqueId() const
GA_Topology & getTopology()
SYS_FORCE_INLINE UT_Vector3 getPos3() const
The fast point position accessor.
T computeAngle(const UT_Vector2T< T > &query_point, const T accuracy_scale=T(2.0)) const
SYS_FORCE_INLINE bool isValid() const
SYS_FORCE_INLINE GA_Index pointIndex(GA_Offset offset) const
Given a point's data offset, return its index.
SYS_FORCE_INLINE bool isTrivialMap() const
const GA_Attribute * findFloatTuple(GA_AttributeOwner owner, GA_AttributeScope scope, const UT_StringRef &name, int min_size=1, int max_size=-1) const
const GA_PointGroup * parsePointDetached(const char *pat, const GEO_Detail *pgdp, bool forceexistence, bool &success)
virtual ~SOP_WindingNumberCache()
UT_Array< UT_Vector2 > myPositions2D
void newSopOperator(OP_OperatorTable *table)
void UTparallelInvoke(bool parallel, F1 &&f1, F2 &&f2)
bool buildGrevilles(UT_Array< GEO_Greville > &dest) const
SYS_FORCE_INLINE void set(GA_Offset off, const T &val) const
T UTsignedAngleSegment(const UT_Vector2T< T > &a, const UT_Vector2T< T > &b, const UT_Vector2T< T > &query)
SYS_FORCE_INLINE GA_Size getNumPrimitives() const
Return the number of primitives.
int64 getMetaCacheCount() const
GA_DataId myTopologyDataID
void update2D(const GA_Detail &mesh_geo, const GA_PrimitiveGroup *prim_group, const UT_StringHolder &group_string, const int approx_order, const int axis0, const int axis1)
const GU_Detail * inputGeo(exint idx) const
const GA_PrimitiveList & getPrimitiveList() const
const GA_PrimitiveGroup * parsePrimitiveDetached(const char *pat, const GEO_Detail *pgdp, bool forceexistence, bool &success)
SOP_NodeCache * cache() const
Container class for all geometry.
static const char *const theDsFile
This is the parameter interface string, below.
SYS_FORCE_INLINE int getNumCols() const
GLenum GLenum GLsizei void * row
void bind(GA_Detail *gdp, GA_AttributeOwner owner, const UT_StringRef &name, int minsize=1)
T UTsignedSolidAngleQuad(const UT_Vector3T< T > &a, const UT_Vector3T< T > &b, const UT_Vector3T< T > &c, const UT_Vector3T< T > &d, const UT_Vector3T< T > &query)
UT_SubtendedAngle< float, float > mySubtendedAngleTree
GA_Range getPrimitiveRange(const GA_PrimitiveGroup *group=0) const
Get a range of all primitives in the detail.
GU_DetailHandle & gdh() const
The initial state of gdh depends on the cookMode()
bool fullBlockAdvance(GA_Offset &start, GA_Offset &end)
SYS_FORCE_INLINE bool isstring() const
UT_Array< int > myTrianglePoints
SYS_FORCE_INLINE FromType size() const
Returns the number of used elements in the list (always <= capacity())
void getUGrevilles(UT_Array< float > &ugrevilles) const
static SYS_FORCE_INLINE const int * fastFaceIndices(GA_Size faceno)
SYS_FORCE_INLINE GA_Size getNumPoints() const
Return the number of points.
bool isEmpty() const
Returns true iff there are no occupied elements in the array.