news 2026/10/13 13:20:58

CAD Sketcher 用户界面详解:Sketcher 侧边栏、Gizmo 标注与偏好设置的实现剖析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CAD Sketcher 用户界面详解:Sketcher 侧边栏、Gizmo 标注与偏好设置的实现剖析
  • 桌面应用
  • 3D建模

【免费下载链接】CAD_Sketcher

Constraint-based geometry sketcher for blender

项目地址:https://gitcode.com/gh_mirrors/ca/CAD_Sketcher
点击查看免费下载

本文围绕 Blender 约束草图扩展 CAD Sketcher 的用户界面文档展开,完整讲解 N 侧边栏(Sketch Selector、Tools、Entity/Constraint Browser)、约束 Gizmo 与上下文菜单的交互方式,并结合 base/preferences.py 等源码逐项补充偏好设置项的默认值、取值范围与底层实现,帮助开发者既会用 UI,也能理解每个开关背后的代码路径。

Sketcher 侧边栏总览

扩展在 N 侧边栏的 "Sketcher" 分类下挂接了若干面板:可以从中设置活动草图(active sketch)、访问草图属性、添加约束,并通过元素浏览器(browsers)与几何元素交互。

从 ui/init.py 的注册列表可以看到整个侧边栏的组成:

  • VIEW3D_PT_sketcher:Sketch Selector 面板(选择/进入草图),实现在 ui/panels/sketch_select.py;
  • VIEW3D_PT_sketcher_tools:Tools 面板,实现在 ui/panels/tools.py;
  • VIEW3D_PT_sketcher_entities:实体浏览器,实现在 ui/panels/entities_list.py;
  • VIEW3D_PT_sketcher_constraints:约束浏览器,实现在 ui/panels/constraints_list.py;
  • 另外还注册了VIEW3D_UL_features特征列表和若干菜单(VIEW3D_MT_selected_menu、VIEW3D_MT_slvs_part等)。

Sketch Selector:进入与离开草图

没有活动草图时,侧边栏会列出当前所选 part 范围内的全部草图,可以从那里把某个草图设为活动状态,或切换其可见性。由于草图本身是纯源数据(source),在视口中保持隐藏,眼睛图标切换的其实是它被实体化(realise)到的 body——那才是屏幕上代表它的东西。

一旦有草图处于活动状态,UI 会切换形态:出现一个醒目的(按下状态的)蓝色按钮用于退出草图,下方显示该草图及其所在 workplane 的属性。对照 ui/panels/sketch_select.py 的sketch_selector函数:

  • 无活动草图时绘制Add Sketch按钮(通过StatefulOps.InvokeTool调用AddSketch工作区工具),旁边还有一个下拉菜单,包含较不常用的自由 3D 草图模式(Add 3D Sketch算子,见 operators/add_sketch_3d.py);
  • 有活动草图时绘制Leave: <name>按钮(depress=True的SetActiveSketch,sketch_name置空即离开草图),并在sketch.geometry_solved为假时把整行标红告警,旁边还有Update刷新按钮;
  • 进入草图后还会显示求解状态:若solver_state != "OKAY"则显示状态名与图标,否则显示自由度(dof)——"Fully defined sketch" 或 "Degrees of freedom: n"。

_draw_workplane函数还会展示 workplane 及其 face anchor:锚定在网格面上时显示"<mesh>, face <index>"形式的锚点名称;当锚点与面脱离(KEY_DETACHED)时以红色 "Detached from face" 告警,并可通过下拉菜单执行 "Make Workplane Free" 解除锚定。

Tools Panel:作用于整个草图的工具

Tools 面板收纳的是"作用于整个草图而非单个元素"的工具:Merge Points、Project Geometry,以及添加约束的按钮组。不在草图内时,这里改为提供 Make Part 和 Add Assembly。

约束按钮有两种布局,通过 "Constraints" 标题行右侧的图标切换:紧凑的icon grid(默认)或带约束名称的列表。无论哪种布局,尺寸约束(dimensional)都与几何约束(geometric)分开排列,并且只显示适用于当前草图模式的约束。

