OSDN Git Service

頂点カラー付きplyファイルの読み込みに対応
authorqw_fuku <fkhideaki@gmail.com>
Sun, 17 Jul 2016 04:47:41 +0000 (13:47 +0900)
committerqw_fuku <fkhideaki@gmail.com>
Sun, 17 Jul 2016 04:47:41 +0000 (13:47 +0900)
Src/LibQtGeoViewerCore/Format/Ply/PLYHeader.cpp
Src/LibQtGeoViewerCore/Format/Ply/PLYHeader.h
Src/LibQtGeoViewerCore/Format/Ply/PLYMesh.cpp
Src/LibQtGeoViewerCore/Format/Ply/PLYMesh.h
Src/LibQtGeoViewerCore/Format/Ply/Plyloader.cpp

index 9dc0063..19c71f9 100644 (file)
@@ -18,6 +18,9 @@ void VertPropIdx::Clear(void)
        nX = -1;
        nY = -1;
        nZ = -1;
+       cR = -1;
+       cG = -1;
+       cB = -1;
 }
 
 int VertPropIdx::GetMaxPropIdx(void) const
@@ -29,6 +32,9 @@ int VertPropIdx::GetMaxPropIdx(void) const
        max_vprop = (std::max)(max_vprop, nX);
        max_vprop = (std::max)(max_vprop, nY);
        max_vprop = (std::max)(max_vprop, nZ);
+       max_vprop = (std::max)(max_vprop, cR);
+       max_vprop = (std::max)(max_vprop, cG);
+       max_vprop = (std::max)(max_vprop, cB);
        max_vprop += 1;
 
        return max_vprop;
@@ -44,7 +50,7 @@ void PlyHeader::Clear(void)
 {
        m_FormatType.clear();
 
-       m_NumVerts      = 0;
+       m_NumVerts = 0;
        m_VPI.Clear();
 
        m_NumFaces = 0;
@@ -67,6 +73,16 @@ bool PlyHeader::HasNormal(void) const
        return (bx && by && bz);
 }
 
+bool PlyHeader::HasCol(void) const
+{
+       bool br = (m_VPI.cR != -1);
+       bool bg = (m_VPI.cG != -1);
+       bool bb = (m_VPI.cB != -1);
+
+       assert(br == bg && bg == bb);
+       return (br && bg && bb);
+}
+
 
 }
 }
index ab86de9..429d5dc 100644 (file)
@@ -23,6 +23,9 @@ public:
        int nX;
        int nY;
        int nZ;
+       int cR;
+       int cG;
+       int cB;
 };
 
 
@@ -34,6 +37,7 @@ public:
 
        int GetMaxPropIdx(void) const;
        bool HasNormal(void) const;
+       bool HasCol(void) const;
 
 public:
        std::string m_FormatType;
index 335353d..5bc5e11 100644 (file)
@@ -48,6 +48,7 @@ void PlyMesh::Clear(void)
        m_Header.Clear();
        m_Verts.clear();
        m_Normals.clear();
+       m_Col.clear();
        m_Faces.clear();
 }
 
@@ -119,6 +120,12 @@ bool PlyMesh::ReadHeader(std::istream& ist)
                                        m_Header.m_VPI.nY = VertPropCount;
                                else if(type == "nz")
                                        m_Header.m_VPI.nZ = VertPropCount;
+                               else if(type == "red")
+                                       m_Header.m_VPI.cR = VertPropCount;
+                               else if(type == "green")
+                                       m_Header.m_VPI.cG = VertPropCount;
+                               else if(type == "blue")
+                                       m_Header.m_VPI.cB = VertPropCount;
 
                                VertPropCount++;
                                continue;
