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.
keyframe_insert()overwrites the previous one. I'd suggest you add N sphere objects instead, then in a loop adjust thelocation, insert a keyframe for each object and update the current frame. – Robert Gützkow Nov 23 '19 at 22:17tryclause and put in some print statements to debug, (whilst learning) The output ofprint(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