7#ifndef OPENSUBDIV3_VTR_LEVEL_H
8#define OPENSUBDIV3_VTR_LEVEL_H
10#include "../version.h"
24namespace OPENSUBDIV_VERSION {
86 void clear() { std::memset((
void*)
this, 0,
sizeof(VTag)); }
88 typedef unsigned short VTagSize;
90 VTagSize _nonManifold : 1;
91 VTagSize _xordinary : 1;
92 VTagSize _boundary : 1;
94 VTagSize _infSharp : 1;
95 VTagSize _semiSharp : 1;
96 VTagSize _semiSharpEdges : 1;
103 VTagSize _incomplete : 1;
104 VTagSize _incidIrregFace : 1;
107 VTagSize _infSharpEdges : 1;
108 VTagSize _infSharpCrease : 1;
109 VTagSize _infIrregular : 1;
112 explicit VTag(VTagSize bits) {
113 std::memcpy(
this, &bits,
sizeof(bits));
115 VTagSize getBits()
const {
117 std::memcpy(&bits,
this,
sizeof(bits));
121 static VTag BitwiseOr(VTag
const vTags[],
int size = 4);
127 void clear() { std::memset((
void*)
this, 0,
sizeof(ETag)); }
129 typedef unsigned char ETagSize;
131 ETagSize _nonManifold : 1;
132 ETagSize _boundary : 1;
133 ETagSize _infSharp : 1;
134 ETagSize _semiSharp : 1;
137 explicit ETag(ETagSize bits) {
138 std::memcpy(
this, &bits,
sizeof(bits));
140 ETagSize getBits()
const {
142 std::memcpy(&bits,
this,
sizeof(bits));
146 static ETag BitwiseOr(ETag
const eTags[],
int size = 4);
151 void clear() { std::memset((
void*)
this, 0,
sizeof(FTag)); }
153 typedef unsigned char FTagSize;
177 VSpan() { std::memset((
void*)
this, 0,
sizeof(VSpan)); }
179 void clear() { std::memset((
void*)
this, 0,
sizeof(VSpan)); }
180 bool isAssigned()
const {
return _numFaces > 0; }
186 unsigned short _periodic : 1;
187 unsigned short _sharp : 1;
195 int getDepth()
const {
return _depth; }
197 int getNumVertices()
const {
return _vertCount; }
198 int getNumFaces()
const {
return _faceCount; }
199 int getNumEdges()
const {
return _edgeCount; }
202 int getNumFaceVerticesTotal()
const {
return (
int) _faceVertIndices.size(); }
203 int getNumFaceEdgesTotal()
const {
return (
int) _faceEdgeIndices.size(); }
204 int getNumEdgeVerticesTotal()
const {
return (
int) _edgeVertIndices.size(); }
205 int getNumEdgeFacesTotal()
const {
return (
int) _edgeFaceIndices.size(); }
206 int getNumVertexFacesTotal()
const {
return (
int) _vertFaceIndices.size(); }
207 int getNumVertexEdgesTotal()
const {
return (
int) _vertEdgeIndices.size(); }
209 int getMaxValence()
const {
return _maxValence; }
210 int getMaxEdgeFaces()
const {
return _maxEdgeFaces; }
235 float getEdgeSharpness(
Index edgeIndex)
const;
236 float getVertexSharpness(
Index vertIndex)
const;
242 void setFaceHole(
Index faceIndex,
bool b);
243 bool isFaceHole(
Index faceIndex)
const;
246 Sdc::Options getFVarOptions(
int channel)
const;
247 int getNumFVarChannels()
const {
return (
int) _fvarChannels.size(); }
248 int getNumFVarValues(
int channel)
const;
251 FVarLevel & getFVarLevel(
int channel) {
return *_fvarChannels[channel]; }
252 FVarLevel
const & getFVarLevel(
int channel)
const {
return *_fvarChannels[channel]; }
255 void setEdgeNonManifold(
Index edgeIndex,
bool b);
256 bool isEdgeNonManifold(
Index edgeIndex)
const;
258 void setVertexNonManifold(
Index vertIndex,
bool b);
259 bool isVertexNonManifold(
Index vertIndex)
const;
262 VTag
const & getVertexTag(
Index vertIndex)
const {
return _vertTags[vertIndex]; }
263 ETag
const & getEdgeTag(
Index edgeIndex)
const {
return _edgeTags[edgeIndex]; }
264 FTag
const & getFaceTag(
Index faceIndex)
const {
return _faceTags[faceIndex]; }
266 VTag & getVertexTag(
Index vertIndex) {
return _vertTags[vertIndex]; }
267 ETag & getEdgeTag(
Index edgeIndex) {
return _edgeTags[edgeIndex]; }
268 FTag & getFaceTag(
Index faceIndex) {
return _faceTags[faceIndex]; }
274 TOPOLOGY_MISSING_EDGE_FACES=0,
275 TOPOLOGY_MISSING_EDGE_VERTS,
276 TOPOLOGY_MISSING_FACE_EDGES,
277 TOPOLOGY_MISSING_FACE_VERTS,
278 TOPOLOGY_MISSING_VERT_FACES,
279 TOPOLOGY_MISSING_VERT_EDGES,
281 TOPOLOGY_FAILED_CORRELATION_EDGE_FACE,
282 TOPOLOGY_FAILED_CORRELATION_FACE_VERT,
283 TOPOLOGY_FAILED_CORRELATION_FACE_EDGE,
285 TOPOLOGY_FAILED_ORIENTATION_INCIDENT_EDGE,
286 TOPOLOGY_FAILED_ORIENTATION_INCIDENT_FACE,
287 TOPOLOGY_FAILED_ORIENTATION_INCIDENT_FACES_EDGES,
289 TOPOLOGY_DEGENERATE_EDGE,
290 TOPOLOGY_NON_MANIFOLD_EDGE,
292 TOPOLOGY_INVALID_CREASE_EDGE,
293 TOPOLOGY_INVALID_CREASE_VERT
296 static char const * getTopologyErrorString(TopologyError errCode);
298 typedef void (* ValidationCallback)(TopologyError errCode,
char const * msg,
void const * clientData);
300 bool validateTopology(ValidationCallback callback=0,
void const * clientData=0)
const;
302 void print(
const Refinement* parentRefinement = 0)
const;
307 bool isSingleCreasePatch(
Index face,
float* sharpnessOut=NULL,
int* rotationOut=NULL)
const;
320 bool doesVertexFVarTopologyMatch(
Index vIndex,
int fvarChannel)
const;
321 bool doesFaceFVarTopologyMatch(
Index fIndex,
int fvarChannel)
const;
322 bool doesEdgeFVarTopologyMatch(
Index eIndex,
int fvarChannel)
const;
324 void getFaceVTags(
Index fIndex, VTag vTags[],
int fvarChannel = -1)
const;
325 void getFaceETags(
Index fIndex, ETag eTags[],
int fvarChannel = -1)
const;
327 VTag getFaceCompositeVTag(
Index fIndex,
int fvarChannel = -1)
const;
330 VTag getVertexCompositeFVarVTag(
Index vIndex,
int fvarChannel)
const;
338 int gatherQuadLinearPatchPoints(
Index fIndex,
Index patchPoints[],
int rotation = 0,
339 int fvarChannel = -1)
const;
341 int gatherQuadRegularInteriorPatchPoints(
Index fIndex,
Index patchPoints[],
int rotation = 0,
342 int fvarChannel = -1)
const;
343 int gatherQuadRegularBoundaryPatchPoints(
Index fIndex,
Index patchPoints[],
int boundaryEdgeInFace,
344 int fvarChannel = -1)
const;
345 int gatherQuadRegularCornerPatchPoints(
Index fIndex,
Index patchPoints[],
int cornerVertInFace,
346 int fvarChannel = -1)
const;
348 int gatherQuadRegularRingAroundVertex(
Index vIndex,
Index ringPoints[],
349 int fvarChannel = -1)
const;
350 int gatherQuadRegularPartialRingAroundVertex(
Index vIndex, VSpan
const & span,
Index ringPoints[],
351 int fvarChannel = -1)
const;
354 int gatherTriRegularInteriorPatchPoints(
Index fIndex,
Index patchVerts[],
int rotation = 0)
const;
355 int gatherTriRegularBoundaryVertexPatchPoints(
Index fIndex,
Index patchVerts[],
int boundaryVertInFace)
const;
356 int gatherTriRegularBoundaryEdgePatchPoints(
Index fIndex,
Index patchVerts[],
int boundaryEdgeInFace)
const;
357 int gatherTriRegularCornerVertexPatchPoints(
Index fIndex,
Index patchVerts[],
int cornerVertInFace)
const;
358 int gatherTriRegularCornerEdgePatchPoints(
Index fIndex,
Index patchVerts[],
int cornerEdgeInFace)
const;
362 void resizeFaces(
int numFaces);
363 void resizeFaceVertices(
int numFaceVertsTotal);
364 void resizeFaceEdges(
int numFaceEdgesTotal);
366 void resizeEdges(
int numEdges);
367 void resizeEdgeVertices();
368 void resizeEdgeFaces(
int numEdgeFacesTotal);
370 void resizeVertices(
int numVertices);
371 void resizeVertexFaces(
int numVertexFacesTotal);
372 void resizeVertexEdges(
int numVertexEdgesTotal);
374 void setMaxValence(
int maxValence);
389 float& getEdgeSharpness(
Index edgeIndex);
390 float& getVertexSharpness(
Index vertIndex);
393 int createFVarChannel(
int fvarValueCount, Sdc::Options
const& options);
394 void destroyFVarChannel(
int channel);
398 void completeFVarChannelTopology(
int channel,
int regBoundaryValence);
402 int getNumFaceVertices(
Index faceIndex)
const {
return _faceVertCountsAndOffsets[2*faceIndex]; }
403 int getOffsetOfFaceVertices(
Index faceIndex)
const {
return _faceVertCountsAndOffsets[2*faceIndex + 1]; }
405 int getNumFaceEdges(
Index faceIndex)
const {
return getNumFaceVertices(faceIndex); }
406 int getOffsetOfFaceEdges(
Index faceIndex)
const {
return getOffsetOfFaceVertices(faceIndex); }
408 int getNumEdgeVertices(
Index )
const {
return 2; }
409 int getOffsetOfEdgeVertices(
Index edgeIndex)
const {
return 2 * edgeIndex; }
411 int getNumEdgeFaces(
Index edgeIndex)
const {
return _edgeFaceCountsAndOffsets[2*edgeIndex]; }
412 int getOffsetOfEdgeFaces(
Index edgeIndex)
const {
return _edgeFaceCountsAndOffsets[2*edgeIndex + 1]; }
414 int getNumVertexFaces(
Index vertIndex)
const {
return _vertFaceCountsAndOffsets[2*vertIndex]; }
415 int getOffsetOfVertexFaces(
Index vertIndex)
const {
return _vertFaceCountsAndOffsets[2*vertIndex + 1]; }
417 int getNumVertexEdges(
Index vertIndex)
const {
return _vertEdgeCountsAndOffsets[2*vertIndex]; }
418 int getOffsetOfVertexEdges(
Index vertIndex)
const {
return _vertEdgeCountsAndOffsets[2*vertIndex + 1]; }
431 void resizeFaceVertices(
Index FaceIndex,
int count);
433 void resizeEdgeFaces(
Index edgeIndex,
int count);
434 void trimEdgeFaces(
Index edgeIndex,
int count);
436 void resizeVertexFaces(
Index vertIndex,
int count);
437 void trimVertexFaces(
Index vertIndex,
int count);
439 void resizeVertexEdges(
Index vertIndex,
int count);
440 void trimVertexEdges(
Index vertIndex,
int count);
451 bool completeTopologyFromFaceVertices();
455 void orientIncidentComponents();
456 bool orderVertexFacesAndEdges(
Index vIndex,
Index* vFaces,
Index* vEdges)
const;
457 bool orderVertexFacesAndEdges(
Index vIndex);
458 bool testVertexNonManifoldCrease(
Index vIndex)
const;
459 void populateLocalIndices();
461 IndexArray shareFaceVertCountsAndOffsets()
const;
465 friend class Refinement;
466 friend class TriRefinement;
467 friend class QuadRefinement;
510 std::vector<Index> _faceVertCountsAndOffsets;
511 std::vector<Index> _faceVertIndices;
512 std::vector<Index> _faceEdgeIndices;
513 std::vector<FTag> _faceTags;
516 std::vector<Index> _edgeVertIndices;
517 std::vector<Index> _edgeFaceCountsAndOffsets;
518 std::vector<Index> _edgeFaceIndices;
519 std::vector<LocalIndex> _edgeFaceLocalIndices;
521 std::vector<float> _edgeSharpness;
522 std::vector<ETag> _edgeTags;
525 std::vector<Index> _vertFaceCountsAndOffsets;
526 std::vector<Index> _vertFaceIndices;
527 std::vector<LocalIndex> _vertFaceLocalIndices;
529 std::vector<Index> _vertEdgeCountsAndOffsets;
530 std::vector<Index> _vertEdgeIndices;
531 std::vector<LocalIndex> _vertEdgeLocalIndices;
533 std::vector<float> _vertSharpness;
534 std::vector<VTag> _vertTags;
537 std::vector<FVarLevel*> _fvarChannels;
544Level::getFaceVertices(
Index faceIndex)
const {
545 return ConstIndexArray(&_faceVertIndices[_faceVertCountsAndOffsets[faceIndex*2+1]],
546 _faceVertCountsAndOffsets[faceIndex*2]);
549Level::getFaceVertices(
Index faceIndex) {
550 return IndexArray(&_faceVertIndices[_faceVertCountsAndOffsets[faceIndex*2+1]],
551 _faceVertCountsAndOffsets[faceIndex*2]);
555Level::resizeFaceVertices(
Index faceIndex,
int count) {
557 int* countOffsetPair = &_faceVertCountsAndOffsets[faceIndex*2];
559 countOffsetPair[0] = count;
560 countOffsetPair[1] = (faceIndex == 0) ? 0 : (countOffsetPair[-2] + countOffsetPair[-1]);
562 _maxValence = std::max(_maxValence, count);
566Level::getFaceVertices()
const {
567 return ConstIndexArray(&_faceVertIndices[0], (
int)_faceVertIndices.size());
574Level::getFaceEdges(
Index faceIndex)
const {
575 return ConstIndexArray(&_faceEdgeIndices[_faceVertCountsAndOffsets[faceIndex*2+1]],
576 _faceVertCountsAndOffsets[faceIndex*2]);
579Level::getFaceEdges(
Index faceIndex) {
580 return IndexArray(&_faceEdgeIndices[_faceVertCountsAndOffsets[faceIndex*2+1]],
581 _faceVertCountsAndOffsets[faceIndex*2]);
588Level::getVertexFaces(
Index vertIndex)
const {
589 return ConstIndexArray( (&_vertFaceIndices[0]) + _vertFaceCountsAndOffsets[vertIndex*2+1],
590 _vertFaceCountsAndOffsets[vertIndex*2]);
593Level::getVertexFaces(
Index vertIndex) {
594 return IndexArray( (&_vertFaceIndices[0]) + _vertFaceCountsAndOffsets[vertIndex*2+1],
595 _vertFaceCountsAndOffsets[vertIndex*2]);
599Level::getVertexFaceLocalIndices(
Index vertIndex)
const {
600 return ConstLocalIndexArray( (&_vertFaceLocalIndices[0]) + _vertFaceCountsAndOffsets[vertIndex*2+1],
601 _vertFaceCountsAndOffsets[vertIndex*2]);
604Level::getVertexFaceLocalIndices(
Index vertIndex) {
605 return LocalIndexArray( (&_vertFaceLocalIndices[0]) + _vertFaceCountsAndOffsets[vertIndex*2+1],
606 _vertFaceCountsAndOffsets[vertIndex*2]);
610Level::resizeVertexFaces(
Index vertIndex,
int count) {
611 int* countOffsetPair = &_vertFaceCountsAndOffsets[vertIndex*2];
613 countOffsetPair[0] = count;
614 countOffsetPair[1] = (vertIndex == 0) ? 0 : (countOffsetPair[-2] + countOffsetPair[-1]);
617Level::trimVertexFaces(
Index vertIndex,
int count) {
618 _vertFaceCountsAndOffsets[vertIndex*2] = count;
625Level::getVertexEdges(
Index vertIndex)
const {
626 return ConstIndexArray( (&_vertEdgeIndices[0]) +_vertEdgeCountsAndOffsets[vertIndex*2+1],
627 _vertEdgeCountsAndOffsets[vertIndex*2]);
630Level::getVertexEdges(
Index vertIndex) {
631 return IndexArray( (&_vertEdgeIndices[0]) +_vertEdgeCountsAndOffsets[vertIndex*2+1],
632 _vertEdgeCountsAndOffsets[vertIndex*2]);
636Level::getVertexEdgeLocalIndices(
Index vertIndex)
const {
637 return ConstLocalIndexArray( (&_vertEdgeLocalIndices[0]) + _vertEdgeCountsAndOffsets[vertIndex*2+1],
638 _vertEdgeCountsAndOffsets[vertIndex*2]);
641Level::getVertexEdgeLocalIndices(
Index vertIndex) {
642 return LocalIndexArray( (&_vertEdgeLocalIndices[0]) + _vertEdgeCountsAndOffsets[vertIndex*2+1],
643 _vertEdgeCountsAndOffsets[vertIndex*2]);
647Level::resizeVertexEdges(
Index vertIndex,
int count) {
648 int* countOffsetPair = &_vertEdgeCountsAndOffsets[vertIndex*2];
650 countOffsetPair[0] = count;
651 countOffsetPair[1] = (vertIndex == 0) ? 0 : (countOffsetPair[-2] + countOffsetPair[-1]);
653 _maxValence = std::max(_maxValence, count);
656Level::trimVertexEdges(
Index vertIndex,
int count) {
657 _vertEdgeCountsAndOffsets[vertIndex*2] = count;
661Level::setMaxValence(
int valence) {
662 _maxValence = valence;
669Level::getEdgeVertices(
Index edgeIndex)
const {
673Level::getEdgeVertices(
Index edgeIndex) {
674 return IndexArray(&_edgeVertIndices[edgeIndex*2], 2);
681Level::getEdgeFaces(
Index edgeIndex)
const {
683 _edgeFaceCountsAndOffsets[edgeIndex*2+1],
684 _edgeFaceCountsAndOffsets[edgeIndex*2]);
687Level::getEdgeFaces(
Index edgeIndex) {
689 _edgeFaceCountsAndOffsets[edgeIndex*2+1],
690 _edgeFaceCountsAndOffsets[edgeIndex*2]);
694Level::getEdgeFaceLocalIndices(
Index edgeIndex)
const {
696 _edgeFaceCountsAndOffsets[edgeIndex*2+1],
697 _edgeFaceCountsAndOffsets[edgeIndex*2]);
700Level::getEdgeFaceLocalIndices(
Index edgeIndex) {
702 _edgeFaceCountsAndOffsets[edgeIndex*2+1],
703 _edgeFaceCountsAndOffsets[edgeIndex*2]);
707Level::resizeEdgeFaces(
Index edgeIndex,
int count) {
708 int* countOffsetPair = &_edgeFaceCountsAndOffsets[edgeIndex*2];
710 countOffsetPair[0] = count;
711 countOffsetPair[1] = (edgeIndex == 0) ? 0 : (countOffsetPair[-2] + countOffsetPair[-1]);
713 _maxEdgeFaces = std::max(_maxEdgeFaces, count);
716Level::trimEdgeFaces(
Index edgeIndex,
int count) {
717 _edgeFaceCountsAndOffsets[edgeIndex*2] = count;
724Level::getEdgeSharpness(
Index edgeIndex)
const {
725 return _edgeSharpness[edgeIndex];
728Level::getEdgeSharpness(
Index edgeIndex) {
729 return _edgeSharpness[edgeIndex];
733Level::getVertexSharpness(
Index vertIndex)
const {
734 return _vertSharpness[vertIndex];
737Level::getVertexSharpness(
Index vertIndex) {
738 return _vertSharpness[vertIndex];
742Level::getVertexRule(
Index vertIndex)
const {
750Level::setFaceHole(
Index faceIndex,
bool b) {
751 _faceTags[faceIndex]._hole = b;
754Level::isFaceHole(
Index faceIndex)
const {
755 return _faceTags[faceIndex]._hole;
762Level::setEdgeNonManifold(
Index edgeIndex,
bool b) {
763 _edgeTags[edgeIndex]._nonManifold = b;
766Level::isEdgeNonManifold(
Index edgeIndex)
const {
767 return _edgeTags[edgeIndex]._nonManifold;
771Level::setVertexNonManifold(
Index vertIndex,
bool b) {
772 _vertTags[vertIndex]._nonManifold = b;
775Level::isVertexNonManifold(
Index vertIndex)
const {
776 return _vertTags[vertIndex]._nonManifold;
783Level::resizeFaces(
int faceCount) {
784 _faceCount = faceCount;
785 _faceVertCountsAndOffsets.resize(2 * faceCount);
787 _faceTags.resize(faceCount);
788 std::memset((
void*) &_faceTags[0], 0, _faceCount *
sizeof(FTag));
791Level::resizeFaceVertices(
int totalFaceVertCount) {
792 _faceVertIndices.resize(totalFaceVertCount);
795Level::resizeFaceEdges(
int totalFaceEdgeCount) {
796 _faceEdgeIndices.resize(totalFaceEdgeCount);
800Level::resizeEdges(
int edgeCount) {
802 _edgeCount = edgeCount;
803 _edgeFaceCountsAndOffsets.resize(2 * edgeCount);
805 _edgeSharpness.resize(edgeCount);
806 _edgeTags.resize(edgeCount);
809 std::memset((
void*) &_edgeTags[0], 0, _edgeCount *
sizeof(ETag));
813Level::resizeEdgeVertices() {
815 _edgeVertIndices.resize(2 * _edgeCount);
818Level::resizeEdgeFaces(
int totalEdgeFaceCount) {
820 _edgeFaceIndices.resize(totalEdgeFaceCount);
821 _edgeFaceLocalIndices.resize(totalEdgeFaceCount);
825Level::resizeVertices(
int vertCount) {
827 _vertCount = vertCount;
828 _vertFaceCountsAndOffsets.resize(2 * vertCount);
829 _vertEdgeCountsAndOffsets.resize(2 * vertCount);
831 _vertSharpness.resize(vertCount);
832 _vertTags.resize(vertCount);
833 std::memset((
void*) &_vertTags[0], 0, _vertCount *
sizeof(VTag));
836Level::resizeVertexFaces(
int totalVertFaceCount) {
838 _vertFaceIndices.resize(totalVertFaceCount);
839 _vertFaceLocalIndices.resize(totalVertFaceCount);
842Level::resizeVertexEdges(
int totalVertEdgeCount) {
844 _vertEdgeIndices.resize(totalVertEdgeCount);
845 _vertEdgeLocalIndices.resize(totalVertEdgeCount);
849Level::shareFaceVertCountsAndOffsets()
const {
853 (
int)_faceVertCountsAndOffsets.size());
860using namespace OPENSUBDIV_VERSION;
ConstArray< LocalIndex > ConstLocalIndexArray
Array< LocalIndex > LocalIndexArray
ConstArray< Index > ConstIndexArray
unsigned short LocalIndex
Array< Index > IndexArray