从常规网格数据库创建wavefront .obj文件

时间:2018-01-07 02:16:44

标签: python database blender point-cloud-library octree

我尝试将常规网格数据库导入到3D场景中以进行可视化/模拟。我认为最简单的方法是将常规网格数据库转换为可导入Blender的格式(例如,wavefront .obj)。常规网格数据库具有以下格式: 例如,第一行有三个整数 3072 3072 10 第一行有三个整数,表示网格的尺寸。在上面的示例中,网格为3072 x 3072 x 10个框。假设1米体素立方体

该文件的提醒有六列

3072 3072 10
1437    1437    1   500 314.781433  4.82E-05
1437    1438    1   500 314.781433  4.82E-05
1437    1439    1   500 314.781433  4.82E-05
1437    1440    1   500 314.781433  4.82E-05
1437    1441    1   500 314.781433  4.82E-05
1437    1442    1   500 314.781433  4.82E-05
1437    1443    1   500 314.781433  4.82E-05
1437    1444    1   500 314.781433  4.82E-05 ....

,其中 文件的其余部分由包含六列数据的行组成。前三列表示体素指数(从0开始计数)。第四列表示与单独的材料数据库文件(.mat)中的条目对应的材料ID。第五列表示以开尔文为单位的温度。最后一栏表示浓度,单位为百万分率(ppm)。

为了简化问题,我们假设我们有一种材料(材料ID 500)。如果我可以将其转换为.obj文件格式,那么我可以编写代码来更新其他材料。

有没有人知道除蛮力以外的其他方法?我可以通过生成3D网格,然后单步执行常规网格文件并检查它是否填充了材质属性,然后仍然无法解决将其放入wavefront .obj文件的问题。格式。我很感谢你的忠告。

Sambler提供了一些代码来直接在Blender中生成网格。我无法让它在搅拌机中运行所以我修改了它。此代码在blender中运行,并向控制台生成输出。但是我没有成功地让它在Blender中生成可见网格。任何帮助,将不胜感激。

import bpy, bmesh
import csv
import os
import glob
import pdb; pdb.set_trace()
from pdb import set_trace as bp
from bpy import context
import csv
import os
import glob
import pdb; pdb.set_trace()
from pdb import set_trace as bp

scale_fac = 0.1
bm = bmesh.new()

filename = 'data.csv'

directory = r'c:\\test\\'
fullpath = os.path.join(directory, filename)
d=[]
with open(fullpath, 'r', newline='') as csvfile:
    data = csv.reader(csvfile, delimiter=' ', quoting=csv.QUOTE_NONE)
    count=0
    for d in data:
        #bp()
        for elements in d:
            parts=elements.split(',')
            if count==0:
                grid_x = int(parts[0].strip(""))
                print(grid_x)
                grid_y = int(parts[1])
                print(grid_y)
                grid_z = int(parts[2])
                print(grid_z)
                count+=1
                #print(count)
            else:
                x = int(parts[0])
                y = int(parts[1])
                z = int(parts[2])
                print(x,y,z)    
        continue
        res = bmesh.ops.create_cube(bm,size=scale_fac)
        bmesh.ops.translate(bm, verts=res['verts'],
                vec=(x*scale_fac , y*scale_fac, z*scale_fac))
        for v in res['verts']:
            for f in v.link_faces:
                f.material_index = int(parts[3])
                print(f.material_index)    
obj_data = bpy.data.meshes.new('gridmesh')
gridobj = bpy.data.objects.new('gridobj', obj_data)
bpy.context.scene.objects.link(gridobj)
bm.to_mesh(gridobj.data)
bm.free()
print("Mesh Complete")

1 个答案:

答案 0 :(得分:0)

您可以直接在blender中读取数据并生成网格,而不是手动创建.obj文件。如果要将网格转移到其他位置,则可以将其导出为.obj。

性能方面,搅拌器可以更好地处理一个具有一百万个顶点的对象,而不是一千个具有一千个顶点的对象,因此我建议将网格构建为一个对象。请参阅this answer了解我之前执行的测试。如果你想要多个物体,那么在你完成时用松散的部分分开是很简单的,虽然很费时。

可以为对象中的每个断开的网格片(或每个面)分配不同的材质。请注意,此处指定的材质索引是分配给对象的材质的索引,可在obj.material_slots中找到。有关创建BI材料的简单示例,请参阅this answer

import bpy, bmesh
import csv

scale_fac = 0.1

bm = bmesh.new()
grid_x , grid_y, grid_z = (0,0,0) # grid limits
with open('data.csv') as csvfile:
    data = csv.reader(csvfile, delimiter=' ', quoting=csv.QUOTE_NONE)
    for d in data:
        if len(d) == 3:
            grid_x = int(d[0])
            grid_y = int(d[1])
            grid_z = int(d[2])
            continue
        x = int(d[0])
        y = int(d[1])
        z = int(d[2])
        res = bmesh.ops.create_cube(bm,size=scale_fac)
        bmesh.ops.translate(bm, verts=res['verts'],
                vec=(x*scale_fac , y*scale_fac, z*scale_fac))
        for v in res['verts']:
            for f in v.link_faces:
                f.material_index = int(d[3])

obj_data = bpy.data.meshes.new('gridmesh')
gridobj = bpy.data.objects.new('gridobj', obj_data)
bpy.context.scene.objects.link(gridobj)
bm.to_mesh(gridobj.data)
bm.free()