1 /*   EXTRAITS DE LA LICENCE
2 	Copyright CEA, contributeurs : Damien
3 	CALISTE, laboratoire L_Sim, (2001-2009)
4         David WAROQUIERS, PCPM UC Louvain la Neuve (2009)
5 
6 	Adresse mèl :
7 	WAROQUIERS, david P waroquiers AT uclouvain P be
8 	CALISTE, damien P caliste AT cea P fr.
9 
10 	Ce logiciel est un programme informatique servant à visualiser des
11 	structures atomiques dans un rendu pseudo-3D.
12 
13 	Ce logiciel est régi par la licence CeCILL soumise au droit français et
14 	respectant les principes de diffusion des logiciels libres. Vous pouvez
15 	utiliser, modifier et/ou redistribuer ce programme sous les conditions
16 	de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
17 	sur le site "http://www.cecill.info".
18 
19 	Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
20 	pris connaissance de la licence CeCILL, et que vous en avez accepté les
21 	termes (cf. le fichier Documentation/licence.fr.txt fourni avec ce logiciel).
22 */
23 
24 /*   LICENCE SUM UP
25 	Copyright CEA, contributors : Damien
26 	CALISTE, laboratoire L_Sim, (2001-2009)
27         David WAROQUIERS, PCPM UC Louvain la Neuve (2009)
28 
29 	E-mail address:
30 	CALISTE, damien P caliste AT cea P fr
31 	WAROQUIERS, david P waroquiers AT uclouvain P be
32 
33 	This software is a computer program whose purpose is to visualize atomic
34 	configurations in 3D.
35 
36 	This software is governed by the CeCILL  license under French law and
37 	abiding by the rules of distribution of free software.  You can  use,
38 	modify and/ or redistribute the software under the terms of the CeCILL
39 	license as circulated by CEA, CNRS and INRIA at the following URL
40 	"http://www.cecill.info".
41 
42 	The fact that you are presently reading this means that you have had
43 	knowledge of the CeCILL license and that you accept its terms. You can
44 	find a copy of this licence shipped with this software at COPYING.
45 */
46 #include "rings.h"
47 
48 #include <string.h>
49 #include <math.h>
50 
51 #include <extraFunctions/plane.h>
52 #include <coreTools/toolMatrix.h>
53 
54 #include <openGLFunctions/objectList.h>
55 
56 /**
57  * SECTION: rings
58  * @short_description: an extension to highlight closed rings in a structure.
59  *
60  * <para>TODO</para>
61  */
62 
63 static VisuGlExt* extRings;
64 static gboolean extRingsIsBuilt;
65 /* static gulong popInc_signal, popDec_signal, popChg_signal; */
66 
67 /* Local callbacks. */
68 /* static void onNodePopulationChanged(VisuData *dataObj, GArray *nodes, gpointer data); */
69 /* static void onPositionChanged(VisuData *dataObj, gpointer data _U_); */
70 
71 /* Local routines. */
72 /* static void rebuildRings(VisuGlExt *ext, VisuData *dataObj, */
73 /*                          VisuGlView *view, gpointer data); */
74 void changeCoordfromBoxChange(VisuData *dataObj, float *coord, float boxChange[3], float *newcoord);
75 
76 
77 #define RADTODEG 57.29577951
78 
79 /* Some test rings that are relevant */
80 #define NB_NODES8 8
81 #define NB_NODES16 16
82 #define NB_NODES10 10
83 #define NB_NODES5 5
84 
85 #define NB_NODES NB_NODES16
86 
87 int testring_1[NB_NODES8] = {30,69,14,60,2,55,31,71}; /* NB_NODES 8*/
88 int testring_2[NB_NODES8] = {10,53,15,50,22,71,11,67}; /* NB_NODES 8*/
89 int testring_3[NB_NODES16] = {2,55,46,64,4,67,11,71,30,69,45,56,6,65,3,60}; /* NB_NODES 16*/
90 int testring_4[NB_NODES16] = {6,56,45,69,30,71,11,67,10,53,43,63,23,51,35,65}; /* NB_NODES 16*/
91 int testring[NB_NODES16] = {22,50,9,68,36,63,23,51,35,65,3,60,14,69,30,71}; /* NB_NODES 16*/
92 int testring_6[NB_NODES10] = {26,54,47,69,30,71,31,55,21,66}; /* NB_NODES 10*/
93 int testring_7[NB_NODES5] = {60,39,8,61,14}; /* NB_NODES 10*/
94 
95 
96 
97 typedef struct
98 {
99   int drawSpheres;
100   int drawCylinders;
101   int drawTrianglePlanars;
102   float sphereRadius;
103   float sphereColor[4];
104   float cylinderRadius;
105   float cylinderColor[4];
106   float trianglePlanarsColor[4];
107 } ringVisualisation;
108 
109 /**
110  * initExtRings: (skip)
111  *
112  * Initialise the ring extension, internal routine, do not use.
113  *
114  * Since: 3.5
115  *
116  * Returns: a newly allocated #VisuGlExt.
117  */
initExtRings()118 VisuGlExt* initExtRings()
119 {
120   /* char *name = EXT_RINGS_ID; */
121   /* char *description = _("Draw a representation for the rings in an atomic structures."); */
122 
123   DBG_fprintf(stderr,"Ext Rings: initialising the rings OpenGL extension...\n");
124 
125   /* extRings  = visu_gl_ext_new(name, _(name), description, */
126   /*                                1, rebuildRings, (gpointer)0); */
127   /* visu_gl_ext_setActive(extRings, FALSE); */
128   extRings = (VisuGlExt*)0;
129 
130   extRingsIsBuilt = FALSE;
131 
132   /* Disable rings extension for now. */
133   return extRings;
134 }
135 /**
136  * extRingsSet_isOn:
137  * @value: a boolean.
138  *
139  * Set if rings are drawn or not.
140  *
141  * Since: 3.5
142  *
143  * Returns: TRUE is status is changed.
144  */
extRingsSet_isOn(gboolean value)145 gboolean extRingsSet_isOn(gboolean value)
146 {
147   if (!visu_gl_ext_setActive(extRings, value))
148     return FALSE;
149 
150   return (value && !extRingsIsBuilt);
151 }
152 /**
153  * extRingsGet_isOn:
154  *
155  * Retrieves if the ring extension is used.
156  *
157  * Since: 3.5
158  *
159  * Returns: TRUE if ring extension is used.
160  */
extRingsGet_isOn()161 gboolean extRingsGet_isOn()
162 {
163   return visu_gl_ext_getActive(extRings);
164 }
165 
166 /* static void onDataReadySignal(GObject *obj _U_, VisuData *dataObj, */
167 /*                               VisuGlView *view, gpointer data _U_) */
168 /* { */
169 /*   DBG_fprintf(stderr, "Ext Rings: catch 'dataRendered' signal.\n"); */
170 /*   if (dataObj && visu_gl_ext_getActive(extRings)) */
171 /*     { */
172 /*       if (visu_data_getChangeElementFlag(dataObj)) */
173 /* 	{ */
174 /* 	  DBG_fprintf(stderr,"Ext Rings: elements not changed, keep it.\n"); */
175 /* 	  return; */
176 /* 	} */
177 /*       extRingsIsBuilt = FALSE; */
178 /*       extRingsDraw(dataObj); */
179 /*     } */
180 /*   if (dataObj && view) */
181 /*     { */
182 /*       popInc_signal = */
183 /*         g_signal_connect(G_OBJECT(dataObj), "PopulationIncrease", */
184 /*                          G_CALLBACK(onNodePopulationChanged), (gpointer)0); */
185 /*       popDec_signal = */
186 /*         g_signal_connect(G_OBJECT(dataObj), "PopulationDecrease", */
187 /*                          G_CALLBACK(onNodePopulationChanged), (gpointer)0); */
188 /*       popChg_signal = */
189 /*         g_signal_connect(G_OBJECT(dataObj), "PositionChanged", */
190 /*                          G_CALLBACK(onPositionChanged), (gpointer)0); */
191 /*     } */
192 /* } */
193 /* static void onDataNotReadySignal(GObject *obj _U_, VisuData *dataObj, */
194 /*                                  VisuGlView *view _U_, gpointer data _U_) */
195 /* { */
196 /*   g_signal_handler_disconnect(G_OBJECT(dataObj), popInc_signal); */
197 /*   g_signal_handler_disconnect(G_OBJECT(dataObj), popDec_signal); */
198 /*   g_signal_handler_disconnect(G_OBJECT(dataObj), popChg_signal); */
199 /* } */
200 /* static void onNodePopulationChanged(VisuData *dataObj, GArray *nodes _U_, */
201 /* 				    gpointer data _U_) */
202 /* { */
203 /*   if (visu_gl_ext_getActive(extRings)) */
204 /*     { */
205 /*       extRingsIsBuilt = FALSE; */
206 /*       extRingsDraw(dataObj); */
207 /*     } */
208 /* } */
209 /* static void onPositionChanged(VisuData *dataObj, gpointer data _U_) */
210 /* { */
211 /*   if (visu_gl_ext_getActive(extRings)) */
212 /*     { */
213 /*       extRingsIsBuilt = FALSE; */
214 /*       extRingsDraw(dataObj); */
215 /*     } */
216 /* } */
217 
218 /* static void rebuildRings(VisuGlExt *ext _U_, VisuData *dataObj, */
219 /*                          VisuGlView *view _U_, gpointer data _U_) */
220 /* { */
221 /*   extRingsIsBuilt = FALSE; */
222 /*   extRingsDraw(dataObj); */
223 /* } */
224 
drawCylinder(float x1,float y1,float z1,float x2,float y2,float z2,float cylRad,int nFaces)225 void drawCylinder(float x1, float y1, float z1, float x2, float y2, float z2, float cylRad, int nFaces)
226 {
227   double vNorm[3];
228   double vDest[3];
229   double cosAlpha;
230   double alpha;
231   double distsq;
232   GLUquadricObj *obj;
233 
234   DBG_fprintf(stderr, "Drawing Cylinder between points (%.4f,%.4f,%.4f) and (%.4f,%.4f,%.4f)\n",x1 , y1 , z1, x2, y2, z2);
235 
236   vDest[0] = x2 - x1;
237   vDest[1] = y2 - y1;
238   vDest[2] = z2 - z1;
239   distsq = (vDest[0]*vDest[0])+(vDest[1]*vDest[1])+(vDest[2]*vDest[2]);
240   if (vDest[0] != 0 || vDest[1] != 0)
241     {
242       vNorm[0] = - vDest[1];
243       vNorm[1] = vDest[0];
244       vNorm[2] = 0.;
245       cosAlpha = sqrt((vDest[2] * vDest[2]) / distsq);
246       if (vDest[2] < 0.)
247         cosAlpha = - cosAlpha;
248       cosAlpha = CLAMP(cosAlpha, -1., 1.);
249       alpha = acos(cosAlpha) * RADTODEG;
250     }
251   else
252     {
253       vNorm[0] = 1.;
254       vNorm[1] = 0.;
255       vNorm[2] = 0.;
256       if (vDest[2] < 0.)
257         alpha = 180.;
258       else
259         alpha = 0.;
260     }
261   obj = gluNewQuadric();
262   glPushMatrix();
263   glTranslated(x1, y1, z1);
264   glRotated(alpha, vNorm[0], vNorm[1], vNorm[2]);
265   gluCylinder(obj, (GLdouble)cylRad, (GLdouble)cylRad,
266 	(GLdouble)sqrt(distsq), (GLint)nFaces, (GLint)1);
267   glPopMatrix();
268   gluDeleteQuadric(obj);
269 }
270 
drawSphere(float x1,float y1,float z1,float sphRad,int longit,int latit)271 void drawSphere(float x1, float y1, float z1, float sphRad, int longit, int latit)
272 {
273   GLUquadricObj *obj;
274 
275   DBG_fprintf(stderr, "Drawing Sphere at point (%.4f,%.4f,%.4f)\n",x1 , y1 , z1);
276   obj = gluNewQuadric();
277   glPushMatrix();
278   glTranslated(x1, y1, z1);
279   gluSphere(obj, sphRad, longit, latit);
280   glPopMatrix();
281   gluDeleteQuadric(obj);
282 }
283 
drawRingPlanar(int ringSize,float * xyzPts,float * boxRing,float bary[3],float baryBox[3])284 void drawRingPlanar(int ringSize, float *xyzPts, float *boxRing, float bary[3], float baryBox[3])
285 {
286   int i;
287   glBegin(GL_TRIANGLES);
288   for (i = 0; i < ringSize-1; i++)
289     {
290       if (baryBox[0] == *(boxRing + i*3) && baryBox[1] == *(boxRing + i*3 + 1) && baryBox[2] == *(boxRing + i*3 + 2))
291         {
292           if (baryBox[0] == *(boxRing + i*3 + 3) && baryBox[1] == *(boxRing + i*3 + 4) && baryBox[2] == *(boxRing + i*3 + 5))
293             {
294               glVertex3fv(bary);
295               glVertex3fv(xyzPts + i*3);
296               glVertex3fv(xyzPts + i*3 + 3);
297             }
298         }
299     }
300   if (baryBox[0] == *(boxRing + (ringSize-1)*3) && baryBox[1] == *(boxRing + (ringSize-1)*3 + 1) && baryBox[2] == *(boxRing + (ringSize-1)*3 + 2))
301     {
302       if (baryBox[0] == *(boxRing) && baryBox[1] == *(boxRing + 1) && baryBox[2] == *(boxRing + 2))
303         {
304           glVertex3fv(bary);
305           glVertex3fv(xyzPts + (ringSize-1)*3);
306           glVertex3fv(xyzPts);
307         }
308     }
309   glEnd();
310 }
311 
computeBaryCenter(VisuData * dataObj,int ringSize,float * xyz,float * boxRing,float * baryCoord,float * baryBox)312 void computeBaryCenter(VisuData *dataObj, int ringSize, float *xyz, float *boxRing, float *baryCoord, float *baryBox)
313 {
314   int i;
315   int bBox[3];
316   float sum[3] = {0.0,0.0,0.0};
317   float tmp[3];
318   float tmp2[3];
319   DBG_fprintf(stderr, "Computing barycenter of the ring\n");
320   for (i = 0; i < ringSize; i++)
321     {
322       tmp[0] = *(boxRing + 3*i);
323       tmp[1] = *(boxRing + 3*i + 1);
324       tmp[2] = *(boxRing + 3*i + 2);
325       tmp2[0] = *(xyz + 3*i);
326       tmp2[1] = *(xyz + 3*i + 1);
327       tmp2[2] = *(xyz + 3*i + 2);
328       changeCoordfromBoxChange(dataObj, tmp2, tmp, baryCoord);
329       sum[0] = sum[0] + *(baryCoord);
330       sum[1] = sum[1] + *(baryCoord + 1);
331       sum[2] = sum[2] + *(baryCoord + 2);
332     }
333   *(baryCoord) = sum[0]/ringSize;
334   *(baryCoord + 1) = sum[1]/ringSize;
335   *(baryCoord + 2) = sum[2]/ringSize;
336   visu_data_getNodeBoxFromCoord(dataObj, baryCoord, bBox);
337   *(baryBox) = (float)bBox[0];
338   *(baryBox + 1) = (float)bBox[1];
339   *(baryBox + 2) = (float)bBox[2];
340   tmp[0] = -*(baryBox);
341   tmp[1] = -*(baryBox + 1);
342   tmp[2] = -*(baryBox + 2);
343   tmp2[0] = *(baryCoord);
344   tmp2[1] = *(baryCoord + 1);
345   tmp2[2] = *(baryCoord + 2);
346   changeCoordfromBoxChange(dataObj, tmp2, tmp, baryCoord);
347   DBG_fprintf(stderr, "Barycenter of the ring :\n   - coordinates (in center box) : %f %f %f \n   - box associated : %f %f %f \n", *(baryCoord), *(baryCoord + 1), *(baryCoord + 2), *(baryBox), *(baryBox + 1), *(baryBox + 2));
348 }
349 
drawRingCylinder(int nbOfPairs,float * xyzPts)350 void drawRingCylinder(int nbOfPairs, float *xyzPts)
351 {
352   float radius = 0.3;
353   int nFaces = 10;
354   int i;
355   for (i = 0; i < nbOfPairs; i++)
356     {
357       drawCylinder((xyzPts + i*6)[0], (xyzPts + i*6)[1], (xyzPts + i*6)[2],
358 	(xyzPts + i*6 + 3)[0],(xyzPts + i*6 + 3)[1], (xyzPts + i*6 + 3)[2], radius, nFaces);
359     }
360 }
361 
drawRingSpheres(int nbOfPairs,float * xyzPts,int * atomInd)362 void drawRingSpheres(int nbOfPairs, float *xyzPts, int *atomInd)
363 {
364   int i;
365   for (i = 0; i < 2*nbOfPairs; i++)
366     {
367       if (*(atomInd + i))
368         drawSphere(*(xyzPts + 3*i), *(xyzPts + 3*i + 1), *(xyzPts + 3*i + 2), 0.4, 10, 10);
369     }
370 }
371 
drawRingLine(int nbOfPairs,float * xyzPts)372 void drawRingLine(int nbOfPairs, float *xyzPts)
373 {
374   int i;
375   glBegin(GL_LINES);
376   for (i = 0; i < nbOfPairs; i++)
377     {
378       glVertex3fv(xyzPts + i * 6);
379       glVertex3fv(xyzPts + i * 6 + 3);
380     }
381   glEnd();
382 }
383 
initTranslationForBoxAndCoord(VisuData * dataObj,int ringSize,float * xyz,float * boxRing)384 void initTranslationForBoxAndCoord(VisuData *dataObj, int ringSize, float *xyz, float *boxRing)
385 {
386   float xyzTrans[3];
387   float boxTrans[3];
388   int i, j, nodeBox[3];
389 
390   visu_pointset_getTranslation(VISU_POINTSET(dataObj), boxTrans);
391   DBG_fprintf(stderr, "Initializing translation for the box indices and coordinates of the ring : \n");
392   DBG_fprintf(stderr, "  with a box translation of %f %f %f\n", boxTrans[0], boxTrans[1], boxTrans[2]);
393   DBG_fprintf(stderr, "Initializing translation for the box indices and coordinates of the ring : \n");
394   for (i = 0; i < ringSize; i++) /* Get the coordinates of the nodes */
395     {
396       for (j = 0; j < 3; j++)
397         {
398           xyzTrans[j] = *(xyz + 3*i + j) + boxTrans[j];
399    /*       *(boxRing + 3*i + j) = *(boxRing + 3*i + j);*/
400         }
401       visu_data_getNodeBoxFromCoord(dataObj, xyzTrans, nodeBox);
402       for (j = 0; j < 3; j++)
403         {
404           DBG_fprintf(stderr, " %d", nodeBox[j]);
405           *(boxRing + 3*i + j) = *(boxRing + 3*i + j) + nodeBox[j];
406         }
407       DBG_fprintf(stderr, "\n");
408     }
409   g_free(boxTrans);
410 }
411 
initRing(VisuData * dataObj _U_,int ringSize,float * xyz _U_,float * boxRing,float * boxChange,int * totNbPts)412 void initRing(VisuData *dataObj _U_, int ringSize, float *xyz _U_, float *boxRing, float *boxChange, int *totNbPts)
413 {
414   int i, j;
415 /*   float initBoxChange[ringSize][3]; */
416 
417   *totNbPts = ringSize;
418   DBG_fprintf(stderr, "Initializing boxChange of a ring : \n");
419 
420   for (i = 0; i < ringSize-1; i++)
421     {
422       for (j = 0; j < 3; j++)
423         {
424           *(boxChange + 3*i + j) = *(boxRing + 3*(i+1) + j) - *(boxRing + 3*i + j);
425           DBG_fprintf(stderr, " %.1f", *(boxChange + 3*i + j));
426         }
427       DBG_fprintf(stderr, "\n");
428     }
429   for (j = 0; j < 3; j++)
430     {
431       *(boxChange + 3*(ringSize-1) + j) = *(boxRing  + j) - *(boxRing + 3*(ringSize-1) + j);
432       DBG_fprintf(stderr, " %.1f", *(boxChange + 3*(ringSize-1) + j));
433     }
434   DBG_fprintf(stderr, "\n");
435   for (i = 0; i < ringSize; i++) /* Calculate the total number of points needed to draw the rings */
436     {
437       for (j = 0; j < 3; j++)
438         {
439           *totNbPts = *totNbPts + ABS(*(boxChange + 3*i + j));
440         }
441     }
442     *totNbPts = *totNbPts * 2;
443     DBG_fprintf(stderr, "Total number of points for this ring (including intersections with the box) : %d \n",*totNbPts);
444 }
445 
changeCoordfromBoxChange(VisuData * dataObj,float * coord,float boxChange[3],float * newcoord)446 void changeCoordfromBoxChange(VisuData *dataObj, float *coord, float boxChange[3], float *newcoord)
447 {
448   float xyz[3], bxyz[3];
449   int i;
450   xyz[0] = *(coord);
451   xyz[1] = *(coord + 1);
452   xyz[2] = *(coord + 2);
453   visu_box_convertXYZtoBoxCoordinates(visu_boxed_getBox(VISU_BOXED(dataObj)), bxyz, xyz);
454   for (i = 0; i < 3; i++)
455     {
456       bxyz[i] = bxyz[i] + boxChange[i];
457     }
458   visu_box_convertBoxCoordinatestoXYZ(visu_boxed_getBox(VISU_BOXED(dataObj)), (float*)newcoord, bxyz);
459   DBG_fprintf(stderr, "Changing coordinate (%f %f %f) from box change (%.1f %.1f %.1f) to (%f %f %f)\n",
460 		xyz[0],xyz[1],xyz[2],boxChange[0],boxChange[1],boxChange[2],*(newcoord),*(newcoord + 1),*(newcoord + 2));
461 }
462 
setVisuPlaneFromBoxChange(VisuData * dataObj,float boxChange[3],VisuPlane * plane)463 void setVisuPlaneFromBoxChange(VisuData *dataObj, float boxChange[3], VisuPlane *plane)
464 {
465   float tmpCoord[3], norm, distToOrigin = 0;
466   float boxMatrix[3][3];
467   float boxToOrtho[3][3];
468   float normal[3];
469   float bC[3];
470   float point[3];
471 /*  float xyz[3];*/
472   int i, j;
473   /* Change the transformation matrix. */
474 
475   DBG_fprintf(stderr, "Setting a new plane from boxchange %.1f %.1f %.1f :\n", boxChange[0], boxChange[1], boxChange[2]);
476   for (j = 0; j < 3; j++)
477     {
478       if (boxChange[j] < 0.)
479         bC[j] = boxChange[j] + 1.;
480       else
481         bC[j] = boxChange[j];
482       tmpCoord[0] = (j == 0)?1.:0.;
483       tmpCoord[1] = (j == 1)?1.:0.;
484       tmpCoord[2] = (j == 2)?1.:0.;
485       visu_box_convertBoxCoordinatestoXYZ(visu_boxed_getBox(VISU_BOXED(dataObj)),
486                                           boxMatrix[j], tmpCoord);
487     }
488   /* We create a matrix to transform the box coordinates to
489      cartesian values keeping the orthogonality. */
490   for (i = 0; i < 3; i++)
491     {
492       norm = 0.;
493       for (j = 0; j < 3; j++)
494 	{
495 	  boxToOrtho[j][i] =
496 	    boxMatrix[(i + 1)%3][(j + 1)%3] *
497 	    boxMatrix[(i + 2)%3][(j + 2)%3] -
498 	    boxMatrix[(i + 1)%3][(j + 2)%3] *
499 	    boxMatrix[(i + 2)%3][(j + 1)%3];
500 	  norm += boxToOrtho[j][i] * boxToOrtho[j][i];
501 	}
502       /* We normalise the tranformation matrix. */
503       norm = sqrt(norm);
504       for (j = 0; j < 3; j++)
505 	boxToOrtho[j][i] /= norm;
506     }
507   tool_matrix_productVector(normal, boxToOrtho, boxChange);
508   DBG_fprintf(stderr, "  - normal vector : %f %f %f\n", normal[0], normal[1], normal[2]);
509   visu_plane_setNormalVector(plane,normal);
510   visu_plane_getNVect(plane,normal);
511   DBG_fprintf(stderr, "  - normal vector (normalized) : %f %f %f\n", normal[0], normal[1], normal[2]);
512   visu_box_convertBoxCoordinatestoXYZ(visu_boxed_getBox(VISU_BOXED(dataObj)), point, bC);
513   for (i = 0; i < 3; i++)
514   {
515     distToOrigin += normal[i]*point[i];
516   }
517   DBG_fprintf(stderr, "  - distance to origin : %f\n", distToOrigin);
518   visu_plane_setDistanceFromOrigin(plane, distToOrigin);
519 }
520 
initDrawCoord(VisuData * dataObj,int ringSize,int * atomInd,float * xyz,float * boxChange,float * drawCoord,int totalNumberOfPoints _U_)521 void initDrawCoord(VisuData *dataObj, int ringSize, int *atomInd, float *xyz,
522 		   float *boxChange, float *drawCoord, int totalNumberOfPoints _U_)
523 {/* Initialize the drawCoordinates : for a given ring size RS and a give number of intersected planes NP,
524     the number of coordinates is 2*(RS + NP), ie one pair of coordinates for each element to draw. */
525   int i, j, k = 0;
526   int np;
527   int l, p;
528   float A[3], B[3], xrB[3], bC[3], tBC[3] = {0.,0.,0.};
529 
530   float *inter;
531   float *change;
532   int *index;
533   VisuPlane **listOfVisuPlanes; /* Number of planes + 1 (in order to get a NULL at the end and stop)*/
534 
535   for (j = 0; j < 3; j++)
536     {
537       *(drawCoord + j) = *(xyz + j);
538       *(atomInd) = 1;
539     }
540   DBG_fprintf(stderr, "Point added (first point) to drawCoord %f %f %f from box (0 0 0)\n",
541                         *(drawCoord + 3*k), *(drawCoord + 3*k + 1), *(drawCoord + 3*k + 2));
542   k++;
543   for (i = 0; i < ringSize-1; i++)
544     {
545       if ( (*(boxChange + 3*i) == 0.) && (*(boxChange + 3*i + 1) == 0.) && (*(boxChange + 3*i + 2) == 0.) )
546         {
547           *(drawCoord + 3*k) = *(xyz + 3*(i+1));
548           *(drawCoord + 3*k + 1) = *(xyz + 3*(i+1) + 1);
549           *(drawCoord + 3*k + 2) = *(xyz + 3*(i+1) + 2);
550           DBG_fprintf(stderr, "Point added to drawCoord %f %f %f from box (0 0 0)\n",
551 			*(drawCoord + 3*k), *(drawCoord + 3*k + 1), *(drawCoord + 3*k + 2));
552           *(atomInd + k) = 1;
553           k++;
554           *(drawCoord + 3*k) = *(xyz + 3*(i+1));
555           *(drawCoord + 3*k + 1) = *(xyz + 3*(i+1) + 1);
556           *(drawCoord + 3*k + 2) = *(xyz + 3*(i+1) + 2);
557           DBG_fprintf(stderr, "Point added to drawCoord %f %f %f from box (0 0 0)\n",
558 			*(drawCoord + 3*k), *(drawCoord + 3*k + 1), *(drawCoord + 3*k + 2));
559           *(atomInd + k) = 1;
560           k++;
561         }
562       else
563         {
564           np = ABS(*(boxChange + 3*i)) + ABS(*(boxChange + 3*i + 1)) + ABS(*(boxChange + 3*i + 2));
565 	  inter = g_malloc(sizeof(float) * np * 3);
566 	  change = g_malloc(sizeof(float) * np * 3);
567 	  index = g_malloc(sizeof(float) * np);
568           for (j = 0; j < 3; j++)
569             {
570               A[j] = *(xyz + 3*i + j);
571               B[j] = *(xyz + 3*(i+1) + j);
572             }
573           DBG_fprintf(stderr, "Point A : %f %f %f\nPoint B : %f %f %f\n",
574 		A[0],A[1],A[2],B[0],B[1],B[2]);
575           DBG_fprintf(stderr, "BoxChange for B : %.1f %.1f %.1f\n",
576 		*(boxChange + 3*i),*(boxChange + 3*i + 1),*(boxChange + 3*i + 2));
577           visu_box_convertXYZtoBoxCoordinates(visu_boxed_getBox(VISU_BOXED(dataObj)), xrB, B);
578           xrB[0] = xrB[0] + *(boxChange + 3*i);
579           xrB[1] = xrB[1] + *(boxChange + 3*i + 1);
580           xrB[2] = xrB[2] + *(boxChange + 3*i + 2);
581           visu_box_convertBoxCoordinatestoXYZ(visu_boxed_getBox(VISU_BOXED(dataObj)), B, xrB);
582           DBG_fprintf(stderr, "Point B after BoxChange : %f %f %f\n",B[0],B[1],B[2]);
583 	  listOfVisuPlanes = g_malloc(sizeof(VisuPlane*) * (np + 1));
584           listOfVisuPlanes[np] = (VisuPlane*)0;
585           p = 0;
586           for (j = 0; j < 3; j++)
587             {
588               bC[0] = 0.;
589               bC[1] = 0.;
590               bC[2] = 0.;
591               for (l = 0; l < ABS(*(boxChange + 3*i + j)); l++)
592                 {
593                   if (*(boxChange + 3*i + j) > 0.)
594                     {
595                       bC[j] = (float)(+l+1);
596                     }
597                   else if (*(boxChange + 3*i + j) < 0.)
598                     {
599                       bC[j] = (float)(-l-1);
600                     }
601                   listOfVisuPlanes[p] = visu_plane_newUndefined();
602                   setVisuPlaneFromBoxChange(dataObj, bC, listOfVisuPlanes[p]);
603                   change[3 * p + 0] = bC[0];
604                   change[3 * p + 1] = bC[1];
605                   change[3 * p + 2] = bC[2];
606                   p++;
607                 }
608             }
609           if (visu_plane_class_getOrderedIntersections(np, listOfVisuPlanes, A, B, (float*)inter, (int*)index))
610             {
611               tBC[0] = 0.;
612               tBC[1] = 0.;
613               tBC[2] = 0.;
614               for (p = 0; p < np; p++)
615                 {
616                   A[0] = inter[3 * p + 0];
617                   A[1] = inter[3 * p + 1];
618                   A[2] = inter[3 * p + 2];
619                   changeCoordfromBoxChange(dataObj, A, tBC, B);
620                   *(drawCoord + 3*k) = B[0];
621                   *(drawCoord + 3*k + 1) = B[1];
622                   *(drawCoord + 3*k + 2) = B[2];
623 /*                  *(drawCoord + 3*k) = inter[p][0];
624                   *(drawCoord + 3*k + 1) = inter[p][1];
625                   *(drawCoord + 3*k + 2) = inter[p][2];*/
626                   DBG_fprintf(stderr, "Point added to drawCoord %f %f %f for a plane\n",
627 			*(drawCoord + 3*k), *(drawCoord + 3*k + 1), *(drawCoord + 3*k + 2));
628                   *(atomInd + k) = 0;
629                   k++;
630 
631                   if (change[index[p] * 3 + 0] < 0.)
632                     tBC[0] = tBC[0] + 1.;
633                   else if (change[index[p] * 3 + 0] > 0.)
634                     tBC[0] = tBC[0] - 1.;
635                   if (change[index[p] * 3 + 1] < 0.)
636                     tBC[1] = tBC[1] + 1.;
637                   else if (change[index[p] * 3 + 1] > 0.)
638                     tBC[1] = tBC[1] - 1.;
639                   if (change[index[p] * 3 + 2] < 0.)
640                     tBC[2] = tBC[2] + 1.;
641                   else if (change[index[p] * 3 + 2] > 0.)
642                     tBC[2] = tBC[2] - 1.;
643                   DBG_fprintf(stderr, "Change of box needed for the next point : %f %f %f\n",
644 			tBC[0],tBC[1],tBC[2]);
645                   A[0] = inter[p * 3 + 0];
646                   A[1] = inter[p * 3 + 1];
647                   A[2] = inter[p * 3 + 2];
648                   changeCoordfromBoxChange(dataObj, A, tBC, B);
649                   *(drawCoord + 3*k) = B[0];
650                   *(drawCoord + 3*k + 1) = B[1];
651                   *(drawCoord + 3*k + 2) = B[2];
652                   DBG_fprintf(stderr, "Point added to drawCoord %f %f %f for a plane\n",
653 			*(drawCoord + 3*k), *(drawCoord + 3*k + 1), *(drawCoord + 3*k + 2));
654                   *(atomInd + k) = 0;
655                   k++;
656                 }
657               *(drawCoord + 3*k) = *(xyz + 3*(i+1));
658               *(drawCoord + 3*k + 1) = *(xyz + 3*(i+1) + 1);
659               *(drawCoord + 3*k + 2) = *(xyz + 3*(i+1) + 2);
660               DBG_fprintf(stderr, "Point added to drawCoord %f %f %f after planes\n",
661 			*(drawCoord + 3*k), *(drawCoord + 3*k + 1), *(drawCoord + 3*k + 2));
662               *(atomInd + k) = 1;
663               k++;
664               *(drawCoord + 3*k) = *(xyz + 3*(i+1));
665               *(drawCoord + 3*k + 1) = *(xyz + 3*(i+1) + 1);
666               *(drawCoord + 3*k + 2) = *(xyz + 3*(i+1) + 2);
667               DBG_fprintf(stderr, "Point added to drawCoord %f %f %f after planes\n",
668 			*(drawCoord + 3*k), *(drawCoord + 3*k + 1), *(drawCoord + 3*k + 2));
669               *(atomInd + k) = 1;
670               k++;
671             }
672           else
673             {
674               DBG_fprintf(stderr, "WARNING : visu_plane_class_getOrderedIntersections did not find any plane !!!\n");
675             }
676 	  g_free(listOfVisuPlanes);
677 	  g_free(inter);
678 	  g_free(change);
679 	  g_free(index);
680         }
681     }
682 
683   if ( (*(boxChange + 3*(ringSize-1)) == 0.) && (*(boxChange + 3*(ringSize-1) + 1) == 0.) && (*(boxChange + 3*(ringSize-1) + 2) == 0.) )
684     {
685       *(drawCoord + 3*k) = *(xyz);
686       *(drawCoord + 3*k + 1) = *(xyz + 1);
687       *(drawCoord + 3*k + 2) = *(xyz + 2);
688       DBG_fprintf(stderr, "Point added to drawCoord %f %f %f from box (0 0 0)\n",
689 			*(drawCoord + 3*k), *(drawCoord + 3*k + 1), *(drawCoord + 3*k + 2));
690       *(atomInd + k) = 1;
691       k++;
692     }
693   else
694     {
695       np = ABS(*(boxChange + 3*(ringSize-1))) + ABS(*(boxChange + 3*(ringSize-1) + 1)) + ABS(*(boxChange + 3*(ringSize-1) + 2));
696       inter = g_malloc(sizeof(float) * np * 3);
697       change = g_malloc(sizeof(float) * np * 3);
698       index = g_malloc(sizeof(float) * np);
699       for (j = 0; j < 3; j++)
700         {
701           A[j] = *(xyz + 3*(ringSize-1) + j);
702           B[j] = *(xyz + j);
703         }
704       DBG_fprintf(stderr, "Point A : %f %f %f\nPoint B : %f %f %f\n",
705 		A[0],A[1],A[2],B[0],B[1],B[2]);
706       DBG_fprintf(stderr, "BoxChange for B : %.1f %.1f %.1f\n",
707 		*(boxChange + 3*(ringSize-1)),*(boxChange + 3*(ringSize-1) + 1),
708 		*(boxChange + 3*(ringSize-1) + 2));
709       visu_box_convertXYZtoBoxCoordinates(visu_boxed_getBox(VISU_BOXED(dataObj)), xrB, B);
710       xrB[0] = xrB[0] + *(boxChange + 3*(ringSize-1));
711       xrB[1] = xrB[1] + *(boxChange + 3*(ringSize-1) + 1);
712       xrB[2] = xrB[2] + *(boxChange + 3*(ringSize-1) + 2);
713       visu_box_convertBoxCoordinatestoXYZ(visu_boxed_getBox(VISU_BOXED(dataObj)), B, xrB);
714       DBG_fprintf(stderr, "Point B after BoxChange : %f %f %f\n",B[0],B[1],B[2]);
715       listOfVisuPlanes = g_malloc(sizeof(VisuPlane*) * (np + 1));
716       listOfVisuPlanes[np] = (VisuPlane*)0;
717       p = 0;
718       for (j = 0; j < 3; j++)
719         {
720           bC[0] = 0.;
721           bC[1] = 0.;
722           bC[2] = 0.;
723           for (l = 0; l < ABS(*(boxChange + 3*(ringSize-1) + j)); l++)
724             {
725               if (*(boxChange + 3*(ringSize-1) + j) > 0.)
726                 {
727                   bC[j] = (float)(+l+1);
728                 }
729               else if (*(boxChange + 3*(ringSize-1) + j) < 0.)
730                 {
731                   bC[j] = (float)(-l-1);
732                 }
733               listOfVisuPlanes[p] = visu_plane_newUndefined();
734               setVisuPlaneFromBoxChange(dataObj, bC, listOfVisuPlanes[p]);
735               change[p * 3 + 0] = bC[0];
736               change[p * 3 + 1] = bC[1];
737               change[p * 3 + 2] = bC[2];
738               p++;
739             }
740         }
741       if (visu_plane_class_getOrderedIntersections(np, listOfVisuPlanes, A, B, (float*)inter, (int*)index))
742         {
743           tBC[0] = 0.;
744           tBC[1] = 0.;
745           tBC[2] = 0.;
746           for (p = 0; p < np; p++)
747             {
748               A[0] = inter[3 * p + 0];
749               A[1] = inter[3 * p + 1];
750               A[2] = inter[3 * p + 2];
751               changeCoordfromBoxChange(dataObj, A, tBC, B);
752               *(drawCoord + 3*k) = B[0];
753               *(drawCoord + 3*k + 1) = B[1];
754               *(drawCoord + 3*k + 2) = B[2];
755 /*              *(drawCoord + 3*k) = inter[p][0];
756               *(drawCoord + 3*k + 1) = inter[p][1];
757               *(drawCoord + 3*k + 2) = inter[p][2];*/
758               DBG_fprintf(stderr, "Point added to drawCoord %f %f %f for a plane\n",
759 			*(drawCoord + 3*k), *(drawCoord + 3*k + 1), *(drawCoord + 3*k + 2));
760                   *(atomInd + k) = 0;
761               k++;
762 
763               if (change[index[p] * 3 + 0] < 0.)
764                 tBC[0] = tBC[0] + 1.;
765               else if (change[index[p] * 3 + 0] > 0.)
766                 tBC[0] = tBC[0] - 1.;
767               if (change[index[p] * 3 + 1] < 0.)
768                 tBC[1] = tBC[1] + 1.;
769               else if (change[index[p] * 3 + 1] > 0.)
770                 tBC[1] = tBC[1] - 1.;
771               if (change[index[p] * 3 + 2] < 0.)
772                 tBC[2] = tBC[2] + 1.;
773               else if (change[index[p] * 3 + 2] > 0.)
774                 tBC[2] = tBC[2] - 1.;
775               DBG_fprintf(stderr, "Change of box needed for the next point : %f %f %f\n",
776 			tBC[0],tBC[1],tBC[2]);
777               A[0] = inter[p * 3 + 0];
778               A[1] = inter[p * 3 + 1];
779               A[2] = inter[p * 3 + 2];
780               changeCoordfromBoxChange(dataObj, A, tBC, B);
781               *(drawCoord + 3*k) = B[0];
782               *(drawCoord + 3*k + 1) = B[1];
783               *(drawCoord + 3*k + 2) = B[2];
784               DBG_fprintf(stderr, "Point added to drawCoord %f %f %f for a plane\n",
785 			*(drawCoord + 3*k), *(drawCoord + 3*k + 1), *(drawCoord + 3*k + 2));
786               *(atomInd + k) = 0;
787               k++;
788             }
789           *(drawCoord + 3*k) = *(xyz);
790           *(drawCoord + 3*k + 1) = *(xyz + 1);
791           *(drawCoord + 3*k + 2) = *(xyz + 2);
792           DBG_fprintf(stderr, "Point added to drawCoord %f %f %f after planes\n",
793 			*(drawCoord + 3*k), *(drawCoord + 3*k + 1), *(drawCoord + 3*k + 2));
794           *(atomInd + k) = 1;
795           k++;
796         }
797       else
798         {
799           DBG_fprintf(stderr, "WARNING : visu_plane_class_getOrderedIntersections did not find any plane !!!\n");
800         }
801       g_free(listOfVisuPlanes);
802       g_free(inter);
803       g_free(change);
804       g_free(index);
805     }
806 }
807 /**
808  * extRingsDraw:
809  * @dataObj: a #VisuData object.
810  *
811  * Draw the rings (if any).
812  *
813  * Since: 3.5
814  */
extRingsDraw(VisuData * dataObj)815 void extRingsDraw(VisuData *dataObj)
816 {
817 
818 /*   float boxring_1[NB_NODES8][3] = {0.,0.,0.,0.,0.,0.,1.,0.,0.,1.,0.,0.,1.,0.,0.,1.,0.,0.,1.,0.,0.,0.,0.,0.}; */
819 /*   float boxring_2[NB_NODES8][3] = {0.,0.,0.}; */
820 /*   float boxring_3[NB_NODES16][3] = {0.}; */
821 /*   float boxring_4[NB_NODES16][3] = {0.,0.,0.}; */
822 /*   float boxring[NB_NODES16][3] = {0.,0.,0.,0.,0.,0.,1.,0.,0.,1.,0.,0.,1.,0.,0.,1.,0.,0.,1.,0.,0.,1.,0.,0.,1.,0.,0.,1.,0.,0.,1.,0.,0.,1.,0.,0.,1.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.}; */
823 /*   float boxring_6[NB_NODES10][3] = {0.,0.,0.,0.,0.,1.,0.,0.,1.,0.,0.,1.,0.,0.,1.,0.,0.,1.,1.,0.,1.,1.,0.,1.,1.,0.,0.,1.,0.,0.}; */
824   float boxring_7[NB_NODES5][3] = {{0.,0.,0.},{0.,0.,0.},{-1.,-1.,-1.},{-1.,-1.,-1.},{0.,0.,0.}};
825 
826   /* int bleh; */
827   float rgba[4] = {1., 0., 0., 0.5};
828 
829   int *my_test = testring;
830   int i, j;
831   VisuNode *vtmp;
832   float sum[3] = {0.0,0.0,0.0};
833   float xyz[NB_NODES][3]; /* The initial coordinates */
834 /*   float XYZ[NB_NODES][3]; */ /* The translated coordinates */
835 /*   float nodeTrans[NB_NODES][3]; */
836   /* float bary[3]; */
837   int totalNumberOfPoints;
838   float *drawCoord;
839   int *atomIndices;
840   float boxChange[NB_NODES][3];
841 /*   float newBoxChange[NB_NODES][3]; */
842   float baryCoord[3];
843   float baryBox[3];
844 
845 
846   if (extRingsIsBuilt || !dataObj)
847     return;
848 
849   DBG_fprintf(stderr, "Ext Rings: drawing the rings.\n");
850   extRingsIsBuilt = TRUE;
851 
852   glNewList(visu_gl_ext_getGlList(extRings), GL_COMPILE);
853 
854   /* for (i = 0; i < 6; i++) */
855   /*   box[i] = visu_data_getBoxGeometry(dataObj, i); */
856 
857   /* Put the drawing primitives here. */
858   DBG_fprintf(stderr, "Coordinates in initial box :\n");
859   for (i = 0; i < NB_NODES; i++) /* Get the coordinates of the nodes */
860     {
861       vtmp = visu_node_array_getFromId(VISU_NODE_ARRAY(dataObj), my_test[i]);
862       xyz[i][0] = vtmp->xyz[0];
863       xyz[i][1] = vtmp->xyz[1];
864       xyz[i][2] = vtmp->xyz[2];
865       for (j = 0; j < 3; j++)
866         {
867           DBG_fprintf(stderr, "  %f",xyz[i][j]);
868           sum[j] = sum[j] + xyz[i][j];
869         }
870       DBG_fprintf(stderr, "\n");
871     }
872   /* bary[0] = sum[0]/NB_NODES; /\* Get the barycentre *\/ */
873   /* bary[1] = sum[1]/NB_NODES; */
874   /* bary[2] = sum[2]/NB_NODES; */
875 
876 
877 /* INITIALIZING THE BOXRINGS AND COORDINATES */
878   initTranslationForBoxAndCoord(dataObj, NB_NODES, (float*)xyz, (float*)boxring_7);
879   for (i = 0; i < NB_NODES; i++) /* Get the coordinates of the nodes */
880     {
881       vtmp = visu_node_array_getFromId(VISU_NODE_ARRAY(dataObj), my_test[i]);
882       visu_data_getNodePosition(dataObj, vtmp, xyz[i]);
883     }
884 
885 /* INITIALIZING THE RINGS*/
886   initRing(dataObj, NB_NODES, (float*)xyz, (float*)boxring_7, (float*)boxChange, &totalNumberOfPoints);
887 
888 /*COMPUTE BARYCENTER OF THE RING*/
889   computeBaryCenter(dataObj, NB_NODES, (float*)xyz, (float*)boxring_7, (float*)baryCoord, (float*)baryBox);
890 
891 
892 /*INITIALIZING THE DRAW COORDINATES*/
893   atomIndices = g_malloc(sizeof(int) * totalNumberOfPoints);
894   drawCoord = g_malloc(sizeof(float) * 3 * totalNumberOfPoints);
895   initDrawCoord(dataObj, NB_NODES, (int*)atomIndices, (float*)xyz, (float*)boxChange, (float*)drawCoord, totalNumberOfPoints);
896 
897   glDisable(GL_LIGHTING);
898   glDisable(GL_CULL_FACE);
899 
900   glColor4fv(rgba);
901 
902 /*   float radius = 0.5; */
903 
904   rgba[0] = 0.;
905   rgba[1] = 1.;
906   rgba[2] = 0.;
907   rgba[3] = 0.5;
908   glColor4fv(rgba);
909   /* bleh = totalNumberOfPoints/2; */
910   drawRingPlanar(NB_NODES,(float*)xyz, (float*)boxring_7, baryCoord, baryBox);
911   rgba[0] = 0.;
912   rgba[1] = 1.;
913   rgba[2] = 0.;
914   rgba[3] = 1.;
915   glColor4fv(rgba);
916 /*  drawRingCylinder(bleh,(float*)drawCoord);*/
917   rgba[0] = 0.;
918   rgba[1] = 0.;
919   rgba[2] = 1.;
920   rgba[3] = 1.;
921 /*  glColor4fv(rgba);
922   drawSphere(baryCoord[0], baryCoord[1], baryCoord[2], 0.5, 10, 10);*/
923   rgba[0] = 1.;
924   rgba[1] = 0.;
925   rgba[2] = 0.;
926   rgba[3] = 1.;
927   glColor4fv(rgba);
928 /*  drawRingSpheres(bleh, (float*)drawCoord, (int*)atomIndices);*/
929 /*  drawRingLine(bleh,(float*)drawCoord);*/
930 
931   g_free(atomIndices);
932   g_free(drawCoord);
933 
934   glEnable(GL_CULL_FACE);
935   glEnable(GL_LIGHTING);
936   glEndList();
937 }
938