Skip to content

Commit f3464d0

Browse files
committed
Merge branch 'master' into opt-refactor
2 parents da0b64f + 9173980 commit f3464d0

File tree

9 files changed

+158
-15
lines changed

9 files changed

+158
-15
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
project(tinyobjloader)
55
cmake_minimum_required(VERSION 2.8.11)
66
set(TINYOBJLOADER_SOVERSION 2)
7-
set(TINYOBJLOADER_VERSION 2.0.0-rc.7)
7+
set(TINYOBJLOADER_VERSION 2.0.0-rc.8)
88

99
#optional double precision support
1010
option(TINYOBJLOADER_USE_DOUBLE "Build library with double precision instead of single (float)" OFF)

README.md

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ TinyObjLoader now use `real_t` for floating point data type.
241241
Default is `float(32bit)`.
242242
You can enable `double(64bit)` precision by using `TINYOBJLOADER_USE_DOUBLE` define.
243243

244-
#### Example code
244+
#### Example code (Deprecated API)
245245

246246
```c++
247247
#define TINYOBJLOADER_IMPLEMENTATION // define this in only *one* .cc
@@ -302,6 +302,69 @@ for (size_t s = 0; s < shapes.size(); s++) {
302302

303303
```
304304

305+
#### Example code (New Object Oriented API)
306+
307+
```c++
308+
#define TINYOBJLOADER_IMPLEMENTATION // define this in only *one* .cc
309+
#include "tiny_obj_loader.h"
310+
311+
312+
std::string inputfile = "cornell_box.obj";
313+
tinyobj::ObjReaderConfig reader_config;
314+
reader_config.mtl_search_path = "./"; // Path to material files
315+
316+
tinyobj::ObjReader reader;
317+
318+
if (!reader.ParseFromFile(inputfile, reader_config)) {
319+
if (!reader.Error().empty()) {
320+
std::cerr << "TinyObjReader: " << reader.Error();
321+
}
322+
exit(1);
323+
}
324+
325+
if (!reader.Warning().empty()) {
326+
std::cout << "TinyObjReader: " << reader.Warning();
327+
}
328+
329+
auto& attrib = reader.GetAttrib();
330+
auto& shapes = reader.GetShapes();
331+
auto& materials = reader.GetMaterials();
332+
333+
// Loop over shapes
334+
for (size_t s = 0; s < shapes.size(); s++) {
335+
// Loop over faces(polygon)
336+
size_t index_offset = 0;
337+
for (size_t f = 0; f < shapes[s].mesh.num_face_vertices.size(); f++) {
338+
int fv = shapes[s].mesh.num_face_vertices[f];
339+
340+
// Loop over vertices in the face.
341+
for (size_t v = 0; v < fv; v++) {
342+
// access to vertex
343+
tinyobj::index_t idx = shapes[s].mesh.indices[index_offset + v];
344+
tinyobj::real_t vx = attrib.vertices[3*idx.vertex_index+0];
345+
tinyobj::real_t vy = attrib.vertices[3*idx.vertex_index+1];
346+
tinyobj::real_t vz = attrib.vertices[3*idx.vertex_index+2];
347+
tinyobj::real_t nx = attrib.normals[3*idx.normal_index+0];
348+
tinyobj::real_t ny = attrib.normals[3*idx.normal_index+1];
349+
tinyobj::real_t nz = attrib.normals[3*idx.normal_index+2];
350+
tinyobj::real_t tx = attrib.texcoords[2*idx.texcoord_index+0];
351+
tinyobj::real_t ty = attrib.texcoords[2*idx.texcoord_index+1];
352+
// Optional: vertex colors
353+
// tinyobj::real_t red = attrib.colors[3*idx.vertex_index+0];
354+
// tinyobj::real_t green = attrib.colors[3*idx.vertex_index+1];
355+
// tinyobj::real_t blue = attrib.colors[3*idx.vertex_index+2];
356+
}
357+
index_offset += fv;
358+
359+
// per-face material
360+
shapes[s].mesh.material_ids[f];
361+
}
362+
}
363+
364+
```
365+
366+
367+
305368
## Optimized loader
306369

307370
Optimized multi-threaded .obj loader is available at `experimental/` directory.

examples/viewer/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
* premake5
66
* glfw3
77
* glew
8+
* xcursor
9+
* xinerama
810

911
## Build on MaCOSX
1012

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
newmtl green
2+
Ka 0 0 0
3+
Kd 0 1 0
4+
Ks 0 0 0
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
mtllib invalid-file-without-spaces.mtl invalid\ file\ with\ spaces.mtl mtl\ filename\ with\ whitespace\ issue46.mtl
2+
3+
v 0.000000 2.000000 2.000000
4+
v 0.000000 0.000000 2.000000
5+
v 2.000000 0.000000 2.000000
6+
v 2.000000 2.000000 2.000000
7+
v 0.000000 2.000000 0.000000
8+
v 0.000000 0.000000 0.000000
9+
v 2.000000 0.000000 0.000000
10+
v 2.000000 2.000000 0.000000
11+
# 8 vertices
12+
13+
g front cube
14+
usemtl green
15+
f 1 2 3 4
16+
g back cube
17+
usemtl green
18+
f 8 7 6 5
19+
g right cube
20+
usemtl green
21+
f 4 3 7 8
22+
g left cube
23+
usemtl green
24+
f 5 6 2 1
25+
g top cube
26+
usemtl green
27+
f 5 1 4 8
28+
g bottom cube
29+
usemtl green
30+
f 2 6 7 3
31+
# 6 elements

