--- id: "0028" title: "C++ ImPlot3D + surface_plot_3d real + scatter_3d" status: completado type: feature domain: - cpp-stack scope: multi-app priority: media depends: [] blocks: [] related: [] created: 2026-05-17 updated: 2026-05-17 tags: [] --- # 0028 — C++ ImPlot3D + surface_plot_3d real + scatter_3d ## APP Metadata | Campo | Valor | |-------|-------| | **ID** | 0028 | | **Estado** | pendiente | | **Prioridad** | media | | **Tipo** | feature — C++ viz (cpp/functions/viz) | ## Dependencias `surface_plot_3d_cpp_viz` ya existe como **STUB**. Este issue quita el stub. **Desbloquea:** dashboards 3D (terreno, FFT 2D, height maps, scatter 3D para PCA/clustering visualizations). --- ## Objetivo 1. Vendorear [ImPlot3D](https://github.com/brenocq/implot3d) (MIT, header + cpp) en `cpp/vendor/implot3d/`. 2. Reescribir **`surface_plot_3d_cpp_viz`** (hoy STUB) con implementacion real. 3. Añadir **`scatter_3d_cpp_viz`** — scatter 3D con color/size por punto. 4. Demos en `primitives_gallery`. ## Contexto `surface_plot_3d_cpp_viz` aparece en el registry pero su `code` es `[STUB] requires ImPlot3D not vendored yet`. Bloquea apps de visualizacion cientifica (heightfield, terreno, superficies parametricas). ImPlot ya esta vendoreado y se usa para 2D. ImPlot3D es del mismo autor (brenocq), API parejo a ImPlot, con tres-axis y rotacion drag-to-orbit. ## Arquitectura ``` cpp/ ├── vendor/implot3d/ # NEW │ ├── implot3d.h │ ├── implot3d.cpp │ ├── implot3d_internal.h │ ├── implot3d_items.cpp │ └── implot3d_demo.cpp # opcional, util como referencia ├── functions/viz/ │ ├── surface_plot_3d.cpp/.h # MOD — quitar STUB │ ├── surface_plot_3d.md # MOD — actualizar tags/notes/code │ ├── scatter_3d.h # NEW │ ├── scatter_3d.cpp # NEW │ └── scatter_3d.md # NEW └── apps/primitives_gallery/ ├── demos_3d.cpp # NEW ├── demos.h # MOD ├── main.cpp # MOD └── CMakeLists.txt # MOD cpp/CMakeLists.txt # MOD — añadir sources de implot3d ``` ### API propuesta ```cpp namespace fn { struct SurfacePlot3DConfig { const float* z; // size = nx * ny, row-major int nx, ny; float x_min = 0.f, x_max = 1.f; float y_min = 0.f, y_max = 1.f; const char* x_label = "x"; const char* y_label = "y"; const char* z_label = "z"; ImVec2 size = {-1, 400}; bool show_colormap = true; }; void surface_plot_3d(const char* title, const SurfacePlot3DConfig& cfg); struct Scatter3DConfig { const float* xs; // size = n const float* ys; const float* zs; const float* sizes = nullptr; // opcional: size = n const ImU32* colors = nullptr; // opcional: size = n int n; ImVec2 size = {-1, 400}; }; void scatter_3d(const char* title, const Scatter3DConfig& cfg); } ``` ## Tareas ### Fase 1 — Vendor - 1.1 Clonar ImPlot3D, copiar fuentes a `cpp/vendor/implot3d/`. Pinear a tag/commit conocido. - 1.2 Inicializar contexto en `app_base` (similar a como ya inicializa ImPlot): `ImPlot3D::CreateContext()` / `DestroyContext()`. - 1.3 Añadir sources al `cpp/CMakeLists.txt`. ### Fase 2 — surface_plot_3d real - 2.1 Reescribir `surface_plot_3d.cpp/.h` con la API de arriba usando `ImPlot3D::PlotSurface`. - 2.2 Actualizar `surface_plot_3d.md`: quitar tag `stub`, actualizar `code`, añadir `uses_functions: []` y `tags: ["3d", "viz"]`. ### Fase 3 — scatter_3d - 3.1 Implementar `scatter_3d.cpp/.h` con `ImPlot3D::PlotScatter`. Soportar size/color por punto. - 3.2 `scatter_3d.md` con frontmatter (`kind: component`, `purity: pure`). ### Fase 4 — Gallery demos - 4.1 `demos_3d.cpp` con dos demos: - `demo_surface_plot_3d()`: malla 64×64 con `z = sin(x)*cos(y)`. Sliders para frecuencia. - `demo_scatter_3d()`: 500 puntos con clusters sinteticos (3 clusters), colores por cluster. - 4.2 Registrar en gallery. ### Fase 5 — Tests + docs - 5.1 Test puro de generacion de datos (la rendering depende del contexto GL, asumir que el smoke-test es la propia gallery). - 5.2 `./fn index` + verificar `surface_plot_3d_cpp_viz` ya no es STUB. ## Ejemplo de uso ```cpp std::vector z(64*64); for (int j=0;j<64;j++) for (int i=0;i<64;i++) z[j*64+i] = std::sin(0.2f*i) * std::cos(0.2f*j); fn::SurfacePlot3DConfig s{}; s.z = z.data(); s.nx = 64; s.ny = 64; fn::surface_plot_3d("terreno", s); ``` ## Decisiones de diseño - **ImPlot3D vs Plotly export**: ImPlot3D mantiene la coherencia con ImPlot 2D que ya usamos. Sin dependencias extra. - **Render-only por ahora**: pan/zoom/orbit las aporta ImPlot3D nativo. ## Riesgos - **ImPlot3D inestable**: pinear commit; documentar version exacta en `cpp/vendor/implot3d/README.md`. - **Performance con malla grande**: documentar limite practico (~256×256 antes de notar drops).