CGAL:如何在加载 .off 文件后访问顶点颜色?

CGAL: How can I access vertex colors after loading an .off file?

加载 .off 文件很容易:

typedef CGAL::Simple_cartesian<double>  Kernel;
typedef CGAL::Surface_mesh<Kernel::Point_3> SurfaceMesh;
typedef CGAL::Polyhedron_3<Kernel> Polyhedron;

...

SurfaceMesh surface;
Polyhedron poly;
std::fstream inputOffFile( "myFile.off" );
inputOffFile >> poly;
CGAL::copy_face_graph( poly, surface);

然后,我可以通过以下方式迭代顶点坐标:

std::vector<float> verts;
for( SurfaceMesh::Vertex_index vi : surface.vertices() )
{
    Point pt = surface.point( vi );
    verts.push_back( pt.x() );
    verts.push_back( pt.y() );
    verts.push_back( pt.z() );
}

但是我怎样才能访问存储在 .off 文件中的顶点颜色呢?

编辑:可能 CGAL::copy_face_graph 没有复制颜色 属性,所以我想我需要一个不同的方法?

您需要使用 SurfaceMesh 的 属性 贴图。当且仅当 OFF 文件有颜色(意味着第一个指示是 COFF 而不是第一行的 OFF),并且每个顶点都有颜色而不仅仅是每个面,那么你的 SurfaceMesh 将有一个内部 属性 贴图称为 "v:color"。您可以通过调用

访问它
SurfaceMesh::Property_map<SurfaceMesh::Vertex_index, CGAL::Color> vcolors =
      surface.property_map<SurfaceMesh::Vertex_index, CGAL::Color >("v:color").first;

for( SurfaceMesh::Vertex_index vi : surface.vertices() )
{
    CGAL::Color ci = vcolors[vi];
}

如果每个面都有颜色,您可以类似地访问它,但是通过搜索名为 "f:color" 的 属性 地图。您可以使用 surface.property_map<......>(...).second.

检查地图是否存在

好的,这是完整的解决方案,包括访问面顶点(如果您想通过 OpenGL 渲染网格,则需要)。使用 SurfaceMesh 是关键。

...
std::vector<Point> verts;
std::vector<Color> cols;

SurfaceMesh::Property_map<SurfaceMesh::Vertex_index, CGAL::Color> vcolors =
    m_pSurface->property_map<SurfaceMesh::Vertex_index, CGAL::Color >( "v:color" ).first;

bool colorExists = m_pSurface->property_map<SurfaceMesh::Vertex_index, CGAL::Color>( "v:color" ).second;

if( !colorExists ) 
    Error(); 

for( SurfaceMesh::Vertex_index vi : m_pSurface->vertices() )
{
    cols.push_back( vcolors[ vi ] );
    verts.push_back( m_pSurface->point( vi ) );
}

for( SurfaceMesh::Face_index face_index : m_pSurface->faces() )
{
    CGAL::Vertex_around_face_circulator<SurfaceMesh> vcirc( m_pSurface->halfedge( face_index ), *m_pSurface ), done( vcirc );

    signed char count = 0;

    do
    {
        count++;
        uint32_t vertexI = *vcirc++;

        const Point &pt = verts[ vertexI ];
        const Color &col = cols[ vertexI ];

        ...

    } while( vcirc != done );

}

非常感谢有用的评论!