Reporting & DocumentationChinese & English

Create a Report from Mesh

Create a Report from Mesh lets you pick a published Mesh and turn all of its measurements into a ready-to-share report (Excel .xlsx or PowerPoint .pptx).

Updated 2026-09-23User manual

Create a Report from Mesh(从 Mesh 生成报告)

Create a Report from Mesh - User Manual

Dragonfly Prototype Apps · Create a Report from Mesh...

版本 Version 1.0 · 2026-07-29


第一部分 中文手册

目录

1. 简介

2. 两类 measurements 的区别(务必理解)

3. 报告里有什么

4. 使用步骤

5. 工作原理(技术路径)

6. 分享到网页(发布 + 链接 + 二维码)

7. 「分享报告」标签页 —— 随窗口关闭而永久失效的临时链接

8. 环境需求

1. 简介

Create a Report from Mesh 让你选择一个已发布的 Mesh,把它上面全部的 measurements 一次性整理成一份可直接汇报的报告(Excel .xlsx 或 PowerPoint .pptx)。

关键点:Mesh 的 measurements 分成两类,本报告严格分开呈现,因为两者的“一个数”含义完全不同,混在一起统计是错的。详见下一节。

另有一个新功能:勾选 “为每个 measurement 添加动画 GIF” 后,程序会围绕 Mesh 从 8 个不同角度(角度数可调)拍摄 3D 渲染截图,并合成为一个循环播放的动画 GIF 放进报告。

本功能由第三方(Prototype Labs / Prototype Apps)提供,并非 Dragonfly 官方开发,Dragonfly 也不提供技术支持;使用风险由使用者自行承担。

2. 两类 measurements 的区别(务必理解)

顶点类 Vertex-based

标签类 Label-based

一个数值代表

一个网格顶点

一个标签(分割出来的一个子对象)

数据本质

分布在表面上的连续场

一个对象总体的逐对象取值

样本数 N

= 顶点数(常达数十万)

= 标签数(常为几个到几千)

典型例子

局部厚度、平均曲率、到某物的距离

每颗颗粒的体积、表面积、等效直径

统计量的含义

描述“表面上的取值分布”

描述“这一群对象的分布”

报告中的位置

工作表/幻灯片前缀 Vertex-

工作表/幻灯片前缀 Label-,并逐标签列出数值

举例:一个平均厚度 12 µm 的顶点类结果,说的是“表面各点的厚度平均为 12 µm”;一个平均体积 6 mm³ 的标签类结果,说的是“这些颗粒平均每颗 6 mm³”。二者不能相互比较,也不能合并计算,因此报告的总览把它们放在两个独立的区块(xlsx)/两页(pptx),并在每一处标注 N 是顶点数还是标签数。

若该 Mesh 还带有面类(face-based)标量槽,报告会注明其数量,但不做统计(面类数据在 Dragonfly 中较少直接用于测量汇报)。

3. 报告里有什么

部分

内容

总览

先列出 Mesh 的顶点数与标签数,接着分两个区块(顶点类 / 标签类)各给一张表:每个 measurement 一行,含平均值、中位数、最小值、最大值、标准差、单位、样本数 N;并附一段说明两类区别的文字。某一类没有数据时明确写“(none on this mesh)”。

每个 measurement 一页

xlsx 中为一个工作表、pptx 中为一张幻灯片,表名/页标题都带 Vertex- 或 Label- 前缀

① 直方图

该 measurement 的数值分布直方图(横轴带单位,标题注明是顶点类还是标签类)

② 3D 截图

仅显示该 Mesh、并按该 measurement 着色的三维渲染截图

③ 动画 GIF(可选)

同一 measurement 的 8 个旋转角度合成的循环 GIF。pptx 中直接嵌入 GIF(放映模式下会自动旋转播放);xlsx 中放入 GIF 首帧静态图并标注 GIF 文件名(GIF 与截图都保留在输出文件夹里)。

④ 逐标签数值(仅标签类)

标签名 + 数值的完整列表

4. 使用步骤

