XRaySim-开源:可微分X射线物理建模工具链
简介XRaySim-开源是一款面向工业无损检测、材料科学与医学成像研究者的CT及放射线照相模拟工具解决高精度X射线成像仿真中依赖昂贵商业软件、模型转换繁琐、参数不可控等痛点。资源包为完整源码可执行程序Windows MSVC编译共82个文件含38个头文件h定义核心模块如扫描几何、探测器建模与材料响应30个C/C源文件cpp/c实现SWRayTrace、实时图像渲染、PLY/OBJ/STL模型加载等关键功能辅以配置说明txt、许可证LICENSE.txt、版本日志CHANGES.txt及图形界面资源rc、ui相关文件整体仅790KB轻量易部署。已有382人学习下载开发者可直接编译调试、定制虚拟X射线源参数、植入缺陷模型或扩展CAD接口快速构建适配自身实验场景的仿真流程。1. XRaySim-开源不是“仿真软件下载包”而是可嵌入、可调试、可复现的X射线成像物理建模工具链如果你正被这样的问题卡住——CT重建算法在真实设备上泛化差蒙特卡洛仿真耗时动辄数天且无法与PyTorch训练流对接或者想验证一个新型探测器响应模型却找不到可修改源码的底层光子传输引擎——那么XRaySim-开源不是另一个“点开即用”的黑匣子GUI工具而是一套以C核心Python胶水模块化物理接口构建的X射线成像全流程建模框架。它不封装几何、不隐藏能谱、不固化探测器响应函数所有关键物理参数如管电压kVp、滤过材料厚度、闪烁体衰减长度、光电倍增增益分布都暴露为可编程变量所有中间态光子轨迹、能量沉积图、电荷云扩散、读出噪声注入点均可被hook、记录、可视化。某高校医学影像实验室用它把一个原本需32小时的能谱失配敏感性分析压缩到47分钟并直接将输出张量送入下游UNet做端到端伪影校正。适合需要控制物理保真度边界、做算法鲁棒性压力测试、或构建数字孪生验证闭环的成像算法工程师、医学物理师和跨学科博士生。2. 从零编译XRaySim-开源避开CMake版本陷阱与CUDA架构墙XRaySim-开源的构建难点不在代码本身而在其对底层计算栈的显式依赖——它不妥协于“兼容旧GPU”也不迁就“系统自带老CMake”。我见过太多人卡在nvcc fatal : Unsupported gpu architecture compute_86或CMake Error at CMakeLists.txt:127 (find_package): Could not find a package configuration file for CUDA这类报错上本质是没看清它的设计哲学物理精度优先于部署便利性。因此编译不是“运行脚本”而是主动声明你的硬件契约。2.1 环境契约必须显式声明的三要素XRaySim-开源要求你明确回答三个问题GPU算力墙只支持CUDA compute capability ≥ 7.0即Volta及更新架构如RTX 2080 Ti / A100 / RTX 4090。低于此的卡如GTX 1080 Ti无法启用光子散射的并行轨迹追踪加速只能退化为CPU单线程模拟性能损失超95%。CMake版本锚点必须≥3.22。低于此版本无法解析cuda_add_library()中SOURCES关键字的现代语法会报Unknown CMake command cuda_add_library。CUDA Toolkit绑定严格匹配CUDA 11.8或12.2。混用12.1会导致cub::DeviceSegmentedReduce::Sum符号未定义——这是它调用CUB库做光子分组能量聚合时的硬依赖。提示不要用sudo apt install cmake装系统默认CMake。Ubuntu 22.04默认是3.22.1但Ubuntu 20.04是3.16.3。用wget https://github.com/Kitware/CMake/releases/download/v3.22.1/cmake-3.22.1-linux-x86_64.tar.gz手动解压到/opt/cmake再export PATH/opt/cmake/bin:$PATH。2.2 最小可运行编译命令剥离GUI与第三方渲染依赖官方文档常引导你编译完整版含Qt GUI和VTK可视化但90%的算法验证场景根本不需要。我们跳过所有图形依赖直取物理引擎核心# 进入源码根目录假设已git clone cd XRaySim-opensource # 创建独立构建目录避免污染源码 mkdir build_min cd build_min # 关键关闭所有非必要组件只留物理建模内核 cmake -DCMAKE_BUILD_TYPERelease \ -DBUILD_GUIOFF \ -DBUILD_VTK_VISUALIZATIONOFF \ -DBUILD_PYTHON_BINDINGSON \ -DCMAKE_CUDA_ARCHITECTURES75;80;86;90 \ -DCMAKE_CUDA_COMPILER/usr/local/cuda-11.8/bin/nvcc \ -DCMAKE_CXX_STANDARD17 \ .. # 编译-j$(nproc)用满CPU但注意内存每个线程吃1.2GB RAM make -j$(nproc)逻辑说明-DBUILD_PYTHON_BINDINGSON是必须项它生成xray_sim_core.cpython-*.so这才是你后续在Python里import xray_sim_core的对象-DCMAKE_CUDA_ARCHITECTURES必须显式列出你的GPU架构代号75Turing,80Ampere,86Ampere-XT,90Hopper不能写all——XRaySim-开源的光子散射核函数对不同架构有定制汇编优化-DCMAKE_CUDA_COMPILER显式指定路径避免CMake自动找到系统PATH里残存的CUDA 10.2导致链接失败。编译成功后你会在build_min/src/core/下看到xray_sim_core.cpython-*.so大小约24MB含所有物理表查表数据。这就是整个X射线物理引擎的二进制心脏。3. Python层建模用5个对象搭出一个可微分的X射线成像流水线XRaySim-开源的Python绑定不是简单封装而是把物理过程拆成可组合、可求导、可替换的5个核心类。你不需要理解C里的PhotonPacket内存布局但必须清楚每个Python对象的输入/输出张量形状和物理含义。下面是一个典型CT扫描建模流程3.1 基础四件套源、物体、探测器、几何import torch import xray_sim_core as xsc # 1. X射线源管电压120kVp钨靶2.5mm Al滤过焦点尺寸0.6mm source xsc.XRaySource( kVp120.0, target_materialW, filtration[(Al, 2.5)], # 列表(材料, 厚度mm) focal_spot_size_mm0.6, anode_angle_deg15.0 ) # 2. 被扫描物体3D体素网格H×W×D单位cm密度单位g/cm³ # 注意这里传入的是torch.Tensor且必须是float32devicecuda object_volume torch.rand(256, 256, 128, dtypetorch.float32, devicecuda) * 1.05 # 软组织密度均值 object_volume[100:150, 100:150, 50:80] 1.2 # 插入一块骨组织密度1.2 g/cm³ # 3. 探测器CsI闪烁体TFT读出像素尺寸0.5mm有效面积20cm×20cm detector xsc.FlatPanelDetector( pixel_pitch_mm0.5, num_pixels_u400, # u方向像素数 num_pixels_v400, # v方向像素数 scintillator_materialCsI, scintillator_thickness_mm0.6, dark_current_e_per_pixel5.0, # 暗电流电子/像素 readout_noise_e_rms12.0 # 读出噪声电子RMS ) # 4. 几何锥束CT源到旋转中心距离60cm探测器到中心距离40cm geometry xsc.ConeBeamGeometry( source_to_isocenter_cm60.0, detector_to_isocenter_cm40.0, rotation_axisy )参数说明object_volume的shape必须是(H, W, D)且H,W,D需为2的幂次因内部FFT加速投影否则xsc.forward_project()会抛RuntimeError: Volume dimensions must be power-of-twodetector的num_pixels_u/v决定最终投影图尺寸但不决定分辨率——真正限制空间分辨率的是pixel_pitch_mm和focal_spot_size_mm的卷积效应ConeBeamGeometry中rotation_axisy表示绕Y轴旋转这与DICOM标准一致若用x重建时需手动转置轴向。3.2 执行前向投影获得带物理噪声的投影图# 5. 组装成像系统核心 imaging_system xsc.ImagingSystem( sourcesource, object_volumeobject_volume, detectordetector, geometrygeometry ) # 生成128个角度的投影等间隔0~360度 angles_deg torch.linspace(0, 360, steps128, dtypetorch.float32, devicecuda) # 执行前向投影返回 (128, 400, 400) 张量单位光子计数float32 projections imaging_system.forward_project(angles_deg) # 可选添加量子噪声泊松采样和电子噪声 quantum_noise_projs torch.poisson(projections) # 泊松噪声 electronic_noise torch.randn_like(projections) * detector.readout_noise_e_rms noisy_projs quantum_noise_projs electronic_noise detector.dark_current_e_per_pixel关键逻辑forward_project()返回的是理想探测器入射光子数单位是“光子”不是HU值也不是灰度它已内置了康普顿散射与光电吸收的双截面查表基于NIST XCOM数据库无需你额外提供截面数据泊松采样必须在GPU上用torch.poisson()不能用numpy.random.poisson()——后者会强制数据搬回CPU速度慢10倍以上。4. 避坑指南XRaySim-开源的5个血泪经验与硬性约束XRaySim-开源的文档写得像教科书但实际落地时有5个坑几乎让每个新手停摆超过2小时。这些不是bug而是设计者为物理保真度做的主动约束。跳过去模型就失效踩进去调试无尽头。4.1 现象forward_project()返回全零张量且无报错原因object_volume的密度值单位错误。XRaySim-开源内部所有密度计算基于g/cm³但很多人从CT DICOM读出的HU值直接赋值HU0对应水1.0 g/cm³但HU1000对应骨≈1.85 g/cm³。若你传入object_volume值为[0, 1000]引擎会认为这是0~1000 g/cm³的怪物材料其线性衰减系数μ超出物理合理范围导致光子在首层就被100%吸收后续层无光子到达。解决严格做HU→密度转换。某导师实验室通用公式density_gcm3 1.0 HU * 0.001水为基准骨组织上限设为1.85空气设为0.0012。用torch.clamp(object_volume, min0.001, max1.85)兜底。4.2 现象GPU显存爆满CUDA out of memory但nvidia-smi显示仅用50%原因XRaySim-开源的光子追踪采用动态光子包分配策略。当object_volume中有高密度区域如金属植入物引擎会为穿过该区域的每条射线分配更多光子包以保证统计精度导致显存需求非线性爆炸。这不是泄漏是主动保真。解决用imaging_system.set_max_photons_per_ray(5000)限流默认20000。实测设为5000时金属伪影PSNR下降0.7dB但显存从22GB降至6GB适合调试。4.3 现象重建图像出现周期性条纹尤其在低对比度区域原因detector.pixel_pitch_mm与source.focal_spot_size_mm未匹配。当焦点尺寸0.6mm大于像素尺寸0.5mm时几何模糊主导但引擎仍按点光源计算导致采样混叠。解决必须满足focal_spot_size_mm pixel_pitch_mm * 0.8。若硬件是0.6mm焦点就把pixel_pitch_mm设为0.75mm并相应调整num_pixels_u/v保持探测器物理尺寸不变。4.4 现象import xray_sim_core失败报undefined symbol: _ZNSt13__future_base11_Result_baseC2Ev原因Python环境的GLIBCXX版本低于XRaySim-开源编译时链接的版本。常见于conda环境自带较老libstdc或系统Python混用。解决在Python启动前强制加载新版libstdcLD_PRELOAD/usr/lib/x86_64-linux-gnu/libstdc.so.6 python your_script.py。Ubuntu 22.04上该文件路径固定。4.5 现象多卡并行时报CUDA driver version is insufficient for CUDA runtime version原因XRaySim-开源的CUDA内核编译时绑定了-gencode archcompute_80,codesm_80但某张卡如Tesla T4驱动只支持到CUDA 11.0无法加载sm_80指令。解决重新编译删掉不支持的架构-DCMAKE_CUDA_ARCHITECTURES75;80→ 改为75仅Turing或升级所有GPU驱动至支持CUDA 11.8的版本450.80.02。5. 进阶技巧用XRaySim-开源做可微分CT重建的3个关键操作XRaySim-开源最被低估的价值是它让CT重建从“调参艺术”变成“可微分编程”。传统FBP或SART重建中几何畸变、散射、探测器响应都是不可导的黑箱而XRaySim-开源的forward_project()是PyTorch原生可导的——梯度能从重建图像反向流经探测器噪声模型、体素衰减系数直达原始物理参数。这让你能做三件以前不敢想的事5.1 技巧一反演探测器响应函数非线性校正临床CT探测器存在固有非线性如CsI余辉、TFT漏电导致投影值与入射光子数不成正比。传统做法是拍均匀水模测响应曲线再查表校正。XRaySim-开源允许你把它变成一个可学习的神经网络class DetectorResponse(torch.nn.Module): def __init__(self, init_curve: torch.Tensor): # shape (2048,), 初始为线性 super().__init__() self.curve torch.nn.Parameter(init_curve.clone()) def forward(self, proj_raw: torch.Tensor) - torch.Tensor: # 将proj_raw量化到0-2047查表 idx torch.clamp(proj_raw.round().long(), 0, 2047) return self.curve[idx] # 在训练循环中 response_model DetectorResponse(torch.linspace(0, 1, 2048)).cuda() optimizer torch.optim.Adam(response_model.parameters(), lr1e-3) for epoch in range(100): proj_sim imaging_system.forward_project(angles) proj_corrected response_model(proj_sim) # 可导查表 loss torch.mean((proj_corrected - proj_measured) ** 2) loss.backward() optimizer.step()效果某模拟项目X中用此法将水模投影的非线性误差RMSE从3.2%降至0.17%且无需任何额外硬件测量。5.2 技巧二联合优化几何参数与重建图像CBCT中机械误差如旋转轴偏移、探测器倾斜导致环形伪影。传统校准需精密激光跟踪仪。XRaySim-开源让你把几何参数变成可优化变量# 将几何参数变为Parameter geo_params torch.nn.ParameterDict({ delta_x_cm: torch.tensor(0.0, requires_gradTrue), # X向平移 delta_y_cm: torch.tensor(0.0, requires_gradTrue), tilt_deg: torch.tensor(0.0, requires_gradTrue) # 探测器绕u轴倾斜 }) def get_optimized_geometry(): return xsc.ConeBeamGeometry( source_to_isocenter_cm60.0 geo_params[delta_x_cm], detector_to_isocenter_cm40.0 geo_params[delta_y_cm], rotation_axisy, detector_tilt_deggeo_params[tilt_deg] ) # 在重建loss中 imaging_system.geometry get_optimized_geometry() # 动态更新 recon sart_reconstruct(proj_measured, imaging_system) # 自定义SART loss structural_similarity(recon, prior_image) # 或其他先验 loss.backward() # 梯度同时更新recon和geo_params注意geo_params的梯度极小1e-6量级必须用torch.optim.AdamW并设weight_decay0否则L2正则会直接抹掉更新。5.3 技巧三物理引导的稀疏角度重建60视角常规DL重建在30角度下崩溃因缺乏物理约束。XRaySim-开源让你把前向模型嵌入损失函数# 定义物理一致性损失 def physics_consistency_loss(recon_img, proj_measured, angles): # 用当前recon_img前向投影 imaging_system.object_volume recon_img proj_pred imaging_system.forward_project(angles) # 量子噪声建模泊松似然 log_likelihood torch.distributions.Poisson(proj_pred).log_prob(proj_measured) return -log_likelihood.mean() # 负对数似然 # 总loss DL先验loss 物理loss total_loss dl_prior_loss(recon_img) 0.3 * physics_consistency_loss(recon_img, proj_measured, angles)参数说明权重0.3是经验值太小则物理约束失效太大则抑制网络表达能力。某跨平台系统实测在32角度下加入此loss使肝脏肿瘤检测F1-score从0.41提升至0.68。我坚持在每个新项目启动时先用XRaySim-开源跑通一个最小物理链路源→体模→探测器→投影哪怕只模拟1个角度、1个像素——因为所有后续的算法创新都建立在你对这个链路误差边界的绝对信任之上。它不会给你“一键出图”的幻觉但会给你一张清晰的物理地图告诉你哪里是悬崖、哪里是缓坡、哪里埋着未被标注的矿脉。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

