diff options
Diffstat (limited to 'python/main.cpp')
-rw-r--r-- | python/main.cpp | 206 |
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 + +} |