You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
180 lines
5.5 KiB
180 lines
5.5 KiB
3 days ago
|
#include "Renderer.h"
|
||
|
#include <memory>
|
||
|
#include <vtkActor.h>
|
||
|
#include <vtkAutoInit.h>
|
||
|
#include <vtkCallbackCommand.h>
|
||
|
#include <vtkCellPicker.h>
|
||
|
#include <vtkConeSource.h>
|
||
|
#include <vtkFloatArray.h>
|
||
|
#include <vtkInteractorStyleTrackballCamera.h>
|
||
|
#include <vtkLineSource.h>
|
||
|
#include <vtkLookupTable.h>
|
||
|
#include <vtkNew.h>
|
||
|
#include <vtkPointData.h>
|
||
|
#include <vtkPoints.h>
|
||
|
#include <vtkPolyLine.h>
|
||
|
#include <vtkPolyline.h>
|
||
|
#include <vtkProperty.h>
|
||
|
#include <vtkRenderer.h>
|
||
|
#include <vtkRendererCollection.h>
|
||
|
#include <vtkScalarBarActor.h>
|
||
|
#include <vtkSmartPointer.h>
|
||
|
#include <vtkTriangle.h>
|
||
|
#include <vtkVertexGlyphFilter.h>
|
||
|
|
||
|
VTK_MODULE_INIT(vtkRenderingOpenGL2);
|
||
|
VTK_MODULE_INIT(vtkInteractionStyle);
|
||
|
VTK_MODULE_INIT(vtkRenderingFreeType);
|
||
|
|
||
|
std::shared_ptr<Renderer> Renderer::_instance = nullptr;
|
||
|
|
||
|
Renderer::Renderer() {
|
||
|
_vtkRenderer = vtkSmartPointer<vtkRenderer>::New();
|
||
|
_vtkRenderer->SetUseFXAA(true);
|
||
|
|
||
|
_renwin = vtkSmartPointer<vtkRenderWindow>::New();
|
||
|
_renwin->AddRenderer(_vtkRenderer);
|
||
|
_renwin->SetSize(800, 800);
|
||
|
_renwin->SetWindowName("OCC Viewer");
|
||
|
|
||
|
vtkNew<vtkInteractorStyleTrackballCamera> iStyle;
|
||
|
_interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
|
||
|
_interactor->SetRenderWindow(_renwin);
|
||
|
_interactor->SetInteractorStyle(iStyle);
|
||
|
|
||
|
/***** Axes */
|
||
|
// vtkNew<MyVTKCoordAxesActor> axes;
|
||
|
// axes->setAxisLength(5, 5, 5);
|
||
|
// axes->setConeRadius(0.1);
|
||
|
// axes->setConeHeight(0.2);
|
||
|
// _vtkRenderer->AddActor(axes);
|
||
|
}
|
||
|
|
||
|
void Renderer::addMesh(const DrawMeshDesc &desc) {
|
||
|
if (!desc.model || !desc.model->m_fBeLoaded) {
|
||
|
std::cerr << "Model not loaded!\n";
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
auto points = vtkSmartPointer<vtkPoints>::New();
|
||
|
for (int i = 0; i < desc.model->GetNumOfVerts(); ++i) {
|
||
|
const auto &v = desc.model->Vert(i);
|
||
|
points->InsertNextPoint(v.x, v.y, v.z);
|
||
|
}
|
||
|
|
||
|
auto polys = vtkSmartPointer<vtkCellArray>::New();
|
||
|
for (int i = 0; i < desc.model->GetNumOfFaces(); ++i) {
|
||
|
const auto &f = desc.model->Face(i);
|
||
|
auto triangle = vtkSmartPointer<vtkTriangle>::New();
|
||
|
triangle->GetPointIds()->SetId(0, f[0]);
|
||
|
triangle->GetPointIds()->SetId(1, f[1]);
|
||
|
triangle->GetPointIds()->SetId(2, f[2]);
|
||
|
polys->InsertNextCell(triangle);
|
||
|
}
|
||
|
|
||
|
auto polyData = vtkSmartPointer<vtkPolyData>::New();
|
||
|
polyData->SetPoints(points);
|
||
|
polyData->SetPolys(polys);
|
||
|
|
||
|
// 如果有顶点法向量
|
||
|
if (!desc.model->m_NormalsToVerts.empty()) {
|
||
|
auto normals = vtkSmartPointer<vtkFloatArray>::New();
|
||
|
normals->SetNumberOfComponents(3);
|
||
|
normals->SetName("Normals");
|
||
|
for (const auto &n : desc.model->m_NormalsToVerts) {
|
||
|
float arr[3] = {static_cast<float>(n.x), static_cast<float>(n.y),
|
||
|
static_cast<float>(n.z)};
|
||
|
normals->InsertNextTuple(arr);
|
||
|
}
|
||
|
polyData->GetPointData()->SetNormals(normals);
|
||
|
}
|
||
|
|
||
|
auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||
|
mapper->SetInputData(polyData);
|
||
|
|
||
|
auto actor = vtkSmartPointer<vtkActor>::New();
|
||
|
actor->SetMapper(mapper);
|
||
|
actor->GetProperty()->SetColor(desc.color.r, desc.color.g, desc.color.b);
|
||
|
actor->GetProperty()->SetOpacity(desc.opacity);
|
||
|
|
||
|
_vtkRenderer->AddActor(actor);
|
||
|
}
|
||
|
|
||
|
void Renderer::addPolyline(const DrawPolylineDesc &desc) {
|
||
|
if (desc.points.empty()) {
|
||
|
std::cerr << "Polyline has no points!\n";
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
auto points = vtkSmartPointer<vtkPoints>::New();
|
||
|
for (const auto &p : desc.points) {
|
||
|
points->InsertNextPoint(p.x, p.y, p.z);
|
||
|
}
|
||
|
|
||
|
auto cells = vtkSmartPointer<vtkCellArray>::New();
|
||
|
|
||
|
// 主 polyline
|
||
|
auto polyLine = vtkSmartPointer<vtkPolyLine>::New();
|
||
|
polyLine->GetPointIds()->SetNumberOfIds(
|
||
|
static_cast<vtkIdType>(desc.points.size()));
|
||
|
for (vtkIdType i = 0; i < static_cast<vtkIdType>(desc.points.size()); ++i) {
|
||
|
polyLine->GetPointIds()->SetId(i, i);
|
||
|
}
|
||
|
cells->InsertNextCell(polyLine);
|
||
|
|
||
|
// 如果需要闭合,额外加一条段:最后一个点 -> 第一个点
|
||
|
if (desc.closed && desc.points.size() > 2) {
|
||
|
vtkIdType lastId = static_cast<vtkIdType>(desc.points.size() - 1);
|
||
|
vtkIdType firstId = 0;
|
||
|
|
||
|
vtkIdType linePts[2] = {lastId, firstId};
|
||
|
cells->InsertNextCell(2, linePts);
|
||
|
}
|
||
|
|
||
|
auto polyData = vtkSmartPointer<vtkPolyData>::New();
|
||
|
polyData->SetPoints(points);
|
||
|
polyData->SetLines(cells);
|
||
|
|
||
|
auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||
|
mapper->SetInputData(polyData);
|
||
|
|
||
|
auto actor = vtkSmartPointer<vtkActor>::New();
|
||
|
actor->SetMapper(mapper);
|
||
|
actor->GetProperty()->SetColor(desc.color.r, desc.color.g, desc.color.b);
|
||
|
actor->GetProperty()->SetLineWidth(desc.width);
|
||
|
|
||
|
_vtkRenderer->AddActor(actor);
|
||
|
}
|
||
|
|
||
|
void Renderer::addPointCloud(const DrawPointCloudDesc &desc) {
|
||
|
auto points = vtkSmartPointer<vtkPoints>::New();
|
||
|
auto vertices = vtkSmartPointer<vtkCellArray>::New();
|
||
|
|
||
|
for (size_t i = 0; i < desc.points.size(); ++i) {
|
||
|
const auto &p = desc.points[i];
|
||
|
vtkIdType pid = points->InsertNextPoint(p.x, p.y, p.z);
|
||
|
vertices->InsertNextCell(1);
|
||
|
vertices->InsertCellPoint(pid);
|
||
|
}
|
||
|
|
||
|
auto polyData = vtkSmartPointer<vtkPolyData>::New();
|
||
|
polyData->SetPoints(points);
|
||
|
polyData->SetVerts(vertices);
|
||
|
|
||
|
// 用GlyphFilter确保显示每个点
|
||
|
auto glyphFilter = vtkSmartPointer<vtkVertexGlyphFilter>::New();
|
||
|
glyphFilter->SetInputData(polyData);
|
||
|
glyphFilter->Update();
|
||
|
|
||
|
auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||
|
mapper->SetInputConnection(glyphFilter->GetOutputPort());
|
||
|
|
||
|
auto actor = vtkSmartPointer<vtkActor>::New();
|
||
|
actor->SetMapper(mapper);
|
||
|
|
||
|
actor->GetProperty()->SetColor(desc.color.r, desc.color.g, desc.color.b);
|
||
|
|
||
|
actor->GetProperty()->SetPointSize(desc.pointSize);
|
||
|
|
||
|
_vtkRenderer->AddActor(actor);
|
||
|
}
|