- Introduced tests for color image handling, ensuring source preservation and premultiplied alpha usage. - Implemented tests for brush stroke operations, validating segment boundaries and brush anti-aliasing. - Added tests for frame anti-aliasing, confirming correct rendering behavior with various alpha values and depth settings. - Created tests for frame projection, ensuring accurate overlap calculations and half-plane clipping. - Developed tests for image premultiplied retention, verifying behavior during loading and packing processes. - Added undo functionality tests for mask operations, ensuring single transaction behavior during edits.
10 KiB
Common 公共函数
src/anyimage/common/ 按 AI、Image、Selection、Viewport、Depth、Material、Object 和 Node 八个业务模块提供 Blender 侧复用能力。调用方直接从对应模块导入函数。
Image 数据块
image.py 处理 Blender Image 数据块及其在 Image Empty 上的完整生命周期,包括像素读取、动画帧、Job 输入、结果 Image 创建和 Empty 引用替换。
| 函数 | 职责 |
|---|---|
image.is_image_empty() |
判断对象是否为带有效 Image 数据的 Empty。 |
image.require_image_empty() |
按名称取得 Image Empty;对象已失效时抛错。 |
image.image_pixels() |
以 Blender 原始顺序读取一维 float32 像素。 |
image.image_rgba() |
读取为 Top-down RGBA float32 数组。 |
image.homography_from_points() |
求解四点之间的 Homography。 |
image.projective_output_size() |
按源像素密度、目标宽高比和资源上限计算投影输出尺寸。 |
image.premultiplied_rgba() |
将 Blender 顺序像素转换为 Top-down 预乘 Alpha RGBA。 |
image.sample_premultiplied_rgba() |
在图片边界坐标中双线性采样预乘 Alpha RGBA,范围外返回透明。 |
image.straight_rgba() |
转换为 straight RGBA,并把相邻可见 RGB 扩展到一圈透明边缘。 |
image.warp_projective_pixels() |
将源 Quad 重采样为矩形 Blender Image 像素。 |
image.video_total_frames() |
返回 Movie 或 Sequence 总帧数,静态图返回 1。 |
image.image_user_settings() |
读取 Image Empty 的帧起点、偏移、时长和循环设置。 |
image.default_extract_frames() |
取得当前 Empty 默认应处理的帧数。 |
image.source_start_frame() |
从源 Image Empty 取得 Job 应处理的起始帧。 |
image.prepare_image_input() |
将 Packed、Dirty、Sequence 等输入准备为 Job 可读路径,并返回临时标记。 |
image.prepare_image_bounds_input() |
复用调用方已读取的 RGBA,按几何 bounds 写出保留原始 Alpha 的矩形 Job 输入。 |
image.cleanup_image_input() |
清理由图片输入 helper 创建的临时文件或目录。 |
image.image_base_name() |
去除图片或视频扩展名和 Blender 数字后缀,得到数据块基础名。 |
image.depth_data_name() |
生成 Depth 结果数据块文件名。 |
image.color_data_name() |
生成 Color 结果数据块文件名。 |
image.load_image_edit_result() |
加载、Pack 并配置直接编辑源 Image 的 Job 结果,以源 Image 完整名称请求新数据块名称。 |
image.load_color_result_image() |
加载、命名、Pack 并配置材质 Color 或 Sequence 结果;不修改 Empty。 |
image.load_normal_result_image() |
加载、命名、设为 Non-Color 并 Pack Normal Map。 |
image.load_packed_rgba_image() |
加载已有 RGBA 文件,继承源图颜色空间和 Alpha mode,命名并 Pack。 |
image.create_image_edit_result() |
从本地编辑后的 RGBA 像素创建 Packed Image,以源 Image 完整名称请求新数据块名称;不修改 Empty。 |
image.replace_empty_image() |
执行 Image Empty 结果替换、共享引用分流、旧数据清理、帧设置继承和可选画布对齐。 |
image.image_empty_bounds() |
计算 Image Empty 在对象局部坐标中的实际显示边界。 |
Remove Background、Upscale、Frame、Mask 与 Rectify 都属于直接 Image 编辑,结果保留 active 或源 Image 数据块的完整名称,包括名称中的 .png 等格式文字。源数据仍被其他对象引用时,重名结果由 Blender 自动追加数字后缀;源数据可清理时,替换入口让结果恢复准确原名。color_data_name()、depth_data_name()、normal_data_name() 仅用于 Plane 与 Cutout 等材质派生贴图。
Image Selection 与视图交互
这组公共能力使用固定术语:
- Selection 是用户在图片空间圈定的业务范围;
SelectionPath只保存路径点,并提供 JSON 编解码。 SelectionMask是 Selection 的纯几何栅格化结果,只包含局部像素权重values和源图几何bounds。- Mask 表示二维像素权重或 Alpha 运算。
viewport.py 处理 View3D 中的点击、坐标投影、ImageGesture 和 Overlay 绘制;它为 Lasso、Brush 与 Polyline 提供对应状态机,Brush 拖动阶段只维护简化后的屏幕路径及 Overlay、提交共用的圆形印记和连接条。selection.py 负责图片空间 Selection 的值、栅格化和 Alpha 修整;SelectionPath → SelectionMask 只在图片编辑或 Shape 生成阶段执行。Frame 在自身业务模块中组合冻结的 Viewport 投影矩阵与对象世界矩阵,把屏幕像素映射到 Image Empty 局部平面;正交视图接受任意有限深度,透视视图只采样观察方向前方的有效交点。
Viewport 对象命中继续由 Blender 原生点选决定。Mask、Rectify 与 Cutout 点到另一对象时只保留原生选择结果;没有命中对象时保留当前 active Image Empty,并把透明区域或 Viewport 空白作为图片操作起点。Frame 的普通空白点击继续清空选择。手势是否与图片范围或可见内容有效相交,由各业务在提交阶段判断。
所有 Path 使用 non-zero winding 填充,同方向重复绕行的重叠区域保持选中。栅格器按路径边与像素中心扫描行的交点累计 winding,只建立 Path Bounds 的局部画布,抗锯齿时增加 2 px 边缘。栅格阶段不接收图片 Alpha 或颜色,Mask 与 Cutout 在各自业务层组合几何 Mask 和图片 Alpha。
Viewport 交互
| 函数 | 职责 |
|---|---|
viewport.report_image_edit_exception() |
将可预期的 Selection 警告和异常映射为 Operator Report。 |
viewport.image_edit_poll() |
判断当前上下文是否允许启动图片编辑工具。 |
viewport.resolve_image_edit_click() |
执行原生点选;点到另一对象时只保留选择结果,空命中时保留 active Image Empty 并开始点选型编辑。 |
viewport.active_image_edit_source() |
要求并取得当前 Selection 内的 active Image Empty。 |
viewport.image_edit_selection_keymap() |
创建普通点击和 Shift 点击的对象选择 keymap,并配置普通点击的空命中策略。 |
viewport.image_edit_drag_keymap() |
创建拖动图片手势及对象点选 keymap。 |
viewport.image_edit_point_keymap() |
创建点选型图片手势及 Shift 追加选择 keymap。 |
viewport.active_view3d_tool_id() |
取得当前 View3D Workspace Tool ID。 |
viewport.draw_dashed_line() |
绘制手势或透视框虚线。 |
viewport.draw_polygon_fill() |
绘制手势或透视框填充预览。 |
viewport.ImageGesture |
复用 Lasso、Brush 与 Polyline 的 Modal 生命周期、源图解析和 Overlay 绘制。 |
viewport.brush_footprint_polygons() |
生成 Brush Overlay 与释放提交共用的圆形印记和连接条。 |
viewport.preview_union_geometry() |
在 screen-space scanline bands 中融合 Brush Primitive,并返回一次填充与外轮廓虚线。 |
viewport.preview_fill_geometry() |
三角化 Lasso、Polyline 的 non-zero winding 填充与外轮廓。 |
viewport.rectangle_screen_path() |
将两个屏幕点规范为 Frame 使用的矩形四角。 |
viewport.screen_path_to_image_pixels() |
将屏幕路径投影为 Image Empty 像素坐标。 |
viewport.serialize_matrix() |
将 4×4 Matrix 序列化为 Operator 可保存的字符串。 |
viewport.deserialize_matrix() |
恢复已序列化的 4×4 Matrix。 |
viewport.drawing_in_region() |
判断 Modal 绘制是否仍位于启动时的 Area 和 Region。 |
Selection 栅格化
| 函数 | 职责 |
|---|---|
selection.selection_path_bounds() |
校验 Selection Path 并返回整数像素包围框。 |
selection.rasterize_selection_path() |
以局部 non-zero scanline 把 SelectionPath 栅格化为纯几何 SelectionMask。 |
selection.trim_pixels_to_alpha() |
按 Alpha 非零区域修整 RGBA 像素。 |
Depth 产物
depth.py 负责 Blender 侧共享的 Depth 文件加载和相机尺度换算,直接加载 Server 写出的 EXR。
| 函数 | 职责 |
|---|---|
depth.load_depth_metadata() |
读取并校验 depth.json 中的图片尺寸、相机内参与参考深度。 |
depth.load_depth_result_image() |
直接加载、命名、设为 Non-Color 并 Pack vector-depth.exr 或 z-depth.exr。 |
depth.camera_depth_values() |
从已加载 Depth Image 读取用于本地标定的 Z 与有效区。 |
depth.depth_uniform_scale() |
根据相机内参、参考深度和 Image Empty 范围计算统一尺度。 |
Object 构建
material.py 构建 Image 材质;object.py 处理 Object 与 Geometry Nodes Modifier;node.py 加载节点资产。
| 函数 | 职责 |
|---|---|
node.load_node_group() |
从随扩展分发的 Blend 资产加载指定 Node Group。 |
material.create_image_material() |
从 Image Empty 创建包含颜色、位移、Normal Map、Alpha 和动画设置的完整材质;非 Shadeless 材质由 Color 直接驱动 Principled IOR Level。 |
object.modifier_input_identifier() |
按接口名称解析 Geometry Nodes Modifier 输入 Identifier。 |
object.set_modifier_input() |
跨受支持 Blender RNA 形式设置 Modifier 输入。 |
object.finalize_object_result() |
激活结果对象,并按需替换或保留源 Empty。 |
AI 准备
ai.py 统一处理 AI 功能的 Environment、模型、Device、输入校验、Job 参数和公共 UI。
| 函数 | 职责 |
|---|---|
ai.draw_ai_setup() |
绘制 AI 未就绪时的安装入口,并返回当前状态。 |
ai.draw_ai_property() |
按 AI 就绪状态绘制并启用业务属性。 |
ai.require_input_path() |
解析 Blender 路径并要求其为现存文件或目录。 |
ai.require_background_input_path() |
在通用路径校验之外限制 BEN2 支持的媒体类型。 |
ai.production_device() |
读取正式任务使用的计算设备。 |
ai.require_environment() |
要求 AnyImage AI Environment 已就绪。 |
ai.invoke_ai_setup_if_needed() |
Environment 未就绪时启动安装交互。 |
ai.require_model() |
校验模型标识和下载状态,并返回模型记录。 |
ai.da3_parameters() |
组装 debug-da3 参数。 |
ai.moge2_parameters() |
组装 MoGe-2 正式任务与 Debug 共用参数。 |