animate_particles.py 4.56 KB
Newer Older
Rafael Pezzi's avatar
Rafael Pezzi committed
1
2
3
4
# -*- 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
#
5
6
7
8
9
#   For console only rendering:
#   $ blender -noaudio --background -P animate_particles.py
#
# TODO: - Implement command line arguments
#         - https://blender.stackexchange.com/questions/6817/how-to-pass-command-line-arguments-to-a-blender-python-script
Rafael Pezzi's avatar
Rafael Pezzi committed
10
11
12
13
14
15

import bpy
bpy.context.user_preferences.view.show_splash = False

import math
import os
16
import random
Rafael Pezzi's avatar
Rafael Pezzi committed
17
18
19
20
21

# Import Particle class
filename = os.path.join(os.path.basename(bpy.data.filepath), "particle.py")
exec(compile(open(filename).read(), filename, 'exec'))

22
23
24
25
26
27
28
29
30
31
32
33
34
t_video=10 # 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}
Rafael Pezzi's avatar
Rafael Pezzi committed
35
36

# Particle radius
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
r_part = 0.05

# Event Multiplicity
n_particles = 10

# 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 = 50
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="N"+str(n_particles)+"_Gaussian_"+str(xpixels)+"px_"
bcsr.filepath = "/tmp/blender/"+output_prefix
#bcsr.threads_mode = 'FIXED'
#bcsr.threads = 16

Rafael Pezzi's avatar
Rafael Pezzi committed
68

69
70
# Function that creates Blender Objects from input list of particles.
## Returns a list of blender objects
Rafael Pezzi's avatar
Rafael Pezzi committed
71
def create(particles):
72
73
74
    bcsr.fps=fps
    bcs.frame_start = 0
    bcs.frame_end = N_frames
Rafael Pezzi's avatar
Rafael Pezzi committed
75
    blender_particles=[]
76
77
78
79
80
81
82

    #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]

Rafael Pezzi's avatar
Rafael Pezzi committed
83
84
    # Create blender spheres (particles)
    for particle in particles:
85
86
        this_type=random.choice(particle_types)
        print("Adding Sphere - Particle " + str(len(blender_particles))+" of "+str(n_particles-1)+" - "+this_type)
Rafael Pezzi's avatar
Rafael Pezzi committed
87
88
89
90
91
        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)
92
93
        this_particle.data.materials.clear()
        this_particle.data.materials.append(bpy.data.materials[this_type])
Rafael Pezzi's avatar
Rafael Pezzi committed
94
95
96
        blender_particles.append(this_particle)
    return blender_particles

97
# Function that animates the scene using the particle propagator class
Rafael Pezzi's avatar
Rafael Pezzi committed
98
99
def animate(objects):
    #Animate particles
100
    for f in range(1, N_frames):
Rafael Pezzi's avatar
Rafael Pezzi committed
101
        t=delta_t*f
102
103
        bcs.frame_current = f
        print("Configuring Frame: "+str(f)+" of "+str(N_frames))
Rafael Pezzi's avatar
Rafael Pezzi committed
104
        for i in range(0, len(objects)):
105
            bcs.objects.active=objects[i]
106
            objects[i].location=(particles[i].Propagate(t))
Rafael Pezzi's avatar
Rafael Pezzi committed
107
108
109
            objects[i].keyframe_insert(data_path='location')


110
# Remove cube
Rafael Pezzi's avatar
Rafael Pezzi committed
111
112
bpy.data.objects.remove(bpy.data.objects['Cube'])

113
114
115
116
117
118
119
120
121
122
123
124
125
camera_forward=bpy.data.objects['Camera']
camera_forward.name = 'ForwardCamera'
camera_forward.location=(0,0,6)
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"]

Rafael Pezzi's avatar
Rafael Pezzi committed
126
# Create particles
127
particles = createNparticlesPropGaussian(n_particles)
Rafael Pezzi's avatar
Rafael Pezzi committed
128
129
130
131
132
133

# Create blender objects
blender_particles = create(particles)

#Animate Scene
animate(blender_particles)
134
bpy.context.scene.frame_current = 20
135
136
137
138

## Todo:
##  - Add option to keep particle trails
##  - Add simple geometry of the ALICE detector
139
140
141
142
143
144
145
146

## Save blender file
#bpy.ops.wm.save_as_mainfile(filepath="/home/pezzi/particles_"+str(n_particles)+".blend")

# Render animation
bpy.ops.render.render(animation=True)

#exit()