+///////////////////////////////////////////////////////////////////////////////
+// meshio::pmd::IO::each_vertex
+///////////////////////////////////////////////////////////////////////////////
+%inline %{
+//! Thin wrapper for ONLY the increment operator
+void _vertices_incr(std::vector<meshio::pmd::Vertex>::const_iterator* iter)
+{
+ // increment the iterator
+ ++(*iter);
+}
+%}
+
+%extend meshio::pmd::IO {
+%pythoncode {
+ def each_vertex(self):
+ iter = self._beginVertices()
+ while True:
+ vertex = self._dereferenceVertex(iter)
+ if vertex:
+ _vertices_incr(iter)
+ yield vertex
+ else:
+ break
+%}
+
+//! get the first element in the vector
+std::vector<meshio::pmd::Vertex>::const_iterator* _beginVertices()
+{
+ return new std::vector<meshio::pmd::Vertex>::const_iterator(
+ ($self->vertices.begin()));
+}
+
+//! dereference the iterator; return NULL if at the end
+const meshio::pmd::Vertex* _dereferenceVertex(
+ const std::vector<meshio::pmd::Vertex>::const_iterator* iter )
+{
+ // if at the end, return NULL
+ if (*iter == ($self)->vertices.end() ) {
+ return NULL;
+ }
+ // otherwise, return the face to which this iterator points
+ return &(**iter);
+}
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// addVertex
+// addMaterial
+// addBone
+// addMorph
+///////////////////////////////////////////////////////////////////////////////
+%extend meshio::pmd::IO {
+
+meshio::pmd::Vertex * addVertex()
+{
+ $self->vertices.push_back(meshio::pmd::Vertex());
+ return &($self->vertices.back());
+}
+
+meshio::pmd::Material *addMaterial()
+{
+ $self->materials.push_back(new meshio::pmd::Material);
+ return $self->materials.back();
+}
+
+meshio::pmd::Bone *addBone()
+{
+ $self->bones.push_back(meshio::pmd::Bone());
+ return &($self->bones.back());
+}
+
+meshio::pmd::Morph *addMorph()
+{
+ $self->morph_list.push_back(meshio::pmd::Morph());
+ return &($self->morph_list.back());
+}
+
+meshio::pmd::IK *addIK()
+{
+ $self->ik_list.push_back(meshio::pmd::IK());
+ return &($self->ik_list.back());
+}
+
+void addBoneDisplay(unsigned short bone_index, unsigned char display_index)
+{
+ $self->bone_display_list.push_back(
+ std::make_pair(bone_index, display_index));
+}
+
+meshio::pmd::BoneDisplayName *addBoneDisplayName()
+{
+ $self->bone_display_name_list.push_back(meshio::pmd::BoneDisplayName());
+ return &($self->bone_display_name_list.back());
+}
+
+meshio::pmd::ToonTexture *getToonTexture(int index)
+{
+ return &($self->toon_textures[index]);
+}
+
+}
+