First pass at our "Eval" API : this checkin is a mileston and is still missing

code paths for certain types of feature adaptive patches.

The check-in adds a new "limitEval" code example.

More to come soon...

fixes #45
This commit is contained in:
manuelk 2013-04-18 19:55:05 -07:00
parent 24356cc680
commit 4bf24d9b95
13 changed files with 2842 additions and 2 deletions

View File

@ -0,0 +1,84 @@
#
# Copyright (C) Pixar. All rights reserved.
#
# This license governs use of the accompanying software. If you
# use the software, you accept this license. If you do not accept
# the license, do not use the software.
#
# 1. Definitions
# The terms "reproduce," "reproduction," "derivative works," and
# "distribution" have the same meaning here as under U.S.
# copyright law. A "contribution" is the original software, or
# any additions or changes to the software.
# A "contributor" is any person or entity that distributes its
# contribution under this license.
# "Licensed patents" are a contributor's patent claims that read
# directly on its contribution.
#
# 2. Grant of Rights
# (A) Copyright Grant- Subject to the terms of this license,
# including the license conditions and limitations in section 3,
# each contributor grants you a non-exclusive, worldwide,
# royalty-free copyright license to reproduce its contribution,
# prepare derivative works of its contribution, and distribute
# its contribution or any derivative works that you create.
# (B) Patent Grant- Subject to the terms of this license,
# including the license conditions and limitations in section 3,
# each contributor grants you a non-exclusive, worldwide,
# royalty-free license under its licensed patents to make, have
# made, use, sell, offer for sale, import, and/or otherwise
# dispose of its contribution in the software or derivative works
# of the contribution in the software.
#
# 3. Conditions and Limitations
# (A) No Trademark License- This license does not grant you
# rights to use any contributor's name, logo, or trademarks.
# (B) If you bring a patent claim against any contributor over
# patents that you claim are infringed by the software, your
# patent license from such contributor to the software ends
# automatically.
# (C) If you distribute any portion of the software, you must
# retain all copyright, patent, trademark, and attribution
# notices that are present in the software.
# (D) If you distribute any portion of the software in source
# code form, you may do so only under this license by including a
# complete copy of this license with your distribution. If you
# distribute any portion of the software in compiled or object
# code form, you may only do so under a license that complies
# with this license.
# (E) The software is licensed "as-is." You bear the risk of
# using it. The contributors give no express warranties,
# guarantees or conditions. You may have additional consumer
# rights under your local laws which this license cannot change.
# To the extent permitted under your local laws, the contributors
# exclude the implied warranties of merchantability, fitness for
# a particular purpose and non-infringement.
#
# *** glViewer ***
set(PLATFORM_LIBRARIES
${OSD_LINK_TARGET}
${GLEW_LIBRARY}
${GLFW_LIBRARIES}
)
include_directories(
${PROJECT_SOURCE_DIR}/opensubdiv
${PROJECT_SOURCE_DIR}/regression
${GLEW_INCLUDE_DIR}
${GLFW_INCLUDE_DIR}
)
add_executable(limitEval
main.cpp
../common/font_image.cpp
../common/hud.cpp
../common/gl_hud.cpp
${INC_FILES}
)
target_link_libraries(limitEval
${PLATFORM_LIBRARIES}
)

