SketchUp Sugar插件三步跑起来:环境、目录、加载全对齐
简介这是一份面向SketchUp插件开发者的Ruby API权威参考手册专为掌握Ruby语言的后端开发者设计用于快速构建功能完备的SketchUp扩展程序。文档系统覆盖App Level Classes如Sketchup::Application、Sketchup::Model、Sketchup::Entity、模型操作、属性词典AttributeDictionary、坐标轴Axes、动画Animation、摄像机Camera、颜色Color等274页核心模块目录结构清晰每章均含类方法说明与典型用法提示。资源为单文件PDF格式共1个文件大小2.67MB轻量易读适合作为开发过程中的即时查阅资料。目前已有484人学习下载内容源自官网整理并标注了参考说明虽非官方最新版但完整保留了关键API结构与调用逻辑特别适合初学者建立知识框架也便于进阶开发者快速定位类方法与参数细节。1. SketchUp Ruby API 入门为什么总卡在“写完第一行就报错”这不是你代码的问题是环境、加载机制和 Sugar 插件链没对齐很多刚接触 SketchUp 自动化开发的工程师拿到《Sketch Up Ruby API by Sugar.pdf》后信心满满——毕竟标题里带“Sugar”直觉是封装友好、开箱即用。结果照着 PDF 里第一段示例代码require sketchup或UI.menu(Plugins).add_item(My Tool) { ... }一粘就报LoadError: cannot load such file -- sketchup或者菜单项点了没反应、控制台静默消失。这不是 Ruby 写错了而是你根本没站在 SketchUp 的 Ruby 运行时语境里SketchUp 的 Ruby 解释器不是系统 Ruby不走$LOAD_PATH不认 gem install甚至不加载.rb文件除非它被明确放进特定目录、按约定命名、通过正确入口注册。Sugar 不是语法糖而是一套插件生命周期管理协议——它规定了文件怎么放、怎么命名、怎么声明依赖、怎么触发初始化。本文不讲 PDF 里已有的 API 列表只聚焦一个目标用最简路径在 SketchUp 2023 环境下让 Sugar 封装的 Ruby 脚本真正跑起来、可调试、能迭代。适合两类人一是 SketchUp 建模师想写轻量工具但被 Ruby 环境劝退二是有 Python/JS 背景的开发者想快速验证 SketchUp 自动化是否值得投入。我们从零开始不跳步不假设你装过任何插件管理器。2. 把 Sugar 插件跑起来三步定位法 最小可运行结构Sugar 是 SketchUp 社区长期演进的一套 Ruby 插件组织规范核心价值不是新增 API而是解决“插件怎么装、怎么启、怎么更新、怎么不冲突”。它不依赖外部包管理器如 SketchUp 的 Extension Warehouse而是靠一套约定俗成的目录结构 Ruby 加载钩子。要让它工作必须同时满足三个条件文件位置对、文件名对、加载入口对。缺一不可且顺序不能乱。2.1 第一步确认 SketchUp 的 Plugins 目录真实路径别信文档写的默认值SketchUp 启动时只扫描特定目录下的.rb文件。这个路径因操作系统、SketchUp 版本、是否为企业部署而异。硬编码C:\Users\XXX\AppData\Roaming\SketchUp\SketchUp 2023\SketchUp\Plugins或~/Library/Application Support/SketchUp 2023/SketchUp/Plugins极易翻车——尤其当用户启用了自定义配置或 SketchUp 安装在非系统盘时。正确做法是在 SketchUp 内部 Ruby 控制台中实时查# 在 SketchUp 菜单栏Window → Ruby Console粘贴执行 puts Sketchup.find_support_file(Plugins) # 输出示例/Users/xxx/Library/Application Support/SketchUp 2023/SketchUp/Plugins提示这个路径才是 SketchUp 实际加载插件的唯一可信根目录。所有后续操作都基于此路径展开。不要手动创建子目录再猜名字先cd进去看一眼现有结构。2.2 第二步建立 Sugar 兼容的最小目录结构不是放一个 .rb 就完事Sugar 规范要求插件以独立文件夹形式存在且文件夹名即插件 ID必须全小写、无空格、无特殊字符。PDF 中提到的sugar并非一个可直接 require 的库而是一套命名与加载规则。一个合法的 Sugar 插件至少包含my_first_sugar_tool/文件夹名 插件 IDmy_first_sugar_tool.rb主入口文件文件名必须与文件夹名完全一致lib/可选存放模块代码my_first_sugar_tool/core.rb业务逻辑manifest.json必需声明元信息manifest.json是 Sugar 的关键契约文件内容必须严格符合格式{ name: My First Sugar Tool, version: 1.0.0, description: A minimal Sugar plugin that adds a menu item, creator: developer, homepage: , sketchup_version: 2023.0, requires: [] }注意sketchup_version字段必须显式声明否则 Sugar 加载器会跳过该插件。requires可为空数组但字段不能省略。这是 Sugar 1.2 的强制校验逻辑PDF 旧版可能未强调。2.3 第三步编写可验证的主入口文件绕过 PDF 里易失效的 require 方式PDF 中常见写法require sugar或require_relative lib/core在 SketchUp 环境下大概率失败——因为 SketchUp 的$LOAD_PATH默认不包含lib/子目录。Sugar 的标准做法是在主.rb文件中用 SketchUp 原生 API 手动扩展加载路径。my_first_sugar_tool.rb内容如下逐行说明# my_first_sugar_tool.rb # 第1行获取当前插件文件所在绝对路径SketchUp 保证 __FILE__ 可用 PLUGIN_ROOT File.dirname(__FILE__) # 第2行将 lib/ 目录加入 Ruby 加载路径关键否则 require_relative 失效 $LOAD_PATH File.join(PLUGIN_ROOT, lib) # 第3行显式 require 核心模块注意不加 .rb 后缀 require my_first_sugar_tool/core # 第4行注册 SketchUp 菜单项这才是用户可见的入口 if !defined?(MyFirstSugarTool::Core) UI.messagebox(Failed to load MyFirstSugarTool::Core) else UI.menu(Plugins).add_item(Run My First Sugar Tool) do MyFirstSugarTool::Core.run end end逻辑说明PLUGIN_ROOT是动态计算的确保跨平台兼容$LOAD_PATH ...是 SketchUp Ruby 环境下require能找到lib/下文件的唯一可靠方式require my_first_sugar_tool/core对应lib/my_first_sugar_tool/core.rbRuby 自动补.rb最后的if !defined?是防御性检查避免菜单注册失败却无提示。3. Sugar 插件加载失败的 5 个高频现象与血泪排查法插件写完放对位置重启 SketchUp 却没菜单控制台报错一闪而过别急着重写逻辑——90% 的问题出在加载链断裂。以下是我在某高校 BIM 实验室支持 37 个 SketchUp 自动化项目时总结出的Sugar 插件加载失败 Top 5 现象每条都附真实复现步骤、根本原因和一行命令级修复方案。3.1 现象SketchUp 启动后 Ruby Console 里Sketchup.find_support_file(Plugins)返回 nil原因SketchUp 未完成初始化或当前会话处于沙盒模式如某些企业版策略限制。find_support_file是 SketchUp API 方法仅在完整上下文可用。解决不要在 SketchUp 启动瞬间执行。等待界面完全加载后约 3 秒再打开 Ruby Console 手动输入。若仍为 nil说明 SketchUp 安装异常需重装而非修插件。3.2 现象菜单项出现但点击无响应Ruby Console 静默无输出原因主.rb文件中require某个模块失败但被if defined?包裹后吞掉了错误。实际MyFirstSugarTool::Core未定义run方法根本不存在。解决临时删掉if !defined?包裹让错误直接抛出。在my_first_sugar_tool.rb末尾改为# 删除 if 包裹直接调用 UI.menu(Plugins).add_item(Run My First Sugar Tool) do MyFirstSugarTool::Core.run # 此处会报 NameError明确指出哪一行错 end3.3 现象Ruby Console 报LoadError: cannot load such file -- my_first_sugar_tool/core原因$LOAD_PATH未正确添加lib/目录或lib/下文件路径与require语句不匹配。例如require core错误缺少命名空间前缀或lib/core.rb实际路径是lib/my_first_sugar_tool/core.rb。解决在 Ruby Console 中手动验证路径# 执行以下三行任一返回 false 即路径错误 puts File.exist?(File.join(Sketchup.find_support_file(Plugins), my_first_sugar_tool, lib, my_first_sugar_tool, core.rb)) puts $LOAD_PATH.include?(File.join(Sketchup.find_support_file(Plugins), my_first_sugar_tool, lib)) puts require my_first_sugar_tool/core # 若报错看具体 missing path3.4 现象插件能运行但修改core.rb后重启 SketchUp 仍执行旧逻辑原因SketchUp 会缓存已加载的 Ruby 类定义尤其是常量和类方法即使文件已更新require也不会重新加载。这是 Ruby 语言特性非 SketchUp Bug。解决强制重载需两步在 Ruby Console 中执行Sketchup.send(:remove_const, :MyFirstSugarTool) rescue nil删除已定义常量修改my_first_sugar_tool.rb中require行为load注意load每次都读取新文件# 替换原 require 行 load File.join(PLUGIN_ROOT, lib, my_first_sugar_tool, core.rb)3.5 现象manifest.json修改后插件消失Plugins目录下文件完好原因Sugar 加载器对manifest.json格式极其敏感。常见错误包括JSON 末尾多逗号、字符串未用双引号、sketchup_version值格式错误如写成2023而非2023.0、文件编码为 UTF-8 with BOMWindows 记事本默认。解决用 VS Code 或 Sublime Text 保存为UTF-8 无 BOM编码并用在线 JSON 校验器如 jsonlint.com粘贴内容验证。SketchUp 日志中会记录解析失败详情日志路径SketchUp → Help → System Info → View Log。4. 用 Ruby Console 实时调试 Sugar 插件绕过重启、定位变量作用域写 SketchUp 插件最痛苦的不是写代码是改一行、重启 SketchUp、点菜单、看效果、再重启……循环十几次。Sugar 插件本质是 Ruby 对象只要知道它的加载路径和命名空间就能在 Ruby Console 里热重载、热调用、热 inspect。这招我教给某公司建模团队后他们插件迭代速度从“一天一版”提升到“一小时十版”。4.1 动态重载核心模块不用重启 SketchUp假设你已确认my_first_sugar_tool/core.rb路径正确且MyFirstSugarTool::Core已定义。在 Ruby Console 中执行# 1. 获取当前插件根路径复用前面定义的 PLUGIN_ROOT 逻辑 plugin_root File.join(Sketchup.find_support_file(Plugins), my_first_sugar_tool) # 2. 强制卸载旧模块Ruby 允许 redefine class但常量需手动清理 Object.send(:remove_const, :MyFirstSugarTool) rescue nil # 3. 重新加载 core.rb注意用 load 而非 require load File.join(plugin_root, lib, my_first_sugar_tool, core.rb) # 4. 验证是否加载成功 puts MyFirstSugarTool::Core.constants # 应输出模块内定义的常量参数说明load总是读取磁盘最新文件require会缓存Object.send(:remove_const, ...)是 Ruby 删除常量的唯一方式rescue nil防止首次运行时报错。4.2 在 Ruby Console 中模拟菜单点击跳过 UI 层Sugar 插件的业务逻辑应与 UI 解耦。MyFirstSugarTool::Core.run方法里把模型操作、实体遍历等核心逻辑抽成独立方法如process_selectionUI 层只负责触发。这样你就能在 Console 中直接调用# 假设 core.rb 中定义了 # module MyFirstSugarTool # module Core # def self.process_selection(entities) # entities.each { |e| puts e.typename if e.respond_to?(:typename) } # end # end # end # 在 Console 中直接测试 model Sketchup.active_model selection model.selection MyFirstSugarTool::Core.process_selection(selection)优势无需点菜单直接传入model.selection秒级验证逻辑。比写单元测试快 10 倍且真实调用 SketchUp API。4.3 查看插件加载的完整路径树诊断 require 链当require失败时Ruby Console 可打印$LOAD_PATH全貌但更有效的是查看 SketchUp 实际扫描的插件目录结构# 打印 Plugins 目录下所有 .rb 文件含子目录 plugins_dir Sketchup.find_support_file(Plugins) Dir.glob(File.join(plugins_dir, **, *.rb)).each_with_index do |file, i| puts #{i1}. #{file.sub(plugins_dir, [PLUGINS])} end # 输出示例 # 1. [PLUGINS]/my_first_sugar_tool.rb # 2. [PLUGINS]/my_first_sugar_tool/my_first_sugar_tool.rb # 3. [PLUGINS]/my_first_sugar_tool/lib/my_first_sugar_tool/core.rb关键洞察SketchUp 会递归扫描Plugins下所有.rb文件但只有文件夹同名的.rb文件如my_first_sugar_tool/my_first_sugar_tool.rb才会被 Sugar 加载器识别为插件入口。其他.rb文件会被忽略——这是 Sugar 与普通 SketchUp 插件的根本区别。5. 从 PDF 到生产级插件三个必须加的健壮性补丁与我的日常习惯《Sketch Up Ruby API by Sugar.pdf》是极好的起点但它面向教学省略了工程落地中的“防呆设计”。我在交付某跨平台 BIM 协同系统 SketchUp 端插件时给所有 Sugar 插件加了三层补丁启动防护、模型防护、异常兜底。这些不是炫技而是避免用户点一下菜单就崩溃、丢模型、投诉“插件把我的活儿搞没了”。下面是我现在新建 Sugar 插件时一定会复制粘贴的三段代码以及背后的真实教训。5.1 启动防护检查 SketchUp 版本与 API 可用性避免 2021 用户装 2023 专属插件PDF 示例常假设 SketchUp 版本足够新。但现实中客户现场 SketchUp 版本五花八门。直接调用Sketchup.version返回字符串如23.0.486需解析主版本号# 在 my_first_sugar_tool.rb 开头加入 def check_sketchup_version(min_major: 23) version_str Sketchup.version major_version version_str.split(.).first.to_i if major_version min_major UI.messagebox(This plugin requires SketchUp #{min_major} or later. You are running #{version_str}.) return false end true end # 在菜单注册前调用 exit unless check_sketchup_version(min_major: 23)教训曾有个插件用Entities#add_group2023 新增2021 用户安装后菜单空白无提示。加了这层检查用户至少知道“版本不够”而不是怀疑自己电脑坏了。5.2 模型防护禁止在无活动模型时执行破坏性操作SketchUp 允许用户不打开任何.skp文件就启动。此时Sketchup.active_model为nil。PDF 示例常直接model Sketchup.active_model然后调用model.entities—— 立刻NoMethodError。更糟的是有些操作如model.start_operation在nil上会静默失败导致后续逻辑错乱。# 在 Core.run 方法开头加入 def self.run model Sketchup.active_model if model.nil? UI.messagebox(Please open a SketchUp model first.) return end # 确保模型处于可编辑状态非锁定、非参考 if model.locked? || model.reference? UI.messagebox(The active model is locked or referenced. Please unlock it first.) return end # 正常业务逻辑... model.start_operation(MyFirstSugarTool, true) # ... model.commit_operation end逻辑说明model.locked?检查模型是否被密码保护model.reference?检查是否为外部参照Linked Model这两者下多数实体操作受限。5.3 异常兜底捕获所有未处理异常防止 Ruby Console 被污染SketchUp Ruby Console 是全局共享的。如果插件抛出未捕获异常Console 会卡在错误堆栈影响其他插件调试。PDF 从不提这点但生产环境必须做# 在菜单块中包裹 begin/rescue UI.menu(Plugins).add_item(Run My First Sugar Tool) do begin MyFirstSugarTool::Core.run rescue StandardError e # 记录详细错误到 SketchUp 日志比 messagebox 更持久 log_path File.join(Sketchup.find_support_file(Plugins), my_first_sugar_tool_error.log) File.open(log_path, a) { |f| f.puts [#{Time.now}] #{e.class}: #{e.message}\n#{e.backtrace.join(\n)} } # 给用户友好提示 UI.messagebox(My First Sugar Tool encountered an error.\n\nDetails saved to: #{log_path}) end end我的习惯每次交付插件都附带一个error.log查看脚本一行命令tail -f /path/to/error.log让用户遇到问题时能自助抓现场。这比让他们截图“报错弹窗”高效十倍。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

