Commit efe37505 authored by Breno Rilho Lemos's avatar Breno Rilho Lemos 💬

Implement dataDriver

parents f254d36e ccfe2e66
# -*- coding: utf-8 -*-
# particulas.py - Protótipo de animação de partículas
# Para utilizar este script chame o blender com a opção -P e o nome do arquivo
# animate_particles.py - Animate HEP events
#
# For console only rendering:
# $ blender -noaudio --background -P animate_particles.py
......@@ -8,143 +7,53 @@
# TODO: - Implement command line arguments
# - https://blender.stackexchange.com/questions/6817/how-to-pass-command-line-arguments-to-a-blender-python-script
import os
import bpy
bpy.context.user_preferences.view.show_splash = False
import math
import os
import random
# Import Particle class
filename = os.path.join(os.path.basename(bpy.data.filepath), "particle.py")
# Import Drivers, partiles and scence functions:
filename = os.path.join(os.path.basename(bpy.data.filepath), "drivers.py")
exec(compile(open(filename).read(), filename, 'exec'))
t_video=20 # total video duration in seconds
t_simulado=0.01 # tempo em microssegundos ~ tempo para percorrer 3m na velocidade da luz
fps = 24 # frames per second
N_frames=t_video*fps # Total number of frames
delta_t=t_simulado/N_frames # time elapsed per frame
particle_types = ["Electron","Pion","Muon","Proton","Kaon"]
clRed = (1, 0, 0)
clGreen = (0, 1, 0)
clBlue = (0, 0, 1)
clMagenta = (0.75, 0, 1)
clYellow = (1, 1, 0)
particle_colors = {"Electron":clRed, "Pion":clGreen, "Muon":clBlue, "Proton":clMagenta, "Kaon": clYellow}
# Particle radius
r_part = 0.02
# Event Multiplicity
n_particles = 5
# Configure Environment
bcs = bpy.context.scene
bcs.world.light_settings.use_environment_light = False
bcs.world.light_settings.environment_energy = 0.1
# Configure Output
bcsr = bcs.render
bcsr.resolution_percentage = 100
bcsr.image_settings.file_format = 'FFMPEG'
bcsr.ffmpeg.format = "MPEG4"
bcsr.ffmpeg.codec = "H264"
bcsr.ffmpeg.use_max_b_frames = False
bcsr.ffmpeg.video_bitrate = 6000
bcsr.ffmpeg.maxrate = 9000
bcsr.ffmpeg.minrate = 0
bcsr.ffmpeg.buffersize = 224 * 8
bcsr.ffmpeg.packetsize = 2048
bcsr.ffmpeg.muxrate = 10080000
fileidentifier="_Gaussian_rpart0.2_noshadows_"
xpixels = int(bcsr.resolution_percentage * bcsr.resolution_x / 100)
output_prefix="N"+str(n_particles)+fileidentifier+str(xpixels)+"px_"
bcsr.filepath = "/tmp/blender/"+output_prefix
#bcsr.threads_mode = 'FIXED'
#bcsr.threads = 16
# Function that creates Blender Objects from input list of particles.
## Returns a list of blender objects
def create(particles):
bcsr.fps=fps
bcs.frame_start = 0
bcs.frame_end = N_frames
blender_particles=[]
#Create Materials
for type in particle_types:
bpy.data.materials.new(name=type)
#bpy.context.object.active_material = (1, 0, 0)
bpy.data.materials[type].diffuse_color = particle_colors[type]
bpy.data.materials[type].use_shadows = False
bpy.data.materials[type].use_cast_shadows = False
# Create blender spheres (particles)
for particle in particles:
this_type=random.choice(particle_types)
print("Adding Sphere - Particle " + str(len(blender_particles))+" of "+str(n_particles-1)+" - "+this_type)
bpy.ops.mesh.primitive_uv_sphere_add()
bpy.ops.object.shade_smooth()
this_particle = bpy.context.object
this_particle.name = "part"+str(particle.iDx)
this_particle.location=((particle.x,particle.y,particle.z))
this_particle.delta_scale=(r_part,r_part,r_part)
this_particle.data.materials.clear()
this_particle.data.materials.append(bpy.data.materials[this_type])
blender_particles.append(this_particle)
return blender_particles
# Function that animates the scene using the particle propagator class
def animate(objects):
#Animate particles
for f in range(1, N_frames):
t=delta_t*f
bcs.frame_current = f
print("Configuring Frame: "+str(f)+" of "+str(N_frames))
for i in range(0, len(objects)):
bcs.objects.active=objects[i]
objects[i].location=(particles[i].Propagate(t))
objects[i].keyframe_insert(data_path='location')
# Remove cube
bpy.data.objects.remove(bpy.data.objects['Cube'])
camera_forward=bpy.data.objects['Camera']
camera_forward.name = 'ForwardCamera'
camera_forward.location=(0,0,10)
camera_forward.rotation_euler[0] = 0
camera_forward.rotation_euler[2] = 0
bpy.ops.object.camera_add(location=(6, 0, 0), rotation=(0, 1.5708, 0))
#bpy.context.object.rotation_euler[1] = 1.5708
bpy.context.object.name = "BarrelCamera"
# Select scene camera
bpy.context.scene.camera = bpy.data.objects["ForwardCamera"]
# Create particles
particles = createNparticlesPropGaussian(n_particles)
# Create blender objects
blender_particles = create(particles)
#Animate Scene
animate(blender_particles)
bpy.context.scene.frame_current = 20
## Todo:
## - Add option to keep particle trails
## - Add simple geometry of the ALICE detector
# Set animation parameters
r_part = 0.05 # Particle radius
simulated_t = 0.015
duration = 15
fps = 24
resolution_percent = 100
#configure output
outputPath = "/tmp/blender/"
fileIdentifier = "PhysicalTrajectories_"
## RenderCameras: ["ForwardCamera", "OverviewCamera", "BarrelCamera"]
renderCamera="ForwardCamera"
renderAnimation = True # True
saveBlenderFile = False # False
"""
# Create and configure animation driver
n_particles = 100 # Event Multiplicity
driver = genDriver("GaussianGenerator",n_particles,3.0) # Simple genDriver takes two parameters: number of particles and Gaussian width
driver.configure(renderCamera, duration, fps, simulated_t, outputPath, fileIdentifier, resolution_percent)
"""
# Create and configure animation driver
driver = dataDriver("AlirootFileGenerator","esd-detail.dat") # Simple dataDriver takes one parameters: filename
driver.configure(renderCamera, duration, fps, simulated_t, outputPath, fileIdentifier, resolution_percent)
### Build scene
init() # Cleanup, addCameras, addALICE_TPC
particles = driver.getParticles()
blender_particles = createSceneParticles(particles) # Create blender objects - one sphere per particle
#Animate scene using driver
animate(blender_particles,particles,driver)
bpy.context.scene.frame_current = 24
## Save blender file
#bpy.ops.wm.save_as_mainfile(filepath="/tmp/N"+str(n_particles)+fileidentifier+".blend")
if saveBlenderFile: bpy.ops.wm.save_as_mainfile(filepath=outputPath+fileIdentifier+".blend")
# Render animation
bpy.ops.render.render(animation=True)
if renderAnimation: driver.render()
#exit()
# -*- coding: utf-8 -*-
# Import Particle class
filename = os.path.join(os.path.basename(bpy.data.filepath), "particle.py")
exec(compile(open(filename).read(), filename, 'exec'))
# Import scene functions
filename = os.path.join(os.path.basename(bpy.data.filepath), "scene_functions.py")
exec(compile(open(filename).read(), filename, 'exec'))
class animationDriver:
def __init__(self,name):
self.name = name
def configure(self, renderCamera, duration, fps, simulated_t, outputPath, fileIdentifier, resolution_percent=100):
self.renderCamera=renderCamera
self.duration=duration # total video duration in seconds
self.fps=fps
self.simulated_t=simulated_t # total simulated time in microseconds. (0.01 -> light travels ~ 3 m)
self.N_frames=duration*fps
self.delta_t=self.simulated_t/self.N_frames # time elapsed per frame
self.outputPath = outputPath
self.fileIdentifier = fileIdentifier
self.resolution_percent = resolution_percent
self.configureOutput()
bcs = bpy.context.scene
bcs.frame_start = 0
bcs.frame_end = self.N_frames
def render(self):
bpy.context.scene.camera = bpy.data.objects[self.renderCamera]
bpy.ops.render.render(animation=True)
def configureOutput(self):
# Configure Output
bcsr = bpy.context.scene.render
bcsr.fps=self.fps
bcsr.resolution_percentage = self.resolution_percent
bcsr.image_settings.file_format = 'FFMPEG'
bcsr.ffmpeg.format = "MPEG4"
bcsr.ffmpeg.codec = "H264"
bcsr.ffmpeg.use_max_b_frames = False
bcsr.ffmpeg.video_bitrate = 6000
bcsr.ffmpeg.maxrate = 9000
bcsr.ffmpeg.minrate = 0
bcsr.ffmpeg.buffersize = 224 * 8
bcsr.ffmpeg.packetsize = 2048
bcsr.ffmpeg.muxrate = 10080000
xpixels = int(bcsr.resolution_percentage * bcsr.resolution_x / 100)
output_prefix=fileIdentifier+str(xpixels)+"px_"+self.name
bcsr.filepath = "/tmp/blender/"+output_prefix
class genDriver(animationDriver): # A driver for particle generators
def __init__(self,name,N_particles, par1):
self.name = name+"_N"+str(n_particles)+"_"
self.N_particles = N_particles
self.par1 = par1
def getParticles(self, x = 0, y = 0, z = 0): # Create particles at given position and return them in a list
particles=[]
#loop over particles
for i in range(0, self.N_particles):
charge = random.choice([+1,-1])
part = ParticlePropagator(i,x,y,z,charge)
part.SetMagneticField()
part.SetProperties(random.gauss(0,self.par1),random.gauss(0,self.par1),random.gauss(0,self.par1))
particles.append(part)
return particles;
class dataDriver(animationDriver): # A driver for data from files.
def __init__(self,name,filename):
self.name = name+"_"+filename+"_"
def getParticles(self): # Create particles acording to parameters from file
# Count number of lines in file = number of particles
detail_file = open(filename, 'r')
linecount = 0
for line in open(filename).readlines( ): linecount += 1 # File must be in the same directory
# Set number of particles
N_particles = linecount
particles=[]
lines = detail_file.readlines()
#loop over particles and get information from data file
for i in range(0, N_particles):
x = lines[i].split(' ')[0]
y = lines[i].split(' ')[1]
z = lines[i].split(' ')[2]
mass = lines[i].split(' ')[3]
charge = lines[i].split(' ')[4]
Px = lines[i].split(' ')[5]
Py = lines[i].split(' ')[6]
Pz = lines[i].split(' ')[7]
part = ParticlePropagator(i,x,y,z,charge,mass)
part.SetMagneticField()
part.SetProperties(Px,Py,Pz)
particles.append(part)
detail_file.close()
return particles;
......@@ -17,14 +17,6 @@ class Particle:
def GetPosition(self):
return self.x, self.y, self.z
#Function that creates N particles and return them in a list
def createNparticles(N_particles, x = 0, y = 0, z = 0): # Create particles at given position and return them in a list
particles=[]
#loop over particles
for i in range(0, N_particles):
part = Particle(i,x,y,z)
particles.append(part)
return particles;
# Derived class to computes the time evolution particle positions
class ParticlePropagator(Particle):
......@@ -45,15 +37,3 @@ class ParticlePropagator(Particle):
Yprop = self.y + Ry * math.sin(omega*time) + Rx * ( math.cos(omega*time) - 1 )
Zprop = self.z + self.Vz * time
return Xprop, Yprop, Zprop
# Function that creates N particle propagators
# Momentum values to be obtained from real data
def createNparticlesPropGaussian(N_particles, x = 0, y = 0, z = 0): # Create particles at given position and return them in a list
particles=[]
#loop over particles
for i in range(0, N_particles):
part = ParticlePropagator(i,x,y,z)
part.SetMagneticField()
part.SetProperties(random.gauss(0,1),random.gauss(0,1),random.gauss(0,1))
particles.append(part)
return particles;
# -*- coding: utf-8 -*-
from particle import *
# Creates one particle propagator with default values
a = ParticlePropagator(0)
a.PrintPosition()
# Configure kinematics
a.SetMagneticField(0.5)
a.SetMomentum(-1.0, 2.0, 3.0)
#Print propagation
print(a.Propagate(1))
print(a.Propagate(2))
print(a.Propagate(3))
print(a.Propagate(3)[0]*2) #Acessing a single element of the result
def init():
bcs = bpy.context.scene
# Configure Environment
bcs.world.light_settings.use_environment_light = False
bcs.world.light_settings.environment_energy = 0.1
# Cleanup
bpy.data.objects.remove(bpy.data.objects['Cube'])
bpy.data.objects.remove(bpy.data.objects['Camera'])
# Basic Objects
addCameras() # Add cameras
addALICE_TPC() # ALICE TPC
def addALICE_TPC():
print("Adding ALICE TPC")
bpy.data.materials.new(name="TPC")
bpy.data.materials["TPC"].diffuse_color = (0, 0.635632, 0.8)
bpy.data.materials["TPC"].use_shadows = False
bpy.data.materials["TPC"].use_cast_shadows = False
bpy.data.materials["TPC"].use_transparency = True
bpy.data.materials["TPC"].alpha = 1
bpy.data.materials["TPC"].specular_alpha = 0
bpy.data.materials["TPC"].raytrace_transparency.fresnel_factor = 5
bpy.data.materials["TPC"].raytrace_transparency.fresnel = 0.3
bpy.ops.mesh.primitive_cylinder_add(radius=2.5, depth=5, view_align=False, enter_editmode=False, location=(0, 0, 0))
TPC = bpy.context.object
TPC.name = "TPC"
TPC.data.materials.clear()
TPC.data.materials.append(bpy.data.materials["TPC"])
def addCameras():
# ForwardCamera
bpy.ops.object.camera_add(location = (0,0,20), rotation = (0, 0, 0))
bpy.context.object.name = "ForwardCamera"
camera_forward=bpy.data.objects['ForwardCamera']
camera_forward.data.type = 'ORTHO'
camera_forward.data.ortho_scale = 10
# OverviewCamera
bpy.ops.object.camera_add(location = (6.98591, -19.7115, 23.9696), rotation = (-0.281366, 0.683857, -1.65684))
bpy.context.object.name = "OverviewCamera"
bpy.context.object.data.lens = 66.78
# Barrel Camera
bpy.ops.object.camera_add(location = (6, 0, 0), rotation = (0, 1.5708, 0))
#bpy.context.object.rotation_euler[1] = 1.5708
bpy.context.object.name = "BarrelCamera"
# Function that creates Blender Objects from input list of particles.
## Returns a list of blender objects
def createSceneParticles(particles):
# Associate particles and colors
particle_types = ["Electron","Pion","Muon","Proton","Kaon"]
clRed = (1, 0, 0)
clGreen = (0, 1, 0)
clBlue = (0, 0, 1)
clMagenta = (0.75, 0, 1)
clYellow = (1, 1, 0)
particle_colors = {"Electron":clRed, "Pion":clGreen, "Muon":clBlue, "Proton":clMagenta, "Kaon": clYellow}
#Create Materials
for type in particle_types:
bpy.data.materials.new(name=type)
#bpy.context.object.active_material = (1, 0, 0)
bpy.data.materials[type].diffuse_color = particle_colors[type]
bpy.data.materials[type].use_shadows = False
bpy.data.materials[type].use_cast_shadows = False
# Create blender spheres (particles)
blender_particles=[]
for particle in particles:
this_type=random.choice(particle_types) #TO DO: make this not random, but according to file data
print("Adding Sphere - Particle " + str(len(blender_particles))+" of "+str(n_particles-1)+" - "+this_type)
bpy.ops.mesh.primitive_uv_sphere_add()
this_particle = bpy.context.object
this_particle.name = "part"+str(particle.iDx)
this_particle.location = ((particle.x,particle.y,particle.z))
this_particle.delta_scale = (r_part,r_part,r_part)
this_particle.data.materials.clear()
this_particle.data.materials.append(bpy.data.materials[this_type])
blender_particles.append(this_particle)
return blender_particles
# Function that animates the scene using the particle propagator class
def animate(objects, particles, driver):
bcs = bpy.context.scene
#Animate particles
for f in range(1, bcs.frame_end):
t = driver.delta_t*f
bcs.frame_current = f
print("Configuring Frame: "+str(f)+" of "+str(bcs.frame_end))
for i in range(0, len(objects)):
bcs.objects.active=objects[i]
objects[i].location=(particles[i].Propagate(t))
objects[i].keyframe_insert(data_path='location')
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment