0

So, I'm pretty new with Blender and and trying to set up an N-body simulation for which I wrote a Python file, but it doesn't seem to do anything:

import bpy
import bmesh
import csv

file = "test.txt"

data_file = open(file, "w+")
data = data_file.readlines()
data_file.close()


for row in data[:500]:
    bpy.ops.object.mode_set(mode = 'EDIT')

    bpy.context.scene.frame_set(framecounts)

    obj = bpy.data.objects['Material.001']
    mesh = obj.data
    bm = bmesh.from_edit_mesh(obj.data)

    try:
        bm.verts[0].co.x = row[0] * 10000
        bm.verts[0].co.y = row[1] * 10000
        bm.verts[0].co.z = row[2] * 10000
        bm.verts[1].co.x = row[3] * 10000
        bm.verts[1].co.y = row[4] * 10000
        bm.verts[1].co.z = row[5] * 10000
        bm.verts[2].co.x = row[6] * 10000
        bm.verts[2].co.y = row[7] * 10000
        bm.verts[2].co.z = row[8] * 10000

        bm.update_edit_mesh(obj.data)

    except:
        pass

    bpy.ops.anim.keyframe_insert(type="Location")

I know the the iteration can be better, but it's just an example for N=3. The text files are like these:

x1 y1 z1 x2 y2 z2 x3 y3 z3...
...

So each line is a separate time step and contains the coordinates per particle. Can someone revise this code? I have a feeling it has to do with the

bm.verts[i]

For the actual simulation I should just try and make a small sphere for each vertex I suppose? Remember that I'm new at this.

Thank you for your time!

EDIT: after some digging and searching around, I now have the following file:

import bpy
import bmesh
import numpy as np

N = 3
r = 0.2
scale = 10 ** 11

file = '/home/julian/Documents/test.txt'

data = np.loadtxt(file)

bpy.ops.object.select_all(action='DESELECT')
bpy.ops.mesh.primitive_uv_sphere_add(radius=r)
sphere = bpy.context.object

def makeSphere(x,y,z):
    ob = sphere.copy()
    ob.location.x = x
    ob.location.y = y
    ob.location.z = z

    bpy.context.collection.objects.link(ob)

for row in data:
    for i in range(0, N):
        x = row[3*i]
        y = row[3*i+1]
        z = row[3*i+2]
        makeSphere(scale * x, scale * y, scale * z)

    bpy.context.view_layer.update()

fullpath = '/home/julian/Documents/finalObject.obj'

print("Exporting OBJ");

bpy.ops.export_scene.obj(filepath=fullpath)

It correctly creates spheres according to the position, but they all seem to coincide with the origin. What I don't have is the following: It should also delete in the for-loop which loops over the timesteps (row) the existing spheres and thus create new ones so that if 'played' it seems like the spheres are following a trajectory.

Guliano
  • 101
  • 1
  • 1
    You're doing a lot of strange things in your script, I'm not sure what parts are intentional. Why is your object named "Material"? Are you aware that you are attempting to move the vertices of a single object? Adding keyframe for the location isn't the right tool when you want to animate the vertex position. The current frame, for which the keyframe is added, isn't update. Therefore each keyframe_insert() overwrites the previous one. I'd suggest you add N sphere objects instead, then in a loop adjust the location, insert a keyframe for each object and update the current frame. – Robert Gützkow Nov 23 '19 at 22:17
  • 1
    I think you might be killing your data in the file before it is being read. Have a look at https://stackoverflow.com/a/23566951/808940. You should probably be using r mode instead. Because there is no data to be read, the loop is never executed. – Moog Nov 24 '19 at 01:48
  • Lose the try clause and put in some print statements to debug, (whilst learning) The output of print(row[0] * 10000) may not be what you are expecting. There is no need to do this with edit mode bmesh. Possibly related https://blender.stackexchange.com/questions/36902/how-to-keyframe-mesh-vertices-in-python – batFINGER Nov 24 '19 at 02:01
  • Thank you for the info! My script is mostly based on 3"D Scientific Visualization with Blender" - Brian R. Kent But since halo objects don't seem to exist anymore in Blender 2.81 I had to try something else. It actually would be weird if 'w+' doesn't work for just reading, because the file exists and I'm not writing anything. But I'll give it a try! – Guliano Nov 24 '19 at 12:45

0 Answers0