open3D打开stl文件的坑!!

项目场景:

本来一个10w点的stl点云文件,用meshlabpyvistacloudcompare等打开显示的都是10w点,用open3D打开偏偏显示的是60w点


问题描述

本来一个10w点的stl点云文件,用meshlabpyvistacloudcompare等打开显示的都是10w点,用open3D打开偏偏显示的是60w点, 导致我跑网络时爆了显存。
使用open3D检查发现,60w里其他的都是重复点,合并重复点之后就还是10w点,但是合并之后保存成stl文件,再用open3D打开就又变成60w点了。

import open3d as o3d

def process_stl_file(file_path):
    # 读取 STL 文件
    mesh = o3d.io.read_triangle_mesh(file_path)

    # 记录原始顶点数量
    original_vertices = len(mesh.vertices)

    # 合并重复顶点
    mesh = mesh.remove_duplicated_vertices()

    # 记录合并后的顶点数量
    merged_vertices = len(mesh.vertices)

    # 输出顶点数量变化
    print(f"原始顶点数量:{original_vertices}")
    print(f"合并后顶点数量:{merged_vertices}")

    # 计算法线
    mesh.compute_vertex_normals()

    # 覆盖保存 STL 文件
    o3d.io.write_triangle_mesh(file_path, mesh)

    # 再次加载检查
    mesh_reloaded = o3d.io.read_triangle_mesh(file_path)
    print(f"重载后顶点数量:{len(mesh_reloaded.vertices)}")

    # 再次处理重复顶点
    mesh_reloaded = mesh_reloaded.remove_duplicated_vertices()
    print(f"重载后(处理重复顶点)顶点数量:{len(mesh_reloaded.vertices)}")

# 调用处理函数
file_path = r"F:\scratch1\0.stl"
process_stl_file(file_path)


原因分析:

先说结论:stl文件没有问题,问题在open3d读取stl文件的逻辑上

STL 文件格式通常不包含顶点索引,而是将每个三角形的三个顶点直接存储。这意味着即使不同三角形共享相同的顶点,STL 文件中也会重复存储这些顶点。
当你从 STL 文件中读取网格时,Open3D 会将这些顶点重新加载,因此可能再次出现重复的顶点。


解决方案:

1.在跑网络时,用open3D读取stl后加入 mesh = mesh.remove_duplicated_vertices() ,就可以快速解决问题
2.将stl转化成ply文件,再用open3D读取

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用 Rust 打开并显示 STL 文件,您可以使用以下步骤: 1. 确定所需的 3D 引擎库。Rust 中有多个 3D 引擎库可供选择,例如 wgpu、glium、piston 等。在这里,我们以 wgpu 为例。 2. 创建一个 Rust 项目,并使用 Cargo 管理依赖。在项目中添加 wgpu 和 stl_io 依赖。 3. 编写代码来加载 STL 文件。可以使用 stl_io 库提供的 API 来实现。该库提供了一个 `load_ascii` 函数和一个 `load_binary` 函数,分别用于加载 ASCII 和二进制格式的 STL 文件。 4. 编写代码来渲染 STL 模型。可以使用 wgpu 提供的 API 来实现。 以下是一个简单的示例代码,该代码使用 wgpu 和 stl_io 实现了一个简单的 STL 模型查看器: ```rust use wgpu::{BackendBit, Device, Instance, Queue, Surface}; use stl_io::ReadBinary; async fn run() { // 初始化 wgpu let instance = Instance::new(BackendBit::PRIMARY); let surface = unsafe { instance.create_surface(window) }; let adapter = instance .request_adapter(&RequestAdapterOptions { power_preference: PowerPreference::Default, compatible_surface: Some(&surface), }) .await .unwrap(); let (device, queue) = adapter .request_device( &DeviceDescriptor { features: Default::default(), limits: Default::default(), shader_validation: true, }, None, ) .await .unwrap(); // 加载 STL 模型 let path = Path::new("path/to/your/stl_model"); let mut reader = BufReader::new(File::open(path).unwrap()); let mut stl_file = reader.read_binary().unwrap(); // 渲染 STL 模型 // ... } fn main() { env_logger::init(); // 创建事件循环 let event_loop = EventLoop::new(); let window = WindowBuilder::new().build(&event_loop).unwrap(); let mut state = AppState::new(&window); // 运行事件循环 let event_loop_proxy = event_loop.create_proxy(); let event_loop_runner = event_loop.run(event_loop_proxy, &mut state); smol::block_on(run()); } ``` 在此代码中,我们首先初始化了 wgpu,并加载了一个 STL 模型。然后,我们可以使用 wgpu 提供的 API 来渲染 STL 模型,例如创建顶点缓冲区、着色器程序、渲染管道等。请注意,此代码仅适用于二进制格式的 STL 文件。如果您要加载 ASCII 格式的 STL 文件,您需要使用 `load_ascii` 函数而不是 `load_binary` 函数来加载文件

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值