atomes 1.1.14
atomes: an atomic scale modeling tool box
Loading...
Searching...
No Matches
d_atoms.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: 'd_atoms.c'
24*
25* Contains:
26*
27
28 - The functions to prepare the OpenGL rendering atom(s) and clone(s)
29
30*
31* List of functions:
32
33 int sphere_vertices (int qual);
34 int sphere_indices (int qual);
35 int find_atom_vertices (gboolean to_pick);
36 int find_clone_vertices (gboolean to_pick);
37
38 float get_sphere_radius (int style, int sp, int ac, int sel);
39
40 void setup_sphere_vertice (float * vertices, vec3_t pos, ColRGBA col, float rad, float alpha);
41 void setup_this_atom (int style, gboolean to_pick, gboolean picked, atom * at, int ac, float * vert, float al);
42 void setup_atom_vertices (int style, gboolean to_pick, float * vertices);
43 void prepare_clone (int style, gboolean to_pick, int picked, atom at, atom bt, float x, float y, float z, float * vertices);
44 void setup_clone_vertices (int style, gboolean to_pick, float * vertices);
45 void atom_positions_colors_and_sizes (int style, gboolean to_pick, float * instances);
46 void create_atom_lists (gboolean to_pick);
47
48 ColRGBA get_atom_color (int i, int j, double al, int picked, gboolean to_pick);
49
50 object_3d * draw_sphere (int quality);
51
52*/
53
54#include "global.h"
55#include "glview.h"
56#include "ogl_shading.h"
57#include "dlp_field.h"
58
60int gColorID[3];
62
74ColRGBA get_atom_color (int i, int j, double al, int picked, gboolean to_pick)
75{
76 // i = atom spec, j = atom id (for coordination maps), al = alpha
77 int s = i;
78 int m;
79 ColRGBA colo;
80 if (to_pick)
81 {
82 gColorID[0]++;
83 if(gColorID[0] > 255)
84 {
85 gColorID[0] = 0;
86 gColorID[1]++;
87 if(gColorID[1] > 255)
88 {
89 gColorID[1] = 0;
90 gColorID[2]++;
91 }
92 }
93 wingl -> color_to_pick[wingl -> to_be_picked] = gColorID[0] + 256*gColorID[1] + 256*256*gColorID[2];
94 colo.red = gColorID[0]/255.0;
95 colo.green = gColorID[1]/255.0;
96 colo.blue = gColorID[2]/255.0;
97 colo.alpha = 1.0;
98 wingl -> to_be_picked ++;
99 }
100 else if (picked)
101 {
102 if (field_color)
103 {
104 colo = init_color (proj_gl -> atoms[step][j].coord[4], num_field_objects);
105 colo.alpha = DEFAULT_OPACITY*0.75;
106 }
107 else
108 {
109 if (picked == 1)
110 {
111 colo.red = 0.0;
112 colo.green = 1.0;
113 colo.blue = 1.0;
114 }
115 else
116 {
117 colo.red = 1.0;
118 colo.green = 0.0;
119 colo.blue = 0.84;
120 }
121 colo.alpha = DEFAULT_OPACITY*0.75;
122 }
123 }
124 else
125 {
126 if (acolorm == 0)
127 {
128 colo.red = plot -> at_color[s].red;
129 colo.green = plot -> at_color[s].green;
130 colo.blue = plot -> at_color[s].blue;
131 colo.alpha = al;// * plot -> m_terial.param[5];
132 }
133 else if (acolorm < 5)
134 {
135 if (acolorm < 3)
136 {
137 s -= proj_sp*(s/proj_sp);
138 }
139 else
140 {
141 s = 0;
142 }
143 int k = proj_gl -> atoms[step][j].coord[acolorm -1];
144 colo.red = plot -> spcolor[acolorm - 1][s][k].red;
145 colo.green = plot -> spcolor[acolorm - 1][s][k].green;
146 colo.blue = plot -> spcolor[acolorm - 1][s][k].blue;
147 colo.alpha = al;// * plot -> m_terial.param[5];
148 }
149 else if (acolorm == 5)
150 {
152 if (fmol)
153 {
154 s = proj_gl -> atoms[0][j].fid;
155 m = fmol -> mol -> natoms;
156 }
157 else
158 {
159 s = 0;
160 m = 1;
161 }
162 colo = init_color (s, m);
163 colo.alpha = al;// * plot -> m_terial.param[5];
164 }
165 else if (acolorm == 6)
166 {
167 colo.red = wingl -> custom_map -> colors[step][j].red;
168 colo.blue = wingl -> custom_map -> colors[step][j].blue;
169 colo.green = wingl -> custom_map -> colors[step][j].green;
170 colo.alpha = wingl -> custom_map -> colors[step][j].alpha;
171 }
172 }
173 return colo;
174}
175
176int nbs, nbl, nba;
177
186{
187 return qual * qual;
188}
189
198{
199 return 2 * qual * (qual - 1);
200}
201
209object_3d * draw_sphere (int quality)
210{
211 float theta, phi;
212 float cos_phi, sin_phi;
213 float xPos, yPos, zPos;
214 int stack, slice;
215 int x, y, z;
216
217 object_3d * new_sphere = g_malloc0 (sizeof*new_sphere);
218 new_sphere -> quality = quality;
219 new_sphere -> num_vertices = sphere_vertices (quality);
220 new_sphere -> vert_buffer_size = 3;
221 new_sphere -> vertices = allocfloat (3*new_sphere -> num_vertices);
222 new_sphere -> num_indices = sphere_indices (quality);
223 new_sphere -> ind_buffer_size = 1;
224 new_sphere -> indices = allocint (new_sphere -> num_indices);
225 x = 0;
226 for (stack=0; stack <= quality-1; stack++)
227 {
228 phi = pi * stack / (quality-1);
229 cos_phi = cos(phi);
230 sin_phi = sin(phi);
231 for (slice=0; slice <= quality-1; slice++)
232 {
233 theta = 2.0 * pi * slice / (quality-1);
234 xPos = cos(theta) * sin_phi;
235 yPos = cos_phi;
236 zPos = sin(theta) * sin_phi;
237 new_sphere -> vertices[3*x] = xPos;
238 new_sphere -> vertices[3*x+1] = yPos;
239 new_sphere -> vertices[3*x+2] = zPos;
240 x ++;
241 }
242 }
243
244 gboolean oddRow = FALSE;
245 z = 0;
246 for (y = 0; y < quality-1; y++)
247 {
248 if (!oddRow) // even rows: y == 0, y == 2; and so on
249 {
250 for (x = 0; x <= quality-1; x++)
251 {
252 new_sphere -> indices[z] = (y * quality + x);
253 new_sphere -> indices[z+1]= ((y + 1) * quality + x);
254 z += 2;
255 }
256 }
257 else
258 {
259 for (x = quality-1; x >= 0; x--)
260 {
261 new_sphere -> indices[z] = ((y + 1) * quality + x);
262 new_sphere -> indices[z+1] = (y * quality + x);
263 z += 2;
264 }
265 }
266 oddRow = !oddRow;
267 }
268 return new_sphere;
269}
270
281float get_sphere_radius (int style, int sp, int ac, int sel)
282{
283 if (style == WIREFRAME || style == PUNT)
284 {
285 return plot -> pointrad[sp + ac*proj_sp] + sel*4.0;
286 }
287 else if (style == SPACEFILL)
288 {
289 return plot -> atomicrad[sp + ac*proj_sp] + sel*0.05;
290 }
291 else if (style == CYLINDERS)
292 {
293 return plot -> radall[ac] + sel*0.05;
294 }
295 else
296 {
297 return plot -> sphererad[sp + ac*proj_sp] + sel*0.05;
298 }
299}
300
312void setup_sphere_vertice (float * vertices, vec3_t pos, ColRGBA col, float rad, float alpha)
313{
314 int l;
316 vertices[l] = pos.x;
317 vertices[l+1] = pos.y;
318 vertices[l+2] = pos.z;
319 vertices[l+3] = rad;
320 vertices[l+4] = col.red;
321 vertices[l+5] = col.green;
322 vertices[l+6] = col.blue;
323 vertices[l+7] = col.alpha * alpha;
324 nbl ++;
325}
326
340void setup_this_atom (int style, gboolean to_pick, gboolean picked, atom * at, int ac, float * vert, float al)
341{
342 int i, j, k;
343 float alpha = 1.0;
344 float shift[3];
345 ColRGBA col = get_atom_color (at -> sp, at -> id, 1.0, picked, to_pick);
346 if (at -> sp > proj_sp - 1) at -> sp -= proj_sp;
347 float rad = get_sphere_radius ((style == NONE) ? plot -> style : style, at -> sp, ac, (picked) ? 1 : 0);
348 for (i=0; i<plot -> extra_cell[0]+1;i++)
349 {
350 for (j=0; j<plot -> extra_cell[1]+1; j++)
351 {
352 for (k=0; k<plot -> extra_cell[2]+1; k++)
353 {
354 shift[0]=i*box_gl -> vect[0][0]+j*box_gl -> vect[1][0]+k*box_gl -> vect[2][0];
355 shift[1]=i*box_gl -> vect[0][1]+j*box_gl -> vect[1][1]+k*box_gl -> vect[2][1];
356 shift[2]=i*box_gl -> vect[0][2]+j*box_gl -> vect[1][2]+k*box_gl -> vect[2][2];
357 at_shift (at, shift);
358 setup_sphere_vertice (vert, vec3(at -> x, at -> y, at -> z), col, rad, (to_pick) ? 1.0 : alpha*al);
359 at_unshift (at, shift);
360 alpha = 0.5;
361 }
362 }
363 }
364}
365
373int find_atom_vertices (gboolean to_pick)
374{
375 int i, j;
376 j = 0;
377 for (i=0; i<proj_at; i++)
378 {
379 if (in_movie_encoding && plot -> at_data != NULL)
380 {
381 if (plot -> at_data[i].show[0])
382 {
383 if (to_pick)
384 {
385 all_styles[0] ++;
386 }
387 else
388 {
389 all_styles[plot -> at_data[i].style + 1] ++;
390 }
391 j ++;
392 }
393 }
394 else
395 {
396 if (proj_gl -> atoms[step][i].show[0])
397 {
398 if (to_pick)
399 {
400 all_styles[0] ++;
401 }
402 else
403 {
404 all_styles[proj_gl -> atoms[step][i].style + 1] ++;
405 }
406 j ++;
407 }
408 }
409 }
410 return j;
411}
412
422void setup_atom_vertices (int style, gboolean to_pick, float * vertices)
423{
424 int i;
425 atom * tmp_a;
426 for (i=0; i<proj_at; i++)
427 {
429 if (in_movie_encoding && plot -> at_data != NULL)
430 {
431 tmp_a -> show[0] = plot -> at_data[i].show[0];
432 tmp_a -> style = plot -> at_data[i].style;
433 }
434 if (tmp_a -> show[0] && (tmp_a -> style == style || to_pick))
435 {
436 setup_this_atom (style, to_pick, 0, tmp_a, 0, vertices, 1.0);
437 }
438 g_free (tmp_a);
439 }
440}
441
457void prepare_clone (int style, gboolean to_pick, int picked, atom at, atom bt, float x, float y, float z, float * vertices)
458{
459 atom * tmp_a = duplicate_atom (& bt);
460 tmp_a -> x += x;
461 tmp_a -> y += y;
462 tmp_a -> z += z;
463 tmp_a -> id = at.id;
464 tmp_a -> sp = at.sp + proj_sp;
465 int sty = at.style;
466 if (in_movie_encoding && plot -> at_data != NULL)
467 {
468 tmp_a -> show[1] = plot -> at_data[at.id].show[1];
469 sty = plot -> at_data[at.id].style;
470 }
471 if (at.show[1] && (sty == style || to_pick))
472 {
473 setup_this_atom (style, to_pick, picked, tmp_a, 1, vertices, 0.5);
474 }
475 g_free (tmp_a);
476}
477
485int find_clone_vertices (gboolean to_pick)
486{
487 int i, j, k, l;
488 l = 0;
489 for (i=0; i < wingl -> bonds[step][1]; i++)
490 {
491 j = wingl -> bondid[step][1][i][0];
492 k = wingl -> bondid[step][1][i][1];
493 if (in_movie_encoding && plot -> at_data != NULL)
494 {
495 if (plot -> at_data[j].show[1])
496 {
497 if (to_pick)
498 {
499 all_styles[0] ++;
500 }
501 else
502 {
503 all_styles[plot -> at_data[j].style + 1] ++;
504 }
505 l++;
506 }
507 if (plot -> at_data[k].show[1])
508 {
509 if (to_pick)
510 {
511 all_styles[0] ++;
512 }
513 else
514 {
515 all_styles[plot -> at_data[k].style + 1] ++;
516 }
517 l++;
518 }
519 }
520 else
521 {
522 if (proj_gl -> atoms[step][j].show[1])
523 {
524 if (to_pick)
525 {
526 all_styles[0] ++;
527 }
528 else
529 {
530 all_styles[proj_gl -> atoms[step][j].style + 1] ++;
531 }
532 l ++;
533 }
534 if (proj_gl -> atoms[step][k].show[1])
535 {
536 if (to_pick)
537 {
538 all_styles[0] ++;
539 }
540 else
541 {
542 all_styles[proj_gl -> atoms[step][k].style + 1] ++;
543 }
544 l ++;
545 }
546 }
547 }
548 return l;
549}
550
560void setup_clone_vertices (int style, gboolean to_pick, float * vertices)
561{
562 int i, j, k;
563 for (i=0; i < wingl -> bonds[step][1]; i++)
564 {
565 j = wingl -> bondid[step][1][i][0];
566 k = wingl -> bondid[step][1][i][1];
567 prepare_clone (style, to_pick, 0,
568 proj_gl -> atoms[step][j],
569 proj_gl -> atoms[step][k],
570 wingl -> clones[step][i].x,
571 wingl -> clones[step][i].y,
572 wingl -> clones[step][i].z, vertices);
573 prepare_clone (style, to_pick, 0,
574 proj_gl -> atoms[step][k],
575 proj_gl -> atoms[step][j],
576 -wingl -> clones[step][i].x,
577 -wingl -> clones[step][i].y,
578 -wingl -> clones[step][i].z, vertices);
579
580 }
581}
582
592void atom_positions_colors_and_sizes (int style, gboolean to_pick, float * instances)
593{
594 setup_atom_vertices (style, to_pick, instances);
595 if (to_pick) wingl -> atoms_to_be_picked = wingl -> clones_to_be_picked = wingl -> to_be_picked;
596 if (plot -> draw_clones)
597 {
598 setup_clone_vertices (style, to_pick, instances);
599 if (to_pick) wingl -> clones_to_be_picked = wingl -> to_be_picked;
600 }
601}
602
610void create_atom_lists (gboolean to_pick)
611{
612 int i, j, k;
613 object_3d * atos;
614 gboolean sphere = TRUE;
615
616 if (! to_pick)
617 {
619 wingl -> create_shaders[ATOMS] = FALSE;
620 }
621
622 for (i=0; i<NUM_STYLES; i++) all_styles[i] = 0;
623 j = find_atom_vertices (to_pick);
624 if (plot -> draw_clones) j += find_clone_vertices (to_pick);
625#ifdef DEBUG
626 g_debug ("Atom LIST:: to_pick= %s, Atom(s) to render= %d", (to_pick) ? "true" : "false", j);
627#endif
628 if (j > 0)
629 {
630 // Render atom(s)
631 j = (plot -> extra_cell[0]+1)*(plot -> extra_cell[1]+1)*(plot -> extra_cell[2]+1);
632 if (! to_pick)
633 {
634 wingl -> n_shaders[ATOMS][step] = 0;
635 for (i=0; i<NUM_STYLES; i++) if (all_styles[i]) wingl -> n_shaders[ATOMS][step] ++;
636 wingl -> ogl_glsl[ATOMS][step] = g_malloc0 (wingl -> n_shaders[ATOMS][step]*sizeof*wingl -> ogl_glsl[ATOMS][step]);
637 }
638 k = 0;
639 for (i=0; i<NUM_STYLES; i++)
640 {
641 sphere = TRUE;
642 if (all_styles[i] || to_pick)
643 {
644 if (! i)
645 {
646 if (plot -> style == WIREFRAME || plot -> style == PUNT) sphere = FALSE;
647 }
648 else
649 {
650 if (i-1 == WIREFRAME || i-1 == PUNT) sphere = FALSE;
651 }
652 if (sphere)
653 {
654 atos = draw_sphere (plot -> quality);
655 }
656 else
657 {
658 atos = g_malloc0 (sizeof*atos);
659 atos -> vert_buffer_size = 3;
660 atos -> num_vertices = 1;
661 atos -> vertices = allocfloat (3);
662 atos -> vertices[0] = atos -> vertices[1] = atos -> vertices[2] = 0.0;
663 }
664 atos -> num_instances = j*all_styles[i];
665 atos -> inst_buffer_size = ATOM_BUFF_SIZE;
666 atos -> instances = allocfloat (j*all_styles[i]*ATOM_BUFF_SIZE);
667 nbl = 0;
668 atom_positions_colors_and_sizes (i-1, to_pick, atos -> instances);
669 if (! to_pick)
670 {
671 if (sphere)
672 {
673 wingl -> ogl_glsl[ATOMS][step][k] = init_shader_program (ATOMS, GLSL_SPHERES, sphere_vertex, NULL, full_color, GL_TRIANGLE_STRIP, 4, 1, TRUE, atos);
674 }
675 else
676 {
677 wingl -> ogl_glsl[ATOMS][step][k] = init_shader_program (ATOMS, GLSL_POINTS, point_vertex, NULL, point_color, GL_POINTS, 4, 1, FALSE, atos);
678 }
679 }
680 else
681 {
682 wingl -> ogl_glsl[PICKS][0][0] = init_shader_program (PICKS, GLSL_SPHERES, sphere_vertex, NULL, full_color, GL_TRIANGLE_STRIP, 4, 1, FALSE, atos);
683 }
684 g_free (atos);
685 k ++;
686 }
687 if (to_pick) break;
688 }
689 }
690}
insertion_menu mol[]
Definition w_library.c:193
ColRGBA init_color(int id, int numid)
initialize color based id number over total number of elements
Definition initcoord.c:81
int nba
Definition d_atoms.c:176
void atom_positions_colors_and_sizes(int style, gboolean to_pick, float *instances)
find atom(s) position(s), color(s) and prepare the data for the OpenGL rendering
Definition d_atoms.c:592
int gColorID[3]
Definition d_atoms.c:60
int all_styles[NUM_STYLES]
Definition d_atoms.c:61
int sphere_indices(int qual)
return the number of OpenGL indices to render a sphere
Definition d_atoms.c:197
void setup_this_atom(int style, gboolean to_pick, gboolean picked, atom *at, int ac, float *vert, float al)
prepare the OpenGL rendering data of an atom / clone
Definition d_atoms.c:340
object_3d * draw_sphere(int quality)
OpenGL 3D sphere object rendering.
Definition d_atoms.c:209
float get_sphere_radius(int style, int sp, int ac, int sel)
get an atom sphere radius
Definition d_atoms.c:281
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
void setup_atom_vertices(int style, gboolean to_pick, float *vertices)
prepare an atom OpenGL rendering
Definition d_atoms.c:422
int nbs
Definition d_atoms.c:176
int atom_id
Definition d_atoms.c:59
void setup_clone_vertices(int style, gboolean to_pick, float *vertices)
find clone(s) position(s), color(s) and prepare the data for the OpenGL rendering
Definition d_atoms.c:560
int nbl
Definition d_atoms.c:176
int sphere_vertices(int qual)
return the number of OpenGL vertices to render a sphere
Definition d_atoms.c:185
void create_atom_lists(gboolean to_pick)
prepare atom(s) and clone(s) OpenGL rendering
Definition d_atoms.c:610
ColRGBA get_atom_color(int i, int j, double al, int picked, gboolean to_pick)
get atom (or clone) color
Definition d_atoms.c:74
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
int find_clone_vertices(gboolean to_pick)
find the number of clones to render
Definition d_atoms.c:485
int find_atom_vertices(gboolean to_pick)
find the number of atom(s) to render
Definition d_atoms.c:373
ColRGBA col
Definition d_measures.c:77
atom_in_selection * tmp_a
Definition d_measures.c:69
int * shift
Definition d_measures.c:72
int atoms[NUM_STYLES][2]
int bonds[NUM_STYLES][2]
GtkTreeSelection * sel
Definition datab.c:102
field_molecule * get_active_field_molecule_from_model_id(project *this_proj, int aid)
retrieve field molecule from overall atom id in the model
Definition dlp_active.c:59
int num_field_objects
Definition dlp_field.c:981
gboolean field_color
Definition dlp_field.c:980
Variable declarations for the creation of the DL_POLY input file(s)
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
void at_unshift(atom *at, float *shift)
correct atomic coordinates modified to display image in cell replica
Definition ogl_draw.c:447
project * proj_gl
Definition ogl_draw.c:60
glwin * wingl
Definition ogl_draw.c:59
int proj_sp
Definition ogl_draw.c:61
void at_shift(atom *at, float *shift)
modify atomic coordinates to display image in cell replica
Definition ogl_draw.c:432
#define DEFAULT_OPACITY
Default OpenGL opacity.
Definition glview.h:74
box_info * box_gl
Definition ogl_draw.c:64
void cleaning_shaders(glwin *view, int shader)
re-initialize an OpenGL shader
int qual
Definition ogl_draw.c:67
#define NUM_STYLES
Definition glview.h:168
int step
Definition ogl_draw.c:70
int acolorm
Definition ogl_draw.c:68
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
@ SPACEFILL
Definition glview.h:175
@ CYLINDERS
Definition glview.h:177
@ WIREFRAME
Definition glview.h:174
@ NONE
Definition glview.h:172
@ PUNT
Definition glview.h:178
@ PICKS
Definition glwin.h:97
@ ATOMS
Definition glwin.h:89
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 * sphere_vertex
const GLchar * point_vertex
Definition ogl_shaders.c:43
const GLchar * point_color
Definition ogl_shaders.c:59
Variable declarations related to GLSL programs Data structure declarations related to GLSL programs...
#define ATOM_BUFF_SIZE
Definition ogl_shading.h:52
@ GLSL_POINTS
Definition ogl_shading.h:38
@ GLSL_SPHERES
Definition ogl_shading.h:39
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 global.h:839
int sp
Definition global.h:841
int id
Definition global.h:840
int style
Definition global.h:879
gboolean show[2]
Definition global.h:875
int style
Definition glwin.h:427
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
gchar * al[3]
Definition w_axis.c:67