@@ -38,15 +38,41 @@ PYBIND11_MODULE(tinyobjloader, tobj_module)
3838 py::class_<attrib_t >(tobj_module, " attrib_t" )
3939 .def (py::init<>())
4040 .def_readonly (" vertices" , &attrib_t ::vertices)
41+ .def_readonly (" vertex_weights" , &attrib_t ::vertex_weights)
42+ .def_readonly (" skin_weights" , &attrib_t ::skin_weights)
43+ .def_readonly (" normals" , &attrib_t ::normals)
44+ .def_readonly (" texcoords" , &attrib_t ::texcoords)
45+ .def_readonly (" colors" , &attrib_t ::colors)
4146 .def (" numpy_vertices" , [] (attrib_t &instance) {
4247 auto ret = py::array_t <real_t >(instance.vertices .size ());
4348 py::buffer_info buf = ret.request ();
4449 memcpy (buf.ptr , instance.vertices .data (), instance.vertices .size () * sizeof (real_t ));
4550 return ret;
4651 })
47- .def_readonly (" normals" , &attrib_t ::normals)
48- .def_readonly (" texcoords" , &attrib_t ::texcoords)
49- .def_readonly (" colors" , &attrib_t ::colors)
52+ .def (" numpy_vertex_weights" , [] (attrib_t &instance) {
53+ auto ret = py::array_t <real_t >(instance.vertex_weights .size ());
54+ py::buffer_info buf = ret.request ();
55+ memcpy (buf.ptr , instance.vertex_weights .data (), instance.vertex_weights .size () * sizeof (real_t ));
56+ return ret;
57+ })
58+ .def (" numpy_normals" , [] (attrib_t &instance) {
59+ auto ret = py::array_t <real_t >(instance.normals .size ());
60+ py::buffer_info buf = ret.request ();
61+ memcpy (buf.ptr , instance.normals .data (), instance.normals .size () * sizeof (real_t ));
62+ return ret;
63+ })
64+ .def (" numpy_texcoords" , [] (attrib_t &instance) {
65+ auto ret = py::array_t <real_t >(instance.texcoords .size ());
66+ py::buffer_info buf = ret.request ();
67+ memcpy (buf.ptr , instance.texcoords .data (), instance.texcoords .size () * sizeof (real_t ));
68+ return ret;
69+ })
70+ .def (" numpy_colors" , [] (attrib_t &instance) {
71+ auto ret = py::array_t <real_t >(instance.colors .size ());
72+ py::buffer_info buf = ret.request ();
73+ memcpy (buf.ptr , instance.colors .data (), instance.colors .size () * sizeof (real_t ));
74+ return ret;
75+ })
5076 ;
5177
5278 py::class_<shape_t >(tobj_module, " shape_t" )
@@ -119,7 +145,7 @@ PYBIND11_MODULE(tinyobjloader, tobj_module)
119145 .def (" GetCustomParameter" , &material_t ::GetCustomParameter)
120146 ;
121147
122- py::class_<mesh_t >(tobj_module, " mesh_t" )
148+ py::class_<mesh_t >(tobj_module, " mesh_t" , py::buffer_protocol () )
123149 .def (py::init<>())
124150 .def_readonly (" num_face_vertices" , &mesh_t ::num_face_vertices)
125151 .def (" numpy_num_face_vertices" , [] (mesh_t &instance) {
@@ -128,6 +154,41 @@ PYBIND11_MODULE(tinyobjloader, tobj_module)
128154 memcpy (buf.ptr , instance.num_face_vertices .data (), instance.num_face_vertices .size () * sizeof (unsigned char ));
129155 return ret;
130156 })
157+ .def (" vertex_indices" , [](mesh_t &self) {
158+ // NOTE: we cannot use py::buffer_info and py:buffer as a return type.
159+ // py::memoriview is not suited for vertex indices usecase, since indices data may be used after
160+ // deleting C++ mesh_t object in Python world.
161+ //
162+ // So create a dedicated Python object(std::vector<int>)
163+
164+ std::vector<int > indices;
165+ indices.resize (self.indices .size ());
166+ for (size_t i = 0 ; i < self.indices .size (); i++) {
167+ indices[i] = self.indices [i].vertex_index ;
168+ }
169+
170+ return indices;
171+ })
172+ .def (" normal_indices" , [](mesh_t &self) {
173+
174+ std::vector<int > indices;
175+ indices.resize (self.indices .size ());
176+ for (size_t i = 0 ; i < self.indices .size (); i++) {
177+ indices[i] = self.indices [i].normal_index ;
178+ }
179+
180+ return indices;
181+ })
182+ .def (" texcoord_indices" , [](mesh_t &self) -> py::buffer_info {
183+
184+ std::vector<int > indices;
185+ indices.resize (self.indices .size ());
186+ for (size_t i = 0 ; i < self.indices .size (); i++) {
187+ indices[i] = self.indices [i].texcoord_index ;
188+ }
189+
190+ return indices;
191+ })
131192 .def_readonly (" indices" , &mesh_t ::indices)
132193 .def (" numpy_indices" , [] (mesh_t &instance) {
133194 // Flatten indexes. index_t is composed of 3 ints(vertex_index, normal_index, texcoord_index).
@@ -154,10 +215,34 @@ PYBIND11_MODULE(tinyobjloader, tobj_module)
154215 });
155216
156217 py::class_<lines_t >(tobj_module, " lines_t" )
157- .def (py::init<>());
218+ .def (py::init<>())
219+ .def_readonly (" indices" , &lines_t ::indices)
220+ .def_readonly (" num_line_vertices" , &lines_t ::num_line_vertices)
221+ ;
158222
159223 py::class_<points_t >(tobj_module, " points_t" )
160- .def (py::init<>());
224+ .def (py::init<>())
225+ .def_readonly (" indices" , &points_t ::indices)
226+ ;
161227
228+ py::class_<joint_and_weight_t >(tobj_module, " joint_and_weight_t" )
229+ .def (py::init<>())
230+ .def_readonly (" joint_id" , &joint_and_weight_t ::joint_id, " Joint index(NOTE: Joint info is provided externally, not from .obj" )
231+ .def_readonly (" weight" , &joint_and_weight_t ::weight, " Weight value(NOTE: weight is not normalized)" )
232+ ;
233+
234+ py::class_<skin_weight_t >(tobj_module, " skin_weight_t" )
235+ .def (py::init<>())
236+ .def_readonly (" vertex_id" , &skin_weight_t ::vertex_id)
237+ .def_readonly (" weightValues" , &skin_weight_t ::weightValues)
238+ ;
239+
240+ py::class_<tag_t >(tobj_module, " tag_t" )
241+ .def (py::init<>())
242+ .def_readonly (" name" , &tag_t ::name)
243+ .def_readonly (" intValues" , &tag_t ::intValues)
244+ .def_readonly (" floatValues" , &tag_t ::floatValues)
245+ .def_readonly (" stringValues" , &tag_t ::stringValues)
246+ ;
162247}
163248
0 commit comments