ui/panels/tools.py 的实现印证了这些细节:

  • 布局开关直接切换偏好项constraint_grid_view(见base/preferences.py中该属性,默认True,即默认网格视图)。切换按钮使用wm.context_toggle算子而非普通的属性勾选框——源码注释解释得很直白:勾选框会把图标染成开/关状态色(白/黑),而算子图标始终跟随主题;
  • 网格视图下用grid_flow(columns=5)排布纯图标按钮(约束名仍在 tooltip 中显示),尺寸约束单独成行一个网格,与几何约束网格同列数同缩放,保证按钮尺寸一致;列表视图下则按kind.title()显示名称;
  • 3D 草图(sketch.is_3d)下会过滤按钮:只保留求解器实际派发的约束(declarations.Supported3DConstraintOperators与Supported3DDimensionKinds),采用"隐藏而非禁用"的策略,让可见按钮在网格中保持无缝的合并布局;
  • 面板底部还有Drawing:区域,显示场景属性scene.sketcher.use_construction(构造线开关)。

不在草图内时,_draw_node_tools改为列出节点修改器工具:NodeExtrude、NodeRevolve、NodeArrayLinear、NodeArrayCircular、NodeBoolean。

Entity Browser 与 Constraint Browser

Entity Browser(bl_label = "Entities")列出当前全部 active entities,每种类型配一个图标,点击名称即可选中。从 ui/panels/entities_list.py 可以看到每行的完整结构:

  • 数据直接读取草图 curve data 上的属性字段curve_id、sketch_type、visible、construction、name——如果curve_id或sketch_type缺失整个面板就不渲染;
  • 行首是两个小开关:Select算子(mode="TOGGLE",按 curve_id 切换选中,选中行整行标红提示)和SetCurveFlag算子(flag="visible"切换可见性);
  • 名称字段本身是RenameCurve算子,点击即可重命名,行首图标由icon_manager.get_entity_icon(ctype, construction)给出,构造线显示虚线样式;
  • 行尾是ContextMenu算子(打开该实体的上下文菜单,悬停时高亮实体)和DeleteEntity删除按钮。

Constraint Browser(bl_label = "Constraints")列出当前全部 active constraints,分为 Dimensional 与 Geometric 两组——这与sketch.constraints.dimensional/sketch.constraints.geometric两个集合一一对应(见 ui/panels/constraints_list.py 的draw方法)。每行包含:

  • visible开关(图标式勾选)与约束类型图标(icon_manager.get_constraint_icon_for_type);
  • 可编辑的约束名称字段;
  • 可编辑的数值字段。源码注释指出一个实现细节:尺寸约束的数值实际存在场景自定义属性scene["slvs:c:{uid}"]中,列表绘制的是这个端点(endpoint),以此保持数值可编辑、且方便挂驱动(driver);
  • 求解失败的约束(constraint.failed)右侧显示ERROR图标;
  • 行尾DeleteConstraint按钮,highlight_hover与highlight_members为真,悬停时同时高亮该约束及其作用的几何;
  • 顶部的Show All/Hide All按钮调用SetAllConstraintsVisibility算子(visibility="SHOW"/"HIDE"),一次性切换整个草图的约束 gizmo 显隐。

Gizmos:约束的视口标注

Gizmo 用于在视口中显示约束:三种尺寸约束(angle、distance、diameter)各有专用 gizmo 类型,点击其 gizmo 可打开菜单来调整约束的设置。

其余约束使用通用 gizmo,显示在其依赖的实体旁边;点击这样的 gizmo 要么打开约束设置菜单,要么在约束没有可设置项时直接删除它。

源码层面(gizmos/constraint.py 与 gizmos/base.py)的分工是这样的:

  • VIEW3D_GGT_slvs_constraintgizmo group 为每个尺寸约束新建一个VIEW3D_GT_slvs_constraint_valuegizmo(gz.type/gz.index指向具体约束),并通过target_set_operator(Operators.TweakConstraintValuePos)绑定拖拽修改数值的算子。尺寸数值文本由_get_formatted_value格式化:LENGTH 单位走units.format_distance(diameter 约束若处于半径模式下前缀 "R"),ROTATION 单位走units.format_angle;
  • 所有几何约束共享一个VIEW3D_GT_slvs_constraintgizmo。源码注释解释了动机:按约束逐个建 gizmo 意味着每次重绘/移动鼠标都要做每约束一次 Python 调用。这个单一 gizmo 的test_select直接根据 drawing/constraint_icons.py 中绘出的图标位置回答命中测试,每个图标是一个 part,绑定到对应约束的ContextMenu算子(delayed=True,等鼠标抬起再弹菜单,避免点击的 RELEASE 穿透触发菜单里的 "Delete");
  • 尺寸 gizmo 的箭头/辅助线(helpline)几何只在_shape_signature变化时重建——签名涵盖数值、draw offset、basis 矩阵和视图缩放,静态视口(包括 modal 拖拽期间的所有重绘)不会每帧重新上传 GPU batch。

图标分组:位于同一元素上、或在屏幕上会重叠的约束图标会被绘制成一个带计数(count)的图标,悬停展开分组即可触达单个约束。这一行为可以在偏好设置的 "Group Constraint Icons" 中关闭。对应实现在 drawing/constraint_icons.py:该模块头部注释说明所有几何约束图标现在用一次批量绘制从同一纹理图集(texture atlas)中完成——早期每个 gizmo 各自绘制一次带采样器的纹理,约束很多时会在 Vulkan 后端耗尽描述符池(VK_ERROR_OUT_OF_POOL_MEMORY)。分组的颜色优先级为 highlight > failed > reference,分组展开由光标悬停(constraint_icons.pick)驱动。

Context Menu:元素属性与操作

上下文菜单用来访问一个元素的属性和操作,有三种入口:

  1. 悬停某个实体后按鼠标右键;
  2. 点击支持该功能的约束 gizmo;
  3. 元素浏览器中对应的按钮。

INFO:上下文菜单只使用悬停的实体,忽略当前选中(selection)。

operators/context_menu.py 的View3D_OT_slvs_context_menu.execute印证了这一点:实体路径取selection.hover(或显式传入的curve_id),约束路径按type+index在get_active_constraints中定位。菜单内容:

  • 实体:通过seed_entity_editor把实体设置(名称、点坐标)载入内联编辑器,由element.draw_props绘制;随后是分隔线和红色警示行的Delete按钮,原点(is_origin)受保护,Delete 置灰;
  • 约束:绘制约束的draw_props(即"设置"),再加DeleteConstraint按钮——这就是文档所说"没有设置可显示时点击直接删除"的来源;
  • 什么都没悬停到(element为 None)时回退到 Blender 默认的VIEW3D_MT_selected_menu对象菜单;
  • delayed=True时算子以 modal 方式运行,鼠标抬起(RELEASE)才执行,用于 gizmo 点击场景。

另外,ui/panels/entities_list.py 行尾的ContextMenu按钮把curve_id直接传给算子并设highlight_hover=True,这就是浏览器入口的实现。

Preferences:偏好设置逐项解析

在 Blender 中通过Edit > Preferences > Add-ons > CAD Sketcher展开已启用的扩展即可访问偏好设置。

Interface

一切关于扩展在视口中如何绘制与表现:淡出非绘制目标对象、将视图对齐到活动实体、实体大小、workplane、约束图标、文字与箭头的尺寸,以及是否把落在同一元素上的约束图标分组合并。

对照 base/preferences.pyPreferences.draw中 "Interface" 分组,各属性及其默认值/范围如下:

属性含义默认值取值范围
auto_hide_objects草图模式下淡出曲线/网格True—
use_align_view激活草图时自动把视图对齐到 workplaneTrue—
entity_scale实体绘制缩放1.0min 0.1,soft_max 3.0
workplane_sizeworkplane 显示大小0.4soft 0.1–1.0
gizmo_scale约束图标缩放18.0min 1.0,soft_max 25.0
group_constraint_icons同元素约束图标合并为一个带计数的图标True—
text_size数值文本字号15min 5,soft_max 25
arrow_scale箭头缩放1.0min 0.2,soft_max 3.0

