Skip to content

Instantly share code, notes, and snippets.

@knowuh
Created April 12, 2023 13:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save knowuh/d4846372e7123a0302e4b533663c7c69 to your computer and use it in GitHub Desktop.
Save knowuh/d4846372e7123a0302e4b533663c7c69 to your computer and use it in GitHub Desktop.
Import a CSV file to a new mesh. All the vertices will be at 0,0,0. Use GeoNodes to map attributes.
bl_info = {
"name": "CSV Mesh Importer",
"author": "Noah and GTP4 :D",
"version": (1, 0),
"blender": (3, 5, 0),
"location": "View3D > Tool Shelf > CSV Mesh Importer",
"description": "Import a mesh from a CSV file",
"category": "Import-Export",
}
import bpy
import csv
from bpy.props import StringProperty, PointerProperty
from bpy.types import Operator, Panel, PropertyGroup
def log(msg):
print(msg)
class CSVVertexProperties(PropertyGroup):
pass # Properties will be dynamically added based on CSV headers
class ImportCSV(Operator):
bl_idname = "import_mesh.csv"
bl_label = "Import CSV"
filepath: StringProperty(subtype="FILE_PATH")
def execute(self, context):
with open(self.filepath, "r") as csvfile:
reader = csv.DictReader(csvfile)
mesh_data = bpy.data.meshes.new("CSV_Mesh")
mesh_obj = bpy.data.objects.new("CSV_Mesh", mesh_data)
context.collection.objects.link(mesh_obj)
context.view_layer.objects.active = mesh_obj
mesh_obj.select_set(True)
attributes = {}
vertices = []
for row in reader:
vertex = tuple([0,0,0])
vertices.append(vertex)
print(row)
for name in row.keys():
print(name)
try:
attributes.setdefault(name, []).append(float(row[name]))
except ValueError:
# Skip any rows that cannot be converted to floats (e.g., header row)
attributes.setdefault(name, []).append(-1.0)
mesh_data.from_pydata(vertices, [], [])
mesh_data.update()
for name in attributes.keys():
mesh_data.attributes.new(name=name, type="FLOAT", domain="POINT")
for name in attributes.keys():
print(name)
mesh_data.attributes[name].data.foreach_set("value", attributes[name])
mesh_data.update()
for i, row in enumerate(reader):
for j, value in enumerate(row):
prop_name = headers[j]
try:
mesh_obj.data.vertices[i][prop_name] = float(value)
except ValueError:
mesh_obj.data.vertices[i][prop_name] = -1.0
return {"FINISHED"}
class ImportCSVFileSelector(Operator):
bl_idname = "import_mesh.csv_file_selector"
bl_label = "Select CSV File"
filepath: StringProperty(subtype="FILE_PATH")
def invoke(self, context, event):
context.window_manager.fileselect_add(self)
return {"RUNNING_MODAL"}
def execute(self, context):
bpy.ops.import_mesh.csv(filepath=self.filepath)
return {"FINISHED"}
class ImportCSVPanel(Panel):
bl_label = "CSV Mesh Importer"
bl_idname = "IMPORT_PT_CSV"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_category = "CSV Mesh Importer"
def draw(self, context):
layout = self.layout
layout.operator("import_mesh.csv_file_selector", text="Import CSV")
def menu_func_import(self, context):
self.layout.operator(ImportCSV.bl_idname, text="CSV Mesh Import (.csv)")
def register():
bpy.utils.register_class(CSVVertexProperties)
bpy.utils.register_class(ImportCSV)
bpy.utils.register_class(ImportCSVFileSelector)
bpy.utils.register_class(ImportCSVPanel)
bpy.types.TOPBAR_MT_file_import.append(menu_func_import)
def unregister():
bpy.utils.unregister_class(CSVVertexProperties)
bpy.utils.unregister_class(ImportCSV)
bpy.utils.unregister_class(ImportCSVFileSelector)
bpy.utils.unregister_class(ImportCSVPanel)
bpy.types.TOPBAR_MT_file_import.remove(menu_func_import)
if __name__ == "__main__":
register()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment