PyParticles3 0.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyparticles/__init__.py +26 -0
- pyparticles/__main__.py +7 -0
- pyparticles/animation/__init__.py +21 -0
- pyparticles/animation/animated_cli.py +53 -0
- pyparticles/animation/animated_ogl.py +691 -0
- pyparticles/animation/animated_ogl_compat.py +243 -0
- pyparticles/animation/animated_scatter.py +94 -0
- pyparticles/animation/animation.py +251 -0
- pyparticles/animation/test_animation.py +310 -0
- pyparticles/demo/__init__.py +33 -0
- pyparticles/demo/bubble.py +106 -0
- pyparticles/demo/electromagnetic_demo.py +128 -0
- pyparticles/demo/electrostatic_demo.py +126 -0
- pyparticles/demo/fountain.py +478 -0
- pyparticles/demo/gas_lennard_jones.py +87 -0
- pyparticles/demo/gravity_clusters.py +73 -0
- pyparticles/demo/solar_system.py +222 -0
- pyparticles/demo/springs.py +141 -0
- pyparticles/demo/springs_constr.py +135 -0
- pyparticles/demo/test.py +34 -0
- pyparticles/forces/__init__.py +21 -0
- pyparticles/forces/const_force.py +140 -0
- pyparticles/forces/damping.py +174 -0
- pyparticles/forces/drag.py +167 -0
- pyparticles/forces/electromagnetic.py +105 -0
- pyparticles/forces/electromagnetic_field.py +95 -0
- pyparticles/forces/electrostatic.py +72 -0
- pyparticles/forces/force.py +75 -0
- pyparticles/forces/force_constrained.py +32 -0
- pyparticles/forces/fused_const_drag.py +445 -0
- pyparticles/forces/gravity.py +345 -0
- pyparticles/forces/lennard_jones.py +74 -0
- pyparticles/forces/linear_spring.py +86 -0
- pyparticles/forces/linear_spring_constrained.py +72 -0
- pyparticles/forces/multiple_force.py +134 -0
- pyparticles/forces/pseudo_bubble.py +226 -0
- pyparticles/forces/van_der_waals_force.py +60 -0
- pyparticles/forces/vector_field_force.py +52 -0
- pyparticles/geometry/__init__.py +21 -0
- pyparticles/geometry/dist.py +24 -0
- pyparticles/geometry/intersection.py +62 -0
- pyparticles/geometry/transformations.py +387 -0
- pyparticles/main/__init__.py +21 -0
- pyparticles/main/main.py +466 -0
- pyparticles/measures/__init__.py +21 -0
- pyparticles/measures/elastic_potential_energy.py +67 -0
- pyparticles/measures/gravitational_potential_energy.py +69 -0
- pyparticles/measures/kinetic_energy.py +68 -0
- pyparticles/measures/mass.py +59 -0
- pyparticles/measures/measure.py +156 -0
- pyparticles/measures/momentum.py +144 -0
- pyparticles/measures/total_energy.py +68 -0
- pyparticles/ode/__init__.py +21 -0
- pyparticles/ode/euler_solver.py +214 -0
- pyparticles/ode/euler_solver_constrained.py +49 -0
- pyparticles/ode/leapfrog_solver.py +37 -0
- pyparticles/ode/leapfrog_solver_constrained.py +53 -0
- pyparticles/ode/midpoint_solver.py +43 -0
- pyparticles/ode/midpoint_solver_constrained.py +60 -0
- pyparticles/ode/ode_solver.py +134 -0
- pyparticles/ode/ode_solver_constrained.py +43 -0
- pyparticles/ode/runge_kutta_solver.py +79 -0
- pyparticles/ode/runge_kutta_solver_constrained.py +98 -0
- pyparticles/ode/sim_time.py +56 -0
- pyparticles/ode/stormer_verlet_solver.py +50 -0
- pyparticles/ode/stormer_verlet_solver_constrained.py +73 -0
- pyparticles/ogl/__init__.py +21 -0
- pyparticles/ogl/axis_ogl.py +210 -0
- pyparticles/ogl/draw_particles_ogl.py +313 -0
- pyparticles/ogl/draw_particles_ogl_compat.py +509 -0
- pyparticles/ogl/draw_vector_field.py +221 -0
- pyparticles/ogl/opencl_gl_vbo.py +485 -0
- pyparticles/ogl/trackball.py +131 -0
- pyparticles/ogl/translate_scene.py +87 -0
- pyparticles/pset/__init__.py +21 -0
- pyparticles/pset/boundary.py +69 -0
- pyparticles/pset/cluster.py +28 -0
- pyparticles/pset/constrained_force_interactions.py +63 -0
- pyparticles/pset/constrained_x.py +158 -0
- pyparticles/pset/constraint.py +42 -0
- pyparticles/pset/default_boundary.py +43 -0
- pyparticles/pset/file_cluster.py +131 -0
- pyparticles/pset/logger.py +152 -0
- pyparticles/pset/octree.py +451 -0
- pyparticles/pset/opencl_context.py +374 -0
- pyparticles/pset/particles_set.py +499 -0
- pyparticles/pset/periodic_boundary.py +36 -0
- pyparticles/pset/rand_cluster.py +188 -0
- pyparticles/pset/rebound_boundary.py +68 -0
- pyparticles/utils/__init__.py +21 -0
- pyparticles/utils/parse_args.py +72 -0
- pyparticles/utils/problem_config.py +608 -0
- pyparticles/utils/pypart_global.py +122 -0
- pyparticles/utils/time_formatter.py +50 -0
- pyparticles3-0.4.0.dist-info/METADATA +395 -0
- pyparticles3-0.4.0.dist-info/RECORD +100 -0
- pyparticles3-0.4.0.dist-info/WHEEL +5 -0
- pyparticles3-0.4.0.dist-info/entry_points.txt +3 -0
- pyparticles3-0.4.0.dist-info/licenses/LICENSE-gpl-3.0.txt +674 -0
- pyparticles3-0.4.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,691 @@
|
|
|
1
|
+
# PyParticles : Particles simulation in python
|
|
2
|
+
# Copyright (C) 2012 Simone Riva
|
|
3
|
+
#
|
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
7
|
+
# (at your option) any later version.
|
|
8
|
+
#
|
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
# GNU General Public License for more details.
|
|
13
|
+
#
|
|
14
|
+
# You should have received a copy of the GNU General Public License
|
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
import pyparticles.animation.animation as pan
|
|
20
|
+
|
|
21
|
+
import numpy as np
|
|
22
|
+
import sys
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
import pyparticles.ogl.trackball as trk
|
|
26
|
+
import pyparticles.ogl.axis_ogl as axgl
|
|
27
|
+
import pyparticles.ogl.translate_scene as tran
|
|
28
|
+
import pyparticles.ogl.draw_vector_field as dvf
|
|
29
|
+
import pyparticles.utils.time_formatter as tf
|
|
30
|
+
import pyparticles.ogl.draw_particles_ogl as drp
|
|
31
|
+
|
|
32
|
+
from OpenGL.GL import *
|
|
33
|
+
from OpenGL.GLUT import *
|
|
34
|
+
from OpenGL.GLU import *
|
|
35
|
+
|
|
36
|
+
if sys.platform.startswith("win") :
|
|
37
|
+
from OpenGL.WGL import *
|
|
38
|
+
|
|
39
|
+
if sys.platform.startswith("linux") :
|
|
40
|
+
from OpenGL.GLX import *
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def InitGL( Width , Height , ReSizeFun ):
|
|
44
|
+
"""
|
|
45
|
+
Initialize OpenGl
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
glClearColor(0.0, 0.0, 0.0, 0.0)
|
|
49
|
+
glClearDepth(1.0)
|
|
50
|
+
glDepthFunc(GL_LESS)
|
|
51
|
+
glEnable(GL_DEPTH_TEST)
|
|
52
|
+
glShadeModel(GL_SMOOTH)
|
|
53
|
+
glEnable(GL_TEXTURE_2D)
|
|
54
|
+
|
|
55
|
+
glEnable (GL_BLEND)
|
|
56
|
+
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
|
|
57
|
+
|
|
58
|
+
glAlphaFunc(GL_GREATER,0.1)
|
|
59
|
+
glEnable(GL_ALPHA_TEST)
|
|
60
|
+
|
|
61
|
+
glEnable (GL_LINE_SMOOTH)
|
|
62
|
+
glHint( GL_LINE_SMOOTH_HINT , GL_NICEST )
|
|
63
|
+
|
|
64
|
+
ReSizeFun(Width, Height)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
InitLight()
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def InitLight() :
|
|
73
|
+
light_ambient = np.array( [ 0.0 , 0.0 , 0.0 , 1.0 ] )
|
|
74
|
+
light_diffuse = np.array( [ 1.0 , 1.0 , 1.0 , 1.0 ] )
|
|
75
|
+
light_specular = np.array( [ 1.0 , 1.0 , 1.0 , 1.0 ] )
|
|
76
|
+
light_position = np.array( [ 2.0 , 5.0 , 5.0 , 10.0 ] )
|
|
77
|
+
|
|
78
|
+
mat_ambient = np.array( [ 0.7 , 0.7 , 0.7 , 1.0 ] )
|
|
79
|
+
mat_diffuse = np.array( [ 0.8 , 0.8 , 0.8 , 1.0 ] )
|
|
80
|
+
mat_specular = np.array( [ 1.0 , 1.0 , 1.0 , 1.0 ] )
|
|
81
|
+
high_shininess = np.array( [ 100.0 ] )
|
|
82
|
+
|
|
83
|
+
glEnable(GL_LIGHT0)
|
|
84
|
+
glEnable(GL_NORMALIZE)
|
|
85
|
+
glEnable(GL_COLOR_MATERIAL)
|
|
86
|
+
#glEnable(GL_LIGHTING)
|
|
87
|
+
|
|
88
|
+
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient)
|
|
89
|
+
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse)
|
|
90
|
+
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular)
|
|
91
|
+
glLightfv(GL_LIGHT0, GL_POSITION, light_position)
|
|
92
|
+
|
|
93
|
+
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient)
|
|
94
|
+
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse)
|
|
95
|
+
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular)
|
|
96
|
+
glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess)
|
|
97
|
+
|
|
98
|
+
def enableLight():
|
|
99
|
+
glEnable(GL_LIGHTING)
|
|
100
|
+
|
|
101
|
+
def disableLight():
|
|
102
|
+
glDisable(GL_LIGHTING)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def DrawGLScene():
|
|
106
|
+
"""
|
|
107
|
+
Draw the current particle scene.
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
# Simulation step
|
|
111
|
+
DrawGLScene.stream()
|
|
112
|
+
|
|
113
|
+
tr = DrawGLScene.animation.translation
|
|
114
|
+
|
|
115
|
+
sim_time = DrawGLScene.animation.ode_solver.time
|
|
116
|
+
|
|
117
|
+
fm = tf.MyTimeFormatter()
|
|
118
|
+
|
|
119
|
+
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
|
|
120
|
+
|
|
121
|
+
Set2DMode( )
|
|
122
|
+
|
|
123
|
+
glut_print( 0.02 , 0.02 , GLUT_BITMAP_9_BY_15 , fm.to_str( sim_time ) , 1.0 , 1.0 , 1.0 , 1.0 )
|
|
124
|
+
|
|
125
|
+
if DrawGLScene.animation.measures_cnt() > 0 :
|
|
126
|
+
print_measures()
|
|
127
|
+
|
|
128
|
+
if DrawGLScene.animation.print_help :
|
|
129
|
+
print_help()
|
|
130
|
+
|
|
131
|
+
if DrawGLScene.animation.fps_print :
|
|
132
|
+
print_fps( DrawGLScene.animation.fps )
|
|
133
|
+
|
|
134
|
+
SetPerspective( DrawGLScene.animation )
|
|
135
|
+
|
|
136
|
+
glPushMatrix()
|
|
137
|
+
|
|
138
|
+
glEnable (GL_FOG)
|
|
139
|
+
glFogf (GL_FOG_DENSITY, 0.05)
|
|
140
|
+
|
|
141
|
+
glLoadIdentity()
|
|
142
|
+
|
|
143
|
+
if DrawGLScene.animation.state == "trackball_down" and DrawGLScene.animation.motion or joystick_func.animation.joy_state == "joy_on":
|
|
144
|
+
( ax , ay , az ) = DrawGLScene.animation.rotatation_axis
|
|
145
|
+
angle = DrawGLScene.animation.rotation_angle
|
|
146
|
+
glRotatef( angle , ax , ay , az )
|
|
147
|
+
DrawGLScene.animation.motion = False
|
|
148
|
+
|
|
149
|
+
glMultMatrixf( DrawGLScene.animation.rot_matrix )
|
|
150
|
+
# save the rot matrix
|
|
151
|
+
DrawGLScene.animation.rot_matrix = glGetFloatv( GL_MODELVIEW_MATRIX )
|
|
152
|
+
|
|
153
|
+
glLoadIdentity()
|
|
154
|
+
glTranslatef( tr[0] , tr[1] , -15.0 )
|
|
155
|
+
glMultMatrixf( DrawGLScene.animation.rot_matrix )
|
|
156
|
+
|
|
157
|
+
if DrawGLScene.animation.light :
|
|
158
|
+
enableLight()
|
|
159
|
+
|
|
160
|
+
DrawGLScene.animation.draw_particles.draw()
|
|
161
|
+
|
|
162
|
+
if DrawGLScene.animation.light :
|
|
163
|
+
disableLight()
|
|
164
|
+
|
|
165
|
+
if DrawGLScene.animation.view_axis :
|
|
166
|
+
DrawGLScene.animation.axis.draw_axis()
|
|
167
|
+
|
|
168
|
+
if DrawGLScene.animation.draw_vector_field :
|
|
169
|
+
DrawGLScene.animation.vector_field.draw()
|
|
170
|
+
|
|
171
|
+
glPopMatrix()
|
|
172
|
+
glutSwapBuffers()
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def Set2DMode( ):
|
|
176
|
+
|
|
177
|
+
glMatrixMode(GL_PROJECTION)
|
|
178
|
+
glLoadIdentity()
|
|
179
|
+
gluOrtho2D(0.0, 1.0, 0.0, 1.0)
|
|
180
|
+
glMatrixMode(GL_MODELVIEW)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def SetPerspective( animation ):
|
|
184
|
+
|
|
185
|
+
per = animation.perspective
|
|
186
|
+
|
|
187
|
+
( w , h ) = animation.win_size
|
|
188
|
+
|
|
189
|
+
glMatrixMode(GL_PROJECTION)
|
|
190
|
+
glLoadIdentity()
|
|
191
|
+
gluPerspective( per[0] , float(w)/float(h), per[1] , per[2] )
|
|
192
|
+
|
|
193
|
+
glMatrixMode(GL_MODELVIEW)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def ReSizeGLScene(Width, Height):
|
|
197
|
+
|
|
198
|
+
if Height == 0:
|
|
199
|
+
Height = 1
|
|
200
|
+
|
|
201
|
+
MousePressed.animation.win_size = ( Width , Height )
|
|
202
|
+
glViewport(0, 0, Width, Height)
|
|
203
|
+
|
|
204
|
+
SetPerspective( MousePressed.animation )
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def KeyPressed( c , x , y ):
|
|
208
|
+
if c == 'a' :
|
|
209
|
+
KeyPressed.animation.view_axis = not KeyPressed.animation.view_axis
|
|
210
|
+
|
|
211
|
+
if c == 'h' :
|
|
212
|
+
KeyPressed.animation.print_help = not KeyPressed.animation.print_help
|
|
213
|
+
|
|
214
|
+
if c == 't' :
|
|
215
|
+
KeyPressed.animation.trajectory = not KeyPressed.animation.trajectory
|
|
216
|
+
|
|
217
|
+
if c == 'f' :
|
|
218
|
+
KeyPressed.animation.fps_print = not KeyPressed.animation.fps_print
|
|
219
|
+
|
|
220
|
+
if c == 'p' :
|
|
221
|
+
KeyPressed.animation.draw_particles.set_particle_model( model="point" )
|
|
222
|
+
|
|
223
|
+
if c == 's' :
|
|
224
|
+
KeyPressed.animation.draw_particles.set_particle_model( model="sphere" )
|
|
225
|
+
|
|
226
|
+
if c == 'o' :
|
|
227
|
+
KeyPressed.animation.draw_particles.set_particle_model( model="teapot" )
|
|
228
|
+
|
|
229
|
+
if c == 'L' :
|
|
230
|
+
KeyPressed.animation.light = True
|
|
231
|
+
|
|
232
|
+
if c == 'l' :
|
|
233
|
+
KeyPressed.animation.light = False
|
|
234
|
+
|
|
235
|
+
if c == 'v' :
|
|
236
|
+
KeyPressed.animation.draw_vector_field = ( not KeyPressed.animation.draw_vector_field ) and ( KeyPressed.animation.vector_field != None )
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def MousePressed( button , state , x , y ):
|
|
242
|
+
#print ("--------------------")
|
|
243
|
+
#print ( "click" )
|
|
244
|
+
#print ( " butt " + str( button ) )
|
|
245
|
+
#print ( " state " + str(state ) )
|
|
246
|
+
#print ( " x " + str(x) )
|
|
247
|
+
#print ( " y " + str(y) )
|
|
248
|
+
|
|
249
|
+
if state == GLUT_DOWN and button == GLUT_LEFT_BUTTON :
|
|
250
|
+
MousePressed.animation.trackball.track_ball_mapping( np.array( [ x , y ] ) )
|
|
251
|
+
MousePressed.animation.state = "trackball_down"
|
|
252
|
+
elif state == GLUT_UP and button == GLUT_LEFT_BUTTON :
|
|
253
|
+
MousePressed.animation.state = "trackball_up"
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
if state == GLUT_DOWN and button == GLUT_RIGHT_BUTTON :
|
|
257
|
+
MousePressed.animation.translate_scene.translate_mapping( np.array( [ x , y ] ) )
|
|
258
|
+
MousePressed.animation.state = "translate_down"
|
|
259
|
+
elif state == GLUT_UP and button == GLUT_RIGHT_BUTTON :
|
|
260
|
+
MousePressed.animation.state = "translate_up"
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
if state == GLUT_DOWN and button == 3 :
|
|
264
|
+
MousePressed.animation.zoom_scene( +1 )
|
|
265
|
+
|
|
266
|
+
if state == GLUT_DOWN and button == 4 :
|
|
267
|
+
MousePressed.animation.zoom_scene( -1 )
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def MouseMotion( x , y ) :
|
|
271
|
+
#print ("--------------------")
|
|
272
|
+
#print ( "move" )
|
|
273
|
+
#print ( " x " + str(x) )
|
|
274
|
+
#print ( " y " + str(y) )
|
|
275
|
+
|
|
276
|
+
if MousePressed.animation.state == "trackball_down" :
|
|
277
|
+
( axis , angle ) = MousePressed.animation.trackball.on_move( np.array( [ x , y ] ) )
|
|
278
|
+
|
|
279
|
+
MousePressed.animation.rotation_angle = angle
|
|
280
|
+
MousePressed.animation.rotatation_axis = ( axis[0] , axis[1] , axis[2] )
|
|
281
|
+
|
|
282
|
+
MousePressed.animation.motion = True
|
|
283
|
+
|
|
284
|
+
elif MousePressed.animation.state == "translate_down" :
|
|
285
|
+
( dx , dy ) = MousePressed.animation.translate_scene.on_move( np.array( [ x , y ] ) )
|
|
286
|
+
( tx , ty ) = MousePressed.animation.translation
|
|
287
|
+
MousePressed.animation.translation = ( tx + dx , ty + dy )
|
|
288
|
+
|
|
289
|
+
MousePressed.animation.motion = True
|
|
290
|
+
|
|
291
|
+
#print( axis )
|
|
292
|
+
#print( angle )
|
|
293
|
+
|
|
294
|
+
def joystick_func( button_mask, x, y, z ):
|
|
295
|
+
#print( "------------------ " )
|
|
296
|
+
#print( "butt %d: " % button_mask )
|
|
297
|
+
#print( "x %d " % x )
|
|
298
|
+
#print( "y %d " % y )
|
|
299
|
+
#print( "z %d " % z )
|
|
300
|
+
|
|
301
|
+
if x == 0 and y == 0 :
|
|
302
|
+
joystick_func.animation.joy_state = "joy_off"
|
|
303
|
+
return
|
|
304
|
+
|
|
305
|
+
( axis , angle ) = joystick_func.animation.trackball.on_joystick( ( x , y ) )
|
|
306
|
+
|
|
307
|
+
joystick_func.animation.rotation_angle = angle
|
|
308
|
+
joystick_func.animation.rotatation_axis = ( axis[0] , axis[1] , axis[2] )
|
|
309
|
+
joystick_func.animation.joy_state = "joy_on"
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def print_help():
|
|
314
|
+
|
|
315
|
+
y = 0.9
|
|
316
|
+
glut_print( 0.1 , y , GLUT_BITMAP_9_BY_15 , "a: Axis ON/OFF" , 1 , 1 , 1 , 1 )
|
|
317
|
+
|
|
318
|
+
y -= 0.05
|
|
319
|
+
glut_print( 0.1 , y , GLUT_BITMAP_9_BY_15 , "t: Trajectory ON/OFF" , 1 , 1 , 1 , 1 )
|
|
320
|
+
|
|
321
|
+
y -= 0.05
|
|
322
|
+
glut_print( 0.1 , y , GLUT_BITMAP_9_BY_15 , "Point model - p: point | s: sphere | o: teapot " , 1 , 1 , 1 , 1 )
|
|
323
|
+
|
|
324
|
+
y -= 0.05
|
|
325
|
+
glut_print( 0.1 , y , GLUT_BITMAP_9_BY_15 , "Lighting - L: On l: OFF " , 1 , 1 , 1 , 1 )
|
|
326
|
+
|
|
327
|
+
y -= 0.05
|
|
328
|
+
glut_print( 0.1 , y , GLUT_BITMAP_9_BY_15 , "v: Toggle vector field " , 1 , 1 , 1 , 1 )
|
|
329
|
+
|
|
330
|
+
y -= 0.05
|
|
331
|
+
glut_print( 0.1 , y , GLUT_BITMAP_9_BY_15 , "f: Toggle FPS " , 1 , 1 , 1 , 1 )
|
|
332
|
+
|
|
333
|
+
y -= 0.1
|
|
334
|
+
glut_print( 0.1 , y , GLUT_BITMAP_9_BY_15 , "h: Toggle help message" , 1 , 1 , 1 , 1 )
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
def print_measures():
|
|
338
|
+
|
|
339
|
+
mnames = print_measures.animation.get_measures_names()
|
|
340
|
+
|
|
341
|
+
y = 0.9
|
|
342
|
+
|
|
343
|
+
for na in mnames:
|
|
344
|
+
m = print_measures.animation.get_measure_value_str( na )
|
|
345
|
+
glut_print( 0.7 , y , GLUT_BITMAP_9_BY_15 , " %s: %s " % ( na , m ) , 1 , 1 , 1 , 1 )
|
|
346
|
+
y -= 0.05
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
def print_fps( fps ):
|
|
350
|
+
glut_print( 0.9 , 0.05 , GLUT_BITMAP_9_BY_15 , "FPS: %.2f" % fps , 1 , 1 , 1 , 1 )
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
def glut_print( x, y, font, text, r, g , b , a):
|
|
354
|
+
|
|
355
|
+
blending = False
|
|
356
|
+
if glIsEnabled(GL_BLEND) :
|
|
357
|
+
blending = True
|
|
358
|
+
|
|
359
|
+
glPushMatrix()
|
|
360
|
+
glColor3f(1,1,1)
|
|
361
|
+
glRasterPos2f(x,y)
|
|
362
|
+
|
|
363
|
+
text = bytes( text.encode("ascii") )
|
|
364
|
+
|
|
365
|
+
glutBitmapString( font , text )
|
|
366
|
+
glPopMatrix()
|
|
367
|
+
|
|
368
|
+
if not blending :
|
|
369
|
+
glDisable(GL_BLEND)
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
if sys.platform.startswith("win"):
|
|
373
|
+
def SwapIntervalEXT( value ):
|
|
374
|
+
import ctypes
|
|
375
|
+
# Open the opengl32.dll
|
|
376
|
+
gldll = ctypes.windll.opengl32
|
|
377
|
+
# define a function pointer prototype of *(GLuint program, GLenum pname, GLint value)
|
|
378
|
+
prototype = ctypes.WINFUNCTYPE( ctypes.c_int , ctypes.c_uint )
|
|
379
|
+
# Get the win gl func adress
|
|
380
|
+
fptr = gldll.wglGetProcAddress( 'wglSwapIntervalEXT' )
|
|
381
|
+
if fptr==0:
|
|
382
|
+
raise Exception( "wglSwapIntervalEXT ('wglSwapIntervalEXT ') returned a zero adress, which will result in a nullpointer error if used.")
|
|
383
|
+
_wglSwapIntervalEXT = prototype( fptr )
|
|
384
|
+
|
|
385
|
+
_wglSwapIntervalEXT( value )
|
|
386
|
+
|
|
387
|
+
elif sys.platform.startswith("linux"):
|
|
388
|
+
def SwapIntervalEXT( value ):
|
|
389
|
+
pass
|
|
390
|
+
else :
|
|
391
|
+
def SwapIntervalEXT( value ):
|
|
392
|
+
pass
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
class AnimatedGl( pan.Animation ):
|
|
398
|
+
def __init__(self):
|
|
399
|
+
super( AnimatedGl , self ).__init__()
|
|
400
|
+
self.__window = None
|
|
401
|
+
|
|
402
|
+
# perspective sutup
|
|
403
|
+
self.__fovy = 40.0
|
|
404
|
+
self.__near = 1.0
|
|
405
|
+
self.__far = 300.0
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
self.__xrot_ax = 1.0
|
|
409
|
+
self.__yrot_ax = 0.0
|
|
410
|
+
self.__zrot_ax = 0.0
|
|
411
|
+
|
|
412
|
+
self.__rot_angle = 0.0
|
|
413
|
+
|
|
414
|
+
self.__trans_x = 0.0
|
|
415
|
+
self.__trans_y = 0.0
|
|
416
|
+
|
|
417
|
+
self.__win_width = 1000
|
|
418
|
+
self.__win_height = 800
|
|
419
|
+
|
|
420
|
+
self.__trackb = trk.TrackBall( self.win_size )
|
|
421
|
+
self.__tran = tran.TranslateScene( self.win_size )
|
|
422
|
+
|
|
423
|
+
self.__light = False
|
|
424
|
+
|
|
425
|
+
self.rot_matrix = np.array( [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ] )
|
|
426
|
+
|
|
427
|
+
self.state = "trackball_down"
|
|
428
|
+
self.joy_state = "joy_off"
|
|
429
|
+
self.motion = False
|
|
430
|
+
|
|
431
|
+
self.view_axis = True
|
|
432
|
+
self.print_help = False
|
|
433
|
+
|
|
434
|
+
self.axis = axgl.AxisOgl()
|
|
435
|
+
self.draw_particles = drp.DrawParticlesGL()
|
|
436
|
+
|
|
437
|
+
self.__draw_vector_field = False
|
|
438
|
+
self.vector_field = None
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
def get_pset(self):
|
|
442
|
+
return super(AnimatedGl,self).get_pset()
|
|
443
|
+
|
|
444
|
+
def set_pset( self , pset ):
|
|
445
|
+
super(AnimatedGl,self).set_pset( pset )
|
|
446
|
+
self.draw_particles.pset = pset
|
|
447
|
+
|
|
448
|
+
pset = property( get_pset , set_pset )
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
def get_rotation_axis( self ):
|
|
452
|
+
return ( self.__xrot_ax , self.__yrot_ax , self.__zrot_ax )
|
|
453
|
+
|
|
454
|
+
def set_rotation_axis( self , rot_xyz_ax ):
|
|
455
|
+
self.__xrot_ax = rot_xyz_ax[0]
|
|
456
|
+
self.__yrot_ax = rot_xyz_ax[1]
|
|
457
|
+
self.__zrot_ax = rot_xyz_ax[2]
|
|
458
|
+
|
|
459
|
+
rotatation_axis = property( get_rotation_axis , set_rotation_axis )
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
def get_rot_angle( self ):
|
|
463
|
+
return self.__rot_angle
|
|
464
|
+
|
|
465
|
+
def set_rot_angle( self , angle ):
|
|
466
|
+
self.__rot_angle = angle
|
|
467
|
+
|
|
468
|
+
rotation_angle = property( get_rot_angle , set_rot_angle )
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
def set_light( self , sw ):
|
|
472
|
+
self.__light = sw
|
|
473
|
+
|
|
474
|
+
def get_light( self ):
|
|
475
|
+
return self.__light
|
|
476
|
+
|
|
477
|
+
light = property( get_light , set_light , doc="enable or disable (True or False) the opengl lighting" )
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
def init_rotation( self , angle , axis ):
|
|
481
|
+
self.__init_rot = list( [ angle , axis ] )
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
def get_trackball( self ):
|
|
486
|
+
return self.__trackb
|
|
487
|
+
|
|
488
|
+
trackball = property( get_trackball )
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
def get_translate_scene(self):
|
|
492
|
+
return self.__tran
|
|
493
|
+
|
|
494
|
+
translate_scene = property( get_translate_scene )
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
def get_rotation( self ):
|
|
498
|
+
return ( self.__xrot , self.__yrot , self.__zrot )
|
|
499
|
+
|
|
500
|
+
def set_rotation( self , rot_xyz ):
|
|
501
|
+
self.__xrot = rot_xyz[0]
|
|
502
|
+
self.__yrot = rot_xyz[1]
|
|
503
|
+
self.__zrot = rot_xyz[2]
|
|
504
|
+
|
|
505
|
+
rotatation = property( get_rotation , set_rotation )
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
def get_translation(self):
|
|
509
|
+
return ( self.__trans_x , self.__trans_y )
|
|
510
|
+
|
|
511
|
+
def set_translation( self , transl ):
|
|
512
|
+
self.__trans_x = transl[0]
|
|
513
|
+
self.__trans_y = transl[1]
|
|
514
|
+
|
|
515
|
+
translation = property( get_translation , set_translation )
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
def get_perspective( self ):
|
|
519
|
+
return ( self.__fovy , self.__near , self.__far )
|
|
520
|
+
|
|
521
|
+
def set_perspective( self , perspective ):
|
|
522
|
+
self.__fovy = perspective[0]
|
|
523
|
+
self.__near = perspective[1]
|
|
524
|
+
self.__far = perspective[2]
|
|
525
|
+
|
|
526
|
+
perspective = property( get_perspective , set_perspective )
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
def get_win_size( self ):
|
|
530
|
+
return ( self.__win_width , self.__win_height )
|
|
531
|
+
|
|
532
|
+
def set_win_size( self , w_size ):
|
|
533
|
+
self.__win_width = w_size[0]
|
|
534
|
+
self.__win_height = w_size[1]
|
|
535
|
+
|
|
536
|
+
self.trackball.win_size = w_size
|
|
537
|
+
self.translate_scene.win_size = w_size
|
|
538
|
+
|
|
539
|
+
win_size = property( get_win_size , set_win_size , doc="get or set the size of the current window. The size is a tuple: (w,h)")
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
def get_trajectory( self ) :
|
|
543
|
+
return super(AnimatedGl,self).get_trajectory()
|
|
544
|
+
|
|
545
|
+
def set_trajectory( self , tr ):
|
|
546
|
+
super(AnimatedGl,self).set_trajectory( tr )
|
|
547
|
+
self.draw_particles.trajectory = tr
|
|
548
|
+
|
|
549
|
+
trajectory = property( get_trajectory , set_trajectory , doc="enable or disable (True or False) the trajectory" )
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
def get_trajectory_step( self ) :
|
|
553
|
+
return super(AnimatedGl,self).get_rajectory_step()
|
|
554
|
+
|
|
555
|
+
def set_trajectory_step( self , trs ):
|
|
556
|
+
super(AnimatedGl,self).set_trajectory_step( trs )
|
|
557
|
+
self.draw_particles.set_trajectory_step( trs )
|
|
558
|
+
|
|
559
|
+
trajectory_step = property( get_trajectory_step , set_trajectory_step , doc="set or get the step for drawing the trajectory" )
|
|
560
|
+
|
|
561
|
+
|
|
562
|
+
def get_draw_vector_field(self):
|
|
563
|
+
return self.__draw_vector_field
|
|
564
|
+
|
|
565
|
+
def set_draw_vector_field( self , f ):
|
|
566
|
+
self.__draw_vector_field = f
|
|
567
|
+
|
|
568
|
+
draw_vector_field = property( get_draw_vector_field , set_draw_vector_field , doc="enable or disable (True of False) vector filed drawing (if available)" )
|
|
569
|
+
|
|
570
|
+
|
|
571
|
+
def add_vector_field_fun( self , fun , unit , density=1.0 , color_fun=None ):
|
|
572
|
+
|
|
573
|
+
if self.vector_field == None :
|
|
574
|
+
|
|
575
|
+
lims = [ self.xlim[0] , self.xlim[1] , self.ylim[0] , self.ylim[1] , self.zlim[0] , self.zlim[1] ]
|
|
576
|
+
|
|
577
|
+
self.vector_field = dvf.DrawVectorField( lims , density )
|
|
578
|
+
|
|
579
|
+
self.vector_field.add_vector_fun( fun , unit , color_fun )
|
|
580
|
+
|
|
581
|
+
|
|
582
|
+
def zoom_scene( self , f ):
|
|
583
|
+
|
|
584
|
+
(w,h) = MousePressed.animation.win_size
|
|
585
|
+
|
|
586
|
+
( fovy , near , far ) = MousePressed.animation.perspective
|
|
587
|
+
|
|
588
|
+
if fovy <= 2.0 and f < 0 :
|
|
589
|
+
f = -0.04
|
|
590
|
+
if fovy <= 0.2 and f < 0 :
|
|
591
|
+
f = 0.0
|
|
592
|
+
if fovy < 2.0 and f > 0 :
|
|
593
|
+
f = 0.04
|
|
594
|
+
if fovy > 179 and f > 0 :
|
|
595
|
+
f = 0.0
|
|
596
|
+
|
|
597
|
+
|
|
598
|
+
MousePressed.animation.perspective = ( fovy+f*2 , near , far )
|
|
599
|
+
MousePressed.animation.translate_scene.fovy = fovy+f*2
|
|
600
|
+
|
|
601
|
+
ReSizeGLScene( w , h )
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
def build_animation(self):
|
|
605
|
+
self.__window = None
|
|
606
|
+
|
|
607
|
+
glutInit(sys.argv)
|
|
608
|
+
|
|
609
|
+
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE)
|
|
610
|
+
glutInitWindowSize( self.win_size[0] , self.win_size[1] )
|
|
611
|
+
glutInitWindowPosition(20, 20)
|
|
612
|
+
|
|
613
|
+
self.__window = glutCreateWindow( ctypes.c_char_p( b"Particles" ) )
|
|
614
|
+
|
|
615
|
+
DGLS = DrawGLScene
|
|
616
|
+
|
|
617
|
+
self.ode_solver.update_force()
|
|
618
|
+
|
|
619
|
+
DGLS.stream = self.data_stream
|
|
620
|
+
|
|
621
|
+
DGLS.animation = self
|
|
622
|
+
|
|
623
|
+
glutDisplayFunc(DGLS)
|
|
624
|
+
glutIdleFunc(DGLS)
|
|
625
|
+
|
|
626
|
+
ReSizeFun = ReSizeGLScene
|
|
627
|
+
ReSizeFun.animation = self
|
|
628
|
+
|
|
629
|
+
KeyPressed.animation = self
|
|
630
|
+
|
|
631
|
+
glutReshapeFunc( ReSizeFun )
|
|
632
|
+
glutKeyboardFunc( KeyPressed )
|
|
633
|
+
|
|
634
|
+
pressed = MousePressed
|
|
635
|
+
pressed.animation = self
|
|
636
|
+
|
|
637
|
+
m_move = MouseMotion
|
|
638
|
+
m_move.animation = self
|
|
639
|
+
|
|
640
|
+
print_measures.animation = self
|
|
641
|
+
joystick_func.animation = self
|
|
642
|
+
|
|
643
|
+
|
|
644
|
+
glutJoystickFunc( joystick_func , 250 )
|
|
645
|
+
glutMouseFunc( pressed )
|
|
646
|
+
glutMotionFunc( m_move )
|
|
647
|
+
|
|
648
|
+
InitGL( self.win_size[0] , self.win_size[1] , ReSizeFun )
|
|
649
|
+
|
|
650
|
+
self.draw_particles.ogl_init()
|
|
651
|
+
self.axis.ogl_init()
|
|
652
|
+
|
|
653
|
+
try:
|
|
654
|
+
self.__init_rot
|
|
655
|
+
except:
|
|
656
|
+
pass
|
|
657
|
+
else:
|
|
658
|
+
glMatrixMode(GL_MODELVIEW)
|
|
659
|
+
glPushMatrix()
|
|
660
|
+
glLoadIdentity()
|
|
661
|
+
glRotatef( self.__init_rot[0] , self.__init_rot[1][0] , self.__init_rot[1][1] , self.__init_rot[1][2] )
|
|
662
|
+
self.rot_matrix = glGetFloatv( GL_MODELVIEW_MATRIX )
|
|
663
|
+
glPopMatrix()
|
|
664
|
+
|
|
665
|
+
if self.vector_field != None :
|
|
666
|
+
self.vector_field.ogl_init()
|
|
667
|
+
|
|
668
|
+
try :
|
|
669
|
+
SwapIntervalEXT(0)
|
|
670
|
+
except :
|
|
671
|
+
print( "ERROR: VSYNC not disabled" )
|
|
672
|
+
|
|
673
|
+
|
|
674
|
+
def data_stream(self):
|
|
675
|
+
|
|
676
|
+
self.pset.log()
|
|
677
|
+
|
|
678
|
+
self.ode_solver.step()
|
|
679
|
+
self.perform_measurement()
|
|
680
|
+
|
|
681
|
+
self.update_fps()
|
|
682
|
+
|
|
683
|
+
return self.ode_solver.steps_cnt
|
|
684
|
+
|
|
685
|
+
|
|
686
|
+
def start(self):
|
|
687
|
+
glutMainLoop()
|
|
688
|
+
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
|