1. 先确保目标 Mesh 上已经计算过 measurements(可用 Compute Vertex Measurements / Compute Overall Measurements 等工具生成;没有任何 measurement 时列表会提示)。

2. 菜单 Prototype Apps ▸ Create a Report from Mesh… 打开面板。

3. 在下拉框中选择一个已发布的 Mesh(括号内显示顶点数、标签数,以及顶点类/标签类 measurement 各有几个);如需刷新点“↻ 刷新”。

4. 选择输出格式(Excel 或 PowerPoint),选择是否包含 3D 截图。

5. 如需旋转动画,勾选“为每个 measurement 添加动画 GIF(3D 旋转)”,并可调整角度数(默认 8)与每帧停留时间(默认 250 ms)。

6. 设置输出文件夹,点“生成报告”。完成后自动打开输出文件夹。

角度数越多、measurement 越多,截图耗时越长(每个角度都要渲染一次)。8 个角度是清晰度与耗时的折中;只想快速出结果时可取消勾选 GIF,仅保留单张 3D 截图。

5. 工作原理(技术路径)

读取 measurements:分别遍历 Mesh 的顶点标量值槽与标签标量值槽(get<Vertex|Label>ScalarValuesSlotCount / …ScalarValues / …ScalarValueDescription / …ScalarValueDimensionUnit),并读取标签名列表,因此每个数值都能对应到具体标签。在 2027.1 中,标签类的第一个槽是标签编号列而不是测量值(Dragonfly 自己的面板也会跳过它),因此不计入报告。

统计与直方图:用 numpy 计算 mean/median/min/max/std(忽略 NaN),用 matplotlib 的面向对象 Agg 接口渲染直方图 PNG(不使用 pyplot,避免在 Dragonfly 进程内争抢全局状态)。

3D 截图:截图期间把当前的 3D 视图(若当前是 2D 视图,则为其布局中的第一个 3D 视图)最大化——可还原,布局本身不会被替换。体数据、ROI、Multi-ROI、Mesh、Graph、标尺、方框与平面会被临时隐藏,只显示该 Mesh(标签、箭头、点等注释保持原样)。Mesh 依次按每个 measurement 着色,并回读确认着色已生效:当前 Dragonfly 版本无法按其着色的 measurement 不生成截图,而不会给出另一个 measurement 的图。截图由 ReportHelper.captureSnapshot 完成。每个对象的 2D 与 3D 可见性、每个视图的相机与层厚、Mesh 的着色以及视图的最大化状态都会先记录下来,结束后逐一恢复——截图中途出错时也一样。当前布局中没有 3D 视图时,报告会在开始前询问;继续则不含截图,统计表与直方图照常生成。

动画 GIF:以 3D 视图当前相机为起点,绕竖直轴用 Camera.getRotatedAroundAxis 生成 N 个等角度相机位姿,每个位姿截一张图,再用 Pillow 把帧序列写成 loop=0 的循环 GIF(帧宽超出上限时等比缩小,避免 pptx 体积过大)。

写文件:xlsx 用 openpyxl(总览表 + 每指标一个工作表并嵌入图片),pptx 用 python-pptx(标题页 + 每类一页总览 + 每指标一页,GIF 以原始 .gif 嵌入以保留动画)。

线程:读取对象与 3D 截图必须在界面线程执行(Dragonfly 要求),随后的统计、直方图、GIF 合成与文件写入在后台线程执行,界面不会卡住。

6. 分享到网页(发布 + 链接 + 二维码)

生成报告后,面板下方的 分享到网页 区域可以把同一份报告做成一个自包含的 HTML 文件(所有图片和旋转 GIF 都内嵌其中)并上传到免费静态托管,随后显示可访问的 URL、一键复制到剪贴板、并显示二维码供手机扫码打开。

三档可见性——请先理解它们的差别

档位

机制

谁能看到

公开

固定可读路径,允许搜索引擎索引

任何人;链接可能出现在搜索结果里

不公开(默认)

22 字符随机不可猜路径 + noindex,nofollow

