// // 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 #include "hbr_utils.h" //------------------------------------------------------------------------------ namespace { template struct LevelMapT { std::vector faces; std::vector edges; std::vector verts; }; }; // Copies vertex data from hbrMesh into hbrVertexData reordered to match // the given refiner and subdivision level. This is used for later easy // comparison between the two. template void GetReorderedHbrVertexData( const OpenSubdiv::Far::TopologyRefiner &farRefiner, const OpenSubdiv::HbrMesh &hbrMesh, std::vector *hbrVertexData, std::vector *hbrVertexOnBoundaryData = NULL) { typedef OpenSubdiv::HbrVertex Hvertex; typedef OpenSubdiv::HbrFace Hface; typedef OpenSubdiv::HbrHalfedge Hhalfedge; struct Mapper { typedef LevelMapT LevelMap; std::vector maps; Mapper(const OpenSubdiv::Far::TopologyRefiner &refiner, const OpenSubdiv::HbrMesh &hmesh) { bool schemeIsLoop = (refiner.GetSchemeType() == OpenSubdiv::Sdc::SCHEME_LOOP); 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 Far // for the base level OpenSubdiv::Far::TopologyLevel const & refBaseLevel = refiner.GetLevel(0); int nfaces = refBaseLevel.GetNumFaces(), nedges = refBaseLevel.GetNumEdges(), nverts = refBaseLevel.GetNumVertices(); maps[0].faces.resize(nfaces, 0); maps[0].edges.resize(nedges, 0); maps[0].verts.resize(nverts, 0); for (int face=0; faceGetEdge(v1); if (! e) { e = v1->GetEdge(v0); } assert(e); maps[0].edges[edge] = e; } for (int vert = 0; vertGetChild(i); } // populate child face-verts -- when present (none for Loop subdivision) if (!schemeIsLoop) { Hvertex * v = f->Subdivide(); Index childVert = refPrevLevel.GetFaceChildVertex(face); assert(v->GetParentFace()); current.verts[childVert] = v; } } for (int edge=0; edge < refPrevLevel.GetNumEdges(); ++edge) { // populate child edge-verts Index childVert = refPrevLevel.GetEdgeChildVertex(edge); Hhalfedge * e = previous.edges[edge]; Hvertex * v = e->Subdivide(); assert(v->GetParentEdge()); current.verts[childVert] = v; } for (int vert = 0; vert < refPrevLevel.GetNumVertices(); ++vert) { // populate child vert-verts Index childVert = refPrevLevel.GetVertexChildVertex(vert); Hvertex * v = previous.verts[vert]->Subdivide(); current.verts[childVert] = v; assert(v->GetParentVertex()); } // populate child edges for (int edge=0; edge < refLevel.GetNumEdges(); ++edge) { ConstIndexArray farVerts = refLevel.GetEdgeVertices(edge); Hvertex const * v0 = current.verts[farVerts[0]], * v1 = current.verts[farVerts[1]]; assert(v0 && v1); Hhalfedge * e= v0->GetEdge(v1); if (! e) { e = v1->GetEdge(v0); } assert(e); current.edges[edge] = e; } ecount += refPrevLevel.GetNumEdges(); } } }; Mapper mapper(farRefiner, hbrMesh); int nverts = hbrMesh.GetNumVertices(); assert( nverts==farRefiner.GetNumVerticesTotal() ); hbrVertexData->resize(nverts); for (int level=0, ofs=0; level<(farRefiner.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 */