Merge pull request #108 from aras-p/regression_tests

Improvements to osd_regression
This commit is contained in:
gelder 2013-02-03 11:04:41 -08:00
commit 687cedfb68
3 changed files with 171 additions and 71 deletions

View File

@ -194,6 +194,16 @@ export NDK_MODULE_PATH=[path to build-ndk/modules]
````
## Regression tests
OpenSubdiv builds a number of regression test executables for testing:
* hbr_regression: Regression testing matching HBR (low-level hierarchical boundary rep) to a pre-generated data set.
* far_regression: Matching FAR (feature-adaptive rep using tables) against HBR results.
* osd_regression: Matching full OSD subdivision against HBR results. Currently checks single threaded CPU kernel only.
## Wish List
There are many things we'd love to do to improve support for subdivs but don't have the resources to. In particular, we would welcome contributions for the following items :

View File

@ -59,7 +59,7 @@ add_subdirectory(hbr_regression)
add_subdirectory(far_regression)
if(OPENGL_FOUND AND GLEW_FOUND AND GLFW_FOUND)
if(OPENGL_FOUND AND (GLEW_FOUND OR APPLE) AND GLFW_FOUND)
add_subdirectory(osd_regression)
else()
set(MISSING "")

View File

@ -82,6 +82,8 @@
#include <osd/cpuComputeController.h>
#include <osd/cpuComputeContext.h>
#include <osd/cpuGLVertexBuffer.h>
#ifdef OPENSUBDIV_HAS_CUDA
#include <osd/cudaDispatcher.h>
#endif
@ -105,6 +107,21 @@
//
#define PRECISION 1e-6
//------------------------------------------------------------------------------
enum BackendType {
kBackendCPU = 0, // raw CPU
kBackendCPUGL = 1, // CPU with GL-backed buffer
//kBackendCL = 2, // OpenCL
kBackendCount
};
static const char* BACKEND_NAMES[kBackendCount] = {
"CPU",
"CPUGL",
//"CL",
};
static int g_Backend = 0;
//------------------------------------------------------------------------------
// Vertex class implementation
struct xyzVV {
@ -224,9 +241,9 @@ bool VertexOnBoundary( xyzvertex const * v ) {
}
//------------------------------------------------------------------------------
template <typename VB>
int checkVertexBuffer( xyzmesh * hmesh,
OpenSubdiv::OsdCpuVertexBuffer * vb,
VB * vb,
std::vector<int> const & remap) {
int count=0;
float deltaAvg[3] = {0.0f, 0.0f, 0.0f},
@ -308,7 +325,36 @@ static void refine( xyzmesh * mesh, int maxlevel ) {
}
//------------------------------------------------------------------------------
int checkMesh( char const * msg, char const * shape, int levels, Scheme scheme=kCatmark ) {
int checkMeshCPU (
OpenSubdiv::FarMesh<OpenSubdiv::OsdVertex>* farmesh,
const std::vector<float>& coarseverts,
xyzmesh * refmesh,
const std::vector<int>& remap)
{
static OpenSubdiv::OsdCpuComputeController *controller = new OpenSubdiv::OsdCpuComputeController();
OpenSubdiv::OsdCpuComputeContext *context = OpenSubdiv::OsdCpuComputeContext::Create(farmesh);
OpenSubdiv::OsdCpuVertexBuffer * vb = OpenSubdiv::OsdCpuVertexBuffer::Create(3, farmesh->GetNumVertices());
vb->UpdateData( & coarseverts[0], (int)coarseverts.size()/3 );
controller->Refine( context, vb );
return checkVertexBuffer(refmesh, vb, remap);
}
int checkMeshCPUGL (
OpenSubdiv::FarMesh<OpenSubdiv::OsdVertex>* farmesh,
const std::vector<float>& coarseverts,
xyzmesh * refmesh,
const std::vector<int>& remap)
{
static OpenSubdiv::OsdCpuComputeController *controller = new OpenSubdiv::OsdCpuComputeController();
OpenSubdiv::OsdCpuComputeContext *context = OpenSubdiv::OsdCpuComputeContext::Create(farmesh);
OpenSubdiv::OsdCpuGLVertexBuffer * vb = OpenSubdiv::OsdCpuGLVertexBuffer::Create(3, farmesh->GetNumVertices());
vb->UpdateData( & coarseverts[0], (int)coarseverts.size()/3 );
controller->Refine( context, vb );
return checkVertexBuffer(refmesh, vb, remap);
}
//------------------------------------------------------------------------------
int checkMesh( char const * msg, char const * shape, int levels, Scheme scheme, int backend ) {
int result =0;
@ -328,20 +374,11 @@ int checkMesh( char const * msg, char const * shape, int levels, Scheme scheme=k
farmesh = meshFactory.Create();
static OpenSubdiv::OsdCpuComputeController *controller =
new OpenSubdiv::OsdCpuComputeController();
OpenSubdiv::OsdCpuComputeContext *context = OpenSubdiv::OsdCpuComputeContext::Create(farmesh);
std::vector<int> remap = meshFactory.GetRemappingTable();
{
OpenSubdiv::OsdCpuVertexBuffer * vb = OpenSubdiv::OsdCpuVertexBuffer::Create(3, farmesh->GetNumVertices());
vb->UpdateData( & coarseverts[0], (int)coarseverts.size()/3 );
controller->Refine( context, vb );
checkVertexBuffer(refmesh, vb, remap);
switch (backend) {
case kBackendCPU: result = checkMeshCPU(farmesh, coarseverts, refmesh, remap); break;
case kBackendCPUGL: result = checkMeshCPUGL(farmesh, coarseverts, refmesh, remap); break;
}
delete hmesh;
@ -350,33 +387,44 @@ int checkMesh( char const * msg, char const * shape, int levels, Scheme scheme=k
}
//------------------------------------------------------------------------------
int main(int argc, char ** argv) {
static void parseArgs(int argc, char ** argv) {
for (int i=1; i<argc; ++i) {
if (not strcmp(argv[i],"-backend")) {
// Make sure we have an OpenGL context : create dummy GLFW window
if (not glfwInit()) {
printf("Failed to initialize GLFW\n");
return 1;
const char * backend = NULL;
if (i<(argc-1))
backend = argv[++i];
if (not strcmp(backend, "all")) {
g_Backend = -1;
} else {
bool found = false;
for (int i = 0; i < kBackendCount; ++i) {
if (not strcmp(backend, BACKEND_NAMES[i])) {
g_Backend = i;
found = true;
break;
}
static const char windowTitle[] = "OpenSubdiv glViewer";
int width=10, height=10;
#if GLFW_VERSION_MAJOR>=3
if (not (g_window=glfwCreateWindow(width, height, windowTitle, NULL, NULL))) {
#else
if (glfwOpenWindow(width, height, 8, 8, 8, 8, 24, 8,GLFW_WINDOW) == GL_FALSE) {
#endif
printf("Failed to open window.\n");
glfwTerminate();
return 1;
}
if (not found) {
printf("-backend : must be 'all' or one of: ");
for (int i = 0; i < kBackendCount; ++i) {
printf("%s ", BACKEND_NAMES[i]);
}
printf("\n");
exit(0);
}
}
}
}
}
#if not defined(__APPLE__)
glewInit();
#endif
//------------------------------------------------------------------------------
int checkBackend(int backend, int levels) {
int levels=5, total=0;
printf("*** checking backend : %s\n", BACKEND_NAMES[backend]);
int total = 0;
#define test_catmark_edgeonly
#define test_catmark_edgecorner
@ -410,166 +458,208 @@ int main(int argc, char ** argv) {
#define test_bilinear_cube
printf("precision : %f\n",PRECISION);
#ifdef test_catmark_edgeonly
#include "../shapes/catmark_edgeonly.h"
total += checkMesh( "test_catmark_edgeonly", catmark_edgeonly, levels, kCatmark );
total += checkMesh( "test_catmark_edgeonly", catmark_edgeonly, levels, kCatmark, backend );
#endif
#ifdef test_catmark_edgecorner
#include "../shapes/catmark_edgecorner.h"
total += checkMesh( "test_catmark_edgeonly", catmark_edgecorner, levels, kCatmark );
total += checkMesh( "test_catmark_edgeonly", catmark_edgecorner, levels, kCatmark, backend );
#endif
#ifdef test_catmark_pyramid
#include "../shapes/catmark_pyramid.h"
total += checkMesh( "test_catmark_pyramid", catmark_pyramid, levels, kCatmark );
total += checkMesh( "test_catmark_pyramid", catmark_pyramid, levels, kCatmark, backend );
#endif
#ifdef test_catmark_pyramid_creases0
#include "../shapes/catmark_pyramid_creases0.h"
total += checkMesh( "test_catmark_pyramid_creases0", catmark_pyramid_creases0, levels, kCatmark );
total += checkMesh( "test_catmark_pyramid_creases0", catmark_pyramid_creases0, levels, kCatmark, backend );
#endif
#ifdef test_catmark_pyramid_creases1
#include "../shapes/catmark_pyramid_creases1.h"
total += checkMesh( "test_catmark_pyramid_creases1", catmark_pyramid_creases1, levels, kCatmark );
total += checkMesh( "test_catmark_pyramid_creases1", catmark_pyramid_creases1, levels, kCatmark, backend );
#endif
#ifdef test_catmark_cube
#include "../shapes/catmark_cube.h"
total += checkMesh( "test_catmark_cube", catmark_cube, levels, kCatmark );
total += checkMesh( "test_catmark_cube", catmark_cube, levels, kCatmark, backend );
#endif
#ifdef test_catmark_cube_creases0
#include "../shapes/catmark_cube_creases0.h"
total += checkMesh( "test_catmark_cube_creases0", catmark_cube_creases0, levels, kCatmark );
total += checkMesh( "test_catmark_cube_creases0", catmark_cube_creases0, levels, kCatmark, backend );
#endif
#ifdef test_catmark_cube_creases1
#include "../shapes/catmark_cube_creases1.h"
total += checkMesh( "test_catmark_cube_creases1", catmark_cube_creases1, levels, kCatmark );
total += checkMesh( "test_catmark_cube_creases1", catmark_cube_creases1, levels, kCatmark, backend );
#endif
#ifdef test_catmark_cube_corner0
#include "../shapes/catmark_cube_corner0.h"
total += checkMesh( "test_catmark_cube_corner0", catmark_cube_corner0, levels, kCatmark );
total += checkMesh( "test_catmark_cube_corner0", catmark_cube_corner0, levels, kCatmark, backend );
#endif
#ifdef test_catmark_cube_corner1
#include "../shapes/catmark_cube_corner1.h"
total += checkMesh( "test_catmark_cube_corner1", catmark_cube_corner1, levels, kCatmark );
total += checkMesh( "test_catmark_cube_corner1", catmark_cube_corner1, levels, kCatmark, backend );
#endif
#ifdef test_catmark_cube_corner2
#include "../shapes/catmark_cube_corner2.h"
total += checkMesh( "test_catmark_cube_corner2", catmark_cube_corner2, levels, kCatmark );
total += checkMesh( "test_catmark_cube_corner2", catmark_cube_corner2, levels, kCatmark, backend );
#endif
#ifdef test_catmark_cube_corner3
#include "../shapes/catmark_cube_corner3.h"
total += checkMesh( "test_catmark_cube_corner3", catmark_cube_corner3, levels, kCatmark );
total += checkMesh( "test_catmark_cube_corner3", catmark_cube_corner3, levels, kCatmark, backend );
#endif
#ifdef test_catmark_cube_corner4
#include "../shapes/catmark_cube_corner4.h"
total += checkMesh( "test_catmark_cube_corner4", catmark_cube_corner4, levels, kCatmark );
total += checkMesh( "test_catmark_cube_corner4", catmark_cube_corner4, levels, kCatmark, backend );
#endif
#ifdef test_catmark_dart_edgecorner
#include "../shapes/catmark_dart_edgecorner.h"
total += checkMesh( "test_catmark_dart_edgecorner", catmark_dart_edgecorner, levels, kCatmark );
total += checkMesh( "test_catmark_dart_edgecorner", catmark_dart_edgecorner, levels, kCatmark, backend );
#endif
#ifdef test_catmark_dart_edgeonly
#include "../shapes/catmark_dart_edgeonly.h"
total += checkMesh( "test_catmark_dart_edgeonly", catmark_dart_edgeonly, levels, kCatmark );
total += checkMesh( "test_catmark_dart_edgeonly", catmark_dart_edgeonly, levels, kCatmark, backend );
#endif
#ifdef test_catmark_tent
#include "../shapes/catmark_tent.h"
total += checkMesh( "test_catmark_tent", catmark_tent, levels, kCatmark );
total += checkMesh( "test_catmark_tent", catmark_tent, levels, kCatmark, backend );
#endif
#ifdef test_catmark_tent_creases0
#include "../shapes/catmark_tent_creases0.h"
total += checkMesh( "test_catmark_tent_creases0", catmark_tent_creases0, levels );
total += checkMesh( "test_catmark_tent_creases0", catmark_tent_creases0, levels, kCatmark, backend );
#endif
#ifdef test_catmark_tent_creases1
#include "../shapes/catmark_tent_creases1.h"
total += checkMesh( "test_catmark_tent_creases1", catmark_tent_creases1, levels );
total += checkMesh( "test_catmark_tent_creases1", catmark_tent_creases1, levels, kCatmark, backend );
#endif
#ifdef test_catmark_square_hedit0
#include "../shapes/catmark_square_hedit0.h"
total += checkMesh( "test_catmark_square_hedit0", catmark_square_hedit0, levels );
total += checkMesh( "test_catmark_square_hedit0", catmark_square_hedit0, levels, kCatmark, backend );
#endif
#ifdef test_catmark_square_hedit1
#include "../shapes/catmark_square_hedit1.h"
total += checkMesh( "test_catmark_square_hedit1", catmark_square_hedit1, levels );
total += checkMesh( "test_catmark_square_hedit1", catmark_square_hedit1, levels, kCatmark, backend );
#endif
#ifdef test_catmark_square_hedit2
#include "../shapes/catmark_square_hedit2.h"
total += checkMesh( "test_catmark_square_hedit2", catmark_square_hedit2, levels );
total += checkMesh( "test_catmark_square_hedit2", catmark_square_hedit2, levels, kCatmark, backend );
#endif
#ifdef test_catmark_square_hedit3
#include "../shapes/catmark_square_hedit3.h"
total += checkMesh( "test_catmark_square_hedit3", catmark_square_hedit3, levels );
total += checkMesh( "test_catmark_square_hedit3", catmark_square_hedit3, levels, kCatmark, backend );
#endif
#ifdef test_loop_triangle_edgeonly
#include "../shapes/loop_triangle_edgeonly.h"
total += checkMesh( "test_loop_triangle_edgeonly", loop_triangle_edgeonly, levels, kLoop );
total += checkMesh( "test_loop_triangle_edgeonly", loop_triangle_edgeonly, levels, kLoop, backend );
#endif
#ifdef test_loop_triangle_edgecorner
#include "../shapes/loop_triangle_edgecorner.h"
total += checkMesh( "test_loop_triangle_edgecorner", loop_triangle_edgecorner, levels, kLoop );
total += checkMesh( "test_loop_triangle_edgecorner", loop_triangle_edgecorner, levels, kLoop, backend );
#endif
#ifdef test_loop_saddle_edgeonly
#include "../shapes/loop_saddle_edgeonly.h"
total += checkMesh( "test_loop_saddle_edgeonly", loop_saddle_edgeonly, levels, kLoop );
total += checkMesh( "test_loop_saddle_edgeonly", loop_saddle_edgeonly, levels, kLoop, backend );
#endif
#ifdef test_loop_saddle_edgecorner
#include "../shapes/loop_saddle_edgecorner.h"
total += checkMesh( "test_loop_saddle_edgecorner", loop_saddle_edgecorner, levels, kLoop );
total += checkMesh( "test_loop_saddle_edgecorner", loop_saddle_edgecorner, levels, kLoop, backend );
#endif
#ifdef test_loop_icosahedron
#include "../shapes/loop_icosahedron.h"
total += checkMesh( "test_loop_icosahedron", loop_icosahedron, levels, kLoop );
total += checkMesh( "test_loop_icosahedron", loop_icosahedron, levels, kLoop, backend );
#endif
#ifdef test_loop_cube
#include "../shapes/loop_cube.h"
total += checkMesh( "test_loop_cube", loop_cube, levels, kLoop );
total += checkMesh( "test_loop_cube", loop_cube, levels, kLoop, backend );
#endif
#ifdef test_loop_cube_creases0
#include "../shapes/loop_cube_creases0.h"
total += checkMesh( "test_loop_cube_creases0", loop_cube_creases0,levels, kLoop );
total += checkMesh( "test_loop_cube_creases0", loop_cube_creases0,levels, kLoop, backend );
#endif
#ifdef test_loop_cube_creases1
#include "../shapes/loop_cube_creases1.h"
total += checkMesh( "test_loop_cube_creases1", loop_cube_creases1, levels, kLoop );
total += checkMesh( "test_loop_cube_creases1", loop_cube_creases1, levels, kLoop, backend );
#endif
#ifdef test_bilinear_cube
#include "../shapes/bilinear_cube.h"
total += checkMesh( "test_bilinear_cube", bilinear_cube, levels, kBilinear );
total += checkMesh( "test_bilinear_cube", bilinear_cube, levels, kBilinear, backend );
#endif
return total;
}
//------------------------------------------------------------------------------
int main(int argc, char ** argv) {
parseArgs(argc, argv);
// Make sure we have an OpenGL context : create dummy GLFW window
if (not glfwInit()) {
printf("Failed to initialize GLFW\n");
return 1;
}
static const char windowTitle[] = "OpenSubdiv glViewer";
int width=10, height=10;
#if GLFW_VERSION_MAJOR>=3
if (not (g_window=glfwCreateWindow(width, height, windowTitle, NULL, NULL))) {
#else
if (glfwOpenWindow(width, height, 8, 8, 8, 8, 24, 8,GLFW_WINDOW) == GL_FALSE) {
#endif
printf("Failed to open window.\n");
glfwTerminate();
return 1;
}
#if not defined(__APPLE__)
glewInit();
#endif
printf("precision : %f\n",PRECISION);
int levels=5, total=0;
if (g_Backend == -1) {
for (int i = 0; i < kBackendCount; ++i)
total += checkBackend (i, levels);
} else {
total += checkBackend (g_Backend, levels);
}
glfwTerminate();
if (total==0)