Skip to content

Commit 91478f1

Browse files
authored
Merge pull request #995 from barfowl/fvar_patch_array_dev
Extended face-varying patch arrays to properly support two types
2 parents c732ff3 + b542bc7 commit 91478f1

File tree

6 files changed

+108
-39
lines changed

6 files changed

+108
-39
lines changed

opensubdiv/far/patchTable.cpp

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "../far/patchTable.h"
2626
#include "../far/patchBasis.h"
2727

28+
#include <algorithm>
2829
#include <cstring>
2930
#include <cstdio>
3031

@@ -157,7 +158,10 @@ struct PatchTable::FVarPatchChannel {
157158

158159
Sdc::Options::FVarLinearInterpolation interpolation;
159160

160-
PatchDescriptor desc;
161+
PatchDescriptor regDesc;
162+
PatchDescriptor irregDesc;
163+
164+
int stride;
161165

162166
std::vector<Index> patchValues;
163167
std::vector<PatchParam> patchParam;
@@ -186,10 +190,16 @@ PatchTable::allocateFVarPatchChannels(int numChannels) {
186190
}
187191
void
188192
PatchTable::allocateFVarPatchChannelValues(
189-
PatchDescriptor desc, int numPatches, int channel) {
193+
PatchDescriptor regDesc, PatchDescriptor irregDesc,
194+
int numPatches, int channel) {
190195
FVarPatchChannel & c = getFVarPatchChannel(channel);
191-
c.desc = desc;
192-
c.patchValues.resize(numPatches*desc.GetNumControlVertices());
196+
c.regDesc = regDesc;
197+
c.irregDesc = irregDesc;
198+
199+
c.stride = std::max(regDesc.GetNumControlVertices(),
200+
irregDesc.GetNumControlVertices());
201+
202+
c.patchValues.resize(numPatches * c.stride);
193203
c.patchParam.resize(numPatches);
194204
}
195205
void
@@ -487,15 +497,30 @@ PatchTable::GetFVarChannelLinearInterpolation(int channel) const {
487497
return c.interpolation;
488498
}
489499
PatchDescriptor
500+
PatchTable::GetFVarPatchDescriptorRegular(int channel) const {
501+
FVarPatchChannel const & c = getFVarPatchChannel(channel);
502+
return c.regDesc;
503+
}
504+
PatchDescriptor
505+
PatchTable::GetFVarPatchDescriptorIrregular(int channel) const {
506+
FVarPatchChannel const & c = getFVarPatchChannel(channel);
507+
return c.irregDesc;
508+
}
509+
PatchDescriptor
490510
PatchTable::GetFVarPatchDescriptor(int channel) const {
491511
FVarPatchChannel const & c = getFVarPatchChannel(channel);
492-
return c.desc;
512+
return c.irregDesc;
493513
}
494514
ConstIndexArray
495515
PatchTable::GetFVarValues(int channel) const {
496516
FVarPatchChannel const & c = getFVarPatchChannel(channel);
497517
return ConstIndexArray(&c.patchValues[0], (int)c.patchValues.size());
498518
}
519+
int
520+
PatchTable::GetFVarValueStride(int channel) const {
521+
FVarPatchChannel const & c = getFVarPatchChannel(channel);
522+
return c.stride;
523+
}
499524
IndexArray
500525
PatchTable::getFVarValues(int channel) {
501526
FVarPatchChannel & c = getFVarPatchChannel(channel);
@@ -504,10 +529,10 @@ PatchTable::getFVarValues(int channel) {
504529
ConstIndexArray
505530
PatchTable::getPatchFVarValues(int patch, int channel) const {
506531
FVarPatchChannel const & c = getFVarPatchChannel(channel);
507-
int ncvsPerPatch = c.desc.GetNumControlVertices();
508532
int ncvsThisPatch = c.patchParam[patch].IsRegular()
509-
? c.desc.GetRegularPatchSize() : ncvsPerPatch;
510-
return ConstIndexArray(&c.patchValues[patch * ncvsPerPatch], ncvsThisPatch);
533+
? c.regDesc.GetNumControlVertices()
534+
: c.irregDesc.GetNumControlVertices();
535+
return ConstIndexArray(&c.patchValues[patch * c.stride], ncvsThisPatch);
511536
}
512537
ConstIndexArray
513538
PatchTable::GetPatchFVarValues(PatchHandle const & handle, int channel) const {
@@ -521,7 +546,7 @@ ConstIndexArray
521546
PatchTable::GetPatchArrayFVarValues(int array, int channel) const {
522547
PatchArray const & pa = getPatchArray(array);
523548
FVarPatchChannel const & c = getFVarPatchChannel(channel);
524-
int ncvs = c.desc.GetNumControlVertices();
549+
int ncvs = c.stride;
525550
int start = pa.patchIndex * ncvs;
526551
int count = pa.numPatches * ncvs;
527552
return ConstIndexArray(&c.patchValues[start], count);
@@ -620,8 +645,8 @@ PatchTable::EvaluateBasisFaceVarying(
620645

621646
PatchParam param = getPatchFVarPatchParam(handle.patchIndex, channel);
622647
PatchDescriptor::Type patchType = param.IsRegular()
623-
? PatchDescriptor::REGULAR
624-
: GetFVarPatchDescriptor(channel).GetType();
648+
? GetFVarPatchDescriptorRegular(channel).GetType()
649+
: GetFVarPatchDescriptorIrregular(channel).GetType();
625650

626651
if (patchType == PatchDescriptor::REGULAR) {
627652
internal::GetBSplineWeights(param, s, t, wP, wDs, wDt, wDss, wDst, wDtt);

opensubdiv/far/patchTable.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,13 @@ class PatchTable {
324324
/// \brief Returns the number of face-varying channels
325325
int GetNumFVarChannels() const;
326326

327-
/// \brief Returns the patch descriptor for \p channel
327+
/// \brief Returns the regular patch descriptor for \p channel
328+
PatchDescriptor GetFVarPatchDescriptorRegular(int channel = 0) const;
329+
330+
/// \brief Returns the irregular patch descriptor for \p channel
331+
PatchDescriptor GetFVarPatchDescriptorIrregular(int channel = 0) const;
332+
333+
/// \brief Returns the default/irregular patch descriptor for \p channel
328334
PatchDescriptor GetFVarPatchDescriptor(int channel = 0) const;
329335

330336
/// \brief Returns the value indices for a given patch in \p channel
@@ -339,6 +345,9 @@ class PatchTable {
339345
/// \brief Returns an array of value indices for the patches in \p channel
340346
ConstIndexArray GetFVarValues(int channel = 0) const;
341347

348+
/// \brief Returns the stride between patches in the value index array of \p channel
349+
int GetFVarValueStride(int channel = 0) const;
350+
342351
/// \brief Returns the value indices for a given patch in \p channel
343352
PatchParam GetPatchFVarPatchParam(PatchHandle const & handle, int channel = 0) const;
344353

@@ -573,7 +582,8 @@ class PatchTable {
573582

574583
void allocateFVarPatchChannels(int numChannels);
575584
void allocateFVarPatchChannelValues(
576-
PatchDescriptor desc, int numPatches, int channel);
585+
PatchDescriptor regDesc, PatchDescriptor irregDesc,
586+
int numPatches, int channel);
577587

578588
// deprecated
579589
void setFVarPatchChannelLinearInterpolation(

opensubdiv/far/patchTableFactory.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -703,18 +703,22 @@ PatchTableBuilder::allocateFVarChannels() {
703703

704704
_table->setFVarPatchChannelLinearInterpolation(interpolation, fvc);
705705

706-
PatchDescriptor::Type fvarPatchType = _patchBuilder->GetLinearPatchType();
706+
PatchDescriptor::Type regPatchType = _patchBuilder->GetLinearPatchType();
707+
PatchDescriptor::Type irregPatchType = regPatchType;
707708
if (_refiner.IsUniform()) {
708709
if (_options.triangulateQuads) {
709-
fvarPatchType = PatchDescriptor::TRIANGLES;
710+
regPatchType = PatchDescriptor::TRIANGLES;
711+
irregPatchType = regPatchType;
710712
}
711713
} else {
712714
if (!isFVarChannelLinear(fvc)) {
713-
fvarPatchType = _patchBuilder->GetIrregularPatchType();
715+
regPatchType = _patchBuilder->GetRegularPatchType();
716+
irregPatchType = _patchBuilder->GetIrregularPatchType();
714717
}
715718
}
716719
_table->allocateFVarPatchChannelValues(
717-
PatchDescriptor(fvarPatchType), npatches, fvc);
720+
PatchDescriptor(regPatchType), PatchDescriptor(irregPatchType),
721+
npatches, fvc);
718722
}
719723
}
720724

@@ -1114,10 +1118,8 @@ PatchTableBuilder::populateAdaptivePatches() {
11141118

11151119
for (int fvc=0; fvc<(int)_fvarChannelIndices.size(); ++fvc) {
11161120

1117-
PatchDescriptor desc = _table->GetFVarPatchDescriptor(fvc);
1118-
11191121
Index pidx = _table->getPatchIndex(arrayIndex, 0);
1120-
int ofs = pidx * desc.GetNumControlVertices();
1122+
int ofs = pidx * _table->GetFVarValueStride(fvc);
11211123

11221124
arrayBuilder.fptr[fvc] = &_table->getFVarValues(fvc)[ofs];
11231125
arrayBuilder.fpptr[fvc] = &_table->getFVarPatchParams(fvc)[pidx];
@@ -1253,8 +1255,7 @@ PatchTableBuilder::populateAdaptivePatches() {
12531255
fvcPatchInfo.isRegular);
12541256
}
12551257
arrayBuilder->fpptr[fvc] ++;
1256-
arrayBuilder->fptr[fvc] +=
1257-
_table->GetFVarPatchDescriptor(fvc).GetNumControlVertices();
1258+
arrayBuilder->fptr[fvc] += _table->GetFVarValueStride(fvc);
12581259
}
12591260

12601261
if (_requiresVaryingPatches) {

opensubdiv/osd/cpuEvaluator.cpp

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,8 @@ CpuEvaluator::EvalPatches(const float *src, BufferDescriptor const &srcDesc,
186186
Far::PatchParam const & param =
187187
patchParamBuffer[coord.handle.patchIndex];
188188
int patchType = param.IsRegular()
189-
? Far::PatchDescriptor::REGULAR
190-
: array.GetPatchType();
189+
? array.GetPatchTypeRegular()
190+
: array.GetPatchTypeIrregular();
191191

192192
int numControlVertices = 0;
193193
if (patchType == Far::PatchDescriptor::REGULAR) {
@@ -207,8 +207,7 @@ CpuEvaluator::EvalPatches(const float *src, BufferDescriptor const &srcDesc,
207207
return false;
208208
}
209209

210-
int indexStride = Far::PatchDescriptor(array.GetPatchType()).GetNumControlVertices();
211-
int indexBase = array.GetIndexBase() + indexStride *
210+
int indexBase = array.GetIndexBase() + array.GetStride() *
212211
(coord.handle.patchIndex - array.GetPrimitiveIdBase());
213212

214213
const int *cvs = &patchIndexBuffer[indexBase];
@@ -265,8 +264,8 @@ CpuEvaluator::EvalPatches(const float *src, BufferDescriptor const &srcDesc,
265264
Far::PatchParam const & param =
266265
patchParamBuffer[coord.handle.patchIndex];
267266
int patchType = param.IsRegular()
268-
? Far::PatchDescriptor::REGULAR
269-
: array.GetPatchType();
267+
? array.GetPatchTypeRegular()
268+
: array.GetPatchTypeIrregular();
270269

271270
int numControlVertices = 0;
272271
if (patchType == Far::PatchDescriptor::REGULAR) {
@@ -285,8 +284,7 @@ CpuEvaluator::EvalPatches(const float *src, BufferDescriptor const &srcDesc,
285284
assert(0);
286285
}
287286

288-
int indexStride = Far::PatchDescriptor(array.GetPatchType()).GetNumControlVertices();
289-
int indexBase = array.GetIndexBase() + indexStride *
287+
int indexBase = array.GetIndexBase() + array.GetStride() *
290288
(coord.handle.patchIndex - array.GetPrimitiveIdBase());
291289

292290
const int *cvs = &patchIndexBuffer[indexBase];
@@ -367,8 +365,8 @@ CpuEvaluator::EvalPatches(const float *src, BufferDescriptor const &srcDesc,
367365
Far::PatchParam const & param =
368366
patchParamBuffer[coord.handle.patchIndex];
369367
int patchType = param.IsRegular()
370-
? Far::PatchDescriptor::REGULAR
371-
: array.GetPatchType();
368+
? array.GetPatchTypeRegular()
369+
: array.GetPatchTypeIrregular();
372370

373371
int numControlVertices = 0;
374372
if (patchType == Far::PatchDescriptor::REGULAR) {
@@ -390,8 +388,7 @@ CpuEvaluator::EvalPatches(const float *src, BufferDescriptor const &srcDesc,
390388
assert(0);
391389
}
392390

393-
int indexStride = Far::PatchDescriptor(array.GetPatchType()).GetNumControlVertices();
394-
int indexBase = array.GetIndexBase() + indexStride *
391+
int indexBase = array.GetIndexBase() + array.GetStride() *
395392
(coord.handle.patchIndex - array.GetPrimitiveIdBase());
396393

397394
const int *cvs = &patchIndexBuffer[indexBase];

opensubdiv/osd/cpuPatchTable.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ CpuPatchTable::CpuPatchTable(const Far::PatchTable *farPatchTable) {
5757
for (int fvc=0; fvc<farPatchTable->GetNumFVarChannels(); ++fvc) {
5858
_fvarPatchArrays[fvc].reserve(nPatchArrays);
5959
_fvarIndexBuffers[fvc].reserve(
60-
numPatches*farPatchTable->GetFVarPatchDescriptor(fvc).GetNumControlVertices());
60+
numPatches * farPatchTable->GetFVarValueStride(fvc));
6161
_fvarParamBuffers[fvc].reserve(numPatches);
6262
}
6363
_patchParamBuffer.reserve(numPatches);
@@ -86,7 +86,9 @@ CpuPatchTable::CpuPatchTable(const Far::PatchTable *farPatchTable) {
8686
// face-varying
8787
for (int fvc=0; fvc<farPatchTable->GetNumFVarChannels(); ++fvc) {
8888
PatchArray fvarPatchArray(
89-
farPatchTable->GetFVarPatchDescriptor(fvc), numPatches, 0, 0);
89+
farPatchTable->GetFVarPatchDescriptorRegular(fvc),
90+
farPatchTable->GetFVarPatchDescriptorIrregular(fvc),
91+
numPatches, 0, 0);
9092
_fvarPatchArrays[fvc].push_back(fvarPatchArray);
9193

9294
Far::ConstIndexArray

opensubdiv/osd/types.h

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#include "../version.h"
2929
#include "../far/patchTable.h"
3030

31+
#include <algorithm>
32+
3133
namespace OpenSubdiv {
3234
namespace OPENSUBDIV_VERSION {
3335

@@ -63,30 +65,62 @@ struct PatchCoord {
6365

6466
struct PatchArray {
6567
// 4-ints struct.
66-
PatchArray(Far::PatchDescriptor desc_in, int numPatches_in,
67-
int indexBase_in, int primitiveIdBase_in) :
68-
desc(desc_in), numPatches(numPatches_in), indexBase(indexBase_in),
68+
PatchArray(Far::PatchDescriptor desc_in,
69+
int numPatches_in, int indexBase_in, int primitiveIdBase_in) :
70+
regDesc(desc_in), desc(desc_in),
71+
numPatches(numPatches_in), indexBase(indexBase_in),
72+
stride(desc_in.GetNumControlVertices()),
73+
primitiveIdBase(primitiveIdBase_in) {}
74+
75+
PatchArray(Far::PatchDescriptor regDesc_in, Far::PatchDescriptor irregDesc_in,
76+
int numPatches_in, int indexBase_in, int primitiveIdBase_in) :
77+
regDesc(regDesc_in), desc(irregDesc_in),
78+
numPatches(numPatches_in), indexBase(indexBase_in),
79+
stride(std::max(regDesc_in.GetNumControlVertices(),
80+
irregDesc_in.GetNumControlVertices())),
6981
primitiveIdBase(primitiveIdBase_in) {}
7082

7183
Far::PatchDescriptor const &GetDescriptor() const {
7284
return desc;
7385
}
86+
Far::PatchDescriptor const &GetDescriptorRegular() const {
87+
return regDesc;
88+
}
89+
Far::PatchDescriptor const &GetDescriptorIrregular() const {
90+
return desc;
91+
}
7492

7593
int GetPatchType() const {
7694
return desc.GetType();
7795
}
96+
int GetPatchTypeRegular() const {
97+
return regDesc.GetType();
98+
}
99+
int GetPatchTypeIrregular() const {
100+
return desc.GetType();
101+
}
102+
78103
int GetNumPatches() const {
79104
return numPatches;
80105
}
81106
int GetIndexBase() const {
82107
return indexBase;
83108
}
109+
int GetStride() const {
110+
return stride;
111+
}
84112
int GetPrimitiveIdBase() const {
85113
return primitiveIdBase;
86114
}
115+
116+
// Separate regular and irregular patch descriptors for cases where the
117+
// array is mixed -- both will be equal if only a single type specified
118+
Far::PatchDescriptor regDesc;
87119
Far::PatchDescriptor desc;
120+
88121
int numPatches;
89122
int indexBase; // an offset within the index buffer
123+
int stride; // stride in buffer between patches
90124
int primitiveIdBase; // an offset within the patch param buffer
91125
};
92126

0 commit comments

Comments
 (0)