VTK 无法正确渲染多边形
VTK does not render polygon correctly
我有一个 VTK 6.3 程序,我已经提炼到下面的列表中。
当我运行它时,渲染的多边形不正确。它应该是一个四边形,边上还有另一个四边形,而不是这个古怪的东西:
看起来好像多边形三角测量有误,当您旋转多边形时,一个流氓三角形会闪烁。
我相信我的多边形指定正确:逆时针和非自相交。
我仔细研究了 VTK 代码,希望找到一种改变三角剖分方法的方法。 VTKPolygon class 包含几种不同的三角剖分方法,但不清楚是否可以手动设置方法。
如果有人有解决此问题的建议,我将不胜感激。
正如我所说,我相信该清单已接近重现该问题的最少代码量。
此外,如评论中所述,此行为已在 VTK 8.0 版中修复。但是,我正在 运行 宁 RHEL 7.4,安装 VTK 版本 7 或 8 并不是直截了当的。 VTK 似乎需要比 RHEL 7.4 可用版本更新的 OpenGL 版本。
#include <vtkActor.h>
#include <vtkCellArray.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkPolygon.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSmartPointer.h>
#include <iostream>
using namespace std;
int main (int argc, char **argv)
{
struct P { float x, y, z; };
vector<P> p;
p.push_back (P {8.0, 3.0, 0.0});
p.push_back (P {7.0, 5.0, 0.0});
p.push_back (P {1.0, 3.0, 0.0});
p.push_back (P {1.0, 2.0, 0.0});
p.push_back (P {0.0, 3.0, 0.0});
p.push_back (P {0.0, 1.0, 0.0});
p.push_back (P {1.0, 1.0, 0.0});
p.push_back (P {1.0, 0.0, 0.0});
vtkSmartPointer<vtkPolygon> poly = vtkSmartPointer<vtkPolygon>::New();
poly->GetPointIds()->SetNumberOfIds(p.size ());
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkCellArray> polygons = vtkSmartPointer<vtkCellArray>::New();
for (size_t i = 0; i < p.size (); ++i)
{
points->InsertNextPoint (p[i].x, p[i].y, p[i].z);
poly->GetPointIds()->SetId(i, i);
}
polygons->InsertNextCell(poly);
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
polydata->SetPoints(points);
polydata->SetPolys(polygons);
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputData(polydata);
vtkSmartPointer<vtkActor> buildingActor = vtkSmartPointer<vtkActor>::New();
buildingActor->SetMapper(mapper);
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(buildingActor);
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindow->Render();
renderWindowInteractor->Start ();
return 0;
}
我认为 VTK 在坐标原点方面有一些技巧。我将您的源代码采纳到 VTK 8.1.1。我更改了坐标集以在 space
中获得两个不同方向的三角形
我把修改后的源放在下面
#include "vtkAutoInit.h"
#define vtkRenderingCore_AUTOINIT 2(vtkRenderingOpenGL2, vtkInteractionStyle)
#include "stdafx.h"
#include <vtkActor.h>
#include <vtkCellArray.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkPolygon.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSmartPointer.h>
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
struct P { float x, y, z; };
vector<P> p;
p.push_back(P{ 8.0, 8.0, 3.0 });
p.push_back(P{ 8.0, 1.0, 0.0 });
p.push_back(P{ 1.0, 8.0, 0.0 });
p.push_back(P{ 1.0, 1.0, 3.0 });
p.push_back(P{ 8.0, 1.0, 0.0 });
vtkSmartPointer<vtkPolygon> poly = vtkSmartPointer<vtkPolygon>::New();
poly->GetPointIds()->SetNumberOfIds(p.size());
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkCellArray> polygons =vtkSmartPointer<vtkCellArray>::New();
for (size_t i = 0; i < p.size(); ++i)
{
points->InsertNextPoint(p[i].x, p[i].y, p[i].z);
poly->GetPointIds()->SetId(i, i);
}
polygons->InsertNextCell(poly);
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
polydata->SetPoints(points);
polydata->SetPolys(polygons);
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputData(polydata);
vtkSmartPointer<vtkActor> buildingActor = vtkSmartPointer<vtkActor>::New();
buildingActor->SetMapper(mapper);
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(buildingActor);
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindow->Render();
renderWindowInteractor->Start();
return 0;
}
我有一个 VTK 6.3 程序,我已经提炼到下面的列表中。
当我运行它时,渲染的多边形不正确。它应该是一个四边形,边上还有另一个四边形,而不是这个古怪的东西:
看起来好像多边形三角测量有误,当您旋转多边形时,一个流氓三角形会闪烁。
我相信我的多边形指定正确:逆时针和非自相交。
我仔细研究了 VTK 代码,希望找到一种改变三角剖分方法的方法。 VTKPolygon class 包含几种不同的三角剖分方法,但不清楚是否可以手动设置方法。
如果有人有解决此问题的建议,我将不胜感激。
正如我所说,我相信该清单已接近重现该问题的最少代码量。
此外,如评论中所述,此行为已在 VTK 8.0 版中修复。但是,我正在 运行 宁 RHEL 7.4,安装 VTK 版本 7 或 8 并不是直截了当的。 VTK 似乎需要比 RHEL 7.4 可用版本更新的 OpenGL 版本。
#include <vtkActor.h>
#include <vtkCellArray.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkPolygon.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSmartPointer.h>
#include <iostream>
using namespace std;
int main (int argc, char **argv)
{
struct P { float x, y, z; };
vector<P> p;
p.push_back (P {8.0, 3.0, 0.0});
p.push_back (P {7.0, 5.0, 0.0});
p.push_back (P {1.0, 3.0, 0.0});
p.push_back (P {1.0, 2.0, 0.0});
p.push_back (P {0.0, 3.0, 0.0});
p.push_back (P {0.0, 1.0, 0.0});
p.push_back (P {1.0, 1.0, 0.0});
p.push_back (P {1.0, 0.0, 0.0});
vtkSmartPointer<vtkPolygon> poly = vtkSmartPointer<vtkPolygon>::New();
poly->GetPointIds()->SetNumberOfIds(p.size ());
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkCellArray> polygons = vtkSmartPointer<vtkCellArray>::New();
for (size_t i = 0; i < p.size (); ++i)
{
points->InsertNextPoint (p[i].x, p[i].y, p[i].z);
poly->GetPointIds()->SetId(i, i);
}
polygons->InsertNextCell(poly);
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
polydata->SetPoints(points);
polydata->SetPolys(polygons);
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputData(polydata);
vtkSmartPointer<vtkActor> buildingActor = vtkSmartPointer<vtkActor>::New();
buildingActor->SetMapper(mapper);
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(buildingActor);
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindow->Render();
renderWindowInteractor->Start ();
return 0;
}
我认为 VTK 在坐标原点方面有一些技巧。我将您的源代码采纳到 VTK 8.1.1。我更改了坐标集以在 space
中获得两个不同方向的三角形我把修改后的源放在下面
#include "vtkAutoInit.h"
#define vtkRenderingCore_AUTOINIT 2(vtkRenderingOpenGL2, vtkInteractionStyle)
#include "stdafx.h"
#include <vtkActor.h>
#include <vtkCellArray.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkPolygon.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSmartPointer.h>
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
struct P { float x, y, z; };
vector<P> p;
p.push_back(P{ 8.0, 8.0, 3.0 });
p.push_back(P{ 8.0, 1.0, 0.0 });
p.push_back(P{ 1.0, 8.0, 0.0 });
p.push_back(P{ 1.0, 1.0, 3.0 });
p.push_back(P{ 8.0, 1.0, 0.0 });
vtkSmartPointer<vtkPolygon> poly = vtkSmartPointer<vtkPolygon>::New();
poly->GetPointIds()->SetNumberOfIds(p.size());
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkCellArray> polygons =vtkSmartPointer<vtkCellArray>::New();
for (size_t i = 0; i < p.size(); ++i)
{
points->InsertNextPoint(p[i].x, p[i].y, p[i].z);
poly->GetPointIds()->SetId(i, i);
}
polygons->InsertNextCell(poly);
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
polydata->SetPoints(points);
polydata->SetPolys(polygons);
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputData(polydata);
vtkSmartPointer<vtkActor> buildingActor = vtkSmartPointer<vtkActor>::New();
buildingActor->SetMapper(mapper);
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(buildingActor);
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindow->Render();
renderWindowInteractor->Start();
return 0;
}