24#ifndef OPENSUBDIV3_VTR_LEVEL_H
25#define OPENSUBDIV3_VTR_LEVEL_H
27#include "../version.h"
29#include "../sdc/types.h"
30#include "../sdc/crease.h"
31#include "../sdc/options.h"
32#include "../vtr/types.h"
41namespace OPENSUBDIV_VERSION {
103 void clear() { std::memset((
void*)
this, 0,
sizeof(VTag)); }
105 typedef unsigned short VTagSize;
107 VTagSize _nonManifold : 1;
108 VTagSize _xordinary : 1;
109 VTagSize _boundary : 1;
110 VTagSize _corner : 1;
111 VTagSize _infSharp : 1;
112 VTagSize _semiSharp : 1;
113 VTagSize _semiSharpEdges : 1;
120 VTagSize _incomplete : 1;
121 VTagSize _incidIrregFace : 1;
124 VTagSize _infSharpEdges : 1;
125 VTagSize _infSharpCrease : 1;
126 VTagSize _infIrregular : 1;
129 explicit VTag(VTagSize bits) {
130 std::memcpy(
this, &bits,
sizeof(bits));
132 VTagSize getBits()
const {
134 std::memcpy(&bits,
this,
sizeof(bits));
138 static VTag BitwiseOr(VTag
const vTags[],
int size = 4);
144 void clear() { std::memset((
void*)
this, 0,
sizeof(ETag)); }
146 typedef unsigned char ETagSize;
148 ETagSize _nonManifold : 1;
149 ETagSize _boundary : 1;
150 ETagSize _infSharp : 1;
151 ETagSize _semiSharp : 1;
154 explicit ETag(ETagSize bits) {
155 std::memcpy(
this, &bits,
sizeof(bits));
157 ETagSize getBits()
const {
159 std::memcpy(&bits,
this,
sizeof(bits));
163 static ETag BitwiseOr(ETag
const eTags[],
int size = 4);
168 void clear() { std::memset((
void*)
this, 0,
sizeof(FTag)); }
170 typedef unsigned char FTagSize;
194 VSpan() { std::memset((
void*)
this, 0,
sizeof(VSpan)); }
196 void clear() { std::memset((
void*)
this, 0,
sizeof(VSpan)); }
197 bool isAssigned()
const {
return _numFaces > 0; }
203 unsigned short _periodic : 1;
204 unsigned short _sharp : 1;
212 int getDepth()
const {
return _depth; }
214 int getNumVertices()
const {
return _vertCount; }
215 int getNumFaces()
const {
return _faceCount; }
216 int getNumEdges()
const {
return _edgeCount; }
219 int getNumFaceVerticesTotal()
const {
return (
int) _faceVertIndices.size(); }
220 int getNumFaceEdgesTotal()
const {
return (
int) _faceEdgeIndices.size(); }
221 int getNumEdgeVerticesTotal()
const {
return (
int) _edgeVertIndices.size(); }
222 int getNumEdgeFacesTotal()
const {
return (
int) _edgeFaceIndices.size(); }
223 int getNumVertexFacesTotal()
const {
return (
int) _vertFaceIndices.size(); }
224 int getNumVertexEdgesTotal()
const {
return (
int) _vertEdgeIndices.size(); }
226 int getMaxValence()
const {
return _maxValence; }
227 int getMaxEdgeFaces()
const {
return _maxEdgeFaces; }
252 float getEdgeSharpness(
Index edgeIndex)
const;
253 float getVertexSharpness(
Index vertIndex)
const;
259 void setFaceHole(
Index faceIndex,
bool b);
260 bool isFaceHole(
Index faceIndex)
const;
263 Sdc::Options getFVarOptions(
int channel)
const;
264 int getNumFVarChannels()
const {
return (
int) _fvarChannels.size(); }
265 int getNumFVarValues(
int channel)
const;
268 FVarLevel & getFVarLevel(
int channel) {
return *_fvarChannels[channel]; }
269 FVarLevel
const & getFVarLevel(
int channel)
const {
return *_fvarChannels[channel]; }
272 void setEdgeNonManifold(
Index edgeIndex,
bool b);
273 bool isEdgeNonManifold(
Index edgeIndex)
const;
275 void setVertexNonManifold(
Index vertIndex,
bool b);
276 bool isVertexNonManifold(
Index vertIndex)
const;
279 VTag
const & getVertexTag(
Index vertIndex)
const {
return _vertTags[vertIndex]; }
280 ETag
const & getEdgeTag(
Index edgeIndex)
const {
return _edgeTags[edgeIndex]; }
281 FTag
const & getFaceTag(
Index faceIndex)
const {
return _faceTags[faceIndex]; }
283 VTag & getVertexTag(
Index vertIndex) {
return _vertTags[vertIndex]; }
284 ETag & getEdgeTag(
Index edgeIndex) {
return _edgeTags[edgeIndex]; }
285 FTag & getFaceTag(
Index faceIndex) {
return _faceTags[faceIndex]; }
291 TOPOLOGY_MISSING_EDGE_FACES=0,
292 TOPOLOGY_MISSING_EDGE_VERTS,
293 TOPOLOGY_MISSING_FACE_EDGES,
294 TOPOLOGY_MISSING_FACE_VERTS,
295 TOPOLOGY_MISSING_VERT_FACES,
296 TOPOLOGY_MISSING_VERT_EDGES,
298 TOPOLOGY_FAILED_CORRELATION_EDGE_FACE,
299 TOPOLOGY_FAILED_CORRELATION_FACE_VERT,
300 TOPOLOGY_FAILED_CORRELATION_FACE_EDGE,
302 TOPOLOGY_FAILED_ORIENTATION_INCIDENT_EDGE,
303 TOPOLOGY_FAILED_ORIENTATION_INCIDENT_FACE,
304 TOPOLOGY_FAILED_ORIENTATION_INCIDENT_FACES_EDGES,
306 TOPOLOGY_DEGENERATE_EDGE,
307 TOPOLOGY_NON_MANIFOLD_EDGE,
309 TOPOLOGY_INVALID_CREASE_EDGE,
310 TOPOLOGY_INVALID_CREASE_VERT
313 static char const * getTopologyErrorString(TopologyError errCode);
315 typedef void (* ValidationCallback)(TopologyError errCode,
char const * msg,
void const * clientData);
317 bool validateTopology(ValidationCallback callback=0,
void const * clientData=0)
const;
319 void print(
const Refinement* parentRefinement = 0)
const;
324 bool isSingleCreasePatch(
Index face,
float* sharpnessOut=NULL,
int* rotationOut=NULL)
const;
337 bool doesVertexFVarTopologyMatch(
Index vIndex,
int fvarChannel)
const;
338 bool doesFaceFVarTopologyMatch(
Index fIndex,
int fvarChannel)
const;
339 bool doesEdgeFVarTopologyMatch(
Index eIndex,
int fvarChannel)
const;
341 void getFaceVTags(
Index fIndex, VTag vTags[],
int fvarChannel = -1)
const;
342 void getFaceETags(
Index fIndex, ETag eTags[],
int fvarChannel = -1)
const;
344 VTag getFaceCompositeVTag(
Index fIndex,
int fvarChannel = -1)
const;
347 VTag getVertexCompositeFVarVTag(
Index vIndex,
int fvarChannel)
const;
355 int gatherQuadLinearPatchPoints(
Index fIndex,
Index patchPoints[],
int rotation = 0,
356 int fvarChannel = -1)
const;
358 int gatherQuadRegularInteriorPatchPoints(
Index fIndex,
Index patchPoints[],
int rotation = 0,
359 int fvarChannel = -1)
const;
360 int gatherQuadRegularBoundaryPatchPoints(
Index fIndex,
Index patchPoints[],
int boundaryEdgeInFace,
361 int fvarChannel = -1)
const;
362 int gatherQuadRegularCornerPatchPoints(
Index fIndex,
Index patchPoints[],
int cornerVertInFace,
363 int fvarChannel = -1)
const;
365 int gatherQuadRegularRingAroundVertex(
Index vIndex,
Index ringPoints[],
366 int fvarChannel = -1)
const;
367 int gatherQuadRegularPartialRingAroundVertex(
Index vIndex, VSpan
const & span,
Index ringPoints[],
368 int fvarChannel = -1)
const;
371 int gatherTriRegularInteriorPatchPoints(
Index fIndex,
Index patchVerts[],
int rotation = 0)
const;
372 int gatherTriRegularBoundaryVertexPatchPoints(
Index fIndex,
Index patchVerts[],
int boundaryVertInFace)
const;
373 int gatherTriRegularBoundaryEdgePatchPoints(
Index fIndex,
Index patchVerts[],
int boundaryEdgeInFace)
const;
374 int gatherTriRegularCornerVertexPatchPoints(
Index fIndex,
Index patchVerts[],
int cornerVertInFace)
const;
375 int gatherTriRegularCornerEdgePatchPoints(
Index fIndex,
Index patchVerts[],
int cornerEdgeInFace)
const;
379 void resizeFaces(
int numFaces);
380 void resizeFaceVertices(
int numFaceVertsTotal);
381 void resizeFaceEdges(
int numFaceEdgesTotal);
383 void resizeEdges(
int numEdges);
384 void resizeEdgeVertices();
385 void resizeEdgeFaces(
int numEdgeFacesTotal);
387 void resizeVertices(
int numVertices);
388 void resizeVertexFaces(
int numVertexFacesTotal);
389 void resizeVertexEdges(
int numVertexEdgesTotal);
391 void setMaxValence(
int maxValence);
406 float& getEdgeSharpness(
Index edgeIndex);
407 float& getVertexSharpness(
Index vertIndex);
410 int createFVarChannel(
int fvarValueCount, Sdc::Options
const& options);
411 void destroyFVarChannel(
int channel);
415 void completeFVarChannelTopology(
int channel,
int regBoundaryValence);
419 int getNumFaceVertices(
Index faceIndex)
const {
return _faceVertCountsAndOffsets[2*faceIndex]; }
420 int getOffsetOfFaceVertices(
Index faceIndex)
const {
return _faceVertCountsAndOffsets[2*faceIndex + 1]; }
422 int getNumFaceEdges(
Index faceIndex)
const {
return getNumFaceVertices(faceIndex); }
423 int getOffsetOfFaceEdges(
Index faceIndex)
const {
return getOffsetOfFaceVertices(faceIndex); }
425 int getNumEdgeVertices(
Index )
const {
return 2; }
426 int getOffsetOfEdgeVertices(
Index edgeIndex)
const {
return 2 * edgeIndex; }
428 int getNumEdgeFaces(
Index edgeIndex)
const {
return _edgeFaceCountsAndOffsets[2*edgeIndex]; }
429 int getOffsetOfEdgeFaces(
Index edgeIndex)
const {
return _edgeFaceCountsAndOffsets[2*edgeIndex + 1]; }
431 int getNumVertexFaces(
Index vertIndex)
const {
return _vertFaceCountsAndOffsets[2*vertIndex]; }
432 int getOffsetOfVertexFaces(
Index vertIndex)
const {
return _vertFaceCountsAndOffsets[2*vertIndex + 1]; }
434 int getNumVertexEdges(
Index vertIndex)
const {
return _vertEdgeCountsAndOffsets[2*vertIndex]; }
435 int getOffsetOfVertexEdges(
Index vertIndex)
const {
return _vertEdgeCountsAndOffsets[2*vertIndex + 1]; }
448 void resizeFaceVertices(
Index FaceIndex,
int count);
450 void resizeEdgeFaces(
Index edgeIndex,
int count);
451 void trimEdgeFaces(
Index edgeIndex,
int count);
453 void resizeVertexFaces(
Index vertIndex,
int count);
454 void trimVertexFaces(
Index vertIndex,
int count);
456 void resizeVertexEdges(
Index vertIndex,
int count);
457 void trimVertexEdges(
Index vertIndex,
int count);
468 bool completeTopologyFromFaceVertices();
472 void orientIncidentComponents();
473 bool orderVertexFacesAndEdges(
Index vIndex,
Index* vFaces,
Index* vEdges)
const;
474 bool orderVertexFacesAndEdges(
Index vIndex);
475 void populateLocalIndices();
477 IndexArray shareFaceVertCountsAndOffsets()
const;
481 friend class Refinement;
482 friend class TriRefinement;
483 friend class QuadRefinement;
526 std::vector<Index> _faceVertCountsAndOffsets;
527 std::vector<Index> _faceVertIndices;
528 std::vector<Index> _faceEdgeIndices;
529 std::vector<FTag> _faceTags;
532 std::vector<Index> _edgeVertIndices;
533 std::vector<Index> _edgeFaceCountsAndOffsets;
534 std::vector<Index> _edgeFaceIndices;
535 std::vector<LocalIndex> _edgeFaceLocalIndices;
537 std::vector<float> _edgeSharpness;
538 std::vector<ETag> _edgeTags;
541 std::vector<Index> _vertFaceCountsAndOffsets;
542 std::vector<Index> _vertFaceIndices;
543 std::vector<LocalIndex> _vertFaceLocalIndices;
545 std::vector<Index> _vertEdgeCountsAndOffsets;
546 std::vector<Index> _vertEdgeIndices;
547 std::vector<LocalIndex> _vertEdgeLocalIndices;
549 std::vector<float> _vertSharpness;
550 std::vector<VTag> _vertTags;
553 std::vector<FVarLevel*> _fvarChannels;
560Level::getFaceVertices(
Index faceIndex)
const {
561 return ConstIndexArray(&_faceVertIndices[_faceVertCountsAndOffsets[faceIndex*2+1]],
562 _faceVertCountsAndOffsets[faceIndex*2]);
565Level::getFaceVertices(
Index faceIndex) {
566 return IndexArray(&_faceVertIndices[_faceVertCountsAndOffsets[faceIndex*2+1]],
567 _faceVertCountsAndOffsets[faceIndex*2]);
571Level::resizeFaceVertices(
Index faceIndex,
int count) {
573 int* countOffsetPair = &_faceVertCountsAndOffsets[faceIndex*2];
575 countOffsetPair[0] = count;
576 countOffsetPair[1] = (faceIndex == 0) ? 0 : (countOffsetPair[-2] + countOffsetPair[-1]);
578 _maxValence = std::max(_maxValence, count);
582Level::getFaceVertices()
const {
583 return ConstIndexArray(&_faceVertIndices[0], (
int)_faceVertIndices.size());
590Level::getFaceEdges(
Index faceIndex)
const {
591 return ConstIndexArray(&_faceEdgeIndices[_faceVertCountsAndOffsets[faceIndex*2+1]],
592 _faceVertCountsAndOffsets[faceIndex*2]);
595Level::getFaceEdges(
Index faceIndex) {
596 return IndexArray(&_faceEdgeIndices[_faceVertCountsAndOffsets[faceIndex*2+1]],
597 _faceVertCountsAndOffsets[faceIndex*2]);
604Level::getVertexFaces(
Index vertIndex)
const {
605 return ConstIndexArray( (&_vertFaceIndices[0]) + _vertFaceCountsAndOffsets[vertIndex*2+1],
606 _vertFaceCountsAndOffsets[vertIndex*2]);
609Level::getVertexFaces(
Index vertIndex) {
610 return IndexArray( (&_vertFaceIndices[0]) + _vertFaceCountsAndOffsets[vertIndex*2+1],
611 _vertFaceCountsAndOffsets[vertIndex*2]);
615Level::getVertexFaceLocalIndices(
Index vertIndex)
const {
616 return ConstLocalIndexArray( (&_vertFaceLocalIndices[0]) + _vertFaceCountsAndOffsets[vertIndex*2+1],
617 _vertFaceCountsAndOffsets[vertIndex*2]);
620Level::getVertexFaceLocalIndices(
Index vertIndex) {
621 return LocalIndexArray( (&_vertFaceLocalIndices[0]) + _vertFaceCountsAndOffsets[vertIndex*2+1],
622 _vertFaceCountsAndOffsets[vertIndex*2]);
626Level::resizeVertexFaces(
Index vertIndex,
int count) {
627 int* countOffsetPair = &_vertFaceCountsAndOffsets[vertIndex*2];
629 countOffsetPair[0] = count;
630 countOffsetPair[1] = (vertIndex == 0) ? 0 : (countOffsetPair[-2] + countOffsetPair[-1]);
633Level::trimVertexFaces(
Index vertIndex,
int count) {
634 _vertFaceCountsAndOffsets[vertIndex*2] = count;
641Level::getVertexEdges(
Index vertIndex)
const {
642 return ConstIndexArray( (&_vertEdgeIndices[0]) +_vertEdgeCountsAndOffsets[vertIndex*2+1],
643 _vertEdgeCountsAndOffsets[vertIndex*2]);
646Level::getVertexEdges(
Index vertIndex) {
647 return IndexArray( (&_vertEdgeIndices[0]) +_vertEdgeCountsAndOffsets[vertIndex*2+1],
648 _vertEdgeCountsAndOffsets[vertIndex*2]);
652Level::getVertexEdgeLocalIndices(
Index vertIndex)
const {
653 return ConstLocalIndexArray( (&_vertEdgeLocalIndices[0]) + _vertEdgeCountsAndOffsets[vertIndex*2+1],
654 _vertEdgeCountsAndOffsets[vertIndex*2]);
657Level::getVertexEdgeLocalIndices(
Index vertIndex) {
658 return LocalIndexArray( (&_vertEdgeLocalIndices[0]) + _vertEdgeCountsAndOffsets[vertIndex*2+1],
659 _vertEdgeCountsAndOffsets[vertIndex*2]);
663Level::resizeVertexEdges(
Index vertIndex,
int count) {
664 int* countOffsetPair = &_vertEdgeCountsAndOffsets[vertIndex*2];
666 countOffsetPair[0] = count;
667 countOffsetPair[1] = (vertIndex == 0) ? 0 : (countOffsetPair[-2] + countOffsetPair[-1]);
669 _maxValence = std::max(_maxValence, count);
672Level::trimVertexEdges(
Index vertIndex,
int count) {
673 _vertEdgeCountsAndOffsets[vertIndex*2] = count;
677Level::setMaxValence(
int valence) {
678 _maxValence = valence;
685Level::getEdgeVertices(
Index edgeIndex)
const {
689Level::getEdgeVertices(
Index edgeIndex) {
690 return IndexArray(&_edgeVertIndices[edgeIndex*2], 2);
697Level::getEdgeFaces(
Index edgeIndex)
const {
699 _edgeFaceCountsAndOffsets[edgeIndex*2+1],
700 _edgeFaceCountsAndOffsets[edgeIndex*2]);
703Level::getEdgeFaces(
Index edgeIndex) {
705 _edgeFaceCountsAndOffsets[edgeIndex*2+1],
706 _edgeFaceCountsAndOffsets[edgeIndex*2]);
710Level::getEdgeFaceLocalIndices(
Index edgeIndex)
const {
712 _edgeFaceCountsAndOffsets[edgeIndex*2+1],
713 _edgeFaceCountsAndOffsets[edgeIndex*2]);
716Level::getEdgeFaceLocalIndices(
Index edgeIndex) {
718 _edgeFaceCountsAndOffsets[edgeIndex*2+1],
719 _edgeFaceCountsAndOffsets[edgeIndex*2]);
723Level::resizeEdgeFaces(
Index edgeIndex,
int count) {
724 int* countOffsetPair = &_edgeFaceCountsAndOffsets[edgeIndex*2];
726 countOffsetPair[0] = count;
727 countOffsetPair[1] = (edgeIndex == 0) ? 0 : (countOffsetPair[-2] + countOffsetPair[-1]);
729 _maxEdgeFaces = std::max(_maxEdgeFaces, count);
732Level::trimEdgeFaces(
Index edgeIndex,
int count) {
733 _edgeFaceCountsAndOffsets[edgeIndex*2] = count;
740Level::getEdgeSharpness(
Index edgeIndex)
const {
741 return _edgeSharpness[edgeIndex];
744Level::getEdgeSharpness(
Index edgeIndex) {
745 return _edgeSharpness[edgeIndex];
749Level::getVertexSharpness(
Index vertIndex)
const {
750 return _vertSharpness[vertIndex];
753Level::getVertexSharpness(
Index vertIndex) {
754 return _vertSharpness[vertIndex];
758Level::getVertexRule(
Index vertIndex)
const {
766Level::setFaceHole(
Index faceIndex,
bool b) {
767 _faceTags[faceIndex]._hole = b;
770Level::isFaceHole(
Index faceIndex)
const {
771 return _faceTags[faceIndex]._hole;
778Level::setEdgeNonManifold(
Index edgeIndex,
bool b) {
779 _edgeTags[edgeIndex]._nonManifold = b;
782Level::isEdgeNonManifold(
Index edgeIndex)
const {
783 return _edgeTags[edgeIndex]._nonManifold;
787Level::setVertexNonManifold(
Index vertIndex,
bool b) {
788 _vertTags[vertIndex]._nonManifold = b;
791Level::isVertexNonManifold(
Index vertIndex)
const {
792 return _vertTags[vertIndex]._nonManifold;
799Level::resizeFaces(
int faceCount) {
800 _faceCount = faceCount;
801 _faceVertCountsAndOffsets.resize(2 * faceCount);
803 _faceTags.resize(faceCount);
804 std::memset((
void*) &_faceTags[0], 0, _faceCount *
sizeof(FTag));
807Level::resizeFaceVertices(
int totalFaceVertCount) {
808 _faceVertIndices.resize(totalFaceVertCount);
811Level::resizeFaceEdges(
int totalFaceEdgeCount) {
812 _faceEdgeIndices.resize(totalFaceEdgeCount);
816Level::resizeEdges(
int edgeCount) {
818 _edgeCount = edgeCount;
819 _edgeFaceCountsAndOffsets.resize(2 * edgeCount);
821 _edgeSharpness.resize(edgeCount);
822 _edgeTags.resize(edgeCount);
825 std::memset((
void*) &_edgeTags[0], 0, _edgeCount *
sizeof(ETag));
829Level::resizeEdgeVertices() {
831 _edgeVertIndices.resize(2 * _edgeCount);
834Level::resizeEdgeFaces(
int totalEdgeFaceCount) {
836 _edgeFaceIndices.resize(totalEdgeFaceCount);
837 _edgeFaceLocalIndices.resize(totalEdgeFaceCount);
841Level::resizeVertices(
int vertCount) {
843 _vertCount = vertCount;
844 _vertFaceCountsAndOffsets.resize(2 * vertCount);
845 _vertEdgeCountsAndOffsets.resize(2 * vertCount);
847 _vertSharpness.resize(vertCount);
848 _vertTags.resize(vertCount);
849 std::memset((
void*) &_vertTags[0], 0, _vertCount *
sizeof(VTag));
852Level::resizeVertexFaces(
int totalVertFaceCount) {
854 _vertFaceIndices.resize(totalVertFaceCount);
855 _vertFaceLocalIndices.resize(totalVertFaceCount);
858Level::resizeVertexEdges(
int totalVertEdgeCount) {
860 _vertEdgeIndices.resize(totalVertEdgeCount);
861 _vertEdgeLocalIndices.resize(totalVertEdgeCount);
865Level::shareFaceVertCountsAndOffsets()
const {
869 (
int)_faceVertCountsAndOffsets.size());
876using namespace OPENSUBDIV_VERSION;
ConstArray< LocalIndex > ConstLocalIndexArray
Array< LocalIndex > LocalIndexArray
ConstArray< Index > ConstIndexArray
unsigned short LocalIndex
Array< Index > IndexArray