【问题标题】:CGAL: How can I access vertex colors after loading an .off file?CGAL:加载 .off 文件后如何访问顶点颜色?
【发布时间】:2019-05-02 15:19:42
【问题描述】:

加载 .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 不复制颜色属性,所以我想我需要一种不同的方法?

【问题讨论】:

    标签: c++ visual-studio 3d cgal


    【解决方案1】:

    您需要使用 SurfaceMesh 的属性映射。当且仅当 OFF 文件有颜色(意味着第一行的第一个指示是 COFF 而不是 OFF),并且每个顶点有颜色,而不仅仅是每个面,那么 SurfaceMesh 将有一个名为“v:颜色”。您可以通过调用访问它

    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 来检查地图是否存在。

    【讨论】:

    • Maxime 写的内容适用于 CGAL::Surface_mesh 而不是 CGAL::Polyhedron_3
    • OMG - 很可能 CGAL::copy_face_graph 不复制颜色属性...?我怎样才能做到这一点?
    • 我调试了CGAL多面体本身的.off-loading,顶点颜色肯定被加载到了一些内部结构中,但SurfaceMesh中不存在......
    • Polyhedron_3 没有优雅的机制来添加属性。这就是为什么我建议切换到 Surface_mesh。 Polyhedron 的 IO 可以解析带颜色的文件但忽略它们。
    • 哦,是的,抱歉,我没有看到 off 被加载到多面体中。为什么不直接加载到表面?因为多面体读取函数不读取颜色,所以他们甚至没有进入 dopy_face_graph() 阶段。
    【解决方案2】:

    好的,这是完整的解决方案,包括对面顶点的访问(如果您想通过 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 );
    
    }
    

    非常感谢提供帮助的 cmets!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多