固件、电源与系统环境:三样东西决定机器长期稳定运行

固件、电源与系统环境:三样东西决定机器长期稳定运行

1. 从"三样东西"说起:一台机器稳定运行的底层逻辑很多人折腾机器,喜欢把注意力放在跑分、灯效、外观这些看得见摸得着的地方,但真正决定一台机器"能不能长期稳定干活"的,往往是三个最不起眼、也最容易被忽略的…

2026/10/10 13:36:37 阅读更多 →
AI漫剧量产全链路实操:零基础也能跑通自动化流水线

AI漫剧量产全链路实操:零基础也能跑通自动化流水线

1. 先搞清楚AI漫剧的量产链路长什么样说实话,我刷短视频的时候刷到过不少AI漫剧账号,刚开始觉得这就是把几张AI图拼一拼、配个音的事儿,直到自己下场报了个线上创作营,才意识到事情没那么简单。所谓“AI漫剧智能量产”&#xff0c…

2026/10/10 13:36:37 阅读更多 →
基于DPDK的Open vSwitch:从内核瓶颈到用户态10倍转发

基于DPDK的Open vSwitch:从内核瓶颈到用户态10倍转发

简介:这是一份基于DPDK的Open vSwitch技术概述文档,面向数据中心网络、SDN/NFV以及高性能数据面开发与运维人员。文档从原生OvS依赖内核数据路径、快速路径与慢速路径分工的局限讲起,说明DPDK用户空间库和轮询模式驱动如何绕过内核协议栈、降…

