88 lines
2.5 KiB
C++
88 lines
2.5 KiB
C++
#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(调用方仍可安全 add,mapper 无输入则不绘制)。
|
||
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
|