Reduce modifcations to OpenSubdiv?
Closed this issue · 2 comments
MeshMaker is a nice project, after a bit of simple messing around I got it to build and run.
I created the file below to reduce the need to modify a clean pull of OpenSubdiv. It's still necessary to add the two accessors (GetFarMesh and GetVertexBuffer) to osd/mesh.h, but having OsdMeshMaker.h as a file in MeshMaker/Classes makes life easier. Maybe the two accessors could be submitted to OpenSubdiv as a pull request, and this OsdMeshMaker.h file could be added to MeshMaker?
//
// OsdMeshMaker.h
// MeshMaker
//
//
pragma once
include <common/shape_utils.h>
class MeshMakerDrawContext : public OpenSubdiv::OsdDrawContext {
public:
typedef GLuint VertexBufferBinding;
MeshMakerDrawContext() { }
virtual ~MeshMakerDrawContext() { }
template<class VERTEX_BUFFER>
static MeshMakerDrawContext *Create(OpenSubdiv::FarMesh<OpenSubdiv::OsdVertex> *farMesh,
VERTEX_BUFFER *vertexBuffer,
bool requirePtexCoordinates=false,
bool requireFVarData=false) {
if (not vertexBuffer)
return NULL;
MeshMakerDrawContext *instance = new MeshMakerDrawContext();
return instance;
}
};
template void
createVertices(OpenSubdiv::HbrMesh *mesh, const std::vector &verts)
{
int vertexCount = verts.size() / 3;
T v;
for (int i = 0; i < vertexCount; i++)
mesh->NewVertex(i, v);
}
template void
createTopology(OpenSubdiv::HbrMesh * mesh, const std::vector &faceverts, const std::vector &nvertsPerFace, Scheme scheme)
{
const int * fv=&(faceverts[0]);
for(int f=0, ptxidx=0;f<(int)nvertsPerFace.size(); f++ ) {
int nv = nvertsPerFace[f];
if ((scheme==kLoop) and (nv!=3)) {
printf("Trying to create a Loop surbd with non-triangle face\n");
exit(1);
}
for(int j=0;j<nv;j++) {
OpenSubdiv::HbrVertex<T> * origin = mesh->GetVertex( fv[j] );
OpenSubdiv::HbrVertex<T> * destination = mesh->GetVertex( fv[ (j+1)%nv] );
OpenSubdiv::HbrHalfedge<T> * opposite = destination->GetEdge(origin);
if(origin==NULL || destination==NULL) {
printf(" An edge was specified that connected a nonexistent vertex\n");
exit(1);
}
if(origin == destination) {
printf(" An edge was specified that connected a vertex to itself\n");
exit(1);
}
if(opposite && opposite->GetOpposite() ) {
printf(" A non-manifold edge incident to more than 2 faces was found\n");
exit(1);
}
if(origin->GetEdge(destination)) {
printf(" An edge connecting two vertices was specified more than once."
" It's likely that an incident face was flipped\n");
exit(1);
}
}
OpenSubdiv::HbrFace<T> * face = mesh->NewFace(nv, (int *)fv, 0);
face->SetPtexIndex(ptxidx);
if ( (scheme==kCatmark or scheme==kBilinear) and nv != 4 )
ptxidx+=nv;
else
ptxidx++;
fv+=nv;
}
mesh->SetInterpolateBoundaryMethod( OpenSubdiv::HbrMesh<T>::k_InterpolateBoundaryEdgeOnly );
//applyTags<T>( mesh, sh );
mesh->Finish();
}
template OpenSubdiv::HbrMesh *
simpleHbr2(const std::vector &vertices, const std::vector &faceverts, const std::vector &nvertsPerFace,
Scheme scheme)
{
OpenSubdiv::HbrMesh *mesh = createMesh(scheme);
createVertices(mesh, vertices);
createTopology(mesh, faceverts, nvertsPerFace, scheme);
return mesh;
}
I just needed a quick hack to make CPU based Catmull-Clark subdivision and OpenSubdiv does it. I would like to remove my fork of OpenSubdiv with some additions and maybe do something more sophisticated. For example I don't use live GPU based subdivision which OpenSubdiv is all about.
I see. For what it's worth I think OpenSubdiv is a pretty good choice in that it implements quite a lot of the corner cases that are hard to get right.