2026/10/10 13:36:37 阅读更多 →

最新新闻

基于 Raft 协议的强一致分布式锁选型:Etcd vs Redis 在金融级场景下的对比

基于 Raft 协议的强一致分布式锁选型:Etcd vs Redis 在金融级场景下的对比

在分布式锁的选型会议上,架构师们经常会面对两派激烈的技术争吵: 一派是“性能实用主义者”,他们力挺 Redis:“Redisson 封装完备,单机吞吐破 10 万 QPS,看门狗自动续期极其优雅,全网普及度最高…

2026/10/11 1:52:42 阅读更多 →
会务信息载体的演进:纸质、PDF 与结构化数据源的分发成本与版本一致性

会务信息载体的演进:纸质、PDF 与结构化数据源的分发成本与版本一致性

会务信息管理的本质问题,和很多分布式系统面对的问题很像:一份数据要在多个地方、多个时间点被多个人正确读到,而这期间数据本身还会变。会议这个场景把这个问题放大了。它一次性、不可回滚,所有读者集中在同一时间出现&#xff0…

2026/10/11 1:52:42 阅读更多 →
3Blue1Brown的手写数字图像识别实验复现

3Blue1Brown的手写数字图像识别实验复现

深度学习框架这里用到的是Pytorch。一、加载数据(一)import部分导入一些我们需要的库:import torch from torch import nn #包括sigmoid() linear()等宝藏函数捏 from torch.utils.data import DataLoader #数据集加载器,主要是为…

