5
$\begingroup$

I have 24 points which correspond to 12 different "elements" (2 points per element) saved in an .csv file with the following column order (1: Element Name, 2: x, 3: y, 4: z). I would like to import them so that there will be an edge between the two points for every element. Alternatively if this is not possible. It would be great to import all the points as separate elements. So I can know which points correspond to which element by the order of import.

Update:

This is great and I would like to extend this to the first six point: I tried to update your code with the edges I want, but it fails.

What does ensure_lookup_table() do ?

In if row[0] there is only one vert. How can I add more ? The Ideal solution would be select 1,6 or all verts and make a mesh. The order of the edges would be cool to have but if too much hustle. Just importing 1, 6 or all verts and connecting them to a mesh would good.

Here my attempt to updated your code:

import bpy
import bmesh
import csv
from mathutils import Vector
from bpy_extras.object_utils import object_data_add

csvfile = open('path2csvfile')

inFile = csv.reader(csvfile, delimiter=',', quotechar='"')
# skip header
inFile.__next__()

for row in inFile:
    #  column order (0: Element Name, 1: x, 2: y, 3: z)
    if row[0] not in bpy.data.objects:
        vert = [Vector((float(row[1]),float(row[2]),float(row[3])))]
        mesh = bpy.data.meshes.new(name=row[0])
        mesh.from_pydata(vert, [], [])
        object_data_add(bpy.context, mesh)
    else:
        bpy.data.objects[row[0]].select = True
        bpy.context.scene.objects.active = bpy.data.objects[row[0]]
        bpy.ops.object.mode_set(mode='EDIT')
        mesh = bmesh.from_edit_mesh(bpy.data.objects[row[0]].data)
        mesh.verts.new((float(row[1]),float(row[2]),float(row[3])))
        mesh.verts.ensure_lookup_table()
        mesh.edges.new([mesh.verts[0],mesh.verts[1]])
        mesh.edges.new([mesh.verts[1],mesh.verts[2]])
        mesh.edges.new([mesh.verts[2],mesh.verts[3]])
        mesh.edges.new([mesh.verts[1],mesh.verts[4]])
        mesh.edges.new([mesh.verts[4],mesh.verts[5]])
        bmesh.update_edit_mesh(bpy.data.objects[row[0]].data, True)
        bpy.ops.object.mode_set(mode='OBJECT')
$\endgroup$
1

2 Answers 2

5
$\begingroup$

Python includes a csv import module, which makes reading the csv data and using it to create objects rather easy.

As we read through the file, if an object with the name in column1 doesn't exist we create it, if it does exist we add a second vertex and make an edge between the two.

This creates a new object for each element name, you can easily join them together once done by selecting them and pressing ⎈ CtrlJ

import bpy
import bmesh
import csv
from mathutils import Vector
from bpy_extras.object_utils import object_data_add

csvfile = open('/path/to/data.csv')

inFile = csv.reader(csvfile, delimiter=',', quotechar='"')
# skip header
inFile.__next__()

for row in inFile:
    #  column order (0: Element Name, 1: x, 2: y, 3: z)
    if row[0] not in bpy.data.objects:
        vert = [Vector((float(row[1]),float(row[2]),float(row[3])))]
        mesh = bpy.data.meshes.new(name=row[0])
        mesh.from_pydata(vert, [], [])
        object_data_add(bpy.context, mesh)
    else:
        bpy.data.objects[row[0]].select = True
        bpy.context.scene.objects.active = bpy.data.objects[row[0]]
        bpy.ops.object.mode_set(mode='EDIT')
        mesh = bmesh.from_edit_mesh(bpy.data.objects[row[0]].data)
        mesh.verts.new((float(row[1]),float(row[2]),float(row[3])))
        mesh.verts.ensure_lookup_table()
        mesh.edges.new([mesh.verts[0],mesh.verts[1]])
        bmesh.update_edit_mesh(bpy.data.objects[row[0]].data, True)
        bpy.ops.object.mode_set(mode='OBJECT')
$\endgroup$
4
  • $\begingroup$ awesome. this looks promising. will test and let you know. thanks a million for the code. $\endgroup$
    – digit
    Commented Mar 25, 2015 at 7:28
  • $\begingroup$ This is very super super nice. Works like a charm. Exactly what I wanted. Thank you very very much. $\endgroup$
    – digit
    Commented Mar 25, 2015 at 9:25
  • $\begingroup$ Sambler, I wonder is it possible to convert point cloud data into a mesh in Blender? $\endgroup$
    – Amir
    Commented Apr 27, 2018 at 16:12
  • $\begingroup$ @Amir Nothing built-in, have a look at this and this, if you can't get cube surfer to work you would have to build it yourself from the source $\endgroup$
    – sambler
    Commented Apr 30, 2018 at 7:24
2
$\begingroup$

One approach, albeit a bit hacky, would be to create a script to convert your CSV coordinates into OBJ format which you can import.

Consider an OBJ file with the following content.

o Cube
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
l 1 2

It defines and object named "Cube" with two vertices (lines 2 and 3) that are connected by an edge (line 4).

You might opt for something like this..

o ElementOne
v 0.006084 -0.388238 -0.181844
v 0.006084 -0.388239 1.818155
l 1 2
o ElementTwo
v 1.500000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
l 3 4

I might even just write down the OBJ file using a notepad, if this is a one use scenario...

$\endgroup$
1
  • $\begingroup$ I think that it is a good solution because it is blender-independent. $\endgroup$
    – D.J.Duff
    Commented Mar 24, 2015 at 9:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .