atomes 1.1.14
atomes: an atomic scale modeling tool box
Loading...
Searching...
No Matches
d_selection.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
24/*
25* This file: 'd_selection.c'
26*
27* Contains:
28*
29
30 - The functions to prepare the OpenGL rendering of the selected: atom(s), clone(s), bond(s) and clone bond(s)
31 - The functions to prepare the unique color rendering for picking the atom(s) and bond(s)
32
33*
34* List of functions:
35
36 int find_selected_clone_vertices (int style, int at);
37 int find_selected_bond_vertices (int sty, int at, int sp, int bi, int pi, int cap);
38 int get_clone_id (int at, int bt);
39 int render_selected (int style, gboolean cylinder, int caps, int bonds, int ncaps, int type, int clone, int shader);
40 int render_picked (int style, gboolean cylinder, int caps, int bonds, int ncaps, int type, int clone, int shader);
41 int prepare_selection_shaders (int style, int shaders, int clone, int type, gboolean do_bonds);
42 int check_selection (int style, int type);
43 int create_selection_lists ();
44 int create_pick_lists ();
45
46 void setup_selected_clone_vertices (int style, int at, int pi, float * vertices);
47 void prepare_selected_bond (int sty, int cap, int bi, int pi, atom * at, atom * bt, float * vertices);
48 void setup_all_selected_bond_vertices (int sty, int cap, int bi, int at, int sb, int pi, float * vertices);
49 void prepare_selected (int style, gboolean cylinder, int clone, int type);
50 void prepare_picked (int style, gboolean cylinder, int clone, int type);
51
52*/
53
54#include "global.h"
55#include "glview.h"
56#include "dlp_field.h"
57
58extern void create_atom_lists (gboolean to_pick);
59extern int create_bond_lists (gboolean to_pick);
60extern object_3d * draw_sphere (int quality);
61extern object_3d * draw_cylinder (int quality, float ra, float rb);
62extern object_3d * draw_cylinder_cap (int quality, float rad, gboolean picked);
63extern void setup_line_vertice (float * vertices, vec3_t pos, ColRGBA col, float alpha);
64extern void setup_sphere_vertice (float * vertices, vec3_t pos, ColRGBA col, float rad, float alpha);
65extern void setup_cylinder_vertice (float * vertices, vec3_t pos_a, vec3_t pos_b, ColRGBA col, float rad, float alpha);
66extern void setup_triangles (float * vertices, vec3_t sa, vec3_t sb, vec3_t sc);
67extern float get_bond_radius (int sty, int ac, int at, int b, int sel);
68extern void setup_this_atom (int style, gboolean to_pick, int picked, atom * at, int ac, float * vert, float al);
69extern void prepare_clone (int style, gboolean to_pick, int picked, atom at, atom bt, float x, float y, float z, float * vertices);
70extern void setup_this_bond (int sty, gboolean to_pick, gboolean picked, int cap, int bi, int pi, atom * at, atom * bt, float al, float * vertices);
71
82void setup_selected_clone_vertices (int style, int at, int pi, float * vertices)
83{
84 int i, j;
85 gboolean doit;
86 distance d;
87 for (i=0; i < proj_gl -> atoms[step][at].numv; i++)
88 {
89 j = proj_gl -> atoms[step][at].vois[i];
90 d = distance_3d (cell_gl, (cell_gl -> npt) ? step : 0, & proj_gl -> atoms[step][at], & proj_gl -> atoms[step][j]);
91 if (d.pbc)
92 {
93 if (in_movie_encoding && plot -> at_data != NULL)
94 {
95 doit = (plot -> at_data[at].pick[pi] && plot -> at_data[at].style == style) ? TRUE : FALSE;
96 }
97 else
98 {
99 doit = (proj_gl -> atoms[0][at].pick[pi] && proj_gl -> atoms[0][at].style == style) ? TRUE : FALSE;
100 }
101 if (doit)
102 {
103 prepare_clone (style, FALSE, pi+1,
104 proj_gl -> atoms[step][at],
105 proj_gl -> atoms[step][j],
106 d.x,
107 d.y,
108 d.z, vertices);
109 }
110 }
111 }
112}
113
122int find_selected_clone_vertices (int style, int at)
123{
124 int i, j, k;
125 gboolean doit = FALSE;
126 distance d;
127 if (in_movie_encoding && plot -> at_data != NULL)
128 {
129 if (plot -> at_data[at].show[1] && plot -> at_data[at].style == style) doit = TRUE;
130 }
131 else
132 {
133 if (proj_gl -> atoms[step][at].show[1] && proj_gl -> atoms[step][at].style == style) doit = TRUE;
134 }
135 k = 0;
136 if (doit)
137 {
138 for (i=0; i < proj_gl -> atoms[step][at].numv; i++)
139 {
140 j = proj_gl -> atoms[step][at].vois[i];
141 d = distance_3d (cell_gl, (cell_gl -> npt) ? step : 0, & proj_gl -> atoms[step][at], & proj_gl -> atoms[step][j]);
142 if (d.pbc) k ++;
143 }
144 }
145 return k;
146}
147
160int find_selected_bond_vertices (int sty, int at, int sp, int bi, int pi, int cap)
161{
162 int i, j, k, l, m, n;
164 gboolean show_a, show_b, show_c, show_d;
165 l = 0;
166 if (in_movie_encoding && plot -> at_data != NULL)
167 {
168 show_a = plot -> at_data[at].show[bi];
169 show_c = plot -> at_data[at].pick[pi];
170 m = plot -> at_data[at].style;
171 }
172 else
173 {
174 show_a = proj_gl -> atoms[step][at].show[bi];
175 show_c = proj_gl -> atoms[step][at].pick[pi];
176 m = proj_gl -> atoms[step][at].style;
177 }
178 if (show_a && show_c && m == sty)
179 {
180 for (i=0; i<proj_gl -> atoms[step][at].numv; i++)
181 {
182 j = proj_gl -> atoms[step][at].vois[i];
183 if (in_movie_encoding && plot -> at_data != NULL)
184 {
185 show_b = plot -> at_data[j].show[bi];
186 show_d = plot -> at_data[j].pick[pi];
187 n = plot -> at_data[j].style;
188 k = proj_gl -> atoms[0][j].sp;
189 }
190 else
191 {
192 show_b = proj_gl -> atoms[step][j].show[bi];
193 show_d = proj_gl -> atoms[step][j].pick[pi];
194 n = proj_gl -> atoms[step][j].style;
195 k = proj_gl -> atoms[step][j].sp;
196 }
197 if (sp == -1 || k == sp)
198 {
199 dist = distance_3d (cell_gl, (cell_gl -> npt) ? step : 0, & proj_gl -> atoms[step][at], & proj_gl -> atoms[step][j]);
200 if ((bi && dist.pbc) ||(! bi && ! dist.pbc))
201 {
202 if (cap)
203 {
204 if ((! show_b || ! show_d) || (m != n)) l += 1 + bi;
205 }
206 else
207 {
208 l += 1 + bi;
209 }
210 }
211 }
212 }
213 }
214 return 2*l;
215}
216
225int get_clone_id (int at, int bt)
226{
227 int i, j, k;
228 for (i=0; i < wingl -> bonds[step][1]; i++)
229 {
230 j = wingl -> bondid[step][1][i][0];
231 k = wingl -> bondid[step][1][i][1];
232 if ((j == at && k == bt) || (j == bt && k == at)) return i;
233 }
234 return -1;
235}
236
250void prepare_selected_bond (int sty, int cap, int bi, int pi, atom * at, atom * bt, float * vertices)
251{
252 if (bi == 0)
253 {
254 setup_this_bond (sty, FALSE, TRUE, cap, bi, pi, at, bt, 1.0, vertices);
255 }
256 else
257 {
258 atom * tmp_a, * tmp_b;
259 distance d = distance_3d (cell_gl, (cell_gl -> npt) ? step : 0, at, bt);
260
261 tmp_a = duplicate_atom (at);
262 tmp_b = duplicate_atom (at);
263 tmp_a -> pick[pi] = bt -> pick[pi];
264 tmp_a -> style = bt -> style;
265 tmp_a -> sp = bt -> sp + proj_sp;
266 tmp_b -> sp += proj_sp;
267 tmp_a -> x -= d.x;
268 tmp_a -> y -= d.y;
269 tmp_a -> z -= d.z;
270 setup_this_bond (sty, FALSE, TRUE, cap, bi, pi, tmp_b, tmp_a, 0.5, vertices);
271 g_free (tmp_a);
272 g_free (tmp_b);
273
274 tmp_a = duplicate_atom (bt);
275 tmp_b = duplicate_atom (bt);
276 tmp_a -> pick[pi] = at -> pick[pi];
277 tmp_a -> style = at -> style;
278 tmp_a -> sp = at -> sp + proj_sp;
279 tmp_b -> sp += proj_sp;
280 tmp_a -> id = at -> id;
281 tmp_a -> x += d.x;
282 tmp_a -> y += d.y;
283 tmp_a -> z += d.z;
284 setup_this_bond (sty, FALSE, TRUE, cap, bi, pi, tmp_a, tmp_b, 0.5, vertices);
285 g_free (tmp_a);
286 g_free (tmp_b);
287 }
288}
289
303void setup_all_selected_bond_vertices (int sty, int cap, int bi, int at, int sb, int pi, float * vertices)
304{
305 int i, j, k, l, m;
307 gboolean show_a, show_b, show_c, show_d;
308 if (in_movie_encoding && plot -> at_data != NULL)
309 {
310 show_a = plot -> at_data[at].show[bi];
311 show_c = plot -> at_data[at].pick[pi];
312 l = plot -> at_data[at].style;
313 }
314 else
315 {
316 show_a = proj_gl -> atoms[step][at].show[bi];
317 show_c = proj_gl -> atoms[step][at].pick[pi];
318 l = proj_gl -> atoms[step][at].style;
319 }
320 if (show_a && show_c && l == sty)
321 {
322 for (i=0; i<proj_gl -> atoms[step][at].numv; i++)
323 {
324 j = proj_gl -> atoms[step][at].vois[i];
325 if (in_movie_encoding && plot -> at_data != NULL)
326 {
327 show_b = plot -> at_data[j].show[bi];
328 show_d = plot -> at_data[j].pick[pi];
329 m = plot -> at_data[j].style;
330 k = proj_gl -> atoms[0][j].sp;
331 }
332 else
333 {
334 show_b = proj_gl -> atoms[step][j].show[bi];
335 show_d = proj_gl -> atoms[step][j].pick[pi];
336 m = proj_gl -> atoms[step][j].style;
337 k = proj_gl -> atoms[step][j].sp;
338 }
339 if (sb == -1 || k == sb)
340 {
341 dist = distance_3d (cell_gl, (cell_gl -> npt) ? step : 0, & proj_gl -> atoms[step][at], & proj_gl -> atoms[step][j]);
342 if ((bi && dist.pbc) ||(! bi && ! dist.pbc))
343 {
344 if (cap)
345 {
346 if ((! show_b || ! show_d) || (l != m))
347 {
348 prepare_selected_bond (sty, cap, bi, pi, & proj_gl -> atoms[step][at], & proj_gl -> atoms[step][j], vertices);
349 }
350 }
351 else
352 {
353 prepare_selected_bond (sty, cap, bi, pi, & proj_gl -> atoms[step][at], & proj_gl -> atoms[step][j], vertices);
354 }
355 }
356 }
357 }
358 }
359}
360
364int *** nbonds[NUM_STYLES][2];
365
376void prepare_selected (int style, gboolean cylinder, int clone, int type)
377{
378 int h, i, j;
380 npbds[style][type] = npcps[style][type] = 0;
381 if (cylinder)
382 {
383 sel = plot -> selected[type] -> first;
384 while (sel)
385 {
386 for (i=0; i<clone; i++)
387 {
388 npbds[style][type] += find_selected_bond_vertices (style-1, sel -> id, -1, i, type, 0);
389 npcps[style][type] += find_selected_bond_vertices (style-1, sel -> id, -1, i, type, 1);
390 }
391 sel = sel -> next;
392 }
393 bonds[style][type] = (npbds[style][type]) ? 1 : 0;
394 caps[style][type] = (npcps[style][type]) ? 1 : 0;
395 }
396 else
397 {
398 sel = plot -> selected[type] -> first;
399 while (sel)
400 {
401 for (i=0; i<clone; i++)
402 {
403 for (j=0; j<proj_sp; j++)
404 {
405 nbonds[style][type][i][sel -> sp][j] += find_selected_bond_vertices (style-1, sel -> id, j, i, type, 0);
406 }
407 }
408 sel = sel -> next;
409 }
410 for (h=0; h<clone; h++)
411 {
412 for (i=0; i<proj_sp; i++)
413 {
414 for (j=0; j<proj_sp; j++)
415 {
416 npbds[style][type] += nbonds[style][type][h][i][j];
417 npcps[style][type] += (nbonds[style][type][h][i][j]) ? 1 : 0;
418 }
419 }
420 }
421 bonds[style][type] = npcps[style][type];
422 caps[style][type] = 0;
423 }
424}
425
436void prepare_picked (int style, gboolean cylinder, int clone, int type)
437{
438 int h, i, j;
439 npbds[style][type] = npcps[style][type] = 0;
440 if (cylinder)
441 {
442 for (i=0; i<proj_at; i++)
443 {
444 if (proj_gl -> atoms[0][i].pick[type])
445 {
446 for (h=0; h<clone; h++)
447 {
448 npbds[style][type] += find_selected_bond_vertices (style-1, i, -1, h, type, 0);
449 npcps[style][type] += find_selected_bond_vertices (style-1, i, -1, h, type, 1);
450 }
451 }
452 }
453 bonds[style][type] = (npbds[style][type]) ? 1 : 0;
454 caps[style][type] = (npcps[style][type]) ? 1 : 0;
455 }
456 else
457 {
458 for (i=0; i<proj_at; i++)
459 {
460 if (proj_gl -> atoms[0][i].pick[type])
461 {
462 for (h=0; h<clone; h++)
463 {
464 for (j=0; j<proj_sp; j++)
465 {
466 nbonds[style][type][h][proj_gl -> atoms[0][i].sp][j] += find_selected_bond_vertices (style-1, i, j, h, type, 0);
467 }
468 }
469 }
470 }
471 for (h=0; h<clone; h++)
472 {
473 for (i=0; i<proj_sp; i++)
474 {
475 for (j=0; j<proj_sp; j++)
476 {
477 npbds[style][type] += nbonds[style][type][h][i][j];
478 npcps[style][type] += (nbonds[style][type][h][i][j]) ? 1 : 0;
479 }
480 }
481 }
482 bonds[style][type] = npcps[style][type];
483 caps[style][type] = 0;
484 }
485}
486
501int render_selected (int style, gboolean cylinder, int caps, int bonds, int ncaps, int type, int clone, int shader)
502{
503 int h, i, j, k, l;
505 object_3d * cyl, * cap;
506 if (cylinder)
507 {
508 cyl = draw_cylinder (plot -> quality, 1.0, 1.0);
509 cyl -> num_instances = (bonds/2) * (plot -> extra_cell[0]+1)*(plot -> extra_cell[1]+1)*(plot -> extra_cell[2]+1);
510 cyl -> inst_buffer_size = CYLI_BUFF_SIZE;
511 cyl -> instances = allocfloat (CYLI_BUFF_SIZE*cyl -> num_instances);
512 if (caps)
513 {
514 cap = draw_cylinder_cap (plot -> quality, 1.0, TRUE);
515 cap -> num_instances = (ncaps/2) * (plot -> extra_cell[0]+1)*(plot -> extra_cell[1]+1)*(plot -> extra_cell[2]+1);
516 cap -> inst_buffer_size = CAPS_BUFF_SIZE;
517 cap -> instances = allocfloat (CAPS_BUFF_SIZE*cap -> num_instances);
518 }
519 for (h=0; h<caps+1; h++)
520 {
521 nbs = 0;
522 for (i=0; i<clone; i++)
523 {
524 sel = plot -> selected[type] -> first;
525 for (j=0; j< plot -> selected[type] -> selected; j++)
526 {
527 for (k=0; k<proj_sp; k++)
528 {
529 setup_all_selected_bond_vertices (style-1, h, i, sel -> id, k, type, (h == 0) ? cyl -> instances: cap -> instances);
530 }
531 if (sel -> next != NULL) sel = sel -> next;
532 }
533 }
534 }
535 l = 1;
536 wingl -> ogl_glsl[SELEC][step][shader] = init_shader_program (SELEC, GLSL_CYLINDERS, cylinder_vertex, NULL, full_color, GL_TRIANGLE_STRIP, 6, 1, cylinder, cyl);
537 g_free (cyl);
538 if (caps)
539 {
540 l ++;
541 wingl -> ogl_glsl[SELEC][step][shader+1] = init_shader_program (SELEC, GLSL_CAPS, cap_vertex, NULL, full_color, GL_TRIANGLE_FAN, 5, 1, cylinder, cap);
542 g_free (cap);
543 }
544 }
545 else
546 {
547 l = 0;
548 for (h=0; h<clone; h++)
549 {
550 for (i=0; i<proj_sp; i++)
551 {
552 for (j=0; j<proj_sp; j++)
553 {
554 if (nbonds[style][type][h][i][j])
555 {
556 cyl = g_malloc0 (sizeof*cyl);
557 cyl -> vert_buffer_size = LINE_BUFF_SIZE;
558 cyl -> num_vertices = nbonds[style][type][h][i][j] * (plot -> extra_cell[0]+1)*(plot -> extra_cell[1]+1)*(plot -> extra_cell[2]+1);
559 cyl -> vertices = allocfloat (cyl -> vert_buffer_size*cyl -> num_vertices);
560 nbs = 0;
561 sel = plot -> selected[type] -> first;
562 for (k=0; k< plot -> selected[type] -> selected; k++)
563 {
564 if (sel -> sp == i)
565 {
566 setup_all_selected_bond_vertices (style-1, 0, h, sel -> id, j, type, cyl -> vertices);
567 }
568 if (sel -> next != NULL) sel = sel -> next;
569 }
570 wingl -> ogl_glsl[SELEC][step][shader+l] = init_shader_program (SELEC, GLSL_LINES, line_vertex, NULL, line_color, GL_LINES, 2, 1, cylinder, cyl);
571 wingl -> ogl_glsl[SELEC][step][shader+l] -> line_width = get_bond_radius (style, h, i+proj_sp*h, j+proj_sp*h, TRUE);
572 g_free (cyl);
573 l++;
574 }
575 }
576 }
577 }
578 }
579 return l;
580}
581
596int render_picked (int style, gboolean cylinder, int caps, int bonds, int ncaps, int type, int clone, int shader)
597{
598 int h, i, j, k, l;
599 object_3d * cyl, * cap;
600
601 if (cylinder)
602 {
603 cyl = draw_cylinder (plot -> quality, 1.0, 1.0);
604 cyl -> num_instances = (bonds/2) * (plot -> extra_cell[0]+1)*(plot -> extra_cell[1]+1)*(plot -> extra_cell[2]+1);
605 cyl -> inst_buffer_size = CYLI_BUFF_SIZE;
606 cyl -> instances = allocfloat (CYLI_BUFF_SIZE*cyl -> num_instances);
607 if (caps)
608 {
609 cap = draw_cylinder_cap (plot -> quality, 1.0, TRUE);
610 cap -> num_instances = (ncaps/2) * (plot -> extra_cell[0]+1)*(plot -> extra_cell[1]+1)*(plot -> extra_cell[2]+1);
611 cap -> inst_buffer_size = CAPS_BUFF_SIZE;
612 cap -> instances = allocfloat (CAPS_BUFF_SIZE*cap -> num_instances);
613 }
614 for (h=0; h<caps+1; h++)
615 {
616 nbs = 0;
617 for (i=0; i<clone; i++)
618 {
619 for (j=0; j<proj_at; j++)
620 {
621 if (proj_gl -> atoms[0][j].pick[type])
622 {
623 for (k=0; k<proj_sp; k++)
624 {
625 setup_all_selected_bond_vertices (style-1, h, i, j, k, type, (h == 0) ? cyl -> instances: cap -> instances);
626 }
627 }
628 }
629 }
630 }
631 l = 1;
632 wingl -> ogl_glsl[SELEC][step][shader] = init_shader_program (SELEC, GLSL_CYLINDERS, cylinder_vertex, NULL, full_color, GL_TRIANGLE_STRIP, 6, 1, cylinder, cyl);
633 g_free (cyl);
634 if (caps)
635 {
636 l ++;
637 wingl -> ogl_glsl[SELEC][step][shader+1] = init_shader_program (SELEC, GLSL_CAPS, cap_vertex, NULL, full_color, GL_TRIANGLE_FAN, 5, 1, cylinder, cap);
638 g_free (cap);
639 }
640 }
641 else
642 {
643 l = 0;
644 for (h=0; h<clone; h++)
645 {
646 for (i=0; i<proj_sp; i++)
647 {
648 for (j=0; j<proj_sp; j++)
649 {
650 if (nbonds[style][type][h][i][j])
651 {
652 cyl = g_malloc0 (sizeof*cyl);
653 cyl -> vert_buffer_size = LINE_BUFF_SIZE;
654 cyl -> num_vertices = nbonds[style][type][h][i][j] * (plot -> extra_cell[0]+1)*(plot -> extra_cell[1]+1)*(plot -> extra_cell[2]+1);
655 cyl -> vertices = allocfloat (cyl -> vert_buffer_size*cyl -> num_vertices);
656 nbs = 0;
657 for (k=0; k<proj_at; k++)
658 {
659 if (proj_gl -> atoms[0][k].pick[type] && proj_gl -> atoms[0][k].sp == i)
660 {
661 setup_all_selected_bond_vertices (style-1, 0, h, k, j, type, cyl -> vertices);
662 }
663 }
664 wingl -> ogl_glsl[SELEC][step][shader+l] = init_shader_program (SELEC, GLSL_LINES, line_vertex, NULL, line_color, GL_LINES, 2, 1, cylinder, cyl);
665 wingl -> ogl_glsl[SELEC][step][shader+l] -> line_width = get_bond_radius (style, h, i+proj_sp*h, j+proj_sp*h, TRUE);
666 g_free (cyl);
667 l++;
668 }
669 }
670 }
671 }
672 }
673 return l;
674}
675
687int prepare_selection_shaders (int style, int shaders, int clone, int type, gboolean do_bonds)
688{
689 int j;
690 int nshaders = 0;
692 gboolean doit;
693 gboolean sphere = TRUE;
694 gboolean cylinder = FALSE;
695 object_3d * atos;
696
697 // Bonds
698 if (do_bonds)
699 {
700 if (bonds[style][type])
701 {
702 if ((style-1 == NONE && (plot -> style == BALL_AND_STICK || plot -> style == CYLINDERS)) || style-1 == BALL_AND_STICK || style-1 == CYLINDERS) cylinder = TRUE;
703 if (plot -> selected[type] -> selected > 0)
704 {
705 nshaders += render_selected (style, cylinder, caps[style][type], npbds[style][type], npcps[style][type], type, clone, shaders);
706 }
707 else
708 {
709 nshaders += render_picked (style, cylinder, caps[style][type], npbds[style][type], npcps[style][type], type, clone, shaders);
710 }
711 g_free (nbonds[style][type]);
712 }
713 }
714 // Atoms
715 if ((style-1 == NONE && (plot -> style == WIREFRAME || plot -> style == PUNT)) || style-1 == WIREFRAME || style-1 == PUNT) sphere = FALSE;
716
717 if (sphere)
718 {
719 atos = draw_sphere (plot -> quality);
720 }
721 else
722 {
723 atos = g_malloc0 (sizeof*atos);
724 atos -> vert_buffer_size = 3;
725 atos -> num_vertices = 1;
726 atos -> vertices = allocfloat (3);
727 atos -> vertices[0] = atos -> vertices[1] = atos -> vertices[2] = 0.0;
728 }
729
730 atos -> num_instances = atoms[style][type] * (plot -> extra_cell[0]+1)*(plot -> extra_cell[1]+1)*(plot -> extra_cell[2]+1);
731 atos -> inst_buffer_size = ATOM_BUFF_SIZE;
732 atos -> instances = allocfloat (atos -> num_instances*ATOM_BUFF_SIZE);
733
734 nbl = 0;
735 if (plot -> selected[type] -> selected)
736 {
737 sel = plot -> selected[type] -> first;
738 for (j=0; j< plot -> selected[type] -> selected; j++)
739 {
740 if (in_movie_encoding && plot -> at_data != NULL)
741 {
742 doit = (plot -> at_data[sel -> id].show[0] && plot -> at_data[sel -> id].style == style-1) ? TRUE : FALSE;
743 }
744 else
745 {
746 doit = (proj_gl -> atoms[step][sel -> id].show[0] && proj_gl -> atoms[step][sel -> id].style == style-1) ? TRUE : FALSE;
747 }
748 if (doit)
749 {
750 setup_this_atom (style-1, FALSE, type+1, & proj_gl -> atoms[step][sel -> id], 0, atos -> instances, 0.75);
751 }
752 if (sel -> next != NULL) sel = sel -> next;
753 }
754
755 if (plot -> draw_clones)
756 {
757 // Clones instances
758 sel = plot -> selected[type] -> first;
759 for (j=0; j< plot -> selected[type] -> selected; j++)
760 {
761 if (proj_gl -> atoms[step][sel -> id].cloned)
762 {
763 setup_selected_clone_vertices (style-1, sel -> id, type, atos -> instances);
764 }
765 if (sel -> next != NULL) sel = sel -> next;
766 }
767 }
768 }
769 else
770 {
771 for (j=0; j<proj_at; j++)
772 {
773 if (in_movie_encoding && plot -> at_data != NULL)
774 {
775 doit = (plot -> at_data[j].pick[type] && plot -> at_data[j].show[0] && plot -> at_data[j].style == style-1) ? TRUE : FALSE;
776 }
777 else
778 {
779 doit = (proj_gl -> atoms[step][j].pick[type] && proj_gl -> atoms[step][j].show[0] && proj_gl -> atoms[step][j].style == style-1) ? TRUE : FALSE;
780 }
781 if (doit)
782 {
783 setup_this_atom (style-1, FALSE, type+1, & proj_gl -> atoms[step][j], 0, atos -> instances, 0.75);
784 }
785 }
786 if (plot -> draw_clones)
787 {
788 // Clones instances
789 for (j=0; j<proj_at; j++)
790 {
791 if (proj_gl -> atoms[step][j].cloned) setup_selected_clone_vertices (style-1, j, type, atos -> instances);
792 }
793 }
794 }
795
796 if (sphere)
797 {
798 wingl -> ogl_glsl[SELEC][step][nshaders+shaders] = init_shader_program (SELEC, GLSL_SPHERES, sphere_vertex, NULL, full_color, GL_TRIANGLE_STRIP, 4, 1, TRUE, atos);
799 }
800 else
801 {
802 wingl -> ogl_glsl[SELEC][step][nshaders+shaders] = init_shader_program (SELEC, GLSL_POINTS, point_vertex, NULL, point_color, GL_POINTS, 4, 1, FALSE, atos);
803 }
804 nshaders ++;
805 g_free (atos);
806 return nshaders;
807}
808
817int check_selection (int style, int type)
818{
820 int j, k;
821 k = 0;
822 if (plot -> selected[type] -> selected)
823 {
824 sel = plot -> selected[type] -> first;
825 for (j=0; j< plot -> selected[type] -> selected; j++)
826 {
827 if (in_movie_encoding && plot -> at_data != NULL)
828 {
829 if (plot -> at_data[sel -> id].show[0] && plot -> at_data[sel -> id].style == style) k ++;
830 }
831 else
832 {
833 if (proj_gl -> atoms[step][sel -> id].show[0] && proj_gl -> atoms[step][sel -> id].style == style) k ++;
834 }
835 if (sel -> next != NULL) sel = sel -> next;
836 }
837
838 if (plot -> draw_clones)
839 {
840 // Clones instances
841 sel = plot -> selected[type] -> first;
842 for (j=0; j< plot -> selected[type] -> selected; j++)
843 {
844 k += find_selected_clone_vertices (style, sel -> id);
845 if (sel -> next != NULL) sel = sel -> next;
846 }
847 }
848 }
849 else
850 {
851 for (j=0; j<proj_at; j++)
852 {
853 if (proj_gl -> atoms[0][j].pick[type] && proj_gl -> atoms[0][j].show[0] && proj_gl -> atoms[0][j].style == style) k ++;
854 }
855 if (plot -> draw_clones)
856 {
857 // Clones instances
858 for (j=0; j<proj_at; j++)
859 {
860 if (proj_gl -> atoms[0][j].pick[type]) k += find_selected_clone_vertices (style, j);
861 }
862 }
863 }
864 return k;
865}
866
873{
874 int h, i, j, k, l;
875#ifdef DEBUG
876 g_debug ("Selected LIST");
877#endif
878 gboolean do_bonds;
879 gboolean cylinder = FALSE;
880
882 wingl -> create_shaders[SELEC] = FALSE;
883 i = (plot -> draw_clones) ? 2 : 1;
884 j = 2;
885 int nshaders = 0;
886 for (k=0; k<j; k++)
887 {
888 if (plot -> selected[k] -> selected > 0 || (! k && wingl -> picked > 0))
889 {
890 for (h=0; h<NUM_STYLES; h++)
891 {
892 do_bonds = TRUE;
893 cylinder = FALSE;
894 if ((! h && (plot -> style == PUNT || plot -> style == SPHERES)) || h-1 == PUNT || h-1 == SPHERES) do_bonds = FALSE;
895 atoms[h][k] = check_selection (h-1, k);
896 nshaders += (atoms[h][k]) ? 1 : 0;
897 if (do_bonds)
898 {
899 nbonds[h][k] = alloctint (i, proj_sp, proj_sp);
900 if ((! h && (plot -> style == BALL_AND_STICK || plot -> style == CYLINDERS)) || h-1 == BALL_AND_STICK || h-1 == CYLINDERS) cylinder = TRUE;
901 if (plot -> selected[k] -> selected > 0)
902 {
903 prepare_selected (h, cylinder, i, k);
904 }
905 else
906 {
907 prepare_picked (h, cylinder, i, k);
908 }
909 nshaders += bonds[h][k] + caps[h][k];
910 }
911 }
912 }
913 }
914 if (! nshaders) return 0;
915 wingl -> ogl_glsl[SELEC][step] = g_malloc0 (nshaders*sizeof*wingl -> ogl_glsl[SELEC][step]);
916 h = 0;
917 for (k=0; k<j; k++)
918 {
919 for (l=0; l<NUM_STYLES; l++)
920 {
921 if (atoms[l][k])
922 {
923 do_bonds = TRUE;
924 if ((! l && (plot -> style == PUNT || plot -> style == SPHERES)) || l-1 == PUNT || l-1 == SPHERES) do_bonds = FALSE;
925 if (plot -> selected[k] -> selected > 0 || (! k && wingl -> picked > 0))
926 {
927 h += prepare_selection_shaders (l, h, i, k, do_bonds);
928 }
929 }
930 }
931 }
932 return nshaders;
933}
934
941{
942 int i, j, k, l;
943#ifdef DEBUG
944 g_debug ("Pick LIST");
945#endif
947 wingl -> create_shaders[PICKS] = FALSE;
948
949 i = (plot -> draw_clones) ? 2:1;
950 j = 0;
951 for (k=0; k<i; k++)
952 {
953 for (l=0; l<proj_sp; l++)
954 {
955 j += plot -> show_atom[k][l];
956 }
957 }
958 if (j == 0) return 0;
959 k = 0;
960 for (i=0; i<proj_at; i++)
961 {
962 if (in_movie_encoding && plot -> at_data != NULL)
963 {
964 k += plot -> at_data[i].show[0];
965 k += plot -> at_data[i].show[1];
966 }
967 else
968 {
969 k += proj_gl -> atoms[step][i].show[0];
970 k += proj_gl -> atoms[step][i].show[1];
971 }
972 }
973 if (k == 0) return 0;
974
975 int nshaders = 1;
976 gboolean bonds = FALSE;
977
978 i = proj_at;
979 if (plot -> draw_clones) i += 2 * wingl -> bonds[step][1];
980 j = wingl -> bonds[step][0] + wingl -> bonds[step][1];
981 if (plot -> style != SPHERES && plot -> style != PUNT && j > 0)
982 {
983 bonds = TRUE;
984 nshaders ++;
985 i += 2 * wingl -> bonds[step][0];
986 if (plot -> draw_clones) i += 4 * wingl -> bonds[step][1];
987 }
988 int tmp_style = plot -> style;
989 plot -> style = BALL_AND_STICK;
990
991 if (wingl -> color_to_pick != NULL)
992 {
993 g_free (wingl -> color_to_pick);
994 wingl -> color_to_pick = NULL;
995 }
996 wingl -> to_be_picked = 0;
997 wingl -> color_to_pick = allocint(i);
998
999 wingl -> n_shaders[PICKS][0] = nshaders;
1000 wingl -> ogl_glsl[PICKS][0] = g_malloc0 (nshaders*sizeof*wingl -> ogl_glsl[PICKS][0]);
1001
1002 gColorID[0] = gColorID[1] = gColorID[2] = 0;
1003 create_atom_lists (TRUE);
1004
1005 wingl -> bonds_to_be_picked = 0;
1006 if (bonds) create_bond_lists (TRUE);
1007
1008 plot -> style = tmp_style;
1009
1010 return nshaders;
1011}
int gColorID[3]
Definition d_atoms.c:60
int nbs
Definition d_atoms.c:176
int nbl
Definition d_atoms.c:176
ColRGBA col
Definition d_measures.c:77
double dist
Definition d_measures.c:73
atom_in_selection * tmp_a
Definition d_measures.c:69
atom_in_selection * tmp_b
Definition d_measures.c:69
int atoms[NUM_STYLES][2]
int caps[NUM_STYLES][2]
int create_bond_lists(gboolean to_pick)
prepare bond(s) and clone bond(s) OpenGL rendering
Definition d_bonds.c:670
int find_selected_bond_vertices(int sty, int at, int sp, int bi, int pi, int cap)
find the number of selected bond(s) to render
int check_selection(int style, int type)
check selection : atom(s) in selection ?
int render_picked(int style, gboolean cylinder, int caps, int bonds, int ncaps, int type, int clone, int shader)
prepare the OpenGL rendering data of to be picked bond / clone bond
int get_clone_id(int at, int bt)
get the bond id of cloned bond
object_3d * draw_sphere(int quality)
OpenGL 3D sphere object rendering.
Definition d_atoms.c:209
int *** nbonds[NUM_STYLES][2]
int find_selected_clone_vertices(int style, int at)
find the number of selected atom(s) to render
void setup_all_selected_bond_vertices(int sty, int cap, int bi, int at, int sb, int pi, float *vertices)
prepare the rendering of all selected bond(s)
int npbds[NUM_STYLES][2]
void prepare_selected(int style, gboolean cylinder, int clone, int type)
prepare the list of selected bond(s) to render
void setup_selected_clone_vertices(int style, int at, int pi, float *vertices)
fill the OpenGL data buffer for a selected atom clone bonds to render
Definition d_selection.c:82
void setup_this_atom(int style, gboolean to_pick, int picked, atom *at, int ac, float *vert, float al)
void setup_this_bond(int sty, gboolean to_pick, gboolean picked, int cap, int bi, int pi, atom *at, atom *bt, float al, float *vertices)
prepare the OpenGL rendering data of a bond / clone bond
Definition d_bonds.c:360
void setup_sphere_vertice(float *vertices, vec3_t pos, ColRGBA col, float rad, float alpha)
fill the OpenGL data buffer for a atom (or clone) to render
Definition d_atoms.c:312
int create_pick_lists()
prepare the picking list OpenGL rendering
void setup_line_vertice(float *vertices, vec3_t pos, ColRGBA col, float alpha)
fill the OpenGL data buffer for a line bond (or clone bond) to render
Definition d_bonds.c:265
object_3d * draw_cylinder_cap(int quality, float rad, gboolean picked)
OpenGL 3D cylinder cap object rendering.
Definition d_bonds.c:169
object_3d * draw_cylinder(int quality, float ra, float rb)
OpenGL 3D cylinder object rendering.
Definition d_bonds.c:98
int prepare_selection_shaders(int style, int shaders, int clone, int type, gboolean do_bonds)
prepare selection shaders
int bonds[NUM_STYLES][2]
void setup_cylinder_vertice(float *vertices, vec3_t pos_a, vec3_t pos_b, ColRGBA col, float rad, float alpha)
void create_atom_lists(gboolean to_pick)
prepare atom(s) and clone(s) OpenGL rendering
Definition d_atoms.c:610
int npcps[NUM_STYLES][2]
int create_selection_lists()
prepare the selected atom(s) and bond(s) OpenGL rendering
float get_bond_radius(int sty, int ac, int at, int b, int sel)
get bond (clone bond) radius
Definition d_bonds.c:239
void prepare_clone(int style, gboolean to_pick, int picked, atom at, atom bt, float x, float y, float z, float *vertices)
prepare the rendering data of a clone
Definition d_atoms.c:457
void setup_triangles(float *vertices, vec3_t sa, vec3_t sb, vec3_t sc)
setup triangle veertices
Definition d_poly.c:126
void prepare_picked(int style, gboolean cylinder, int clone, int type)
prepare the list of the bond that can be picked to render
void prepare_selected_bond(int sty, int cap, int bi, int pi, atom *at, atom *bt, float *vertices)
prepare the rendering of a selected bond
int render_selected(int style, gboolean cylinder, int caps, int bonds, int ncaps, int type, int clone, int shader)
prepare the OpenGL rendering data of to selected bond / clone bond
GtkTreeSelection * sel
Definition datab.c:102
Variable declarations for the creation of the DL_POLY input file(s)
distance distance_3d(cell_info *cell, int mdstep, atom *at, atom *bt)
distance between atom a and b in 3D
Definition ogl_utils.c:81
int *** alloctint(int xal, int yal, int zal)
allocate an int *** pointer
Definition global.c:365
double pi
Definition global.c:195
gboolean in_movie_encoding
Definition global.c:180
int * allocint(int val)
allocate an int * pointer
Definition global.c:326
float * allocfloat(int val)
allocate a float * pointer
Definition global.c:410
Global variable declarations Global convenience function declarations Global data structure defin...
Variable declarations related to the OpenGL window Function declarations related to the OpenGL wind...
image * plot
Definition ogl_draw.c:66
project * proj_gl
Definition ogl_draw.c:60
glwin * wingl
Definition ogl_draw.c:59
gboolean pick
int proj_sp
Definition ogl_draw.c:61
void cleaning_shaders(glwin *view, int shader)
re-initialize an OpenGL shader
#define NUM_STYLES
Definition glview.h:168
int step
Definition ogl_draw.c:70
atom * duplicate_atom(atom *at)
copy (partially) an atom data structure
Definition ogl_draw.c:396
glsl_program * init_shader_program(int object, int object_id, const GLchar *vertex, const GLchar *geometry, const GLchar *fragment, GLenum type_of_vertices, int narray, int nunif, gboolean lightning, object_3d *obj)
create an OpenGL shader program
int proj_at
Definition ogl_draw.c:62
cell_info * cell_gl
Definition ogl_draw.c:65
@ SPHERES
Definition glview.h:176
@ BALL_AND_STICK
Definition glview.h:173
@ CYLINDERS
Definition glview.h:177
@ WIREFRAME
Definition glview.h:174
@ NONE
Definition glview.h:172
@ PUNT
Definition glview.h:178
shaders
The different types of shaders in the atomes program.
Definition glwin.h:88
@ PICKS
Definition glwin.h:97
@ SELEC
Definition glwin.h:91
double z
Definition ogl_draw.c:57
double y
Definition ogl_draw.c:57
double x
Definition ogl_draw.c:57
const GLchar * full_color
const GLchar * cylinder_vertex
const GLchar * line_color
const GLchar * cap_vertex
const GLchar * line_vertex
Definition ogl_shaders.c:80
const GLchar * sphere_vertex
const GLchar * point_vertex
Definition ogl_shaders.c:43
const GLchar * point_color
Definition ogl_shaders.c:59
#define LINE_BUFF_SIZE
Definition ogl_shading.h:49
#define ATOM_BUFF_SIZE
Definition ogl_shading.h:52
#define CAPS_BUFF_SIZE
Definition ogl_shading.h:51
#define CYLI_BUFF_SIZE
Definition ogl_shading.h:50
@ GLSL_CAPS
Definition ogl_shading.h:42
@ GLSL_POINTS
Definition ogl_shading.h:38
@ GLSL_LINES
Definition ogl_shading.h:40
@ GLSL_SPHERES
Definition ogl_shading.h:39
@ GLSL_CYLINDERS
Definition ogl_shading.h:41
Definition global.h:839
int style
Definition glwin.h:427
int b
Definition tab-1.c:95
int d
Definition tab-1.c:95
gchar * al[3]
Definition w_axis.c:67