其中entity_scale与gizmo_scale带有update=theme.update回调(base/theme.py),修改后立即对所有 VIEW_3D 区域执行tag_redraw。"淡出"的实际消费点在 operators/utilities.py:fade_objects = get_prefs().auto_hide_objects在进入草图时据此淡出场景对象;use_align_view则在 operators/utilities.py 与 operators/workplane_anchor.py 中被读取,决定是否调用view3d.view_axis对齐视图。

Geometry

  • Curve Resolution— 圆弧与圆被网格化(mesh)时每边的最大夹角。它是新草图的默认值;每个草图在自己的 Convert modifier 上保留各自的数值,见 integration。对应属性curve_angular_resolution,subtype="ANGLE",默认math.radians(7.5),范围 0.1°–90°,描述文本明确提示可在该草图的 "CAD Sketcher Convert modifier" 上按草图修改;
  • Boolean Solver— 新布尔运算使用的求解器,Exact 或更快的 Manifold,之后可逐布尔修改。属性boolean_solver默认"Manifold",选项来自 utilities/boolean_nodes.py 的SOLVER_ITEMS:Exact 对不完美几何稳健但慢,Manifold 快得多但只处理干净的闭合网格(非流形输入会被丢弃)。偏好项描述提到 Manifold 约为另一求解器七倍快,且遇到处理不了的输入会自行回落到 Exact。

Units

决定数值显示所用的精度:公制小数位、英制分数、角度小数位。

实现集中在 units.py:

  • decimal_precision:IntProperty,默认 3,min 0,soft_max 7,控制_format_metric_length的小数位数(按场景length_unit输出 m / cm / mm / µm / km,ADAPTIVE 或use_separate时走 Blender 内置bpy.utils.units.to_string);
  • imperial_precision:枚举1"/1/2"/1/4"/1/8"/1/16"/1/32"/1/64",由_inches_to_fraction把英寸值取整到对应分数并格式化为n-m⁄n″(英尺制再加′);
  • angle_precision:IntProperty,min 0,max 5,默认 0;format_angle按场景旋转单位输出°或rad。

注意这些格式函数读取的是当前场景的单位制(unit_settings.system),所以公制/英制切换即时生效,偏好项只是控制精度。

Advanced

  • "What's New" 对话框是否在扩展更新后显示(show_whats_new,默认True,对应 base/whats_new.py);
  • 启用 "Show Debug Settings"(show_debug_settings,默认False)会打开一些实验性功能,需谨慎使用。从 utilities/preferences.py 看,is_experimental()就是读这个开关,use_experimental(setting, fallback)在非实验模式下强制回退——这是实验功能进入各代码路径的统一门控;
  • 日志级别logging_level:枚举CRITICAL / ERROR / WARNING / INFO / DEBUG / NOTSET,默认值2(Warning),update回调on_logging_level_update直接logger.setLevel。

偏好面板顶部还有一组快捷链接("What's New" 算子、Documentation、Source Code、Report a Bug、Request a Feature、Discord),方便从面板直接跳转。

Theme

扩展用到的颜色都在 theme 部分定义;扩展同时支持主题预设(theme presets),包括适配浅色视口的 light 预设。预设体系由 base/preferences.py 顶部的SKETCHER_PT_theme_presets(继承PresetPanel)实现:preset_subdir = "bgs/theme"、preset_operator = "script.execute_preset"、preset_add_operator = "bgs.theme_preset_add"——即预设以 Python 脚本形式保存在扩展资源目录下的bgs/theme子目录,通过 Blender 标准的 preset 机制执行。

展开偏好项里的 "Theme" 开关后,list_props_recursiv会递归遍历theme_settings(base/theme.py 的ThemeSettings)的 RNA 属性并全部渲染出来,结构上分两组:

  • ThemeSettingsEntity:default、highlight、selected、selected_highlight、inactive、inactive_selected、fixed七种实体颜色;
  • ThemeSettingsConstraint:default、highlight、failed、failed_highlight、reference(引用测量)、text、text_highlight等约束颜色。

所有颜色项都带update=theme.update回调,改动即时重绘视口。约束的着色在 gizmos/utilities.py 的get_constraint_color_type与 gizmos/base.py 的_set_colors中被消费:失败约束用failed色、悬停高亮叠加*_highlight色,颜色按 gizmo 指针缓存(_gizmo_colors),只有真正变化时才写入,避免每帧无谓的属性设置。

主题预设脚本的存放路径可以在 Blender 的 Python 控制台执行以下语句获得:

bpy.utils.user_resource("SCRIPTS")

小结

CAD Sketcher 的 UI 是一条从面板到算子再到绘制层的完整链路:侧边栏面板(ui/panels/)负责状态展示与算子入口,gizmo 层(gizmos/)负责视口内的标注与命中测试,偏好设置(base/preferences.py)提供全局行为开关并被绘制与算子代码直接读取。理解这三层各自的职责,再配合 ui/selected_menu.py、operators/context_menu.py 等入口,就能在修改界面行为或排查 UI 问题时快速定位到对应代码。

  • 桌面应用
  • 3D建模

【免费下载链接】CAD_Sketcher

Constraint-based geometry sketcher for blender

项目地址:https://gitcode.com/gh_mirrors/ca/CAD_Sketcher
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/13 13:20:42

内核网络设备状态深度拆解:从ip link到ethtool的排障指南

刚接手一套线上系统的那段时间&#xff0c;一半以上的疑难网络故障&#xff0c;最后都落在三个字上面&#xff1a;看状态。确切地说&#xff0c;是看内核网络设备状态。 这里的“状态”不是 ping 通不通、网页能不能打开那么简单。在 Linux 网络栈里&#xff0c;一张网卡从物…

作者头像 李华
网站建设 2026/10/13 13:19:51

通达信公式迁移Python:向量化改写与性能优化实战

1. 为什么要把通达信公式搬到Python里做过A股量化或者自定义指标的朋友&#xff0c;大概率都写过通达信公式。这东西上手快&#xff0c;语法简单&#xff0c;几行代码就能画出均线、MACD、KDJ&#xff0c;盘中预警也方便。但真要把一套成熟的通达信策略拿去做回测、做参数寻优、…

作者头像 李华
网站建设 2026/10/13 13:19:50

Java校内二手交易系统毕设全攻略:从Spring Boot到小程序实战

1. 项目定位与需求拆解&#xff1a;为什么“校内二手交易”是最稳妥的毕设选题每年到二月底三月初&#xff0c;总有一批计算机专业的大四学生开始焦虑毕业设计选题。Java校内二手交易市场这套系统&#xff0c;我前前后后带人做过不下二十个版本&#xff0c;从最早SSH框架的JSP项…

作者头像 李华
网站建设 2026/10/13 13:19:06

从190页SAP方案到实施蓝图:叉车行业数字化转型指南

简介&#xff1a;一份190页PPT的公益资料&#xff0c;聚焦大型叉车集团数字化转型中SAP解决方案的整体落地路径&#xff0c;适合制造企业数字化负责人、ERP实施顾问及行业方案架构师研读。内容覆盖科技公司能力介绍、叉车集团业务理解与总体框架、销售板块营销与融资租赁、生产…

作者头像 李华
网站建设 2026/10/13 13:17:29

uniapp 对接融云 IM 与 RTC:单聊群聊音视频全链路落地实践

简介&#xff1a;这份资源面向使用 uniapp 开发即时通讯功能的移动端开发者&#xff0c;重点解决融云 IM 在聊天、群聊及单多人音视频通话场景下的对接难题。内容涵盖消息监听、消息撤回回执、分页获取聊天记录、会话未读数统计、免打扰时间设置、输入状态消息以及单人/多人语音…

作者头像 李华