aboutsummaryrefslogtreecommitdiff
path: root/python/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'python/main.cpp')
-rw-r--r--python/main.cpp206
1 files changed, 206 insertions, 0 deletions
diff --git a/python/main.cpp b/python/main.cpp
new file mode 100644
index 0000000..4f1d0e0
--- /dev/null
+++ b/python/main.cpp
@@ -0,0 +1,206 @@
+// python2/3 module for tinyobjloader
+//
+// usage:
+// import tinyobjloader as tol
+// model = tol.LoadObj(name)
+// print(model["shapes"])
+// print(model["materials"]
+// note:
+// `shape.mesh.index_t` is represented as flattened array: (vertex_index, normal_index, texcoord_index) * num_faces
+
+#include <Python.h>
+#include <vector>
+#include "../tiny_obj_loader.h"
+
+typedef std::vector<double> vectd;
+typedef std::vector<int> vecti;
+
+PyObject* pyTupleFromfloat3(float array[3]) {
+ int i;
+ PyObject* tuple = PyTuple_New(3);
+
+ for (i = 0; i <= 2; i++) {
+ PyTuple_SetItem(tuple, i, PyFloat_FromDouble(array[i]));
+ }
+
+ return tuple;
+}
+
+extern "C" {
+
+static PyObject* pyLoadObj(PyObject* self, PyObject* args) {
+ PyObject *rtndict, *pyshapes, *pymaterials, *pymaterial_indices, *attribobj, *current, *meshobj;
+
+ char const* current_name;
+ char const* filename;
+ vectd vect;
+ std::vector<tinyobj::index_t> indices;
+ std::vector<unsigned char> face_verts;
+
+ tinyobj::attrib_t attrib;
+ std::vector<tinyobj::shape_t> shapes;
+ std::vector<tinyobj::material_t> materials;
+
+ if (!PyArg_ParseTuple(args, "s", &filename)) return NULL;
+
+ std::string err;
+ tinyobj::LoadObj(&attrib, &shapes, &materials, &err, filename);
+
+ pyshapes = PyDict_New();
+ pymaterials = PyDict_New();
+ pymaterial_indices = PyList_New(0);
+ rtndict = PyDict_New();
+
+ attribobj = PyDict_New();
+
+ for (int i = 0; i <= 2; i++) {
+ current = PyList_New(0);
+
+ switch (i) {
+ case 0:
+ current_name = "vertices";
+ vect = vectd(attrib.vertices.begin(), attrib.vertices.end());
+ break;
+ case 1:
+ current_name = "normals";
+ vect = vectd(attrib.normals.begin(), attrib.normals.end());
+ break;
+ case 2:
+ current_name = "texcoords";
+ vect = vectd(attrib.texcoords.begin(), attrib.texcoords.end());
+ break;
+ }
+
+ for (vectd::iterator it = vect.begin(); it != vect.end(); it++) {
+ PyList_Insert(current, it - vect.begin(), PyFloat_FromDouble(*it));
+ }
+
+ PyDict_SetItemString(attribobj, current_name, current);
+ }
+
+ for (std::vector<tinyobj::shape_t>::iterator shape = shapes.begin();
+ shape != shapes.end(); shape++) {
+ meshobj = PyDict_New();
+ tinyobj::mesh_t cm = (*shape).mesh;
+
+ {
+ current = PyList_New(0);
+
+ for (size_t i = 0; i < cm.indices.size(); i++) {
+ // Flatten index array: v_idx, vn_idx, vt_idx, v_idx, vn_idx, vt_idx,
+ // ...
+ PyList_Insert(current, 3 * i + 0,
+ PyLong_FromLong(cm.indices[i].vertex_index));
+ PyList_Insert(current, 3 * i + 1,
+ PyLong_FromLong(cm.indices[i].normal_index));
+ PyList_Insert(current, 3 * i + 2,
+ PyLong_FromLong(cm.indices[i].texcoord_index));
+ }
+
+ PyDict_SetItemString(meshobj, "indices", current);
+ }
+
+ {
+ current = PyList_New(0);
+
+ for (size_t i = 0; i < cm.num_face_vertices.size(); i++) {
+ // Widen data type to long.
+ PyList_Insert(current, i, PyLong_FromLong(cm.num_face_vertices[i]));
+ }
+
+ PyDict_SetItemString(meshobj, "num_face_vertices", current);
+ }
+
+ {
+ current = PyList_New(0);
+
+ for (size_t i = 0; i < cm.material_ids.size(); i++) {
+ PyList_Insert(current, i, PyLong_FromLong(cm.material_ids[i]));
+ }
+
+ PyDict_SetItemString(meshobj, "material_ids", current);
+ }
+
+ PyDict_SetItemString(pyshapes, (*shape).name.c_str(), meshobj);
+ }
+
+ for (std::vector<tinyobj::material_t>::iterator mat = materials.begin();
+ mat != materials.end(); mat++) {
+ PyObject* matobj = PyDict_New();
+ PyObject* unknown_parameter = PyDict_New();
+
+ for (std::map<std::string, std::string>::iterator p =
+ mat->unknown_parameter.begin();
+ p != mat->unknown_parameter.end(); ++p) {
+ PyDict_SetItemString(unknown_parameter, p->first.c_str(),
+ PyUnicode_FromString(p->second.c_str()));
+ }
+
+ PyDict_SetItemString(matobj, "shininess",
+ PyFloat_FromDouble(mat->shininess));
+ PyDict_SetItemString(matobj, "ior", PyFloat_FromDouble(mat->ior));
+ PyDict_SetItemString(matobj, "dissolve",
+ PyFloat_FromDouble(mat->dissolve));
+ PyDict_SetItemString(matobj, "illum", PyLong_FromLong(mat->illum));
+ PyDict_SetItemString(matobj, "ambient_texname",
+ PyUnicode_FromString(mat->ambient_texname.c_str()));
+ PyDict_SetItemString(matobj, "diffuse_texname",
+ PyUnicode_FromString(mat->diffuse_texname.c_str()));
+ PyDict_SetItemString(matobj, "specular_texname",
+ PyUnicode_FromString(mat->specular_texname.c_str()));
+ PyDict_SetItemString(
+ matobj, "specular_highlight_texname",
+ PyUnicode_FromString(mat->specular_highlight_texname.c_str()));
+ PyDict_SetItemString(matobj, "bump_texname",
+ PyUnicode_FromString(mat->bump_texname.c_str()));
+ PyDict_SetItemString(
+ matobj, "displacement_texname",
+ PyUnicode_FromString(mat->displacement_texname.c_str()));
+ PyDict_SetItemString(matobj, "alpha_texname",
+ PyUnicode_FromString(mat->alpha_texname.c_str()));
+ PyDict_SetItemString(matobj, "ambient", pyTupleFromfloat3(mat->ambient));
+ PyDict_SetItemString(matobj, "diffuse", pyTupleFromfloat3(mat->diffuse));
+ PyDict_SetItemString(matobj, "specular",
+ pyTupleFromfloat3(mat->specular));
+ PyDict_SetItemString(matobj, "transmittance",
+ pyTupleFromfloat3(mat->transmittance));
+ PyDict_SetItemString(matobj, "emission",
+ pyTupleFromfloat3(mat->emission));
+ PyDict_SetItemString(matobj, "unknown_parameter", unknown_parameter);
+
+ PyDict_SetItemString(pymaterials, mat->name.c_str(), matobj);
+ PyList_Append(pymaterial_indices, PyUnicode_FromString(mat->name.c_str()));
+ }
+
+ PyDict_SetItemString(rtndict, "shapes", pyshapes);
+ PyDict_SetItemString(rtndict, "materials", pymaterials);
+ PyDict_SetItemString(rtndict, "material_indices", pymaterial_indices);
+ PyDict_SetItemString(rtndict, "attribs", attribobj);
+
+ return rtndict;
+}
+
+static PyMethodDef mMethods[] = {
+
+ {"LoadObj", pyLoadObj, METH_VARARGS}, {NULL, NULL, 0, NULL}
+
+};
+
+#if PY_MAJOR_VERSION >= 3
+
+static struct PyModuleDef moduledef = {PyModuleDef_HEAD_INIT, "tinyobjloader",
+ NULL, -1, mMethods};
+
+PyMODINIT_FUNC PyInit_tinyobjloader(void) {
+ return PyModule_Create(&moduledef);
+}
+
+#else
+
+PyMODINIT_FUNC inittinyobjloader(void) {
+ Py_InitModule3("tinyobjloader", mMethods, NULL);
+}
+
+#endif // PY_MAJOR_VERSION >= 3
+
+}