Skip to content

Commit 87b906c

Browse files
committed
Add parsing p line(point primtive).
1 parent 776344b commit 87b906c

File tree

8 files changed

+147
-28
lines changed

8 files changed

+147
-28
lines changed

README.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Old version is available `v0.9.x` branch https://github.com/syoyo/tinyobjloader/
2626

2727
## What's new
2828

29+
* 14 Apr, 2019 : Bump version v2.0.0 rc0. New C++ API and python bindings!(1.x API still exists for backward compatibility)
2930
* 20 Aug, 2016 : Bump version v1.0.0. New data structure and API!
3031

3132
### Old version
@@ -39,11 +40,11 @@ Previous old version is avaiable in `v0.9.x` branch.
3940
tinyobjloader can successfully load 6M triangles Rungholt scene.
4041
http://casual-effects.com/data/index.html
4142

42-
![](images/sanmugel.png)
43+
![](images/sanmugel.png)
4344

44-
* [examples/viewer/](examples/viewer) OpenGL .obj viewer
45-
* [examples/callback_api/](examples/callback_api/) Callback API example
46-
* [examples/voxelize/](examples/voxelize/) Voxelizer example
45+
* [examples/viewer/](examples/viewer) OpenGL .obj viewer
46+
* [examples/callback_api/](examples/callback_api/) Callback API example
47+
* [examples/voxelize/](examples/voxelize/) Voxelizer example
4748

4849
## Use case
4950

@@ -191,7 +192,7 @@ mesh_t::num_face_vertices => array of the number of vertices per face(e.g. 3 = t
191192
192193
| face[0] | face[1] | face[2] | | face[n-1] |
193194
+----+----+----+----+----+----+----+----+----+----+ +--------+--------+--------+
194-
| i0 | i1 | i2 | i3 | i4 | i5 | i6 | i7 | i8 | i9 | ... | i(n-3) | i(n-2) | i(n-1) |
195+
| i0 | i1 | i2 | i3 | i4 | i5 | i6 | i7 | i8 | i9 | ... | i(n-3) | i(n-2) | i(n-1) |
195196
+----+----+----+----+----+----+----+----+----+----+ +--------+--------+--------+
196197
197198
```
@@ -201,7 +202,7 @@ Note that when `triangulate` flas is true in `tinyobj::LoadObj()` argument, `num
201202
### float data type
202203

203204
TinyObjLoader now use `real_t` for floating point data type.
204-
Default is `float(32bit)`.
205+
Default is `float(32bit)`.
205206
You can enable `double(64bit)` precision by using `TINYOBJLOADER_USE_DOUBLE` define.
206207

207208
#### Example code
@@ -218,7 +219,7 @@ std::vector<tinyobj::material_t> materials;
218219
std::string warn;
219220
std::string err;
220221
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, inputfile.c_str());
221-
222+
222223
if (!err.empty()) { // `err` may contain warning message.
223224
std::cerr << err << std::endl;
224225
}

loader_example.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,10 @@ static void PrintInfo(const tinyobj::attrib_t& attrib,
139139
shapes[i].name.c_str());
140140
printf("Size of shape[%ld].mesh.indices: %lu\n", static_cast<long>(i),
141141
static_cast<unsigned long>(shapes[i].mesh.indices.size()));
142-
printf("Size of shape[%ld].path.indices: %lu\n", static_cast<long>(i),
143-
static_cast<unsigned long>(shapes[i].path.indices.size()));
142+
printf("Size of shape[%ld].lines.indices: %lu\n", static_cast<long>(i),
143+
static_cast<unsigned long>(shapes[i].lines.indices.size()));
144+
printf("Size of shape[%ld].points.indices: %lu\n", static_cast<long>(i),
145+
static_cast<unsigned long>(shapes[i].points.indices.size()));
144146

145147
size_t index_offset = 0;
146148

models/points-prim.obj

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
mtllib cube.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 g0
14+
usemtl white
15+
p 1 2 3 4 5 6 7 8

python/bindings.cc

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace py = pybind11;
88

99
using namespace tinyobj;
1010