1132
examples/limitEval/main.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -79,8 +79,12 @@ set(CPU_SOURCE_FILES
cpuKernel.cpp
cpuComputeController.cpp
cpuComputeContext.cpp
cpuEvalLimitContext.cpp
cpuEvalLimitController.cpp
cpuEvalLimitKernel.cpp
cpuVertexBuffer.cpp
error.cpp
evalLimitContext.cpp
drawContext.cpp
drawRegistry.cpp
sortedDrawContext.cpp
@ -98,14 +102,18 @@ set(INC_FILES
set(PRIVATE_HEADER_FILES
debug.h
cpuKernel.h
cpuEvalLimitKernel.h
)
set(PUBLIC_HEADER_FILES
computeController.h
cpuComputeContext.h
cpuComputeController.h
cpuEvalLimitContext.h
cpuEvalLimitController.h
cpuVertexBuffer.h
error.h
evalLimitContext.h
mesh.h
nonCopyable.h
drawContext.h

View File

@ -0,0 +1,178 @@
//
// Copyright (C) Pixar. All rights reserved.
//
// This license governs use of the accompanying software. If you
// use the software, you accept this license. If you do not accept
// the license, do not use the software.
//
// 1. Definitions
// The terms "reproduce," "reproduction," "derivative works," and
// "distribution" have the same meaning here as under U.S.
// copyright law. A "contribution" is the original software, or
// any additions or changes to the software.
// A "contributor" is any person or entity that distributes its
// contribution under this license.
// "Licensed patents" are a contributor's patent claims that read
// directly on its contribution.
//
// 2. Grant of Rights
// (A) Copyright Grant- Subject to the terms of this license,
// including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide,
// royalty-free copyright license to reproduce its contribution,
// prepare derivative works of its contribution, and distribute
// its contribution or any derivative works that you create.
// (B) Patent Grant- Subject to the terms of this license,
// including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide,
// royalty-free license under its licensed patents to make, have
// made, use, sell, offer for sale, import, and/or otherwise
// dispose of its contribution in the software or derivative works
// of the contribution in the software.
//
// 3. Conditions and Limitations
// (A) No Trademark License- This license does not grant you
// rights to use any contributor's name, logo, or trademarks.
// (B) If you bring a patent claim against any contributor over
// patents that you claim are infringed by the software, your
// patent license from such contributor to the software ends
// automatically.
// (C) If you distribute any portion of the software, you must
// retain all copyright, patent, trademark, and attribution
// notices that are present in the software.
// (D) If you distribute any portion of the software in source
// code form, you may do so only under this license by including a
// complete copy of this license with your distribution. If you
// distribute any portion of the software in compiled or object
// code form, you may only do so under a license that complies
// with this license.
// (E) The software is licensed "as-is." You bear the risk of
// using it. The contributors give no express warranties,
// guarantees or conditions. You may have additional consumer
// rights under your local laws which this license cannot change.
// To the extent permitted under your local laws, the contributors
// exclude the implied warranties of merchantability, fitness for
// a particular purpose and non-infringement.
//
#include "../osd/cpuEvalLimitContext.h"
#include "../osd/vertexDescriptor.h"
#include <string.h>
#include <cassert>
#include <cstdio>
#include <cmath>
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
OsdCpuEvalLimitContext *
OsdCpuEvalLimitContext::Create(FarMesh<OsdVertex> const * farmesh) {
assert(farmesh);
// we do not support uniform yet
if (not farmesh->GetPatchTables())
return NULL;
return new OsdCpuEvalLimitContext(farmesh);
}
OsdCpuEvalLimitContext::OsdCpuEvalLimitContext(FarMesh<OsdVertex> const * farmesh) :
OsdEvalLimitContext(farmesh) {
FarPatchTables const * patchTables = farmesh->GetPatchTables();
assert(patchTables);
_patchMap = new OsdCpuEvalLimitContext::PatchMap( *patchTables );
size_t npatches = patchTables->GetNumPatches(),
nvertices = patchTables->GetNumControlVertices();
_patchArrays.reserve(npatches);
_patchBitFields.reserve(npatches);
_patchBuffer.reserve(nvertices);
// Full regular patches
_AppendPatchArray(OsdPatchDescriptor(kRegular, 0, 0, 0, 0),
patchTables->GetFullRegularPatches(),
patchTables->GetFullRegularPtexCoordinates());
_AppendPatchArray(OsdPatchDescriptor(kBoundary, 0, 0, 0, 0),
patchTables->GetFullBoundaryPatches(),
patchTables->GetFullBoundaryPtexCoordinates());
_AppendPatchArray(OsdPatchDescriptor(kCorner, 0, 0, 0, 0),
patchTables->GetFullCornerPatches(),
patchTables->GetFullCornerPtexCoordinates());
_AppendPatchArray(OsdPatchDescriptor(kGregory, 0, 0, patchTables->GetMaxValence(), 0),
patchTables->GetFullGregoryPatches(),
patchTables->GetFullGregoryPtexCoordinates());
_AppendPatchArray(OsdPatchDescriptor(kBoundaryGregory, 0, 0, patchTables->GetMaxValence(), 0),
patchTables->GetFullBoundaryGregoryPatches(),
patchTables->GetFullBoundaryGregoryPtexCoordinates());
_vertexValenceBuffer = patchTables->GetVertexValenceTable();
_quadOffsetBuffer = patchTables->GetQuadOffsetTable();
// Transition patches
for (int p=0; p<5; ++p) {
_AppendPatchArray(OsdPatchDescriptor(kTransitionRegular, p, 0, 0, 0),
patchTables->GetTransitionRegularPatches(p),
patchTables->GetTransitionRegularPtexCoordinates(p));
for (int r=0; r<4; ++r) {
_AppendPatchArray(OsdPatchDescriptor(kTransitionBoundary, p, r, 0, 0),
patchTables->GetTransitionBoundaryPatches(p, r),
patchTables->GetTransitionBoundaryPtexCoordinates(p, r));
_AppendPatchArray(OsdPatchDescriptor(kTransitionCorner, p, r, 0, 0),
patchTables->GetTransitionCornerPatches(p, r),
patchTables->GetTransitionCornerPtexCoordinates(p, r));
}
}
}
OsdCpuEvalLimitContext::~OsdCpuEvalLimitContext() {
delete _patchMap;
}
int
OsdCpuEvalLimitContext::_AppendPatchArray(
OsdPatchDescriptor const & desc,
FarPatchTables::PTable const & pTable,
FarPatchTables::PtexCoordinateTable const & ptxTable )
{
if (pTable.first.empty() or ptxTable.empty())
return 0;
OsdPatchArray array;
array.desc = desc;
array.firstIndex = (int)_patchBuffer.size();
array.numIndices = (int)pTable.first.size();
array.gregoryQuadOffsetBase = 0;
//array.gregoryVertexValenceBase = gregoryQuadOffsetBase;
// copy patch array descriptor
_patchArrays.push_back(array);
// copy patches bitfields
for (int i=0; i<(int)ptxTable.size(); ++i) {
_patchBitFields.push_back( ptxTable[i].bitField );
}
// copy control vertices indices
_patchBuffer.insert( _patchBuffer.end(), pTable.first.begin(), pTable.first.end());
return 1;
}
} // end namespace OPENSUBDIV_VERSION
} // end namespace OpenSubdiv

View File

@ -0,0 +1,359 @@
//
// Copyright (C) Pixar. All rights reserved.
//
// This license governs use of the accompanying software. If you
// use the software, you accept this license. If you do not accept
// the license, do not use the software.
//
// 1. Definitions
// The terms "reproduce," "reproduction," "derivative works," and
// "distribution" have the same meaning here as under U.S.
// copyright law. A "contribution" is the original software, or
// any additions or changes to the software.
// A "contributor" is any person or entity that distributes its
// contribution under this license.
// "Licensed patents" are a contributor's patent claims that read
// directly on its contribution.
//
// 2. Grant of Rights
// (A) Copyright Grant- Subject to the terms of this license,
// including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide,
// royalty-free copyright license to reproduce its contribution,
// prepare derivative works of its contribution, and distribute
// its contribution or any derivative works that you create.
// (B) Patent Grant- Subject to the terms of this license,
// including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide,
// royalty-free license under its licensed patents to make, have
// made, use, sell, offer for sale, import, and/or otherwise
// dispose of its contribution in the software or derivative works
// of the contribution in the software.
//
// 3. Conditions and Limitations
// (A) No Trademark License- This license does not grant you
// rights to use any contributor's name, logo, or trademarks.
// (B) If you bring a patent claim against any contributor over
// patents that you claim are infringed by the software, your
// patent license from such contributor to the software ends
// automatically.
// (C) If you distribute any portion of the software, you must
// retain all copyright, patent, trademark, and attribution
// notices that are present in the software.
// (D) If you distribute any portion of the software in source
// code form, you may do so only under this license by including a
// complete copy of this license with your distribution. If you
// distribute any portion of the software in compiled or object
// code form, you may only do so under a license that complies
// with this license.
// (E) The software is licensed "as-is." You bear the risk of
// using it. The contributors give no express warranties,
// guarantees or conditions. You may have additional consumer
// rights under your local laws which this license cannot change.
// To the extent permitted under your local laws, the contributors
// exclude the implied warranties of merchantability, fitness for
// a particular purpose and non-infringement.
//
#ifndef OSD_CPU_EVAL_LIMIT_CONTEXT_H
#define OSD_CPU_EVAL_LIMIT_CONTEXT_H
#include "../version.h"
#include "../osd/evalLimitContext.h"
#include "../osd/vertexDescriptor.h"
#include <map>
#include <stdio.h>
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
class OsdCpuEvalLimitContext : public OsdEvalLimitContext {
public:
/// \brief Factory
/// Returns an EvalLimitContext from the given farmesh.
/// Note : the farmesh is expected to be feature-adaptive and have ptex
/// coordinates tables.
static OsdCpuEvalLimitContext * Create(FarMesh<OsdVertex> const * farmesh);
/// Destructor
virtual ~OsdCpuEvalLimitContext();
/// Binds the data buffers.
///
/// @param inDesc vertex buffer data descriptor shared by all input data buffers
///
/// @param inQ input vertex data
///
/// @param outDesc vertex buffer data descriptor shared by all output data buffers
///
/// @param outQ output vertex data
///
/// @param outDQu optional output derivative along "u" of the vertex data
///
/// @param outDQv optional output derivative along "v" of the vertex data
///
template<class VERTEX_BUFFER, class OUTPUT_BUFFER>
void BindVertexBuffers( OsdVertexBufferDescriptor const & inDesc, VERTEX_BUFFER *inQ,
OsdVertexBufferDescriptor const & outDesc, OUTPUT_BUFFER *outQ,
OUTPUT_BUFFER *outdQu=0,
OUTPUT_BUFFER *outdQv=0) {
_inDesc = inDesc;
_inQ = inQ ? inQ->BindCpuBuffer() : 0;
_outDesc = outDesc;
_outQ = outQ ? outQ->BindCpuBuffer() : 0 ;
_outdQu = outdQu ? outdQu->BindCpuBuffer() : 0 ;
_outdQv = outdQv ? outdQv->BindCpuBuffer() : 0 ;
}
/// Unbind the data buffers
void UnbindVertexBuffers() {
_inQ = 0;
_outQ = 0;
_outdQu = 0;
_outdQv = 0;
}
/// Returns the input vertex buffer descriptor
const OsdVertexBufferDescriptor & GetInputDesc() const {
return _inDesc;
}
/// Returns the output vertex buffer descriptor
const OsdVertexBufferDescriptor & GetOutputDesc() const {
return _outDesc;
}
/// Returns the input vertex buffer data
float const * GetInputVertexData() const {
return _inQ;
}
/// Returns the output vertex buffer data
float * GetOutputVertexData() const {
return _outQ;
}
/// Returns the U derivative of the output vertex buffer data
float * GetOutputVertexDataUDerivative() const {
return _outdQu;
}
/// Returns the V derivative of the output vertex buffer data
float * GetOutputVertexDataVDerivative() const {
return _outdQv;
}
/// Returns the vector of patch arrays
const OsdPatchArrayVector & GetPatchArrayVector() const {
return _patchArrays;
}
/// Returns the vector of per-patch parametric data
const std::vector<FarPtexCoord::BitField> & GetPatchBitFields() const {
return _patchBitFields;
}
/// The ordered array of control vertex indices for all the patches
const std::vector<unsigned int> & GetControlVertices() const {
return _patchBuffer;
}
/// XXXX
const int * GetVertexValenceBuffer() const {
return &_vertexValenceBuffer[0];
}
const unsigned int *GetQuadOffsetBuffer() const {
return &_quadOffsetBuffer[0];
}
/// Maps coarse-face ptex coordinates to children patches
struct PatchMap {
public:
/// \brief Returns the number and list of patch indices for a given face.
///
/// PatchMaps map coarse faces to their childrn feature adaptive patches.
/// Coarse faces are indexed using their ptex face ID to resolve parametric
/// ambiguity on non-quad faces. Note : this "map" is actually a vector, so
/// queries are O(1) order.
///
/// @param faceid the ptex face index to search for
///
/// @param npatches the number of children patches found for the faceid
///
/// @param patches a set of pointers to the individual patch handles
///
bool GetChildPatchesHandles( int faceid, int * npatches, OsdPatchHandle const ** patches ) const {
if (_handles.empty() or _offsets.empty() or (faceid>=(int)_offsets.size()))
return false;
*npatches = (faceid==(int)_offsets.size()-1 ? (unsigned int)_handles.size()-1 : _offsets[faceid+1]) - _offsets[faceid] + 1;
*patches = &_handles[ _offsets[faceid] ];
return true;
}
private:
friend class OsdCpuEvalLimitContext;
typedef std::multimap<unsigned int, OsdPatchHandle> MultiMap;
// Inserts the patches from the array into the multimap
int _AddPatchArray( int arrayid, int ringsize,
FarPatchTables::PtexCoordinateTable const & ptxtable,
int & nfaces, MultiMap & mmap ) {
if (ptxtable.empty())
return 0;
for (int i=0; i<(int)ptxtable.size(); ++i) {
int faceId = ptxtable[i].faceIndex;
OsdPatchHandle handle = { arrayid, i*ringsize, (unsigned int)mmap.size() };
mmap.insert( std::pair<unsigned int, OsdPatchHandle>(faceId, handle) );
nfaces = std::max(nfaces, faceId);
}
return 1;
}
// Constructor
PatchMap( FarPatchTables const & patchTables ) {
int npatches = (int)patchTables.GetNumPatches();
_handles.reserve(npatches);
MultiMap mmap;
// Insert all the patch arrays into the map
int arrayId=0, nfaces=0;
arrayId+=_AddPatchArray( arrayId,
patchTables.GetRegularPatchRingsize(),
patchTables.GetFullRegularPtexCoordinates(),
nfaces, mmap );
arrayId+=_AddPatchArray( arrayId,
patchTables.GetBoundaryPatchRingsize(),
patchTables.GetFullBoundaryPtexCoordinates(),
nfaces, mmap );
arrayId+=_AddPatchArray( arrayId,
patchTables.GetCornerPatchRingsize(),
patchTables.GetFullCornerPtexCoordinates(),
nfaces, mmap );
arrayId+=_AddPatchArray( arrayId,
patchTables.GetGregoryPatchRingsize(),
patchTables.GetFullGregoryPtexCoordinates(),
nfaces, mmap );
for (unsigned char pattern=0; pattern<5; ++pattern) {
arrayId+=_AddPatchArray( arrayId,
patchTables.GetRegularPatchRingsize(),
patchTables.GetTransitionRegularPtexCoordinates(pattern),
nfaces, mmap );
for (unsigned char rot=0; rot<4; ++rot) {
arrayId+=_AddPatchArray( arrayId,
patchTables.GetBoundaryPatchRingsize(),
patchTables.GetTransitionBoundaryPtexCoordinates(pattern, rot),
nfaces, mmap );
arrayId+=_AddPatchArray( arrayId,
patchTables.GetCornerPatchRingsize(),
patchTables.GetTransitionCornerPtexCoordinates(pattern, rot),
nfaces, mmap );
}
}
++nfaces;
_handles.resize( mmap.size() );
_offsets.reserve( nfaces );
_offsets.push_back(0);
unsigned int handlesIdx = 0, faceId=mmap.begin()->first;
// Serialize the multi-map
for (MultiMap::const_iterator it=mmap.begin(); it!=mmap.end(); ++it, ++handlesIdx) {
assert(it->first >= faceId);
if (it->first != faceId) {
faceId = it->first;
// position the offset marker to the new face
_offsets.push_back( handlesIdx );
}
// copy the patch id into the table
_handles[handlesIdx] = it->second;
}
}
// Patch handle allowing location of individual patch data inside patch
// arrays or in serialized form
std::vector<OsdPatchHandle> _handles;
// offset to the first handle of the child patches for each coarse face
std::vector<unsigned int> _offsets;
};
/// Returns a map object that can connect a faceId to a list of children patches
const PatchMap * GetPatchesMap() const {
return _patchMap;
}
protected:
explicit OsdCpuEvalLimitContext(FarMesh<OsdVertex> const * farmesh);
private:
//--------------------------------------------------------------------------
int _AppendPatchArray( OsdPatchDescriptor const & desc,
FarPatchTables::PTable const & pT,
FarPatchTables::PtexCoordinateTable const & ptxT );
// Topology data for a mesh
OsdPatchArrayVector _patchArrays; // patch descriptor for each patch in the mesh
std::vector<FarPtexCoord::BitField> _patchBitFields; // per-patch parametric info
std::vector<unsigned int> _patchBuffer; // list of control vertices
std::vector<int> _vertexValenceBuffer; // extra Gregory patch data buffers
std::vector<unsigned int> _quadOffsetBuffer;
PatchMap * _patchMap;
OsdVertexBufferDescriptor _inDesc,
_outDesc;
float * _inQ, // input vertex data
* _outQ, // output vertex data
* _outdQu, // U derivative of output vertex data
* _outdQv; // V derivative of output vertex data
};
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
} // end namespace OpenSubdiv
#endif /* OSD_CPU_EVAL_LIMIT_CONTEXT_H */

