【虚幻5蓝图Editor Utility Widget:创建高效模型材质自动匹配和资产管理工具,从3DMax到Unreal和Unity引擎_系列第二篇】
虚幻5蓝图Editor Utility Widget
- 一、基础框架搭建
- 背景:
- 1. 创建Editor Utility Widget
- 2.根控件选择窗口
- 3.界面功能定位与阶段
- 4.查看继承树
- 5.目标效果
- 二、模块化设计流程
- 1.材质替换核心流程:
- 2.完整代码如下
- 三、可视化界面UI布局
- 1. 添加标题栏
- 2. 构建滚动列表区域
- 3. 构建Apply按钮
- 4. Apply按钮点击功能添加
- 5. 变量模块分组
- 6. 新增变量`材质实例`
- 7.定义Python参数输入元素
- 8.整体展示:
- 四、代码的详细解析
- 1. 材质路径获取模块
- 2. 材质优先级配置模块
- 3. 静态网格材质处理模块
- 4. 骨骼网格材质处理模块
- 5. 批量处理主逻辑模块
- 五、Unreal API 关键用途总结
- 六、学习资源链接
一、基础框架搭建
背景:
在第一篇中【3DMax脚本MaxScript开发:创建高效模型虚拟体绑定和材质管理系统,从3DMax到Unreal和Unity引擎_系列第一篇】,设计了一个3Dmax模型虚拟体绑定和材质统一分配的插件,现在根据上一篇的工具设计,在UE5中用Editor Utility Widget来实现一个网格体材质自动匹配功能。
在UE5中,我将通过一个具体的逻辑结构和GUI设计示例,解决模型资产因多来源导致的材质命名混乱、手动分配效率低下等问题,对模型材质进行批量调控。
在UE5的Editor Utility Widget开发中设计一款网格体材质批量匹配工具。
通过可视化界面实现材质名称与网格体逻辑的自动化映射,简化美术流程并提升资源管理一致性。
1. 创建Editor Utility Widget
启用必要插件
:
- 打开 Edit > Plugins,搜索并启用 “Editor Scripting Utilities”(这是创建Editor Utility Widget的必要前提)。
通过主工具栏的"Add"菜单创建
:
- 选择 Editor Utilities > Editor Utility Widget。
右键创建
:
- 在内容浏览器(Content Browser)中,右键点击目标文件夹的空白区域。
- 选择
Editor Utilities
>Editor Utility Widget
。
这里我创建后命名为“BP_Widget_BatchAssignMaterials
”,并将其保存至/Game/BatchAssignMaterials
目录下。接下来,我们将逐步实现UI布局、数据绑定和核心逻辑。
学习资源推荐
- Editor Utility Widgets 官方指南
- Editor Scripting 插件说明
- UMG UI设计教程
2.根控件选择窗口
- 虚幻引擎创建Editor Utility Widget时的根控件选择窗口,创建后弹出这个窗口,选择一个根控件作为UI的基础。
- 选择一个合适的根控件,这里我选择“
Stack Box
”,点击“Select
”按钮。
控件分类系统
- COMMON区:推荐布局容器(Stack Box/Grid Panel),适合快速构建基础界面框架
- ALL CLASSES区:提供完整控件库(含20个可用项),支持EditorUtility系列专用组件
- Stack Box:支持垂直/水平自动排列(Orientation参数可配置)
- Grid Panel:表格布局容器(自动保持列宽一致性)
3.界面功能定位与阶段
下图里面展示了Unreal Engine的Editor Utility Widget设计界面。下图
- 左侧红框内是UI设计时的控件列表,按钮和布局组件,“
Tile Bar Area
”等元素。
其中“BP_Widget_BatchAssignMaterial
”的继承关系如下:
- 中间是设计区域,显示了具体的控件和属性设置,可视化拖拽布局,属性调试。
- 右侧红框则是“Batch Assign Materials”面板,列出了多种材质选项,这应该是运行时美术实际看到的界面。也是本次制作的目标效果。
区域 | 功能定位 | 对应阶段 |
---|---|---|
左侧红框区域 | UI设计面板(Editor Utility Widget 的控件库与层级管理) | 设计阶段 |
中间主区域 | UI编辑区(可视化拖拽布局,属性调试) | 设计阶段 |
右侧红框区域 | 运行时功能面板(用户实际操作的批量材质分配界面) | 运行阶段 |
Widget Blueprint学习资源推荐
Editor Utility Widgets 指南
4.查看继承树
创建完**
Editor Utility Widget
** 后,可以在Class Viewer中查看和搜索相关类。
在Unreal Engine上方菜单栏的 Tools > Class Viewer 打开窗口。如下图所示:
开发中的典型应用场景
想了解某个类的属性,可以在Class Viewer来查找或确认。
在开发过程中需要确认某个Widget的继承关系或属性是否正确设置,或者在处理资源路径过长的问题。
比如这里我的命名是BP_Widget_BatchAssignMaterials,
那么可以在层级结构Widget继承体系找到:Visual → Widget → UserWidget → EditorUtilityWidget → 当前类
继承关系节点 | 用途说明 |
---|---|
Visual | UI元素的基类,提供渲染能力。 |
Widget | UMG控件的核心父类,包含布局、交互等通用功能。 |
UserWidget | 用户自定义控件的直接父类,支持蓝图逻辑绑定。 |
EditorUtilityWidget | 专用于编辑器工具的子类,提供与Unreal编辑器交互的API(如菜单扩展、资产操作等)。 |
如需进一步扩展功能,可参考Unreal官方文档中的Editor Scripting Utilities 。
5.目标效果
二、模块化设计流程
1.材质替换核心流程:
思路如下:
2.完整代码如下
import unrealdef print_material_path(material_asset):if material_asset is None:print("材质未找到!")returnreturn material_asset.get_outer().get_path_name()MATERIAL_PRIORITY_LIST = [("Interior_Other_FrostedPlastic", print_material_path(plastic)),("Wheel_FrostedMetal", print_material_path(plastic)),("DaytimeRunningLight", print_material_path(daytime_running_light)),("RearRunningLight", print_material_path(backup_light)),("DoorOuterMirror", print_material_path(door_outer_mirror)),("RearLightGlass", print_material_path(rear_light_glass)),("FrostedPlasticRed", print_material_path(frosted_plastic_red)),("FrostedPlastic", print_material_path(frosted_plastic)),("glass1", print_material_path(glass1)),("WheelDisc", print_material_path(wheel_disc)),("GlassSkylight", print_material_path(glass_skylight)),("FrostedMetal", print_material_path(frosted_metal)),("BrakeLight", print_material_path(backup_light)),("BackupLight", print_material_path(backup_light)),("ClothDown", print_material_path(cloth_down)),("TurnLight", print_material_path(turn_light)),("Leather", print_material_path(leather)),("ClothUp", print_material_path(cloth_up)),("Chrome", print_material_path(chrome)),("Mirror", print_material_path(mirror)),("Paint", print_material_path(paint)),("CCAScreen", print_material_path(cca_screen)),("Plate", print_material_path(plate)),("Black", print_material_path(black)),("Int", print_material_path(int)),("Plastic", print_material_path(plastic)),("Glass", print_material_path(glass)),("WheelTire", print_material_path(wheeltire)),
]def process_static_mesh(staticmesh_assets):modified = Falsematerial_slots = staticmesh_assets.static_materialsfor index, material_slot in enumerate(material_slots):slot_name = str(material_slot.material_slot_name)matched_material = Nonefor keyword, material_path in MATERIAL_PRIORITY_LIST:if keyword.lower() in slot_name.lower():material = unreal.load_asset(material_path)if material:matched_material = materialbreakif matched_material:current_material = material_slot.material_interfaceif current_material != matched_material:staticmesh_assets.set_material(index, matched_material)modified = Trueunreal.log(f"StaticMesh替换成功:{staticmesh_assets.get_name()} [{slot_name}] -> {matched_material.get_name()}")return modifieddef process_skeletal_mesh(skeletal_mesh):modified = Falsematerials = list(skeletal_mesh.get_editor_property('materials'))for mat_idx in range(len(materials)):original_slot = materials[mat_idx]slot_name = str(original_slot.material_slot_name)target_material = Nonefor keyword, material_path in MATERIAL_PRIORITY_LIST:if keyword.lower() in slot_name.lower():target_material = unreal.load_asset(material_path)if target_material:breakif target_material:new_slot = unreal.SkeletalMaterial()new_slot.material_slot_name = original_slot.material_slot_namenew_slot.material_interface = target_materialmaterials[mat_idx] = new_slotmodified = Trueunreal.log(f"SkeletalMesh替换成功:{slot_name} => {target_material.get_name()}")if modified:skeletal_mesh.set_editor_property('materials', materials)return modifieddef batch_assign_materials():# 获取所有选中资产并过滤selected_assets = unreal.EditorUtilityLibrary.get_selected_assets()mesh_assets = [asset for asset in selected_assets if isinstance(asset, (unreal.StaticMesh, unreal.SkeletalMesh))]if not mesh_assets:unreal.log_warning("未选中有效的网格资产!如果Mesh插槽内已有资产,请查找资产后重新载入。")returntotal_meshes = len(mesh_assets)processed_meshes = 0with unreal.ScopedSlowTask(total_meshes, "批量替换材质中...") as slow_task:slow_task.make_dialog(True)for mesh_idx, mesh in enumerate(mesh_assets):if slow_task.should_cancel():breakprogress_percent = (mesh_idx + 1) / total_meshes * 100slow_task.enter_progress_frame(1, f"处理 {mesh.get_name()} ({progress_percent:.1f}%)")modified = Falseif isinstance(mesh, unreal.StaticMesh):modified = process_static_mesh(mesh)elif isinstance(mesh, unreal.SkeletalMesh):modified = process_skeletal_mesh(mesh)if modified:unreal.EditorAssetLibrary.save_loaded_asset(mesh)processed_meshes += 1result_msg = f"批量材质替换完成!成功处理 {processed_meshes}/{total_meshes} 个网格"unreal.log(result_msg)unreal.EditorDialog.show_message("操作完成", result_msg, unreal.AppMsgType.OK)if __name__ == "__main__":batch_assign_materials()
三、可视化界面UI布局
1. 添加标题栏
创建Window Title Bar Area
- 拖拽 Horizontal Box 到StackBox内,命名为
WindowTitleBarArea
。- 调整字体大小和颜色。具体的属性配置可以看着调整,不做详细的提示。
- 添加标题文本
- 在
Window Title Bar Area
内拖拽Text
,命名为TitleText
。
2. 构建滚动列表区域
静态网格列表(左侧)
- 拖拽
ScrollBox
到StackBox
内 → 命名为StaticMesh_ScrollBox
。
- 在
ScrollBox
内添加DetailsView
作为列表项容器。
添加滚动列表(ScrollBox)
,具体的属性配置可以看着调整,不做详细的提示。
骨骼网格列表(左侧)
可以直接复制上述操作完的结构,主要放置在**StackBox
**内。也可以直接重新拖入,更新命名 。
3. 构建Apply按钮
- 拖拽 Button 到StackBox内 → 命名为
Button_Apply
;
- 拖拽 Text 到Button_Apply内 → 设置文本为 “Apply”,背景色为绿色。
左侧为 蓝图逻辑编辑区(节点图表),右侧为 GUI设计界面(UMG可视化布局),中间红色箭头指示二者的 动态绑定关系。
4. Apply按钮点击功能添加
进入蓝图逻辑编辑
- 在UMG编辑器中,点击Button_Apply按钮,在Details面板中找到 Events 部分,点击On Clicked。这时界面自动跳转到 图表(Graph) 模式。
- 如果没有跳转可以在UMG编辑器顶部切换至 图表(Graph) 模式(非设计模式)。
此时会自动在图表中生成
OnClicked
事件节点。
将OnClicked
事件的输出引脚(白色箭头)连接到功能节点的输入引脚。
拖拽
OnClicked(Button_Apply)
事件的执行Exec
引脚(白色箭头),弹出检索窗口搜索**Execute Python Script
**功能,并链接节点的输入引脚。
演示如下:
5. 变量模块分组
- **
VARIABLES
** 是蓝图编辑器中用于集中管理当前蓝图所有变量的区域。
在蓝图中,Category 用于将变量、函数等元素按功能模块分组,提升可维护性。
在 Details 面板的Category
字段输入分类名称(如StaticMesh
)。
分组如下图
变量模块分组演示如下:
6. 新增变量材质实例
点击加号,新增变量
材质实例
输入接口,Assign Materials
:MaterialInterface
类型,存储待批量分配的材质实例。
材质实例的配置,根据项目需求,可能会有所不同。以下是我的材质实例命名和分类;
7.定义Python参数输入元素
8.整体展示:
黄颜色的表示:执行Python脚本节点(也就是**
Execute Python Script
**的蓝图节点),定义Python参数输入元素。
蓝色的表示:变量的节点展示。
整体展示如下:
四、代码的详细解析
1. 材质路径获取模块
def print_material_path(material_asset):if material_asset is None:print("材质未找到!")returnreturn material_asset.get_outer().get_path_name()
- 功能:获取材质资源的完整路径。
- 核心Unreal API:
material_asset.get_outer()
: 返回材质所属的外部对象(如Package)。get_path_name()
: 获取对象在Unreal中的完整路径(例如/Game/Materials/MyMaterial
)。
- 问题说明:
- 在
MATERIAL_PRIORITY_LIST
的print_material_path(plastic)
存在未定义变量问题,需确保plastic
等变量是已加载的材质实例。
- 在
2. 材质优先级配置模块
MATERIAL_PRIORITY_LIST = [("Interior_Other_FrostedPlastic", print_material_path(plastic)),# ... 其他条目
]
- 功能:定义材质插槽名称与目标材质的映射关系,按优先级匹配。
- 逻辑说明:
- 每个条目包含一个关键字(如
"FrostedPlastic"
)和材质路径。 - 通过字符串匹配插槽名称(不区分大小写)来动态加载材质。
- 每个条目包含一个关键字(如
3. 静态网格材质处理模块
def process_static_mesh(staticmesh_assets):material_slots = staticmesh_assets.static_materialsstaticmesh_assets.set_material(index, matched_material)
- 功能:遍历静态网格的材质插槽,按优先级列表替换材质。
- 核心Unreal API:
static_materials
: 获取静态网格的所有材质插槽(StaticMaterial
列表)。set_material(index, material)
: 替换指定索引的材质。load_asset(material_path)
: 根据路径加载材质资源。
- 关键操作:
- 通过插槽名称匹配关键字,动态加载并替换材质。
4. 骨骼网格材质处理模块
def process_skeletal_mesh(skeletal_mesh):materials = list(skeletal_mesh.get_editor_property('materials'))new_slot = unreal.SkeletalMaterial()skeletal_mesh.set_editor_property('materials', materials)
- 功能:处理骨骼网格材质,逻辑类似静态网格。
- 核心Unreal API:
get_editor_property('materials')
: 获取骨骼网格的材质列表。unreal.SkeletalMaterial()
: 创建新的骨骼网格材质插槽对象。set_editor_property()
: 修改骨骼网格的材质属性。
- 差异点:
- 骨骼网格材质需通过
SkeletalMaterial
对象封装。
- 骨骼网格材质需通过
5. 批量处理主逻辑模块
def batch_assign_materials():selected_assets = unreal.EditorUtilityLibrary.get_selected_assets()with unreal.ScopedSlowTask(...):unreal.EditorAssetLibrary.save_loaded_asset(mesh)
- 功能:批量处理选中的网格资产,支持进度条和撤销操作。
- 核心Unreal API:
EditorUtilityLibrary.get_selected_assets()
: 获取用户在内容浏览器中选中的资产。ScopedSlowTask
: 显示进度条,防止编辑器卡死。EditorAssetLibrary.save_loaded_asset()
: 保存修改后的资产。
- 流程控制:
- 过滤静态/骨骼网格 → 遍历处理 → 保存修改 → 反馈结果。
五、Unreal API 关键用途总结
API/属性 | 用途 |
---|---|
load_asset() | 根据路径加载资源(材质、网格等)。 |
set_material() | 替换静态网格的材质插槽。 |
get_editor_property() | 获取资产的编辑器属性(如材质列表)。 |
EditorUtilityLibrary | 处理编辑器交互(选中资产、弹窗等)。 |
ScopedSlowTask | 执行长时间任务时显示进度条。 |
六、学习资源链接
-
Unreal Python API 官方文档
https://docs.unrealengine.com/5.0/en-US/PythonAPI/ -
Editor Scripting 教程
https://docs.unrealengine.com/5.0/en-US/editor-scripting-in-unreal-engine/ -
StaticMesh API 参考
StaticMesh Class -
材质系统文档
Material System Overview
最终效果展示
相关文章:
【虚幻5蓝图Editor Utility Widget:创建高效模型材质自动匹配和资产管理工具,从3DMax到Unreal和Unity引擎_系列第二篇】
虚幻5蓝图Editor Utility Widget 一、基础框架搭建背景:1. 创建Editor Utility Widget2.根控件选择窗口3.界面功能定位与阶段4.查看继承树5.目标效果 二、模块化设计流程1.材质替换核心流程:2.完整代码如下 三、可视化界面UI布局1. 添加标题栏2. 构建滚动…...
机器学习第三篇 模型评估(交叉验证)
Sklearn:可以做数据预处理、分类、回归、聚类,不能做神经网络。原始的工具包文档:scikit-learn: machine learning in Python — scikit-learn 1.6.1 documentation数据集:使用的是MNIST手写数字识别技术,大小为70000,数据类型为7…...
php数据库连接
前言 最近在学习php,刚好学习到了php连接数据库记录一下 总结 //1、与mysql建立连接$conn mysql_connect("127.0.0.1","root","root");//设置编码mysql_set_charset(utf8);//2、选择要操作的数据库mysql_select_db("xuesheng…...
Android Studio学习记录1
Android Studio打包APK 本文为个人学习记录,仅供参考,如有错误请指出。本文主要记录在Android Studio中开发时遇到的问题和回答。 随着学习的深入,项目完成并通过测试之后免不了需要进入打包环节。这篇文章主要记录一下尝试打包APK的过程。我…...
【JAVA ee初阶】多线程(3)
一、出现线程安全的原因 1.【根本原因】线程的调度执行时随机的(抢占式执行)->罪魁祸首 2.多个线程同时修改同一个变量 如果是一个线程修改一个变量 或者 多个线程读取同一个变量 或者 多个线程修改不同变量 这些都没事。 3.修改操作不是原子的&a…...
【Java ee初阶】多线程(4)
一、java是怎么做到可重入的 java中,通过synchronized进行加锁,指定一个()包含了一个锁对象。(锁对象本身是一个啥样的对象,这并不重要,重点关注锁对象是不是同一个对象) 后面搭配…...
Day15(贪心算法)——LeetCode121.买卖股票的最佳时机55.跳跃游戏
1 LeetCode121.买卖股票的最佳时机(LeetCode121) 1.1 题目描述 题目描述如下: 示例如下: 1.2 问题分析及解决 要求最大利润,即当天与之前天的价格之差最大值。因此我们可以遍历数组,记录下当前遇到的最小值,然后用当天的价…...
2025汽车制造企业数字化转型路径参考
以应用场景作为切入点,引导相关企业推进数字化深度转型和规模化改造,是目前实践探索出来的一条可行路径。 汽车制造行业是相对集聚的制造业领域,通过搭建“转型场景图谱——转型通用工具——转型路径指引”分析框架,聚焦需求侧共…...
雷池WAF的身份认证 - GitHub
雷池支持通过 GitHub 认证的方式,让用户使用 GitHub 身份安全登录应用或网站。使用此功能需要 GitHub 账号 。 第一步:在 GitHub 创建一个 OAuth 应用 可参阅 GitHub 官方文档,创建一个 GitHub OAuth 应用,并获取应用的 ClientI…...
【Linux】第十二章 安装和更新软件包
目录 1. 什么是RPM? 2. dnf是什么,它和rpm有什么联系和区别? 3. RHEL 中如何做才能启用对第三方存储库的支持? 4. 怎么理解RHEL9中的应用流(Application Streams)和模块(Modules)? 5. RHEL9 有两个必要的软件存储…...
【权限模型】RBAC模型详解
大家好,我是jstart千语。今天给大家介绍一下鉴权模型RBAC,传统的鉴权模式就是基于用户和权限之间的多对多关系。而RBAC就更加的精准,更好管理。 RBAC介绍 RBAC(Role-Based Access Control)是一种通过角色(…...
tree命令
tree [选项] [目录...] 指定要显示的目录。如果没有指定目录,tree 会显示当前目录及其子目录结构。 常用选项 -a 显示所有文件和目录,包括隐藏文件(以 . 开头的文件)。 -d 只显示目录,不显示文件。 -L LEVEL …...
【Vue.js】组件数据通信:基于Props 实现父组件→子组件传递数据(最基础案例)
概览 前言父子通信流程关键技术点关键规则 实战1. 在父组件中注册子组件2. 子组件接收父组件传入的数据补充与总结 前言 在 Vue 3 中,父组件向子组件传递数据是通过props实现的。父组件在子组件的标签上绑定数据,子组件通过定义props接收这些数据。这种…...
信创时代技术栈选择与前景分析:国产替代背景下的战略路径与实践指南
🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,10年以上C/C, C#, Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C、C#等开发语言,熟悉Java常用开…...
Python内置方法干货总结
如果你还在为提升Python代码能力发愁,那么掌握内置方法就是你的捷径!很多初学者和进阶者忽略了这一“宝藏”,其实,Python的内置方法不仅能让你代码更简洁,还能大幅提升开发效率。今天,咱们就来一次系统梳理…...
小草GrassRouter多卡聚合路由器聚合卫星、MESH网络应用解决方案
一、多网融合解决方案 卫星网络融合 支持接入卫星通信模块,在无地面网络覆盖的极端场景(如偏远山区、海洋救援)下,形成“5G卫星”双链路冗余传输,卫星链路可作为核心通信备份,确保关键指令和视频数据实…...
Spring反射机制
Spring反射机制 反射机制是加载类时,在运行时动态地获取类的信息,并且可以操作类或对象的属性、方法、构造函数等成员的能力。在 Java 里,反射机制的实现主要依赖于 java.lang.reflect 包下的多个类,以及 java.lang 包中的 Class…...
PCB硬件电路设计_pcb布线设计
1.MCU最小系统电路 这些电路都会非常接近MCU,他们的可靠性决定了MCU能否正常工作。 外围电路,为了布线整齐美观,尽量避免打过多的通孔。在布局的时候走线的顺序和元器件顺序尽可能的保持一直避免走线交叉。 2.晶振电路布线 一般情况下我们…...
Qt开发:XML文件的写入与读取
文章目录 一、使用 QDomDocument操作节点1.1 将信息写入XML文件中1.2.从XML文件中读取信息 二、使用 QXmlStreamWriter操作节点2.1 将信息写入XML文件中2.2 从XML文件中读取信息 三、总结 一、使用 QDomDocument操作节点 1.1 将信息写入XML文件中 #include <QDomDocument&…...
PCI/PXI 总线的可编程电阻卡
701X 系列是阿尔泰科技基于 PCI/PXI 总线的可编程电阻卡,多种电阻范围可选,稳定性好;准确 度低至 0.2%;分辨率设置精细,可低至 0.125Ω,适用于传感器仿真应用。 701X 系列高精度程控电阻模块具有高设置分辨…...
火语言RPA--腾讯云存储
【组件功能】:存储本地文件至腾讯云 选择本地文件,通过腾讯云存储配置上传至腾讯云对象存储的指定地域指定存储桶指定路径。 配置预览 配置说明 SecretId 支持T或# 前往官网获取或创建。参考链接:https://console.cloud.tencent.com/cam/…...
使用POI和EasyExcel使用导入
1.使用POI导入 1.1导入依赖 <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version></dependency> 1.2创建工具类 package com.ruoyi.common.utils.poi;import org.ap…...
AWS PrivateLink vs Lattice:深度解析两大网络服务的异同
导语: 在AWS的网络服务生态中,PrivateLink和Lattice都是备受关注的解决方案。本文将深入探讨这两项服务的核心特性、应用场景以及它们之间的关键区别,帮助您在复杂的网络架构设计中做出明智的选择。 一、AWS PrivateLink 概述 定义 AWS PrivateLink 是一种网络服务,允许您…...
Linux系统编程---exec簇:进程的加载与替换
1、exec簇基础 在Linux中,用于加载并执行指定程序的API有exec簇和system函数。 exec簇的进程替换不会创建一个新的进程,只是加载新的程序代码和数据,替换当前进程执行的程序代码。 system函数的进程替换是创建一个新的子进程,然后…...
C++ 之 【模拟实现 list(节点、迭代器、常见接口)】(将三个模板放在同一个命名空间就实现 list 啦)
1.前提准备 (1) list 的底层结构一般是带头双向循环链表 (1)为避免命名冲突,需要创建一个命名空间来存放模拟实现的 list (2)下面模拟实现list时,声明和定义不分离(具体原因后续讲解) 2.完整实现 2.1 链表节点 template<class T>//节点写成类模板…...
数字图像处理 -- 眼底图像血管分割方法
算法框架 基于深度学习的 U-Net 架构,结合注意力机制(Attention Gate)与多尺度特征提取,以提高细小血管的检测能力。整体流程如下: 输入图像预处理:提取绿色通道 & CLAHE 增强数据增强:旋…...
基于ffmpeg的音视频编码
1 音频编码 本质上是由pcm文件转到一个协议文件 比如说aac协议 1.1 音频基本知识回归 比特率 比特率是指单位时间内传输或处理的比特(bit)数量,通常用 bps(bits per second,比特每秒)来表示。它是衡量数…...
Android wifi开发调试总结
Android wifi开发调试简单总结 文章目录 Android wifi开发调试简单总结一、前言二、wifi demo开发1、开关和连接2、wifi开启主要流程3 、wifi主要广播4、相关日志5、demo示例 三、其他1、Wifi开发小结2、其他wifi知识小结(1)Android无线Wifi开发…...
LLVIP、KAIST、M3FD数据集
LLVIP、KAIST、M3FD数据集 (可见光红外,双模态数据集,已配准已对齐已清洗,已处理为txt格式,YOLO可直接训练) 电子产品,一经出售,概不退换 算法设计、毕业设计、期刊专利!…...
datasets 数据处理封装后,统一处理流程以避免Dataset Map顺序依赖问题
文章目录 处理流程说明小结 在实际项目中,我们常常需要对数据集进行预处理。为了规范操作,我封装了一个基础数据集处理类: class DatasetAbstract:"""所有数据集都应包含以下几个字段:* question:用户…...
【学习笔记】机器学习(Machine Learning) | 第四章(3)| 多变量线性回归
机器学习(Machine Learning) 简要声明 基于吴恩达教授(Andrew Ng)课程视频 BiliBili课程资源 文章目录 机器学习(Machine Learning)简要声明 三、特征工程与多项式回归(一)特征工程:从数据中发…...
将本地Springboot项目部署到Linux服务器
1、打包后端项目 在IDEA的终端上执行命令 mvn clean package "-Dmaven.test.skiptrue" 在target目录下查看jar包是否存在 2、idea运行jar包(可选) 在IDEA的终端上执行命令 # 进入jar包所在目录 E:\LzpWorkspaces\lzp-records> cd .\tar…...
无人设备遥控器之实时数据保护技术篇
无人设备遥控器的实时数据保护技术是保障设备安全运行、避免信息泄露或恶意干扰的核心手段,其核心目标是在复杂电磁环境和网络攻击威胁下,确保指令传输的完整性、保密性和抗干扰性。 一、技术实现路径 链路层加密与认证 动态密钥协商:采用…...
【优秀三方库研读】【性能优化点滴】odygrd/quill 解决伪共享
一、伪共享(False Sharing)问题本质 当不同CPU核心频繁修改**同一缓存行(Cache Line)**中的不同变量时,会导致严重的性能下降。现代CPU的缓存系统以缓存行(通常64字节)为单位操作内存ÿ…...
JavaScript性能优化实战(6):网络请求与资源加载优化
引言 在现代Web应用开发中,网络性能已成为影响用户体验的关键因素。据统计,用户等待页面加载的耐心通常不超过3秒,超过这个时间,约40%的用户会选择离开。此外,Google的研究表明,页面加载时间每增加0.5秒,流量就会下降约20%。因此,优化网络请求和资源加载不仅关乎用户体…...
re题(49)BUUCTF-crackMe
BUUCTF在线评测 int wmain() {FILE *v0; // eaxFILE *v1; // eaxchar v3; // [esp3h] [ebp-405h]char v4[256]; // [esp4h] [ebp-404h] BYREFchar Format[256]; // [esp104h] [ebp-304h] BYREFchar v6[256]; // [esp204h] [ebp-204h] BYREFchar v7[256]; // [esp304h] [ebp-10…...
Python中的单例模式:深入探索元类与装饰器实现
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 单例模式(Singleton Pattern)是设计模式中的一种重要模式,确保一个类在整个应用中只有一个实例,并且提供全局访问点。Python语言作为一…...
深入解析 Babylon.js 中的 TransformNode.lookAt 方法
在 3D 开发中,控制对象朝向是一个基础但关键的需求。Babylon.js 作为一款强大的 Web3D 引擎,提供了 TransformNode.lookAt 方法来实现这一功能。本文将全面解析这个方法的使用技巧、参数含义以及常见应用场景。 方法基础 TransformNode.lookAt 的基本签…...
SpringCloud组件——Gateway
一.网关 1.问题提出 我们通过Eureka,Nacos解决了服务注册,服务发现的问题,使用SpringCloud LoadBalance解决了负载均衡的问题,使用OpenFeign解决了远程调用的问题。 但是当前所有微服务的接口都是直接对外暴露的,可…...
Boost 库安装 (windows 11)
Boost 库安装 (windows 11 1 下载2 生成3 使用 1 下载 下载地址:https://www.boost.org/ 有的时候会需要历史版本下载: https://www.boost.org/users/history/ 2 生成 1、解压后点击 bootstrap.bat,会生成可执行程序b2.exe 2、双击运行b2.…...
lmms-eval--微调实战笔记
lmms-eval--大模型调用平台,方便新手上手大模型微调 lmms-eval的更多用法,没有mathversehttps://github.com/EleutherAI/lm-evaluation-harness.git 单卡运行,模型gpt-j-6B,数据集hellaswag git clone --depth 1 https://github.com/Eleuthe…...
序列密码算法ShanLooog512设计原理详解
序列密码算法ShanLooog512设计原理详解 ShanLooog512(闪龙512)为序列密码算法,内部状态为512比特,密钥长度为128或256比特,轮函数为FFFFFFFF,循环轮数为24轮,输出密钥流为512比特的状态。与Salsa20类似,内…...
Matplotlib可视化基础
1. 折线图 matplotlib.pyplot.plot() # 主要参数: x,y -- 接收array,表示X轴和Y轴对应的数据,无默认 color -- 接收特定string,指定线条的颜色,默认为None linestyle -- 接收特定string,指定线条的类型…...
Linux 内核网络协议栈中的关键数据结构:inet_skb_parm 与 ip_options
在 Linux 内核的网络协议栈中,数据包的高效处理依赖于一系列精心设计的数据结构。这些结构体不仅需要存储网络数据的元信息,还需支持复杂的协议逻辑(如路由、分片、安全策略等)。本文聚焦两个核心结构体 struct inet_skb_parm 和 struct ip_options,解析它们的设计原理、功…...
oracle 数据库查询指定用户下每个表占用空间的大小,倒序显示
oracle 查询指定用户下每个表占用空间的大小,倒序显示 使用场景:数据分析;导出医院正式库到开发环境时,查询出占用表空间高的业务表、导出时排除该表 在Oracle数据库中,要查询指定用户下每个表占用空间的大小并以倒序…...
Missashe考研日记-day29
Missashe考研日记-day29 1 专业课408 学习时间:3h学习内容: 今天先是把虚拟存储剩余的课听完了,然后就是做课后选择题,57道,已经接受了OS课后题尤其多的事实了。解决并且理解完习题之后就开始预习文件管理的内容&…...
【AI】【MCP】搭建私人王炸MCP自动化工作流
目录 一、什么是MCP 二、MCP大集合 三、准备工作 3.1 安装node.js 3.2 安装vscode 3.3 安装cline插件 3.3.1 安装 3.3.2 配置Cline 四、配置MCP服务 4.1 Search-mcp服务 4.2 playwright-mcp 服务 前言:梦想组合,轻松办公,告别手动&a…...
多元函数微分之传统方法和全微分法
一、传统方法 使用链式法则,先对中间变量(如 u,v)求偏导,再乘以中间变量对最终变量(如 x,y)的偏导。 二、全微分法 基于全微分形式不变性,直接对 zf(u,v) 求全微分 dz,再代入 du 和…...
新手SEO基础优化全解析
内容概要 对于刚接触SEO的新手而言,系统化理解优化逻辑是避免无效操作的关键。本文将从基础概念入手,逐步拆解搜索引擎排名的影响要素,围绕关键词分析、技术优化、内容策略三大核心模块,提供可落地的操作框架。通过结合工具使用说…...
MATLAB退火算法和遗传算法解决旅行商问题
模拟退火算法和遗传算法都是常用于解决旅行商问题(TSP)的优化算法,它们在原理、搜索方式、收敛速度和适用场景等方面存在一些区别: 原理 模拟退火算法:模拟退火算法的灵感来源于固体退火原理。固体在加热后缓慢冷却时…...