atomes 1.3.1
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-2026 by CNRS and University of Strasbourg */
15
23
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 float get_bond_radius (int sty, int ac, int at, int b, int sel);
64extern void setup_this_atom (int style, gboolean to_pick, int picked, atom * at, int ac, float * vert, float al);
65extern void prepare_clone (int style, gboolean to_pick, int picked, atom at, atom bt, float x, float y, float z, float * vertices);
66extern 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);
67extern object_3d * draw_billboard_quad (void);
68extern float get_sphere_radius (int style, int sp, int ac, int sel);
69
80void setup_selected_clone_vertices (int style, int at, int pi, float * vertices)
81{
82 int i, j;
83 gboolean doit;
84 distance d;
85 for (i=0; i < proj_gl -> atoms[step][at].numv; i++)
86 {
87 j = proj_gl -> atoms[step][at].vois[i];
88 d = distance_3d (cell_gl, (cell_gl -> npt) ? step : 0, & proj_gl -> atoms[step][at], & proj_gl -> atoms[step][j]);
89 if (d.pbc)
90 {
91 if (in_movie_encoding && plot -> at_data != NULL)
92 {
93 doit = (plot -> at_data[at].pick[pi] && plot -> at_data[at].style == style) ? TRUE : FALSE;
94 }
95 else
96 {
97 doit = (proj_gl -> atoms[0][at].pick[pi] && proj_gl -> atoms[0][at].style == style) ? TRUE : FALSE;
98 }
99 if (doit)
100 {
101 prepare_clone (style, FALSE, pi+1,
102 proj_gl -> atoms[step][at],
103 proj_gl -> atoms[step][j],
104 d.x,
105 d.y,
106 d.z, vertices);
107 }
108 }
109 }
110}
111
120int find_selected_clone_vertices (int style, int at)
121{
122 int i, j, k;
123 gboolean doit = FALSE;
124 distance d;
125 if (in_movie_encoding && plot -> at_data != NULL)
126 {
127 if (plot -> at_data[at].show[1] && plot -> at_data[at].style == style) doit = TRUE;
128 }
129 else
130 {
131 if (proj_gl -> atoms[step][at].show[1] && proj_gl -> atoms[step][at].style == style) doit = TRUE;
132 }
133 k = 0;
134 if (doit)
135 {
136 for (i=0; i < proj_gl -> atoms[step][at].numv; i++)
137 {
138 j = proj_gl -> atoms[step][at].vois[i];
139 d = distance_3d (cell_gl, (cell_gl -> npt) ? step : 0, & proj_gl -> atoms[step][at], & proj_gl -> atoms[step][j]);
140 if (d.pbc) k ++;
141 }
142 }
143 return k;
144}
145
158int find_selected_bond_vertices (int sty, int at, int sp, int bi, int pi, int cap)
159{
160 int i, j, k, l, m, n;
162 gboolean show_a, show_b, show_c, show_d;
163 l = 0;
164 if (in_movie_encoding && plot -> at_data != NULL)
165 {
166 show_a = plot -> at_data[at].show[bi];
167 show_c = plot -> at_data[at].pick[pi];
168 m = plot -> at_data[at].style;
169 }
170 else
171 {
172 show_a = proj_gl -> atoms[step][at].show[bi];
173 show_c = proj_gl -> atoms[step][at].pick[pi];
174 m = proj_gl -> atoms[step][at].style;
175 }
176 if (show_a && show_c && m == sty)
177 {
178 for (i=0; i<proj_gl -> atoms[step][at].numv; i++)
179 {
180 j = proj_gl -> atoms[step][at].vois[i];
181 if (in_movie_encoding && plot -> at_data != NULL)
182 {
183 show_b = plot -> at_data[j].show[bi];
184 show_d = plot -> at_data[j].pick[pi];
185 n = plot -> at_data[j].style;
186 k = proj_gl -> atoms[0][j].sp;
187 }
188 else
189 {
190 show_b = proj_gl -> atoms[step][j].show[bi];
191 show_d = proj_gl -> atoms[step][j].pick[pi];
192 n = proj_gl -> atoms[step][j].style;
193 k = proj_gl -> atoms[step][j].sp;
194 }
195 if (sp == -1 || k == sp)
196 {
197 dist = distance_3d (cell_gl, (cell_gl -> npt) ? step : 0, & proj_gl -> atoms[step][at], & proj_gl -> atoms[step][j]);
198 if ((bi && dist.pbc) ||(! bi && ! dist.pbc))
199 {
200 if (cap)
201 {
202 if ((! show_b || ! show_d) || (m != n)) l += 1 + bi;
203 }
204 else
205 {
206 l += 1 + bi;
207 }
208 }
209 }
210 }
211 }
212 return 2*l;
213}
214
223int get_clone_id (int at, int bt)
224{
225 int i, j, k;
226 for (i=0; i < wingl -> bonds[step][1]; i++)
227 {
228 j = wingl -> bondid[step][1][i][0];
229 k = wingl -> bondid[step][1][i][1];
230 if ((j == at && k == bt) || (j == bt && k == at)) return i;
231 }
232 return -1;
233}
234
248void prepare_selected_bond (int sty, int cap, int bi, int pi, atom * at, atom * bt, float * vertices)
249{
250 if (bi == 0)
251 {
252 setup_this_bond (sty, FALSE, TRUE, cap, bi, pi, at, bt, 1.0, vertices);
253 }
254 else
255 {
256 atom * tmp_a, * tmp_b;
257 distance d = distance_3d (cell_gl, (cell_gl -> npt) ? step : 0, at, bt);
258
259 tmp_a = duplicate_atom (at);
260 tmp_b = duplicate_atom (at);
261 tmp_a -> pick[pi] = bt -> pick[pi];
262 tmp_a -> style = bt -> style;
263 tmp_a -> sp = bt -> sp + proj_sp;
264 tmp_b -> sp += proj_sp;
265 tmp_a -> x -= d.x;
266 tmp_a -> y -= d.y;
267 tmp_a -> z -= d.z;
268 setup_this_bond (sty, FALSE, TRUE, cap, bi, pi, tmp_b, tmp_a, 0.5, vertices);
271
272 tmp_a = duplicate_atom (bt);
273 tmp_b = duplicate_atom (bt);
274 tmp_a -> pick[pi] = at -> pick[pi];
275 tmp_a -> style = at -> style;
276 tmp_a -> sp = at -> sp + proj_sp;
277 tmp_b -> sp += proj_sp;
278 tmp_a -> id = at -> id;
279 tmp_a -> x += d.x;
280 tmp_a -> y += d.y;
281 tmp_a -> z += d.z;
282 setup_this_bond (sty, FALSE, TRUE, cap, bi, pi, tmp_a, tmp_b, 0.5, vertices);
285 }
286}
287
301void setup_all_selected_bond_vertices (int sty, int cap, int bi, int at, int sb, int pi, float * vertices)
302{
303 int i, j, k, l, m;
305 gboolean show_a, show_b, show_c, show_d;
306 if (in_movie_encoding && plot -> at_data != NULL)
307 {
308 show_a = plot -> at_data[at].show[bi];
309 show_c = plot -> at_data[at].pick[pi];
310 l = plot -> at_data[at].style;
311 }
312 else
313 {
314 show_a = proj_gl -> atoms[step][at].show[bi];
315 show_c = proj_gl -> atoms[step][at].pick[pi];
316 l = proj_gl -> atoms[step][at].style;
317 }
318 if (show_a && show_c && l == sty)
319 {
320 for (i=0; i<proj_gl -> atoms[step][at].numv; i++)
321 {
322 j = proj_gl -> atoms[step][at].vois[i];
323 if (in_movie_encoding && plot -> at_data != NULL)
324 {
325 show_b = plot -> at_data[j].show[bi];
326 show_d = plot -> at_data[j].pick[pi];
327 m = plot -> at_data[j].style;
328 k = proj_gl -> atoms[0][j].sp;
329 }
330 else
331 {
332 show_b = proj_gl -> atoms[step][j].show[bi];
333 show_d = proj_gl -> atoms[step][j].pick[pi];
334 m = proj_gl -> atoms[step][j].style;
335 k = proj_gl -> atoms[step][j].sp;
336 }
337 if (sb == -1 || k == sb)
338 {
339 dist = distance_3d (cell_gl, (cell_gl -> npt) ? step : 0, & proj_gl -> atoms[step][at], & proj_gl -> atoms[step][j]);
340 if ((bi && dist.pbc) ||(! bi && ! dist.pbc))
341 {
342 if (cap)
343 {
344 if ((! show_b || ! show_d) || (l != m))
345 {
346 prepare_selected_bond (sty, cap, bi, pi, & proj_gl -> atoms[step][at], & proj_gl -> atoms[step][j], vertices);
347 }
348 }
349 else
350 {
351 prepare_selected_bond (sty, cap, bi, pi, & proj_gl -> atoms[step][at], & proj_gl -> atoms[step][j], vertices);
352 }
353 }
354 }
355 }
356 }
357}
358
362int *** sbonds[NUM_STYLES][2];
363
374void prepare_selected (int style, gboolean cylinder, int clone, int type)
375{
376 int h, i, j;
378 npbds[style][type] = npcps[style][type] = 0;
379 if (cylinder)
380 {
381 sel = plot -> selected[type] -> first;
382 while (sel)
383 {
384 for (i=0; i<clone; i++)
385 {
386 npbds[style][type] += find_selected_bond_vertices (style-1, sel -> id, -1, i, type, 0);
387 npcps[style][type] += find_selected_bond_vertices (style-1, sel -> id, -1, i, type, 1);
388 }
389 sel = sel -> next;
390 }
391 bonds[style][type] = (npbds[style][type]) ? 1 : 0;
392 caps[style][type] = (npcps[style][type]) ? 1 : 0;
393 }
394 else
395 {
396 sel = plot -> selected[type] -> first;
397 while (sel)
398 {
399 for (i=0; i<clone; i++)
400 {
401 for (j=0; j<proj_sp; j++)
402 {
403 sbonds[style][type][i][sel -> sp][j] += find_selected_bond_vertices (style-1, sel -> id, j, i, type, 0);
404 }
405 }
406 sel = sel -> next;
407 }
408 for (h=0; h<clone; h++)
409 {
410 for (i=0; i<proj_sp; i++)
411 {
412 for (j=0; j<proj_sp; j++)
413 {
414 npbds[style][type] += sbonds[style][type][h][i][j];
415 npcps[style][type] += (sbonds[style][type][h][i][j]) ? 1 : 0;
416 }
417 }
418 }
419 bonds[style][type] = npcps[style][type];
420 caps[style][type] = 0;
421 }
422}
423
434void prepare_picked (int style, gboolean cylinder, int clone, int type)
435{
436 int h, i, j;
437 npbds[style][type] = npcps[style][type] = 0;
438 if (cylinder)
439 {
440 for (i=0; i<proj_at; i++)
441 {
442 if (proj_gl -> atoms[0][i].pick[type])
443 {
444 for (h=0; h<clone; h++)
445 {
446 npbds[style][type] += find_selected_bond_vertices (style-1, i, -1, h, type, 0);
447 npcps[style][type] += find_selected_bond_vertices (style-1, i, -1, h, type, 1);
448 }
449 }
450 }
451 bonds[style][type] = (npbds[style][type]) ? 1 : 0;
452 caps[style][type] = (npcps[style][type]) ? 1 : 0;
453 }
454 else
455 {
456 for (i=0; i<proj_at; i++)
457 {
458 if (proj_gl -> atoms[0][i].pick[type])
459 {
460 for (h=0; h<clone; h++)
461 {
462 for (j=0; j<proj_sp; j++)
463 {
464 sbonds[style][type][h][proj_gl -> atoms[0][i].sp][j] += find_selected_bond_vertices (style-1, i, j, h, type, 0);
465 }
466 }
467 }
468 }
469 for (h=0; h<clone; h++)
470 {
471 for (i=0; i<proj_sp; i++)
472 {
473 for (j=0; j<proj_sp; j++)
474 {
475 npbds[style][type] += sbonds[style][type][h][i][j];
476 npcps[style][type] += (sbonds[style][type][h][i][j]) ? 1 : 0;
477 }
478 }
479 }
480 bonds[style][type] = npcps[style][type];
481 caps[style][type] = 0;
482 }
483}
484
499int render_selected (int style, gboolean cylinder, int caps, int bonds, int ncaps, int type, int clone, int shader)
500{
501 int h, i, j, k, l;
503 object_3d * cyl, * cap;
504
505 if (cylinder)
506 {
507 cyl = plot -> ray_tracing ? draw_billboard_quad () : draw_cylinder (plot -> quality, 1.0, 1.0);
508 cyl -> num_instances = (bonds/2) * (plot -> abc -> extra_cell[0]+1)*(plot -> abc -> extra_cell[1]+1)*(plot -> abc -> extra_cell[2]+1);
509 cyl -> inst_buffer_size = plot -> ray_tracing ? CYLI_BUFF_SIZE + 2 : CYLI_BUFF_SIZE;
510 allocate_instances (cyl);
511 if (caps)
512 {
513 cap = plot -> ray_tracing ? draw_billboard_quad () : draw_cylinder_cap (plot -> quality, 1.0, TRUE);
514 cap -> num_instances = (ncaps/2) * (plot -> abc -> extra_cell[0]+1)*(plot -> abc -> extra_cell[1]+1)*(plot -> abc -> extra_cell[2]+1);
515 cap -> inst_buffer_size = CAPS_BUFF_SIZE;
516 allocate_instances (cap);
517 }
518 for (h=0; h<caps+1; h++)
519 {
520 nbs = 0;
521 for (i=0; i<clone; i++)
522 {
523 sel = plot -> selected[type] -> first;
524 for (j=0; j< plot -> selected[type] -> selected; j++)
525 {
526 for (k=0; k<proj_sp; k++)
527 {
528 setup_all_selected_bond_vertices (style-1, h, i, sel -> id, k, type, (h == 0) ? cyl -> instances: cap -> instances);
529 }
530 if (sel -> next != NULL) sel = sel -> next;
531 }
532 }
533 }
534 l = 1;
535 const GLchar * vs_sel_cyl = (plot -> ray_tracing) ? cylinder_vertex_ray : cylinder_vertex;
536 const GLchar * fs_sel = (plot -> ray_tracing) ? full_color_ray : full_color;
537 int narray_sel = plot -> ray_tracing ? 8 : 6;
538 wingl -> ogl_glsl[SELEC][step][shader] = init_shader_program (SELEC, GLSL_CYLINDERS, vs_sel_cyl, NULL, fs_sel, GL_TRIANGLE_STRIP, narray_sel, 1, cylinder, cyl);
539 if (caps)
540 {
541 l ++;
542 const GLchar * vs_sel_cap = (plot -> ray_tracing) ? cap_vertex_ray : cap_vertex;
543 GLenum prim_sel_cap = plot -> ray_tracing ? GL_TRIANGLE_STRIP : GL_TRIANGLE_FAN;
544 wingl -> ogl_glsl[SELEC][step][shader+1] = init_shader_program (SELEC, GLSL_CAPS, vs_sel_cap, NULL, fs_sel, prim_sel_cap, 5, 1, cylinder, cap);
545 }
546 }
547 else
548 {
549 l = 0;
550 for (h=0; h<clone; h++)
551 {
552 for (i=0; i<proj_sp; i++)
553 {
554 for (j=0; j<proj_sp; j++)
555 {
556 if (sbonds[style][type][h][i][j])
557 {
558 cyl = g_malloc0(sizeof*cyl);
559 cyl -> vert_buffer_size = LINE_BUFF_SIZE;
560 cyl -> num_vertices = sbonds[style][type][h][i][j] * (plot -> abc -> extra_cell[0]+1)*(plot -> abc -> extra_cell[1]+1)*(plot -> abc -> extra_cell[2]+1);
561 cyl -> vertices = allocfloat (cyl -> vert_buffer_size*cyl -> num_vertices);
562 nbs = 0;
563 sel = plot -> selected[type] -> first;
564 for (k=0; k< plot -> selected[type] -> selected; k++)
565 {
566 if (sel -> sp == i)
567 {
568 setup_all_selected_bond_vertices (style-1, 0, h, sel -> id, j, type, cyl -> vertices);
569 }
570 if (sel -> next != NULL) sel = sel -> next;
571 }
572 wingl -> ogl_glsl[SELEC][step][shader+l] = init_shader_program (SELEC, GLSL_LINES, line_vertex, NULL, line_color, GL_LINES, 2, 1, cylinder, cyl);
573 wingl -> ogl_glsl[SELEC][step][shader+l] -> line_width = get_bond_radius (style, h, i+proj_sp*h, j+proj_sp*h, TRUE);
574 l++;
575 }
576 }
577 }
578 }
579 }
580 return l;
581}
582
597int render_picked (int style, gboolean cylinder, int caps, int bonds, int ncaps, int type, int clone, int shader)
598{
599 int h, i, j, k, l;
600 object_3d * cyl, * cap;
601
602 if (cylinder)
603 {
604 cyl = (plot -> ray_tracing) ? draw_billboard_quad () : draw_cylinder (plot -> quality, 1.0, 1.0);
605 cyl -> num_instances = (bonds/2) * (plot -> abc -> extra_cell[0]+1)*(plot -> abc -> extra_cell[1]+1)*(plot -> abc -> extra_cell[2]+1);
606 cyl -> inst_buffer_size = plot -> ray_tracing ? CYLI_BUFF_SIZE + 2 : CYLI_BUFF_SIZE;
607 allocate_instances (cyl);
608 if (caps)
609 {
610 cap = (plot -> ray_tracing) ? draw_billboard_quad () : draw_cylinder_cap (plot -> quality, 1.0, TRUE);
611 cap -> num_instances = (ncaps/2) * (plot -> abc -> extra_cell[0]+1)*(plot -> abc -> extra_cell[1]+1)*(plot -> abc -> extra_cell[2]+1);
612 cap -> inst_buffer_size = CAPS_BUFF_SIZE;
613 allocate_instances (cap);
614 }
615 for (h=0; h<caps+1; h++)
616 {
617 nbs = 0;
618 for (i=0; i<clone; i++)
619 {
620 for (j=0; j<proj_at; j++)
621 {
622 if (proj_gl -> atoms[0][j].pick[type])
623 {
624 for (k=0; k<proj_sp; k++)
625 {
626 setup_all_selected_bond_vertices (style-1, h, i, j, k, type, (h == 0) ? cyl -> instances: cap -> instances);
627 }
628 }
629 }
630 }
631 }
632 l = 1;
633 const GLchar * vs_cyl = (plot -> ray_tracing) ? cylinder_vertex_ray : cylinder_vertex;
634 const GLchar * fs_cyl = (plot -> ray_tracing) ? full_color_ray : full_color;
635 wingl -> ogl_glsl[SELEC][step][shader] = init_shader_program (SELEC, GLSL_CYLINDERS, vs_cyl, NULL, fs_cyl, GL_TRIANGLE_STRIP, 6, 1, cylinder, cyl);
636 if (caps)
637 {
638 l ++;
639 const GLchar * vs_cap = (plot -> ray_tracing) ? cap_vertex_ray : cap_vertex;
640 GLenum prim_cap = (plot -> ray_tracing) ? GL_TRIANGLE_STRIP : GL_TRIANGLE_FAN;
641 wingl -> ogl_glsl[SELEC][step][shader+1] = init_shader_program (SELEC, GLSL_CAPS, vs_cap, NULL, fs_cyl, prim_cap, 5, 1, cylinder, cap);
642 }
643 }
644 else
645 {
646 l = 0;
647 for (h=0; h<clone; h++)
648 {
649 for (i=0; i<proj_sp; i++)
650 {
651 for (j=0; j<proj_sp; j++)
652 {
653 if (sbonds[style][type][h][i][j])
654 {
655 cyl = g_malloc0(sizeof*cyl);
656 cyl -> vert_buffer_size = LINE_BUFF_SIZE;
657 cyl -> num_vertices = sbonds[style][type][h][i][j] * (plot -> abc -> extra_cell[0]+1)*(plot -> abc -> extra_cell[1]+1)*(plot -> abc -> extra_cell[2]+1);
658 cyl -> vertices = allocfloat (cyl -> vert_buffer_size*cyl -> num_vertices);
659 nbs = 0;
660 for (k=0; k<proj_at; k++)
661 {
662 if (proj_gl -> atoms[0][k].pick[type] && proj_gl -> atoms[0][k].sp == i)
663 {
664 setup_all_selected_bond_vertices (style-1, 0, h, k, j, type, cyl -> vertices);
665 }
666 }
667 wingl -> ogl_glsl[SELEC][step][shader+l] = init_shader_program (SELEC, GLSL_LINES, line_vertex, NULL, line_color, GL_LINES, 2, 1, cylinder, cyl);
668 wingl -> ogl_glsl[SELEC][step][shader+l] -> line_width = get_bond_radius (style, h, i+proj_sp*h, j+proj_sp*h, TRUE);
669 l++;
670 }
671 }
672 }
673 }
674 }
675 return l;
676}
677
689int prepare_selection_shaders (int style, int shaders, int clone, int type, gboolean do_bonds)
690{
691 int i,j;
692 int nshaders = 0;
694 gboolean doit;
695 gboolean sphere = TRUE;
696 gboolean cylinder = FALSE;
697 object_3d * atos;
698
699 // Atoms
700 if ((style-1 == NONE && (plot -> style == WIREFRAME || plot -> style == PUNT)) || style-1 == WIREFRAME || style-1 == PUNT) sphere = FALSE;
701
702 if (sphere)
703 {
704 atos = (plot -> ray_tracing) ? draw_billboard_quad () : draw_sphere (plot -> quality);
705 }
706 else
707 {
708 atos = g_malloc0(sizeof*atos);
709 atos -> vert_buffer_size = 3;
710 atos -> num_vertices = 1;
711 atos -> vertices = allocfloat (3);
712 atos -> vertices[0] = atos -> vertices[1] = atos -> vertices[2] = 0.0;
713 }
714
715 atos -> num_instances = atoms[style][type] * (plot -> abc -> extra_cell[0]+1)*(plot -> abc -> extra_cell[1]+1)*(plot -> abc -> extra_cell[2]+1);
716 atos -> inst_buffer_size = ATOM_BUFF_SIZE;
717 allocate_instances (atos);
718
719 nbl = 0;
720 if (plot -> selected[type] -> selected)
721 {
722 sel = plot -> selected[type] -> first;
723 for (j=0; j< plot -> selected[type] -> selected; j++)
724 {
725 if (in_movie_encoding && plot -> at_data != NULL)
726 {
727 doit = (plot -> at_data[sel -> id].show[0] && plot -> at_data[sel -> id].style == style-1) ? TRUE : FALSE;
728 }
729 else
730 {
731 doit = (proj_gl -> atoms[step][sel -> id].show[0] && proj_gl -> atoms[step][sel -> id].style == style-1) ? TRUE : FALSE;
732 }
733 if (doit)
734 {
735 setup_this_atom (style-1, FALSE, type+1, & proj_gl -> atoms[step][sel -> id], 0, atos -> instances, 1.0);//0.75);
736 }
737 if (sel -> next != NULL) sel = sel -> next;
738 }
739
740 if (plot -> draw_clones)
741 {
742 // Clones instances
743 sel = plot -> selected[type] -> first;
744 for (j=0; j< plot -> selected[type] -> selected; j++)
745 {
746 if (proj_gl -> atoms[step][sel -> id].cloned)
747 {
748 setup_selected_clone_vertices (style-1, sel -> id, type, atos -> instances);
749 }
750 if (sel -> next != NULL) sel = sel -> next;
751 }
752 }
753 }
754 else
755 {
756 for (j=0; j<proj_at; j++)
757 {
758 if (in_movie_encoding && plot -> at_data != NULL)
759 {
760 doit = (plot -> at_data[j].pick[type] && plot -> at_data[j].show[0] && plot -> at_data[j].style == style-1) ? TRUE : FALSE;
761 }
762 else
763 {
764 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;
765 }
766 if (doit)
767 {
768 setup_this_atom (style-1, FALSE, type+1, & proj_gl -> atoms[step][j], 0, atos -> instances, 0.75);
769 }
770 }
771 if (plot -> draw_clones)
772 {
773 // Clones instances
774 for (j=0; j<proj_at; j++)
775 {
776 if (proj_gl -> atoms[step][j].cloned) setup_selected_clone_vertices (style-1, j, type, atos -> instances);
777 }
778 }
779 }
780
781 if (sphere)
782 {
783 const GLchar * vs_sel_sph = (plot -> ray_tracing) ? sphere_vertex_ray : sphere_vertex;
784 const GLchar * fs_sel_sph = (plot -> ray_tracing) ? full_color_ray : full_color;
785 wingl -> ogl_glsl[SELEC][step][shaders+nshaders] = init_shader_program (SELEC, GLSL_SPHERES, vs_sel_sph, NULL, fs_sel_sph, GL_TRIANGLE_STRIP, 4, 1, TRUE, atos);
786 }
787 else
788 {
789 wingl -> ogl_glsl[SELEC][step][shaders+nshaders] = init_shader_program (SELEC, GLSL_POINTS, point_vertex, NULL, point_color, GL_POINTS, 4, 1, FALSE, atos);
790 }
791
792 nshaders ++;
793 // Bonds
794 if (do_bonds)
795 {
796 if (bonds[style][type])
797 {
798 if ((style-1 == NONE && (plot -> style == BALL_AND_STICK || plot -> style == CYLINDERS)) || style-1 == BALL_AND_STICK || style-1 == CYLINDERS) cylinder = TRUE;
799 if (plot -> selected[type] -> selected > 0)
800 {
801 nshaders += render_selected (style, cylinder, caps[style][type], npbds[style][type], npcps[style][type], type, clone, shaders+nshaders);
802 }
803 else
804 {
805 nshaders += render_picked (style, cylinder, caps[style][type], npbds[style][type], npcps[style][type], type, clone, shaders+nshaders);
806 }
807 for (i=0; i<((plot -> draw_clones) ? 2 : 1); i++)
808 {
809 if (sbonds[style][type][i])
810 {
811 for (j=0; j<proj_sp; j++)
812 {
813 g_free (sbonds[style][type][i][j]);
814 sbonds[style][type][i][j] = NULL;
815 }
816 g_free (sbonds[style][type][i]);
817 sbonds[style][type][i] = NULL;
818 }
819 }
820 if (sbonds[style][type])
821 {
822 g_free (sbonds[style][type]);
823 sbonds[style][type] = NULL;
824 }
825 }
826 }
827 return nshaders;
828}
829
838int check_selection (int style, int type)
839{
841 int j, k;
842 k = 0;
843 if (plot -> selected[type] -> selected)
844 {
845 sel = plot -> selected[type] -> first;
846 for (j=0; j< plot -> selected[type] -> selected; j++)
847 {
848 if (in_movie_encoding && plot -> at_data != NULL)
849 {
850 if (plot -> at_data[sel -> id].show[0] && plot -> at_data[sel -> id].style == style) k ++;
851 }
852 else
853 {
854 if (proj_gl -> atoms[step][sel -> id].show[0] && proj_gl -> atoms[step][sel -> id].style == style) k ++;
855 }
856 if (sel -> next != NULL) sel = sel -> next;
857 }
858
859 if (plot -> draw_clones)
860 {
861 // Clones instances
862 sel = plot -> selected[type] -> first;
863 for (j=0; j< plot -> selected[type] -> selected; j++)
864 {
865 k += find_selected_clone_vertices (style, sel -> id);
866 if (sel -> next != NULL) sel = sel -> next;
867 }
868 }
869 }
870 else
871 {
872 for (j=0; j<proj_at; j++)
873 {
874 if (proj_gl -> atoms[0][j].pick[type] && proj_gl -> atoms[0][j].show[0] && proj_gl -> atoms[0][j].style == style) k ++;
875 }
876 if (plot -> draw_clones)
877 {
878 // Clones instances
879 for (j=0; j<proj_at; j++)
880 {
881 if (proj_gl -> atoms[0][j].pick[type]) k += find_selected_clone_vertices (style, j);
882 }
883 }
884 }
885 return k;
886}
887
894{
895 int h, i, j, k, l;
896#ifdef DEBUG
897 g_debug ("Selected LIST");
898#endif
899 gboolean do_bonds;
900 gboolean cylinder = FALSE;
901
903 wingl -> create_shaders[SELEC] = FALSE;
904 i = (plot -> draw_clones) ? 2 : 1;
905 j = 2;
906 int nshaders = 0;
907
908 for (k=0; k<j; k++)
909 {
910 if (plot -> selected[k] -> selected > 0 || (! k && wingl -> picked > 0))
911 {
912 for (h=0; h<NUM_STYLES; h++)
913 {
914 do_bonds = TRUE;
915 cylinder = FALSE;
916 if ((! h && (plot -> style == PUNT || plot -> style == SPHERES)) || h-1 == PUNT || h-1 == SPHERES) do_bonds = FALSE;
917 atoms[h][k] = check_selection (h-1, k);
918 nshaders += (atoms[h][k]) ? 1 : 0;
919 if (do_bonds)
920 {
921 sbonds[h][k] = alloctint (i, proj_sp, proj_sp);
922 if ((! h && (plot -> style == BALL_AND_STICK || plot -> style == CYLINDERS)) || h-1 == BALL_AND_STICK || h-1 == CYLINDERS) cylinder = TRUE;
923 if (plot -> selected[k] -> selected > 0)
924 {
925 prepare_selected (h, cylinder, i, k);
926 }
927 else
928 {
929 prepare_picked (h, cylinder, i, k);
930 }
931 nshaders += bonds[h][k] + caps[h][k];
932 }
933 else
934 {
935 sbonds[h][k] = NULL;
936 }
937 }
938 }
939 }
940
941 if (! nshaders) return 0;
942 wingl -> ogl_glsl[SELEC][step] = g_malloc0(nshaders*sizeof*wingl -> ogl_glsl[SELEC][step]);
943 h = 0;
944 for (k=0; k<j; k++)
945 {
946 for (l=0; l<NUM_STYLES; l++)
947 {
948 if (atoms[l][k])
949 {
950 do_bonds = TRUE;
951 if ((! l && (plot -> style == PUNT || plot -> style == SPHERES)) || l-1 == PUNT || l-1 == SPHERES) do_bonds = FALSE;
952 if (plot -> selected[k] -> selected > 0 || (! k && wingl -> picked > 0))
953 {
954 h += prepare_selection_shaders (l, h, i, k, do_bonds);
955 }
956 }
957 }
958 }
959
960 return nshaders;
961}
962
969{
970 int i, j, k, l;
971#ifdef DEBUG
972 g_debug ("Pick LIST");
973#endif
975 wingl -> create_shaders[PICKS] = FALSE;
976
977 i = (plot -> draw_clones) ? 2:1;
978 j = 0;
979 for (k=0; k<i; k++)
980 {
981 for (l=0; l<proj_sp; l++)
982 {
983 j += plot -> show_atom[k][l];
984 }
985 }
986 if (j == 0) return 0;
987 k = 0;
988 for (i=0; i<proj_at; i++)
989 {
990 if (in_movie_encoding && plot -> at_data != NULL)
991 {
992 k += plot -> at_data[i].show[0];
993 k += plot -> at_data[i].show[1];
994 }
995 else
996 {
997 k += proj_gl -> atoms[step][i].show[0];
998 k += proj_gl -> atoms[step][i].show[1];
999 }
1000 }
1001 if (k == 0) return 0;
1002
1003 int nshaders = 1;
1004 gboolean bonds = FALSE;
1005
1006 i = proj_at;
1007 if (plot -> draw_clones) i += 2 * wingl -> bonds[step][1];
1008 j = wingl -> bonds[step][0] + wingl -> bonds[step][1];
1009 if (plot -> style != SPHERES && plot -> style != PUNT && j > 0)
1010 {
1011 bonds = TRUE;
1012 nshaders ++;
1013 i += 2 * wingl -> bonds[step][0];
1014 if (plot -> draw_clones) i += 4 * wingl -> bonds[step][1];
1015 }
1016 int tmp_style = plot -> style;
1017 plot -> style = BALL_AND_STICK;
1018
1019 if (wingl -> color_to_pick != NULL)
1020 {
1021 g_free (wingl -> color_to_pick);
1022 wingl -> color_to_pick = NULL;
1023 }
1024 wingl -> to_be_picked = 0;
1025 wingl -> color_to_pick = allocint (i);
1026
1027 wingl -> n_shaders[PICKS][0] = nshaders;
1028 wingl -> ogl_glsl[PICKS][0] = g_malloc0(nshaders*sizeof*wingl -> ogl_glsl[PICKS][0]);
1029
1030 gboolean saved_ray = plot -> ray_tracing;
1031 plot -> ray_tracing = FALSE;
1032
1033 gColorID[0] = gColorID[1] = gColorID[2] = 0;
1034 create_atom_lists (TRUE);
1035
1036 wingl -> bonds_to_be_picked = 0;
1037 if (bonds) create_bond_lists (TRUE);
1038
1039 plot -> ray_tracing = saved_ray;
1040 plot -> style = tmp_style;
1041
1042 return nshaders;
1043}
int gColorID[3]
Definition d_atoms.c:61
int nbs
Definition d_atoms.c:165
object_3d * draw_billboard_quad()
create a camera-aligned billboard quad proxy for perfect impostors.
Definition d_atoms.c:273
int nbl
Definition d_atoms.c:165
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 *** sbonds[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:685
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_billboard_quad(void)
create a camera-aligned billboard quad proxy for perfect impostors.
Definition d_atoms.c:273
object_3d * draw_sphere(int quality)
OpenGL 3D sphere object rendering.
Definition d_atoms.c:198
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:80
float get_sphere_radius(int style, int sp, int ac, int sel)
get an atom sphere radius
Definition d_atoms.c:305
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:374
int create_pick_lists()
prepare the picking list OpenGL rendering
object_3d * draw_cylinder_cap(int quality, float rad, gboolean picked)
OpenGL 3D cylinder cap object rendering.
Definition d_bonds.c:173
object_3d * draw_cylinder(int quality, float ra, float rb)
OpenGL 3D cylinder object rendering.
Definition d_bonds.c:102
int prepare_selection_shaders(int style, int shaders, int clone, int type, gboolean do_bonds)
prepare selection shaders
int bonds[NUM_STYLES][2]
void create_atom_lists(gboolean to_pick)
prepare atom(s) and clone(s) OpenGL rendering
Definition d_atoms.c:643
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:243
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:490
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 the 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:340
double pi
Definition global.c:202
gboolean in_movie_encoding
Definition global.c:184
int * allocint(int val)
allocate an int * pointer
Definition global.c:301
float * allocfloat(int val)
allocate a float * pointer
Definition global.c:385
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:72
project * proj_gl
Definition ogl_draw.c:66
glwin * wingl
Definition ogl_draw.c:65
gboolean pick
int proj_sp
Definition ogl_draw.c:67
void cleaning_shaders(glwin *view, int shader)
re-initialize an OpenGL shader
atom * free_atom(atom *at)
free an atom data structure
Definition ogl_draw.c:484
#define NUM_STYLES
Definition glview.h:177
int step
Definition ogl_draw.c:76
atom * duplicate_atom(atom *at)
copy (partially) an atom data structure
Definition ogl_draw.c:449
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:68
cell_info * cell_gl
Definition ogl_draw.c:71
@ SPHERES
Definition glview.h:185
@ BALL_AND_STICK
Definition glview.h:182
@ CYLINDERS
Definition glview.h:186
@ WIREFRAME
Definition glview.h:183
@ NONE
Definition glview.h:181
@ PUNT
Definition glview.h:187
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:63
double y
Definition ogl_draw.c:63
double x
Definition ogl_draw.c:63
const GLchar * full_color
const GLchar * cap_vertex_ray
const GLchar * cylinder_vertex
const GLchar * full_color_ray
const GLchar * cylinder_vertex_ray
const GLchar * line_color
Definition ogl_shaders.c:93
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:50
const GLchar * point_color
Definition ogl_shaders.c:66
const GLchar * sphere_vertex_ray
void allocate_instances(object_3d *object)
allocate the instances buffer of a 3D object
#define LINE_BUFF_SIZE
Definition ogl_shading.h:50
#define ATOM_BUFF_SIZE
Definition ogl_shading.h:53
#define CAPS_BUFF_SIZE
Definition ogl_shading.h:52
#define CYLI_BUFF_SIZE
Definition ogl_shading.h:51
@ 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:964
double z
Definition glwin.h:127
double y
Definition glwin.h:126
gboolean pbc
Definition glwin.h:128
double x
Definition glwin.h:125