只有拿到链接的人。这不是登录鉴权,链接一旦转发就收不回来

密码保护

报告正文用 AES-256-GCM 加密,浏览器端用 WebCrypto 输入口令解密

拿到链接并且知道口令的人。托管方与任何找到 URL 的人只拿到密文

免费托管普遍不提供真正的登录鉴权(GitHub Pages 私有仓库需要 Pro/Team,Netlify/Vercel 的密码保护是付费功能)。因此“密码保护”是免费层唯一能提供真正机密性的方式。口令永不保存在任何文件里,请通过与链接不同的渠道发送。

使用步骤

1. 先正常生成一次报告(分享区域在报告生成成功后才可用)。

2. 选择托管平台:GitHub Pages / Netlify / Gitee Pages(码云)。

3. 填写该平台的账号信息(仓库名、令牌等)。这些会被记住,下次打开即已填好。

4. 选择可见性;若选“密码保护”,输入本次使用的口令。

5. 点“发布到网页”。上传前会弹出确认框,明确列出文件名、大小、托管平台、路径与可见性——请核对后再确认。

6. 发布完成后复制 URL 或让对方扫二维码。二维码图片同时保存在报告输出文件夹里(report_qr.png),可直接放进 PPT。

7. 不想再分享时点“撤下”,已发布的文件会从托管方删除。

令牌安全(重要)

令牌以明文保存在 %LOCALAPPDATA%\DragonflyPrototypeLabs\settings\ 下的设置文件中。因此请使用细粒度 PAT,并且只授权一个专用仓库的 Contents 与 Pages 写权限;不要使用 classic 的 repo 全权令牌——那种令牌可以改写你名下所有仓库。另外请注意:上传报告等于把其中的图像数据发布到第三方服务器上。

各平台注意事项:GitHub Pages 免费版要求仓库为公开,且每次发布后构建需要 10–60 秒,刚发布时短暂 404 是正常的;Netlify 几秒即生效,随机子域名本身就不易被猜到;Gitee Pages 国内访问快,但免费版不会自动构建——上传后需要到仓库的 Pages 页面手动点一次“更新”,且 Gitee 要求实名认证后才能使用 Pages。

所有发布记录(时间、平台、URL、可见性、大小)保存在 %LOCALAPPDATA%\DragonflyPrototypeLabs\published_reports.json,方便你知道自己在网上放了哪些内容。

7. 「分享报告」标签页 —— 随窗口关闭而永久失效的临时链接

第二个标签页 分享报告 与上一节恰好相反:不需要账号、不上传、不留痕迹。它打开一条 Cloudflare 快速隧道 —— 由本机向外建立一条连接,因此不需要改防火墙、也不需要任何入站访问 —— Cloudflare 会返回一个随机公网地址,例如 https://green-pond-fox-tree.trycloudflare.com。只要窗口保持打开,报告就由本机提供;窗口一关,该地址永久失效:Cloudflare 不会再次分配同一个地址。

两条分享路径该用哪一条

在网上分享报告(第一个标签页)

分享报告(本标签页)

有效期

直到你主动撤下

仅在本窗口打开期间

需要账号

需要(GitHub / Netlify / Gitee)

不需要

是否上传报告

是,上传到第三方服务器

否 —— 由本机提供

保密性

不可猜路径,或真正的密码(AES-256-GCM)

无:任何拿到链接的人都能看

可靠性

正常的托管服务

Cloudflare 的测试设施:有速率限制,不承诺可用性

适合

把结果正式交付给客户

让外网的人在接下来十分钟看一眼

本路径故意不设密码。分享期间任何拿到链接的人都能查看报告,而链接是可以被转发、被日志记录的。真正的保护是「窗口会关闭」。因此本标签页不应作为向客户交付结果的通道 —— 那种场景请用第一个标签页。

使用步骤

1. 先在第一个标签页生成报告(没有报告时「开始分享」是禁用的;正在生成新报告时也会被禁用)。

2. 切到「分享报告」,点击「开始分享」。

