subd support: n-sided polygons & pixar crease tags
+ optional parameter to triangulate polygons to maintain compatibility + added create tag test & example subd crease tag file from OpenSubD source code
This commit is contained in:
101
catmark_torus_creases0.obj
Normal file
101
catmark_torus_creases0.obj
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
# This file uses centimeters as units for non-parametric coordinates.
|
||||||
|
|
||||||
|
v 1.25052 0.517982 0.353553
|
||||||
|
v 0.597239 0.247384 0.353553
|
||||||
|
v 0.597239 0.247384 -0.353553
|
||||||
|
v 1.25052 0.517982 -0.353553
|
||||||
|
v 0.517982 1.25052 0.353553
|
||||||
|
v 0.247384 0.597239 0.353553
|
||||||
|
v 0.247384 0.597239 -0.353553
|
||||||
|
v 0.517982 1.25052 -0.353553
|
||||||
|
v -0.517982 1.25052 0.353553
|
||||||
|
v -0.247384 0.597239 0.353553
|
||||||
|
v -0.247384 0.597239 -0.353553
|
||||||
|
v -0.517982 1.25052 -0.353553
|
||||||
|
v -1.25052 0.517982 0.353553
|
||||||
|
v -0.597239 0.247384 0.353553
|
||||||
|
v -0.597239 0.247384 -0.353553
|
||||||
|
v -1.25052 0.517982 -0.353553
|
||||||
|
v -1.25052 -0.517982 0.353553
|
||||||
|
v -0.597239 -0.247384 0.353553
|
||||||
|
v -0.597239 -0.247384 -0.353553
|
||||||
|
v -1.25052 -0.517982 -0.353553
|
||||||
|
v -0.517982 -1.25052 0.353553
|
||||||
|
v -0.247384 -0.597239 0.353553
|
||||||
|
v -0.247384 -0.597239 -0.353553
|
||||||
|
v -0.517982 -1.25052 -0.353553
|
||||||
|
v 0.517982 -1.25052 0.353553
|
||||||
|
v 0.247384 -0.597239 0.353553
|
||||||
|
v 0.247384 -0.597239 -0.353553
|
||||||
|
v 0.517982 -1.25052 -0.353553
|
||||||
|
v 1.25052 -0.517982 0.353553
|
||||||
|
v 0.597239 -0.247384 0.353553
|
||||||
|
v 0.597239 -0.247384 -0.353553
|
||||||
|
v 1.25052 -0.517982 -0.353553
|
||||||
|
vt 0 0
|
||||||
|
vt 1 0
|
||||||
|
vt 1 1
|
||||||
|
vt 0 1
|
||||||
|
f 5/1/1 6/2/2 2/3/3 1/4/4
|
||||||
|
f 6/1/5 7/2/6 3/3/7 2/4/8
|
||||||
|
f 7/1/9 8/2/10 4/3/11 3/4/12
|
||||||
|
f 8/1/13 5/2/14 1/3/15 4/4/16
|
||||||
|
f 9/1/17 10/2/18 6/3/19 5/4/20
|
||||||
|
f 10/1/21 11/2/22 7/3/23 6/4/24
|
||||||
|
f 11/1/25 12/2/26 8/3/27 7/4/28
|
||||||
|
f 12/1/29 9/2/30 5/3/31 8/4/32
|
||||||
|
f 13/1/33 14/2/34 10/3/35 9/4/36
|
||||||
|
f 14/1/37 15/2/38 11/3/39 10/4/40
|
||||||
|
f 15/1/41 16/2/42 12/3/43 11/4/44
|
||||||
|
f 16/1/45 13/2/46 9/3/47 12/4/48
|
||||||
|
f 17/1/49 18/2/50 14/3/51 13/4/52
|
||||||
|
f 18/1/53 19/2/54 15/3/55 14/4/56
|
||||||
|
f 19/1/57 20/2/58 16/3/59 15/4/60
|
||||||
|
f 20/1/61 17/2/62 13/3/63 16/4/64
|
||||||
|
f 21/1/65 22/2/66 18/3/67 17/4/68
|
||||||
|
f 22/1/69 23/2/70 19/3/71 18/4/72
|
||||||
|
f 23/1/73 24/2/74 20/3/75 19/4/76
|
||||||
|
f 24/1/77 21/2/78 17/3/79 20/4/80
|
||||||
|
f 25/1/81 26/2/82 22/3/83 21/4/84
|
||||||
|
f 26/1/85 27/2/86 23/3/87 22/4/88
|
||||||
|
f 27/1/89 28/2/90 24/3/91 23/4/92
|
||||||
|
f 28/1/93 25/2/94 21/3/95 24/4/96
|
||||||
|
f 29/1/97 30/2/98 26/3/99 25/4/100
|
||||||
|
f 30/1/101 31/2/102 27/3/103 26/4/104
|
||||||
|
f 31/1/105 32/2/106 28/3/107 27/4/108
|
||||||
|
f 32/1/109 29/2/110 25/3/111 28/4/112
|
||||||
|
f 1/1/113 2/2/114 30/3/115 29/4/116
|
||||||
|
f 2/1/117 3/2/118 31/3/119 30/4/120
|
||||||
|
f 3/1/121 4/2/122 32/3/123 31/4/124
|
||||||
|
f 4/1/125 1/2/126 29/3/127 32/4/128
|
||||||
|
t crease 2/1/0 1 5 4.7
|
||||||
|
t crease 2/1/0 5 9 4.7
|
||||||
|
t crease 2/1/0 9 13 4.7
|
||||||
|
t crease 2/1/0 13 17 4.7
|
||||||
|
t crease 2/1/0 17 21 4.7
|
||||||
|
t crease 2/1/0 21 25 4.7
|
||||||
|
t crease 2/1/0 25 29 4.7
|
||||||
|
t crease 2/1/0 29 1 4.7
|
||||||
77
test.cc
77
test.cc
@@ -7,14 +7,16 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
static void PrintInfo(const std::vector<tinyobj::shape_t>& shapes)
|
static void PrintInfo(const std::vector<tinyobj::shape_t>& shapes, bool triangulate = true)
|
||||||
{
|
{
|
||||||
std::cout << "# of shapes : " << shapes.size() << std::endl;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < shapes.size(); i++) {
|
for (size_t i = 0; i < shapes.size(); i++) {
|
||||||
printf("shape[%ld].name = %s\n", i, shapes[i].name.c_str());
|
printf("shape[%ld].name = %s\n", i, shapes[i].name.c_str());
|
||||||
printf("shape[%ld].indices: %ld\n", i, shapes[i].mesh.indices.size());
|
printf("shape[%ld].indices: %ld\n", i, shapes[i].mesh.indices.size());
|
||||||
assert((shapes[i].mesh.indices.size() % 3) == 0);
|
if (triangulate)
|
||||||
|
{
|
||||||
|
assert((shapes[i].mesh.indices.size() % 3) == 0);
|
||||||
|
}
|
||||||
for (size_t f = 0; f < shapes[i].mesh.indices.size(); f++) {
|
for (size_t f = 0; f < shapes[i].mesh.indices.size(); f++) {
|
||||||
printf(" idx[%ld] = %d\n", f, shapes[i].mesh.indices[f]);
|
printf(" idx[%ld] = %d\n", f, shapes[i].mesh.indices[f]);
|
||||||
}
|
}
|
||||||
@@ -27,7 +29,51 @@ static void PrintInfo(const std::vector<tinyobj::shape_t>& shapes)
|
|||||||
shapes[i].mesh.positions[3*v+1],
|
shapes[i].mesh.positions[3*v+1],
|
||||||
shapes[i].mesh.positions[3*v+2]);
|
shapes[i].mesh.positions[3*v+2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("shape[%ld].numFaces: %ld\n", i, shapes[i].mesh.numVertices.size());
|
||||||
|
for (size_t v = 0; v < shapes[i].mesh.numVertices.size(); v++) {
|
||||||
|
printf(" numVerts[%ld] = %ld\n", v,
|
||||||
|
(long) shapes[i].mesh.numVertices[v]);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("shape[%ld].numTags: %ld\n", i, shapes[i].mesh.tags.size());
|
||||||
|
for (size_t t = 0; t < shapes[i].mesh.tags.size(); t++) {
|
||||||
|
printf(" tag[%ld] = %s ", t, shapes[i].mesh.tags[t].name.c_str());
|
||||||
|
printf(" ints: [");
|
||||||
|
for (int j = 0; j < shapes[i].mesh.tags[t].intValues.size(); ++j)
|
||||||
|
{
|
||||||
|
printf("%ld", (long) shapes[i].mesh.tags[t].intValues[j]);
|
||||||
|
if (j < (shapes[i].mesh.tags[t].intValues.size()-1))
|
||||||
|
{
|
||||||
|
printf(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("]");
|
||||||
|
|
||||||
|
printf(" floats: [");
|
||||||
|
for (int j = 0; j < shapes[i].mesh.tags[t].floatValues.size(); ++j)
|
||||||
|
{
|
||||||
|
printf("%f", shapes[i].mesh.tags[t].floatValues[j]);
|
||||||
|
if (j < (shapes[i].mesh.tags[t].floatValues.size()-1))
|
||||||
|
{
|
||||||
|
printf(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("]");
|
||||||
|
|
||||||
|
printf(" strings: [");
|
||||||
|
for (int j = 0; j < shapes[i].mesh.tags[t].stringValues.size(); ++j)
|
||||||
|
{
|
||||||
|
printf("%s", shapes[i].mesh.tags[t].stringValues[j].c_str());
|
||||||
|
if (j < (shapes[i].mesh.tags[t].stringValues.size()-1))
|
||||||
|
{
|
||||||
|
printf(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("]");
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
printf("shape[%ld].material.name = %s\n", i, shapes[i].material.name.c_str());
|
printf("shape[%ld].material.name = %s\n", i, shapes[i].material.name.c_str());
|
||||||
printf(" material.Ka = (%f, %f ,%f)\n", shapes[i].material.ambient[0], shapes[i].material.ambient[1], shapes[i].material.ambient[2]);
|
printf(" material.Ka = (%f, %f ,%f)\n", shapes[i].material.ambient[0], shapes[i].material.ambient[1], shapes[i].material.ambient[2]);
|
||||||
printf(" material.Kd = (%f, %f ,%f)\n", shapes[i].material.diffuse[0], shapes[i].material.diffuse[1], shapes[i].material.diffuse[2]);
|
printf(" material.Kd = (%f, %f ,%f)\n", shapes[i].material.diffuse[0], shapes[i].material.diffuse[1], shapes[i].material.diffuse[2]);
|
||||||
@@ -54,19 +100,20 @@ static void PrintInfo(const std::vector<tinyobj::shape_t>& shapes)
|
|||||||
static bool
|
static bool
|
||||||
TestLoadObj(
|
TestLoadObj(
|
||||||
const char* filename,
|
const char* filename,
|
||||||
const char* basepath = NULL)
|
const char* basepath = NULL,
|
||||||
|
bool triangulate = true)
|
||||||
{
|
{
|
||||||
std::cout << "Loading " << filename << std::endl;
|
std::cout << "Loading " << filename << std::endl;
|
||||||
|
|
||||||
std::vector<tinyobj::shape_t> shapes;
|
std::vector<tinyobj::shape_t> shapes;
|
||||||
std::string err = tinyobj::LoadObj(shapes, filename, basepath);
|
std::string err = tinyobj::LoadObj(shapes, filename, basepath, triangulate);
|
||||||
|
|
||||||
if (!err.empty()) {
|
if (!err.empty()) {
|
||||||
std::cerr << err << std::endl;
|
std::cerr << err << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintInfo(shapes);
|
PrintInfo(shapes, triangulate);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -78,7 +125,7 @@ TestStreamLoadObj()
|
|||||||
std::cout << "Stream Loading " << std::endl;
|
std::cout << "Stream Loading " << std::endl;
|
||||||
|
|
||||||
std::stringstream objStream;
|
std::stringstream objStream;
|
||||||
objStream
|
objStream
|
||||||
<< "mtllib cube.mtl\n"
|
<< "mtllib cube.mtl\n"
|
||||||
"\n"
|
"\n"
|
||||||
"v 0.000000 2.000000 2.000000\n"
|
"v 0.000000 2.000000 2.000000\n"
|
||||||
@@ -111,7 +158,7 @@ TestStreamLoadObj()
|
|||||||
"f 2 6 7 3\n"
|
"f 2 6 7 3\n"
|
||||||
"# 6 elements";
|
"# 6 elements";
|
||||||
|
|
||||||
std::string matStream(
|
std::string matStream(
|
||||||
"newmtl white\n"
|
"newmtl white\n"
|
||||||
"Ka 0 0 0\n"
|
"Ka 0 0 0\n"
|
||||||
"Kd 1 1 1\n"
|
"Kd 1 1 1\n"
|
||||||
@@ -153,19 +200,19 @@ std::string matStream(
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::stringstream m_matSStream;
|
std::stringstream m_matSStream;
|
||||||
};
|
};
|
||||||
|
|
||||||
MaterialStringStreamReader matSSReader(matStream);
|
MaterialStringStreamReader matSSReader(matStream);
|
||||||
std::vector<tinyobj::shape_t> shapes;
|
std::vector<tinyobj::shape_t> shapes;
|
||||||
std::string err = tinyobj::LoadObj(shapes, objStream, matSSReader);
|
std::string err = tinyobj::LoadObj(shapes, objStream, matSSReader);
|
||||||
|
|
||||||
if (!err.empty()) {
|
if (!err.empty()) {
|
||||||
std::cerr << err << std::endl;
|
std::cerr << err << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintInfo(shapes);
|
PrintInfo(shapes);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +221,6 @@ main(
|
|||||||
int argc,
|
int argc,
|
||||||
char **argv)
|
char **argv)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
const char* basepath = NULL;
|
const char* basepath = NULL;
|
||||||
if (argc > 2) {
|
if (argc > 2) {
|
||||||
@@ -185,7 +231,8 @@ main(
|
|||||||
assert(true == TestLoadObj("cornell_box.obj"));
|
assert(true == TestLoadObj("cornell_box.obj"));
|
||||||
assert(true == TestLoadObj("cube.obj"));
|
assert(true == TestLoadObj("cube.obj"));
|
||||||
assert(true == TestStreamLoadObj());
|
assert(true == TestStreamLoadObj());
|
||||||
|
assert(true == TestLoadObj("catmark_torus_creases0.obj", NULL, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// Copyright 2012-2013, Syoyo Fujita.
|
// Copyright 2012-2013, Syoyo Fujita.
|
||||||
//
|
//
|
||||||
// Licensed under 2-clause BSD liecense.
|
// Licensed under 2-clause BSD liecense.
|
||||||
//
|
//
|
||||||
|
|
||||||
@@ -38,6 +38,14 @@ struct vertex_index {
|
|||||||
vertex_index(int vidx, int vtidx, int vnidx) : v_idx(vidx), vt_idx(vtidx), vn_idx(vnidx) {};
|
vertex_index(int vidx, int vtidx, int vnidx) : v_idx(vidx), vt_idx(vtidx), vn_idx(vnidx) {};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct tag_sizes {
|
||||||
|
tag_sizes() : num_ints(0), num_floats(0), num_strings(0) {}
|
||||||
|
int num_ints;
|
||||||
|
int num_floats;
|
||||||
|
int num_strings;
|
||||||
|
};
|
||||||
|
|
||||||
// for std::map
|
// for std::map
|
||||||
static inline bool operator<(const vertex_index& a, const vertex_index& b)
|
static inline bool operator<(const vertex_index& a, const vertex_index& b)
|
||||||
{
|
{
|
||||||
@@ -62,7 +70,7 @@ static inline bool isNewLine(const char c) {
|
|||||||
return (c == '\r') || (c == '\n') || (c == '\0');
|
return (c == '\r') || (c == '\n') || (c == '\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make index zero-base, and also support relative index.
|
// Make index zero-base, and also support relative index.
|
||||||
static inline int fixIndex(int idx, int n)
|
static inline int fixIndex(int idx, int n)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -122,6 +130,30 @@ static inline void parseFloat3(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static tag_sizes parseTagTriple(const char* & token)
|
||||||
|
{
|
||||||
|
tag_sizes ts;
|
||||||
|
|
||||||
|
ts.num_ints = atoi(token);
|
||||||
|
token += strcspn(token, "/ \t\r");
|
||||||
|
if (token[0] != '/') {
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
token++;
|
||||||
|
|
||||||
|
ts.num_floats = atoi(token);
|
||||||
|
token += strcspn(token, "/ \t\r");
|
||||||
|
if (token[0] != '/') {
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
token++;
|
||||||
|
|
||||||
|
ts.num_strings = atoi(token);
|
||||||
|
token += strcspn(token, "/ \t\r") + 1;
|
||||||
|
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
// Parse triples: i, i/j/k, i//k, i/j
|
// Parse triples: i, i/j/k, i//k, i/j
|
||||||
static vertex_index parseTriple(
|
static vertex_index parseTriple(
|
||||||
const char* &token,
|
const char* &token,
|
||||||
@@ -145,7 +177,7 @@ static vertex_index parseTriple(
|
|||||||
token += strcspn(token, "/ \t\r");
|
token += strcspn(token, "/ \t\r");
|
||||||
return vi;
|
return vi;
|
||||||
}
|
}
|
||||||
|
|
||||||
// i/j/k or i/j
|
// i/j/k or i/j
|
||||||
vi.vt_idx = fixIndex(atoi(token), vtsize);
|
vi.vt_idx = fixIndex(atoi(token), vtsize);
|
||||||
token += strcspn(token, "/ \t\r");
|
token += strcspn(token, "/ \t\r");
|
||||||
@@ -157,7 +189,7 @@ static vertex_index parseTriple(
|
|||||||
token++; // skip '/'
|
token++; // skip '/'
|
||||||
vi.vn_idx = fixIndex(atoi(token), vnsize);
|
vi.vn_idx = fixIndex(atoi(token), vnsize);
|
||||||
token += strcspn(token, "/ \t\r");
|
token += strcspn(token, "/ \t\r");
|
||||||
return vi;
|
return vi;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int
|
static unsigned int
|
||||||
@@ -184,13 +216,13 @@ updateVertex(
|
|||||||
positions.push_back(in_positions[3*i.v_idx+1]);
|
positions.push_back(in_positions[3*i.v_idx+1]);
|
||||||
positions.push_back(in_positions[3*i.v_idx+2]);
|
positions.push_back(in_positions[3*i.v_idx+2]);
|
||||||
|
|
||||||
if (i.vn_idx >= 0) {
|
if (i.vn_idx >= 0 && (i.vn_idx * 3 + 2) < in_normals.size() ) {
|
||||||
normals.push_back(in_normals[3*i.vn_idx+0]);
|
normals.push_back(in_normals[3*i.vn_idx+0]);
|
||||||
normals.push_back(in_normals[3*i.vn_idx+1]);
|
normals.push_back(in_normals[3*i.vn_idx+1]);
|
||||||
normals.push_back(in_normals[3*i.vn_idx+2]);
|
normals.push_back(in_normals[3*i.vn_idx+2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i.vt_idx >= 0) {
|
if (i.vt_idx >= 0 && (i.vt_idx * 2 +1) < in_texcoords.size()) {
|
||||||
texcoords.push_back(in_texcoords[2*i.vt_idx+0]);
|
texcoords.push_back(in_texcoords[2*i.vt_idx+0]);
|
||||||
texcoords.push_back(in_texcoords[2*i.vt_idx+1]);
|
texcoords.push_back(in_texcoords[2*i.vt_idx+1]);
|
||||||
}
|
}
|
||||||
@@ -228,9 +260,11 @@ exportFaceGroupToShape(
|
|||||||
const std::vector<float> &in_normals,
|
const std::vector<float> &in_normals,
|
||||||
const std::vector<float> &in_texcoords,
|
const std::vector<float> &in_texcoords,
|
||||||
const std::vector<std::vector<vertex_index> >& faceGroup,
|
const std::vector<std::vector<vertex_index> >& faceGroup,
|
||||||
|
std::vector<tag_t>& tags,
|
||||||
const material_t &material,
|
const material_t &material,
|
||||||
const std::string &name,
|
const std::string &name,
|
||||||
const bool is_material_seted)
|
const bool is_material_seted,
|
||||||
|
const bool triangulate)
|
||||||
{
|
{
|
||||||
if (faceGroup.empty()) {
|
if (faceGroup.empty()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -247,26 +281,38 @@ exportFaceGroupToShape(
|
|||||||
for (size_t i = 0; i < faceGroup.size(); i++) {
|
for (size_t i = 0; i < faceGroup.size(); i++) {
|
||||||
const std::vector<vertex_index>& face = faceGroup[i];
|
const std::vector<vertex_index>& face = faceGroup[i];
|
||||||
|
|
||||||
vertex_index i0 = face[0];
|
|
||||||
vertex_index i1(-1);
|
|
||||||
vertex_index i2 = face[1];
|
|
||||||
|
|
||||||
size_t npolys = face.size();
|
size_t npolys = face.size();
|
||||||
|
|
||||||
// Polygon -> triangle fan conversion
|
if (triangulate) {
|
||||||
for (size_t k = 2; k < npolys; k++) {
|
vertex_index i0 = face[0];
|
||||||
i1 = i2;
|
vertex_index i1(-1);
|
||||||
i2 = face[k];
|
vertex_index i2 = face[1];
|
||||||
|
|
||||||
unsigned int v0 = updateVertex(vertexCache, positions, normals, texcoords, in_positions, in_normals, in_texcoords, i0);
|
// Polygon -> triangle fan conversion
|
||||||
unsigned int v1 = updateVertex(vertexCache, positions, normals, texcoords, in_positions, in_normals, in_texcoords, i1);
|
for (size_t k = 2; k < npolys; k++) {
|
||||||
unsigned int v2 = updateVertex(vertexCache, positions, normals, texcoords, in_positions, in_normals, in_texcoords, i2);
|
i1 = i2;
|
||||||
|
i2 = face[k];
|
||||||
|
|
||||||
indices.push_back(v0);
|
unsigned int v0 = updateVertex(vertexCache, positions, normals, texcoords, in_positions, in_normals, in_texcoords, i0);
|
||||||
indices.push_back(v1);
|
unsigned int v1 = updateVertex(vertexCache, positions, normals, texcoords, in_positions, in_normals, in_texcoords, i1);
|
||||||
indices.push_back(v2);
|
unsigned int v2 = updateVertex(vertexCache, positions, normals, texcoords, in_positions, in_normals, in_texcoords, i2);
|
||||||
|
|
||||||
|
indices.push_back(v0);
|
||||||
|
indices.push_back(v1);
|
||||||
|
indices.push_back(v2);
|
||||||
|
|
||||||
|
shape.mesh.numVertices.push_back(3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (size_t k = 0; k < npolys; k++) {
|
||||||
|
unsigned int v = updateVertex(vertexCache, positions, normals, texcoords, in_positions, in_normals, in_texcoords, face[k]);
|
||||||
|
indices.push_back(v);
|
||||||
|
|
||||||
|
shape.mesh.numVertices.push_back(npolys);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -277,6 +323,7 @@ exportFaceGroupToShape(
|
|||||||
shape.mesh.normals.swap(normals);
|
shape.mesh.normals.swap(normals);
|
||||||
shape.mesh.texcoords.swap(texcoords);
|
shape.mesh.texcoords.swap(texcoords);
|
||||||
shape.mesh.indices.swap(indices);
|
shape.mesh.indices.swap(indices);
|
||||||
|
shape.mesh.tags.swap(tags);
|
||||||
|
|
||||||
if(is_material_seted) {
|
if(is_material_seted) {
|
||||||
shape.material = material;
|
shape.material = material;
|
||||||
@@ -299,7 +346,7 @@ std::string LoadMtl (
|
|||||||
std::stringstream err;
|
std::stringstream err;
|
||||||
|
|
||||||
material_t material;
|
material_t material;
|
||||||
|
|
||||||
int maxchars = 8192; // Alloc enough size.
|
int maxchars = 8192; // Alloc enough size.
|
||||||
std::vector<char> buf(maxchars); // Alloc enough size.
|
std::vector<char> buf(maxchars); // Alloc enough size.
|
||||||
while (inStream.peek() != -1) {
|
while (inStream.peek() != -1) {
|
||||||
@@ -326,9 +373,9 @@ std::string LoadMtl (
|
|||||||
|
|
||||||
assert(token);
|
assert(token);
|
||||||
if (token[0] == '\0') continue; // empty line
|
if (token[0] == '\0') continue; // empty line
|
||||||
|
|
||||||
if (token[0] == '#') continue; // comment line
|
if (token[0] == '#') continue; // comment line
|
||||||
|
|
||||||
// new mtl
|
// new mtl
|
||||||
if ((0 == strncmp(token, "newmtl", 6)) && isSpace((token[6]))) {
|
if ((0 == strncmp(token, "newmtl", 6)) && isSpace((token[6]))) {
|
||||||
// flush previous material.
|
// flush previous material.
|
||||||
@@ -344,7 +391,7 @@ std::string LoadMtl (
|
|||||||
material.name = namebuf;
|
material.name = namebuf;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ambient
|
// ambient
|
||||||
if (token[0] == 'K' && token[1] == 'a' && isSpace((token[2]))) {
|
if (token[0] == 'K' && token[1] == 'a' && isSpace((token[2]))) {
|
||||||
token += 2;
|
token += 2;
|
||||||
@@ -355,7 +402,7 @@ std::string LoadMtl (
|
|||||||
material.ambient[2] = b;
|
material.ambient[2] = b;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// diffuse
|
// diffuse
|
||||||
if (token[0] == 'K' && token[1] == 'd' && isSpace((token[2]))) {
|
if (token[0] == 'K' && token[1] == 'd' && isSpace((token[2]))) {
|
||||||
token += 2;
|
token += 2;
|
||||||
@@ -366,7 +413,7 @@ std::string LoadMtl (
|
|||||||
material.diffuse[2] = b;
|
material.diffuse[2] = b;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// specular
|
// specular
|
||||||
if (token[0] == 'K' && token[1] == 's' && isSpace((token[2]))) {
|
if (token[0] == 'K' && token[1] == 's' && isSpace((token[2]))) {
|
||||||
token += 2;
|
token += 2;
|
||||||
@@ -377,7 +424,7 @@ std::string LoadMtl (
|
|||||||
material.specular[2] = b;
|
material.specular[2] = b;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// transmittance
|
// transmittance
|
||||||
if (token[0] == 'K' && token[1] == 't' && isSpace((token[2]))) {
|
if (token[0] == 'K' && token[1] == 't' && isSpace((token[2]))) {
|
||||||
token += 2;
|
token += 2;
|
||||||
@@ -499,7 +546,8 @@ std::string
|
|||||||
LoadObj(
|
LoadObj(
|
||||||
std::vector<shape_t>& shapes,
|
std::vector<shape_t>& shapes,
|
||||||
const char* filename,
|
const char* filename,
|
||||||
const char* mtl_basepath)
|
const char* mtl_basepath,
|
||||||
|
bool triangulate)
|
||||||
{
|
{
|
||||||
|
|
||||||
shapes.clear();
|
shapes.clear();
|
||||||
@@ -517,20 +565,23 @@ LoadObj(
|
|||||||
basePath = mtl_basepath;
|
basePath = mtl_basepath;
|
||||||
}
|
}
|
||||||
MaterialFileReader matFileReader( basePath );
|
MaterialFileReader matFileReader( basePath );
|
||||||
|
|
||||||
return LoadObj(shapes, ifs, matFileReader);
|
return LoadObj(shapes, ifs, matFileReader, triangulate);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string LoadObj(
|
std::string LoadObj(
|
||||||
std::vector<shape_t>& shapes,
|
std::vector<shape_t>& shapes,
|
||||||
std::istream& inStream,
|
std::istream& inStream,
|
||||||
MaterialReader& readMatFn)
|
MaterialReader& readMatFn,
|
||||||
|
bool triangulate)
|
||||||
{
|
{
|
||||||
std::stringstream err;
|
std::stringstream err;
|
||||||
|
|
||||||
std::vector<float> v;
|
std::vector<float> v;
|
||||||
std::vector<float> vn;
|
std::vector<float> vn;
|
||||||
std::vector<float> vt;
|
std::vector<float> vt;
|
||||||
|
std::vector<tag_t> tags;
|
||||||
|
|
||||||
std::vector<std::vector<vertex_index> > faceGroup;
|
std::vector<std::vector<vertex_index> > faceGroup;
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
@@ -565,7 +616,7 @@ std::string LoadObj(
|
|||||||
|
|
||||||
assert(token);
|
assert(token);
|
||||||
if (token[0] == '\0') continue; // empty line
|
if (token[0] == '\0') continue; // empty line
|
||||||
|
|
||||||
if (token[0] == '#') continue; // comment line
|
if (token[0] == '#') continue; // comment line
|
||||||
|
|
||||||
// vertex
|
// vertex
|
||||||
@@ -614,7 +665,7 @@ std::string LoadObj(
|
|||||||
}
|
}
|
||||||
|
|
||||||
faceGroup.push_back(face);
|
faceGroup.push_back(face);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -641,13 +692,13 @@ std::string LoadObj(
|
|||||||
char namebuf[4096];
|
char namebuf[4096];
|
||||||
token += 7;
|
token += 7;
|
||||||
sscanf(token, "%s", namebuf);
|
sscanf(token, "%s", namebuf);
|
||||||
|
|
||||||
std::string err_mtl = readMatFn(namebuf, material_map);
|
std::string err_mtl = readMatFn(namebuf, material_map);
|
||||||
if (!err_mtl.empty()) {
|
if (!err_mtl.empty()) {
|
||||||
faceGroup.clear(); // for safety
|
faceGroup.clear(); // for safety
|
||||||
return err_mtl;
|
return err_mtl;
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -656,7 +707,7 @@ std::string LoadObj(
|
|||||||
|
|
||||||
// flush previous face group.
|
// flush previous face group.
|
||||||
shape_t shape;
|
shape_t shape;
|
||||||
bool ret = exportFaceGroupToShape(shape, v, vn, vt, faceGroup, material, name, is_material_seted);
|
bool ret = exportFaceGroupToShape(shape, v, vn, vt, faceGroup, tags, material, name, is_material_seted, triangulate);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
shapes.push_back(shape);
|
shapes.push_back(shape);
|
||||||
}
|
}
|
||||||
@@ -688,7 +739,7 @@ std::string LoadObj(
|
|||||||
|
|
||||||
// flush previous face group.
|
// flush previous face group.
|
||||||
shape_t shape;
|
shape_t shape;
|
||||||
bool ret = exportFaceGroupToShape(shape, v, vn, vt, faceGroup, material, name, is_material_seted);
|
bool ret = exportFaceGroupToShape(shape, v, vn, vt, faceGroup, tags, material, name, is_material_seted, triangulate);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
shapes.push_back(shape);
|
shapes.push_back(shape);
|
||||||
}
|
}
|
||||||
@@ -706,11 +757,51 @@ std::string LoadObj(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (token[0] == 't' && isSpace(token[1])) {
|
||||||
|
tag_t tag;
|
||||||
|
|
||||||
|
char namebuf[4096];
|
||||||
|
token += 2;
|
||||||
|
sscanf(token, "%s", namebuf);
|
||||||
|
tag.name = std::string(namebuf);
|
||||||
|
|
||||||
|
token += tag.name.size() + 1;
|
||||||
|
|
||||||
|
tag_sizes ts = parseTagTriple(token);
|
||||||
|
|
||||||
|
tag.intValues.resize(ts.num_ints);
|
||||||
|
|
||||||
|
for(int i = 0; i < ts.num_ints; ++i)
|
||||||
|
{
|
||||||
|
tag.intValues[i] = atoi(token);
|
||||||
|
token += strcspn(token, "/ \t\r") + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tag.floatValues.resize(ts.num_floats);
|
||||||
|
for(int i = 0; i < ts.num_floats; ++i)
|
||||||
|
{
|
||||||
|
tag.floatValues[i] = parseFloat(token);
|
||||||
|
token += strcspn(token, "/ \t\r") + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tag.stringValues.resize(ts.num_strings);
|
||||||
|
for(int i = 0; i < ts.num_strings; ++i)
|
||||||
|
{
|
||||||
|
char stringValueBuffer[4096];
|
||||||
|
|
||||||
|
sscanf(token, "%s", stringValueBuffer);
|
||||||
|
tag.stringValues[i] = stringValueBuffer;
|
||||||
|
token += tag.stringValues[i].size() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tags.push_back(tag);
|
||||||
|
}
|
||||||
|
|
||||||
// Ignore unknown command.
|
// Ignore unknown command.
|
||||||
}
|
}
|
||||||
|
|
||||||
shape_t shape;
|
shape_t shape;
|
||||||
bool ret = exportFaceGroupToShape(shape, v, vn, vt, faceGroup, material, name, is_material_seted);
|
bool ret = exportFaceGroupToShape(shape, v, vn, vt, faceGroup, tags, material, name, is_material_seted, triangulate);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
shapes.push_back(shape);
|
shapes.push_back(shape);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,12 +34,23 @@ typedef struct
|
|||||||
std::map<std::string, std::string> unknown_parameter;
|
std::map<std::string, std::string> unknown_parameter;
|
||||||
} material_t;
|
} material_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
|
||||||
|
std::vector<int> intValues;
|
||||||
|
std::vector<float> floatValues;
|
||||||
|
std::vector<std::string> stringValues;
|
||||||
|
} tag_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
std::vector<float> positions;
|
std::vector<float> positions;
|
||||||
std::vector<float> normals;
|
std::vector<float> normals;
|
||||||
std::vector<float> texcoords;
|
std::vector<float> texcoords;
|
||||||
std::vector<unsigned int> indices;
|
std::vector<unsigned int> indices;
|
||||||
|
std::vector<unsigned char> numVertices; //Is it worth it 255 faces
|
||||||
|
std::vector<tag_t> tags;
|
||||||
} mesh_t;
|
} mesh_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -82,7 +93,9 @@ class MaterialFileReader:
|
|||||||
std::string LoadObj(
|
std::string LoadObj(
|
||||||
std::vector<shape_t>& shapes, // [output]
|
std::vector<shape_t>& shapes, // [output]
|
||||||
const char* filename,
|
const char* filename,
|
||||||
const char* mtl_basepath = NULL);
|
const char* mtl_basepath = NULL,
|
||||||
|
bool triangulate = true
|
||||||
|
);
|
||||||
|
|
||||||
/// Loads object from a std::istream, uses GetMtlIStreamFn to retrieve
|
/// Loads object from a std::istream, uses GetMtlIStreamFn to retrieve
|
||||||
/// std::istream for materials.
|
/// std::istream for materials.
|
||||||
@@ -90,7 +103,8 @@ std::string LoadObj(
|
|||||||
std::string LoadObj(
|
std::string LoadObj(
|
||||||
std::vector<shape_t>& shapes, // [output]
|
std::vector<shape_t>& shapes, // [output]
|
||||||
std::istream& inStream,
|
std::istream& inStream,
|
||||||
MaterialReader& readMatFn);
|
MaterialReader& readMatFn,
|
||||||
|
bool triangulate = true);
|
||||||
|
|
||||||
/// Loads materials into std::map
|
/// Loads materials into std::map
|
||||||
/// Returns an empty string if successful
|
/// Returns an empty string if successful
|
||||||
|
|||||||
Reference in New Issue
Block a user