python读取.stl文件(以及转换为obj方法)

这篇具有很好参考价值的文章主要介绍了python读取.stl文件(以及转换为obj方法)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

.1 文本方式读取 

代码如下

stl_path='/home/pxing/codes/point_improve/data/003_cracker_box/0.stl'



points=[]
f = open(stl_path)
lines = f.readlines()
prefix='vertex'
num=3
for line in lines:
    #print (line)

    if line.startswith(prefix):

        values = line.strip().split()
        #print(values[1:4])
        if num%3==0:
          points.append(values[1:4])
          num=0
        num+=1
    #print(type(line))
print(points)
f.close()

该代码可以直接将stl文件中对点直接都输出

改进版本

import numpy as np

stl_path='/home/pxing/codes/point_improve/data/003_cracker_box/0.stl'
points=[]
f = open(stl_path)
lines = f.readlines()
prefix='vertex'
num=3
for line in lines:
    #print (line)

    if line.startswith(prefix):

        values = line.strip().split()
        #print(values[1:4])
        if num%3==0:
          points.append(values[1:4])
          num=0
        num+=1
    #print(type(line))
points=np.array(points)
f.close()
print(points.shape)
np.save("/home/pxing/codes/point_improve/feature_get/point_get/test.npy", points)

把输出的点转换为npy并且保存

1.1 stl解析

.stl文件格式如下图所示:

python读取.stl文件(以及转换为obj方法)

那么读取该文件就需要知道stl的构成

stl是一种表示三角网格的文件格式

STL只能用来表示封闭的面或者体,stl文件有两种:一种是ASCII明码格式,另一种是二进制格式

ASCII明码格式:

STL文件的首行给出了文件路径及文件名

STL三维模型就是由一系列这样的三角面片构成

三角面片的信息单元 facet 是一个带矢量方向的三角面片

每一个facet由7 行数据组成:

facet normal 是三角面片指向实体外部的法矢量坐标

outer loop 代表随后的3行数据分别是三角面片的3个顶点坐标

3顶点沿指向实体外部的法矢量方向逆时针排列

solid [filename] //文件名,可以是任何字符

facet normal [i j k] //面的法线,i、j、k为三个分量,各分量之间用空格隔开,不能用逗号隔开

outor loop

vertex [x y z] //三角面片的第一个点,x、y、z三个坐标之间要用空格隔开

vertex [x y z] //三角面片的第二个点

vertex [x y z] //三角面片的第三个点

endloop

endfacet //完成一个三角面片的定义

、、、、 //其他facet

endsolid [filename] //完成一个stl文件的定义

示例:

在电脑上新建一个txt文件,然后编辑。编辑完了之后保存,并将文件后缀名改为stl,即可完成一个创建了一个stl文件。如下图,利用文本编辑器将一个四面体的几何数据保存到文件中

效果如下图所示:

python读取.stl文件(以及转换为obj方法)

1.2 stl创建 

创建一个三角形面片

solid   mystl    
facet   normal  0 -1 0
outor   loop
vertex  -100 0 0 
vertex  100 0 0
vertex  0 0 -100 
endloop
endfacet 
end solid mystl

python读取.stl文件(以及转换为obj方法)

1.3 stl分割

完成了stl分割

stl_path='/home/harry/projects/spoon_to_scoop/object_process/spilt/decomp.stl'
with open(stl_path, "r") as f:
    lines = f.readlines()
    target_end = "endsolid" 
    i=0
    for line in lines:
            with open('/home/harry/projects/spoon_to_scoop/object_process/spilt/'+'bow_'+str(i)+".stl", "a") as new_f:
                new_f.write(line)
            if target_end in line:
                i+=1

python读取.stl文件(以及转换为obj方法)

1.4 obj读取

def read_obj_vertices(file_path):
    vertices = []

    with open(file_path, 'r') as file:
        for line in file:
            if line.startswith('v '):
                vertex = line.strip().split(' ')[1:]
                vertex = [float(coord) for coord in vertex]
                vertices.append(vertex)

    return vertices


if __name__=='__main__':
    obj_file_path = './object/nontextured.obj'
    vertices = read_obj_vertices(obj_file_path)

    list=[]

    for vertex in vertices:
        list.append(vertex)
    print(list[0])

.2 把点转换为.stl

import numpy as np
import sys
sys.path.append('/home/pxing/codes/grasp_ROI_get/')
from gripper_area import area_get

arr=np.array(area_get.main())
#print(arr[0,0:3])
with open('stl_process/data/test1.stl','a') as file0:
    print('solid   mystl ',file=file0)
    print('facet   normal' ,0,0,0,file=file0)
    print('outor   loop',file=file0)
    
    print('vertex',arr[0,0],arr[0,1],arr[0,2 ],file=file0)
    print('vertex',arr[1,0],arr[1,1],arr[1,2 ],file=file0)
    print('vertex',arr[2,0],arr[2,1],arr[2,2 ],file=file0)
    
    print('endloop\nendfacet',file=file0)
    print('end solid mystl',file=file0)

.3 stl组装

import os
import numpy as np

def stl_get(stl_path):
    points=[]
    f = open(stl_path)
    lines = f.readlines()
    prefix='vertex'
    num=3
    for line in lines:
        #print (line)

        if line.startswith(prefix):
            values = line.strip().split()
            #print(values[1:4])
            if num%3==0:
                points.append([values[1],values[2],values[3]])
                num=0
            num+=1
        #print(type(line))
    points=np.array(points,dtype='float64')

    #points=points*1000#3d打印用

    
    f.close()
    #print(points.shape)
    #np.save("/home/pxing/codes/point_improve/feature_get/point_get/index_mm_level.npy", t)
    return points

def stl_generate(arr,stl_path):
    with open(stl_path,'a') as file0:
        print('solid   mystl ',file=file0)
        for i in range((arr.shape[0]-3)):
            print('facet   normal' ,0,0,0,file=file0)
            print('outor   loop',file=file0)
            print('vertex',arr[i,0],arr[i,1],arr[i,2 ],file=file0)
            print('vertex',arr[i+1,0],arr[i+1,1],arr[i+1,2 ],file=file0)
            print('vertex',arr[i+2,0],arr[i+2,1],arr[i+2,2 ],file=file0)
            print('endloop\nendfacet',file=file0)
        
        print('end solid mystl',file=file0)
    print('generate success')

def mkdir(path):
 
	folder = os.path.exists(path)

	if not folder:#判断是否存在文件夹如果不存在则创建为文件夹
		os.makedirs(path) #makedirs 创建文件时如果路径不存在会创建这个路径




file_path='/home/pxing/codes/point_improve/data/process_projection/'#stl储存的位置
goods_list=os.listdir(file_path)
for i in goods_list:
    #对所有0子文件夹进行组装
    index=0
    file_stl_path=file_path+i+'/'+str(index)
    stl_list=os.listdir(file_stl_path)
    
    if stl_list:
        arr_assembly=np.array([[0,0,0]])#创建一个空数组来组成后面的元素
        for j in stl_list:
            print(stl_list)
            stl_path=file_stl_path+'/'+j
            arr=stl_get(stl_path)
            arr_assembly=np.concatenate((arr_assembly,arr),axis=0)
        
        arr_assembly=np.delete(arr_assembly,[0,0],axis=0)
        file_save_path='/home/pxing/codes/point_improve/data/auto_assembly_data/'+i+'/'+str(index)
        mkdir(file_save_path)
        stl_save_path=file_save_path+'/'+str(index)+'.stl'
        stl_generate(arr_assembly,stl_save_path)
            
        
    else:
        pass

.4 stl转obj(带f法向量的obj)

import numpy as np



def stl_get(stl_path):
    points=[]
    f = open(stl_path)
    lines = f.readlines()
    prefix='vertex'
    num=3
    for line in lines:
        #print (line)

        if line.startswith(prefix):
            values = line.strip().split()
            #print(values[1:4])
            if num%3==0:
                points.append([values[1],values[2],values[3]])
                num=0
            num+=1
        #print(type(line))
    points=np.array(points,dtype='float64')

    #points=points*1000#3d打印用

    
    f.close()
    #print(points.shape)
    #np.save("/home/pxing/codes/point_improve/feature_get/point_get/index_mm_level.npy", t)
    return points

# 点云数据

