C++ Class 中的 VTK Visualizer 不渲染场景

VTK Visualizer in a C++ Class Does not Render the Scene

我正在尝试将 VTK here 提供的示例放入 C++ class。此示例读取一个 STL 文件并将其可视化为 window。

下面是我的代码,没有编译器或 运行-time 错误。我的输入 STL 文件被正确读取,但我的代码退出时没有生成任何 STL 对象的可视化。

在我的 C++ class 中,我通过将 reader 与可视化工具分开并将它们放入 class 中的两个函数来组织 VTK 示例代码。可视化工具使用映射器、参与者和渲染器来可视化 STL 对象。但是,我无法获得代码来可视化我的 STL 对象。

让我的 C++ class 工作的唯一方法是将函数 visualize 的代码复制到我的 readSTL 函数中,然后我可以看到 window 在其中渲染了我的 STL 对象。

有人可以给我一些提示,告诉我如何在 class 中的单独函数中执行可视化吗?

#include <vtkPolyData.h>
#include <vtkSTLReader.h>
#include <vtkSmartPointer.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>


class triangulation
{
public:
    vtkIdType numberOfFaces;
    // Constructor
    triangulation(void);
    triangulation(std::string filename);
    void setFilename(std::string filename);
    std::string getFilename(void);

    // Getters
    vtkSmartPointer<vtkPolyData> getMesh(void);
    vtkSmartPointer<vtkCellArray> getPolys(void);
    vtkSmartPointer<vtkPoints>    getPoints(void);
    vtkSmartPointer<vtkDataArray> getDataArray(void);
    vtkIdType getNumberofFaces(void);

    // Visualizer
    void visualize(void);

    // Reader
    void readSTL(void);

private:
    std::string stlFilename;
    vtkSmartPointer<vtkPolyData> mesh;
    vtkSmartPointer<vtkSTLReader> reader;
    vtkSmartPointer<vtkCellArray> polys;
    vtkSmartPointer<vtkPoints>    points;
    vtkSmartPointer<vtkDataArray> dataArray;
};

triangulation::triangulation()
{
    //
}

triangulation::triangulation(std::string filename)
{
    setFilename(filename);
}


void triangulation::readSTL(void)
{
    vtkSmartPointer<vtkSTLReader> reader = vtkSmartPointer<vtkSTLReader>::New();
    reader->SetFileName(stlFilename.c_str());
    reader->Update();
    mesh = reader->GetOutput();
    polys = mesh->GetPolys();
    points = mesh->GetPoints();
    numberOfFaces = mesh->GetNumberOfCells();
}

void triangulation::setFilename(std::string filename)
{
    stlFilename = filename;
}

std::string triangulation::getFilename(void)
{
    return stlFilename;
}

vtkSmartPointer<vtkPolyData> triangulation::getMesh(void)
{
    return mesh;
}

vtkSmartPointer<vtkCellArray> triangulation::getPolys(void)
{
    return polys;
}

vtkIdType triangulation::getNumberofFaces(void)
{
    return numberOfFaces;
}

vtkSmartPointer<vtkPoints> triangulation::getPoints(void)
{
    return points;
}

vtkSmartPointer<vtkDataArray> triangulation::getDataArray(void)
{
    return dataArray;
}

void triangulation::visualize(void)
{
    // Visualize
    vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputConnection(reader->GetOutputPort());

    vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper);

    vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
    vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer(renderer);
    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    renderWindowInteractor->SetRenderWindow(renderWindow);

    renderer->AddActor(actor);
    renderer->SetBackground(.3, .6, .3); // Background color green

    renderWindow->Render();
    renderWindowInteractor->Start();
}



int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        cout << "Required parameters: Filename" << endl;
        return EXIT_FAILURE;
    }

    std::string inputFilename = argv[1];
    cout << inputFilename << endl;
    triangulation *tr = new triangulation(inputFilename);
    tr->readSTL();
    cout << "Number of Faces = " << tr->getNumberofFaces() << endl;

    vtkSmartPointer<vtkPolyData> mesh = tr->getMesh();
    vtkSmartPointer<vtkCellArray> polys = tr->getPolys();
    vtkSmartPointer<vtkPoints>    points = tr->getPoints();
    vtkSmartPointer<vtkDataArray> data = tr->getDataArray();
    //mesh->Print(cout);
    // polys->Print(cout);
    // points->Print(cout);
    // data->Print(cout);
    tr->visualize();


    delete tr;
    return EXIT_SUCCESS;
}

这是我用来测试代码的 STL 对象:

"myobject.stl":

solid STL generated by MeshLab
  facet normal -4.919344e-01  2.986337e-01  8.178133e-01
    outer loop
      vertex  -1.265660e+00  4.756133e+00  1.702858e-01
      vertex  -1.649185e+00  4.810246e+00 -8.017353e-02
      vertex  -1.602208e+00  4.484959e+00  6.686619e-02
    endloop
  endfacet
  facet normal -5.898571e-01  2.603427e-01  7.643889e-01
    outer loop
      vertex  -1.861084e+00  4.821712e+00 -2.475956e-01
      vertex  -1.602208e+00  4.484959e+00  6.686619e-02
      vertex  -1.649185e+00  4.810246e+00 -8.017353e-02
    endloop
  endfacet
  facet normal -6.398674e-01  2.007942e-01  7.417893e-01
    outer loop
      vertex  -1.861084e+00  4.821712e+00 -2.475956e-01
      vertex  -1.845646e+00  4.479523e+00 -1.416520e-01
      vertex  -1.602208e+00  4.484959e+00  6.686619e-02
    endloop
  endfacet
  facet normal -6.901410e-01  1.854371e-01  6.995131e-01
    outer loop
      vertex  -2.043903e+00  4.838252e+00 -4.323493e-01
      vertex  -1.845646e+00  4.479523e+00 -1.416520e-01
      vertex  -1.861084e+00  4.821712e+00 -2.475956e-01
    endloop
  endfacet
endsolid vcg

如果您只需替换 triangulation::readSTL() 中的以下行,您的代码就可以工作:

// Problem: local variable 'reader' shadows class member 'reader'.
vtkSmartPointer<vtkSTLReader> reader = vtkSmartPointer<vtkSTLReader>::New();
// Solution: 
reader = vtkSmartPointer<vtkSTLReader>::New();

因为 class-成员 reader 保持未初始化,应用程序在 triangulation::visualize().

中访问时崩溃并出现段错误

提示:如果您随后使用 this-> 或命名前缀(m__)来引用 class 成员,您可能就不会遇到此问题.请参阅此 SO post 了解一些解释。