View File

@ -0,0 +1,179 @@
//
// Copyright (C) Pixar. All rights reserved.
//
// This license governs use of the accompanying software. If you
// use the software, you accept this license. If you do not accept
// the license, do not use the software.
//
// 1. Definitions
// The terms "reproduce," "reproduction," "derivative works," and
// "distribution" have the same meaning here as under U.S.
// copyright law. A "contribution" is the original software, or
// any additions or changes to the software.
// A "contributor" is any person or entity that distributes its
// contribution under this license.
// "Licensed patents" are a contributor's patent claims that read
// directly on its contribution.
//
// 2. Grant of Rights
// (A) Copyright Grant- Subject to the terms of this license,
// including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide,
// royalty-free copyright license to reproduce its contribution,
// prepare derivative works of its contribution, and distribute
// its contribution or any derivative works that you create.
// (B) Patent Grant- Subject to the terms of this license,
// including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide,
// royalty-free license under its licensed patents to make, have
// made, use, sell, offer for sale, import, and/or otherwise
// dispose of its contribution in the software or derivative works
// of the contribution in the software.
//
// 3. Conditions and Limitations
// (A) No Trademark License- This license does not grant you
// rights to use any contributor's name, logo, or trademarks.
// (B) If you bring a patent claim against any contributor over
// patents that you claim are infringed by the software, your
// patent license from such contributor to the software ends
// automatically.
// (C) If you distribute any portion of the software, you must
// retain all copyright, patent, trademark, and attribution
// notices that are present in the software.
// (D) If you distribute any portion of the software in source
// code form, you may do so only under this license by including a
// complete copy of this license with your distribution. If you
// distribute any portion of the software in compiled or object
// code form, you may only do so under a license that complies
// with this license.
// (E) The software is licensed "as-is." You bear the risk of
// using it. The contributors give no express warranties,
// guarantees or conditions. You may have additional consumer
// rights under your local laws which this license cannot change.
// To the extent permitted under your local laws, the contributors
// exclude the implied warranties of merchantability, fitness for
// a particular purpose and non-infringement.
//
#include "../osd/cpuEvalLimitController.h"
#include "../osd/cpuEvalLimitKernel.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
OsdCpuEvalLimitController::OsdCpuEvalLimitController() {
}
OsdCpuEvalLimitController::~OsdCpuEvalLimitController() {
}
int
OsdCpuEvalLimitController::_EvalLimitSample( OpenSubdiv::OsdEvalCoords const & coords,
OsdCpuEvalLimitContext const *context,
unsigned int index ) {
int npatches=0;
OsdPatchHandle const * patchHandles;
// Get the list of all children patches of the face described in coords
if (not context->GetPatchesMap()->GetChildPatchesHandles( coords.face, &npatches, &patchHandles))
return 0;
// Position lookup pointers at the indexed vertex
float const * inQ = context->GetInputVertexData();
float * outQ = context->GetOutputVertexData() + index * context->GetOutputDesc().stride;
float * outdQu = context->GetOutputVertexDataUDerivative() + index * context->GetOutputDesc().stride;
float * outdQv = context->GetOutputVertexDataVDerivative() + index * context->GetOutputDesc().stride;
for (int i=0; i<npatches; ++i) {
OsdPatchHandle const & handle = patchHandles[i];
FarPtexCoord::BitField bits = context->GetPatchBitFields()[ handle.serialIndex ];
float frac = 1.0f / float( 1 << bits.GetDepth() );
// Are the coordinates within the parametric space covered by the patch ?
float pu = (float)bits.GetU()*frac;
if ( (coords.u < pu) or (coords.u > pu+frac) )
continue;
float pv = (float)bits.GetV()*frac;
if ( (coords.v < pv) or (coords.v > pv+frac) )
continue;
assert( handle.array < context->GetPatchArrayVector().size() );
OsdPatchArray const & parray = context->GetPatchArrayVector()[ handle.array ];
unsigned int const * cvs = &context->GetControlVertices()[ parray.firstIndex + handle.vertexOffset ];
// normalize u,v coordinates
float u = (coords.u - pu) / frac,
v = (coords.v - pv) / frac;
assert( (u>=0.0f) and (u<=1.0f) and (v>=0.0f) and (v<=1.0f) );
// Based on patch type - go execute interpolation
switch( parray.desc.type ) {
case kRegular :
evalBSpline( v, u, cvs,
context->GetInputDesc(),
inQ,
context->GetOutputDesc(),
outQ, outdQu, outdQv); return 1;
case kBoundary : return 0;
case kCorner : return 0;
case kGregory : /*evalGregory(v, u, cvs,
unsigned int const * quadOffsetBuffer,
int maxValence,
unsigned int const * vertexIndices,
OsdVertexBufferDescriptor const & inDesc,
float const * inQ,
OsdVertexBufferDescriptor const & outDesc,
float * outQ,
float * outDQU,
float * outDQV );*/ return 0;
return 0;
case kBoundaryGregory : return 0;
case kTransitionRegular :
switch( bits.GetRotation() ) {
case 0 : break;
case 1 : { float tmp=v; v=1.0f-u; u=tmp; } break;
case 2 : { u=1.0f-u; v=1.0f-v; } break;
case 3 : { float tmp=u; u=1.0f-v; v=tmp; } break;
default:
assert(0);
}
evalBSpline( v, u, cvs,
context->GetInputDesc(),
inQ,
context->GetOutputDesc(),
outQ, outdQu, outdQv); return 1;
case kTransitionBoundary: return 0;
case kTransitionCorner : return 0;
default:
assert(0);
}
}
return 0;
}
} // end namespace OPENSUBDIV_VERSION
} // end namespace OpenSubdiv