python/setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def __str__(self):
8282

8383
setuptools.setup(
8484
name="tinyobjloader",
85-
version="2.0.0rc7",
85+
version="2.0.0rc8",
8686
description="Tiny but powerful Wavefront OBJ loader",
8787
long_description=long_description,
8888
long_description_content_type="text/markdown",

tests/Makefile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
.PHONY: clean
22

3-
CXX = clang++
3+
CXX ?= clang++
44
CXXFLAGS ?= -g -O1
5+
EXTRA_CXXFLAGS ?= -std=c++03 -fsanitize=address
56

67
tester: tester.cc ../tiny_obj_loader.h
7-
$(CXX) $(CXXFLAGS) -fsanitize=address -o tester tester.cc
8+
$(CXX) $(CXXFLAGS) $(EXTRA_CXXFLAGS) -o tester tester.cc
89

910
all: tester
1011

tests/tester.cc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1308,6 +1308,30 @@ void test_texres_texopt_issue248() {
13081308
TEST_CHECK("input.jpg" == materials[0].diffuse_texname);
13091309
}
13101310

1311+
void test_mtl_filename_with_whitespace_issue46() {
1312+
tinyobj::attrib_t attrib;
1313+
std::vector<tinyobj::shape_t> shapes;
1314+
std::vector<tinyobj::material_t> materials;
1315+
1316+
std::string warn;
1317+
std::string err;
1318+
bool ret =
1319+
tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
1320+
"../models/mtl filename with whitespace issue46.obj",
1321+
gMtlBasePath);
1322+
1323+
if (!warn.empty()) {
1324+
std::cout << "WARN: " << warn << std::endl;
1325+
}
1326+
1327+
if (!err.empty()) {
1328+
std::cerr << "ERR: " << err << std::endl;
1329+
}
1330+
TEST_CHECK(true == ret);
1331+
TEST_CHECK(1 == materials.size());
1332+
TEST_CHECK("green" == materials[0].name);
1333+
}
1334+
13111335
// Fuzzer test.
13121336
// Just check if it does not crash.
13131337
// Disable by default since Windows filesystem can't create filename of afl
@@ -1407,4 +1431,6 @@ TEST_LIST = {
14071431
test_usemtl_whitespace_issue246},
14081432
{"texres_texopt_issue248",
14091433
test_texres_texopt_issue248},
1434+
{"test_mtl_filename_with_whitespace_issue46",
1435+
test_mtl_filename_with_whitespace_issue46},
14101436
{NULL, NULL}};

tiny_obj_loader.h

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ THE SOFTWARE.
2828
// * Support points primitive.
2929
// * Support multiple search path for .mtl(v1 API).
3030
// * Support vertex weight `vw`(as an tinyobj extension)
31+
// * Support escaped whitespece in mtllib
3132
// version 1.4.0 : Modifed ParseTextureNameAndOption API
3233
// version 1.3.1 : Make ParseTextureNameAndOption API public
3334
// version 1.3.0 : Separate warning and error message(breaking API of LoadObj)
@@ -1658,16 +1659,31 @@ static bool exportGroupsToShape(shape_t *shape, const PrimGroup &prim_group,
16581659
return true;
16591660
}
16601661

1661-
// Split a string with specified delimiter character.
1662-
// http://stackoverflow.com/questions/236129/split-a-string-in-c
1663-
static void SplitString(const std::string &s, char delim,
1662+
// Split a string with specified delimiter character and escape character.
1663+
// https://rosettacode.org/wiki/Tokenize_a_string_with_escaping#C.2B.2B
1664+
static void SplitString(const std::string &s, char delim, char escape,
16641665
std::vector<std::string> &elems) {
1665-
std::stringstream ss;
1666-
ss.str(s);
1667-
std::string item;
1668-
while (std::getline(ss, item, delim)) {
1669-
elems.push_back(item);
1666+
std::string token;
1667+
1668+
bool escaping = false;
1669+
for (size_t i = 0; i < s.size(); ++i) {
1670+
char ch = s[i];
1671+
if (escaping) {
1672+
escaping = false;
1673+
} else if (ch == escape) {
1674+
escaping = true;
1675+
continue;
1676+
} else if (ch == delim) {
1677+
if (!token.empty()) {
1678+
elems.push_back(token);
1679+
}
1680+
token.clear();
1681+
continue;
1682+
}
1683+
token += ch;
16701684
}
1685+
1686+
elems.push_back(token);
16711687
}
16721688

16731689
static std::string JoinPath(const std::string &dir,
@@ -2483,7 +2499,7 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
24832499
token += 7;
24842500

24852501
std::vector<std::string> filenames;
2486-
SplitString(std::string(token), ' ', filenames);
2502+
SplitString(std::string(token), ' ', '\\', filenames);
24872503

24882504
if (filenames.empty()) {
24892505
if (warn) {
@@ -2891,7 +2907,7 @@ bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback,
28912907
token += 7;
28922908

28932909
std::vector<std::string> filenames;
2894-
SplitString(std::string(token), ' ', filenames);
2910+
SplitString(std::string(token), ' ', '\\', filenames);
28952911

28962912
if (filenames.empty()) {
28972913
if (warn) {

0 commit comments

Comments
 (0)