是否可以使用 CGAL 绘制 3d 线段?

Is it possible to draw 3d segments with CGAL?

我想画3d线段,相机可以旋转,这样可以从不同的角度观察线段。我想知道是否有办法用 CGAL 绘制它们?我知道 CGAL 不是专门用于可视化的,所以这个问题本身可能有点愚蠢。但是如果它有这个功能对我来说真的很有帮助,因为我对CGAL有一些经验。
我尝试学习OpenGL,但我不可能在短时间内掌握它。而且我也不想花太多时间去学习OpenGL,因为以后的工作中不会再用到它。
如果CGAL没有这个功能,能否请您推荐一些轻量级可以绘制3d线段的开源库?我不需要功能非常丰富但庞大的图书馆。一款易于使用且重量轻的最适合我。非常感谢!

CGAL::Basic_viewer_qt 允许在 2D/3D 中绘制点、线段和面。 您可以定义自己的查看器,继承自此 class.

按照 Marc 的建议,查看不同的 draw_XXX.h 文件,了解如何在 CGAL 中为多个查看器实现这一点。

听从Marc Glisse和gdamiand的建议,我仿照文件draw_triangulation3.h中的classSimpleTriangulation3ViewerQt,写了一个class,名称为SimpleSegments3ViewerQt。它确实有效。谢谢你的建议!这是代码。

#pragma once
#include<CGAL/Qt/Basic_viewer_qt.h>

//a struct that describes 3d segment, Point is the data structure of vertex of segment.
template<typename Point>
struct mySegment3d {
    Point begin;
    Point end;
    mySegment3d() {}
    mySegment3d(Point b,Point e):begin(b),end(e){}
};

#ifdef CGAL_USE_BASIC_VIEWER

#include<CGAL/Qt/init_ogl_context.h>

//viewer for mySegment3d
//Segs3 is an array of mySegment3d which can be traveled by iterator, such as std::veector<mySegment3d>. 
template<class Segs3,class point>
class SimpleSegments3ViewerQt :public CGAL::Basic_viewer_qt
{
    typedef Basic_viewer_qt         Base;
    typedef mySegment3d<point>      mySegment3d;

public:
    //construct the viewer
    SimpleSegments3ViewerQt(QWidget* parent,
        const Segs3& seg3,
        const char* title = "Basic Segs3 Viewer") :
        //First draw: vertices, edges, faces, multi-color, no inverse normal
        Base(parent, title, true, true, false, false, true),
        s3(seg3)
    {
        compute_elements();
    }
protected:
    const Segs3& s3;
protected:
    void compute_edge(const mySegment3d& seg) {
        add_segment(seg.begin, seg.end, CGAL::IO::blue());
    }
    void compute_vertex(const mySegment3d& seg) {
        add_point(seg.begin, CGAL::IO::red());
        add_point(seg.end,CGAL::IO::red());
    }
    void compute_elements() {
        clear();
        for (auto itor = s3.begin(); itor != s3.end(); ++itor) {
            compute_vertex(*itor);
            compute_edge(*itor);
        }
    }
    virtual void keyPressEvent(QKeyEvent* e) {
        Base::keyPressEvent(e);
    }
};


//draw function
template<typename Segs3,typename Point>
void draw(const Segs3& s3, const char* title = "Segs3 Basic Viewer") {
#if defined(CGAL_TEST_SUITE)
    bool cgal_test_suite = true;
#else
    bool cgal_test_suite = qEnvironmentVariableIsSet("CGAL_TEST_SUITE");
#endif
    if (!cgal_test_suite) {
        CGAL::Qt::init_ogl_context(4, 3);
        int argc = 1;
        const char* argv[2] = { "segs3_viewer","[=10=]" };
        QApplication app(argc, const_cast<char**>(argv));
        
        SimpleSegments3ViewerQt<Segs3,Point> mainwindow(app.activeWindow(),
            s3, title);
        mainwindow.show();
        app.exec();
    }
}

#endif

这是一个用法示例。

#include<vector>
#include<CGAL/Simple_cartesian.h>
#include"draw_segments_3.h"
typedef CGAL::Simple_cartesian<double> kernel;
typedef kernel::Point_3 Point_3;
//draw_segments3 test
int main() {
    std::vector<mySegment3d<Point_3>> segs;
    Point_3 p0(0, 0, 0), p1(1, 2, 3), p2(5, 3, 1), p3(3, 1, 10);
    mySegment3d<Point_3> s0(p0, p1), s1(p0, p2), s2(p0, p3);
    segs.emplace_back(s0);
    segs.emplace_back(s1);
    segs.emplace_back(s2);
    draw<std::vector<mySegment3d<Point_3>>,Point_3>(segs);
}