24#ifndef OPENSUBDIV3_VTR_FVAR_LEVEL_H
25#define OPENSUBDIV3_VTR_FVAR_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"
33#include "../vtr/level.h"
41namespace OPENSUBDIV_VERSION {
90 void clear() { std::memset(
this, 0,
sizeof(ETag)); }
92 typedef unsigned char ETagSize;
94 ETagSize _mismatch : 1;
95 ETagSize _disctsV0 : 1;
96 ETagSize _disctsV1 : 1;
99 Level::ETag combineWithLevelETag(Level::ETag)
const;
111 void clear() { std::memset(
this, 0,
sizeof(ValueTag)); }
113 bool isMismatch()
const {
return _mismatch; }
114 bool isCrease()
const {
return _crease; }
115 bool isCorner()
const {
return !_crease; }
116 bool isSemiSharp()
const {
return _semiSharp; }
117 bool isInfSharp()
const {
return !_semiSharp && !_crease; }
118 bool isDepSharp()
const {
return _depSharp; }
119 bool hasCreaseEnds()
const {
return _crease || _semiSharp; }
121 bool hasInfSharpEdges()
const {
return _infSharpEdges; }
122 bool hasInfIrregularity()
const {
return _infIrregular; }
124 typedef unsigned char ValueTagSize;
127 ValueTagSize _mismatch : 1;
128 ValueTagSize _xordinary : 1;
129 ValueTagSize _nonManifold : 1;
130 ValueTagSize _crease : 1;
131 ValueTagSize _semiSharp : 1;
132 ValueTagSize _depSharp : 1;
134 ValueTagSize _infSharpEdges : 1;
135 ValueTagSize _infIrregular : 1;
137 Level::VTag combineWithLevelVTag(Level::VTag)
const;
140 explicit ValueTag(ValueTagSize bits) {
141 std::memcpy(
this, &bits,
sizeof(bits));
143 ValueTagSize getBits()
const {
145 std::memcpy(&bits,
this,
sizeof(bits));
150 typedef Vtr::ConstArray<ValueTag> ConstValueTagArray;
151 typedef Vtr::Array<ValueTag> ValueTagArray;
158 struct CreaseEndPair {
163 typedef Vtr::ConstArray<CreaseEndPair> ConstCreaseEndPairArray;
164 typedef Vtr::Array<CreaseEndPair> CreaseEndPairArray;
172 FVarLevel(Level
const& level);
176 Level
const& getLevel()
const {
return _level; }
178 int getNumValues()
const {
return _valueCount; }
179 int getNumFaceValuesTotal()
const {
return (
int) _faceVertValues.size(); }
181 bool isLinear()
const {
return _isLinear; }
182 bool hasLinearBoundaries()
const {
return _hasLinearBoundaries; }
183 bool hasSmoothBoundaries()
const {
return ! _hasLinearBoundaries; }
184 bool hasCreaseEnds()
const {
return hasSmoothBoundaries(); }
186 Sdc::Options getOptions()
const {
return _options; }
193 ETag getEdgeTag(
Index eIndex)
const {
return _edgeTags[eIndex]; }
194 bool edgeTopologyMatches(
Index eIndex)
const {
return !getEdgeTag(eIndex)._mismatch; }
197 int getNumVertexValues(
Index v)
const {
return _vertSiblingCounts[v]; }
198 Index getVertexValueOffset(
Index v, Sibling i = 0)
const {
return _vertSiblingOffsets[v] + i; }
200 Index getVertexValue(
Index v, Sibling i = 0)
const {
return _vertValueIndices[getVertexValueOffset(v,i)]; }
208 ConstValueTagArray getVertexValueTags(
Index vIndex)
const;
209 ValueTagArray getVertexValueTags(
Index vIndex);
211 ConstCreaseEndPairArray getVertexValueCreaseEnds(
Index vIndex)
const;
212 CreaseEndPairArray getVertexValueCreaseEnds(
Index vIndex);
214 ConstSiblingArray getVertexFaceSiblings(
Index vIndex)
const;
215 SiblingArray getVertexFaceSiblings(
Index vIndex);
218 ValueTag getValueTag(
Index valueIndex)
const {
return _vertValueTags[valueIndex]; }
219 bool valueTopologyMatches(
Index valueIndex)
const {
return !getValueTag(valueIndex)._mismatch; }
221 CreaseEndPair getValueCreaseEndPair(
Index valueIndex)
const {
return _vertValueCreaseEnds[valueIndex]; }
224 void getFaceValueTags(
Index faceIndex, ValueTag valueTags[])
const;
226 ValueTag getFaceCompositeValueTag(
Index faceIndex)
const;
229 void getEdgeFaceValues(
Index eIndex,
int fIncToEdge,
Index valuesPerVert[2])
const;
230 void getVertexEdgeValues(
Index vIndex,
Index valuesPerEdge[])
const;
231 void getVertexCreaseEndValues(
Index vIndex, Sibling sibling,
Index endValues[2])
const;
234 void setOptions(Sdc::Options
const& options);
235 void resizeVertexValues(
int numVertexValues);
236 void resizeValues(
int numValues);
237 void resizeComponents();
240 void completeTopologyFromFaceValues(
int regBoundaryValence);
241 void initializeFaceValuesFromFaceVertices();
242 void initializeFaceValuesFromVertexFaceSiblings();
245 void gatherValueSpans(
Index vIndex, ValueSpan * vValueSpans)
const;
248 bool validate()
const;
250 void buildFaceVertexSiblingsFromVertexFaceSiblings(std::vector<Sibling>& fvSiblings)
const;
254 friend class FVarRefinement;
256 Level
const & _level;
259 Sdc::Options _options;
262 bool _hasLinearBoundaries;
263 bool _hasDependentSharpness;
278 std::vector<Index> _faceVertValues;
281 std::vector<ETag> _edgeTags;
284 std::vector<Sibling> _vertSiblingCounts;
285 std::vector<int> _vertSiblingOffsets;
286 std::vector<Sibling> _vertFaceSiblings;
289 std::vector<Index> _vertValueIndices;
290 std::vector<ValueTag> _vertValueTags;
291 std::vector<CreaseEndPair> _vertValueCreaseEnds;
298FVarLevel::getFaceValues(
Index fIndex)
const {
300 int vCount = _level.getNumFaceVertices(fIndex);
301 int vOffset = _level.getOffsetOfFaceVertices(fIndex);
305FVarLevel::getFaceValues(
Index fIndex) {
307 int vCount = _level.getNumFaceVertices(fIndex);
308 int vOffset = _level.getOffsetOfFaceVertices(fIndex);
309 return IndexArray(&_faceVertValues[vOffset], vCount);
312inline FVarLevel::ConstSiblingArray
313FVarLevel::getVertexFaceSiblings(
Index vIndex)
const {
315 int vCount = _level.getNumVertexFaces(vIndex);
316 int vOffset = _level.getOffsetOfVertexFaces(vIndex);
317 return ConstSiblingArray(&_vertFaceSiblings[vOffset], vCount);
319inline FVarLevel::SiblingArray
320FVarLevel::getVertexFaceSiblings(
Index vIndex) {
322 int vCount = _level.getNumVertexFaces(vIndex);
323 int vOffset = _level.getOffsetOfVertexFaces(vIndex);
324 return SiblingArray(&_vertFaceSiblings[vOffset], vCount);
328FVarLevel::getVertexValues(
Index vIndex)
const
330 int vCount = getNumVertexValues(vIndex);
331 int vOffset = getVertexValueOffset(vIndex);
335FVarLevel::getVertexValues(
Index vIndex)
337 int vCount = getNumVertexValues(vIndex);
338 int vOffset = getVertexValueOffset(vIndex);
339 return IndexArray(&_vertValueIndices[vOffset], vCount);
342inline FVarLevel::ConstValueTagArray
343FVarLevel::getVertexValueTags(
Index vIndex)
const
345 int vCount = getNumVertexValues(vIndex);
346 int vOffset = getVertexValueOffset(vIndex);
347 return ConstValueTagArray(&_vertValueTags[vOffset], vCount);
349inline FVarLevel::ValueTagArray
350FVarLevel::getVertexValueTags(
Index vIndex)
352 int vCount = getNumVertexValues(vIndex);
353 int vOffset = getVertexValueOffset(vIndex);
354 return ValueTagArray(&_vertValueTags[vOffset], vCount);
357inline FVarLevel::ConstCreaseEndPairArray
358FVarLevel::getVertexValueCreaseEnds(
Index vIndex)
const
360 int vCount = getNumVertexValues(vIndex);
361 int vOffset = getVertexValueOffset(vIndex);
362 return ConstCreaseEndPairArray(&_vertValueCreaseEnds[vOffset], vCount);
364inline FVarLevel::CreaseEndPairArray
365FVarLevel::getVertexValueCreaseEnds(
Index vIndex)
367 int vCount = getNumVertexValues(vIndex);
368 int vOffset = getVertexValueOffset(vIndex);
369 return CreaseEndPairArray(&_vertValueCreaseEnds[vOffset], vCount);
373FVarLevel::findVertexValueIndex(
Index vertexIndex,
Index valueIndex)
const {
375 if (_level.getDepth() > 0)
return valueIndex;
377 Index vvIndex = getVertexValueOffset(vertexIndex);
378 while (_vertValueIndices[vvIndex] != valueIndex) {
388FVarLevel::ETag::combineWithLevelETag(Level::ETag levelTag)
const
390 if (this->_mismatch) {
391 levelTag._boundary =
true;
392 levelTag._infSharp =
true;
397FVarLevel::ValueTag::combineWithLevelVTag(Level::VTag levelTag)
const
399 if (this->_mismatch) {
407 if (this->isCorner()) {
412 if (this->isCrease() || this->isSemiSharp()) {
413 levelTag._infSharp =
false;
414 levelTag._infSharpCrease =
true;
415 levelTag._corner =
false;
417 levelTag._infSharp =
true;
418 levelTag._infSharpCrease =
false;
419 levelTag._corner = !this->_infIrregular && !this->_infSharpEdges;
421 levelTag._infSharpEdges =
true;
422 levelTag._infIrregular = this->_infIrregular;
424 levelTag._boundary =
true;
425 levelTag._xordinary = this->_xordinary;
427 levelTag._nonManifold |= this->_nonManifold;
436using namespace OPENSUBDIV_VERSION;
ConstArray< LocalIndex > ConstLocalIndexArray
Array< LocalIndex > LocalIndexArray
ConstArray< Index > ConstIndexArray
unsigned short LocalIndex
Array< Index > IndexArray