geopro/src/render/actors/ScatterActor.cpp

88 lines
2.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "actors/ScatterActor.hpp"
#include <cstddef>
#include <vector>
#include <vtkCellArray.h>
#include <vtkDoubleArray.h>
#include <vtkNew.h>
#include <vtkPointData.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include "ColorLutBuilder.hpp"
namespace geopro::render {
namespace {
// LUT 级数。
constexpr int kLutLevels = 256;
} // namespace
vtkSmartPointer<vtkActor> buildScatter(const geopro::core::ScatterField& s,
const geopro::core::ColorScale& cs,
float pointSize)
{
const std::size_t n = s.v.size();
// 退化输入:无值或 x/y 长度不足 → 空 actor(调用方仍可安全 addmapper 无输入则不绘制)。
if (n == 0 || s.x.size() < n || s.y.size() < n) {
return vtkSmartPointer<vtkActor>::New();
}
vtkNew<vtkPoints> points;
points->SetNumberOfPoints(static_cast<vtkIdType>(n));
vtkNew<vtkCellArray> verts; // 每点一个 vtkVertex(GL_POINTS),渲染为方块点
vtkNew<vtkDoubleArray> sc;
sc->SetName("v");
sc->SetNumberOfTuples(static_cast<vtkIdType>(n));
for (std::size_t i = 0; i < n; ++i) {
const auto id = static_cast<vtkIdType>(i);
// y=深度(越大越深)→取负,使深部在下、剖面不倒置(与 GridContourActor 一致)。
points->SetPoint(id, s.x[i], -s.y[i], 0.0);
verts->InsertNextCell(1, &id);
sc->SetValue(id, s.v[i]);
}
vtkNew<vtkPolyData> poly;
poly->SetPoints(points);
poly->SetVerts(verts);
poly->GetPointData()->SetScalars(sc);
// 色阶范围:优先 colorBar 真实分段值(非均匀),否则回退到 v 实测范围。
const std::vector<double> stops = cs.stopValues();
double vmin, vmax;
if (stops.size() >= 2) {
vmin = stops.front();
vmax = stops.back();
} else {
vmin = s.v.front();
vmax = vmin;
for (double v : s.v) {
if (v < vmin) vmin = v;
if (v > vmax) vmax = v;
}
if (vmin >= vmax) vmax = vmin + 1.0;
}
auto lut = buildLut(cs, vmin, vmax, kLutLevels);
vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputData(poly);
mapper->SetScalarModeToUsePointData();
mapper->SetLookupTable(lut);
mapper->SetScalarRange(vmin, vmax);
auto actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
actor->GetProperty()->SetPointSize(pointSize);
return actor;
}
} // namespace geopro::render