Files
Viper_VRTE/vqt6/_bridge_canvas.h
T
TermiNexus 728d090815 feat(vqt6/vipermath/vipersimd/w32/requests): 自绘 Canvas/Graph3D/ChartView 与 Qt6 Charts、新增 gzip 与 torch-lite 模块, 修包装类悬垂指针与中文路径/exp/大文件下载
- vqt6: 包装类统一补 __new__ 堆分配, 修"创建函数栈帧 alloca"被存进字段/跨帧返回后 _ptr 悬垂(传给 QLayout::addWidget 等即崩溃); 菜单类按依赖顺序前移, menuBar()/statusBar() 改返回裸指针; 接入 Qt6 Charts 并新增 _bridge_canvas(Canvas 手绘板 / Graph3D 软件 3D 网络图 / ChartView 折线图); 新增自绘 QRadioButton(圆环+内点, 过渡动画)、剪贴板、应用级字体族 API
- 新增模块: gzip.vp(RFC1952/1951 解码器)、torch/(torch-lite 稠密张量 + conv/pool 前反向)
- vipersimd: 新增 scalar_fma/add/mul/sqrt_array 未向量化对照内核(与对应 SIMD 版逐位一致)
- w32: 新增 UTF-8/UTF-16 路径转换, CreateFile/CreateDirectory 走 W 系列, 修中文路径被按 GBK 误读; read_all 参数 max_count -> buf_size 并文档化"容量含终止符"契约
- requests: https 响应缓冲按需翻倍扩容(上限 256MB), 修 MB 级正文(如 MNIST .gz)被 4KB 静默截断
- vipermath: 重写 exp 为范围归约 + 短泰勒, 修负值发散(x=-30 得 3.7e10)与 NaN 触发 2^31 次缩放导致的卡死
- builtins: 新增 sizet/uzt 别名; stdarg: va_arg 参数 CType -> CPtr
- chore: 删除 vendored jpeg change.log
2026-09-10 23:09:05 +08:00

100 lines
5.6 KiB
C

// ============================================================
// vqt6/_bridge_canvas.h — 自绘控件 C 桥接声明
//
// 三个自绘控件(不依赖 Q_OBJECT/moc, 回调直接走 vqt6_trigger_slot):
// * Canvas — 手绘板 / 28x28 灰度图显示(带扫描线、网格)
// * Graph3D — 软件 3D 神经网络结构图(QPainter 透视投影)
// * ChartView — Qt Charts 折线图(loss/acc 曲线)
//
// 设计约定: Graph3D 的 API 与渲染后端无关(只暴露
// setup/set_values/set_edge_weights/set_layer_alpha/set_view),
// 将来若换成 OpenGL 后端, Viper 侧调用代码无需改动。
// ============================================================
#ifndef VQT6_BRIDGE_CANVAS_H
#define VQT6_BRIDGE_CANVAS_H
#include "_bridge.h"
#ifdef __cplusplus
extern "C" {
#endif
// ============================================================
// Canvas — 手绘板 / 28x28 灰度显示
// 坐标系约定: 内部统一用 0..1 归一化坐标, 与控件像素尺寸解耦
// ============================================================
VQT6_API void* vqt6_canvas_create(void);
VQT6_API void* vqt6_canvas_create_with_parent(void* parent);
VQT6_API void vqt6_canvas_clear(void* canvas);
VQT6_API int vqt6_canvas_has_ink(void* canvas);
VQT6_API void vqt6_canvas_set_mode(void* canvas, int mode); // 0=手绘 1=图像显示
VQT6_API int vqt6_canvas_mode(void* canvas);
VQT6_API void vqt6_canvas_set_pen(void* canvas, int r, int g, int b, double width_norm);
VQT6_API void vqt6_canvas_set_grid(void* canvas, int on); // 28x28 辅助网格
VQT6_API void vqt6_canvas_set_scan_line(void* canvas, int y_norm); // 0..1000, <0=关
VQT6_API void vqt6_canvas_set_bg(void* canvas, int r, int g, int b);
// 手绘内容 → 28x28 灰度(MNIST 预处理: 包围盒缩放到 20x20 后按质心居中); 无墨迹返回 0
VQT6_API int vqt6_canvas_to_mnist28(void* canvas, unsigned char* out);
// 28x28 灰度 → 显示(自动切到图像显示模式)
VQT6_API void vqt6_canvas_set_image28(void* canvas, const unsigned char* in);
// 笔迹完成(鼠标抬起)回调
VQT6_API void vqt6_canvas_connect_changed(void* canvas, vqt6_slot_callback_t cb, void* user_data);
// ============================================================
// Graph3D — 软件 3D 神经网络结构图
// 层布局: 每层按近正方形网格排在 XY 平面, 各层沿 Z 轴依次排列
// ============================================================
VQT6_API void* vqt6_graph3d_create(void);
VQT6_API void* vqt6_graph3d_create_with_parent(void* parent);
// layer_sizes: 自输入层到输出层各层节点数; 建立节点与前向全连接边
VQT6_API void vqt6_graph3d_setup(void* g, const int* layer_sizes, int n_layers);
VQT6_API void vqt6_graph3d_clear(void* g);
VQT6_API int vqt6_graph3d_node_count(void* g);
VQT6_API int vqt6_graph3d_edge_count(void* g);
// 逐层点亮: alpha 0..1(节点与相邻边同时生效)
VQT6_API void vqt6_graph3d_set_layer_alpha(void* g, int layer, double alpha);
VQT6_API void vqt6_graph3d_set_all_layer_alpha(void* g, double alpha);
// 每节点激活值(长度 = node_count), 取值 0..1, 影响节点亮度与半径
VQT6_API void vqt6_graph3d_set_values(void* g, const double* values, int n);
// 边权重(长度 = edge_count, 按层间顺序), 影响颜色/透明度, 并按 |w| 裁剪
VQT6_API void vqt6_graph3d_set_edge_weights(void* g, const double* w, int n);
VQT6_API void vqt6_graph3d_set_edge_threshold(void* g, double t); // |w|归一后低于此值不画
VQT6_API void vqt6_graph3d_set_edge_budget(void* g, int max_edges); // 最多画多少条(取 |w| 最大)
VQT6_API void vqt6_graph3d_set_view(void* g, double yaw_deg, double pitch_deg, double dist);
VQT6_API void vqt6_graph3d_get_view(void* g, double* yaw_deg, double* pitch_deg, double* dist);
VQT6_API void vqt6_graph3d_set_bg(void* g, int r, int gcol, int b);
VQT6_API void vqt6_graph3d_set_node_scale(void* g, double s);
VQT6_API void vqt6_graph3d_connect_view_changed(void* g, vqt6_slot_callback_t cb, void* user_data);
// 原点复位
VQT6_API void vqt6_graph3d_reset_view(void* g);
// ============================================================
// ChartView — Qt Charts 折线图(loss/acc)
// ============================================================
VQT6_API void* vqt6_chartview_create(void);
VQT6_API void* vqt6_chartview_create_with_parent(void* parent);
// 新增一条折线, 返回 series 句柄; right_axis!=0 时挂到右侧 Y 轴
VQT6_API void* vqt6_chartview_add_line(void* view, const char* name,
int r, int g, int b, int right_axis);
VQT6_API void vqt6_chartview_append(void* view, void* series, double x, double y);
VQT6_API void vqt6_chartview_clear_series(void* view, void* series);
VQT6_API void vqt6_chartview_clear_all(void* view);
// 按当前数据重算坐标轴范围(左轴/右轴各自独立)
VQT6_API void vqt6_chartview_autoscale(void* view);
VQT6_API void vqt6_chartview_set_title(void* view, const char* utf8);
VQT6_API void vqt6_chartview_set_legend_visible(void* view, int visible);
VQT6_API void vqt6_chartview_set_background(void* view, int r, int g, int b);
// 滑动窗口: 每条折线超过 max_points 时丢弃最旧的点(max_points<=0 表示不限制)
VQT6_API void vqt6_chartview_set_max_points(void* view, int max_points);
// 打开(或复用)只读大窗; 同一 view 只建一次, 关闭仅隐藏不销毁
VQT6_API void* vqt6_chartview_open_zoom(void* view, const char* title);
// 把源图当前曲线与轴范围同步到大窗(仅在大窗可见时生效)
VQT6_API void vqt6_chartview_sync_zoom(void* view);
#ifdef __cplusplus
}
#endif
#endif // VQT6_BRIDGE_CANVAS_H