3. 仅第一次会询问是否下载 Cloudflare 的 cloudflared.exe(约 52 MB),并说明下载来源。它按用户保存在 %LOCALAPPDATA%\DragonflyPrototypeLabs\cloudflared,之后重复使用。

4. 确认对话框会写明文件、大小、没有密码、以及什么情况下分享结束。请认真读:报告里包含你的图像数据。

5. 等待。状态会显示「地址已分配 —— 正在等待它开始响应。请先不要发送。」这一阶段刻意不提供任何可复制的链接。

6. 状态变绿后,用「复制链接」,或让对方扫二维码(二维码同时保存在报告旁边,文件名 share_qr.png)。

7. 「本机预览」会在你自己的浏览器里打开同一个页面 —— 与对方看到的逐字节相同,由同一个服务提供。

8. 「已被打开 N 次;最近一次 …」统计的是页面被真正读取的次数,因此你能知道对方到底看没看。

9. 结束时点「停止分享」—— 或者直接关闭窗口,或退出 Dragonfly。

三种结果,以及为什么是三种

状态

含义

该怎么做

已就绪(绿色)

本机已经从公网地址取到了我们自己的页面,说明它确实可达

把链接发出去

无法确认(琥珀色)

隧道已建立,但本机在 2 分钟内访问不到该地址 —— 通常是它的 DNS 名称还没在本机开始解析,或者连续开隧道被 Cloudflare 限流

链接仍然会给你:对方用的不是本机的 DNS,可以先发过去问一下,或者停止后重试

分享失败(红色)

cloudflared 根本没有返回地址 —— 一般是本机没有外网出口,或被代理拦截

检查本机的外网访问;日志里有 cloudflared 自己的输出

2026-08-07 在本网络实测,也正是琥珀色状态存在的原因:连续开三条快速隧道,只有一条变为可达(45 秒后),另外两条始终没有解析出来。地址分配后大约 40 秒才真正开始工作,所以如果标签页立刻把地址交给你,你发出去对方只会看到 404 —— 因此本标签页会等,并且明确告诉你处于哪一种情况,而不是宣称它无法证明的成功或失败。

暴露了什么,没暴露什么

只提供这一个报告页面,且直接从内存提供 —— 绝不提供目录,也绝不提供任何由请求决定的文件路径。noindex 同时以响应头和 meta 标签发送,robots.txt 拒绝一切抓取,因此即使爬虫碰到这个地址,也不会把报告收进比分享本身更长命的搜索索引。任何可能写入的请求(POST、PUT、DELETE)都会被拒绝。提供出去的页面上带有一条中英双语横幅,告知读者该链接是临时的。

如果 Dragonfly 被强制结束而没有关闭分享,隧道进程可能比它活得更久、继续占用那个地址。因此每条隧道都会被记录,标签页打开时会清理上一次会话遗留的隧道 —— 这样「关闭窗口即失效」在崩溃之后同样成立。

8. 环境需求

无需虚拟环境、GPU 或管理员权限,纯进程内运行。xlsx、直方图、GIF 分别使用 Dragonfly 自带的 openpyxl、matplotlib 与 Pillow;选择 pptx 时会在首次使用时自动下载一次 python-pptx(之后离线可用)。3D 截图与 GIF 需要有一个真实的 3D 视图;若当前没有可用视图,程序会跳过截图并照常输出统计与直方图。


Part II English Manual

Contents

1. Introduction

2. How the two measurement families differ (read this first)

3. What the report contains

4. How to use it

5. How it works (technical path)

6. Share on the web (publish + link + QR code)

7. Share Report tab - a temporary link that dies with the window

8. Requirements

1. Introduction

Create a Report from Mesh lets you pick a published Mesh and turn all of its measurements into a ready-to-share report (Excel .xlsx or PowerPoint .pptx).

Key point: mesh measurements come in two families and this report keeps them strictly apart, because a single number means something entirely different in each — pooling them would be plain wrong. See the next section.

There is also a new option: tick "Add animated GIF for each measurement" and the plugin captures the 3D rendering from 8 different angles (count adjustable) around the mesh and combines the frames into one looping animated GIF placed in the report.