View File

@ -0,0 +1,143 @@
//
// Copyright (C) Pixar. All rights reserved.
//
// This license governs use of the accompanying software. If you
// use the software, you accept this license. If you do not accept
// the license, do not use the software.
//
// 1. Definitions
// The terms "reproduce," "reproduction," "derivative works," and
// "distribution" have the same meaning here as under U.S.
// copyright law. A "contribution" is the original software, or
// any additions or changes to the software.
// A "contributor" is any person or entity that distributes its
// contribution under this license.
// "Licensed patents" are a contributor's patent claims that read
// directly on its contribution.
//
// 2. Grant of Rights
// (A) Copyright Grant- Subject to the terms of this license,
// including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide,
// royalty-free copyright license to reproduce its contribution,
// prepare derivative works of its contribution, and distribute
// its contribution or any derivative works that you create.
// (B) Patent Grant- Subject to the terms of this license,
// including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide,
// royalty-free license under its licensed patents to make, have
// made, use, sell, offer for sale, import, and/or otherwise
// dispose of its contribution in the software or derivative works
// of the contribution in the software.
//
// 3. Conditions and Limitations
// (A) No Trademark License- This license does not grant you
// rights to use any contributor's name, logo, or trademarks.
// (B) If you bring a patent claim against any contributor over
// patents that you claim are infringed by the software, your
// patent license from such contributor to the software ends
// automatically.
// (C) If you distribute any portion of the software, you must
// retain all copyright, patent, trademark, and attribution
// notices that are present in the software.
// (D) If you distribute any portion of the software in source
// code form, you may do so only under this license by including a
// complete copy of this license with your distribution. If you
// distribute any portion of the software in compiled or object
// code form, you may only do so under a license that complies
// with this license.
// (E) The software is licensed "as-is." You bear the risk of
// using it. The contributors give no express warranties,
// guarantees or conditions. You may have additional consumer
// rights under your local laws which this license cannot change.
// To the extent permitted under your local laws, the contributors
// exclude the implied warranties of merchantability, fitness for
// a particular purpose and non-infringement.
//
#ifndef OSD_CPU_EVAL_LIMIT_CONTROLLER_H
#define OSD_CPU_EVAL_LIMIT_CONTROLLER_H
#include "../version.h"
#include "../osd/evalLimitContext.h"
#include "../osd/cpuEvalLimitContext.h"
#include "../osd/vertexDescriptor.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
/// \brief CPU controler for limit surface evaluation.
///
/// A CPU-driven controller that can be called to evaluate samples on the limit
/// surface for a given EvalContext.
///
class OsdCpuEvalLimitController {
public:
/// Constructor.
OsdCpuEvalLimitController();
/// Destructor.
~OsdCpuEvalLimitController();
/// \brief Represents a location on the limit surface
struct OsdEvalCoords {
int face; // Ptex unique face ID
float u,v; // local u,v
};
/// \brief Vertex interpolation of samples at the limit
///
/// Evaluates "vertex" interpolation of a sample on the surface limit.
///
/// Warning : this function is re-entrant but it breaks the Osd API pattern
/// by requiring the client code to bind and unbind the vertex buffers to
/// the EvalLimitContext.
///
/// Ex :
/// \code
/// evalCtxt->BindVertexBuffers( ... );
///
/// parallel_for( int index=0; i<nsamples; ++index ) {
/// evalCtrlr->EvalLimitSample( coord, evalCtxt, index );
/// }
///
/// evalCtxt->UnbindVertexBuffers();
/// \endcode
///
/// @param coords location on the limit surface to be evaluated
///
/// @param context the EvalLimitContext that the controller will evaluate
///
/// @param index the index of the vertex in the output buffers bound to the
/// context
///
template<class VERTEX_BUFFER, class OUTPUT_BUFFER>
int EvalLimitSample( OpenSubdiv::OsdEvalCoords const & coords,
OsdCpuEvalLimitContext * context,
unsigned int index
) {
if (not context)
return 0;
int n = _EvalLimitSample( coords, context, index );
return n;
}
private:
int _EvalLimitSample( OpenSubdiv::OsdEvalCoords const & coords,
OsdCpuEvalLimitContext const * context,
unsigned int index );
};
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
} // end namespace OpenSubdiv
#endif /* OSD_CPU_EVAL_LIMIT_CONTROLLER_H */

View File

@ -0,0 +1,427 @@
//
// Copyright (C) Pixar. All rights reserved.
//
// This license governs use of the accompanying software. If you
// use the software, you accept this license. If you do not accept
// the license, do not use the software.
//
// 1. Definitions
// The terms "reproduce," "reproduction," "derivative works," and
// "distribution" have the same meaning here as under U.S.
// copyright law. A "contribution" is the original software, or
// any additions or changes to the software.
// A "contributor" is any person or entity that distributes its
// contribution under this license.
// "Licensed patents" are a contributor's patent claims that read
// directly on its contribution.
//
// 2. Grant of Rights
// (A) Copyright Grant- Subject to the terms of this license,
// including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide,
// royalty-free copyright license to reproduce its contribution,
// prepare derivative works of its contribution, and distribute
// its contribution or any derivative works that you create.
// (B) Patent Grant- Subject to the terms of this license,
// including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide,
// royalty-free license under its licensed patents to make, have
// made, use, sell, offer for sale, import, and/or otherwise
// dispose of its contribution in the software or derivative works
// of the contribution in the software.
//
// 3. Conditions and Limitations
// (A) No Trademark License- This license does not grant you
// rights to use any contributor's name, logo, or trademarks.
// (B) If you bring a patent claim against any contributor over
// patents that you claim are infringed by the software, your
// patent license from such contributor to the software ends
// automatically.
// (C) If you distribute any portion of the software, you must
// retain all copyright, patent, trademark, and attribution
// notices that are present in the software.
// (D) If you distribute any portion of the software in source
// code form, you may do so only under this license by including a
// complete copy of this license with your distribution. If you
// distribute any portion of the software in compiled or object
// code form, you may only do so under a license that complies
// with this license.
// (E) The software is licensed "as-is." You bear the risk of
// using it. The contributors give no express warranties,
// guarantees or conditions. You may have additional consumer
// rights under your local laws which this license cannot change.
// To the extent permitted under your local laws, the contributors
// exclude the implied warranties of merchantability, fitness for
// a particular purpose and non-infringement.
//
#include "../osd/cpuEvalLimitKernel.h"
#include <math.h>
#include <cstdio>
#include <cstdlib>
#include <string.h>
#include <algorithm>
#include <vector>
#include <cassert>
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
inline void
evalCubicBSpline(float u, float B[4], float BU[4])
{
float t = u;
float s = 1.0f - u;
float C0 = s * (0.5f * s);
float C1 = t * (s + 0.5f * t) + s * (0.5f * s + t);
float C2 = t * ( 0.5f * t);
B[0] = 1.f/3.f * s * C0;
B[1] = (2.f/3.f * s + t) * C0 + (2.f/3.f * s + 1.f/3.f * t) * C1;
B[2] = (1.f/3.f * s + 2.f/3.f * t) * C1 + ( s + 2.f/3.f * t) * C2;
B[3] = 1.f/3.f * t * C2;
if (BU) {
BU[0] = - C0;
BU[1] = C0 - C1;
BU[2] = C1 - C2;
BU[3] = C2;
}
}
void
evalBSpline(float u, float v,
unsigned int const * vertexIndices,
OsdVertexBufferDescriptor const & inDesc,
float const * inQ,
OsdVertexBufferDescriptor const & outDesc,
float * outQ,
float * outDQU,
float * outDQV ) {
// make sure that we have enough space to store results
assert( inDesc.length <= (outDesc.stride-outDesc.offset) );
bool evalDeriv = (outDQU or outDQV);
// XXX these dynamic allocs won't work w/ VC++
float B[4], D[4],
*BU=(float*)alloca(inDesc.length*4*sizeof(float)),
*DU=(float*)alloca(inDesc.length*4*sizeof(float));
memset(BU, 0, inDesc.length*4*sizeof(float));
memset(DU, 0, inDesc.length*4*sizeof(float));
evalCubicBSpline(u, B, evalDeriv ? D : 0);
float const * inOffset = inQ + inDesc.offset;
for (int i=0; i<4; ++i) {
for (int j=0; j<4; ++j) {
float const * in = inOffset + vertexIndices[i+j*4]*inDesc.stride;
for (int k=0; k<inDesc.length; ++k) {
BU[i*inDesc.length+k] += in[k] * B[j];
if (evalDeriv)
DU[i*inDesc.length+k] += in[k] * D[j];
}
}
}
evalCubicBSpline(v, B, evalDeriv ? D : 0);
float * Q = outQ + outDesc.offset,
* dQU = outDQU + outDesc.offset,
* dQV = outDQV + outDesc.offset;
// clear result
memset(Q, 0, inDesc.length*sizeof(float));
if (evalDeriv) {
memset(dQU, 0, inDesc.length*sizeof(float));
memset(dQV, 0, inDesc.length*sizeof(float));
}
for (int i=0; i<4; ++i) {
for (int k=0; k<inDesc.length; ++k) {
Q[k] += BU[inDesc.length*i+k] * B[i];
if (evalDeriv) {
dQU[k] += DU[inDesc.length*i+k] * B[i];
dQV[k] += BU[inDesc.length*i+k] * D[i];
}
}
}
}
inline void
univar4x4(float u, float B[4], float D[4])
{
float t = u;
float s = 1.0f - u;
float A0 = s * s;
float A1 = 2 * s * t;
float A2 = t * t;
B[0] = s * A0;
B[1] = t * A0 + s * A1;
B[2] = t * A1 + s * A2;
B[3] = t * A2;
if (D) {
D[0] = - A0;
D[1] = A0 - A1;
D[2] = A1 - A2;
D[3] = A2;
}
}
inline float
csf(unsigned int n, unsigned int j)
{
if (j%2 == 0) {
return cosf((2.0f * float(M_PI) * float(float(j-0)/2.0f))/(float(n)+3.0f));
} else {
return sinf((2.0f * float(M_PI) * float(float(j-1)/2.0f))/(float(n)+3.0f));
}
}
void
evalGregory(float u, float v,
int const * vertexValenceBuffer,
unsigned int const * quadOffsetBuffer,
int maxValence,
unsigned int const * vertexIndices,
OsdVertexBufferDescriptor const & inDesc,
float const * inQ,
OsdVertexBufferDescriptor const & outDesc,
float * outQ,
float * outDQU,
float * outDQV )
{
static float const ef[7] = {
0.813008f, 0.500000f, 0.363636f, 0.287505f,
0.238692f, 0.204549f, 0.179211f
};
// make sure that we have enough space to store results
assert( inDesc.length <= (outDesc.stride-outDesc.offset) );
bool evalDeriv = (outDQU or outDQV);
int valences[4], length=inDesc.length;
float const * inQo = inQ + inDesc.offset;
float *r=(float*)alloca(length*4*maxValence*sizeof(float)), *rp=r,
*e0=(float*)alloca(length*4*sizeof(float)),
*e1=(float*)alloca(length*4*sizeof(float));
float *opos=(float*)alloca(length*4*sizeof(float));
for (int vid=0; vid < 4; ++vid, rp+=maxValence*length) {
int vertexID = vertexIndices[vid];
const int *valenceTable = vertexValenceBuffer + vertexID * (2*maxValence+1);
int valence = valenceTable[0];
valences[vid] = valence;
float *f=(float*)alloca(maxValence*length*sizeof(float)), *fp=f,
*Q=(float*)alloca(length*sizeof(float)),
*oQ=(float*)alloca(length*sizeof(float));
memcpy(Q, inQo + vertexID*inDesc.stride, length*sizeof(float));
memset(oQ, 0, length*sizeof(float));
for (int i=0; i<valence; ++i) {
int im = (i+valence-1)&valence;
int ip = (i+1)%valence;
int idx_neighbor = valenceTable[2*i + 0 + 1];
int idx_diagonal = valenceTable[2*i + 1 + 1];
int idx_neighbor_p = valenceTable[2*ip + 0 + 1];
int idx_neighbor_m = valenceTable[2*im + 0 + 1];
int idx_diagonal_m = valenceTable[2*im + 1 + 1];
float const * neighbor = inQo + idx_neighbor * inDesc.stride;
float const * diagonal = inQo + idx_diagonal * inDesc.stride;
float const * neighbor_p = inQo + idx_neighbor_p * inDesc.stride;
float const * neighbor_m = inQo + idx_neighbor_m * inDesc.stride;
float const * diagonal_m = inQo + idx_diagonal_m * inDesc.stride;
for (int k=0; k<length; ++k, ++fp, ++rp) {
*fp = (Q[k]*float(valence) + (neighbor_p[k]+neighbor[k])*2.0f + diagonal[k])/(float(valence)+5.0f);
oQ[k] += *fp;
// XXXX manuelk rp indexing is clunky
*rp = (neighbor_p[k]-neighbor_m[k])/3.0f + (diagonal[k]-diagonal_m[k])/6.0f;
}
}
for (int k=0; k<length; ++k)
opos[vid*length+k] = oQ[k]/valence;
for (int i=0; i<valence; ++i) {
int im = (i+valence-1)%valence;
for (int k=0; k<length; ++k) {
float e = 0.5f*(f[i*length+k]+f[im*length+k]);
e0[vid*length+k] += csf(valence-3, 2*i) * e;
e1[vid*length+k] += csf(valence-3, 2*i+1) * e;
}
}
for (int k=0; k<length; ++k) {
e0[vid*length+k] *= ef[valence-3];
e1[vid*length+k] *= ef[valence-3];
}
}
// tess control
float *Ep=(float*)alloca(length*4*sizeof(float)),
*Em=(float*)alloca(length*4*sizeof(float)),
*Fp=(float*)alloca(length*4*sizeof(float)),
*Fm=(float*)alloca(length*4*sizeof(float));
for (int vid=0; vid<4; ++vid) {
int ip = (vid+1)%4;
int im = (vid+3)%4;
int n = valences[vid];
const unsigned int *quadOffsets = quadOffsetBuffer;
int start = quadOffsets[vid] & 0x00ff;
int prev = (quadOffsets[vid] & 0xff00) / 256;
for (int k=0, ofs=vid*length; k<length; ++k, ++ofs) {
Ep[ofs] = opos[ofs] + e0[ofs] * csf(n-3, 2*start) + e1[ofs]*csf(n-3, 2*start +1);
Em[ofs] = opos[ofs] + e0[ofs] * csf(n-3, 2*prev ) + e1[ofs]*csf(n-3, 2*prev + 1);
}
unsigned int np = valences[ip],
nm = valences[im];
unsigned int prev_p = quadOffsets[ip] & 0xff00 / 256;
float *Em_ip=(float*)alloca(length*sizeof(float)),
*Ep_im=(float*)alloca(length*sizeof(float));
unsigned int start_m = quadOffsets[im] & 0x00ff;
for (int k=0, ipofs=ip*length, imofs=im*length; k<length; ++k, ++ipofs, ++imofs) {
Em_ip[k] = opos[ipofs] + e0[ipofs]*csf(np-3, 2*prev_p) + e1[ipofs]*csf(np-3, 2*prev_p+1);
Ep_im[k] = opos[imofs] + e0[imofs]*csf(nm-3, 2*start_m) + e1[imofs]*csf(nm-3, 2*start_m+1);
}
float s1 = 3.0f - 2.0f*csf(n-3,2)-csf(np-3,2),
s2 = 2.0f*csf(n-3,2),
s3 = 3.0f -2.0f*cos(2.0f*float(M_PI)/float(n)) - cos(2.0f*float(M_PI)/float(nm));
rp = r + vid*maxValence*length;
for (int k=0, ofs=vid*length; k<length; ++k, ++ofs) {
Fp[ofs] = (csf(np-3,2)*opos[ofs] + s1*Ep[ofs] + s2*Em_ip[k] + rp[start*length+k])/3.0f;
Fm[ofs] = (csf(nm-3,2)*opos[ofs] + s3*Em[ofs] + s2*Ep_im[k] - rp[prev*length+k])/3.0f;
}
}
float * p[20];
for (int i=0, ofs=0; i<4; ++i, ofs+=length) {
p[i*5+0] = opos + ofs;
p[i*5+1] = Ep + ofs;
p[i*5+2] = Em + ofs;
p[i*5+3] = Fp + ofs;
p[i*5+4] = Fm + ofs;
}
float U = 1-u, V=1-v;
float d11 = u+v; if(u+v==0.0f) d11 = 1.0f;
float d12 = U+v; if(U+v==0.0f) d12 = 1.0f;
float d21 = u+V; if(u+V==0.0f) d21 = 1.0f;
float d22 = U+V; if(U+V==0.0f) d22 = 1.0f;
float *q=(float*)alloca(length*16*sizeof(float));
for (int k=0; k<length; ++k) {
q[ 5*length+k] = (u*p[ 3][k] + v*p[ 4][k])/d11;
q[ 6*length+k] = (U*p[ 9][k] + v*p[ 8][k])/d12;
q[ 9*length+k] = (u*p[19][k] + V*p[18][k])/d21;
q[10*length+k] = (U*p[13][k] + V*p[14][k])/d22;
}
memcpy(q+0*length, p[0], length*sizeof(float));
memcpy(q+1*length, p[1], length*sizeof(float));
memcpy(q+2*length, p[7], length*sizeof(float));
memcpy(q+3*length, p[5], length*sizeof(float));
memcpy(q+4*length, p[2], length*sizeof(float));
memcpy(q+7*length, p[6], length*sizeof(float));
memcpy(q+8*length, p[16], length*sizeof(float));
memcpy(q+11*length, p[12], length*sizeof(float));
memcpy(q+12*length, p[15], length*sizeof(float));
memcpy(q+13*length, p[17], length*sizeof(float));
memcpy(q+14*length, p[11], length*sizeof(float));
memcpy(q+15*length, p[10], length*sizeof(float));
float B[4], D[4],
*BU=(float*)alloca(inDesc.length*4*sizeof(float)),
*DU=(float*)alloca(inDesc.length*4*sizeof(float));
memset(BU, 0, inDesc.length*4*sizeof(float));
memset(DU, 0, inDesc.length*4*sizeof(float));
univar4x4(u, B, evalDeriv ? D : 0);
float const * inOffset = inQ + inDesc.offset;
for (int i=0; i<4; ++i) {
for (int j=0; j<4; ++j) {
float const * in = inOffset + vertexIndices[i+j*4]*inDesc.stride;
for (int k=0; k<inDesc.length; ++k) {
BU[i*inDesc.length+k] += in[k] * B[j];
if (evalDeriv)
DU[i*inDesc.length+k] += in[k] * D[j];
}
in += inDesc.stride;
}
}
univar4x4(v, B, evalDeriv ? D : 0);
float * Q = outQ + outDesc.offset;
float * dQU = outDQU + outDesc.offset;
float * dQV = outDQV + outDesc.offset;
// clear result
memset(Q, 0, outDesc.length*sizeof(float));
if (evalDeriv) {
memset(dQU, 0, outDesc.length*sizeof(float));
memset(dQV, 0, outDesc.length*sizeof(float));
}
for (int i=0; i<4; ++i) {
for (int k=0; k<inDesc.length; ++k) {
Q[k] += BU[i] * B[i];
if (evalDeriv) {
dQU[k] += DU[i] * B[i];
dQV[k] += BU[i] * D[i];
}
}
}
}
} // end namespace OPENSUBDIV_VERSION
} // end namespace OpenSubdiv

View File

@ -0,0 +1,96 @@
//
// Copyright (C) Pixar. All rights reserved.
//
// This license governs use of the accompanying software. If you
// use the software, you accept this license. If you do not accept
// the license, do not use the software.
//
// 1. Definitions
// The terms "reproduce," "reproduction," "derivative works," and
// "distribution" have the same meaning here as under U.S.
// copyright law. A "contribution" is the original software, or
// any additions or changes to the software.
// A "contributor" is any person or entity that distributes its
// contribution under this license.
// "Licensed patents" are a contributor's patent claims that read
// directly on its contribution.
//
// 2. Grant of Rights
// (A) Copyright Grant- Subject to the terms of this license,
// including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide,
// royalty-free copyright license to reproduce its contribution,
// prepare derivative works of its contribution, and distribute
// its contribution or any derivative works that you create.
// (B) Patent Grant- Subject to the terms of this license,
// including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide,
// royalty-free license under its licensed patents to make, have
// made, use, sell, offer for sale, import, and/or otherwise
// dispose of its contribution in the software or derivative works
// of the contribution in the software.
//
// 3. Conditions and Limitations
// (A) No Trademark License- This license does not grant you
// rights to use any contributor's name, logo, or trademarks.
// (B) If you bring a patent claim against any contributor over
// patents that you claim are infringed by the software, your
// patent license from such contributor to the software ends
// automatically.
// (C) If you distribute any portion of the software, you must
// retain all copyright, patent, trademark, and attribution
// notices that are present in the software.
// (D) If you distribute any portion of the software in source
// code form, you may do so only under this license by including a
// complete copy of this license with your distribution. If you
// distribute any portion of the software in compiled or object
// code form, you may only do so under a license that complies
// with this license.
// (E) The software is licensed "as-is." You bear the risk of
// using it. The contributors give no express warranties,
// guarantees or conditions. You may have additional consumer
// rights under your local laws which this license cannot change.
// To the extent permitted under your local laws, the contributors
// exclude the implied warranties of merchantability, fitness for
// a particular purpose and non-infringement.
//
#ifndef OSD_CPU_EVAL_LIMIT_KERNEL_H
#define OSD_CPU_EVAL_LIMIT_KERNEL_H
#include "../version.h"
#include "../osd/vertexDescriptor.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
void
evalBSpline(float u, float v,
unsigned int const * vertexIndices,
OsdVertexBufferDescriptor const & inDesc,
float const * inQ,
OsdVertexBufferDescriptor const & outDesc,
float * outQ,
float * outDQU,
float * outDQV );
void
evalGregory(float u, float v,
int const * vertexValenceBuffer,
unsigned int const * quadOffsetBuffer,
int maxValence,
unsigned int const * vertexIndices,
OsdVertexBufferDescriptor const & inDesc,
float const * inQ,
OsdVertexBufferDescriptor const & outDesc,
float * outQ,
float * outDQU,
float * outDQV );
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
} // end namespace OpenSubdiv
#endif /* OSD_CPU_EVAL_LIMIT_KERNEL_H */

View File

@ -0,0 +1,75 @@
//
// Copyright (C) Pixar. All rights reserved.
//
// This license governs use of the accompanying software. If you
// use the software, you accept this license. If you do not accept
// the license, do not use the software.
//
// 1. Definitions
// The terms "reproduce," "reproduction," "derivative works," and
// "distribution" have the same meaning here as under U.S.
// copyright law. A "contribution" is the original software, or
// any additions or changes to the software.
// A "contributor" is any person or entity that distributes its
// contribution under this license.
// "Licensed patents" are a contributor's patent claims that read
// directly on its contribution.
//
// 2. Grant of Rights
// (A) Copyright Grant- Subject to the terms of this license,
// including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide,
// royalty-free copyright license to reproduce its contribution,
// prepare derivative works of its contribution, and distribute
// its contribution or any derivative works that you create.
// (B) Patent Grant- Subject to the terms of this license,
// including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide,
// royalty-free license under its licensed patents to make, have
// made, use, sell, offer for sale, import, and/or otherwise
// dispose of its contribution in the software or derivative works
// of the contribution in the software.
//
// 3. Conditions and Limitations
// (A) No Trademark License- This license does not grant you
// rights to use any contributor's name, logo, or trademarks.
// (B) If you bring a patent claim against any contributor over
// patents that you claim are infringed by the software, your
// patent license from such contributor to the software ends
// automatically.
// (C) If you distribute any portion of the software, you must
// retain all copyright, patent, trademark, and attribution
// notices that are present in the software.
// (D) If you distribute any portion of the software in source
// code form, you may do so only under this license by including a
// complete copy of this license with your distribution. If you
// distribute any portion of the software in compiled or object
// code form, you may only do so under a license that complies
// with this license.
// (E) The software is licensed "as-is." You bear the risk of
// using it. The contributors give no express warranties,
// guarantees or conditions. You may have additional consumer
// rights under your local laws which this license cannot change.
// To the extent permitted under your local laws, the contributors
// exclude the implied warranties of merchantability, fitness for
// a particular purpose and non-infringement.
//
#include "../osd/evalLimitContext.h"
#include "../osd/vertexDescriptor.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
OsdEvalLimitContext::OsdEvalLimitContext(FarMesh<OsdVertex> const * farmesh) {
_adaptive = farmesh->SupportsFeatureAdaptive();
}
OsdEvalLimitContext::~OsdEvalLimitContext() {
}
} // end namespace OPENSUBDIV_VERSION
} // end namespace OpenSubdiv

View File

@ -0,0 +1,117 @@
//
// Copyright (C) Pixar. All rights reserved.
//
// This license governs use of the accompanying software. If you
// use the software, you accept this license. If you do not accept
// the license, do not use the software.
//
// 1. Definitions
// The terms "reproduce," "reproduction," "derivative works," and
// "distribution" have the same meaning here as under U.S.
// copyright law. A "contribution" is the original software, or
// any additions or changes to the software.
// A "contributor" is any person or entity that distributes its
// contribution under this license.
// "Licensed patents" are a contributor's patent claims that read
// directly on its contribution.
//
// 2. Grant of Rights
// (A) Copyright Grant- Subject to the terms of this license,
// including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide,
// royalty-free copyright license to reproduce its contribution,
// prepare derivative works of its contribution, and distribute
// its contribution or any derivative works that you create.
// (B) Patent Grant- Subject to the terms of this license,
// including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide,
// royalty-free license under its licensed patents to make, have
// made, use, sell, offer for sale, import, and/or otherwise
// dispose of its contribution in the software or derivative works
// of the contribution in the software.
//
// 3. Conditions and Limitations
// (A) No Trademark License- This license does not grant you
// rights to use any contributor's name, logo, or trademarks.
// (B) If you bring a patent claim against any contributor over
// patents that you claim are infringed by the software, your
// patent license from such contributor to the software ends
// automatically.
// (C) If you distribute any portion of the software, you must
// retain all copyright, patent, trademark, and attribution
// notices that are present in the software.
// (D) If you distribute any portion of the software in source
// code form, you may do so only under this license by including a
// complete copy of this license with your distribution. If you
// distribute any portion of the software in compiled or object
// code form, you may only do so under a license that complies
// with this license.
// (E) The software is licensed "as-is." You bear the risk of
// using it. The contributors give no express warranties,
// guarantees or conditions. You may have additional consumer
// rights under your local laws which this license cannot change.
// To the extent permitted under your local laws, the contributors
// exclude the implied warranties of merchantability, fitness for
// a particular purpose and non-infringement.
//
#ifndef OSD_EVAL_LIMIT_CONTEXT_H
#define OSD_EVAL_LIMIT_CONTEXT_H
#include "../version.h"
#include "../far/mesh.h"
#include "../osd/nonCopyable.h"
#include "../osd/patch.h"
#include "../osd/vertex.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
/// \brief Coordinates set on a limit surface
///
class OsdEvalCoords {
public:
OsdEvalCoords() { }
/// \brief Constructor
///
/// @param f Ptex face id
///
/// @param x parametric location on face
///
/// @param y parametric location on face
///
OsdEvalCoords(int f, float x, float y) : face(f), u(x), v(y) { }
unsigned int face; // Ptex face ID
float u,v; // local face (u,v)
};
/// \brief LimitEval Context
///
/// A stub class to derive LimitEval context classes.
///
class OsdEvalLimitContext : OsdNonCopyable<OsdEvalLimitContext> {
public:
/// \brief Destructor.
virtual ~OsdEvalLimitContext();
protected:
explicit OsdEvalLimitContext(FarMesh<OsdVertex> const * farmesh);
private:
bool _adaptive;
};
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
} // end namespace OpenSubdiv
#endif /* OSD_EVAL_LIMIT_CONTEXT_H */

View File

@ -77,11 +77,25 @@ enum OsdPatchType {
kTransitionCorner = 8,
};
/// \brief A bitfield-based descriptor for feature adaptive patches
struct OsdPatchDescriptor {
OsdPatchDescriptor() :
type(kNonPatch), pattern(0), rotation(0), subpatch(0),
maxValence(0), numElements(0) {}
/// \brief Constructor
///
/// @param type Patch type enum (see OsdPatchType)
///
/// @param pattern Transition pattern. One of 5 patterns (see : "Feature Adaptive
/// GPU Rendering of Catmull-Clark Subdivision Surfaces")
///
/// @param rotation Number of CCW parametric rotations of the patch.
///
/// @param maxValence The maximum vertex valence (set for the entire mesh)
///
/// @param numElements Stride of the data in the vertex buffer (used for drawing)
///
OsdPatchDescriptor(
OsdPatchType type,
unsigned char pattern,
@ -91,6 +105,7 @@ struct OsdPatchDescriptor {
type(type), pattern(pattern), rotation(rotation), subpatch(0),
maxValence(maxValence), numElements(numElements) {}
/// Returns the number of control vertices expected for a patch of this type
short GetPatchSize() const {
switch (type) {
case kNonPatch : return (loop ? 3:4);
@ -120,21 +135,31 @@ struct OsdPatchDescriptor {
unsigned char numElements:5; // 0-31
};
bool operator< (OsdPatchDescriptor const & a,
OsdPatchDescriptor const & b);
/// \brief A container to aggregate patches of the same type.
struct OsdPatchArray {
OsdPatchDescriptor desc;
int firstIndex; // index of first vertex in patch indices array
int numIndices; // number of vertex indices in indices array
int levelBase; // XXX ???
int gregoryVertexValenceBase;
int gregoryQuadOffsetBase;
};
typedef std::vector<OsdPatchArray> OsdPatchArrayVector;
/// Unique patch identifier
struct OsdPatchHandle {
unsigned int array, // OsdPatchArray containing the patch
vertexOffset, // Offset to the first CV of the patch
serialIndex; // Serialized Index of the patch
};
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;

View File

@ -167,11 +167,28 @@ struct OsdVertexDescriptor {
int numVaryingElements;
};
/// \brief Describes vertex elements in interleaved data buffers
struct OsdVertexBufferDescriptor {
/// Default Constructor
OsdVertexBufferDescriptor()
: offset(0), length(0), stride(0) { }
OsdVertexBufferDescriptor() : offset(0), length(0), stride(0) { }
/// Constructor
OsdVertexBufferDescriptor(int o, int l, int s) : offset(o), length(l), stride(s) { }
/// True if the descriptor values are internally consistent
bool IsValid() const {
return (offset<length) and (stride>=length);
}
/// True if the 'other' descriptor can be used as a destination for
/// data evaluations.
bool CanEval( OsdVertexBufferDescriptor const & other ) const {
return IsValid() and
other.IsValid() and
(length==other.length) and
(other.length <= (stride-offset));
}
int offset; // offset to desired element data
int length; // number or length of the data