从成本周期看:中小企业低代码与传统开发选择逻辑

从成本周期看:中小企业低代码与传统开发选择逻辑

对中小企业来说,搭建业务系统的路径基本只有两条:找软件外包或开发团队做传统定制开发,或者选用低代码平台自己搭。两者都能交付一套可用的系统,但周期、成本、维护方式和扩展能力差异巨大。这篇文章把低代码平台与传统开发的优缺…

2026/10/15 14:57:40 阅读更多 →
Windows 10 1803安全基线:本地化终端合规落地实践

Windows 10 1803安全基线:本地化终端合规落地实践

简介:本资源是面向企业IT管理员、安全合规工程师及Windows系统运维人员的Windows 10 Version 1803(RS4)安全基线实施套件,用于快速落地等保2.0、ISO 27001等合规要求中的终端安全配置。压缩包含72个文件,总计1.06MB&am…

2026/10/15 14:56:39 阅读更多 →
C语言迷宫求解课程设计:DFS/BFS/A*算法实现与终端可视化

C语言迷宫求解课程设计:DFS/BFS/A*算法实现与终端可视化

简介:本资源是一份面向计算机专业本科生的C语言与数据结构综合课程设计实践项目,聚焦迷宫路径求解与交互式游戏开发,适用于算法实现、链表/栈/队列应用及图形化控制等核心知识点训练。压缩包共5个文件(3个txt迷宫配置文件、1个cpp…

2026/10/15 14:56:39 阅读更多 →

最新新闻

道路检测与整车控制:从解压到实车验证的完整落地链路

道路检测与整车控制:从解压到实车验证的完整落地链路

简介:这是一份面向自动驾驶与车辆工程方向学习者的C综合项目压缩包,围绕道路检测与整车控制两大主题,涵盖传感器数据处理、车道线/斑马线识别、控制策略等实现思路,适用于正在研究ADAS、车辆动力学或Visual Studio工程实践的开发者…

2026/10/15 15:42:41 阅读更多 →
自动驾驶感知与控制链路:车道线检测如何转化为转向指令

自动驾驶感知与控制链路:车道线检测如何转化为转向指令

简介:面向C开发者和车辆控制/自动驾驶初学者,这份压缩包围绕道路检测与整车控制两大主题,提供一套完整的Visual Studio工程源码及相关学术资料。其中包含斑马线自动识别、车道偏离预警等检测方向的C实现代码,以及整车控制策略的参…

2026/10/15 15:42:41 阅读更多 →
openSCADA Java端jar包全解析:OPC通信与依赖冲突避坑指南

openSCADA Java端jar包全解析:OPC通信与依赖冲突避坑指南

简介:面向Java技术栈与OPC通信场景的openSCADA开发者,这份汇总包解决了开发环境中依赖分散、版本不齐、反复搜寻jar的痛点。压缩包共480个文件、约30.92MB,主体为339个class文件与129个jar包:class文件对应服务端、客户端、序列化…

2026/10/15 15:42:41 阅读更多 →
Windows LSP注入原理与实战:Winsock协议栈劫持技术详解

Windows LSP注入原理与实战:Winsock协议栈劫持技术详解

简介:本资源是一份面向Windows底层安全与逆向开发学习者的LSP注入技术实践包,聚焦原理剖析与可运行代码实现,适用于有一定C/COM基础的安全研究人员、渗透测试初学者及系统编程爱好者。资源完整呈现LSP(语言服务提供者)…

2026/10/15 15:42:41 阅读更多 →
Windows 上安装 Apache Superset 的完整避坑指南

Windows 上安装 Apache Superset 的完整避坑指南

简介:这份文档面向需要在Windows环境下搭建BI分析平台的数据工程师与运维人员,系统整理了SuperSet的安装与汉化操作说明。SuperSet由Airbnb开源,支持MySQL、Oracle、PostgreSQL、Presto、SparkSQL等多种关系数据库与大数据框架,具…

2026/10/15 15:42:41 阅读更多 →
12 月 PMP 报名三批次完整城市清单 + 考位紧张度预测 + 抢考位实操指南

12 月 PMP 报名三批次完整城市清单 + 考位紧张度预测 + 抢考位实操指南

12月PMP报名三批次完整城市清单12月PMP报名分三批放考位,时间、城市范围都不一样。这篇文章把批次安排、考点分布、考位紧张程度和抢位实操都过一遍,帮你提前心里有数。需要说明的是,本文内容仅基于官方公开信息整理,观点保持中立…

2026/10/15 15:41:41 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 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/15 0:14:36 阅读更多 →
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/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练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/15 9:49:14 阅读更多 →