geopro/tests/spike/render_verify.cpp

117 lines
4.8 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.

// 离屏渲染验证:把真实数据渲成 PNG肉眼核对方向/2D-3D 差异(不靠"进程活着"自欺)。
// 产出(D:/dev/spike_data/):
// verify_section.png —— 平面反演剖面(#18, 数据详情), 浅部在上、深部在下, 纵向夸张填满
// verify_curtain_top.png —— 帘面俯视(二维)
// verify_curtain_3d.png —— 帘面透视(三维)
#include <fstream>
#include <numeric>
#include <sstream>
#include <string>
#include <vtkActor.h>
#include <vtkNew.h>
#include <vtkPNGWriter.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkWindowToImageFilter.h>
#include "CameraPreset.hpp"
#include "ColorLutBuilder.hpp"
#include "actors/CurtainActor.hpp"
#include "actors/GridContourActor.hpp"
#include "actors/AnomalyActor.hpp"
#include "actors/MapLineActor.hpp"
#include "actors/ScatterActor.hpp"
#include "geo/GeoLocalFrame.hpp"
#include "parse/SampleParsers.hpp"
static std::string slurp(const char* p) {
std::ifstream f(p);
std::stringstream s; s << f.rdbuf(); return s.str();
}
static void renderToPng(vtkRenderer* ren, const char* path, int w, int h) {
vtkNew<vtkRenderWindow> rw;
rw->SetOffScreenRendering(1);
rw->AddRenderer(ren);
rw->SetSize(w, h);
rw->Render();
vtkNew<vtkWindowToImageFilter> w2i; w2i->SetInput(rw);
vtkNew<vtkPNGWriter> png; png->SetFileName(path);
png->SetInputConnection(w2i->GetOutputPort()); png->Write();
}
int main() {
using namespace geopro;
const std::string dir = "D:/dev/spike_data/";
core::Grid g = data::parseGrid(slurp((dir + "grid.json").c_str()));
core::ColorScale cs = data::parseColorScale(slurp((dir + "colorbar.json").c_str()));
// 1) 平面剖面 (#18) — 俯视看 XY 平面(face-on); 纵向夸张 1.5x 填满宽面板(物探惯例)
{
auto a = render::buildGridContour(g, cs);
const double exag = 1.5;
vtkNew<vtkRenderer> ren; ren->SetBackground(1, 1, 1);
if (a.bands) { a.bands->SetScale(1.0, exag, 1.0); ren->AddActor(a.bands); }
if (a.edges) { a.edges->SetScale(1.0, exag, 1.0); ren->AddActor(a.edges); }
render::applyTop2D(ren);
renderToPng(ren, (dir + "verify_section.png").c_str(), 1100, 360);
}
// GeoLocalFrame: 原点取 lat/lon 均值
double lat0 = std::accumulate(g.lat.begin(), g.lat.end(), 0.0) / (g.lat.empty() ? 1 : g.lat.size());
double lon0 = std::accumulate(g.lon.begin(), g.lon.end(), 0.0) / (g.lon.empty() ? 1 : g.lon.size());
core::GeoLocalFrame frame(lat0, lon0);
// 2) 二维地图:测线折线俯视(浅灰底)
{
auto line = render::buildSurveyLine(g, frame);
vtkNew<vtkRenderer> ren; ren->SetBackground(0.96, 0.97, 0.99);
ren->AddActor(line);
render::applyTop2D(ren);
renderToPng(ren, (dir + "verify_map.png").c_str(), 700, 500);
}
// 3) 帘面透视(三维);纵向夸张 z*3使 15m 深度相对 62m 长度更像一道墙
{
auto a = render::buildCurtain(g, cs, frame);
a->SetScale(1.0, 1.0, 3.0);
vtkNew<vtkRenderer> ren; ren->SetBackground(1, 1, 1);
ren->AddActor(a);
render::applyFree3D(ren);
renderToPng(ren, (dir + "verify_curtain_3d.png").c_str(), 700, 500);
}
// 4) 散点 (#17) — 剖面原数据彩色方块散点; x=距离, y=深度(取负向下), face-on 俯视
{
core::ScatterField s = data::parseScatter(slurp((dir + "scatter.json").c_str()));
core::ColorScale scs = data::parseColorScale(slurp((dir + "scatter_colorbar.json").c_str()));
auto a = render::buildScatter(s, scs, 4.0F);
vtkNew<vtkRenderer> ren; ren->SetBackground(1, 1, 1);
ren->AddActor(a);
render::applyTop2D(ren);
renderToPng(ren, (dir + "verify_scatter.png").c_str(), 1100, 360);
std::printf("SCATTER pts=%zu\n", s.v.size());
}
// 5) 异常叠加 — #18 平面剖面 + 异常 dashed 折线叠加(同纵向夸张 1.5x 对齐)
{
std::vector<core::Anomaly> anomalies =
data::parseAnomalies(slurp((dir + "anomaly.json").c_str()));
auto a = render::buildGridContour(g, cs);
const double exag = 1.5;
vtkNew<vtkRenderer> ren; ren->SetBackground(1, 1, 1);
if (a.bands) { a.bands->SetScale(1.0, exag, 1.0); ren->AddActor(a.bands); }
if (a.edges) { a.edges->SetScale(1.0, exag, 1.0); ren->AddActor(a.edges); }
auto anomActors = render::buildAnomalies(anomalies);
for (auto& act : anomActors) {
act->SetScale(1.0, exag, 1.0);
ren->AddActor(act);
}
render::applyTop2D(ren);
renderToPng(ren, (dir + "verify_section_anomaly.png").c_str(), 1100, 360);
std::printf("ANOMALY n=%zu\n", anomalies.size());
}
std::printf("RENDER_VERIFY_DONE grid=%dx%d lat0=%.5f lon0=%.5f\n", g.nx(), g.ny(), lat0, lon0);
return 0;
}