stl_path='/home/pxing/codes/point_improve/data/rotation_data/assembly_projection_isaac.stl'
points = stl_get(stl_path)

# 计算点云的法向量
def compute_normals(points):
    normals = []
    for i, p0 in enumerate(points):
        v1 = points[(i+1) % len(points)] - p0
        v2 = points[(i+2) % len(points)] - p0
        normals.append(np.cross(v1, v2))
    return normals

normals = compute_normals(points)

# 将点云和法向量保存为OBJ格式文件
with open('/home/pxing/codes/point_improve/data/obj/point_f_assembly.obj', 'w') as f:
    for i, p in enumerate(points):
        f.write(f'v {p[0]} {p[1]} {p[2]}\n')
        n = normals[i]
        f.write(f'vn {n[0]} {n[1]} {n[2]}\n')

生成带面的obj文章来源地址https://www.toymoban.com/news/detail-450494.html

import numpy as np



def stl_get(stl_path):
    points=[]
    f = open(stl_path)
    lines = f.readlines()
    prefix='vertex'
    num=3
    for line in lines:
        #print (line)

        if line.startswith(prefix):
            values = line.strip().split()
            #print(values[1:4])
            if num%3==0:
                points.append([values[1],values[2],values[3]])
                num=0
            num+=1
        #print(type(line))
    points=np.array(points,dtype='float64')

    #points=points*1000#3d打印用

    
    f.close()
    #print(points.shape)
    #np.save("/home/pxing/codes/point_improve/feature_get/point_get/index_mm_level.npy", t)
    return points

# 点云数据

stl_path='/home/pxing/codes/point_improve/data/rotation_data/assembly_projection_isaac.stl'
points = stl_get(stl_path)
 

# 计算点云的法向量
def compute_normals(points):
    normals = []
    for i, p0 in enumerate(points):
        v1 = points[(i+1) % len(points)] - p0
        v2 = points[(i+2) % len(points)] - p0
        normals.append(np.cross(v1, v2))
    return normals

normals = compute_normals(points)

# 将点云和法向量保存为OBJ格式文件
with open('/home/pxing/codes/point_improve/data/obj/point_f_assembly.obj', 'w') as f:
    for i, p in enumerate(points):
        f.write(f'v {p[0]} {p[1]} {p[2]}\n')
        n = normals[i]
        f.write(f'vn {n[0]} {n[1]} {n[2]}\n')

    # 将点云转换为面信息
    for i in range(0, len(points), 3):
        f.write(f'f {i+1}//{i+1} {i+2}//{i+2} {i+3}//{i+3}\n')

.5 ply生成

import numpy as np

def stl_get(stl_path):
    points=[]
    f = open(stl_path)
    lines = f.readlines()
    prefix='vertex'
    num=3
    for line in lines:
        #print (line)

        if line.startswith(prefix):
            values = line.strip().split()
            #print(values[1:4])
            if num%3==0:
                points.append([values[1],values[2],values[3]])
                num=0
            num+=1
        #print(type(line))
    points=np.array(points,dtype='float64')

    #points=points*1000#3d打印用

    
    f.close()
    #print(points.shape)
    #np.save("/home/pxing/codes/point_improve/feature_get/point_get/index_mm_level.npy", t)
    return points

# 点云数据

stl_path='/home/pxing/codes/point_improve/data/rotation_data/assembly_projection_isaac.stl'
points = stl_get(stl_path)

# 将点云保存为含有顶点和面信息的PLY格式文件
with open('/home/pxing/codes/point_improve/data/obj/point_cloud.ply', 'w') as f:
    # 写入PLY文件头
    f.write('ply\n')
    f.write('format ascii 1.0\n')
    f.write(f'element vertex {len(points)}\n')
    f.write('property float x\n')
    f.write('property float y\n')
    f.write('property float z\n')
    f.write(f'element face {len(points)}\n')
    f.write('property list uchar int vertex_indices\n')
    f.write('end_header\n')

    # 写入点云数据
    for p in points:
        f.write(f'{p[0]} {p[1]} {p[2]}\n')

    # 写入面数据
    for i in range(len(points)):
        f.write(f'3 {i} {i} {i}\n')