11-
PYBIND11_MODULE(tinyobjloader, tobj_module)
11+
PYBIND11_MODULE(tinyobj, tobj_module)
1212
{
1313
tobj_module.doc() = "Python bindings for TinyObjLoader.";
1414

@@ -30,11 +30,25 @@ PYBIND11_MODULE(tinyobjloader, tobj_module)
3030
.def_property_readonly("vertices", &attrib_t::GetVertices);
3131

3232
py::class_<shape_t>(tobj_module, "shape_t")
33-
.def(py::init<>());
33+
.def(py::init<>())
34+
.def_readonly("name", &shape_t::name)
35+
.def_readonly("mesh", &shape_t::mesh)
36+
.def_readonly("lines", &shape_t::lines)
37+
.def_readonly("points", &shape_t::points);
3438

39+
// TODO(syoyo): write more bindings
3540
py::class_<material_t>(tobj_module, "material_t")
3641
.def(py::init<>());
3742

43+
py::class_<mesh_t>(tobj_module, "mesh_t")
44+
.def(py::init<>());
45+
46+
py::class_<lines_t>(tobj_module, "lines_t")
47+
.def(py::init<>());
48+
49+
py::class_<points_t>(tobj_module, "points_t")
50+
.def(py::init<>());
51+
3852
py::class_<ObjReaderConfig>(tobj_module, "ObjReaderConfig")
3953
.def(py::init<>());
4054

python/sample.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
import sys
2-
import tinyobjloader
2+
import tinyobj
33

44
filename = "../models/cornell_box.obj";
55

6-
config = tinyobjloader.ObjLoaderConfig()
6+
config = tinyobj.ObjReaderConfig()
77

8-
loader = tinyobjloader.ObjLoader()
8+
reader = tinyobj.ObjReader()
99

10-
ret = loader.Load(filename, config)
10+
ret = reader.ParseFromFile(filename, config)
1111

1212
if ret == False:
1313
print("Failed to load : ", filename)
1414
sys.exit(-1)
1515

16-
attrib = loader.GetAttrib()
16+
attrib = reader.GetAttrib()
1717
print("attrib.vertices = ", len(attrib.vertices))
1818
for v in attrib.vertices:
1919
print(v)
20+
21+
# TODO(syoyo): print mesh
22+
for shape in reader.GetShapes():
23+
print(shape.name)
24+
print(len(shape.mesh.indices))

python/setup.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
from distutils.core import setup, Extension
22

33

4-
m = Extension('tinyobjloader',
4+
# `../tiny_obj_loader.cc` contains implementation of tiny_obj_loader.
5+
m = Extension('tinyobj',
56
sources = ['bindings.cc', '../tiny_obj_loader.cc'],
67
extra_compile_args=['-std=c++11'],
78
include_dirs = ['../', '../pybind11/include']
89
)
910

1011

11-
setup (name = 'tinyobjloader',
12+
setup (name = 'tinyobj',
1213
version = '0.1',
1314
description = 'Python module for tinyobjloader',
1415
ext_modules = [m])

tests/tester.cc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,29 @@ TEST_CASE("line-primitive", "[line]") {
961961
REQUIRE(2 == shapes[0].lines.num_line_vertices.size());
962962
}
963963

964+
TEST_CASE("points-primitive", "[points]") {
965+
tinyobj::attrib_t attrib;
966+
std::vector<tinyobj::shape_t> shapes;
967+
std::vector<tinyobj::material_t> materials;
968+
969+
std::string warn;
970+
std::string err;
971+
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
972+
"../models/points-prim.obj", gMtlBasePath);
973+
974+
if (!warn.empty()) {
975+
std::cout << "WARN: " << warn << std::endl;
976+
}
977+
978+
if (!err.empty()) {
979+
std::cerr << "ERR: " << err << std::endl;
980+
}
981+
982+
REQUIRE(true == ret);
983+
REQUIRE(1 == shapes.size());
984+
REQUIRE(8 == shapes[0].points.indices.size());
985+
}
986+
964987
TEST_CASE("multiple-group-names", "[group]") {
965988
tinyobj::attrib_t attrib;
966989
std::vector<tinyobj::shape_t> shapes;

tiny_obj_loader.h

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ THE SOFTWARE.
2424

2525
//
2626
// version 2.0.0 : Add new object oriented API. 1.x API is still provided.
27+
// * Support line primitive.
28+
// * Support points primitive.
2729
// version 1.4.0 : Modifed ParseTextureNameAndOption API
2830
// version 1.3.1 : Make ParseTextureNameAndOption API public
2931
// version 1.3.0 : Separate warning and error message(breaking API of LoadObj)
@@ -410,13 +412,20 @@ class ObjReader {
410412
///
411413
/// Load .obj and .mtl from a file.
412414
///
415+
/// @param[in] filename wavefront .obj filename
416+
/// @param[in] config Reader configuration
417+
///
413418
bool ParseFromFile(const std::string &filename, const ObjReaderConfig &config);
414419

415420
///
416421
/// Parse .obj from a text string.
417422
/// Need to supply .mtl text string by `mtl_text`.
418423
/// This function ignores `mtllib` line in .obj text.
419424
///
425+
/// @param[in] obj_text wavefront .obj filename
426+
/// @param[in] mtl_text wavefront .mtl filename
427+
/// @param[in] config Reader configuration
428+
///
420429
bool ParseFromString(const std::string &obj_text, const std::string &mtl_text, const ObjReaderConfig &config);
421430

422431
///
@@ -551,15 +560,15 @@ struct face_t {
551560
};
552561

553562
// Internal data structure for line representation
554-
struct line_t {
563+
struct __line_t {
555564
// l v1/vt1 v2/vt2 ...
556565
// In the specification, line primitrive does not have normal index, but
557566
// TinyObjLoader allow it
558567
std::vector<vertex_index_t> vertex_indices;
559568
};
560569

561-
// Internal data structure for pint representation
562-
struct point_t {
570+
// Internal data structure for points representation
571+
struct __points_t {
563572
// p v1 v2 ...
564573
// In the specification, point primitrive does not have normal index and
565574
// texture coord index, but TinyObjLoader allow it.
@@ -580,20 +589,20 @@ struct obj_shape {
580589
};
581590

582591
//
583-
// Manages group of primitives(face, line, point, ...)
592+
// Manages group of primitives(face, line, points, ...)
584593
struct PrimGroup {
585594
std::vector<face_t> faceGroup;
586-
std::vector<line_t> lineGroup;
587-
std::vector<point_t> pointGroup;
595+
std::vector<__line_t> lineGroup;
596+
std::vector<__points_t> pointsGroup;
588597

589598
void clear() {
590599
faceGroup.clear();
591600
lineGroup.clear();
592-
pointGroup.clear();
601+
pointsGroup.clear();
593602
}
594603

595604
bool IsEmpty() const {
596-
return faceGroup.empty() && lineGroup.empty() && pointGroup.empty();
605+
return faceGroup.empty() && lineGroup.empty() && pointsGroup.empty();
597606
}
598607

599608
// TODO(syoyo): bspline, surface, ...
@@ -1494,6 +1503,24 @@ static bool exportGroupsToShape(shape_t *shape, const PrimGroup &prim_group,
14941503
}
14951504
}
14961505

1506+
// points
1507+
if (!prim_group.pointsGroup.empty()) {
1508+
// Flatten & convert indices
1509+
for (size_t i = 0; i < prim_group.pointsGroup.size(); i++) {
1510+
for (size_t j = 0; j < prim_group.pointsGroup[i].vertex_indices.size(); j++) {
1511+
1512+
const vertex_index_t &vi = prim_group.pointsGroup[i].vertex_indices[j];
1513+
1514+
index_t idx;
1515+
idx.vertex_index = vi.v_idx;
1516+
idx.normal_index = vi.vn_idx;
1517+
idx.texcoord_index = vi.vt_idx;
1518+
1519+
shape->points.indices.push_back(idx);
1520+
}
1521+
}
1522+
}
1523+
14971524
return true;
14981525
}
14991526

@@ -2077,7 +2104,7 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
20772104
if (token[0] == 'l' && IS_SPACE((token[1]))) {
20782105
token += 2;
20792106

2080-
line_t line;
2107+
__line_t line;
20812108

20822109
while (!IS_NEW_LINE(token[0])) {
20832110
vertex_index_t vi;
@@ -2086,7 +2113,7 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
20862113
static_cast<int>(vt.size() / 2), &vi)) {
20872114
if (err) {
20882115
std::stringstream ss;
2089-
ss << "Failed parse `l' line(e.g. zero value for face index. line "
2116+
ss << "Failed parse `l' line(e.g. zero value for vertex index. line "
20902117
<< line_num << ".)\n";
20912118
(*err) += ss.str();
20922119
}
@@ -2104,6 +2131,37 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
21042131
continue;
21052132
}
21062133

2134+
// points
2135+
if (token[0] == 'p' && IS_SPACE((token[1]))) {
2136+
token += 2;
2137+
2138+
__points_t pts;
2139+
2140+
while (!IS_NEW_LINE(token[0])) {
2141+
vertex_index_t vi;
2142+
if (!parseTriple(&token, static_cast<int>(v.size() / 3),
2143+
static_cast<int>(vn.size() / 3),
2144+
static_cast<int>(vt.size() / 2), &vi)) {
2145+
if (err) {
2146+
std::stringstream ss;
2147+
ss << "Failed parse `p' line(e.g. zero value for vertex index. line "
2148+
<< line_num << ".)\n";
2149+
(*err) += ss.str();
2150+
}
2151+
return false;
2152+
}
2153+
2154+
pts.vertex_indices.push_back(vi);
2155+
2156+
size_t n = strspn(token, " \t\r");
2157+
token += n;
2158+
}
2159+
2160+
prim_group.pointsGroup.push_back(pts);
2161+
2162+
continue;
2163+
}
2164+
21072165
// face
21082166
if (token[0] == 'f' && IS_SPACE((token[1]))) {
21092167
token += 2;

0 commit comments

Comments
 (0)