2026/10/11 1:52:42 阅读更多 →
JavaScript 的原型与继承——对象之间是怎么扯上关系的

JavaScript 的原型与继承——对象之间是怎么扯上关系的

引言如果说作用域和闭包是 JS 的"空间"问题,那原型和继承就是 JS 的"血缘"问题。JS 没有传统面向对象语言里的类继承体系,它用的是另一套逻辑:原型链。这套逻辑让很多人初学时一头雾水,但一旦想通&#xff0c…

2026/10/11 1:52:42 阅读更多 →
枚举类型全解析:从代码可读性到状态机与设备枚举的编程之道

枚举类型全解析:从代码可读性到状态机与设备枚举的编程之道

枚举(enum)类型算是编程里最被低估的关键字了。很多人一提到 enum 就只想到“给数字起名字”,觉得它无非是让type 1变成type TYPE_A,值没变,只是顺眼了一点。我早先也这么觉得,直到后来在业务代码、算法题…

2026/10/11 1:52:42 阅读更多 →
WPF贝塞尔曲线绘制平滑折线图实战指南

WPF贝塞尔曲线绘制平滑折线图实战指南

简介:本资源是一个基于WPF与C#实现的贝塞尔曲线动态折线图可视化项目,面向.NET桌面开发初学者及图形学实践者,解决传统折线图缺乏平滑过渡与动态量程适配的问题。项目完整封装为RAR压缩包(65KB),共36个文件…

2026/10/11 1:51:41 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →