Skip to content

Commit f9a2915

Browse files
committed
Update copyright year.
Implement basic python binding using pybind11.
1 parent 007b110 commit f9a2915

File tree

6 files changed

+204
-13
lines changed

6 files changed

+204
-13
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The MIT License (MIT)
22

3-
Copyright (c) 2012-2016 Syoyo Fujita and many contributors.
3+
Copyright (c) 2012-2019 Syoyo Fujita and many contributors.
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

python/bindings.cc

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
#include "pybind11/pybind11.h"
22
#include "pybind11/stl.h"
3+
#include "pybind11/numpy.h"
34

4-
#include "tiny_obj_loader.h"
5+
// Use double precision for better python integration.
6+
#define TINYOBJLOADER_USE_DOUBLE
57

8+
// define some helper functions for pybind11
9+
#define TINY_OBJ_LOADER_PYTHON_BINDING
10+
#include "tiny_obj_loader.h"
611

712
namespace py = pybind11;
813

@@ -31,7 +36,11 @@ PYBIND11_MODULE(tinyobj, tobj_module)
3136

3237
py::class_<attrib_t>(tobj_module, "attrib_t")
3338
.def(py::init<>())
34-
.def_property_readonly("vertices", &attrib_t::GetVertices);
39+
.def_readonly("vertices", &attrib_t::vertices)
40+
.def_readonly("normals", &attrib_t::normals)
41+
.def_readonly("texcoords", &attrib_t::texcoords)
42+
.def_readonly("colors", &attrib_t::colors)
43+
;
3544

3645
py::class_<shape_t>(tobj_module, "shape_t")
3746
.def(py::init<>())
@@ -47,9 +56,61 @@ PYBIND11_MODULE(tinyobj, tobj_module)
4756
.def_readwrite("texcoord_index", &index_t::texcoord_index)
4857
;
4958

50-
// TODO(syoyo): write more bindings
59+
// NOTE(syoyo): It looks it is rather difficult to expose assignment by array index to
60+
// python world for array variable.
61+
// For example following python scripting does not work well.
62+
//
63+
// print(mat.diffuse)
64+
// >>> [0.1, 0.2, 0.3]
65+
// mat.diffuse[1] = 1.0
66+
// print(mat.diffuse)
67+
// >>> [0.1, 0.2, 0.3] # No modification
68+
//
69+
// https://github.com/pybind/pybind11/issues/1134
70+
//
71+
// so, we need to update array variable like this:
72+
//
73+
// diffuse = mat.diffuse
74+
// diffuse[1] = 1.0
75+
// mat.diffuse = diffuse
76+
//
5177
py::class_<material_t>(tobj_module, "material_t")
52-
.def(py::init<>());
78+
.def(py::init<>())
79+
.def_readwrite("name", &material_t::name)
80+
.def_property("ambient", &material_t::GetAmbient, &material_t::SetAmbient)
81+
.def_property("diffuse", &material_t::GetDiffuse, &material_t::SetDiffuse)
82+
.def_property("specular", &material_t::GetSpecular, &material_t::SetSpecular)
83+
.def_property("transmittance", &material_t::GetTransmittance, &material_t::SetTransmittance)
84+
.def_readwrite("shininess", &material_t::shininess)
85+
.def_readwrite("ior", &material_t::ior)
86+
.def_readwrite("dissolve", &material_t::dissolve)
87+
.def_readwrite("illum", &material_t::illum)
88+
.def_readwrite("ambient_texname", &material_t::ambient_texname)
89+
.def_readwrite("diffuse_texname", &material_t::diffuse_texname)
90+
.def_readwrite("specular_texname", &material_t::specular_texname)
91+
.def_readwrite("specular_highlight_texname", &material_t::specular_highlight_texname)
92+
.def_readwrite("bump_texname", &material_t::bump_texname)
93+
.def_readwrite("displacement_texname", &material_t::displacement_texname)
94+
.def_readwrite("alpha_texname", &material_t::alpha_texname)
95+
.def_readwrite("reflection_texname", &material_t::reflection_texname)
96+
// TODO(syoyo): Expose texture parameter
97+
// PBR
98+
.def_readwrite("roughness", &material_t::roughness)
99+
.def_readwrite("metallic", &material_t::metallic)
100+
.def_readwrite("sheen", &material_t::sheen)
101+
.def_readwrite("clearcoat_thickness", &material_t::clearcoat_thickness)
102+
.def_readwrite("clearcoat_roughness", &material_t::clearcoat_roughness)
103+
.def_readwrite("anisotropy", &material_t::anisotropy)
104+
.def_readwrite("anisotropy_rotation", &material_t::anisotropy_rotation)
105+
106+
.def_readwrite("roughness_texname", &material_t::roughness_texname)
107+
.def_readwrite("metallic_texname", &material_t::metallic_texname)
108+
.def_readwrite("sheen_texname", &material_t::sheen_texname)
109+
.def_readwrite("emissive_texname", &material_t::emissive_texname)
110+
.def_readwrite("normal_texname", &material_t::normal_texname)
111+
112+
.def("GetCustomParameter", &material_t::GetCustomParameter)
113+
;
53114

54115
py::class_<mesh_t>(tobj_module, "mesh_t")
55116
.def(py::init<>())

python/sample.py

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,54 @@
1818
print("Failed to load : ", filename)
1919
sys.exit(-1)
2020

21+
print("Warn:", reader.Warning())
22+
print("Err:", reader.Error())
23+
2124
attrib = reader.GetAttrib()
2225
print("attrib.vertices = ", len(attrib.vertices))
23-
for v in attrib.vertices:
24-
print(v)
26+
print("attrib.normals = ", len(attrib.normals))
27+
print("attrib.texcoords = ", len(attrib.texcoords))
28+
29+
# vertex data must be `xyzxyzxyz...`
30+
assert len(attrib.vertices) % 3 == 0
31+
32+
# normal data must be `xyzxyzxyz...`
33+
assert len(attrib.normals) % 3 == 0
34+
35+
# texcoords data must be `uvuvuv...`
36+
assert len(attrib.texcoords) % 2 == 0
37+
38+
for (i, v) in enumerate(attrib.vertices):
39+
print("v[{}] = {}".format(i, v))
40+
41+
for (i, v) in enumerate(attrib.normals):
42+
print("vn[{}] = {}".format(i, v))
43+
44+
for (i, v) in enumerate(attrib.texcoords):
45+
print("vt[{}] = {}".format(i, t))
46+
47+
materials = reader.GetMaterials()
48+
print("Num materials: ", len(materials))
49+
for m in materials:
50+
print(m.name)
51+
print(m.diffuse)
52+
print(m.diffuse_texname)
53+
# Partial update(array indexing) does not work
54+
# m.diffuse[1] = 1.0
55+
56+
# Update with full object assignment works
57+
m.diffuse = [1, 2, 3]
58+
print(m.diffuse)
59+
60+
#print(m.shininess)
61+
#print(m.illum)
2562

26-
# TODO(syoyo): print mesh
27-
for shape in reader.GetShapes():
63+
shapes = reader.GetShapes()
64+
print("Num shapes: ", len(shapes))
65+
for shape in shapes:
2866
print(shape.name)
29-
for idx in shape.mesh.indices:
30-
print("v_idx ", idx.vertex_index)
67+
print("num_indices = {}".format(len(shape.mesh.indices)))
68+
for (i, idx) in enumerate(shape.mesh.indices):
69+
print("[{}] v_idx {}".format(i, idx.vertex_index))
70+
print("[{}] vn_idx {}".format(i, idx.normal_index))
71+
print("[{}] vt_idx {}".format(i, idx.texcoord_index))

python/setup.py

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

33

4-
# `../tiny_obj_loader.cc` contains implementation of tiny_obj_loader.
4+
# `tiny_obj_loader.cc` contains implementation of tiny_obj_loader.
55
m = Extension('tinyobj',
6-
sources = ['bindings.cc', '../tiny_obj_loader.cc'],
6+
sources = ['bindings.cc', 'tiny_obj_loader.cc'],
77
extra_compile_args=['-std=c++11'],
88
include_dirs = ['../', '../pybind11/include']
99
)

python/tiny_obj_loader.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Use double precision for better python integration.
2+
// Need also define this in `binding.cc`(and all compilation units)
3+
#define TINYOBJLOADER_USE_DOUBLE
4+
5+
#define TINYOBJLOADER_IMPLEMENTATION
6+
#include "tiny_obj_loader.h"

tiny_obj_loader.h

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,89 @@ typedef struct {
225225
int pad2;
226226

227227
std::map<std::string, std::string> unknown_parameter;
228+
229+
#ifdef TINY_OBJ_LOADER_PYTHON_BINDING
230+
// For pybind11
231+
std::array<double, 3> GetDiffuse() {
232+
std::array<double, 3> values;
233+
values[0] = double(diffuse[0]);
234+
values[1] = double(diffuse[1]);
235+
values[2] = double(diffuse[2]);
236+
237+
return values;
238+
}
239+
240+
std::array<double, 3> GetSpecular() {
241+
std::array<double, 3> values;
242+
values[0] = double(specular[0]);
243+
values[1] = double(specular[1]);
244+
values[2] = double(specular[2]);
245+
246+
return values;
247+
}
248+
249+
std::array<double, 3> GetTransmittance() {
250+
std::array<double, 3> values;
251+
values[0] = double(transmittance[0]);
252+
values[1] = double(transmittance[1]);
253+
values[2] = double(transmittance[2]);
254+
255+
return values;
256+
}
257+
258+
std::array<double, 3> GetEmission() {
259+
std::array<double, 3> values;
260+
values[0] = double(emission[0]);
261+
values[1] = double(emission[1]);
262+
values[2] = double(emission[2]);
263+
264+
return values;
265+
}
266+
267+
std::array<double, 3> GetAmbient() {
268+
std::array<double, 3> values;
269+
values[0] = double(ambient[0]);
270+
values[1] = double(ambient[1]);
271+
values[2] = double(ambient[2]);
272+
273+
return values;
274+
}
275+
276+
void SetDiffuse(std::array<double, 3> &a) {
277+
diffuse[0] = real_t(a[0]);
278+
diffuse[1] = real_t(a[1]);
279+
diffuse[2] = real_t(a[2]);
280+
}
281+
282+
void SetAmbient(std::array<double, 3> &a) {
283+
ambient[0] = real_t(a[0]);
284+
ambient[1] = real_t(a[1]);
285+
ambient[2] = real_t(a[2]);
286+
}
287+
288+
void SetSpecular(std::array<double, 3> &a) {
289+
specular[0] = real_t(a[0]);
290+
specular[1] = real_t(a[1]);
291+
specular[2] = real_t(a[2]);
292+
}
293+
294+
void SetTransmittance(std::array<double, 3> &a) {
295+
transmittance[0] = real_t(a[0]);
296+
transmittance[1] = real_t(a[1]);
297+
transmittance[2] = real_t(a[2]);
298+
}
299+
300+
std::string GetCustomParameter(const std::string &key) {
301+
std::map<std::string, std::string>::const_iterator it = unknown_parameter.find(key);
302+
303+
if (it != unknown_parameter.end()) {
304+
return it->second;
305+
}
306+
return std::string();
307+
}
308+
309+
#endif
310+
228311
} material_t;
229312

230313
typedef struct {

0 commit comments

Comments
 (0)