Utility_Apps/Blender/simple scripts/CSV Terrain Import for Blender/Script 1.py
Ryan Schultz 9330cc2c77 The following scripts import survey-style CSV point data into Blender and generates a triangulated 3D terrain surface.
-   Reads CSV files containing `x, y, z, label`
-   Converts coordinates from feet to the current Blender scene units
-   Offsets large world coordinates near the origin for precision
-   Corrects axis orientation (Y flip + proper Z alignment)
-   Creates labeled empties for each survey point
-   Optionally filters out unwanted point types (e.g. buildings or utilities)
-   Generates a Delaunay-triangulated 3D mesh surface from the remaining points

The result is a clean, unit-accurate terrain mesh built directly from raw survey data inside Blender.
2026-02-23 16:56:03 -06:00

59 lines
No EOL
1.7 KiB
Python

import bpy
import csv
# Path to your CSV file
csv_path = r"D:\Dropbox\Gitea_OD\Utility_Apps\Blender\simple scripts\CSV Terrain Import for Blender\example.csv" # change this
# Name for the collection
collection_name = "CSV_Points"
# CSV units: feet
CSV_UNIT_TO_METERS = 0.3048
# Get Blender unit scale
scene = bpy.context.scene
unit_scale = scene.unit_settings.scale_length # e.g., 1.0 for meters, 0.3048 for feet
# Combined scale to convert CSV feet to Blender units
scale = CSV_UNIT_TO_METERS / unit_scale
# Create collection (or get it if it exists)
if collection_name in bpy.data.collections:
col = bpy.data.collections[collection_name]
else:
col = bpy.data.collections.new(collection_name)
bpy.context.scene.collection.children.link(col)
# Read CSV and collect data
points_data = []
xs, ys, zs = [], [], []
with open(csv_path, newline='') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
x = float(row['x'])
y = float(row['y'])
z = float(row['z'])
label = row['label']
points_data.append((x, y, z, label))
xs.append(x)
ys.append(y)
zs.append(z)
# Compute offsets to bring mesh near origin
x_offset = min(xs)
y_offset = min(ys)
z_min = min(zs)
# Create empties
for x, y, z, label in points_data:
x_adj = (x - x_offset) * scale
y_adj = -(y - y_offset) * scale # flip Y
z_adj = (z - z_min) * scale
empty = bpy.data.objects.new(label, None)
empty.location = (x_adj, y_adj, z_adj)
col.objects.link(empty)
print(f"Created {len(points_data)} empties in collection '{collection_name}'")
print(f"Offsets: X -= {x_offset}, Y flipped & offset -= {y_offset}, Z -= {z_min}")
print(f"Applied scale to convert CSV feet to Blender units: {scale}")