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 ## 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 : 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) 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) add_subdirectory(osd_regression)
else() else()
set(MISSING "") set(MISSING "")

View File

@ -82,6 +82,8 @@
#include <osd/cpuComputeController.h> #include <osd/cpuComputeController.h>
#include <osd/cpuComputeContext.h> #include <osd/cpuComputeContext.h>
#include <osd/cpuGLVertexBuffer.h>
#ifdef OPENSUBDIV_HAS_CUDA #ifdef OPENSUBDIV_HAS_CUDA
#include <osd/cudaDispatcher.h> #include <osd/cudaDispatcher.h>
#endif #endif
@ -105,6 +107,21 @@
// //
#define PRECISION 1e-6 #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 // Vertex class implementation
struct xyzVV { struct xyzVV {
@ -224,9 +241,9 @@ bool VertexOnBoundary( xyzvertex const * v ) {
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template <typename VB>
int checkVertexBuffer( xyzmesh * hmesh, int checkVertexBuffer( xyzmesh * hmesh,
OpenSubdiv::OsdCpuVertexBuffer * vb, VB * vb,
std::vector<int> const & remap) { std::vector<int> const & remap) {
int count=0; int count=0;
float deltaAvg[3] = {0.0f, 0.0f, 0.0f}, 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; int result =0;
@ -328,20 +374,11 @@ int checkMesh( char const * msg, char const * shape, int levels, Scheme scheme=k
farmesh = meshFactory.Create(); farmesh = meshFactory.Create();
static OpenSubdiv::OsdCpuComputeController *controller =
new OpenSubdiv::OsdCpuComputeController();
OpenSubdiv::OsdCpuComputeContext *context = OpenSubdiv::OsdCpuComputeContext::Create(farmesh);
std::vector<int> remap = meshFactory.GetRemappingTable(); std::vector<int> remap = meshFactory.GetRemappingTable();
{
OpenSubdiv::OsdCpuVertexBuffer * vb = OpenSubdiv::OsdCpuVertexBuffer::Create(3, farmesh->GetNumVertices());
vb->UpdateData( & coarseverts[0], (int)coarseverts.size()/3 ); switch (backend) {
case kBackendCPU: result = checkMeshCPU(farmesh, coarseverts, refmesh, remap); break;
controller->Refine( context, vb ); case kBackendCPUGL: result = checkMeshCPUGL(farmesh, coarseverts, refmesh, remap); break;
checkVertexBuffer(refmesh, vb, remap);
} }
delete hmesh; 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 const char * backend = NULL;
if (not glfwInit()) {
printf("Failed to initialize GLFW\n"); if (i<(argc-1))
return 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(); int checkBackend(int backend, int levels) {
#endif
int levels=5, total=0; printf("*** checking backend : %s\n", BACKEND_NAMES[backend]);
int total = 0;
#define test_catmark_edgeonly #define test_catmark_edgeonly
#define test_catmark_edgecorner #define test_catmark_edgecorner
@ -410,166 +458,208 @@ int main(int argc, char ** argv) {
#define test_bilinear_cube #define test_bilinear_cube
printf("precision : %f\n",PRECISION);
#ifdef test_catmark_edgeonly #ifdef test_catmark_edgeonly
#include "../shapes/catmark_edgeonly.h" #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 #endif
#ifdef test_catmark_edgecorner #ifdef test_catmark_edgecorner
#include "../shapes/catmark_edgecorner.h" #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 #endif
#ifdef test_catmark_pyramid #ifdef test_catmark_pyramid
#include "../shapes/catmark_pyramid.h" #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 #endif
#ifdef test_catmark_pyramid_creases0 #ifdef test_catmark_pyramid_creases0
#include "../shapes/catmark_pyramid_creases0.h" #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 #endif
#ifdef test_catmark_pyramid_creases1 #ifdef test_catmark_pyramid_creases1
#include "../shapes/catmark_pyramid_creases1.h" #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 #endif
#ifdef test_catmark_cube #ifdef test_catmark_cube
#include "../shapes/catmark_cube.h" #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 #endif
#ifdef test_catmark_cube_creases0 #ifdef test_catmark_cube_creases0
#include "../shapes/catmark_cube_creases0.h" #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 #endif
#ifdef test_catmark_cube_creases1 #ifdef test_catmark_cube_creases1
#include "../shapes/catmark_cube_creases1.h" #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 #endif
#ifdef test_catmark_cube_corner0 #ifdef test_catmark_cube_corner0
#include "../shapes/catmark_cube_corner0.h" #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 #endif
#ifdef test_catmark_cube_corner1 #ifdef test_catmark_cube_corner1
#include "../shapes/catmark_cube_corner1.h" #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 #endif
#ifdef test_catmark_cube_corner2 #ifdef test_catmark_cube_corner2
#include "../shapes/catmark_cube_corner2.h" #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 #endif
#ifdef test_catmark_cube_corner3 #ifdef test_catmark_cube_corner3
#include "../shapes/catmark_cube_corner3.h" #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 #endif
#ifdef test_catmark_cube_corner4 #ifdef test_catmark_cube_corner4
#include "../shapes/catmark_cube_corner4.h" #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 #endif
#ifdef test_catmark_dart_edgecorner #ifdef test_catmark_dart_edgecorner
#include "../shapes/catmark_dart_edgecorner.h" #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 #endif
#ifdef test_catmark_dart_edgeonly #ifdef test_catmark_dart_edgeonly
#include "../shapes/catmark_dart_edgeonly.h" #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 #endif
#ifdef test_catmark_tent #ifdef test_catmark_tent
#include "../shapes/catmark_tent.h" #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 #endif
#ifdef test_catmark_tent_creases0 #ifdef test_catmark_tent_creases0
#include "../shapes/catmark_tent_creases0.h" #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 #endif
#ifdef test_catmark_tent_creases1 #ifdef test_catmark_tent_creases1
#include "../shapes/catmark_tent_creases1.h" #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 #endif
#ifdef test_catmark_square_hedit0 #ifdef test_catmark_square_hedit0
#include "../shapes/catmark_square_hedit0.h" #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 #endif
#ifdef test_catmark_square_hedit1 #ifdef test_catmark_square_hedit1
#include "../shapes/catmark_square_hedit1.h" #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 #endif
#ifdef test_catmark_square_hedit2 #ifdef test_catmark_square_hedit2
#include "../shapes/catmark_square_hedit2.h" #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 #endif
#ifdef test_catmark_square_hedit3 #ifdef test_catmark_square_hedit3
#include "../shapes/catmark_square_hedit3.h" #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 #endif
#ifdef test_loop_triangle_edgeonly #ifdef test_loop_triangle_edgeonly
#include "../shapes/loop_triangle_edgeonly.h" #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 #endif
#ifdef test_loop_triangle_edgecorner #ifdef test_loop_triangle_edgecorner
#include "../shapes/loop_triangle_edgecorner.h" #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 #endif
#ifdef test_loop_saddle_edgeonly #ifdef test_loop_saddle_edgeonly
#include "../shapes/loop_saddle_edgeonly.h" #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 #endif
#ifdef test_loop_saddle_edgecorner #ifdef test_loop_saddle_edgecorner
#include "../shapes/loop_saddle_edgecorner.h" #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 #endif
#ifdef test_loop_icosahedron #ifdef test_loop_icosahedron
#include "../shapes/loop_icosahedron.h" #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 #endif
#ifdef test_loop_cube #ifdef test_loop_cube
#include "../shapes/loop_cube.h" #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 #endif
#ifdef test_loop_cube_creases0 #ifdef test_loop_cube_creases0
#include "../shapes/loop_cube_creases0.h" #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 #endif
#ifdef test_loop_cube_creases1 #ifdef test_loop_cube_creases1
#include "../shapes/loop_cube_creases1.h" #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 #endif
#ifdef test_bilinear_cube #ifdef test_bilinear_cube
#include "../shapes/bilinear_cube.h" #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 #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(); glfwTerminate();
if (total==0) if (total==0)