首页 > 解决方案 > C++ 类中的 VTK Visualizer 不渲染场景

问题描述

我正在尝试将 VTK这里提供的示例放入 C++ 类中。此示例读取一个 STL 文件并将其可视化在一个窗口中。

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

在我的 C++ 类中,我通过将阅读器与可视化器分开并将它们放入类中的两个函数来组织 VTK 示例代码。可视化器使用映射器、演员和渲染器来可视化 STL 对象。但是,我无法获取代码来可视化我的 STL 对象。

我能够让我的 C++ 类工作的唯一方法是将函数的代码复制visualize到我的readSTL函数中,然后我可以看到其中呈现了我的 STL 对象的窗口。

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

#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 对象:

“我的对象.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

标签: c++classvtk

解决方案


如果您只需替换以下行,您的代码将起作用triangulation::readSTL()

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

由于类成员reader仍未初始化,因此应用程序在triangulation::visualize().

this->提示:如果您随后使用或 命名前缀(m__)来指代类成员,您可能不会遇到此问题。有关一些解释,请参阅此SO 帖子


推荐阅读