// // Copyright 2013 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. // #include "shape_utils.h" #include #include #include #include //------------------------------------------------------------------------------ static char const * sgets( char * s, int size, char ** stream ) { for (int i=0; ischeme = shapescheme; char * str=const_cast(shapestr), line[256]; bool done = false; while( not done ) { done = sgets(line, sizeof(line), &str)==0; char* end = &line[strlen(line)-1]; if (*end == '\n') *end = '\0'; // strip trailing nl float x, y, z, u, v; switch (line[0]) { case 'v': switch (line[1]) { case ' ': if(sscanf(line, "v %f %f %f", &x, &y, &z) == 3) { s->verts.push_back(x); switch( axis ) { case 0 : s->verts.push_back(-z); s->verts.push_back(y); break; case 1 : s->verts.push_back(y); s->verts.push_back(z); break; } } break; case 't': if(sscanf(line, "vt %f %f", &u, &v) == 2) { s->uvs.push_back(u); s->uvs.push_back(v); } break; case 'n' : if(sscanf(line, "vn %f %f %f", &x, &y, &z) == 3) { s->normals.push_back(x); s->normals.push_back(y); s->normals.push_back(z); } break; // skip normals for now } break; case 'f': if(line[1] == ' ') { int vi, ti, ni; const char* cp = &line[2]; while (*cp == ' ') cp++; int nverts = 0, nitems=0; while( (nitems=sscanf(cp, "%d/%d/%d", &vi, &ti, &ni))>0) { nverts++; s->faceverts.push_back(vi-1); if(nitems >= 1) s->faceuvs.push_back(ti-1); if(nitems >= 2) s->facenormals.push_back(ni-1); while (*cp && *cp != ' ') cp++; while (*cp == ' ') cp++; } s->nvertsPerFace.push_back(nverts); } break; case 't' : if(line[1] == ' ') { Shape::tag * t = tag::parseTag( line ); if (t) s->tags.push_back(t); } break; } } return s; } //------------------------------------------------------------------------------ Shape::tag * Shape::tag::parseTag(char const * line) { tag * t = 0; const char* cp = &line[2]; char tname[50]; while (*cp == ' ') cp++; if (sscanf(cp, "%s", tname )!=1) return t; while (*cp && *cp != ' ') cp++; int nints=0, nfloats=0, nstrings=0; while (*cp == ' ') cp++; if (sscanf(cp, "%d/%d/%d", &nints, &nfloats, &nstrings)!=3) return t; while (*cp && *cp != ' ') cp++; std::vector tintargs; for (int i=0; i tfloatargs; for (int i=0; i tstringargs; for (int i=0; iname = tname; t->intargs = tintargs; t->floatargs = tfloatargs; t->stringargs = tstringargs; return t; } //------------------------------------------------------------------------------ std::string Shape::tag::genTag() const { std::stringstream t; t<<"\"t \""<(t)); t<<" "; std::copy(floatargs.begin(), floatargs.end(), std::ostream_iterator(t)); t<<" "; std::copy(stringargs.begin(), stringargs.end(), std::ostream_iterator(t)); t<<"\\n\"\n"; return t.str(); } //------------------------------------------------------------------------------ std::string Shape::genShape(char const * name) const { std::stringstream sh; sh<<"static char const * "<0 ? faceuvs[idx+j]+1 : vert, normal = (int)facenormals.size()>0 ? facenormals[idx+j]+1 : vert; sh << vert << "/" << uv << "/" << normal << " "; } sh << "\\n\"\n"; idx+=nvertsPerFace[i]; } for (int i=0; i<(int)tags.size(); ++i) sh << tags[i]->genTag(); return sh.str(); } //------------------------------------------------------------------------------ std::string Shape::genObj() const { std::stringstream sh; sh<<"# This file uses centimeters as units for non-parametric coordinates.\n\n"; for (int i=0; i<(int)verts.size(); i+=3) sh << "v " << verts[i] << " " << verts[i+1] << " " << verts[i+2] <<"\n"; for (int i=0; i<(int)uvs.size(); i+=2) sh << "vt " << uvs[i] << " " << uvs[i+1] << "\n"; for (int i=0; i<(int)normals.size(); i+=3) sh << "vn " << normals[i] << " " << normals[i+1] << " " << normals[i+2] <<"\n"; for (int i=0, idx=0; i<(int)nvertsPerFace.size();++i) { sh << "f "; for (int j=0; j0 ? faceuvs[idx+j]+1 : vert, normal = (int)facenormals.size()>0 ? facenormals[idx+j]+1 : vert; sh << vert << "/" << uv << "/" << normal << " "; } sh << "\n"; idx+=nvertsPerFace[i]; } for (int i=0; i<(int)tags.size(); ++i) sh << tags[i]->genTag(); return sh.str(); } //------------------------------------------------------------------------------ std::string Shape::genRIB() const { std::stringstream rib; rib << "HierarchicalSubdivisionMesh \"catmull-clark\" "; rib << "["; std::copy(nvertsPerFace.begin(), nvertsPerFace.end(), std::ostream_iterator(rib)); rib << "] "; rib << "["; std::copy(faceverts.begin(), faceverts.end(), std::ostream_iterator(rib)); rib << "] "; std::stringstream names, nargs, intargs, floatargs, strargs; for (int i=0; i<(int)tags.size();) { tag * t = tags[i]; names << t->name; nargs << t->intargs.size() << " " << t->floatargs.size() << " " << t->stringargs.size(); std::copy(t->intargs.begin(), t->intargs.end(), std::ostream_iterator(intargs)); std::copy(t->floatargs.begin(), t->floatargs.end(), std::ostream_iterator(floatargs)); std::copy(t->stringargs.begin(), t->stringargs.end(), std::ostream_iterator(strargs)); if (++i<(int)tags.size()) { names << " "; nargs << " "; intargs << " "; floatargs << " "; strargs << " "; } } rib << "["<(rib)); rib << "] "; return rib.str(); }