atomes 1.1.14
atomes: an atomic scale modeling tool box
Loading...
Searching...
No Matches
glview.c
Go to the documentation of this file.
1/* This file is part of the 'atomes' software
2
3'atomes' is free software: you can redistribute it and/or modify it under the terms
4of the GNU Affero General Public License as published by the Free Software Foundation,
5either version 3 of the License, or (at your option) any later version.
6
7'atomes' is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
8without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9See the GNU General Public License for more details.
10
11You should have received a copy of the GNU Affero General Public License along with 'atomes'.
12If not, see <https://www.gnu.org/licenses/>
13
14Copyright (C) 2022-2024 by CNRS and University of Strasbourg */
15
22/*
23* This file: 'glview.c'
24*
25* Contains:
26*
27
28 - The callbacks of the OpenGL window
29
30*
31* List of functions:
32
33 GLuint * allocgluint (int val);
34 GLuint ** allocdgluint (int xal, int yal);
35
36 GLfloat ** allocdGLfloat (int xal, int yal);
37
38 gboolean is_GLExtension_Supported (const char * extension);
39
40 G_MODULE_EXPORT gboolean on_motion (GtkWidget * widg, GdkEvent * event, gpointer data);
41 G_MODULE_EXPORT gboolean on_lib_pressed (GtkWidget * widg, GdkEvent * event, gpointer data);
42 G_MODULE_EXPORT gboolean on_glwin_button_event (GtkWidget * widg, GdkEvent * event, gpointer data);
43 G_MODULE_EXPORT gboolean on_scrolled (GtkWidget * widg, GdkEvent * event, gpointer data);
44 G_MODULE_EXPORT gboolean on_glwin_pointer_scoll (GtkEventControllerScroll * event, gdouble dx, gdouble dy, gpointer data);
45 G_MODULE_EXPORT gboolean on_expose (GtkGLArea * area, GdkGLContext * context, gpointer data);
46 G_MODULE_EXPORT gboolean on_expose (GtkWidget * widg, cairo_t * cr, gpointer data);
47
48 void update_bonds_ (int * bd, int * stp,
49 int * bdim, int bda[* bdim], int bdb[* bdim],
50 double * x, double * y, double * z);
51 void sort (int dim, int * tab);
52 void update_atom_neighbors_ (int * stp, int * at, int * nv);
53 void update_this_neighbor_ (int * stp, int * at, int * iv, int * nv);
54 void update (glwin * view);
55 void transform (glwin * view, double aspect);
56 void reshape (glwin * view, int width, int height);
57 void save_rotation_quaternion (glwin * view);
58 void edit_for_motion (glwin * view);
59 void motion (glwin * view, gint x, gint y, GdkModifierType state);
60 void render_this_gl_window (glwin * view, GtkGLArea * area, gint button, double ptx, double pty);
61 void render_this_gl_window (glwin * view, GtkWidget * widg, gint button);
62 void glwin_lib_pressed (double x, double y, guint event_type, int event_button, gpointer data);
63 void glwin_button_event (double event_x, double event_y, guint event_button, guint event_type, guint32 event_time, gpointer data);
64 void zoom (glwin * view, int delta);
65 void rotate_x_y (glwin * view, double angle_x, double angle_y);
66 void init_camera (project * this_proj, int get_depth);
67 void image_init_spec_data (image * img, project * this_proj, int nsp);
68 void set_img_lights (project * this_proj, image * img);
69 void init_img (project * this_proj);
70 void init_opengl (glwin * view);
71 void center_molecule (project * this_proj);
72 void center_this_molecule (glwin * view);
73 void free_glwin_spec_data (project * this_proj, int spec);
74 void glwin_init_spec_data (project * this_proj, int nspec);
75 void init_glwin (glwin * view);
76 void gtk_window_change_gdk_visual (GtkWidget * win);
77
78 G_MODULE_EXPORT void on_glwin_pointer_motion (GtkEventControllerMotion * motc, gdouble x, gdouble y, gpointer data);
79 G_MODULE_EXPORT void on_lib_button_pressed (GtkGesture * gesture, int n_press, double x, double y, gpointer data);
80 G_MODULE_EXPORT void on_lib_button_released (GtkGesture * gesture, int n_press, double x, double y, gpointer data);
81 G_MODULE_EXPORT void on_glwin_button_pressed (GtkGesture * gesture, int n_press, double x, double y, gpointer data);
82 G_MODULE_EXPORT void on_glwin_button_released (GtkGesture * gesture, int n_press, double x, double y, gpointer data);
83 G_MODULE_EXPORT void on_realize (GtkGLArea * area, gpointer data);
84 G_MODULE_EXPORT void on_realize (GtkWidget * widg, gpointer data);
85
86 GError * init_gtk_gl_area (GtkGLArea * area);
87
88 ColRGBA set_default_color (int z);
89
90*/
91
92#include "global.h"
93#include "interface.h"
94#include "initcoord.h"
95#include "bind.h"
96#include "project.h"
97#include "glview.h"
98
101extern void process_the_hits (glwin * view, gint event_button, double ptx, double pty);
102extern void arc_ball_rotation (glwin * view, int x, int y);
103extern vec3_t get_arc_ball_vector (glwin * view, int x, int y);
104extern Light init_light_source (int type, float val, float vbl);
105extern void rotate_quat (project * this_proj, vec4_t q, int status, int axis);
106extern void translate (project * this_proj, int status, int axis, vec3_t trans);
107extern vec3_t get_bary (project * this_proj, int status);
108extern void update_labels (glwin * view);
109extern void prepare_atom_edition (gpointer data, gboolean visible);
110extern atom_search * allocate_atom_search (int proj, int action, int searchid, int tsize);
111extern int action_atoms_from_project (project * this_proj, atom_search * asearch, gboolean visible);
112extern atomic_object * create_object_from_frag_mol (project * this_proj, int coord, int geo, atom_search * remove);
113
115
123GLuint * allocgluint (int val)
124{
125 GLuint * var = NULL;
126
127 var = g_malloc0 (val*sizeof*var);
128 return var;
129}
130
139GLuint ** allocdgluint (int xal, int yal)
140{
141 GLuint ** var = NULL;
142 int i;
143
144 var = g_malloc (xal*sizeof*var);
145 for ( i = 0 ; i < xal ; i ++ )
146 {
147 /* allocation d'un tableau de tableau */
148 var[i] = allocgluint(yal);
149 }
150 return var;
151}
152
161GLfloat ** allocdGLfloat (int xal, int yal)
162{
163 GLfloat ** var = NULL;
164 int i;
165
166 var = g_malloc (xal*sizeof*var);
167 for ( i = 0 ; i < xal ; i ++ )
168 {
169 /* allocation d'un tableau de tableau */
170 var[i] = g_malloc0 (yal*sizeof*var[i]);
171 }
172 return var;
173}
174
175const float light_pos[MAX_LIGHTS][4] = {{-0.1f, 0.1f, 1.0f, 0.0f},
176 { 1.0f, 2.0f, 0.5f, 0.0f},
177 {-1.0f, 2.0f, -1.0f, 0.0f},
178 {-1.0f, -1.0f, 0.0f, 0.0f}};
179
188{
189 ColRGBA col;
190 double colors[116][3]={{1.00, 1.00, 1.00},
191 {0.85, 1.00, 1.00},
192 {0.80, 0.50, 1.00},
193 {0.76, 1.00, 0.00},
194 {1.00, 0.71, 0.71},
195 {0.56, 0.56, 0.56},
196 {0.18, 0.31, 0.97},
197 {1.00, 0.05, 0.05},
198 {0.56, 0.87, 0.31},
199 {0.70, 0.89, 0.96},
200 {0.67, 0.36, 0.95},
201 {0.54, 1.00, 0.00},
202 {0.75, 0.65, 0.65},
203 {0.94, 0.78, 0.62},
204 {1.00, 0.50, 0.00},
205 {1.00, 1.00, 0.19},
206 {0.12, 0.94, 0.12},
207 {0.50, 0.82, 0.89},
208 {0.56, 0.25, 0.83},
209 {0.24, 1.00, 0.00},
210 {0.90, 0.90, 0.90},
211 {0.75, 0.76, 0.78},
212 {0.65, 0.65, 0.67},
213 {0.54, 0.60, 0.78},
214 {0.61, 0.48, 0.78},
215 {0.87, 0.40, 0.20},
216 {0.94, 0.56, 0.62},
217 {0.31, 0.81, 0.31},
218 {0.78, 0.50, 0.20},
219 {0.49, 0.50, 0.69},
220 {0.76, 0.56, 0.56},
221 {0.40, 0.56, 0.56},
222 {0.74, 0.50, 0.89},
223 {1.00, 0.63, 0.00},
224 {0.65, 0.16, 0.16},
225 {0.36, 0.72, 0.82},
226 {0.44, 0.18, 0.69},
227 {0.00, 1.00, 0.00},
228 {0.58, 1.00, 1.00},
229 {0.58, 0.88, 0.88},
230 {0.45, 0.76, 0.79},
231 {0.33, 0.71, 0.71},
232 {0.23, 0.62, 0.62},
233 {0.14, 0.56, 0.56},
234 {0.04, 0.49, 0.55},
235 {0.00, 0.41, 0.52},
236 {0.75, 0.75, 0.75},
237 {1.00, 0.85, 0.56},
238 {0.65, 0.46, 0.45},
239 {0.40, 0.50, 0.50},
240 {0.62, 0.39, 0.71},
241 {0.83, 0.48, 0.00},
242 {0.58, 0.00, 0.58},
243 {0.26, 0.62, 0.69},
244 {0.34, 0.09, 0.56},
245 {0.00, 0.79, 0.00},
246 {0.44, 0.83, 1.00},
247 {1.00, 1.00, 0.78},
248 {0.85, 1.00, 0.78},
249 {0.78, 1.00, 0.78},
250 {0.64, 1.00, 0.78},
251 {0.56, 1.00, 0.78},
252 {0.38, 1.00, 0.78},
253 {0.27, 1.00, 0.78},
254 {0.19, 1.00, 0.78},
255 {0.12, 1.00, 0.78},
256 {0.00, 1.00, 0.61},
257 {0.00, 0.90, 0.46},
258 {0.00, 0.83, 0.32},
259 {0.00, 0.75, 0.22},
260 {0.00, 0.67, 0.14},
261 {0.30, 0.76, 1.00},
262 {0.30, 0.65, 1.00},
263 {0.13, 0.58, 0.84},
264 {0.15, 0.49, 0.67},
265 {0.15, 0.40, 0.59},
266 {0.09, 0.33, 0.53},
267 {0.81, 0.81, 0.87},
268 {1.00, 0.81, 0.13},
269 {0.72, 0.72, 0.81},
270 {0.65, 0.33, 0.30},
271 {0.34, 0.35, 0.38},
272 {0.62, 0.31, 0.71},
273 {0.67, 0.36, 0.00},
274 {0.46, 0.31, 0.27},
275 {0.26, 0.51, 0.59},
276 {0.26, 0.00, 0.40},
277 {0.00, 0.49, 0.00},
278 {0.44, 0.67, 0.98},
279 {0.00, 0.73, 1.00},
280 {0.00, 0.63, 1.00},
281 {0.00, 0.56, 1.00},
282 {0.00, 0.50, 1.00},
283 {0.00, 0.42, 1.00},
284 {0.33, 0.36, 0.95},
285 {0.54, 0.31, 0.89},
286 {0.63, 0.21, 0.83},
287 {0.70, 0.12, 0.83},
288 {0.70, 0.12, 0.73},
289 {0.70, 0.05, 0.65},
290 {0.74, 0.05, 0.53},
291 {0.78, 0.00, 0.40},
292 {0.80, 0.00, 0.35},
293 {0.82, 0.00, 0.31},
294 {0.85, 0.00, 0.27},
295 {0.88, 0.00, 0.22},
296 {0.90, 0.00, 0.18},
297 {0.92, 0.00, 0.15},
298 {0.93, 0.00, 0.14},
299 {0.94, 0.00, 0.13},
300 {0.95, 0.00, 0.12},
301 {0.96, 0.00, 0.10},
302 {0.97, 0.00, 0.10},
303 {0.98, 0.00, 0.10},
304 {0.99, 0.00, 0.10}};
305 // Dumy atoms have z < 1
306 int Z = (z < 1) ? 1 : z;
307 col.red = colors[Z-1][0];
308 col.green = colors[Z-1][1];
309 col.blue = colors[Z-1][2];
310 col.alpha = 1.0;
311 return col;
312}
313
330void update_bonds_ (int * bd, int * stp,
331 int * bdim, int bda[* bdim], int bdb[* bdim],
332 double * x, double * y, double * z)
333{
334 int i, j, k;
335
336 active_glwin -> allbonds[* bd] += * bdim;
337 active_glwin -> bonds[* stp][* bd] = * bdim;
338
339 if (* bdim > 0)
340 {
341 active_glwin -> bondid[* stp][* bd] = NULL;
342 active_glwin -> bondid[* stp][* bd] = allocdint (* bdim, 2);
343 for (i=0; i< * bdim; i++)
344 {
345 j = bda[i] - 1;
346 k = bdb[i] - 1;
347 active_glwin -> bondid[* stp][* bd][i][0] = j;
348 active_glwin -> bondid[* stp][* bd][i][1] = k;
349 }
350 if (* bd)
351 {
352 if (active_glwin -> clones[* stp] != NULL)
353 {
354 g_free (active_glwin -> clones[* stp]);
355 active_glwin -> clones[* stp] = NULL;
356 }
357 active_glwin -> clones[* stp] = g_malloc0 (*bdim*sizeof*active_glwin -> clones[* stp]);
358 for (i=0; i< * bdim; i++)
359 {
360 active_glwin -> clones[* stp][i].x = x[i];
361 active_glwin -> clones[* stp][i].y = y[i];
362 active_glwin -> clones[* stp][i].z = z[i];
363 j = bda[i] - 1;
364 k = bdb[i] - 1;
365 active_project -> atoms[* stp][j].cloned = TRUE;
366 active_project -> atoms[* stp][k].cloned = TRUE;
367 }
368 }
369 }
370}
371
380void sort (int dim, int * tab)
381{
382 int i, j, val;
383 for (i=1; i<dim; i++)
384 {
385 val = tab[i];
386 for (j=i-1; j>-1; j--)
387 {
388 if (tab[j] <= val) break;
389 tab[j+1] = tab[j];
390 }
391 tab[j+1]=val;
392 }
393}
394
404void update_atom_neighbors_ (int * stp, int * at, int * nv)
405{
406 active_project -> atoms[* stp][* at].numv = * nv;
407 if (* nv)
408 {
409 active_project -> atoms[* stp][* at].vois = allocint(* nv);
410 }
411}
412
423void update_this_neighbor_ (int * stp, int * at, int * iv, int * nv)
424{
425 active_project -> atoms[* stp][* at].vois[* iv] = * nv - 1;
426 if (* iv == active_project -> atoms[* stp][* at].numv - 1)
427 {
428 sort (active_project -> atoms[* stp][* at].numv, active_project -> atoms[* stp][* at].vois);
429 }
430}
431
439void update (glwin * view)
440{
441 gtk_gl_area_queue_render ((GtkGLArea *)view -> plot);
442#ifdef G_OS_WIN32
443 gtk_widget_hide (view -> plot);
444 gtk_widget_show (view -> plot);
445#endif
446}
447
456void transform (glwin * view, double aspect)
457{
458 GLdouble w, h;
459 GLdouble dw, dh;
460
461 double zoom = view -> anim -> last -> img -> zoom;
462 view -> zoom_factor = zoom * 0.1 * view -> anim -> last -> img -> p_depth / (2.0 * view -> anim -> last -> img -> gfar);
463 if (view -> anim -> last -> img -> rep == ORTHOGRAPHIC)
464 {
465 zoom *= (view -> anim -> last -> img -> p_depth / view -> anim -> last -> img -> gnear);
466 }
467 dw = view -> anim -> last -> img -> c_shift[0]*2.0*zoom;
468 dh = view -> anim -> last -> img -> c_shift[1]*2.0*zoom;
469 if (aspect > 1.0)
470 {
471 w = zoom * aspect;
472 h = zoom;
473 }
474 else
475 {
476 w = zoom;
477 h = zoom / aspect;
478 }
479 view -> anim -> last -> img -> gleft = -w + dw;
480 view -> anim -> last -> img -> gright = w + dw;
481 view -> anim -> last -> img -> gbottom = -h + dh;
482 view -> anim -> last -> img -> gtop = h + dh;
483
484 if (view -> anim -> last -> img -> rep == PERSPECTIVE)
485 {
486 view -> projection_matrix = m4_frustum (view -> anim -> last -> img -> gleft,
487 view -> anim -> last -> img -> gright,
488 view -> anim -> last -> img -> gbottom,
489 view -> anim -> last -> img -> gtop,
490 view -> anim -> last -> img -> gnear,
491 view -> anim -> last -> img -> gfar);
492 }
493 else
494 {
495 view -> projection_matrix = m4_ortho (view -> anim -> last -> img -> gleft,
496 view -> anim -> last -> img -> gright,
497 view -> anim -> last -> img -> gbottom,
498 view -> anim -> last -> img -> gtop,
499 -view -> anim -> last -> img -> gfar,
500 view -> anim -> last -> img -> gfar);
501 }
502}
503
513void reshape (glwin * view, int width, int height)
514{
515 double aspect;
516 int scale = 1.0;
517 if (view -> win)
518 {
519 if (GTK_IS_WIDGET(view -> win))
520 {
521 scale = gtk_widget_get_scale_factor (view -> win);
522 }
523 }
524 glViewport (0, 0, (GLsizei) scale * width, (GLsizei) scale * height);
525 view -> view_port = vec4 (0.0, 0.0, width, height);
526 aspect = (double) width / (double) height;
527 transform (view, aspect);
528}
529
538{
539 //int i;
540 //for (i=0; i<4; i++) old_rotation_quaternion[i] = view -> anim -> last -> img -> rotation_quaternion[i];
541 old_rotation_quaternion.w = view -> anim -> last -> img -> rotation_quaternion.w;
542 old_rotation_quaternion.x = view -> anim -> last -> img -> rotation_quaternion.x;
543 old_rotation_quaternion.y = view -> anim -> last -> img -> rotation_quaternion.y;
544 old_rotation_quaternion.z = view -> anim -> last -> img -> rotation_quaternion.z;
545}
546
555{
556 gboolean check_edit = FALSE;
557 project * this_proj = get_project_by_id(view -> proj);
558 prepare_atom_edition (& view -> colorp[0][0], FALSE);
559 atom_search * move_search = allocate_atom_search (this_proj -> id, DISPL, DISPL, this_proj -> natomes);
560 int ** frag = allocdint (this_proj -> coord -> totcoord[2], 2);
561 int i, j, k;
562 j = 0;
563 for (i=0; i<this_proj -> natomes; i++)
564 {
565 k = this_proj -> atoms[0][i].coord[2];
566 frag[k][0] ++;
567 if (this_proj -> atoms[0][i].pick[0])
568 {
569 move_search -> todo[i] = 1;
570 frag[k][1] ++;
571 j ++;
572 }
573 }
574 if (j)
575 {
576 for (i=0; i<this_proj -> coord -> totcoord[2]; i++)
577 {
578 if (frag[i][1] && frag[i][1] < frag[i][0])
579 {
580 check_edit = TRUE;
581 break;
582 }
583 }
584 if (check_edit)
585 {
586 action_atoms_from_project (this_proj, move_search,
587 (this_proj -> modelgl -> atom_win) ? this_proj -> modelgl -> atom_win -> visible : FALSE);
588 }
589 else
590 {
591 atomic_object * object;
592 for (i=0; i<this_proj -> coord -> totcoord[2]; i++)
593 {
594 if (frag[i][1])
595 {
596 object_motion = TRUE;
597 object = create_object_from_frag_mol (this_proj, 2, i, NULL);
598 object_motion = FALSE;
599 g_free (object);
600 }
601 }
602 }
603 g_free (frag);
604 }
605 view -> baryc[1] = get_bary (this_proj, 1);
606 move_search = free_this_search_data (move_search);
607 view -> prepare_motion = FALSE;
608}
609
620void motion (glwin * view, gint x, gint y, GdkModifierType state)
621{
622 view -> mouseAction = MOTION;
623 int i;
624 if (view -> mouseStatus == CLICKED)
625 {
626 if (view -> mode == EDITION && view -> prepare_motion && view -> rebuild[0][0]) edit_for_motion (view);
627
628 if (state & GDK_BUTTON1_MASK)
629 {
630 arc_ball_rotation (view, x, y);
631 }
632 else if (state & GDK_BUTTON2_MASK)
633 {
634 if (view -> mode != EDITION)
635 {
636 view -> anim -> last -> img -> c_shift[0] -= (double) (x - view -> mouseX) / view -> pixels[0];
637 view -> anim -> last -> img -> c_shift[1] += (double) (y - view -> mouseY) / view -> pixels[1];
638 for (i=0; i<2; i++)
639 {
640 if (view -> camera_widg[i+5])
641 {
642 if (GTK_IS_WIDGET(view -> camera_widg[i+5]))
643 {
644 gtk_spin_button_set_value ((GtkSpinButton *)view -> camera_widg[i+5], - view -> anim -> last -> img -> c_shift[i]);
645 }
646 }
647 }
648 }
649 else
650 {
651 vec3_t pos_a = vec3(x, - y, 0.75);
652 vec3_t pos_b = vec3(view -> mouseX, - view -> mouseY, 0.75);
653 vec3_t trans_a = v3_un_project (pos_a, view -> view_port, view -> projection_matrix);
654 vec3_t trans_b = v3_un_project (pos_b, view -> view_port, view -> projection_matrix);
655 vec3_t trans;
656 trans.x = (trans_a.x - trans_b.x);
657 trans.y = (trans_b.y - trans_a.y);
658 if (view -> anim -> last -> img -> rep == PERSPECTIVE)
659 {
660 trans.x *= view -> anim -> last -> img -> p_depth;
661 trans.y *= view -> anim -> last -> img -> p_depth;
662 }
663 trans.z = 0.0;
664 translate (get_project_by_id(view -> proj), 1, 1, trans);
665 }
666 }
667 if (view -> mode == EDITION)
668 {
670#ifdef GTK3
671 // GTK3 Menu Action To Check
673#endif
674 }
675 view -> mouseX = x;
676 view -> mouseY = y;
677 update (view);
678 }
679}
680
681#ifdef GTK3
691G_MODULE_EXPORT gboolean on_motion (GtkWidget * widg, GdkEvent * event, gpointer data)
692{
693 glwin * view = (glwin *) data;
694 if (view -> mouseStatus != RELEASED)
695 {
696 GdkEventMotion * mevent = (GdkEventMotion *)event;
697 gint x, y;
698 GdkModifierType state;
699 if (mevent -> is_hint)
700 {
701 gdk_window_get_device_position (mevent -> window, mevent -> device, & x, & y, & state);
702 }
703 else
704 {
705 x = (gint) mevent -> x;
706 y = (gint) mevent -> y;
707 state = (GdkModifierType) mevent -> state;
708 }
709 motion (view, x, y, state);
710 }
711 return FALSE;
712}
713#else
724G_MODULE_EXPORT void on_glwin_pointer_motion (GtkEventControllerMotion * motc, gdouble x, gdouble y, gpointer data)
725{
726 glwin * view = (glwin *) data;
727 if (view -> mouseStatus != RELEASED)
728 {
729 motion (view, (gint)x, (gint)y, gtk_event_controller_get_current_event_state((GtkEventController*)motc));
730 }
731}
732#endif
733
734#ifdef GTKGLAREA
746void render_this_gl_window (glwin * view, GtkGLArea * area, gint button, double ptx, double pty)
747#else
757void render_this_gl_window (glwin * view, GtkWidget * widg, gint button)
758#endif
759{
760#ifdef GTKGLAREA
761 view -> pixels[0] = gtk_widget_get_allocated_width (GTK_WIDGET(area));
762 view -> pixels[1] = gtk_widget_get_allocated_height (GTK_WIDGET(area));
763 gtk_gl_area_make_current (area);
764 if (gtk_gl_area_get_error (area) == NULL)
765#else
766 view -> pixels[0] = gtk_widget_get_allocated_width (widg);
767 view -> pixels[1] = gtk_widget_get_allocated_height (widg);
768 GdkWindow * win = gtk_widget_get_window (widg);
769 if (glXMakeCurrent (GDK_WINDOW_XDISPLAY (win), GDK_WINDOW_XID (win), view -> glcontext))
770#endif
771 {
772 reshape (view, view -> pixels[0], view -> pixels[1]);
773 draw (view);
774 if (view -> to_pick)
775 {
776 if (button) process_the_hits (view, button, ptx, pty);
777 view -> to_pick = FALSE;
778 reshape (view, view -> pixels[0], view -> pixels[1]);
779 draw (view);
780 }
781#ifdef GTKGLAREA
782 glFlush ();
783#else
784 glXSwapBuffers (GDK_WINDOW_XDISPLAY (win), GDK_WINDOW_XID (win));
785#endif
786 }
787}
788
800void glwin_lib_pressed (double x, double y, guint event_type, guint event_button, gpointer data)
801{
802 glwin * view = (glwin *) data;
803 switch (event_type)
804 {
805 case GDK_BUTTON_PRESS:
806 view -> mouseStatus = CLICKED;
807 view -> mouseX = x;
808 view -> mouseY = y;
809 if (event_button == 1)
810 {
812 arc_ball_init = get_arc_ball_vector (view, view -> mouseX, view -> mouseY);
813 view -> to_pick = FALSE;
814 update (view);
815 }
816 break;
817 case GDK_BUTTON_RELEASE:
818 view -> mouseStatus = RELEASED;
819 break;
820 }
821}
822
823#ifdef GTK3
833G_MODULE_EXPORT gboolean on_lib_pressed (GtkWidget * widg, GdkEvent * event, gpointer data)
834{
835 GdkEventButton * bevent = (GdkEventButton*)event;
836 glwin_lib_pressed (bevent -> x, bevent -> y, bevent -> type, bevent -> button, data);
837 return FALSE;
838}
839#else
851G_MODULE_EXPORT void on_lib_button_pressed (GtkGesture * gesture, int n_press, double x, double y, gpointer data)
852{
853 glwin_lib_pressed (x, y, GDK_BUTTON_PRESS, gtk_gesture_single_get_current_button ((GtkGestureSingle * )gesture), data);
854}
855
867G_MODULE_EXPORT void on_lib_button_released (GtkGesture * gesture, int n_press, double x, double y, gpointer data)
868{
869 glwin_lib_pressed (x, y, GDK_BUTTON_RELEASE, gtk_gesture_single_get_current_button ((GtkGestureSingle * )gesture), data);
870}
871#endif // GTK3
872
874
887void glwin_button_event (double event_x, double event_y, guint event_button, guint event_type, guint32 event_time, gpointer data)
888{
889 glwin * view = (glwin *) data;
890 switch (event_type)
891 {
892 case GDK_BUTTON_PRESS:
893 view -> mouseStatus = CLICKED;
894 view -> mouseX = event_x;
895 view -> mouseY = event_y;
896 clock_gettime (CLOCK_MONOTONIC, & start_time);
897 if (event_button == 1 || event_button == 3)
898 {
900 arc_ball_init = get_arc_ball_vector (view, view -> mouseX, view -> mouseY);
901 view -> nth_copy = 0;
902 view -> insert_coords = get_insertion_coordinates (view);
903#ifdef GTKGLAREA
904 render_this_gl_window (view, GTK_GL_AREA(view -> plot), event_button, event_x, event_y);
905#else
906 render_this_gl_window (view, plot, event_button);
907#endif
908 }
909 break;
910 case GDK_BUTTON_RELEASE:
911 view -> mouseStatus = RELEASED;
912 clock_gettime (CLOCK_MONOTONIC, & stop_time);
914 {
915 view -> to_pick = TRUE;
916#ifdef GTKGLAREA
917 render_this_gl_window (view, GTK_GL_AREA(view -> plot), event_button, event_x, event_y);
918#else
919 render_this_gl_window (view, plot, event_button);
920#endif
921 }
922 if (view -> mode == EDITION && view -> mouseAction == MOTION)
923 {
924 view -> baryc[1] = get_bary (get_project_by_id(view -> proj), 1);
925 view -> mouseAction = ANALYZE;
926 }
927 if (event_button == 3)
928 {
929 switch (to_pop.action)
930 {
931 case 1:
933 break;
934 case 2:
936 break;
937 }
938 to_pop.action = 0;
939 }
940 break;
941 }
942}
943
944#ifdef GTK3
954G_MODULE_EXPORT gboolean on_glwin_button_event (GtkWidget * widg, GdkEvent * event, gpointer data)
955{
956 GdkEventButton * bevent = (GdkEventButton*)event;
957 glwin_button_event (bevent -> x, bevent -> y, bevent -> button, bevent -> type, bevent -> time, data);
958 return FALSE;
959}
960#else
972G_MODULE_EXPORT void on_glwin_button_pressed (GtkGesture * gesture, int n_press, double x, double y, gpointer data)
973{
974 glwin_button_event (x, y, gtk_gesture_single_get_current_button ((GtkGestureSingle * )gesture), GDK_BUTTON_PRESS, gtk_event_controller_get_current_event_time((GtkEventController *)gesture), data);
975}
976
988G_MODULE_EXPORT void on_glwin_button_released (GtkGesture * gesture, int n_press, double x, double y, gpointer data)
989{
990 glwin_button_event (x, y, gtk_gesture_single_get_current_button ((GtkGestureSingle * )gesture), GDK_BUTTON_RELEASE, gtk_event_controller_get_current_event_time((GtkEventController *)gesture), data);
991}
992#endif // GTK3
993
994// Zoom in or out
1003void zoom (glwin * view, int delta)
1004{
1005 view -> anim -> last -> img -> zoom += delta * view -> zoom_factor;
1006 if (view -> camera_widg[0])
1007 {
1008 if (GTK_IS_WIDGET(view -> camera_widg[0]))
1009 {
1010 gtk_spin_button_set_value ((GtkSpinButton *)view -> camera_widg[0], 1.0-0.5*view -> anim -> last -> img -> zoom);
1011 }
1012 }
1013}
1014
1015#ifdef GTK3
1025G_MODULE_EXPORT gboolean on_scrolled (GtkWidget * widg, GdkEvent * event, gpointer data)
1026{
1027 glwin * view = (glwin *) data;
1028 GdkEventScroll * sevent = (GdkEventScroll *)event;
1029 if (sevent -> direction == GDK_SCROLL_UP)
1030 {
1031 zoom (view, 1);
1032 }
1033 else if (sevent -> direction == GDK_SCROLL_DOWN && view -> anim -> last -> img -> zoom > ZOOM_MAX)
1034 {
1035 zoom (view, -1);
1036 }
1037 update_labels (view);
1038 update (view);
1039 return FALSE;
1040}
1041#else
1052G_MODULE_EXPORT gboolean on_glwin_pointer_scoll (GtkEventControllerScroll * event, gdouble dx, gdouble dy, gpointer data)
1053{
1054 glwin * view = (glwin *) data;
1055 if (dy < 0)
1056 {
1057 zoom (view, 1);
1058 }
1059 else if (dy > 0 && view -> anim -> last -> img -> zoom > ZOOM_MAX)
1060 {
1061 zoom (view, -1);
1062 }
1063 update_labels (view);
1064 update (view);
1065 return TRUE;
1066}
1067#endif
1068
1078void rotate_x_y (glwin * view, double angle_x, double angle_y)
1079{
1080 vec3_t axis;
1081 vec4_t q_a, q_b, q_c;
1082 axis.x = 0.0;
1083 axis.y = 1.0;
1084 axis.z = 0.0;
1085 q_a = axis_to_quat (axis, -pi*angle_y/180.0);
1086 axis.x = 1.0;
1087 axis.y = 0.0;
1088 axis.z = 0.0;
1089 q_b = axis_to_quat (axis, -pi*angle_x/180.0);
1090 q_c = q4_mul (q_a, q_b);
1091 view -> anim -> last -> img -> c_angle[0] -= angle_x;
1092 view -> anim -> last -> img -> c_angle[1] -= angle_y;
1093 int i;
1094 for (i=0; i<2; i++)
1095 {
1096 if (abs(view -> anim -> last -> img -> c_angle[i]) > 180.0) view -> anim -> last -> img -> c_angle[i] = 0.0;
1097 if (view -> camera_widg[i+3])
1098 {
1099 if (GTK_IS_WIDGET(view -> camera_widg[i+3]))
1100 {
1101 gtk_spin_button_set_value ((GtkSpinButton *)view -> camera_widg[i+3], view -> anim -> last -> img -> c_angle[i]);
1102 }
1103 }
1104 }
1105
1106 if (view -> mode != EDITION)
1107 {
1108 view -> anim -> last -> img -> rotation_quaternion = q4_mul (old_rotation_quaternion, q_c);
1109 }
1110 else
1111 {
1112 rotate_quat (get_project_by_id(view -> proj), q_c, 1, 1);
1113 init_default_shaders (view);
1114#ifdef GTK3
1115 // GTK3 Menu Action To Check
1117#endif
1118 }
1119}
1120
1129void init_camera (project * this_proj, int get_depth)
1130{
1131 glwin * view = this_proj -> modelgl;
1132 if (get_depth) view -> anim -> last -> img -> p_depth = (this_proj -> natomes) ? oglmax_ () : 50.0;
1133 if (view -> camera_widg[1])
1134 {
1135 if (GTK_IS_WIDGET(view -> camera_widg[1]))
1136 {
1137 gtk_spin_button_set_value ((GtkSpinButton *)view -> camera_widg[1], view -> anim -> last -> img -> p_depth);
1138 }
1139 }
1140 view -> anim -> last -> img -> gnear = 6.0;//view -> anim -> last -> img -> p_depth/15.0;
1141 if (view -> camera_widg[2])
1142 {
1143 if (GTK_IS_WIDGET(view -> camera_widg[2]))
1144 {
1145 gtk_spin_button_set_value ((GtkSpinButton *)view -> camera_widg[2], view -> anim -> last -> img -> gnear);
1146 }
1147 }
1148 view -> anim -> last -> img -> gfar = view -> anim -> last -> img -> p_depth*2.0;
1149 view -> anim -> last -> img -> rotation_quaternion.w = 0.0;
1150 view -> anim -> last -> img -> rotation_quaternion.x = 0.0;
1151 view -> anim -> last -> img -> rotation_quaternion.y = 0.0;
1152 view -> anim -> last -> img -> rotation_quaternion.z = 1.0;
1153 int i;
1154 for (i=0; i<2; i++)
1155 {
1156 view -> anim -> last -> img -> c_shift[i] = 0.0;
1157 view -> anim -> last -> img -> c_angle[i] = 0.0;
1158 if (view -> camera_widg[i+5])
1159 {
1160 if (GTK_IS_WIDGET(view -> camera_widg[i+5]))
1161 {
1162 gtk_spin_button_set_value ((GtkSpinButton *)view -> camera_widg[i+5], view -> anim -> last -> img -> c_shift[i]);
1163 }
1164 }
1165 }
1168 view -> anim -> last -> img -> zoom = ZOOM;
1169 if (view -> camera_widg[0])
1170 {
1171 if (GTK_IS_WIDGET(view -> camera_widg[0]))
1172 {
1173 gtk_spin_button_set_value ((GtkSpinButton *)view -> camera_widg[0], 1.0 - 0.5*view -> anim -> last -> img -> zoom);
1174 }
1175 }
1176}
1177
1187void image_init_spec_data (image * img, project * this_proj, int nsp)
1188{
1189 int i, j;
1190 // Chemical species related
1191 for (i = 0; i<2; i++)
1192 {
1193 img -> show_label[i] = allocbool(nsp);
1194 img -> show_atom[i] = allocbool(nsp);
1195 for (j=0; j<nsp; j++) img -> show_atom[i][j] = TRUE;
1196 }
1197 img -> at_color = g_malloc0 (2*nsp*sizeof*img -> at_color);
1198 img -> sphererad = allocdouble (2*nsp);
1199 img -> pointrad = allocdouble (2*nsp);
1200 img -> atomicrad = allocdouble (2*nsp);
1201 img -> bondrad = allocddouble (2*nsp, 2*nsp);
1202 img -> linerad = allocddouble (2*nsp, 2*nsp);
1203 for (i = 0; i < nsp; i++)
1204 {
1205 img -> sphererad[i] = img -> sphererad[i+nsp] = this_proj -> chemistry -> chem_prop[CHEM_R][i]/2.0;
1206 img -> atomicrad[i] = img -> atomicrad[i+nsp] = this_proj -> chemistry -> chem_prop[CHEM_R][i];
1207 img -> pointrad[i] = img -> pointrad[i+nsp] = DEFAULT_SIZE;
1208 img -> at_color[i] = img -> at_color[i+nsp] = set_default_color ((int)this_proj -> chemistry -> chem_prop[CHEM_Z][i]);
1209 img -> linerad[i][i] = img -> linerad[i+nsp][i+nsp] = DEFAULT_SIZE;
1210 img -> bondrad[i][i] = img -> bondrad[i+nsp][i+nsp] = min(1.0, img -> sphererad[i]/2.0);
1211 }
1212 for (i=0; i < nsp-1; i++)
1213 {
1214 for (j=i+1; j < nsp; j++)
1215 {
1216 img -> linerad[i][j] = img -> linerad[j][i]
1217 = img -> linerad[i+nsp][j+nsp]
1218 = img -> linerad[j+nsp][i+nsp] = DEFAULT_SIZE;
1219 img -> bondrad[i][j] = min(1.0, img -> sphererad[i]/2.0);
1220 img -> bondrad[i][j] = min(img -> bondrad[i][j], img -> sphererad[j]/2.0);
1221 img -> bondrad[j][i] = img -> bondrad[i+nsp][j+nsp]
1222 = img -> bondrad[j+nsp][i+nsp]
1223 = img -> bondrad[i][j];
1224 }
1225 }
1226 for (i=0; i<10; i++)
1227 {
1228 img -> spcolor[i] = NULL;
1229 if (i < 2)
1230 {
1231 img -> spcolor[i] = g_malloc (nsp*sizeof*img -> spcolor[i]);
1232 }
1233 else
1234 {
1235 img -> spcolor[i] = g_malloc (1*sizeof*img -> spcolor[i]);
1236 img -> spcolor[i][0] = NULL;
1237 }
1238 }
1239}
1240
1249void set_img_lights (project * this_proj, image * img)
1250{
1251 img -> lights = 3;
1252 if (img -> l_ght) g_free (img -> l_ght);
1253 img -> l_ght = g_malloc0 (3*sizeof*img -> l_ght);
1254 float val;
1255 if (this_proj -> cell.box)
1256 {
1257 val = (this_proj -> cell.box[0].param[0][0] == 0.0) ? img -> p_depth : this_proj -> cell.box[0].param[0][0];
1258 }
1259 else
1260 {
1261 val = img -> p_depth;
1262 }
1263 float vbl = img -> p_depth;
1264 img -> l_ght[0] = init_light_source (0, val, vbl);
1265 img -> l_ght[1] = init_light_source (1, val, vbl);
1266 img -> l_ght[2] = init_light_source (1, val, vbl);
1267}
1268
1276void init_img (project * this_proj)
1277{
1278 int i;
1279 this_proj -> modelgl -> anim -> last -> img = g_malloc0(sizeof*this_proj -> modelgl -> anim -> last -> img);
1280 image * img = this_proj -> modelgl -> anim -> last -> img;
1281 img -> backcolor.red = 0.0;
1282 img -> backcolor.green = 0.0;
1283 img -> backcolor.blue = 0.0;
1284 img -> backcolor.alpha = 1.0;
1285 img -> box_color.red = 0.0;
1286 img -> box_color.green = 1.0;
1287 img -> box_color.blue = 0.0;
1288 img -> box_color.alpha = 1.0;
1289 img -> color_map[0] = 0;
1290 img -> color_map[1] = 0;
1291 img -> box_axis_rad[BOX] = 0.05;
1292 img -> box_axis_line[BOX] = DEFAULT_SIZE;
1293 img -> axispos = BOTTOM_RIGHT;
1294 img -> box_axis_rad[AXIS] = 0.1;
1295 img -> box_axis_line[AXIS] = DEFAULT_SIZE;
1296 img -> axis_length = 2.0*DEFAULT_SIZE;
1297 img -> axis_color = NULL;
1298 img -> axis_pos[0] = 50.0;
1299 img -> axis_pos[1] = 50.0;
1300 img -> axis_pos[2] = 0.0;
1301 img -> axis_labels = 1;
1302 img -> filled_type = NONE;
1303 img -> quality = QUALITY;
1304 img -> render = FILL;
1305 img -> rep = PERSPECTIVE;
1306
1307 // Visual styles
1308 img -> style = (this_proj -> natomes <= 1000) ? BALL_AND_STICK : DEFAULT_STYLE;
1309 img -> box_axis[AXIS] = NONE; // (this_proj -> natomes <= 1000) ? CYLINDERS : DEFAULT_STYLE;
1310 if (this_proj -> cell.pbc)
1311 {
1312 img -> box_axis[BOX] = (this_proj -> natomes <= 1000) ? CYLINDERS : DEFAULT_STYLE;
1313 }
1314 else
1315 {
1316 img -> box_axis[BOX] = NONE;
1317 }
1318
1319 for (i=0; i<5; i++)
1320 {
1321 img -> labels_position[i] = 1;
1322 img -> labels_render[i] = BETTER_TEXT;
1323 if (i < 2) img -> labels_format[i] = SYMBOL_AND_NUM;
1324 img -> labels_font[i] = g_strdup_printf ("Sans Bold 12");
1325 }
1326 img -> mtilt = TRUE;
1327 img -> mfactor = 1;
1328 img -> mwidth = 1.0;
1329 for (i=0; i<2; i++)
1330 {
1331 img -> labels_font[3+i] = g_strdup_printf ("Courier New Bold 18");
1332 img -> labels_color[3+i] = g_malloc (sizeof*img -> labels_color[3]);
1333 img -> labels_color[3+i][0].red = 1.0;
1334 img -> labels_color[3+i][0].green = 1.0;
1335 img -> labels_color[3+i][0].blue = 1.0;
1336 img -> labels_color[3+i][0].alpha = 1.0;
1337 img -> selected[i] = g_malloc0 (sizeof*img -> selected[i]);
1338 }
1339 img -> axis_title[0] = g_strdup_printf ("x");
1340 img -> axis_title[1] = g_strdup_printf ("y");
1341 img -> axis_title[2] = g_strdup_printf ("z");
1342
1343 img -> radall[0] = img -> radall[1] = 0.1;
1344
1345 if (this_proj -> nspec) image_init_spec_data (img, this_proj, this_proj -> nspec);
1346 this_proj -> modelgl -> p_moy = img -> p_depth = (this_proj -> natomes) ? oglmax_ () : 50.0;
1347 set_img_lights (this_proj, img);
1348 img -> m_terial.predefine = 4;
1349 img -> m_terial.albedo = vec3(0.5, 0.5, 0.5);
1350 img -> m_terial.param[0] = DEFAULT_LIGHTNING;
1351 img -> m_terial.param[1] = DEFAULT_METALLIC;
1352 img -> m_terial.param[2] = DEFAULT_ROUGHNESS;
1353 img -> m_terial.param[3] = DEFAULT_AMBIANT_OCCLUSION;
1354 img -> m_terial.param[4] = DEFAULT_GAMMA_CORRECTION;
1355 img -> m_terial.param[5] = DEFAULT_OPACITY;
1356
1357 img -> f_g.density = 0.005;
1358 img -> f_g.depth[0] = 1.0;
1359 img -> f_g.depth[1] = 90.0;
1360 img -> f_g.color = vec3 (0.01f, 0.01f, 0.01f);
1361}
1362
1370gboolean is_GLExtension_Supported (const char * extension)
1371{
1372 int i, j;
1373 i = j = 0;
1374 glGetIntegerv (GL_NUM_EXTENSIONS, & i);
1375 for (j=0; j<i; j++)
1376 {
1377 if (g_strcmp0 (extension, (const char*)glGetStringi(GL_EXTENSIONS, j)) == 0) return TRUE;
1378 }
1379 return FALSE;
1380}
1381
1389void init_opengl (glwin * view)
1390{
1391 glEnable (GL_DEPTH_TEST);
1392 glDepthMask (GL_TRUE);
1393 glDepthFunc (GL_LEQUAL);
1394 glDepthRange (0.0f, 1.0f);
1395 glClearDepth (1.0f);
1396
1397 glEnable (GL_NORMALIZE);
1398
1399 glShadeModel(GL_SMOOTH);
1400 glCullFace(GL_BACK);
1401 glEnable (GL_CULL_FACE); // Incompatible with polyhedra viz
1402
1403 glEnable (GL_COLOR_SUM_EXT);
1404
1405 glEnable (GL_PROGRAM_POINT_SIZE);
1406 glEnable (GL_VERTEX_PROGRAM_POINT_SIZE);
1407 glEnable (GL_POINT_SPRITE);
1408
1409 glEnable (GL_POINT_SMOOTH);
1410 glHint (GL_POINT_SMOOTH_HINT, GL_NICEST);
1411 glEnable (GL_LINE_SMOOTH); // Lines antialiasing
1412 glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
1413
1414 glDisable (GL_POLYGON_SMOOTH); // To disable ploygon antialiasing
1415 glEnable (GL_POLYGON_STIPPLE);
1416 glEnable (GL_POLYGON_OFFSET_FILL);
1417
1418 glEnable (GL_BLEND);
1419 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1420
1421 glPolygonOffset (1.0, 1.0);
1422 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
1423
1424 glHint (GL_FOG_HINT, GL_NICEST);
1425 glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
1426
1427 ogl_texture = (is_GLExtension_Supported("GL_ARB_texture_rectangle")) ? GL_TEXTURE_RECTANGLE_ARB : GL_TEXTURE_2D;
1428}
1429
1437void center_molecule (project * this_proj)
1438{
1439 int l, i, j;
1440 double x, y, z;
1441 // We need to center the molecule at (0.0, 0.0, 0.0)
1442 // Thus (0, 0, 0) will be the center of the box
1443 mat4_t rot;
1444 vec3_t bini, bend;
1445 for (l = 0; l < this_proj -> steps; l++)
1446 {
1447 x = 0.0;
1448 y = 0.0;
1449 z = 0.0;
1450 for (i = 0; i < this_proj -> natomes; i++)
1451 {
1452 x += this_proj -> atoms[l][i].x;
1453 y += this_proj -> atoms[l][i].y;
1454 z += this_proj -> atoms[l][i].z;
1455 }
1456 x /= this_proj -> natomes;
1457 y /= this_proj -> natomes;
1458 z /= this_proj -> natomes;
1459 for (i = 0; i < this_proj -> natomes; i++)
1460 {
1461 this_proj -> atoms[l][i].x -= x;
1462 this_proj -> atoms[l][i].y -= y;
1463 this_proj -> atoms[l][i].z -= z;
1464 }
1465
1466 for (i=0; i<FILLED_STYLES; i++)
1467 {
1468 if (this_proj -> modelgl -> volume_box[i])
1469 {
1470 if (this_proj -> modelgl -> volume_box[i][l])
1471 {
1472 this_proj -> modelgl -> volume_box[i][l][6] -= x;
1473 this_proj -> modelgl -> volume_box[i][l][7] -= y;
1474 this_proj -> modelgl -> volume_box[i][l][8] -= z;
1475 rot = m4_rotation_anti_xyz (this_proj -> modelgl -> volume_box[i][l][3], this_proj -> modelgl -> volume_box[i][l][4], this_proj -> modelgl -> volume_box[i][l][5]);
1476 bini = m4_mul_coord (rot, vec3(this_proj -> modelgl -> volume_box[i][l][6], this_proj -> modelgl -> volume_box[i][l][7], this_proj -> modelgl -> volume_box[i][l][8]));
1477 bini.x -= x;
1478 bini.y -= y;
1479 bini.z -= z;
1480 rot = m4_rotation_xyz (this_proj -> modelgl -> volume_box[i][l][3], this_proj -> modelgl -> volume_box[i][l][4], this_proj -> modelgl -> volume_box[i][l][5]);
1481 bend = m4_mul_coord (rot, bini);
1482 this_proj -> modelgl -> volume_box[i][l][6] = bend.x;
1483 this_proj -> modelgl -> volume_box[i][l][7] = bend.y;
1484 this_proj -> modelgl -> volume_box[i][l][8] = bend.z;
1485 }
1486 }
1487 if (this_proj -> modelgl -> frag_box[i])
1488 {
1489 if (this_proj -> modelgl -> frag_box[i][l])
1490 {
1491 for (j=0; j<this_proj -> coord -> totcoord[2]; j++)
1492 {
1493 rot = m4_rotation_anti_xyz (this_proj -> modelgl -> frag_box[i][l][j][3], this_proj -> modelgl -> frag_box[i][l][j][4], this_proj -> modelgl -> frag_box[i][l][j][5]);
1494 bini = m4_mul_coord (rot, vec3(this_proj -> modelgl -> frag_box[i][l][j][6], this_proj -> modelgl -> frag_box[i][l][j][7], this_proj -> modelgl -> frag_box[i][l][j][8]));
1495 bini.x -= x;
1496 bini.y -= y;
1497 bini.z -= z;
1498 rot = m4_rotation_xyz (this_proj -> modelgl -> frag_box[i][l][j][3], this_proj -> modelgl -> frag_box[i][l][j][4], this_proj -> modelgl -> frag_box[i][l][j][5]);
1499 bend = m4_mul_coord (rot, bini);
1500 this_proj -> modelgl -> frag_box[i][l][j][6] = bend.x;
1501 this_proj -> modelgl -> frag_box[i][l][j][7] = bend.y;
1502 this_proj -> modelgl -> frag_box[i][l][j][8] = bend.z;
1503 }
1504 }
1505 }
1506 }
1507 }
1508 this_proj -> cell.crystal = FALSE;
1509}
1510
1519{
1521 view -> insert_coords = vec3(0.0, 0.0, 0.0);
1522 int shaders[6] = {ATOMS, BONDS, POLYS, RINGS, SELEC, VOLMS};
1524 view -> create_shaders[PICKS] = TRUE;
1525 view -> create_shaders[MDBOX] = TRUE;
1526 view -> create_shaders[LABEL] = TRUE;
1527 view -> create_shaders[MEASU] = TRUE;
1528 update (view);
1529}
1530
1539void free_glwin_spec_data (project * this_proj, int spec)
1540{
1541 int i, j, k;
1542
1543 for (i=0; i<NUM_COLORS; i++)
1544 {
1545 if (this_proj -> modelgl -> colorp[i] != NULL)
1546 {
1547 g_free (this_proj -> modelgl -> colorp[i]);
1548 this_proj -> modelgl -> colorp[i] = NULL;
1549 }
1550 }
1551 for (i=0; i<10; i++)
1552 {
1553 k = (i > 2) ? 1 : spec;
1554 if (i < 2 || i > 3)
1555 {
1556 for (j=0; j<k; j++)
1557 {
1558 if (this_proj -> coord -> geolist[i][j] != NULL)
1559 {
1560 g_free (this_proj -> coord -> geolist[i][j]);
1561 this_proj -> coord -> geolist[i][j] = NULL;
1562 }
1563 }
1564 this_proj -> coord -> geolist[i]=NULL;
1565 }
1566 }
1567 for (i=0; i<spec; i++)
1568 {
1569 if (this_proj -> coord -> partial_geo[i] != NULL) g_free (this_proj -> coord -> partial_geo[i]);
1570 this_proj -> coord -> partial_geo[i] = NULL;
1571 }
1572 g_free (this_proj -> coord -> partial_geo);
1573 this_proj -> coord -> partial_geo = NULL;
1574}
1575
1584void glwin_init_spec_data (project * this_proj, int nspec)
1585{
1586 int i, j, k;
1587 for (i=0; i<NUM_COLORS; i++)
1588 {
1589 this_proj -> modelgl -> colorp[i] = NULL;
1590 this_proj -> modelgl -> colorp[i] = g_malloc (nspec*2*sizeof*this_proj -> modelgl -> colorp[i]);
1591 for (j=0; j<nspec*2; j++)
1592 {
1593 this_proj -> modelgl -> colorp[i][j].a = this_proj -> id;
1594 this_proj -> modelgl -> colorp[i][j].b = i;
1595 this_proj -> modelgl -> colorp[i][j].c = j;
1596 }
1597 }
1598#ifdef GTK3
1599 // GTK3 Menu Action To Check
1600 int l;
1601#endif
1602 for (i=0; i<10; i++)
1603 {
1604 k = (i > 2) ? 1 : nspec;
1605#ifdef GTK3
1606 // GTK3 Menu Action To Check
1607 for (j = 0; j < 2; j++)
1608 {
1609 this_proj -> modelgl -> oglmv[j][i] = NULL;
1610 this_proj -> modelgl -> oglmv[j][i] = g_malloc0 (k*sizeof*this_proj -> modelgl -> oglmv[j][i]);
1611 if (i < 9)
1612 {
1613 this_proj -> modelgl -> oglmc[j][i] = NULL;
1614 this_proj -> modelgl -> oglmc[j][i] = g_malloc0 (k*sizeof*this_proj -> modelgl -> oglmc[j][i]);
1615 }
1616 if (i < 2 || (i > 3 && i < 9))
1617 {
1618 this_proj -> modelgl -> oglmpv[j][i] = NULL;
1619 this_proj -> modelgl -> oglmpv[j][i] = g_malloc0 (k*sizeof*this_proj -> modelgl -> oglmpv[j][i]);
1620 }
1621 for (l=0; l<k; l++)
1622 {
1623 this_proj -> modelgl -> oglmv[j][i][l] = NULL;
1624 if (i < 9) this_proj -> modelgl -> oglmc[j][i][l] = NULL;
1625 if (i < 2 || (i > 3 && i < 9)) this_proj -> modelgl -> oglmpv[j][i][l] = NULL;
1626 }
1627 }
1628#endif
1629 if (i < 2 || i > 3)
1630 {
1631 this_proj -> coord -> geolist[i] = g_malloc0 (k*sizeof*this_proj -> coord -> geolist[i]);
1632 for (j=0; j<k; j++)
1633 {
1634 this_proj -> coord -> geolist[i][j] = NULL;
1635 }
1636 }
1637 }
1638 this_proj -> coord -> partial_geo = g_malloc0 (nspec*sizeof*this_proj -> coord -> partial_geo);
1639 for (i=0; i<nspec; i++) this_proj -> coord -> partial_geo[i] = NULL;
1640}
1641
1649void init_glwin (glwin * view)
1650{
1651 project * this_proj = get_project_by_id(view -> proj); // Have to be the active project
1652 view -> anim = g_malloc0 (sizeof*view -> anim);
1653 snapshot * snap = g_malloc0 (sizeof*snap);
1654 view -> anim -> first = snap;
1655 view -> anim -> last = snap;
1656 init_img (this_proj);
1657 init_camera (this_proj, FALSE);
1658 view -> mouseStatus = RELEASED;
1659 view -> mouseAction = ANALYZE;
1660 // Warning, if not centered at start-up, dmtx could fail
1661 if (! this_proj -> cell.crystal) center_molecule (this_proj);
1662
1663 view -> bonds = allocdint (this_proj -> steps, 2);
1664 view -> bondid = g_malloc0 (this_proj -> steps*sizeof*view -> bondid);
1665 view -> clones = g_malloc0 (this_proj -> steps*sizeof*view -> clones);
1666 int i;
1667 for (i=0; i < this_proj -> steps; i++)
1668 {
1669 view -> bondid[i] = g_malloc0 (2*sizeof*view -> bondid[i]);
1670 view -> clones[i] = NULL;
1671 }
1672
1673 // Data that depends on the number of chemical species
1674 glwin_init_spec_data (this_proj, (this_proj -> nspec) ? this_proj -> nspec : 1);
1675
1676 view -> stop = TRUE;
1677 view -> speed = 100;
1678 view -> zoom_factor = ZOOM_FACTOR;
1679 view -> mode = ANALYZE;
1680 view -> selection_mode = ATOMS;
1681 // On normal motion and copy rebuild:
1682 view -> rebuild[0][0] = view -> rebuild[1][0] = (this_proj -> steps > 1) ? FALSE : TRUE;
1683 view -> init = TRUE;
1684 init_opengl (view);
1685 init_shaders (view);
1686 this_proj -> initgl = TRUE;
1687#ifdef GTK4
1688 update_menu_bar (view);
1689#endif
1690}
1691
1699GError * init_gtk_gl_area (GtkGLArea * area)
1700{
1701 if (area == NULL)
1702 {
1703 area = (GtkGLArea *)gtk_gl_area_new ();
1704 }
1705 else
1706 {
1707 gtk_gl_area_make_current (area);
1708 }
1709 gtk_gl_area_set_has_depth_buffer (area, TRUE);
1710 gtk_gl_area_set_has_stencil_buffer (area, TRUE);
1711 return gtk_gl_area_get_error (area);
1712}
1713
1714#ifdef GTKGLAREA
1723G_MODULE_EXPORT void on_realize (GtkGLArea * area, gpointer data)
1724#else
1733G_MODULE_EXPORT void on_realize (GtkWidget * widg, gpointer data)
1734#endif
1735{
1736 glwin * view = (glwin *)data;
1737 GError * err;
1738#ifdef GTKGLAREA
1739 err = init_gtk_gl_area (area);
1740 if (err == NULL)
1741 {
1742#else
1743 GdkWindow * xwin = gtk_widget_get_window (view -> plot);
1744 GLint attr_list[] = {GLX_DOUBLEBUFFER,
1745 GLX_RGBA,
1746 GLX_DEPTH_SIZE, 1,
1747 GLX_RED_SIZE, 1,
1748 GLX_GREEN_SIZE, 1,
1749 GLX_BLUE_SIZE, 1,
1750 None};
1751 XVisualInfo * visualinfo = glXChooseVisual (GDK_WINDOW_XDISPLAY (xwin),
1752 gdk_screen_get_number (gdk_window_get_screen (xwin)), attr_list);
1753 view -> glcontext = glXCreateContext (GDK_WINDOW_XDISPLAY (xwin), visualinfo, NULL, TRUE);
1754 g_free (visualinfo);
1755 if (glXMakeCurrent (GDK_WINDOW_XDISPLAY (xwin), GDK_WINDOW_XID (xwin), view -> glcontext))
1756 {
1757#endif
1758 init_glwin (view);
1759 }
1760 else
1761 {
1762#ifdef GTK3
1763#ifdef GTKGLAREA
1764#ifndef G_OS_WIN32
1765 if (atomes_visual)
1766 {
1767 atomes_visual = 0;
1768 goto end;
1769 }
1770#endif
1771#endif
1772#endif
1773 gchar * errm = g_strdup_printf ("Impossible to initialize the OpenGL 3D rendering ! \n %s\n", err -> message);
1774 g_error_free (err);
1775 show_error (errm, 0, MainWindow);
1776 g_free (errm);
1777 atomes_visual = -1;
1778 }
1779#ifdef GTK3
1780 end:;
1781#endif
1782}
1783
1784#ifdef GTKGLAREA
1794G_MODULE_EXPORT gboolean on_expose (GtkGLArea * area, GdkGLContext * context, gpointer data)
1795#else
1805G_MODULE_EXPORT gboolean on_expose (GtkWidget * widg, cairo_t * cr, gpointer data)
1806#endif
1807{
1808 glwin * view = (glwin *) data;
1809#ifdef GTK3
1810 GdkEvent * event = gtk_get_current_event ();
1811 if (event && event -> type == GDK_EXPOSE && ((GdkEventExpose *)event) -> count > 0) return TRUE;
1812#endif
1813#ifdef GTKGLAREA
1814 render_this_gl_window (view, area, 0, 0.0, 0.0);
1815#else
1816 render_this_gl_window (view, widg, 0);
1817#endif
1818 return TRUE;
1819}
Binding to the Fortran90 subroutines.
double oglmax_()
gchar * axis[3]
Definition w_axis.c:65
integer(kind=c_int) function chemistry()
Definition chemistry.F90:22
color colorp[64]
double scale(double axe)
find appropriate major tick spacing based on axis length
Definition curve.c:204
ColRGBA col
Definition d_measures.c:77
int atoms[NUM_STYLES][2]
int bonds[NUM_STYLES][2]
float val
Definition dlp_init.c:117
void init_default_shaders(glwin *view)
re-initialize the default OpenGL shaders
dint rep
Definition dlp_edit.c:2239
int ** allocdint(int xal, int yal)
allocate an int ** pointer
Definition global.c:342
double pi
Definition global.c:195
struct timespec start_time
Definition global.c:191
gboolean * allocbool(int val)
allocate a gboolean * pointer
Definition global.c:266
double ** allocddouble(int xal, int yal)
allocate a double ** pointer
Definition global.c:487
double * allocdouble(int val)
allocate a double * pointer
Definition global.c:471
GtkWidget * MainWindow
Definition global.c:214
int * allocint(int val)
allocate an int * pointer
Definition global.c:326
gboolean object_motion
Definition global.c:186
double get_calc_time(struct timespec start, struct timespec stop)
get calculation time in s
Definition global.c:636
int atomes_visual
Definition global.c:165
struct timespec stop_time
Definition global.c:192
Global variable declarations Global convenience function declarations Global data structure defin...
glwin * active_glwin
Definition project.c:53
project * proj
#define CHEM_R
Definition global.h:271
#define min(a, b)
Definition global.h:75
#define CHEM_Z
Definition global.h:269
project * active_project
Definition project.c:47
project * get_project_by_id(int p)
get project pointer using id number
Definition project.c:120
void transform(glwin *view, double aspect)
transform the OpenGL window
Definition glview.c:456
void update_bonds_(int *bd, int *stp, int *bdim, int bda[*bdim], int bdb[*bdim], double *x, double *y, double *z)
update bonding information from Fortran90
Definition glview.c:330
int action_atoms_from_project(project *this_proj, atom_search *asearch, gboolean visible)
apply atom edition action to project (motion, remove, replace, insert, random move)
vec3_t get_arc_ball_vector(glwin *view, int x, int y)
Definition arcball.c:46
G_MODULE_EXPORT void on_realize(GtkWidget *widg, gpointer data)
realize event for the OpenGL widget
Definition glview.c:1733
atomic_object * create_object_from_frag_mol(project *this_proj, int coord, int geo, atom_search *remove)
create object from a fragment or a molecule
G_MODULE_EXPORT void on_glwin_pointer_motion(GtkEventControllerMotion *motc, gdouble x, gdouble y, gpointer data)
handle mouse motion event in the OpenGL window GTK4
Definition glview.c:724
GLfloat ** allocdGLfloat(int xal, int yal)
allocate a GLfloat ** pointer
Definition glview.c:161
void render_this_gl_window(glwin *view, GtkWidget *widg, gint button)
render the OpenGL window
Definition glview.c:757
GLuint ** allocdgluint(int xal, int yal)
allocate a GLuint ** pointer
Definition glview.c:139
void glwin_button_event(double event_x, double event_y, guint event_button, guint event_type, guint32 event_time, gpointer data)
handle mouse button event on the OpenGL window
Definition glview.c:887
vec4_t old_rotation_quaternion
Definition arcball.c:44
void update_labels(glwin *view)
update labels (on representation data update)
Definition m_rep.c:83
void arc_ball_rotation(glwin *view, int x, int y)
Perform arcball rotation.
Definition arcball.c:73
void save_rotation_quaternion(glwin *view)
save the rotation quaternion of the last image
Definition glview.c:537
void update(glwin *view)
update the rendering of the OpenGL window
Definition glview.c:439
vec3_t arc_ball_init
Definition arcball.c:42
void init_opengl(glwin *view)
initialize OpenGL rendering parameters for a glwin pointer
Definition glview.c:1389
void prepare_atom_edition(gpointer data, gboolean visible)
prepare atom edition
Definition atom_edit.c:459
GError * init_gtk_gl_area(GtkGLArea *area)
initialize a GtkGLArea, return error if any
Definition glview.c:1699
void init_img(project *this_proj)
initialize an image data structure
Definition glview.c:1276
GLenum ogl_texture
Definition glview.c:114
Light init_light_source(int type, float val, float vbl)
initialize a light source
Definition w_advance.c:324
void free_glwin_spec_data(project *this_proj, int spec)
free the memory used by the chemical species related data in a glwin data structure
Definition glview.c:1539
gl_pop_info to_pop
Definition glview.c:873
void glwin_init_spec_data(project *this_proj, int nspec)
initialize the glwin chemical species related pointers
Definition glview.c:1584
G_MODULE_EXPORT void on_lib_button_released(GtkGesture *gesture, int n_press, double x, double y, gpointer data)
handle mouse button release event on the molecular library OpenGL window (limited interaction)
Definition glview.c:867
void zoom(glwin *view, int delta)
zoom in or zoom out in the OpenGL window
Definition glview.c:1003
atom_search * allocate_atom_search(int proj, int action, int searchid, int tsize)
allocate atom search data structure
Definition atom_edit.c:392
G_MODULE_EXPORT void on_lib_button_pressed(GtkGesture *gesture, int n_press, double x, double y, gpointer data)
handle mouse button press event on the molecular library OpenGL window (limited interaction)
Definition glview.c:851
void translate(project *this_proj, int status, int axis, vec3_t trans)
translate
Definition atom_move.c:230
G_MODULE_EXPORT void on_glwin_button_released(GtkGesture *gesture, int n_press, double x, double y, gpointer data)
mouse button released signal on the OpenGL window
Definition glview.c:988
void update_atom_neighbors_(int *stp, int *at, int *nv)
update an atom number of neighbors from Fortran90
Definition glview.c:404
void glwin_lib_pressed(double x, double y, guint event_type, guint event_button, gpointer data)
handle mouse button event on the molecular library OpenGL window
Definition glview.c:800
void init_camera(project *this_proj, int get_depth)
intialize the OpenGL camera settings
Definition glview.c:1129
G_MODULE_EXPORT void on_glwin_button_pressed(GtkGesture *gesture, int n_press, double x, double y, gpointer data)
mouse button pressed signal on the OpenGL window
Definition glview.c:972
void edit_for_motion(glwin *view)
if edition mode is one some steps are required
Definition glview.c:554
void rotate_quat(project *this_proj, vec4_t q, int status, int axis)
rotate using quaternion
Definition atom_move.c:269
void process_the_hits(glwin *view, gint event_button, double ptx, double pty)
process a mouse click
Definition selection.c:590
void motion(glwin *view, gint x, gint y, GdkModifierType state)
mouse motion in the OpenGL window
Definition glview.c:620
ColRGBA set_default_color(int z)
pick the default color for an atom
Definition glview.c:187
void set_img_lights(project *this_proj, image *img)
initialize lightning for an image data structure
Definition glview.c:1249
GLuint * allocgluint(int val)
allocate a GLuint * pointer
Definition glview.c:123
vec3_t get_bary(project *this_proj, int status)
get barycenter of atomic coordinates
Definition atom_move.c:170
const float light_pos[MAX_LIGHTS][4]
Definition glview.c:175
void center_this_molecule(glwin *view)
center atomic coordinates around (0,0,0) and refresh shaders
Definition glview.c:1518
void rotate_x_y(glwin *view, double angle_x, double angle_y)
rotate the OpenGL camera
Definition glview.c:1078
void init_glwin(glwin *view)
initialize a glwin pointer
Definition glview.c:1649
void reshape(glwin *view, int width, int height)
reshape (resize) the OpenGL window
Definition glview.c:513
void center_molecule(project *this_proj)
center atomic coordinates around (0,0,0)
Definition glview.c:1437
gboolean is_GLExtension_Supported(const char *extension)
test if this GLExtension is support
Definition glview.c:1370
G_MODULE_EXPORT gboolean on_glwin_pointer_scoll(GtkEventControllerScroll *event, gdouble dx, gdouble dy, gpointer data)
handle mouse scroll event on the OpenGL window
Definition glview.c:1052
G_MODULE_EXPORT gboolean on_expose(GtkWidget *widg, cairo_t *cr, gpointer data)
OpenGL rendering widget expose event callback GTK3.
Definition glview.c:1805
void update_this_neighbor_(int *stp, int *at, int *iv, int *nv)
update atom neighbor list from Fortran90
Definition glview.c:423
void image_init_spec_data(image *img, project *this_proj, int nsp)
initialize the chemical species related pointers in an image data structure
Definition glview.c:1187
void sort(int dim, int *tab)
sort, nim to max, a table by integer value
Definition glview.c:380
Variable declarations related to the OpenGL window Function declarations related to the OpenGL wind...
image * plot
Definition ogl_draw.c:66
@ BETTER_TEXT
Definition glview.h:234
#define DEFAULT_LIGHTNING
Default OpenGL material ligthning.
Definition glview.h:49
atom_search * free_this_search_data(atom_search *this_search)
free atom search data structure
Definition popup.c:284
#define ZOOM_MAX
Maximum value for the OpenGL zoom factor.
Definition glview.h:125
#define DEFAULT_AMBIANT_OCCLUSION
Default OpenGL material ambiant occlusion.
Definition glview.h:64
@ BOTTOM_RIGHT
Definition glview.h:207
#define DEFAULT_GAMMA_CORRECTION
Default OpenGL material gamma correction.
Definition glview.h:69
#define ZOOM_FACTOR
Default value for the OpenGL zoom factor.
Definition glview.h:120
void draw(glwin *view)
main drawing subroutine for the OpenGL window
Definition ogl_draw.c:461
void re_create_md_shaders(int nshaders, int shaders[nshaders], project *this_proj)
re-initialize some MD dependent OpenGL shaders
action
Definition glview.h:189
gboolean pick
void popup_main_menu(glwin *view, double ptx, double pty)
create the OpenGL window popup menu
Definition popup.c:4132
void init_shaders(glwin *view)
initialize all the OpenGL shaders
#define CAMERA_ANGLE_X
Default value for the OpenGL camera pitch in °
Definition glview.h:100
#define MAX_LIGHTS
Maximum number of light sources.
Definition glview.h:80
@ MOTION
Definition glview.h:159
@ ANALYZE
Definition glview.h:157
@ EDITION
Definition glview.h:158
#define DEFAULT_OPACITY
Default OpenGL opacity.
Definition glview.h:74
render
Definition glview.h:182
@ FILL
Definition glview.h:183
void popup_selection(glwin *view, double ptx, double pty, int se, int pe, int ai, int bi, int ac)
create the contextual popup menu, right click on atom or bond
Definition popup.c:3667
@ PERSPECTIVE
Definition glview.h:152
@ ORTHOGRAPHIC
Definition glview.h:151
@ RELEASED
Definition glview.h:200
@ CLICKED
Definition glview.h:199
#define DEFAULT_SIZE
Definition glview.h:45
#define DEFAULT_ROUGHNESS
Default OpenGL material roughness.
Definition glview.h:59
#define DEFAULT_METALLIC
Default OpenGL material metallic.
Definition glview.h:54
@ SYMBOL_AND_NUM
Definition glview.h:217
#define ZOOM
Default value for the OpenGL zoom.
Definition glview.h:115
#define DEFAULT_STYLE
Default OpenGL style: ball and stick.
Definition glview.h:43
vec3_t get_insertion_coordinates(glwin *view)
get the insertion coordinates to insert object in the 3D window
Definition glwindow.c:646
#define QUALITY
Default OpenGL quality (number of polygons)
Definition glview.h:39
#define CAMERA_ANGLE_Y
Default value for the OpenGL camera heading in °
Definition glview.h:105
@ DISPL
Definition glview.h:224
@ BALL_AND_STICK
Definition glview.h:173
@ CYLINDERS
Definition glview.h:177
@ NONE
Definition glview.h:172
#define FILLED_STYLES
Definition glwin.h:105
#define BOX
Definition glwin.h:54
#define NUM_COLORS
Definition glwin.h:65
#define AXIS
Definition glwin.h:55
shaders
The different types of shaders in the atomes program.
Definition glwin.h:88
@ BONDS
Definition glwin.h:90
@ PICKS
Definition glwin.h:97
@ LABEL
Definition glwin.h:98
@ VOLMS
Definition glwin.h:102
@ POLYS
Definition glwin.h:92
@ SELEC
Definition glwin.h:91
@ MDBOX
Definition glwin.h:93
@ MEASU
Definition glwin.h:99
@ ATOMS
Definition glwin.h:89
@ RINGS
Definition glwin.h:96
#define GL_COLOR_SUM_EXT
Definition glwin.h:39
#define GL_TEXTURE_RECTANGLE_ARB
Definition glwin.h:51
GLXContext glcontext
GdkWindow * xwin
Function declarations to handle the atomic coordination data.
void set_advanced_bonding_menus(glwin *view)
void show_error(char *error, int val, GtkWidget *win)
show error message
Definition interface.c:293
Messaging function declarations.
double z
Definition ogl_draw.c:57
double y
Definition ogl_draw.c:57
double x
Definition ogl_draw.c:57
Function declarations for reading atomes project file Function declarations for saving atomes proje...
float blue
Definition global.h:118
float alpha
Definition global.h:119
float red
Definition global.h:116
float green
Definition global.h:117
Definition glwin.h:181
int action
Definition glview.h:369
double y
Definition glview.h:370
int pts[5]
Definition glview.h:371
double x
Definition glview.h:370
Definition glwin.h:875
Definition glwin.h:277
coord_info * coord
Definition global.h:908
float y
Definition math_3d.h:130
float x
Definition math_3d.h:130
float z
Definition math_3d.h:130
float w
Definition math_3d.h:149
float y
Definition math_3d.h:149
float x
Definition math_3d.h:149
float z
Definition math_3d.h:149
GtkWidget * axis_title
Definition tab-4.c:101
int status
Definition w_advance.c:160
GtkWidget * img
Definition workspace.c:70