Add support for hierarchical hole edits.

- add tag parsing for h-hole in shape_utils
- re-create Renderman's test shape from the documentation (catmark_square_hedit.h)
- fix Hbr to correctly pass the hole tag from parent to child face
- fix FarSubdivisionTables to handle disconnected face-vertices without crashing

fixes #75
This commit is contained in:
manuelk 2013-03-01 18:27:19 -08:00
parent 20b41baff8
commit ea1a87441f
8 changed files with 186 additions and 16 deletions

View File

@ -449,6 +449,8 @@ initializeShapes( ) {
#include <shapes/catmark_square_hedit3.h>
g_defaultShapes.push_back(SimpleShape(catmark_square_hedit3, "catmark_square_hedit3", kCatmark));
#include <shapes/catmark_square_hedit4.h>
g_defaultShapes.push_back(SimpleShape(catmark_square_hedit4, "catmark_square_hedit4", kCatmark));
#ifndef WIN32 // exceeds max string literal (65535 chars)

View File

@ -136,6 +136,9 @@ protected:
_vertVertsList;
private:
// Returns the subdivision level of a vertex
static int getVertexDepth(HbrVertex<T> * v);
template <class Type> static int sumList( std::vector<std::vector<Type> > const & list, int level );
// Sums the number of adjacent vertices required to interpolate a Vert-Vertex
@ -173,9 +176,7 @@ FarSubdivisionTablesFactory<T,U>::FarSubdivisionTablesFactory( HbrMesh<T> const
HbrVertex<T> * v = mesh->GetVertex(i);
assert(v);
assert(v->IsConnected());
int depth = v->GetFace()->GetDepth();
int depth = getVertexDepth( v );
if (depth>maxlevel)
continue;
@ -222,9 +223,7 @@ FarSubdivisionTablesFactory<T,U>::FarSubdivisionTablesFactory( HbrMesh<T> const
HbrVertex<T> * v = mesh->GetVertex(i);
assert(v);
assert(v->IsConnected());
int depth = v->GetFace()->GetDepth();
int depth = getVertexDepth( v );
if (depth>maxlevel)
continue;
@ -262,6 +261,22 @@ FarSubdivisionTablesFactory<T,U>::FarSubdivisionTablesFactory( HbrMesh<T> const
}
template <class T, class U> int
FarSubdivisionTablesFactory<T,U>::getVertexDepth(HbrVertex<T> * v) {
if (v->IsConnected()) {
return v->GetFace()->GetDepth();
} else {
// Un-connected vertices do not have a face pointer, so we have to seek
// the parent. Note : subdivision tables can only work with face-vertices,
// so we assert out of the other types.
HbrFace<T> * parent = v->GetParentFace();
assert(parent);
return parent->GetDepth()+1;
}
}
template <class T, class U>
template <class Type> int
FarSubdivisionTablesFactory<T,U>::sumList( std::vector<std::vector<Type> > const & list, int level) {

View File

@ -425,6 +425,9 @@ template <class T>
void
HbrBilinearSubdivision<T>::transferEditsToChild(HbrFace<T>* face, HbrFace<T>* child, int index) {
// Hand down hole tag
child->SetHole(face->IsHole());
// Hand down pointers to hierarchical edits
if (HbrHierarchicalEdit<T>** edits = face->GetHierarchicalEdits()) {
while (HbrHierarchicalEdit<T>* edit = *edits) {
@ -437,9 +440,6 @@ HbrBilinearSubdivision<T>::transferEditsToChild(HbrFace<T>* face, HbrFace<T>* ch
edits++;
}
}
// Hand down hole tag
child->SetHole(face->IsHole());
}

View File

@ -447,6 +447,9 @@ template <class T>
void
HbrCatmarkSubdivision<T>::transferEditsToChild(HbrFace<T>* face, HbrFace<T>* child, int index) {
// Hand down hole tag
child->SetHole(face->IsHole());
// Hand down pointers to hierarchical edits
if (HbrHierarchicalEdit<T>** edits = face->GetHierarchicalEdits()) {
while (HbrHierarchicalEdit<T>* edit = *edits) {
@ -459,9 +462,6 @@ HbrCatmarkSubdivision<T>::transferEditsToChild(HbrFace<T>* face, HbrFace<T>* chi
edits++;
}
}
// Hand down hole tag
child->SetHole(face->IsHole());
}

View File

@ -206,6 +206,8 @@ public:
// Subdivide the face into a vertex if needed and return
HbrVertex<T>* Subdivide();
bool HasChildVertex() const { return vchild!=-1; }
// Remove the reference to subdivided vertex
void RemoveChild() { vchild = -1; }

View File

@ -462,6 +462,9 @@ template <class T>
void
HbrLoopSubdivision<T>::transferEditsToChild(HbrFace<T>* face, HbrFace<T>* child, int index) {
// Hand down hole tag
child->SetHole(face->IsHole());
// Hand down pointers to hierarchical edits
if (HbrHierarchicalEdit<T>** edits = face->GetHierarchicalEdits()) {
while (HbrHierarchicalEdit<T>* edit = *edits) {
@ -474,9 +477,6 @@ HbrLoopSubdivision<T>::transferEditsToChild(HbrFace<T>* face, HbrFace<T>* child,
edits++;
}
}
// Hand down hole tag
child->SetHole(face->IsHole());
}
template <class T>

View File

@ -63,6 +63,7 @@
#include <hbr/catmark.h>
#include <hbr/vertexEdit.h>
#include <hbr/cornerEdit.h>
#include <hbr/holeEdit.h>
#include <stdio.h>
#include <string.h>
@ -600,7 +601,66 @@ void applyTags( OpenSubdiv::HbrMesh<T> * mesh, shape const * sh ) {
} // End of subop processing loop
} else if (t->name=="faceedit") {
printf("hierarchical face edits not supported (yet)\n");
int nint = (int)t->intargs.size();
for (int k=0; k<nint; ) {
int pathlength = t->intargs[k];
if (k+pathlength>=nint) {
printf("Invalid path length for %s tag on SubdivisionMesh", t->name.c_str());
goto nexttag;
}
int faceid = t->intargs[k+1];
int nsubfaces = pathlength - 1;
int *subfaces = &t->intargs[k+2];
OpenSubdiv::HbrFace<T> * f = mesh->GetFace(faceid);
if (!f) {
printf("Invalid face %d specified for %s tag on SubdivisionMesh.\n", faceid, t->name.c_str());
goto nexttag;
}
// Found the face. Do some preliminary error checking to make sure the path is
// correct. First value in path depends on the number of vertices of the face
// which we have in hand
if (nsubfaces && (subfaces[0] < 0 || subfaces[0] >= f->GetNumVertices()) ) {
printf("Invalid path component %d in %s tag on SubdivisionMesh.\n", subfaces[0], t->name.c_str());
goto nexttag;
}
// All subsequent values must be less than 4 (FIXME or 3 in the loop case?)
for (int l=1; l<nsubfaces; ++l) {
if (subfaces[l] < 0 || subfaces[l] > 3) {
printf("Invalid path component %d in %s tag on SubdivisionMesh.\n", subfaces[0], t->name.c_str());
goto nexttag;
}
}
// Now loop over string ops
int nstring = (int)t->stringargs.size();
for (int l = 0; l < nstring; ) {
if ( t->stringargs[l] == "hole" ) {
// Construct the edit
OpenSubdiv::HbrHoleEdit<T> * edit = new OpenSubdiv::HbrHoleEdit<T>(faceid, nsubfaces, subfaces);
mesh->AddHierarchicalEdit(edit);
++l;
} else if ( t->stringargs[l] == "attributes" ) {
// see NgpSubdivMesh.cpp:4341
printf("\"attributes\" face tag not supported yet.\n");
goto nexttag;
} else if ( t->stringargs[l] == "set" || t->stringargs[l] == "add" ) {
// see NgpSubdivMesh.cpp:4341
printf("\"set\" and \"add\" face tag not supported yet.\n");
goto nexttag;
} else {
printf("Faceedit tag specifies invalid operation '%s' on Subdivmesh.\n", t->stringargs[l].c_str());
goto nexttag;
}
}
// Advance to next path
k += pathlength + 1;
} // end face path loop
} else {
printf("Unknown tag : \"%s\" - skipping\n", t->name.c_str());
}

View File

@ -0,0 +1,91 @@
//
// 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_square_hedit4 =
"# This file uses centimeters as units for non-parametric coordinates.\n"
"\n"
"v -1 -1 0\n"
"v -0.333333 -1 0\n"
"v 0.333333 -1 0\n"
"v 1 -1 0\n"
"v -1 -0.333333 0\n"
"v -0.333333 -0.333333 0\n"
"v 0.333333 -0.333333 0\n"
"v 1 -0.333333 0\n"
"v -1 0.333333 0\n"
"v -0.333333 0.333333 0\n"
"v 0.333333 0.333333 0\n"
"v 1 0.333333 0\n"
"v -1 1 0\n"
"v -0.333333 1 0\n"
"v 0.333333 1 0\n"
"v 1 1 0\n"
"vt 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"s off\n"
"f 1/1/1 2/1/1 6/1/1 5/1/1\n"
"f 2/1/1 3/1/1 7/1/1 6/1/1\n"
"f 3/1/1 4/1/1 8/1/1 7/1/1\n"
"f 5/1/1 6/1/1 10/1/1 9/1/1\n"
"f 6/1/1 7/1/1 11/1/1 10/1/1\n"
"f 7/1/1 8/1/1 12/1/1 11/1/1\n"
"f 9/1/1 10/1/1 14/1/1 13/1/1\n"
"f 10/1/1 11/1/1 15/1/1 14/1/1\n"
"f 11/1/1 12/1/1 16/1/1 15/1/1\n"
"t interpolateboundary 1/0/0 2\n"
"t vertexedit 20/12/3 4 4 1 1 0 4 4 1 1 1 4 4 1 1 2 4 4 1 1 3 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 add P value\n"
"t faceedit 4/0/1 3 4 1 1 hole\n"
;