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

#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);
}