diff --git a/examples/glViewer/viewer.cpp b/examples/glViewer/viewer.cpp index bff20182..a66785ea 100755 --- a/examples/glViewer/viewer.cpp +++ b/examples/glViewer/viewer.cpp @@ -403,6 +403,9 @@ initializeShapes( ) { #include g_defaultShapes.push_back(SimpleShape(catmark_hole_test1, "catmark_hole_test1", kCatmark)); +#include + g_defaultShapes.push_back(SimpleShape(catmark_hole_test2, "catmark_hole_test2", kCatmark)); + #include g_defaultShapes.push_back(SimpleShape(catmark_pyramid_creases0, "catmark_pyramid_creases0", kCatmark)); diff --git a/opensubdiv/far/meshFactory.h b/opensubdiv/far/meshFactory.h index 9a57cd2d..bb0167b5 100644 --- a/opensubdiv/far/meshFactory.h +++ b/opensubdiv/far/meshFactory.h @@ -241,7 +241,7 @@ FarMeshFactory::refine( HbrMesh * mesh, int maxlevel ) { HbrHalfedge * e = f->GetFirstEdge(); for (int i=0; iGetNumVertices(); ++i) { assert(e); - if ((not e->IsBoundary()) and (not e->GetOpposite()->GetFace()->IsHole())) { + if (e->GetRightFace() and (not e->GetRightFace()->IsHole())) { // RefineFaceAtVertex only creates a single child face // centered on the passed vertex @@ -340,29 +340,35 @@ template void FarMeshFactory::refineVertexNeighbors(HbrVertex * v) { assert(v); - + HbrHalfedge * start = v->GetIncidentEdge(), * next=start; do { - if (next->GetRightFace()) - next->GetRightFace()->_adaptiveFlags.isTagged=true; - if (next->GetLeftFace()) - next->GetLeftFace()->_adaptiveFlags.isTagged=true; + HbrFace * lft = next->GetLeftFace(), + * rgt = next->GetRightFace(); - HbrHalfedge * istart = next, - * inext = istart; - do { - inext->GetOrgVertex()->Refine(); - inext = inext->GetNext(); - } while (istart != inext); + if (not ((lft and lft->IsHole()) and + (rgt and rgt->IsHole()) ) ) { + + if (rgt) + rgt->_adaptiveFlags.isTagged=true; + if (lft) + lft->_adaptiveFlags.isTagged=true; + + HbrHalfedge * istart = next, + * inext = istart; + do { + if (not inext->IsInsideHole() ) + inext->GetOrgVertex()->Refine(); + inext = inext->GetNext(); + } while (istart != inext); + } next = v->GetNextEdge( next ); } while (next and next!=start); } -// XXXX manuelk : std::sets are slow. -// with the "isTagged" flag on verts we can prob. ditch verts / nextverts !!! template struct VertCompare { bool operator()(HbrVertex const * v1, HbrVertex const * v2 ) const { //return v1->GetID() < v2->GetID(); @@ -399,6 +405,10 @@ FarMeshFactory::refineAdaptive( HbrMesh * mesh, int maxIsolate ) { for (int i=0; i * f = mesh->GetFace(i); + + if (f->IsHole()) + continue; + for (int j=0; jGetNumVertices(); ++j) { HbrHalfedge * e = f->GetEdge(j); @@ -429,39 +439,44 @@ FarMeshFactory::refineAdaptive( HbrMesh * mesh, int maxIsolate ) { verts = nextverts; nextverts.clear(); - + // Refine vertices for (typename VertSet::iterator i=verts.begin(); i!=verts.end(); ++i) { HbrVertex * v = *i; assert(v); - + if (level>0) v->_adaptiveFlags.isTagged=true; else v->_adaptiveFlags.wasTagged=true; - + refineVertexNeighbors(v); - + // Tag non-BSpline vertices for refinement if (not vertexIsBSpline(v, true)) nextverts.insert(v->Subdivide()); - + // Refine edges with creases or edits int valence = v->GetValence(); _maxValence = std::max(_maxValence, valence); HbrHalfedge * e = v->GetIncidentEdge(); for (int j=0; jIsSharp(false) and (not e->IsBoundary())) { - nextverts.insert( e->Subdivide() ); - nextverts.insert( e->GetOrgVertex()->Subdivide() ); - nextverts.insert( e->GetDestVertex()->Subdivide() ); + + // Skip edges that have already been processed (HasChild()) + if ((not e->HasChild()) and e->IsSharp(false) and (not e->IsBoundary())) { + + if (not e->IsInsideHole()) { + nextverts.insert( e->Subdivide() ); + nextverts.insert( e->GetOrgVertex()->Subdivide() ); + nextverts.insert( e->GetDestVertex()->Subdivide() ); + } } HbrHalfedge * next = v->GetNextEdge(e); e = next ? next : e->GetPrev(); } - + // Flag verts with hierarchical edits for neighbor refinement at the next level HbrVertex * childvert = v->Subdivide(); HbrHalfedge * childedge = childvert->GetIncidentEdge(); diff --git a/opensubdiv/far/patchTablesFactory.h b/opensubdiv/far/patchTablesFactory.h index b7555ccd..3401c8ac 100644 --- a/opensubdiv/far/patchTablesFactory.h +++ b/opensubdiv/far/patchTablesFactory.h @@ -212,7 +212,7 @@ FarPatchTablesFactory::FarPatchTablesFactory( HbrMesh const * mesh, int nf HbrFace * f = mesh->GetFace(i); - if (f->_adaptiveFlags.isTagged) { + if (f->_adaptiveFlags.isTagged and (not f->IsHole())) { HbrVertex * v = f->Subdivide(); assert(v); v->_adaptiveFlags.wasTagged=true; @@ -241,23 +241,31 @@ FarPatchTablesFactory::FarPatchTablesFactory( HbrMesh const * mesh, int nf if (not (left and right)) continue; - if (left->_adaptiveFlags.isTagged ^ right->_adaptiveFlags.isTagged) { + // a tagged edge w/ no children is inside a hole + if (e->HasChild() and (left->_adaptiveFlags.isTagged ^ right->_adaptiveFlags.isTagged)) { + e->_adaptiveFlags.isTransition = true; HbrVertex * child = e->Subdivide(); - assert( child ); + assert(child); // These edges will require extra rows of CVs to maintain water-tightness - HbrHalfedge * org = child->GetEdge(e->GetOrgVertex()->Subdivide()), - * dst = child->GetEdge(e->GetDestVertex()->Subdivide()); - assert( org and dst ); + // Note : vertices inside holes have no children + if (e->GetOrgVertex()->HasChild()) { + HbrHalfedge * org = child->GetEdge(e->GetOrgVertex()->Subdivide()); + if (org) + org->_adaptiveFlags.isWatertightCritical=true; + } - org->_adaptiveFlags.isWatertightCritical=true; - dst->_adaptiveFlags.isWatertightCritical=true; + if (e->GetDestVertex()->HasChild()) { + HbrHalfedge * dst = child->GetEdge(e->GetDestVertex()->Subdivide()); + if (dst) + dst->_adaptiveFlags.isWatertightCritical=true; + } } } } - + // Second pass : count boundaries / identify transition constellation for (int i=0; i * left = GetLeftFace(); + if (left and (not left->IsHole())) + return false; + + HbrFace * right = GetRightFace(); + if (right and (not right->IsHole())) + return false; + + return true; + } + bool IsTransition() const { return _adaptiveFlags.isTransition; } bool IsTriangleHead() const { return _adaptiveFlags.isTriangleHead; } diff --git a/opensubdiv/hbr/vertex.h b/opensubdiv/hbr/vertex.h index f953d311..55ea0d23 100644 --- a/opensubdiv/hbr/vertex.h +++ b/opensubdiv/hbr/vertex.h @@ -275,6 +275,9 @@ public: validmask = 0; } + // True if the edge has a subdivided child vertex + bool HasChild() const { return vchild!=-1; } + // Remove the reference to subdivided vertex void RemoveChild() { vchild = -1; } diff --git a/regression/shapes/catmark_hole_test2.h b/regression/shapes/catmark_hole_test2.h new file mode 100644 index 00000000..bc6ca5b8 --- /dev/null +++ b/regression/shapes/catmark_hole_test2.h @@ -0,0 +1,161 @@ +// +// 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. +// +static char const * catmark_hole_test2 = +"# This file uses centimeters as units for non-parametric coordinates.\n" +"\n" +"v -0.250000 -0.000000 0.250000\n" +"v -0.125000 -0.000000 0.250000\n" +"v 0.000000 -0.000000 0.250000\n" +"v 0.125000 -0.000000 0.250000\n" +"v 0.250000 -0.000000 0.250000\n" +"v -0.250000 -0.000000 0.125000\n" +"v -0.125000 0.125000 0.125000\n" +"v 0.000000 0.125000 0.125000\n" +"v 0.125000 -0.000000 0.125000\n" +"v 0.250000 -0.000000 0.125000\n" +"v -0.250000 0.000000 0.000000\n" +"v -0.125000 0.000000 0.000000\n" +"v 0.000000 0.000000 0.000000\n" +"v 0.125000 0.000000 0.000000\n" +"v 0.250000 0.000000 0.000000\n" +"v -0.250000 0.000000 -0.125000\n" +"v -0.125000 0.000000 -0.125000\n" +"v 0.000000 0.000000 -0.125000\n" +"v 0.125000 0.000000 -0.125000\n" +"v 0.250000 0.000000 -0.125000\n" +"v -0.250000 0.000000 -0.250000\n" +"v -0.125000 0.000000 -0.250000\n" +"v 0.000000 0.000000 -0.250000\n" +"v 0.125000 0.000000 -0.250000\n" +"v 0.250000 0.000000 -0.250000\n" +"vt 0.000000 0.000000\n" +"vt 0.250000 0.000000\n" +"vt 0.500000 0.000000\n" +"vt 0.750000 0.000000\n" +"vt 1.000000 0.000000\n" +"vt 0.000000 0.250000\n" +"vt 0.250000 0.250000\n" +"vt 0.500000 0.250000\n" +"vt 0.750000 0.250000\n" +"vt 1.000000 0.250000\n" +"vt 0.000000 0.500000\n" +"vt 0.250000 0.500000\n" +"vt 0.500000 0.500000\n" +"vt 0.750000 0.500000\n" +"vt 1.000000 0.500000\n" +"vt 0.000000 0.750000\n" +"vt 0.250000 0.750000\n" +"vt 0.500000 0.750000\n" +"vt 0.750000 0.750000\n" +"vt 1.000000 0.750000\n" +"vt 0.000000 1.000000\n" +"vt 0.250000 1.000000\n" +"vt 0.500000 1.000000\n" +"vt 0.750000 1.000000\n" +"vt 1.000000 1.000000\n" +"vn 0.000000 1.000000 0.000000\n" +"vn 0.000000 1.000000 0.000000\n" +"vn 0.000000 1.000000 0.000000\n" +"vn 0.000000 1.000000 0.000000\n" +"vn 0.000000 1.000000 0.000000\n" +"vn 0.000000 1.000000 0.000000\n" +"vn 0.000000 1.000000 0.000000\n" +"vn 0.000000 1.000000 0.000000\n" +"vn 0.000000 1.000000 0.000000\n" +"vn 0.000000 1.000000 0.000000\n" +"vn 0.000000 1.000000 0.000000\n" +"vn 0.000000 1.000000 0.000000\n" +"vn 0.000000 1.000000 0.000000\n" +"vn 0.000000 1.000000 0.000000\n" +"vn 0.000000 1.000000 0.000000\n" +"vn 0.000000 1.000000 0.000000\n" +"vn 0.000000 1.000000 0.000000\n" +"vn 0.000000 1.000000 0.000000\n" +"vn 0.000000 1.000000 0.000000\n" +"vn 0.000000 1.000000 0.000000\n" +"vn 0.000000 1.000000 0.000000\n" +"vn 0.000000 1.000000 0.000000\n" +"vn 0.000000 1.000000 0.000000\n" +"vn 0.000000 1.000000 0.000000\n" +"vn 0.000000 1.000000 0.000000\n" +"s off\n" +"f 1/1/1 2/2/2 7/7/3 6/6/4\n" +"f 2/2/2 3/3/5 8/8/6 7/7/3\n" +"f 3/3/5 4/4/7 9/9/8 8/8/6\n" +"f 4/4/7 5/5/9 10/10/10 9/9/8\n" +"f 6/6/4 7/7/3 12/12/11 11/11/12\n" +"f 7/7/3 8/8/6 13/13/13 12/12/11\n" +"f 8/8/6 9/9/8 14/14/14 13/13/13\n" +"f 9/9/8 10/10/10 15/15/15 14/14/14\n" +"f 11/11/12 12/12/11 17/17/16 16/16/17\n" +"f 12/12/11 13/13/13 18/18/18 17/17/16\n" +"f 13/13/13 14/14/14 19/19/19 18/18/18\n" +"f 14/14/14 15/15/15 20/20/20 19/19/19\n" +"f 16/16/17 17/17/16 22/22/21 21/21/22\n" +"f 17/17/16 18/18/18 23/23/23 22/22/21\n" +"f 18/18/18 19/19/19 24/24/24 23/23/23\n" +"f 19/19/19 20/20/20 25/25/25 24/24/24\n" +"t hole 4/0/0 5 6 9 10\n" +"t interpolateboundary 1/0/0 1\n" +"t crease 2/1/0 6 7 7.5\n" +; + + + + + +