animate_particles.py 5.36 KB
Newer Older
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
10 11 12 13 14 15

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

import math
import os
16
import random
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
t_video=15 # total video duration in seconds
t_simulado=0.015 # tempo em microssegundos ~ tempo para percorrer 3m na velocidade da luz
24 25 26 27 28 29 30 31 32 33 34
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}
35 36

# Particle radius
37 38 39
r_part = 0.05

# Event Multiplicity
40
n_particles = 200
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

# 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

68

69 70
# Function that creates Blender Objects from input list of particles.
## Returns a list of blender objects
71
def create(particles):
72 73 74
    bcsr.fps=fps
    bcs.frame_start = 0
    bcs.frame_end = N_frames
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]

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)
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])
94 95 96
        blender_particles.append(this_particle)
    return blender_particles

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


110
# Remove cube
111 112
bpy.data.objects.remove(bpy.data.objects['Cube'])

113 114
camera_forward=bpy.data.objects['Camera']
camera_forward.name = 'ForwardCamera'
115
camera_forward.location=(0,0,20)
116 117
camera_forward.rotation_euler[0] = 0
camera_forward.rotation_euler[2] = 0
118 119 120 121
camera_forward.data.type = 'ORTHO'
camera_forward.data.ortho_scale = 10


122 123 124 125 126 127 128 129

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

130
# Create particles
131
particles = createNparticlesPropGaussian(n_particles)
132 133 134 135

# Create blender objects
blender_particles = create(particles)

136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
# ALICE 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"])



157 158
#Animate Scene
animate(blender_particles)
159
bpy.context.scene.frame_current = 20
160 161 162 163

## Todo:
##  - Add option to keep particle trails
##  - Add simple geometry of the ALICE detector
164 165 166 167 168

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

# Render animation
169
#bpy.ops.render.render(animation=True)
170 171

#exit()