mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-11-15 08:20:08 +00:00
Merge pull request #399 from c64kernal/dev
osd_regression test ported over to new API and small bug fix in vtr
This commit is contained in:
commit
e8a7684d8d
@ -36,6 +36,7 @@
|
||||
#include "osd/opencl.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
static bool HAS_CL_VERSION_1_1 () {
|
||||
#ifdef OPENSUBDIV_HAS_OPENCL
|
||||
@ -58,6 +59,11 @@ static bool HAS_CL_VERSION_1_1 () {
|
||||
}
|
||||
static bool initCL(cl_context *clContext, cl_command_queue *clQueue)
|
||||
{
|
||||
if (!clGetPlatformIDs) {
|
||||
printf("Error clGetPlatformIDs call not bound.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
cl_int ciErrNum;
|
||||
|
||||
cl_platform_id cpPlatform = 0;
|
||||
|
@ -373,6 +373,11 @@ QuadRefinement::populateEdgeFaceRelation() {
|
||||
child._edgeFaceIndices.resize( childEdgeFaceIndexSizeEstimate);
|
||||
child._edgeFaceLocalIndices.resize(childEdgeFaceIndexSizeEstimate);
|
||||
|
||||
// Update _maxEdgeFaces from the parent level before calling the
|
||||
// populateEdgeFacesFromParent methods below, as these may further
|
||||
// update _maxEdgeFaces.
|
||||
child._maxEdgeFaces = parent._maxEdgeFaces;
|
||||
|
||||
populateEdgeFacesFromParentFaces();
|
||||
populateEdgeFacesFromParentEdges();
|
||||
|
||||
@ -382,8 +387,6 @@ QuadRefinement::populateEdgeFaceRelation() {
|
||||
child.getOffsetOfEdgeFaces(child.getNumEdges()-1);
|
||||
child._edgeFaceIndices.resize( childEdgeFaceIndexSizeEstimate);
|
||||
child._edgeFaceLocalIndices.resize(childEdgeFaceIndexSizeEstimate);
|
||||
|
||||
child._maxEdgeFaces = parent._maxEdgeFaces;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -366,6 +366,11 @@ TriRefinement::populateEdgeFaceRelation() {
|
||||
_child->_edgeFaceIndices.resize(childEdgeFaceIndexSizeEstimate);
|
||||
_child->_edgeFaceLocalIndices.resize(childEdgeFaceIndexSizeEstimate);
|
||||
|
||||
// Update _maxEdgeFaces from the parent level before calling the
|
||||
// populateEdgeFacesFromParent methods below, as these may further
|
||||
// update _maxEdgeFaces.
|
||||
_child->_maxEdgeFaces = _parent->_maxEdgeFaces;
|
||||
|
||||
populateEdgeFacesFromParentFaces();
|
||||
populateEdgeFacesFromParentEdges();
|
||||
|
||||
@ -375,8 +380,6 @@ TriRefinement::populateEdgeFaceRelation() {
|
||||
_child->getOffsetOfEdgeFaces(_child->getNumEdges()-1);
|
||||
_child->_edgeFaceIndices.resize(childEdgeFaceIndexSizeEstimate);
|
||||
_child->_edgeFaceLocalIndices.resize(childEdgeFaceIndexSizeEstimate);
|
||||
|
||||
_child->_maxEdgeFaces = _parent->_maxEdgeFaces;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -27,6 +27,7 @@ set(REGRESSION_COMMON_SOURCE_FILES
|
||||
)
|
||||
|
||||
set(REGRESSION_COMMON_HEADER_FILES
|
||||
cmp_utils.h
|
||||
hbr_utils.h
|
||||
shape_utils.h
|
||||
vtr_utils.h
|
||||
|
195
regression/common/cmp_utils.h
Normal file
195
regression/common/cmp_utils.h
Normal file
@ -0,0 +1,195 @@
|
||||
//
|
||||
// Copyright 2015 Pixar
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "Apache License")
|
||||
// with the following modification; you may not use this file except in
|
||||
// compliance with the Apache License and the following modification to it:
|
||||
// Section 6. Trademarks. is deleted and replaced with:
|
||||
//
|
||||
// 6. Trademarks. This License does not grant permission to use the trade
|
||||
// names, trademarks, service marks, or product names of the Licensor
|
||||
// and its affiliates, except as required to comply with Section 4(c) of
|
||||
// the License and to reproduce the content of the NOTICE file.
|
||||
//
|
||||
// You may obtain a copy of the Apache License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the Apache License with the above modification is
|
||||
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the Apache License for the specific
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
|
||||
#ifndef CMP_UTILS_H
|
||||
#define CMP_UTILS_H
|
||||
|
||||
#include <far/topologyRefinerFactory.h>
|
||||
|
||||
#include "../../regression/common/hbr_utils.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
// Copies vertex data from hmesh into hbrVertexData reordered to match
|
||||
// the given refiner and subdivision level. This is used for later easy
|
||||
// comparison between the two.
|
||||
template<class T>
|
||||
void
|
||||
GetReorderedHbrVertexData(
|
||||
const OpenSubdiv::Far::TopologyRefiner &refiner,
|
||||
const OpenSubdiv::HbrMesh<T> &hmesh,
|
||||
std::vector<T> *hbrVertexData,
|
||||
std::vector<bool> *hbrVertexOnBoundaryData = NULL)
|
||||
{
|
||||
typedef OpenSubdiv::HbrVertex<T> Hvertex;
|
||||
typedef OpenSubdiv::HbrFace<T> Hface;
|
||||
typedef OpenSubdiv::HbrHalfedge<T> Hhalfedge;
|
||||
|
||||
struct Mapper {
|
||||
|
||||
struct LevelMap {
|
||||
std::vector<Hface *> faces;
|
||||
std::vector<Hhalfedge *> edges;
|
||||
std::vector<Hvertex *> verts;
|
||||
};
|
||||
|
||||
std::vector<LevelMap> maps;
|
||||
|
||||
Mapper(const OpenSubdiv::Far::TopologyRefiner &refiner,
|
||||
const OpenSubdiv::HbrMesh<T> &hmesh) {
|
||||
|
||||
maps.resize(refiner.GetMaxLevel()+1);
|
||||
|
||||
typedef OpenSubdiv::Far::Index Index;
|
||||
typedef OpenSubdiv::Far::ConstIndexArray ConstIndexArray;
|
||||
|
||||
{ // Populate base level
|
||||
// note : topological ordering is identical between Hbr and Vtr
|
||||
// for the base level
|
||||
|
||||
int nfaces = refiner.GetNumFaces(0),
|
||||
nedges = refiner.GetNumEdges(0),
|
||||
nverts = refiner.GetNumVertices(0);
|
||||
|
||||
maps[0].faces.resize(nfaces, 0);
|
||||
maps[0].edges.resize(nedges, 0);
|
||||
maps[0].verts.resize(nverts, 0);
|
||||
|
||||
for (int face=0; face<nfaces; ++face) {
|
||||
maps[0].faces[face] = hmesh.GetFace(face);
|
||||
}
|
||||
|
||||
for (int edge = 0; edge <nedges; ++edge) {
|
||||
|
||||
ConstIndexArray vtrVerts = refiner.GetEdgeVertices(0, edge);
|
||||
|
||||
Hvertex const * v0 = hmesh.GetVertex(vtrVerts[0]),
|
||||
* v1 = hmesh.GetVertex(vtrVerts[1]);
|
||||
|
||||
Hhalfedge * e = v0->GetEdge(v1);
|
||||
if (not e) {
|
||||
e = v1->GetEdge(v0);
|
||||
}
|
||||
assert(e);
|
||||
|
||||
maps[0].edges[edge] = e;
|
||||
}
|
||||
|
||||
for (int vert = 0; vert<nverts; ++vert) {
|
||||
maps[0].verts[vert] = hmesh.GetVertex(vert);
|
||||
}
|
||||
}
|
||||
|
||||
// Populate refined levels
|
||||
for (int level=1, ecount=0; level<=refiner.GetMaxLevel(); ++level) {
|
||||
|
||||
LevelMap & previous = maps[level-1],
|
||||
& current = maps[level];
|
||||
|
||||
current.faces.resize(refiner.GetNumFaces(level), 0);
|
||||
current.edges.resize(refiner.GetNumEdges(level), 0);
|
||||
current.verts.resize(refiner.GetNumVertices(level), 0);
|
||||
|
||||
for (int face=0; face < refiner.GetNumFaces(level-1); ++face) {
|
||||
|
||||
// populate child faces
|
||||
Hface * f = previous.faces[face];
|
||||
|
||||
ConstIndexArray childFaces = refiner.GetFaceChildFaces(level-1, face);
|
||||
assert(childFaces.size()==f->GetNumVertices());
|
||||
|
||||
for (int i=0; i<childFaces.size(); ++i) {
|
||||
current.faces[childFaces[i]] = f->GetChild(i);
|
||||
}
|
||||
|
||||
// populate child face-verts
|
||||
Index childVert = refiner.GetFaceChildVertex(level-1, face);
|
||||
Hvertex * v = f->Subdivide();
|
||||
assert(v->GetParentFace());
|
||||
current.verts[childVert] = v;
|
||||
}
|
||||
|
||||
for (int edge=0; edge < refiner.GetNumEdges(level-1); ++edge) {
|
||||
// populate child edge-verts
|
||||
Index childVert = refiner.GetEdgeChildVertex(level-1,edge);
|
||||
Hhalfedge * e = previous.edges[edge];
|
||||
Hvertex * v = e->Subdivide();
|
||||
assert(v->GetParentEdge());
|
||||
current.verts[childVert] = v;
|
||||
}
|
||||
|
||||
for (int vert = 0; vert < refiner.GetNumVertices(level-1); ++vert) {
|
||||
// populate child vert-verts
|
||||
Index childVert = refiner.GetVertexChildVertex(level-1, vert);
|
||||
Hvertex * v = previous.verts[vert]->Subdivide();
|
||||
current.verts[childVert] = v;
|
||||
assert(v->GetParentVertex());
|
||||
}
|
||||
|
||||
// populate child edges
|
||||
for (int edge=0; edge < refiner.GetNumEdges(level); ++edge) {
|
||||
|
||||
ConstIndexArray vtrVerts = refiner.GetEdgeVertices(level, edge);
|
||||
|
||||
Hvertex const * v0 = current.verts[vtrVerts[0]],
|
||||
* v1 = current.verts[vtrVerts[1]];
|
||||
assert(v0 and v1);
|
||||
|
||||
Hhalfedge * e= v0->GetEdge(v1);
|
||||
if (not e) {
|
||||
e = v1->GetEdge(v0);
|
||||
}
|
||||
assert(e);
|
||||
current.edges[edge] = e;
|
||||
}
|
||||
ecount += refiner.GetNumEdges(level-1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Mapper mapper(refiner, hmesh);
|
||||
|
||||
int nverts = hmesh.GetNumVertices();
|
||||
assert( nverts==refiner.GetNumVerticesTotal() );
|
||||
|
||||
hbrVertexData->resize(nverts);
|
||||
|
||||
for (int level=0, ofs=0; level<(refiner.GetMaxLevel()+1); ++level) {
|
||||
|
||||
typename Mapper::LevelMap & map = mapper.maps[level];
|
||||
for (int i=0; i<(int)map.verts.size(); ++i) {
|
||||
Hvertex * v = map.verts[i];
|
||||
if (hbrVertexOnBoundaryData) {
|
||||
(*hbrVertexOnBoundaryData)[ofs] = hbrVertexOnBoundary(v);
|
||||
}
|
||||
(*hbrVertexData)[ofs++] = v->GetData();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#endif /* CMP_UTILS_H */
|
@ -625,4 +625,70 @@ simpleHbr(char const * Shapestr, Scheme scheme, std::vector<float> & verts, bool
|
||||
return mesh;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template <class T>
|
||||
OpenSubdiv::HbrMesh<T> *
|
||||
interpolateHbrVertexData(char const * Shapestr, Scheme scheme, int maxlevel) {
|
||||
|
||||
// Hbr interpolation
|
||||
OpenSubdiv::HbrMesh<T> *hmesh = simpleHbr<T>(Shapestr, scheme,
|
||||
/* verts vector */ 0, /* fvar */ false);
|
||||
assert(hmesh);
|
||||
|
||||
for (int level=0, firstface=0; level<maxlevel; ++level ) {
|
||||
int nfaces = hmesh->GetNumFaces();
|
||||
for (int i=firstface; i<nfaces; ++i) {
|
||||
|
||||
OpenSubdiv::HbrFace<T> * f = hmesh->GetFace(i);
|
||||
assert(f->GetDepth()==level);
|
||||
if (not f->IsHole()) {
|
||||
f->Refine();
|
||||
}
|
||||
}
|
||||
// Hbr allocates faces sequentially, skip faces that have already been
|
||||
// refined.
|
||||
firstface = nfaces;
|
||||
}
|
||||
|
||||
return hmesh;
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Returns true if a vertex or any of its parents is on a boundary
|
||||
template <class T>
|
||||
bool
|
||||
hbrVertexOnBoundary(const OpenSubdiv::HbrVertex<T> *v)
|
||||
{
|
||||
if (not v)
|
||||
return false;
|
||||
|
||||
if (v->OnBoundary())
|
||||
return true;
|
||||
|
||||
OpenSubdiv::HbrVertex<T> const * pv = v->GetParentVertex();
|
||||
if (pv)
|
||||
return hbrVertexOnBoundary(pv);
|
||||
else {
|
||||
OpenSubdiv::HbrHalfedge<T> const * pe = v->GetParentEdge();
|
||||
if (pe) {
|
||||
return hbrVertexOnBoundary(pe->GetOrgVertex()) or
|
||||
hbrVertexOnBoundary(pe->GetDestVertex());
|
||||
} else {
|
||||
OpenSubdiv::HbrFace<T> const * pf = v->GetParentFace(), * rootf = pf;
|
||||
while (pf) {
|
||||
pf = pf->GetParent();
|
||||
if (pf)
|
||||
rootf=pf;
|
||||
}
|
||||
if (rootf)
|
||||
for (int i=0; i<rootf->GetNumVertices(); ++i)
|
||||
if (rootf->GetVertex(i)->OnBoundary())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#endif /* HBR_UTILS_H */
|
||||
|
@ -124,9 +124,51 @@ GetSdcOptions(Shape const & shape) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
InterpolateFVarData(OpenSubdiv::Far::TopologyRefiner & refiner,
|
||||
Shape const & shape, std::vector<float> & fvarData);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
OpenSubdiv::Far::TopologyRefiner *
|
||||
InterpolateVtrVertexData(const char *shapeStr, Scheme scheme, int maxlevel,
|
||||
std::vector<T> &data) {
|
||||
|
||||
typedef OpenSubdiv::Far::TopologyRefiner FarTopologyRefiner;
|
||||
typedef OpenSubdiv::Far::TopologyRefinerFactory<Shape> FarTopologyRefinerFactory;
|
||||
|
||||
// Vtr interpolation
|
||||
Shape * shape = Shape::parseObj(shapeStr, scheme);
|
||||
|
||||
FarTopologyRefiner * refiner =
|
||||
FarTopologyRefinerFactory::Create(*shape,
|
||||
FarTopologyRefinerFactory::Options(
|
||||
GetSdcType(*shape), GetSdcOptions(*shape)));
|
||||
assert(refiner);
|
||||
|
||||
FarTopologyRefiner::UniformOptions options(maxlevel);
|
||||
options.fullTopologyInLastLevel=true;
|
||||
refiner->RefineUniform(options);
|
||||
|
||||
// populate coarse mesh positions
|
||||
data.resize(refiner->GetNumVerticesTotal());
|
||||
for (int i=0; i<refiner->GetNumVertices(0); i++) {
|
||||
data[i].SetPosition(shape->verts[i*3+0],
|
||||
shape->verts[i*3+1],
|
||||
shape->verts[i*3+2]);
|
||||
}
|
||||
|
||||
T * verts = &data[0];
|
||||
refiner->Interpolate(verts, verts+refiner->GetNumVertices(0));
|
||||
|
||||
delete shape;
|
||||
return refiner;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace OpenSubdiv {
|
||||
|
@ -46,8 +46,6 @@ GLFWwindow* g_window=0;
|
||||
#include <stdio.h>
|
||||
#include <cassert>
|
||||
|
||||
#include <far/meshFactory.h>
|
||||
|
||||
#include <osd/vertex.h>
|
||||
#include <osd/cpuVertexBuffer.h>
|
||||
#include <osd/cpuComputeController.h>
|
||||
@ -55,6 +53,8 @@ GLFWwindow* g_window=0;
|
||||
|
||||
#include <osd/cpuGLVertexBuffer.h>
|
||||
|
||||
#include <far/stencilTablesFactory.h>
|
||||
|
||||
#ifdef OPENSUBDIV_HAS_CUDA
|
||||
#endif
|
||||
|
||||
@ -67,7 +67,10 @@ GLFWwindow* g_window=0;
|
||||
#include "../../examples/common/clInit.h" // XXXX TODO move file out of examples
|
||||
#endif
|
||||
|
||||
|
||||
#include "../../regression/common/cmp_utils.h"
|
||||
#include "../../regression/common/hbr_utils.h"
|
||||
#include "../../regression/common/vtr_utils.h"
|
||||
|
||||
//
|
||||
// Regression testing matching Osd to Hbr
|
||||
@ -82,6 +85,8 @@ GLFWwindow* g_window=0;
|
||||
//
|
||||
#define PRECISION 1e-6
|
||||
|
||||
using namespace OpenSubdiv;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
enum BackendType {
|
||||
kBackendCPU = 0, // raw CPU
|
||||
@ -145,21 +150,6 @@ struct xyzVV {
|
||||
}
|
||||
}
|
||||
|
||||
void ApplyVertexEdit(OpenSubdiv::FarVertexEdit const & edit) {
|
||||
const float *src = edit.GetEdit();
|
||||
switch(edit.GetOperation()) {
|
||||
case OpenSubdiv::FarVertexEdit::Set:
|
||||
_pos[0] = src[0];
|
||||
_pos[1] = src[1];
|
||||
_pos[2] = src[2];
|
||||
break;
|
||||
case OpenSubdiv::FarVertexEdit::Add:
|
||||
_pos[0] += src[0];
|
||||
_pos[1] += src[1];
|
||||
_pos[2] += src[2];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ApplyMovingVertexEdit(const OpenSubdiv::HbrMovingVertexEdit<xyzVV> &) { }
|
||||
|
||||
@ -179,78 +169,60 @@ typedef OpenSubdiv::HbrHalfedge<xyzVV> xyzhalfedge;
|
||||
typedef OpenSubdiv::HbrFaceOperator<xyzVV> xyzFaceOperator;
|
||||
typedef OpenSubdiv::HbrVertexOperator<xyzVV> xyzVertexOperator;
|
||||
|
||||
typedef OpenSubdiv::HbrMesh<OpenSubdiv::OsdVertex> OsdHbrMesh;
|
||||
typedef OpenSubdiv::HbrVertex<OpenSubdiv::OsdVertex> OsdHbrVertex;
|
||||
typedef OpenSubdiv::HbrFace<OpenSubdiv::OsdVertex> OsdHbrFace;
|
||||
typedef OpenSubdiv::HbrHalfedge<OpenSubdiv::OsdVertex> OsdHbrHalfedge;
|
||||
typedef OpenSubdiv::Far::TopologyRefiner FarTopologyRefiner;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Returns true if a vertex or any of its parents is on a boundary
|
||||
bool
|
||||
VertexOnBoundary( xyzvertex const * v ) {
|
||||
|
||||
if (not v)
|
||||
return false;
|
||||
|
||||
if (v->OnBoundary())
|
||||
return true;
|
||||
|
||||
xyzvertex const * pv = v->GetParentVertex();
|
||||
if (pv)
|
||||
return VertexOnBoundary(pv);
|
||||
else {
|
||||
xyzhalfedge const * pe = v->GetParentEdge();
|
||||
if (pe) {
|
||||
return VertexOnBoundary(pe->GetOrgVertex()) or
|
||||
VertexOnBoundary(pe->GetDestVertex());
|
||||
} else {
|
||||
xyzface const * pf = v->GetParentFace(), * rootf = pf;
|
||||
while (pf) {
|
||||
pf = pf->GetParent();
|
||||
if (pf)
|
||||
rootf=pf;
|
||||
}
|
||||
if (rootf)
|
||||
for (int i=0; i<rootf->GetNumVertices(); ++i)
|
||||
if (rootf->GetVertex(i)->OnBoundary())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int
|
||||
checkVertexBuffer( xyzmesh * hmesh, const float * vbData, int numElements, std::vector<int> const & remap) {
|
||||
checkVertexBuffer(
|
||||
const FarTopologyRefiner &refiner, xyzmesh * hmesh,
|
||||
const float * vbData, int numElements) {
|
||||
|
||||
int count=0;
|
||||
float deltaAvg[3] = {0.0f, 0.0f, 0.0f},
|
||||
deltaCnt[3] = {0.0f, 0.0f, 0.0f};
|
||||
|
||||
int nverts = hmesh->GetNumVertices();
|
||||
std::vector<xyzVV> hbrVertexData;
|
||||
std::vector<bool> hbrVertexOnBoundaryData;
|
||||
|
||||
// Only care about vertex on boundary conditions if the interpolate boundary
|
||||
// is 'none'
|
||||
std::vector<bool> *hbrVertexOnBoundaryPtr =
|
||||
(hmesh->GetInterpolateBoundaryMethod() ==
|
||||
xyzmesh::k_InterpolateBoundaryNone)
|
||||
? &hbrVertexOnBoundaryData
|
||||
: NULL;
|
||||
|
||||
|
||||
GetReorderedHbrVertexData(refiner, *hmesh, &hbrVertexData,
|
||||
hbrVertexOnBoundaryPtr);
|
||||
|
||||
//int nverts = hmesh->GetNumVertices();
|
||||
int nverts = (int)hbrVertexData.size();
|
||||
|
||||
for (int i=0; i<nverts; ++i) {
|
||||
|
||||
xyzvertex * hv = hmesh->GetVertex(i);
|
||||
const float * ov = & vbData[ i * numElements ];
|
||||
|
||||
const float * ov = & vbData[ remap[ hv->GetID() ] * numElements ];
|
||||
|
||||
// boundary interpolation rules set to "none" produce "undefined" vertices on
|
||||
// boundary vertices : far does not match hbr for those, so skip comparison.
|
||||
if ( hmesh->GetInterpolateBoundaryMethod()==xyzmesh::k_InterpolateBoundaryNone and
|
||||
VertexOnBoundary(hv) )
|
||||
// boundary interpolation rules set to "none" produce "undefined"
|
||||
// vertices on boundary vertices : far does not match hbr for those,
|
||||
// so skip comparison.
|
||||
if (hbrVertexOnBoundaryPtr and (*hbrVertexOnBoundaryPtr)[i])
|
||||
continue;
|
||||
|
||||
const float *hbrPos = hbrVertexData[i].GetPos();
|
||||
|
||||
if ( hv->GetData().GetPos()[0] != ov[0] )
|
||||
|
||||
if ( hbrPos[0] != ov[0] )
|
||||
deltaCnt[0]++;
|
||||
if ( hv->GetData().GetPos()[1] != ov[1] )
|
||||
if ( hbrPos[1] != ov[1] )
|
||||
deltaCnt[1]++;
|
||||
if ( hv->GetData().GetPos()[2] != ov[2] )
|
||||
if ( hbrPos[2] != ov[2] )
|
||||
deltaCnt[2]++;
|
||||
|
||||
float delta[3] = { hv->GetData().GetPos()[0] - ov[0],
|
||||
hv->GetData().GetPos()[1] - ov[1],
|
||||
hv->GetData().GetPos()[2] - ov[2] };
|
||||
float delta[3] = { hbrPos[0] - ov[0],
|
||||
hbrPos[1] - ov[1],
|
||||
hbrPos[2] - ov[2] };
|
||||
|
||||
deltaAvg[0]+=delta[0];
|
||||
deltaAvg[1]+=delta[1];
|
||||
@ -259,9 +231,9 @@ checkVertexBuffer( xyzmesh * hmesh, const float * vbData, int numElements, std::
|
||||
float dist = sqrtf( delta[0]*delta[0]+delta[1]*delta[1]+delta[2]*delta[2]);
|
||||
if ( dist > PRECISION ) {
|
||||
printf("// HbrVertex<T> %d fails : dist=%.10f (%.10f %.10f %.10f)"
|
||||
" (%.10f %.10f %.10f)\n", i, dist, hv->GetData().GetPos()[0],
|
||||
hv->GetData().GetPos()[1],
|
||||
hv->GetData().GetPos()[2],
|
||||
" (%.10f %.10f %.10f)\n", i, dist, hbrPos[0],
|
||||
hbrPos[1],
|
||||
hbrPos[2],
|
||||
ov[0],
|
||||
ov[1],
|
||||
ov[2] );
|
||||
@ -289,77 +261,133 @@ checkVertexBuffer( xyzmesh * hmesh, const float * vbData, int numElements, std::
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
refine( xyzmesh * mesh, int maxlevel ) {
|
||||
static void
|
||||
buildStencilTables(
|
||||
const FarTopologyRefiner &refiner,
|
||||
Far::StencilTables const **vertexStencils,
|
||||
Far::StencilTables const **varyingStencils)
|
||||
{
|
||||
Far::StencilTablesFactory::Options soptions;
|
||||
soptions.generateOffsets = true;
|
||||
soptions.generateIntermediateLevels = true;
|
||||
|
||||
for (int l=0; l<maxlevel; ++l ) {
|
||||
int nfaces = mesh->GetNumFaces();
|
||||
for (int i=0; i<nfaces; ++i) {
|
||||
xyzface * f = mesh->GetFace(i);
|
||||
if (f->GetDepth()==l)
|
||||
f->Refine();
|
||||
}
|
||||
}
|
||||
*vertexStencils = Far::StencilTablesFactory::Create(refiner, soptions);
|
||||
|
||||
soptions.interpolationMode = Far::StencilTablesFactory::INTERPOLATE_VARYING;
|
||||
*varyingStencils = Far::StencilTablesFactory::Create(refiner, soptions);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static int
|
||||
checkMeshCPU( OpenSubdiv::FarMesh<OpenSubdiv::OsdVertex>* farmesh,
|
||||
const std::vector<float>& coarseverts,
|
||||
xyzmesh * refmesh,
|
||||
const std::vector<int>& remap) {
|
||||
checkMeshCPU( FarTopologyRefiner *refiner,
|
||||
const std::vector<xyzVV>& coarseverts,
|
||||
xyzmesh * refmesh) {
|
||||
|
||||
static OpenSubdiv::OsdCpuComputeController *controller = new OpenSubdiv::OsdCpuComputeController();
|
||||
static Osd::CpuComputeController *controller =
|
||||
new Osd::CpuComputeController();
|
||||
|
||||
|
||||
Far::StencilTables const *vertexStencils;
|
||||
Far::StencilTables const *varyingStencils;
|
||||
buildStencilTables(*refiner, &vertexStencils, &varyingStencils);
|
||||
Osd::CpuComputeContext *context = Osd::CpuComputeContext::Create(
|
||||
vertexStencils, varyingStencils);
|
||||
|
||||
|
||||
assert(coarseverts.size() == refiner->GetNumVerticesTotal());
|
||||
|
||||
OpenSubdiv::OsdCpuComputeContext *context = OpenSubdiv::OsdCpuComputeContext::Create(farmesh->GetSubdivisionTables(), farmesh->GetVertexEditTables());
|
||||
Osd::CpuVertexBuffer * vb =
|
||||
Osd::CpuVertexBuffer::Create(3, refiner->GetNumVerticesTotal());
|
||||
|
||||
OpenSubdiv::OsdCpuVertexBuffer * vb = OpenSubdiv::OsdCpuVertexBuffer::Create(3, farmesh->GetNumVertices());
|
||||
vb->UpdateData( coarseverts[0].GetPos(), 0, (int)coarseverts.size() );
|
||||
|
||||
vb->UpdateData( & coarseverts[0], 0, (int)coarseverts.size()/3 );
|
||||
Far::KernelBatchVector kernelBatches;
|
||||
kernelBatches.push_back(
|
||||
Far::StencilTablesFactory::Create(*vertexStencils));
|
||||
|
||||
controller->Refine( context, farmesh->GetKernelBatches(), vb );
|
||||
|
||||
return checkVertexBuffer(refmesh, vb->BindCpuBuffer(), vb->GetNumElements(), remap);
|
||||
controller->Compute( context, kernelBatches, vb );
|
||||
|
||||
int result = checkVertexBuffer(*refiner, refmesh, vb->BindCpuBuffer(),
|
||||
vb->GetNumElements());
|
||||
|
||||
delete context;
|
||||
delete vertexStencils;
|
||||
delete varyingStencils;
|
||||
delete vb;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static 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();
|
||||
checkMeshCPUGL(FarTopologyRefiner *refiner,
|
||||
const std::vector<xyzVV>& coarseverts,
|
||||
xyzmesh * refmesh) {
|
||||
|
||||
static Osd::CpuComputeController *controller =
|
||||
new Osd::CpuComputeController();
|
||||
|
||||
OpenSubdiv::OsdCpuComputeContext *context = OpenSubdiv::OsdCpuComputeContext::Create(farmesh->GetSubdivisionTables(), farmesh->GetVertexEditTables());
|
||||
Far::StencilTables const *vertexStencils;
|
||||
Far::StencilTables const *varyingStencils;
|
||||
buildStencilTables(*refiner, &vertexStencils, &varyingStencils);
|
||||
Osd::CpuComputeContext *context = Osd::CpuComputeContext::Create(
|
||||
vertexStencils, varyingStencils);
|
||||
|
||||
|
||||
OpenSubdiv::OsdCpuGLVertexBuffer * vb = OpenSubdiv::OsdCpuGLVertexBuffer::Create(3, farmesh->GetNumVertices());
|
||||
Osd::CpuGLVertexBuffer *vb = Osd::CpuGLVertexBuffer::Create(3,
|
||||
refiner->GetNumVerticesTotal());
|
||||
|
||||
vb->UpdateData( & coarseverts[0], 0, (int)coarseverts.size()/3 );
|
||||
vb->UpdateData( coarseverts[0].GetPos(), 0, (int)coarseverts.size() );
|
||||
|
||||
Far::KernelBatchVector kernelBatches;
|
||||
kernelBatches.push_back(
|
||||
Far::StencilTablesFactory::Create(*vertexStencils));
|
||||
|
||||
controller->Refine( context, farmesh->GetKernelBatches(), vb );
|
||||
controller->Compute( context, kernelBatches, vb );
|
||||
|
||||
return checkVertexBuffer(refmesh, vb->BindCpuBuffer(), vb->GetNumElements(), remap);
|
||||
int result = checkVertexBuffer(*refiner, refmesh,
|
||||
vb->BindCpuBuffer(), vb->GetNumElements());
|
||||
|
||||
delete context;
|
||||
delete vertexStencils;
|
||||
delete varyingStencils;
|
||||
delete vb;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static int
|
||||
checkMeshCL( OpenSubdiv::FarMesh<OpenSubdiv::OsdVertex>* farmesh,
|
||||
const std::vector<float>& coarseverts,
|
||||
xyzmesh * refmesh,
|
||||
const std::vector<int>& remap ) {
|
||||
|
||||
checkMeshCL( FarTopologyRefiner *refiner,
|
||||
const std::vector<xyzVV>& coarseverts,
|
||||
xyzmesh * refmesh) {
|
||||
|
||||
#ifdef OPENSUBDIV_HAS_OPENCL
|
||||
|
||||
static OpenSubdiv::OsdCLComputeController *controller = new OpenSubdiv::OsdCLComputeController(g_clContext, g_clQueue);
|
||||
static Osd::CLComputeController *controller =
|
||||
new Osd::CLComputeController(g_clContext, g_clQueue);
|
||||
|
||||
Far::StencilTables const *vertexStencils;
|
||||
Far::StencilTables const *varyingStencils;
|
||||
buildStencilTables(*refiner, &vertexStencils, &varyingStencils);
|
||||
Osd::CLComputeContext *context = Osd::CLComputeContext::Create(g_clContext,
|
||||
vertexStencils, varyingStencils);
|
||||
|
||||
Osd::CLGLVertexBuffer *vb =
|
||||
Osd::CLGLVertexBuffer::Create(3, refiner->GetNumVerticesTotal(),
|
||||
g_clContext);
|
||||
|
||||
OpenSubdiv::OsdCLComputeContext *context = OpenSubdiv::OsdCLComputeContext::Create(farmesh->GetSubdivisionTables(), farmesh->GetVertexEditTables(), g_clContext);
|
||||
vb->UpdateData( coarseverts[0].GetPos(), 0, (int)coarseverts.size(),
|
||||
g_clQueue );
|
||||
|
||||
Far::KernelBatchVector kernelBatches;
|
||||
kernelBatches.push_back(
|
||||
Far::StencilTablesFactory::Create(*vertexStencils));
|
||||
|
||||
OpenSubdiv::OsdCLGLVertexBuffer * vb = OpenSubdiv::OsdCLGLVertexBuffer::Create(3, farmesh->GetNumVertices(), g_clContext);
|
||||
|
||||
vb->UpdateData( & coarseverts[0], 0, (int)coarseverts.size()/3, g_clQueue );
|
||||
|
||||
controller->Refine( context, farmesh->GetKernelBatches(), vb );
|
||||
controller->Compute( context, kernelBatches, vb );
|
||||
|
||||
// read data back from CL buffer
|
||||
size_t dataSize = vb->GetNumVertices() * vb->GetNumElements();
|
||||
@ -367,9 +395,14 @@ checkMeshCL( OpenSubdiv::FarMesh<OpenSubdiv::OsdVertex>* farmesh,
|
||||
|
||||
clEnqueueReadBuffer (g_clQueue, vb->BindCLBuffer(g_clQueue), CL_TRUE, 0, dataSize * sizeof(float), data, 0, NULL, NULL);
|
||||
|
||||
int result = checkVertexBuffer(refmesh, data, vb->GetNumElements(), remap);
|
||||
int result = checkVertexBuffer(
|
||||
*refiner, refmesh, data, vb->GetNumElements());
|
||||
|
||||
delete[] data;
|
||||
delete context;
|
||||
delete vertexStencils;
|
||||
delete varyingStencils;
|
||||
delete vb;
|
||||
|
||||
return result;
|
||||
#else
|
||||
@ -385,28 +418,29 @@ checkMesh( char const * msg, std::string const & shape, int levels, Scheme schem
|
||||
|
||||
printf("- %s (scheme=%d)\n", msg, scheme);
|
||||
|
||||
xyzmesh * refmesh = simpleHbr<xyzVV>(shape.c_str(), scheme, 0);
|
||||
xyzmesh * refmesh =
|
||||
interpolateHbrVertexData<xyzVV>(shape.c_str(), scheme, levels);
|
||||
|
||||
refine( refmesh, levels );
|
||||
std::vector<xyzVV> vtrVertexData;
|
||||
|
||||
|
||||
std::vector<float> coarseverts;
|
||||
|
||||
OsdHbrMesh * hmesh = simpleHbr<OpenSubdiv::OsdVertex>(shape.c_str(), scheme, coarseverts);
|
||||
|
||||
OpenSubdiv::FarMeshFactory<OpenSubdiv::OsdVertex> meshFactory(hmesh, levels);
|
||||
|
||||
OpenSubdiv::FarMesh<OpenSubdiv::OsdVertex> * farmesh = meshFactory.Create();
|
||||
|
||||
std::vector<int> remap = meshFactory.GetRemappingTable();
|
||||
FarTopologyRefiner *refiner =
|
||||
InterpolateVtrVertexData(shape.c_str(), scheme, levels,
|
||||
vtrVertexData);
|
||||
|
||||
switch (backend) {
|
||||
case kBackendCPU : result = checkMeshCPU(farmesh, coarseverts, refmesh, remap); break;
|
||||
case kBackendCPUGL : result = checkMeshCPUGL(farmesh, coarseverts, refmesh, remap); break;
|
||||
case kBackendCL : result = checkMeshCL(farmesh, coarseverts, refmesh, remap); break;
|
||||
case kBackendCPU:
|
||||
result = checkMeshCPU(refiner, vtrVertexData, refmesh);
|
||||
break;
|
||||
case kBackendCPUGL:
|
||||
result = checkMeshCPUGL(refiner, vtrVertexData, refmesh);
|
||||
break;
|
||||
case kBackendCL:
|
||||
result = checkMeshCL(refiner, vtrVertexData, refmesh);
|
||||
break;
|
||||
}
|
||||
|
||||
delete hmesh;
|
||||
delete refmesh;
|
||||
delete refiner;
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -449,17 +483,21 @@ int checkBackend(int backend, int levels) {
|
||||
#define test_catmark_tent
|
||||
#define test_catmark_tent_creases0
|
||||
#define test_catmark_tent_creases1
|
||||
#define test_catmark_square_hedit0
|
||||
#define test_catmark_square_hedit1
|
||||
#define test_catmark_square_hedit2
|
||||
#define test_catmark_square_hedit3
|
||||
|
||||
#define test_loop_triangle_edgeonly
|
||||
#define test_loop_triangle_edgecorner
|
||||
#define test_loop_icosahedron
|
||||
#define test_loop_cube
|
||||
#define test_loop_cube_creases0
|
||||
#define test_loop_cube_creases1
|
||||
|
||||
// Hedits don't yet work.
|
||||
//#define test_catmark_square_hedit0
|
||||
//#define test_catmark_square_hedit1
|
||||
//#define test_catmark_square_hedit2
|
||||
//#define test_catmark_square_hedit3
|
||||
|
||||
// Loop doesn't yet work.
|
||||
//#define test_loop_triangle_edgeonly
|
||||
//#define test_loop_triangle_edgecorner
|
||||
//#define test_loop_icosahedron
|
||||
//#define test_loop_cube
|
||||
//#define test_loop_cube_creases0
|
||||
//#define test_loop_cube_creases1
|
||||
|
||||
#define test_bilinear_cube
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#include "../../regression/common/hbr_utils.h"
|
||||
#include "../../regression/common/vtr_utils.h"
|
||||
#include "../../regression/common/cmp_utils.h"
|
||||
|
||||
#include "init_shapes.h"
|
||||
|
||||
@ -112,68 +113,11 @@ private:
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
typedef OpenSubdiv::HbrMesh<xyzVV> Hmesh;
|
||||
typedef OpenSubdiv::HbrFace<xyzVV> Hface;
|
||||
typedef OpenSubdiv::HbrVertex<xyzVV> Hvertex;
|
||||
typedef OpenSubdiv::HbrHalfedge<xyzVV> Hhalfedge;
|
||||
|
||||
static Hmesh *
|
||||
interpolateHbrVertexData(ShapeDesc const & desc, int maxlevel) {
|
||||
|
||||
// Hbr interpolation
|
||||
Hmesh * hmesh = simpleHbr<xyzVV>(desc.data.c_str(), desc.scheme, /*verts vector*/ 0, /*fvar*/ false);
|
||||
assert(hmesh);
|
||||
|
||||
for (int level=0, firstface=0; level<maxlevel; ++level ) {
|
||||
int nfaces = hmesh->GetNumFaces();
|
||||
for (int i=firstface; i<nfaces; ++i) {
|
||||
|
||||
Hface * f = hmesh->GetFace(i);
|
||||
assert(f->GetDepth()==level);
|
||||
if (not f->IsHole()) {
|
||||
f->Refine();
|
||||
}
|
||||
}
|
||||
// Hbr allocates faces sequentially, skip faces that have already been refined.
|
||||
firstface = nfaces;
|
||||
}
|
||||
|
||||
return hmesh;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
typedef OpenSubdiv::Far::TopologyRefiner FarTopologyRefiner;
|
||||
typedef OpenSubdiv::Far::TopologyRefinerFactory<Shape> FarTopologyRefinerFactory;
|
||||
|
||||
static FarTopologyRefiner *
|
||||
interpolateVtrVertexData(ShapeDesc const & desc, int maxlevel, std::vector<xyzVV> & data) {
|
||||
|
||||
// Vtr interpolation
|
||||
Shape * shape = Shape::parseObj(desc.data.c_str(), desc.scheme);
|
||||
|
||||
FarTopologyRefiner * refiner =
|
||||
FarTopologyRefinerFactory::Create(*shape,
|
||||
FarTopologyRefinerFactory::Options(GetSdcType(*shape), GetSdcOptions(*shape)));
|
||||
assert(refiner);
|
||||
|
||||
FarTopologyRefiner::UniformOptions options(maxlevel);
|
||||
options.fullTopologyInLastLevel=true;
|
||||
refiner->RefineUniform(options);
|
||||
|
||||
// populate coarse mesh positions
|
||||
data.resize(refiner->GetNumVerticesTotal());
|
||||
for (int i=0; i<refiner->GetNumVertices(0); i++) {
|
||||
data[i].SetPosition(shape->verts[i*3+0],
|
||||
shape->verts[i*3+1],
|
||||
shape->verts[i*3+2]);
|
||||
}
|
||||
|
||||
xyzVV * verts = &data[0];
|
||||
refiner->Interpolate(verts, verts+refiner->GetNumVertices(0));
|
||||
|
||||
delete shape;
|
||||
return refiner;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#ifdef foo
|
||||
static void
|
||||
@ -191,129 +135,6 @@ printVertexData(std::vector<xyzVV> const & hbrBuffer, std::vector<xyzVV> const &
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//------------------------------------------------------------------------------
|
||||
struct Mapper {
|
||||
|
||||
struct LevelMap {
|
||||
std::vector<Hface *> faces;
|
||||
std::vector<Hhalfedge *> edges;
|
||||
std::vector<Hvertex *> verts;
|
||||
};
|
||||
|
||||
std::vector<LevelMap> maps;
|
||||
|
||||
Mapper(FarTopologyRefiner * refiner, Hmesh * hmesh) {
|
||||
|
||||
assert(refiner and hmesh);
|
||||
|
||||
maps.resize(refiner->GetMaxLevel()+1);
|
||||
|
||||
typedef OpenSubdiv::Far::Index Index;
|
||||
typedef OpenSubdiv::Far::ConstIndexArray ConstIndexArray;
|
||||
|
||||
{ // Populate base level
|
||||
// note : topological ordering is identical between Hbr and Vtr for the
|
||||
// base level
|
||||
|
||||
int nfaces = refiner->GetNumFaces(0),
|
||||
nedges = refiner->GetNumEdges(0),
|
||||
nverts = refiner->GetNumVertices(0);
|
||||
|
||||
maps[0].faces.resize(nfaces, 0);
|
||||
maps[0].edges.resize(nedges, 0);
|
||||
maps[0].verts.resize(nverts, 0);
|
||||
|
||||
for (int face=0; face<nfaces; ++face) {
|
||||
maps[0].faces[face] = hmesh->GetFace(face);
|
||||
}
|
||||
|
||||
for (int edge = 0; edge <nedges; ++edge) {
|
||||
|
||||
ConstIndexArray vtrVerts = refiner->GetEdgeVertices(0, edge);
|
||||
|
||||
Hvertex const * v0 = hmesh->GetVertex(vtrVerts[0]),
|
||||
* v1 = hmesh->GetVertex(vtrVerts[1]);
|
||||
|
||||
Hhalfedge * e = v0->GetEdge(v1);
|
||||
if (not e) {
|
||||
e = v1->GetEdge(v0);
|
||||
}
|
||||
assert(e);
|
||||
|
||||
maps[0].edges[edge] = e;
|
||||
}
|
||||
|
||||
for (int vert = 0; vert<nverts; ++vert) {
|
||||
maps[0].verts[vert] = hmesh->GetVertex(vert);
|
||||
}
|
||||
}
|
||||
|
||||
// Populate refined levels
|
||||
for (int level=1, ecount=0; level<=refiner->GetMaxLevel(); ++level) {
|
||||
|
||||
LevelMap & previous = maps[level-1],
|
||||
& current = maps[level];
|
||||
|
||||
current.faces.resize(refiner->GetNumFaces(level), 0);
|
||||
current.edges.resize(refiner->GetNumEdges(level), 0);
|
||||
current.verts.resize(refiner->GetNumVertices(level), 0);
|
||||
|
||||
for (int face=0; face < refiner->GetNumFaces(level-1); ++face) {
|
||||
|
||||
// populate child faces
|
||||
Hface * f = previous.faces[face];
|
||||
|
||||
ConstIndexArray childFaces = refiner->GetFaceChildFaces(level-1, face);
|
||||
assert(childFaces.size()==f->GetNumVertices());
|
||||
|
||||
for (int i=0; i<childFaces.size(); ++i) {
|
||||
current.faces[childFaces[i]] = f->GetChild(i);
|
||||
}
|
||||
|
||||
// populate child face-verts
|
||||
Index childVert = refiner->GetFaceChildVertex(level-1, face);
|
||||
Hvertex * v = f->Subdivide();
|
||||
assert(v->GetParentFace());
|
||||
current.verts[childVert] = v;
|
||||
}
|
||||
|
||||
for (int edge=0; edge < refiner->GetNumEdges(level-1); ++edge) {
|
||||
// populate child edge-verts
|
||||
Index childVert = refiner->GetEdgeChildVertex(level-1,edge);
|
||||
Hhalfedge * e = previous.edges[edge];
|
||||
Hvertex * v = e->Subdivide();
|
||||
assert(v->GetParentEdge());
|
||||
current.verts[childVert] = v;
|
||||
}
|
||||
|
||||
for (int vert = 0; vert < refiner->GetNumVertices(level-1); ++vert) {
|
||||
// populate child vert-verts
|
||||
Index childVert = refiner->GetVertexChildVertex(level-1, vert);
|
||||
Hvertex * v = previous.verts[vert]->Subdivide();
|
||||
current.verts[childVert] = v;
|
||||
assert(v->GetParentVertex());
|
||||
}
|
||||
|
||||
// populate child edges
|
||||
for (int edge=0; edge < refiner->GetNumEdges(level); ++edge) {
|
||||
|
||||
ConstIndexArray vtrVerts = refiner->GetEdgeVertices(level, edge);
|
||||
|
||||
Hvertex const * v0 = current.verts[vtrVerts[0]],
|
||||
* v1 = current.verts[vtrVerts[1]];
|
||||
assert(v0 and v1);
|
||||
|
||||
Hhalfedge * e= v0->GetEdge(v1);
|
||||
if (not e) {
|
||||
e = v1->GetEdge(v0);
|
||||
}
|
||||
assert(e);
|
||||
current.edges[edge] = e;
|
||||
}
|
||||
ecount += refiner->GetNumEdges(level-1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static int
|
||||
@ -329,32 +150,15 @@ checkMesh(ShapeDesc const & desc, int maxlevel) {
|
||||
std::vector<xyzVV> hbrVertexData,
|
||||
vtrVertexData;
|
||||
|
||||
Hmesh * hmesh =
|
||||
interpolateHbrVertexData(desc, maxlevel);
|
||||
Hmesh * hmesh = interpolateHbrVertexData<xyzVV>(
|
||||
desc.data.c_str(), desc.scheme, maxlevel);
|
||||
|
||||
FarTopologyRefiner * refiner =
|
||||
interpolateVtrVertexData(desc, maxlevel, vtrVertexData);
|
||||
InterpolateVtrVertexData<xyzVV>(
|
||||
desc.data.c_str(), desc.scheme, maxlevel, vtrVertexData);
|
||||
|
||||
{ // copy Hbr vertex data into a re-ordered buffer (for easier comparison)
|
||||
|
||||
Mapper mapper(refiner, hmesh);
|
||||
|
||||
int nverts = hmesh->GetNumVertices();
|
||||
assert( nverts==refiner->GetNumVerticesTotal() );
|
||||
|
||||
hbrVertexData.resize(nverts);
|
||||
|
||||
for (int level=0, ofs=0; level<(maxlevel+1); ++level) {
|
||||
|
||||
Mapper::LevelMap & map = mapper.maps[level];
|
||||
for (int i=0; i<(int)map.verts.size(); ++i) {
|
||||
Hvertex * v = map.verts[i];
|
||||
hbrVertexData[ofs++] = v->GetData();
|
||||
}
|
||||
}
|
||||
|
||||
//printVertexData(hbrVertexData, vtrVertexData);
|
||||
}
|
||||
// copy Hbr vertex data into a re-ordered buffer (for easier comparison)
|
||||
GetReorderedHbrVertexData(*refiner, *hmesh, &hbrVertexData);
|
||||
|
||||
int nverts = (int)vtrVertexData.size();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user