@@ -169,34 +176,39 @@ bool PlyMesh::CheckHeader(const std::string& line, const char* header) const
 
 bool PlyMesh::ReadBinary( std::istream& ist , bool is_little_endian)
 {
-       bool has_norm = m_Header.HasNormal();
+       bool hasNorm = m_Header.HasNormal();
+       bool hasCol = m_Header.HasCol();
 
        m_Verts.resize(m_Header.m_NumVerts);
-       if(has_norm)
+       if (hasNorm)
                m_Normals.resize(m_Header.m_NumVerts);
+       if (hasCol)
+               m_Col.resize(m_Header.m_NumVerts);
 
-       for(size_t i = 0; i < m_Header.m_NumVerts; ++i)
+       for (size_t i = 0; i < m_Header.m_NumVerts; ++i)
        {
                ist.read((char*)m_Verts[i].v(), sizeof(float) * 3);
-
-               if(has_norm)
+               
+               if (hasNorm)
                        ist.read((char*)m_Normals[i].v(), sizeof(float) * 3);
+               if (hasCol)
+                       ist.read((char*)m_Col[i].v(), sizeof(char) * 3);
 
-               if(!is_little_endian)
+               if (!is_little_endian)
                        ToBigEndian(m_Verts[i]);
        }
 
        m_Faces.resize(m_Header.m_NumFaces);
-       for(size_t i = 0; i < m_Header.m_NumFaces; ++i)
+       for (size_t i = 0; i < m_Header.m_NumFaces; ++i)
        {
                unsigned char nf;
                ist.read((char*)&nf, sizeof(unsigned char));
 
                m_Faces[i].m_Vid.resize((int)nf);
-               for(int j = 0; j < (int)nf; ++j)
+               for (int j = 0; j < (int)nf; ++j)
                {
                        ist.read((char*)&m_Faces[i].m_Vid[j], sizeof(int));
-                       if(!is_little_endian)
+                       if (!is_little_endian)
                                ToBigEndian(m_Faces[i].m_Vid[j]);
                }
        }
@@ -210,6 +222,8 @@ bool PlyMesh::ReadAscii( std::istream& ist )
        m_Verts.resize(m_Header.m_NumVerts);
        if (m_Header.HasNormal())
                m_Normals.resize(m_Header.m_NumVerts);
+       if (m_Header.HasCol())
+               m_Col.resize(m_Header.m_NumVerts);
 
        int max_vprop = m_Header.GetMaxPropIdx();
 
@@ -220,35 +234,26 @@ bool PlyMesh::ReadAscii( std::istream& ist )
 
                std::istringstream is(s);
 
-               for(int j = 0; j < max_vprop; ++j)
+               for (int j = 0; j < max_vprop; ++j)
                {
-                       float f;
-                       is >> f;
-
                        if (j == m_Header.m_VPI.vX)
-                       {
-                               m_Verts[i].x = f;
-                       }
+                               is >> m_Verts[i].x;
                        else if (j == m_Header.m_VPI.vY)
-                       {
-                               m_Verts[i].y = f;
-                       }
+                               is >> m_Verts[i].y;
                        else if (j == m_Header.m_VPI.vZ)
-                       {
-                               m_Verts[i].z = f;
-                       }
+                               is >> m_Verts[i].z;
                        else if (j == m_Header.m_VPI.nX)
-                       {
-                               m_Normals[i].x = f;
-                       }
+                               is >> m_Normals[i].x;
                        else if (j == m_Header.m_VPI.nY)
-                       {
-                               m_Normals[i].y = f;
-                       }
+                               is >> m_Normals[i].y;
                        else if (j == m_Header.m_VPI.nZ)
-                       {
-                               m_Normals[i].z = f;
-                       }
+                               is >> m_Normals[i].z;
+                       else if (j == m_Header.m_VPI.cR)
+                               m_Col[i].x = ReadColorElem(is);
+                       else if (j == m_Header.m_VPI.cG)
+                               m_Col[i].y = ReadColorElem(is);
+                       else if (j == m_Header.m_VPI.cB)
+                               m_Col[i].z = ReadColorElem(is);
                }
        }
 
@@ -267,6 +272,13 @@ bool PlyMesh::ReadAscii( std::istream& ist )
        return true;
 }
 
+unsigned char PlyMesh::ReadColorElem(std::istream& is)
+{
+       int i;
+       is >> i;
+       return (unsigned char)i;
+}
+
 bool PlyMesh::GetNextLine(std::istream& ist, std::string& s) const
 {
        while(!ist.eof())
@@ -300,8 +312,16 @@ bool PlyMesh::ConvertToBaseMesh( BaseMesh& o_mesh ) const
 
        o_mesh.m_Verts = m_Verts;
 
+       o_mesh.m_Col.resize(m_Col.size());
+       for (size_t i = 0; i < m_Col.size(); ++i)
+       {
+               o_mesh.m_Col[i].x = (float)m_Col[i].x / 255.0f;
+               o_mesh.m_Col[i].y = (float)m_Col[i].y / 255.0f;
+               o_mesh.m_Col[i].z = (float)m_Col[i].z / 255.0f;
+       }
+
        o_mesh.m_Faces.resize(m_Faces.size());
-       for(size_t i = 0; i < m_Faces.size(); ++i)
+       for (size_t i = 0; i < m_Faces.size(); ++i)
        {
                o_mesh.m_Faces[i].m_VertIds = m_Faces[i].m_Vid;
        }
index ad8d798..9805a35 100644 (file)
@@ -5,6 +5,7 @@
 #include <string>
 
 #include <C2/lm/vector3.h>
+#include <C2/graph/Color.h>
 
 #include "PlyFace.h"
 #include "PlyHeader.h"
@@ -44,10 +45,13 @@ private:
        bool ReadAscii( std::istream& ist );
        bool ReadBinary( std::istream& ist , bool is_litle_endian );
 
+       unsigned char ReadColorElem(std::istream& is);
+
 public:
        PlyHeader m_Header;
        std::vector<lm::vec3f> m_Verts;
        std::vector<lm::vec3f> m_Normals;
+       std::vector<lgr::color3b> m_Col;
        std::vector<PlyFace> m_Faces;
 };
 
index 6f91014..b53f17a 100644 (file)
@@ -1,7 +1,7 @@
 #include "stdafx.h"
 #include "Plyloader.h"
 
-#include <LibGeo/Mesh/PLY/PlyMesh.h>
+#include "PlyMesh.h"
 
 #include <LibQtGeoViewerCore/SceneMain.h>
 
@@ -12,7 +12,7 @@
 bool PlyLoader::Load(SceneMain& scene, const std::string& filename)
 {
        lib_geo::ply::PlyMesh ply_mesh;
-       if( !ply_mesh.Load( filename ) )
+       if (!ply_mesh.Load(filename))
                return false;
 
        GeomObject* geom = scene.CreateNewGeometry();