This feature is provided by a third party (Prototype Labs / Prototype Apps), not officially developed or supported by Dragonfly. Use at your own risk.

2. How the two measurement families differ (read this first)

Vertex-based

Label-based

One value represents

one mesh vertex

one label (one segmented sub-object)

Nature of the data

a continuous field sampled over the surface

one number per object, across a population

Sample count N

= vertex count (often hundreds of thousands)

= label count (a few to a few thousand)

Typical examples

local thickness, mean curvature, distance to something

volume, surface area or equivalent diameter per particle

What the statistics mean

the distribution of values over the surface

the distribution across that population of objects

Where it lands in the report

sheets/slides prefixed Vertex-

sheets/slides prefixed Label-, plus a per-label value listing

For example: a vertex-based mean thickness of 12 µm says "averaged over the surface, the material is 12 µm thick"; a label-based mean volume of 6 mm³ says "these particles average 6 mm³ each". The two cannot be compared or combined, so the overview places them in two separate blocks (xlsx) / on two separate slides (pptx) and every N is labelled as either a vertex count or a label count.

If the Mesh also carries face-based scalar slots, the report states how many but does not analyse them (face data is rarely used directly for measurement reporting in Dragonfly).

3. What the report contains

Part

Content

Overview

The mesh's vertex and label counts, then two separate blocks (vertex-based / label-based), each a table with one row per measurement: mean, median, min, max, std, unit and sample count N — plus a short note stating how the families differ. A family with no data is explicitly reported as "(none on this mesh)".

One page per measurement

A worksheet in xlsx, a slide in pptx; every sheet name / slide title is prefixed Vertex- or Label-

1. Histogram

The distribution of that measurement (axis carries the unit, the title states which family it belongs to)

2. 3D screenshot

A 3D rendering showing only this Mesh, coloured by that measurement

3. Animated GIF (optional)

8 rotated views of the same measurement combined into a looping GIF. pptx embeds the GIF itself (PowerPoint animates it in slideshow mode); xlsx shows its first frame and states the GIF filename (both the GIF and the stills stay in the output folder).

4. Per-label values (label-based only)

The complete list of label names and their values

4. How to use it

1. Make sure the target Mesh already carries measurements (compute them first with e.g. Compute Vertex Measurements / Compute Overall Measurements; the list tells you when a mesh has none).

2. Open Prototype Apps ▸ Create a Report from Mesh… from the menu.

3. Pick a published Mesh from the drop-down (the brackets show its vertex count, label count and how many vertex-based / label-based measurements it has); press "↻ Refresh" if you just created it.

4. Choose the output format (Excel or PowerPoint) and whether to include 3D screenshots.

5. For the rotating animation, tick "Add animated GIF for each measurement (3D rotation)" and adjust the number of angles (default 8) and the per-frame delay (default 250 ms) if you want.

6. Set the output folder and press "Generate report". The output folder opens automatically when it finishes.

More angles and more measurements mean more capture time, since every angle is a separate render. 8 angles is a good clarity/time compromise; for a quick result leave the GIF unticked and keep just the single 3D screenshot.

5. How it works (technical path)

Reading measurements: the vertex scalar slots and the label scalar slots are walked separately (get<Vertex|Label>ScalarValuesSlotCount / …ScalarValues / …ScalarValueDescription / …ScalarValueDimensionUnit), and the label name list is read too, so every label-based value can be attributed to a named label. On 2027.1 the first label slot is the label-ID column, not a measurement (Dragonfly's own panels skip it), so it is not reported.

Statistics and histograms: numpy computes mean/median/min/max/std ignoring NaN; matplotlib's object-oriented Agg interface renders the histogram PNGs (never pyplot, to avoid fighting over global state inside the Dragonfly process).

3D screenshots: the current 3D view (or, from a 2D view, the first 3D view of its layout) is maximised for the capture - reversibly, the layout itself is never replaced. Volumes, ROIs, Multi-ROIs, meshes, graphs, rulers, boxes and planes are temporarily hidden so only this Mesh shows (annotations such as labels, arrows and points are left as they are). The mesh is coloured by each measurement in turn, and the colouring is read back: a measurement this Dragonfly build cannot colour by gets no screenshot rather than a picture of another measurement. ReportHelper.captureSnapshot takes the picture. Every object's 2D and 3D visibility, every view's camera and slab thickness, the mesh's colouring and the maximised view are recorded first and put back afterwards - also when a capture fails half way. When the layout has no 3D view the report asks before it starts, and then contains no screenshots; the statistics and histograms are still produced.

Animated GIF: starting from the 3D view's current camera, N equally spaced camera poses are generated around the vertical axis with Camera.getRotatedAroundAxis, one frame is captured per pose, and Pillow writes the sequence as a loop=0 GIF (frames are scaled down past a width cap so the pptx stays reasonably small).

Writing the files: xlsx via openpyxl (overview table plus one worksheet per measurement with the images embedded); pptx via python-pptx (title slide, one overview slide per family, one slide per measurement, with the GIF embedded as a real .gif so the animation survives).

Threading: reading objects and capturing 3D views must happen on the UI thread (a Dragonfly requirement); the statistics, histograms, GIF assembly and file writing then run on a worker thread, so the UI never freezes.

After a report is generated, the Share the report on the web group can turn the same report into one self-contained HTML file (every image and rotation GIF embedded) and upload it to free static hosting. The panel then shows the URL, copies it to the clipboard on one click, and shows a QR code so a phone can open it.

Three visibility levels - understand the difference first

Level

Mechanism

Who can see it

Public

a readable, fixed path; indexing allowed

anyone; the link may show up in search results

Unlisted (default)

a 22-character unguessable path + noindex,nofollow

only people with the link. This is not authentication - once forwarded, the link cannot be recalled

Password protected

the report body is AES-256-GCM encrypted and decrypted in the browser via WebCrypto

anyone who has the link AND the password. The host, and anyone who finds the URL, holds ciphertext only

Free hosting generally does NOT offer real authentication (GitHub Pages for a private repository needs Pro/Team; password protection on Netlify/Vercel is a paid feature). Password mode is therefore the only way to get real confidentiality on a free tier. The password is NEVER stored anywhere - send it through a different channel than the link.

How to use it

1. Generate the report as usual first (the share group stays disabled until a report exists).

2. Pick the host: GitHub Pages / Netlify / Gitee Pages.

3. Fill in that host's account fields (repository, token, ...). They are remembered for next time.

4. Choose the visibility; for password mode, type the password to use this time.

5. Press "Publish to the web". A confirmation dialog lists the filename, size, host, path and visibility - check it before confirming.

6. Copy the URL, or let the other person scan the QR code. The QR image is also saved next to the report (report_qr.png) so you can drop it into a slide.

7. Press "Take it down" when you no longer want it shared; the published file is deleted from the host.

Token safety (important)

The token is stored in PLAIN TEXT in the settings file under %LOCALAPPDATA%\DragonflyPrototypeLabs\settings\. So use a fine-grained PAT scoped to ONE dedicated repository with Contents and Pages write access; do not use a classic repo token, which can rewrite every repository the account owns. Also remember that uploading a report publishes the image data inside it to a third-party server.

Per-host notes: GitHub Pages on a free account needs a PUBLIC repository and takes 10-60 s to build after each publish, so a brief 404 right after publishing is normal. Netlify is live in seconds and its random subdomain is already hard to guess. Gitee Pages is fast inside China but does NOT rebuild automatically on the free tier - after uploading you must click 更新 once on the repository's Pages page, and Gitee requires real-name verification before Pages works at all.

Every publish is recorded in %LOCALAPPDATA%\DragonflyPrototypeLabs\published_reports.json (time, host, URL, visibility, size) so you can see what of yours is online.

The second tab, Share Report, is the opposite of the section above: no account, no upload, and no lasting trace. It opens a Cloudflare quick tunnel - one OUTBOUND connection from this machine, so no firewall rule and no inbound access are needed - and Cloudflare hands back a random public address such as https://green-pond-fox-tree.trycloudflare.com. The report is served from THIS computer while the window stays open. Close the window and the address stops working permanently: Cloudflare never reissues it.

Which of the two sharing routes to use

Share the report on the web (first tab)

Share Report (this tab)

Lifetime

until you take it down

only while this window is open

Needs an account

yes (GitHub / Netlify / Gitee)

no

Report is uploaded

yes, to a third-party server

no - served from this machine

Confidentiality

unlisted path, or a real password (AES-256-GCM)

none: anyone with the link can read it

Reliability

a normal hosting service

a Cloudflare TEST facility: rate-limited, no availability promise

Use it for

delivering results to a customer

letting somebody outside look at this for the next ten minutes

There is deliberately NO password on this route. While sharing, anyone who has the link can read the report, and a link can be forwarded or logged. The protection is that the window closes. Because of that, this tab must not be used as a delivery channel for customer results - use the first tab for that.

How to use it

1. Generate the report on the first tab (the Start button stays disabled until a report exists, and is disabled again while a new report is being generated).

2. Switch to Share Report and press "Start sharing".

3. The first time only, it offers to download Cloudflare's cloudflared.exe (about 52 MB) and says where from. It is saved once per user under %LOCALAPPDATA%\DragonflyPrototypeLabs\cloudflared and reused afterwards.

4. A confirmation dialog states the file, its size, that there is no password, and what ends the share. Read it: the report contains your image data.

5. Wait. The status goes "Address issued - waiting for it to start answering. Do not send it yet." Nothing is offered for copying during this stage on purpose.

6. Once the status turns green, use "Copy link", or let the other person scan the QR code (also saved next to the report as share_qr.png).

7. "Preview locally" opens the same page from this machine in your own browser - it is byte for byte what the recipient sees, served by the same server.

8. "Opened N times; last at ..." counts real reads of the page, so you can tell whether the other person actually looked.

9. Press "Stop sharing" when done - or simply close the window, or quit Dragonfly.

The three outcomes, and why there are three

Status

What it means

What to do

Live (green)

the public address was fetched from this machine and served our own page, so it is definitely routable

send the link

Could not confirm (amber)

the tunnel is open, but this machine could not reach the address within 2 minutes - usually its DNS name has not started resolving here yet, or Cloudflare rate-limited a repeated quick tunnel

the link is still offered: the recipient's DNS is not this one, so send it and ask, or stop and try again

Sharing failed (red)

cloudflared never reported an address at all - normally no outbound internet access, or a proxy blocking it

check outbound access from this machine; the log has cloudflared's own output

MEASURED on 2026-08-07 from this network, and the reason the amber state exists: of three consecutive quick tunnels, ONE became reachable (after 45 seconds) and two never resolved at all. The address is issued about 40 seconds before it starts working, so a tab that handed it over immediately would have you send a link that answers 404 - which is why this one waits, and says which of the three cases it is in rather than claiming success or failure it cannot prove.

What is exposed, and what is not

Only the one report page is served, from memory - never a directory, and never a file path a request could influence. noindex is sent both as a header and as a meta tag, and robots.txt disallows everything, so a crawler that stumbles on the address does not carry the report into a search index that would outlive the share. Anything that could write (POST, PUT, DELETE) is refused. The served page carries a bilingual banner telling the reader the link is temporary.

If Dragonfly is killed without closing the share, the tunnel process can outlive it and keep the address registered. Every tunnel is therefore recorded, and the tab sweeps leftovers from a previous session when it opens - so "closing the window kills the link" also holds after a crash.

8. Requirements

No venv, GPU or admin rights — pure in-process. xlsx, histograms and GIFs use Dragonfly's own openpyxl, matplotlib and Pillow respectively; choosing pptx downloads python-pptx once on first use (offline afterwards). 3D screenshots and GIFs need a real 3D view; with no usable view the captures are skipped and the statistics and histograms are still produced.

You’ve reached the end of this manual.Explore the library →