atomes 1.2.1
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-2025 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#include "preferences.h"
59
61int gColorID[3];
63
75ColRGBA get_atom_color (int i, int j, double al, int picked, gboolean to_pick)
76{
77 // i = atom spec, j = atom id (for coordination maps), al = alpha
78 int s = i;
79 int m;
80 ColRGBA colo;
81 if (to_pick)
82 {
83 gColorID[0]++;
84 if(gColorID[0] > 255)
85 {
86 gColorID[0] = 0;
87 gColorID[1]++;
88 if(gColorID[1] > 255)
89 {
90 gColorID[1] = 0;
91 gColorID[2]++;
92 }
93 }
94 wingl -> color_to_pick[wingl -> to_be_picked] = gColorID[0] + 256*gColorID[1] + 256*256*gColorID[2];
95 colo.red = gColorID[0]/255.0;
96 colo.green = gColorID[1]/255.0;
97 colo.blue = gColorID[2]/255.0;
98 colo.alpha = 1.0;
99 wingl -> to_be_picked ++;
100 }
101 else if (picked)
102 {
103 if (field_color)
104 {
105 colo = init_color (proj_gl -> atoms[step][j].coord[4], num_field_objects);
106 colo.alpha = DEFAULT_OPACITY*0.75;
107 }
108 else
109 {
110 colo = plot -> sel_color[(picked == 1) ? 0 : 1];
111 }
112 }
113 else
114 {
115 if (acolorm == 0)
116 {
117 colo.red = plot -> at_color[s].red;
118 colo.green = plot -> at_color[s].green;
119 colo.blue = plot -> at_color[s].blue;
120 colo.alpha = al;// * plot -> m_terial.param[5];
121 }
122 else if (acolorm < 5)
123 {
124 if (acolorm < 3)
125 {
126 s -= proj_sp*(s/proj_sp);
127 }
128 else
129 {
130 s = 0;
131 }
132 int k = proj_gl -> atoms[step][j].coord[acolorm -1];
133 colo.red = plot -> spcolor[acolorm - 1][s][k].red;
134 colo.green = plot -> spcolor[acolorm - 1][s][k].green;
135 colo.blue = plot -> spcolor[acolorm - 1][s][k].blue;
136 colo.alpha = al;// * plot -> m_terial.param[5];
137 }
138 else if (acolorm == 5)
139 {
141 if (fmol)
142 {
143 s = proj_gl -> atoms[0][j].fid;
144 m = fmol -> mol -> natoms;
145 }
146 else
147 {
148 s = 0;
149 m = 1;
150 }
151 colo = init_color (s, m);
152 colo.alpha = al;// * plot -> m_terial.param[5];
153 }
154 else if (acolorm == 6)
155 {
156 colo.red = wingl -> custom_map -> colors[step][j].red;
157 colo.blue = wingl -> custom_map -> colors[step][j].blue;
158 colo.green = wingl -> custom_map -> colors[step][j].green;
159 colo.alpha = wingl -> custom_map -> colors[step][j].alpha;
160 }
161 }
162 return colo;
163}
164
165int nbs, nbl, nba;
166
175{
176 return qual * qual;
177}
178
187{
188 return 2 * qual * (qual - 1);
189}
190
198object_3d * draw_sphere (int quality)
199{
200 float theta, phi;
201 float cos_phi, sin_phi;
202 float xPos, yPos, zPos;
203 int stack, slice;
204 int x, y, z;
205
206 object_3d * new_sphere = g_malloc0 (sizeof*new_sphere);
207 new_sphere -> quality = quality;
208 new_sphere -> num_vertices = sphere_vertices (quality);
209 new_sphere -> vert_buffer_size = 3;
210 new_sphere -> vertices = allocfloat (3*new_sphere -> num_vertices);
211 new_sphere -> num_indices = sphere_indices (quality);
212 new_sphere -> ind_buffer_size = 1;
213 new_sphere -> indices = allocint (new_sphere -> num_indices);
214 x = 0;
215 for (stack=0; stack <= quality-1; stack++)
216 {
217 phi = pi * stack / (quality-1);
218 cos_phi = cos(phi);
219 sin_phi = sin(phi);
220 for (slice=0; slice <= quality-1; slice++)
221 {
222 theta = 2.0 * pi * slice / (quality-1);
223 xPos = cos(theta) * sin_phi;
224 yPos = cos_phi;
225 zPos = sin(theta) * sin_phi;
226 new_sphere -> vertices[3*x] = xPos;
227 new_sphere -> vertices[3*x+1] = yPos;
228 new_sphere -> vertices[3*x+2] = zPos;
229 x ++;
230 }
231 }
232
233 gboolean oddRow = FALSE;
234 z = 0;
235 for (y = 0; y < quality-1; y++)
236 {
237 if (!oddRow) // even rows: y == 0, y == 2; and so on
238 {
239 for (x = 0; x <= quality-1; x++)
240 {
241 new_sphere -> indices[z] = (y * quality + x);
242 new_sphere -> indices[z+1]= ((y + 1) * quality + x);
243 z += 2;
244 }
245 }
246 else
247 {
248 for (x = quality-1; x >= 0; x--)
249 {
250 new_sphere -> indices[z] = ((y + 1) * quality + x);
251 new_sphere -> indices[z+1] = (y * quality + x);
252 z += 2;
253 }
254 }
255 oddRow = !oddRow;
256 }
257 return new_sphere;
258}
259
270float get_sphere_radius (int style, int sp, int ac, int sel)
271{
272 if (style == WIREFRAME || style == PUNT)
273 {
274 return plot -> pointrad[sp + ac*proj_sp] + sel*4.0;
275 }
276 else if (style == SPACEFILL)
277 {
278 return plot -> atomicrad[sp + ac*proj_sp] + sel*0.05;
279 }
280 else if (style == CYLINDERS)
281 {
282 return plot -> radall[ac] + sel*0.1;
283 }
284 else
285 {
286 return plot -> sphererad[sp + ac*proj_sp] + sel*0.05;
287 }
288}
289
301void setup_sphere_vertice (float * vertices, vec3_t pos, ColRGBA col, float rad, float alpha)
302{
303 int l;
305 vertices[l] = pos.x;
306 vertices[l+1] = pos.y;
307 vertices[l+2] = pos.z;
308 vertices[l+3] = rad;
309 vertices[l+4] = col.red;
310 vertices[l+5] = col.green;
311 vertices[l+6] = col.blue;
312 vertices[l+7] = col.alpha * alpha;
313 nbl ++;
314}
315
329void setup_this_atom (int style, gboolean to_pick, gboolean picked, atom * at, int ac, float * vert, float al)
330{
331 int i, j, k;
332 float alpha = 1.0;
333 float shift[3];
334 ColRGBA col = get_atom_color (at -> sp, at -> id, 1.0, picked, to_pick);
335 if (at -> sp > proj_sp - 1) at -> sp -= proj_sp;
336 float rad = get_sphere_radius ((style == NONE) ? plot -> style : style, at -> sp, ac, (picked) ? 1 : 0);
337 for (i=0; i<plot -> abc -> extra_cell[0]+1;i++)
338 {
339 for (j=0; j<plot -> abc -> extra_cell[1]+1; j++)
340 {
341 for (k=0; k<plot -> abc -> extra_cell[2]+1; k++)
342 {
343 shift[0]=i*box_gl -> vect[0][0]+j*box_gl -> vect[1][0]+k*box_gl -> vect[2][0];
344 shift[1]=i*box_gl -> vect[0][1]+j*box_gl -> vect[1][1]+k*box_gl -> vect[2][1];
345 shift[2]=i*box_gl -> vect[0][2]+j*box_gl -> vect[1][2]+k*box_gl -> vect[2][2];
346 at_shift (at, shift);
347 setup_sphere_vertice (vert, vec3(at -> x, at -> y, at -> z), col, rad, (to_pick) ? 1.0 : alpha*al);
348 at_unshift (at, shift);
349 alpha = 0.5;
350 }
351 }
352 }
353}
354
362int find_atom_vertices (gboolean to_pick)
363{
364 int i, j;
365 j = 0;
366 for (i=0; i<proj_at; i++)
367 {
368 if (in_movie_encoding && plot -> at_data != NULL)
369 {
370 if (plot -> at_data[i].show[0])
371 {
372 if (to_pick)
373 {
374 all_styles[0] ++;
375 }
376 else
377 {
378 all_styles[plot -> at_data[i].style + 1] ++;
379 }
380 j ++;
381 }
382 }
383 else
384 {
385 if (proj_gl -> atoms[step][i].show[0])
386 {
387 if (to_pick)
388 {
389 all_styles[0] ++;
390 }
391 else
392 {
393 all_styles[proj_gl -> atoms[step][i].style + 1] ++;
394 }
395 j ++;
396 }
397 }
398 }
399 return j;
400}
401
411void setup_atom_vertices (int style, gboolean to_pick, float * vertices)
412{
413 int i;
414 atom * tmp_a;
415 for (i=0; i<proj_at; i++)
416 {
418 if (in_movie_encoding && plot -> at_data != NULL)
419 {
420 tmp_a -> show[0] = plot -> at_data[i].show[0];
421 tmp_a -> style = plot -> at_data[i].style;
422 }
423 if (tmp_a -> show[0] && (tmp_a -> style == style || to_pick))
424 {
425 setup_this_atom (style, to_pick, 0, tmp_a, 0, vertices, 1.0);
426 }
427 g_free (tmp_a);
428 }
429}
430
446void prepare_clone (int style, gboolean to_pick, int picked, atom at, atom bt, float x, float y, float z, float * vertices)
447{
448 atom * tmp_a = duplicate_atom (& bt);
449 tmp_a -> x += x;
450 tmp_a -> y += y;
451 tmp_a -> z += z;
452 tmp_a -> id = at.id;
453 tmp_a -> sp = at.sp + proj_sp;
454 int sty = at.style;
455 if (in_movie_encoding && plot -> at_data != NULL)
456 {
457 tmp_a -> show[1] = plot -> at_data[at.id].show[1];
458 sty = plot -> at_data[at.id].style;
459 }
460 if (at.show[1] && (sty == style || to_pick))
461 {
462 setup_this_atom (style, to_pick, picked, tmp_a, 1, vertices, 0.5);
463 }
464 g_free (tmp_a);
465}
466
474int find_clone_vertices (gboolean to_pick)
475{
476 int i, j, k, l;
477 l = 0;
478 for (i=0; i < wingl -> bonds[step][1]; i++)
479 {
480 j = wingl -> bondid[step][1][i][0];
481 k = wingl -> bondid[step][1][i][1];
482 if (in_movie_encoding && plot -> at_data != NULL)
483 {
484 if (plot -> at_data[j].show[1])
485 {
486 if (to_pick)
487 {
488 all_styles[0] ++;
489 }
490 else
491 {
492 all_styles[plot -> at_data[j].style + 1] ++;
493 }
494 l++;
495 }
496 if (plot -> at_data[k].show[1])
497 {
498 if (to_pick)
499 {
500 all_styles[0] ++;
501 }
502 else
503 {
504 all_styles[plot -> at_data[k].style + 1] ++;
505 }
506 l++;
507 }
508 }
509 else
510 {
511 if (proj_gl -> atoms[step][j].show[1])
512 {
513 if (to_pick)
514 {
515 all_styles[0] ++;
516 }
517 else
518 {
519 all_styles[proj_gl -> atoms[step][j].style + 1] ++;
520 }
521 l ++;
522 }
523 if (proj_gl -> atoms[step][k].show[1])
524 {
525 if (to_pick)
526 {
527 all_styles[0] ++;
528 }
529 else
530 {
531 all_styles[proj_gl -> atoms[step][k].style + 1] ++;
532 }
533 l ++;
534 }
535 }
536 }
537 return l;
538}
539
549void setup_clone_vertices (int style, gboolean to_pick, float * vertices)
550{
551 int i, j, k;
552 for (i=0; i < wingl -> bonds[step][1]; i++)
553 {
554 j = wingl -> bondid[step][1][i][0];
555 k = wingl -> bondid[step][1][i][1];
556 prepare_clone (style, to_pick, 0,
557 proj_gl -> atoms[step][j],
558 proj_gl -> atoms[step][k],
559 wingl -> clones[step][i].x,
560 wingl -> clones[step][i].y,
561 wingl -> clones[step][i].z, vertices);
562 prepare_clone (style, to_pick, 0,
563 proj_gl -> atoms[step][k],
564 proj_gl -> atoms[step][j],
565 -wingl -> clones[step][i].x,
566 -wingl -> clones[step][i].y,
567 -wingl -> clones[step][i].z, vertices);
568
569 }
570}
571
581void atom_positions_colors_and_sizes (int style, gboolean to_pick, float * instances)
582{
583 setup_atom_vertices (style, to_pick, instances);
584 if (to_pick) wingl -> atoms_to_be_picked = wingl -> clones_to_be_picked = wingl -> to_be_picked;
585 if (plot -> draw_clones)
586 {
587 setup_clone_vertices (style, to_pick, instances);
588 if (to_pick) wingl -> clones_to_be_picked = wingl -> to_be_picked;
589 }
590}
591
599void create_atom_lists (gboolean to_pick)
600{
601 int i, j, k;
602 object_3d * atos;
603 gboolean sphere = TRUE;
604
605 if (! to_pick)
606 {
608 wingl -> create_shaders[ATOMS] = FALSE;
609 }
610
611 for (i=0; i<NUM_STYLES; i++) all_styles[i] = 0;
612 j = find_atom_vertices (to_pick);
613 if (plot -> draw_clones) j += find_clone_vertices (to_pick);
614#ifdef DEBUG
615 g_debug ("Atom LIST:: to_pick= %s, Atom(s) to render= %d", (to_pick) ? "true" : "false", j);
616#endif
617 if (j > 0)
618 {
619 // Render atom(s)
620 j = (plot -> abc -> extra_cell[0]+1)*(plot -> abc -> extra_cell[1]+1)*(plot -> abc -> extra_cell[2]+1);
621 if (! to_pick)
622 {
623 wingl -> n_shaders[ATOMS][step] = 0;
624 for (i=0; i<NUM_STYLES; i++) if (all_styles[i]) wingl -> n_shaders[ATOMS][step] ++;
625 wingl -> ogl_glsl[ATOMS][step] = g_malloc0 (wingl -> n_shaders[ATOMS][step]*sizeof*wingl -> ogl_glsl[ATOMS][step]);
626 }
627 k = 0;
628 for (i=0; i<NUM_STYLES; i++)
629 {
630 sphere = TRUE;
631 if (all_styles[i] || to_pick)
632 {
633 if (! i)
634 {
635 if (plot -> style == WIREFRAME || plot -> style == PUNT) sphere = FALSE;
636 }
637 else
638 {
639 if (i-1 == WIREFRAME || i-1 == PUNT) sphere = FALSE;
640 }
641 if (sphere)
642 {
643 atos = draw_sphere (plot -> quality);
644 }
645 else
646 {
647 atos = g_malloc0 (sizeof*atos);
648 atos -> vert_buffer_size = 3;
649 atos -> num_vertices = 1;
650 atos -> vertices = allocfloat (3);
651 atos -> vertices[0] = atos -> vertices[1] = atos -> vertices[2] = 0.0;
652 }
653 atos -> num_instances = j*all_styles[i];
654 atos -> inst_buffer_size = ATOM_BUFF_SIZE;
655 atos -> instances = allocfloat (j*all_styles[i]*ATOM_BUFF_SIZE);
656 nbl = 0;
657 atom_positions_colors_and_sizes (i-1, to_pick, atos -> instances);
658 if (! to_pick)
659 {
660 if (sphere)
661 {
662 wingl -> ogl_glsl[ATOMS][step][k] = init_shader_program (ATOMS, GLSL_SPHERES, sphere_vertex, NULL, full_color, GL_TRIANGLE_STRIP, 4, 1, TRUE, atos);
663 }
664 else
665 {
666 wingl -> ogl_glsl[ATOMS][step][k] = init_shader_program (ATOMS, GLSL_POINTS, point_vertex, NULL, point_color, GL_POINTS, 4, 1, FALSE, atos);
667 }
668 }
669 else
670 {
671 wingl -> ogl_glsl[PICKS][0][0] = init_shader_program (PICKS, GLSL_SPHERES, sphere_vertex, NULL, full_color, GL_TRIANGLE_STRIP, 4, 1, FALSE, atos);
672 }
673 g_free (atos);
674 k ++;
675 }
676 if (to_pick) break;
677 }
678 }
679}
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:165
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:581
int gColorID[3]
Definition d_atoms.c:61
int all_styles[NUM_STYLES]
Definition d_atoms.c:62
int sphere_indices(int qual)
return the number of OpenGL indices to render a sphere
Definition d_atoms.c:186
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:329
object_3d * draw_sphere(int quality)
OpenGL 3D sphere object rendering.
Definition d_atoms.c:198
float get_sphere_radius(int style, int sp, int ac, int sel)
get an atom sphere radius
Definition d_atoms.c:270
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:301
void setup_atom_vertices(int style, gboolean to_pick, float *vertices)
prepare an atom OpenGL rendering
Definition d_atoms.c:411
int nbs
Definition d_atoms.c:165
int atom_id
Definition d_atoms.c:60
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:549
int nbl
Definition d_atoms.c:165
int sphere_vertices(int qual)
return the number of OpenGL vertices to render a sphere
Definition d_atoms.c:174
void create_atom_lists(gboolean to_pick)
prepare atom(s) and clone(s) OpenGL rendering
Definition d_atoms.c:599
ColRGBA get_atom_color(int i, int j, double al, int picked, gboolean to_pick)
get atom (or clone) color
Definition d_atoms.c:75
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:446
int find_clone_vertices(gboolean to_pick)
find the number of clones to render
Definition d_atoms.c:474
int find_atom_vertices(gboolean to_pick)
find the number of atom(s) to render
Definition d_atoms.c:362
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:314
float * allocfloat(int val)
allocate a float * pointer
Definition global.c:398
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:70
void at_unshift(atom *at, float *shift)
correct atomic coordinates modified to display image in cell replica
Definition ogl_draw.c:495
project * proj_gl
Definition ogl_draw.c:64
glwin * wingl
Definition ogl_draw.c:63
int proj_sp
Definition ogl_draw.c:65
void at_shift(atom *at, float *shift)
modify atomic coordinates to display image in cell replica
Definition ogl_draw.c:480
#define DEFAULT_OPACITY
Default OpenGL opacity.
Definition glview.h:75
box_info * box_gl
Definition ogl_draw.c:68
void cleaning_shaders(glwin *view, int shader)
re-initialize an OpenGL shader
int qual
Definition ogl_draw.c:71
#define NUM_STYLES
Definition glview.h:177
int step
Definition ogl_draw.c:74
int acolorm
Definition ogl_draw.c:72
atom * duplicate_atom(atom *at)
copy (partially) an atom data structure
Definition ogl_draw.c:444
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:66
@ SPACEFILL
Definition glview.h:184
@ CYLINDERS
Definition glview.h:186
@ WIREFRAME
Definition glview.h:183
@ NONE
Definition glview.h:181
@ PUNT
Definition glview.h:187
@ PICKS
Definition glwin.h:97
@ ATOMS
Definition glwin.h:89
double z
Definition ogl_draw.c:61
double y
Definition ogl_draw.c:61
double x
Definition ogl_draw.c:61
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:53
@ GLSL_POINTS
Definition ogl_shading.h:38
@ GLSL_SPHERES
Definition ogl_shading.h:39
Preference variable declarations.
float blue
Definition global.h:126
float alpha
Definition global.h:127
float red
Definition global.h:124
float green
Definition global.h:125
Definition global.h:891
int sp
Definition global.h:893
int id
Definition global.h:892
int style
Definition global.h:931
gboolean show[2]
Definition global.h:927
int style
Definition glwin.h:465
coord_info * coord
Definition global.h:961
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:73