You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从规则网格数据库生成Wavefront .obj文件?Blender可视化代码求助

Hey there! Let's break down solutions for your two core issues—efficiently converting your voxel grid to OBJ, and fixing that Blender script to generate visible geometry.


Efficient Voxel Grid to OBJ Conversion (Beyond Brute Force)

Since your grid is regular (fixed-size voxels), you can skip generating every single voxel and focus only on surface geometry—this cuts down on unnecessary polygons drastically, especially for large grids like your 3072×3072×10 example. Here's how to approach it:

  • Surface Voxel Detection: A voxel only needs to be rendered if it has at least one empty neighbor (in x±1, y±1, z±1 directions). For each voxel in your database, check if adjacent positions exist in the data—if not, that face of the voxel is exposed and needs to be added to the mesh.
  • OBJ Optimization: Instead of writing full cubes, generate individual faces for exposed surfaces. OBJ supports reusing vertex coordinates, so you can precompute all unique vertex positions first, then reference them by index in face definitions. For materials, use mtllib to link your .mat file and usemtl to assign material IDs to faces.
  • Face Merging: For contiguous voxels in the same plane (e.g., a column of voxels along the z-axis), merge their exposed faces into a single large rectangle instead of multiple small faces. This is especially useful for your thin z-dimension grid.

Fixing Your Blender Script to Generate Visible Meshes

Your original script had a few key logic and setup issues that prevented mesh rendering. Here's the fixed version with explanations:

import bpy, bmesh
import csv
import os

scale_fac = 0.1
bm = bmesh.new()

# --- 1. Read CSV data (handle BOM header properly) ---
filename = 'data.csv'
directory = r'c:\test\'
fullpath = os.path.join(directory, filename)

voxels = []
grid_x, grid_y, grid_z = 0, 0, 0

# Use utf-8-sig to auto-handle the  BOM header
with open(fullpath, 'r', newline='', encoding='utf-8-sig') as csvfile:
    data = csv.reader(csvfile, delimiter=' ', quoting=csv.QUOTE_NONE)
    count = 0
    for row in data:
        for elements in row:
            parts = elements.split(',')
            if count == 0:
                # Parse grid dimensions
                grid_x = int(parts[0])
                grid_y = int(parts[1])
                grid_z = int(parts[2])
                count += 1
                print(f"Loaded grid: {grid_x}x{grid_y}x{grid_z}")
            else:
                # Store voxel coordinates and material ID
                x = int(parts[0])
                y = int(parts[1])
                z = int(parts[2])
                mat_id = int(parts[3])
                voxels.append( (x, y, z, mat_id) )

# --- 2. Create/load material for voxel ID 500 ---
mat_name = f"Material_500"
if mat_name not in bpy.data.materials:
    mat = bpy.data.materials.new(name=mat_name)
    mat.diffuse_color = (0.7, 0.3, 0.3, 1)  # Red for easy visibility
else:
    mat = bpy.data.materials[mat_name]

# --- 3. Generate cubes for each voxel ---
for x, y, z, mat_id in voxels:
    # Create cube mesh
    cube_res = bmesh.ops.create_cube(bm, size=scale_fac)
    # Translate to voxel position (adjust coordinates if needed for Blender's Z-up space)
    bmesh.ops.translate(bm, verts=cube_res['verts'], vec=(
        x * scale_fac,
        y * scale_fac,
        z * scale_fac
    ))
    # Assign material index (we're using a single material, so index 0)
    for face in cube_res['faces']:
        face.material_index = 0

# --- 4. Convert BMesh to Blender object and link to scene ---
mesh_data = bpy.data.meshes.new('VoxelGrid_Mesh')
voxel_obj = bpy.data.objects.new('VoxelGrid', mesh_data)

# Add material to the object
if not voxel_obj.data.materials:
    voxel_obj.data.materials.append(mat)

# Link object to active collection (Blender 2.8+)
bpy.context.collection.objects.link(voxel_obj)

# Write BMesh data to the object
bm.to_mesh(voxel_obj.data)
bm.free()

print(f"Success! Generated {len(voxels)} visible voxels.")

Key Fixes & Improvements:

  • CSV Reading Logic: Stores all voxel coordinates instead of overwriting x/y/z with the last value, then loops through them to generate cubes.
  • BOM Header Handling: Uses encoding='utf-8-sig' to eliminate the  character without manual stripping.
  • Material Setup: Creates a material and links it to the object before assigning material indices to faces (previously, the object had no materials assigned, so indices were ignored).
  • Scene Linking: Uses Blender 2.8+ collection system (replace with bpy.context.scene.objects.link(voxel_obj) if using older versions).

Bonus Optimization for Large Grids:

For your 3072×3072×10 grid, generating individual cubes will be slow and memory-heavy. Instead, modify the script to generate only exposed faces (as mentioned in the OBJ conversion section) using bmesh.ops.create_grid() for each exposed plane, which will drastically reduce polygon count.


内容的提问来源于stack exchange,提问作者thiirane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:42:25