atomes 1.1.16
atomes: an atomic scale modeling tool box
Loading...
Searching...
No Matches
d_rings.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_rings.c'
24*
25* Contains:
26*
27
28 - The functions to prepare the OpenGL rendering of rings polyhedra
29
30*
31* List of functions:
32
33 int prepare_rings_gl (float * vertices, int se, int ge, int ta, int id, gboolean go);
34
35 void create_ring_lists ();
36
37*/
38
39#include "global.h"
40#include "glview.h"
41#include "color_box.h"
42
43extern ColRGBA pcol;
44extern int nbs, nbl, nba;
45extern void setup_tetrahedron (float * vertices, GLfloat ** xyz);
46extern void setup_polyhedron (float * vertices, GLfloat ** xyz, int s);
47extern void get_centroid (GLfloat ** xyz, int id);
48extern void check_triangles (int s, GLfloat ** xyz);
49
62int prepare_rings_gl (float * vertices, int se, int ge, int ta, int id, gboolean go)
63{
64 int i, j, k, l, m;
65 gboolean clones;
66 gboolean add_poly;
67 gboolean old_pbc;
68 GLfloat *** xyz;
69 distance d;
70 atom at, bt;
71
72 xyz = alloctfloat (ta, ta, 3);
73 j = -1;
74
75 clones = FALSE;
76 j = wingl -> all_rings[se][step][ta-1][id][0];
77 l = 0;
78 xyz[0][l][0] = proj_gl -> atoms[step][j].x;
79 xyz[0][l][1] = proj_gl -> atoms[step][j].y;
80 xyz[0][l][2] = proj_gl -> atoms[step][j].z;
81 for (i=1; i < ta; i++)
82 {
83 j = wingl -> all_rings[se][step][ta-1][id][i];
84 at = proj_gl -> atoms[step][j];
85 bt.x = xyz[0][i-1][0];
86 bt.y = xyz[0][i-1][1];
87 bt.z = xyz[0][i-1][2];
88 d = distance_3d (cell_gl, (cell_gl -> npt) ? step : 0, & at, & bt);
89 if (d.pbc) clones = TRUE;
90 xyz[0][i][0] = xyz[0][i-1][0] + d.x;
91 xyz[0][i][1] = xyz[0][i-1][1] + d.y;
92 xyz[0][i][2] = xyz[0][i-1][2] + d.z;
93 }
94 l = ta;
95 m = 0;
96 if (clones)
97 {
98 old_pbc = cell_gl -> pbc;
99 cell_gl -> pbc = FALSE;
100 add_poly = TRUE;
101 while (add_poly)
102 {
103 for (i=0; i<ta; i++)
104 {
105 j = wingl -> all_rings[se][step][ta-1][id][i];
106 at = proj_gl -> atoms[step][j];
107 add_poly = TRUE;
108 for (k=0; k<m+1; k++)
109 {
110 bt.x = xyz[k][i][0];
111 bt.y = xyz[k][i][1];
112 bt.z = xyz[k][i][2];
113 d = distance_3d (cell_gl, (cell_gl -> npt) ? step : 0, & at, & bt);
114 if (d.length < 0.01)
115 {
116 add_poly = FALSE;
117 break;
118 }
119 }
120 if (add_poly) break;
121 }
122 if (add_poly)
123 {
124 m ++;
125 bt.x = xyz[0][i][0];
126 bt.y = xyz[0][i][1];
127 bt.z = xyz[0][i][2];
128 d = distance_3d (cell_gl, (cell_gl -> npt) ? step : 0, & at, & bt);
129 for (j=0; j<ta; j++)
130 {
131 xyz[m][j][0] = xyz[0][j][0] + d.x;
132 xyz[m][j][1] = xyz[0][j][1] + d.y;
133 xyz[m][j][2] = xyz[0][j][2] + d.z;
134 }
135 }
136 }
137 cell_gl -> pbc = old_pbc;
138 }
139 if (! go) return m+1;
140
141 if (plot -> draw_clones || ! clones || plot -> cloned_poly)
142 {
143 for (i=0; i<m+1; i++)
144 {
145 // Set color
146 pcol = plot -> spcolor[4+se][0][ge];
147 get_centroid (xyz[i], l);
148 if (l == 4)
149 {
150 setup_tetrahedron (vertices, xyz[i]);
151 }
152 else
153 {
154 check_triangles (l, xyz[i]);
155 setup_polyhedron (vertices, xyz[i], l);
156 }
157 }
158 }
159 g_free (xyz);
160 xyz = NULL;
161 return 0;
162}
163
170{
171 // The order to draw the polyhedra could be based on the alpha channel
172 // from the most transparent to the less transparent
173 // However a better way is to used the neighbor list, if 3 atoms are linked thru bonds
174 // and that all 3 of them are involved in polyhedra then the one at
175 // the center is to be drawn first ... yet to be implemented
176 int i, j, k, l, m, n;
177#ifdef DEBUG
178 g_debug ("Ring LIST");
179#endif
181 if (wingl -> rings)
182 {
183 int rtot = 0;
184 int * nrings[5];
185 for (i=0; i < 5; i++)
186 {
187 nrings[i] = g_malloc0 (coord_gl -> totcoord[i+4]*sizeof*nrings[i]);
188 for (j=0; j < coord_gl -> totcoord[i+4]; j++)
189 {
190 // k is the size of the ring in total number of atoms:
191 k = coord_gl -> geolist[i+4][0][j];
192 l = 0;
193 if (plot -> show_poly[i+4][j])
194 {
195 // Show all rings
196 for (m = 0; m < wingl -> num_rings[i][step][k-1]; m++)
197 {
198 l += prepare_rings_gl (NULL, i, j, k, m, FALSE);
199 }
200 }
201 else if (! in_movie_encoding || plot -> i_rings[i] == NULL)
202 {
203 // Show selected rings
204 for (m=0; m < wingl -> num_rings[i][step][k-1]; m++)
205 {
206 if (wingl -> show_rpoly[i][step][k-1][m])
207 {
208 l += prepare_rings_gl (NULL, i, j, k, m, FALSE);
209 }
210 }
211 }
212 // m is the number of summit of the polyhedra
213 // +1 if only a 3 atom size ring to include a centroid
214 m = (k == 3) ? k+1: k;
215 // Then we need the max number of triangles for all these polyedron
216 nrings[i][j] = l*(m*(m-1)*(m-2)/6);
217 rtot += nrings[i][j]*3;
218 }
219 if (in_movie_encoding && plot -> i_rings[i] != NULL)
220 {
221 for (l=0; l<plot -> i_rings[i][0][0]; l++)
222 {
223 j = plot -> i_rings[i][l+1][0];
224 k = coord_gl -> geolist[i+4][0][j];
225 m = prepare_rings_gl (NULL, i, j, k, plot -> i_rings[i][l+1][1], FALSE);
226 if (m)
227 {
228 n = (k == 3) ? k+1: k;
229 nrings[i][j] += (n*(n-1)*(n-2)/6);
230 rtot += (n*(n-1)*(n-2)/6)*3;
231 }
232 }
233 }
234 }
235 if (rtot > 0)
236 {
237 wingl -> ogl_glsl[RINGS][step] = g_malloc0 (sizeof*wingl -> ogl_glsl[RINGS][step]);
238 wingl -> n_shaders[RINGS][step] = 1;
239 object_3d * rings = g_malloc0 (sizeof*rings);
240 rings -> vert_buffer_size = POLY_BUFF_SIZE;
241 rings -> num_vertices = rtot * (plot -> extra_cell[0]+1)*(plot -> extra_cell[1]+1)*(plot -> extra_cell[2]+1);
242 rings -> vertices = allocfloat (rings -> vert_buffer_size*rings -> num_vertices);
243 nba = 0;
244 for (i=0; i < 5; i++)
245 {
246 for (j=0; j < coord_gl -> totcoord[i+4]; j++)
247 {
248 if (nrings[i][j])
249 {
250 k = coord_gl -> geolist[i+4][0][j];
251 if (plot -> show_poly[i+4][j])
252 {
253 for (l=0; l < wingl -> num_rings[i][step][k-1]; l++)
254 {
255 prepare_rings_gl (rings -> vertices, i, j, k, l, TRUE);
256 }
257 }
258 else if (! in_movie_encoding || plot -> i_rings[i] == NULL)
259 {
260 for (l=0; l < wingl -> num_rings[i][step][k-1]; l++)
261 {
262 if (wingl -> show_rpoly[i][step][k-1][l])
263 {
264 prepare_rings_gl (rings -> vertices, i, j, k, l, TRUE);
265 }
266 }
267 }
268 }
269 }
270 if (in_movie_encoding && plot -> i_rings[i] != NULL)
271 {
272 for (l=0; l<plot -> i_rings[i][0][0]; l++)
273 {
274 j = plot -> i_rings[i][l+1][0];
275 k = coord_gl -> geolist[i+4][0][j];
276 prepare_rings_gl (rings -> vertices, i, j, k, plot -> i_rings[i][l+1][1], TRUE);
277 }
278 }
279 }
280 wingl -> ogl_glsl[RINGS][step][0] = init_shader_program (RINGS, GLSL_POLYEDRA, full_vertex, NULL, full_color, GL_TRIANGLES, 3, 1, TRUE, rings);
281 g_free (rings);
282 }
283 }
284 wingl -> create_shaders[RINGS] = FALSE;
285}
286
Structure definitions for color management Function declarations for color management.
atom * ta
Definition d_measures.c:70
int nba
Definition d_rings.c:44
void check_triangles(int s, GLfloat **xyz)
check triangle intersection
Definition d_poly.c:360
void create_ring_lists()
prepare ring(s) polyhedra OpenGL rendering
Definition d_rings.c:169
void get_centroid(GLfloat **xyz, int id)
find the barycenter of a polyhedron
Definition d_poly.c:267
int prepare_rings_gl(float *vertices, int se, int ge, int ta, int id, gboolean go)
prepare a ring polyhedra OpenGL rendering
Definition d_rings.c:62
ColRGBA pcol
Definition d_poly.c:60
int nbs
Definition d_atoms.c:176
int nbl
Definition d_rings.c:44
void setup_tetrahedron(float *vertices, GLfloat **xyz)
fill the OpenGL data buffer for a tetrahedra to render
Definition d_poly.c:227
void setup_polyhedron(float *vertices, GLfloat **xyz, int s)
fill the OpenGL data buffer for a polyhedron to render
Definition d_poly.c:152
int atoms[NUM_STYLES][2]
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
gboolean in_movie_encoding
Definition global.c:180
float * allocfloat(int val)
allocate a float * pointer
Definition global.c:398
float *** alloctfloat(int xal, int yal, int zal)
allocate a float *** pointer
Definition global.c:437
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
void cleaning_shaders(glwin *view, int shader)
re-initialize an OpenGL shader
int step
Definition ogl_draw.c:70
coord_info * coord_gl
Definition ogl_draw.c:63
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
cell_info * cell_gl
Definition ogl_draw.c:65
@ RINGS
Definition glwin.h:96
G_MODULE_EXPORT void cloned_poly(GtkWidget *widg, gpointer data)
cloned polyehdra callback - GTK3
Definition m_poly.c:181
const GLchar * full_color
const GLchar * full_vertex
#define POLY_BUFF_SIZE
Definition ogl_shading.h:48
@ GLSL_POLYEDRA
Definition ogl_shading.h:43
Definition global.h:886
double z
Definition global.h:892
double y
Definition global.h:891
double x
Definition global.h:890
double x
Definition glwin.h:124
int d
Definition tab-1.c:95