到了这里,关于python读取.stl文件(以及转换为obj方法)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python 文本文件的读取

    在Python编程中,读取文件是非常常见的操作。 文件一般分为文本文件和二进制文件两种。 下面介绍文本文件的读取方法: 1. 使用open函数读取文件 使用Python内置函数open()可以打开一个文件,并返回一个文件对象。在文件对象上可以调用read()方法读取文件内容。以下是一个简单

    2024年02月06日
    浏览(43)
  • python中读取文本文件txt

    文件创建 如果文件不存在就是创建,如果文件存在就是打开操作 文件对象创建 文件读 以下的函数都是文件对象的成员函数 read() 一次性读取文件的所有内容放在一个大字符串中,即存在内存中 readline() 逐行读取文本,结果是一个list readlines() 一次性读取文本的所有内容,结

    2024年02月05日
    浏览(67)
  • Python:实现文本转换为Excel文件(附代码)

    Python:实现文本转换为Excel文件(附代码) 在日常办公和生活中,我们经常需要将文本文件转换为Excel文件,以便更好地进行管理和处理。利用Python编程语言,可以非常方便地实现这一操作。 以下是Python实现文本转换为Excel文件的完整源代码:

    2024年02月14日
    浏览(47)
  • Python读取文件相对路径理解以及文件读取路径格式

    绝对路径 :指的是是当前文件在 计算机磁盘中存放的具体位置 就是死的,物理上面的 相对路径 :指的是文件 相对于当前的py文件所处的位置 。就是参照py文件来说明路径,参照物嘛 读取文件路径方式(path.xls文件为例子)   执行命令的py文件同path.xls文件在同一个目录an

    2024年02月06日
    浏览(45)
  • 倾斜摄影三维模型OSGB格式转换OBJ格式的主要技术方法

     将倾斜摄影所获得的三维模型从OSGB格式转换为OBJ格式,可以实现更加灵活和便捷的数据应用和管理。主要技术方法如下: 1、使用转换工具 目前市面上有许多三维模型格式转换工具,比如K3DMaker、FME、GlobalMapper、ArcGIS等。这些工具可以将OSGB格式的倾斜摄影三维模型转换为

    2024年02月07日
    浏览(39)
  • vue-3d-model js在线预览obj,dae,ply,json,fbx,stl,gltf格式的3D文件

    在线预览地址vue-3d-model js在线预览obj,dae,ply,json,fbx,stl,gltf格式的3D文件 效果: 例子使用了.obj 3D文件格式,自带了截图和旋转功能,其他的3D格式只需要切换一个vue的模板标签即可。具体标签格式如下: 可支持obj,dae,ply,json,fbx,stl,gltf等格式的3D文件格式显示。只需要单页面html即

    2024年02月12日
    浏览(53)
  • Python读取一个csv文件并转换为Numpy矩阵

    利用pandas库读取,转为numpy矩阵 注意读取csv文件时第一行数据默认不读,因此需要给csv加一行。   运行结果  

    2024年02月12日
    浏览(40)
  • [visionOS] [Apple Vision Pro] 3D模型文件格式转换:obj转usdz

    1,先要安装好Python3.7 【必须是Python3.7.x版本】 到Python官方去下载macOS版的Python3.7.x安装包 Python Releases for macOS | Python.org 要注意找一下,有些 3.7.x版本没有macOS安装包, 这里直接给出其中两个可以下载的 Python 3.7.8rc1 - June 17, 2020 Download macOS 64-bit installer Python 3.7.9 - Aug. 17, 2020

    2024年02月16日
    浏览(107)
  • Python - 读取pdf、word、excel、ppt、csv、txt文件提取所有文本

    本文对使用python读取pdf、word、excel、ppt、csv、txt等常用文件,并提取所有文本的方法进行分享和使用总结。 可以读取不同文件的库和方法当然不止下面分享的这些,本文的代码主要目标都是:方便提取文件中所有文本的实现方式。 这些库的更多使用方法,请到官方文档中查

    2024年02月13日
    浏览(102)
  • python hdfs远程连接以及上传文件,读取文件内容,删除文件

    目录 一、python连接操作hdfs 1 往hdfs上传文件 2 处理并存储到hdfs 3 读取hdfs上的txt文件 这里使用的是 pip 安装,很方便:      

    2024年02月11日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包