1 /* GLArea.c */
2 /**********************************************************************************************************
3 Copyright (c) 2002-2013 Abdul-Rahman Allouche. All rights reserved
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
6 documentation files (the Gabedit), to deal in the Software without restriction, including without limitation
7 the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
8 and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9
10 The above copyright notice and this permission notice shall be included in all copies or substantial portions
11 of the Software.
12
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
14 TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
15 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
16 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17 DEALINGS IN THE SOFTWARE.
18 ************************************************************************************************************/
19
20 #include "../../Config.h"
21 #include <gdk/gdkkeysyms.h>
22 #include <gtk/gtkgl.h>
23 /* #include <pthread.h>*/
24 #include "GlobalOrb.h"
25 #include "../Utils/Vector3d.h"
26 #include "../Utils/Transformation.h"
27 #include "../Utils/UtilsGL.h"
28 #include "GeomDraw.h"
29 #include "../Utils/Utils.h"
30 #include "../Utils/UtilsInterface.h"
31 #include "../Utils/AtomsProp.h"
32 #include "../Utils/Constants.h"
33 #include "UtilsOrb.h"
34 #include "GeomOrbXYZ.h"
35 #include "Basis.h"
36 #include "TriangleDraw.h"
37 #include "ContoursDraw.h"
38 #include "PlanesMappedDraw.h"
39 #include "ContoursPov.h"
40 #include "PlanesMappedPov.h"
41 #include "SurfacesPov.h"
42 #include "Orbitals.h"
43 #include "StatusOrb.h"
44 #include "GridPlans.h"
45 #include "Dipole.h"
46 #include "AxisGL.h"
47 #include "PrincipalAxisGL.h"
48 #include "VibrationDraw.h"
49 #include "Images.h"
50 #include "PovrayGL.h"
51 #include "MenuToolBarGL.h"
52 #include "LabelsGL.h"
53 #include "RingsOrb.h"
54 #include "RingsPov.h"
55
56
57 /* static pthread_mutex_t theRender_mutex = PTHREAD_MUTEX_INITIALIZER;*/
58
59 static gint OperationType = OPERATION_ROTATION_FREE;
60
61 static gint numberOfSurfaces = 0;
62 static GLuint* positiveSurfaces = NULL;
63 static GLuint* negativeSurfaces = NULL;
64 static GLuint* nullSurfaces = NULL;
65
66 static GLuint listRings[] = {0,0,0,0,0,0};
67 static gboolean selectedListRings[] = {FALSE,FALSE,FALSE,FALSE,FALSE,FALSE};
68 static gint nMaxListRings = G_N_ELEMENTS (listRings);
69
70 static GLuint GeomList = 0;
71 static GLuint VibList = 0;
72 static GLuint DipList = 0;
73 static GLuint axisList = 0;
74 static GLuint principalAxisList = 0;
75 static GLuint* contoursLists = NULL;
76 static GLuint* planesMappedLists = NULL;
77 static gint i0Contours = 0;
78 static gint i1Contours = 1;
79 static gint i0PlaneMapped = 0;
80 static gint i1PlaneMapped = 1;
81 static gint numPlaneContours = 0;
82 static gint numPlaneMaps = 0;
83 static gint numberOfContours = 0;
84 static gdouble* values = NULL;
85 static gint optcol = 0;
86 static gint nPlanesContours = 0;
87 static gint nPlanesMapped = 0;
88 static gboolean newPlaneMapped = FALSE;
89 static gint newPlaneGridForContours = FALSE;
90 static gint newPlaneGridForPlanesMapped = FALSE;
91 static gdouble gapContours = 0.0;
92 static gdouble gapPlanesMapped = 0.0;
93 static gboolean lightOnOff[3] = { TRUE,FALSE,FALSE};
94 static gdouble Trans[3] = { 0,0,-50.0};
95 static V4d light0_position = {0.0, 0.0,50.0,0.0};
96 static V4d light1_position = {0.0, 50.0,50.0,0.0};
97 static V4d light2_position = {50.0, 0.0,50.0,0.0};
98 static gdouble zNear = 1.0;
99 static gdouble zFar = 100.0;
100 static GLdouble Zoom = 45;
101 static gboolean perspective = TRUE;
102 static gboolean animateContours = FALSE;
103 static gboolean animatePlanesMapped = FALSE;
104 /*********************************************************************************************/
105 static gdouble scaleBall = 1.0;
106 static gdouble scaleStick = 1.0;
107 static gboolean showOneSurface = TRUE;
108 static gboolean showBox = TRUE;
109
110 static PangoContext *ft2_context = NULL;
111
112 /*********************************************************************************************/
113 static V4d BackColor[7] =
114 {
115 {0.0, 0.0, 0.0, 1.0}, /* black */
116 {1.0, 1.0, 1.0, 1.0}, /* white */
117 {1.0, 0.0, 0.0, 1.0}, /* red */
118 {0.0, 1.0, 0.0, 1.0}, /* green */
119 {0.0, 0.0, 1.0, 1.0}, /* blue */
120 {1.0, 0.5, 0.5, 1.0}, /* peach */
121 {0.7, 0.7, 0.7, 1.0}, /* Grey */
122 };
123 /*********************************************************************************************/
getScaleBall()124 gdouble getScaleBall()
125 {
126 return scaleBall;
127 }
128 /*********************************************************************************************/
getScaleStick()129 gdouble getScaleStick()
130 {
131 return scaleStick;
132 }
133 /*********************************************************************************************/
getShowOneSurface()134 gboolean getShowOneSurface()
135 {
136 return showOneSurface;
137 }
138 /*********************************************************************************************/
getShowBox()139 gboolean getShowBox()
140 {
141 return showBox;
142 }
143 /*********************************************************************************************/
setShowBox(gboolean c)144 void setShowBox(gboolean c)
145 {
146 showBox = c;
147 }
148 /*********************************************************************************************/
setScaleBall(gdouble a)149 void setScaleBall(gdouble a)
150 {
151 scaleBall = fabs(a);
152 }
153 /*********************************************************************************************/
setScaleStick(gdouble a)154 void setScaleStick(gdouble a)
155 {
156 scaleStick = fabs(a);
157 }
158 /*********************************************************************************************/
setShowOneSurface(gboolean a)159 void setShowOneSurface(gboolean a)
160 {
161 showOneSurface = a;
162 }
163 /*********************************************************************************************/
getOptCol()164 gint getOptCol()
165 {
166 return optcol;
167 }
168 /*********************************************************************************************/
setOptCol(gint i)169 void setOptCol(gint i)
170 {
171 optcol = i;
172 if(optcol<-1 || optcol>6) optcol = 0;
173 }
174 /*********************************************************************************************/
build_rings(gint size,gboolean showMessage)175 void build_rings(gint size, gboolean showMessage)
176 {
177 if(size<3 || size > nMaxListRings-1+3)
178 return ;
179 selectedListRings[size-3] = TRUE;
180 IsoRingsAllGenLists(&listRings[size-3], size,size, showMessage);
181 }
182 /*********************************************************************************************/
delete_rings_all()183 void delete_rings_all()
184 {
185 gint i;
186 for(i=0;i<nMaxListRings;i++)
187 {
188 selectedListRings[i] = FALSE;
189 if (glIsList(listRings[i]) == GL_TRUE) glDeleteLists(listRings[i],1);
190 listRings[i] = 0;
191 }
192 deleteRingsPovRayFile();
193 }
194 /*********************************************************************************************/
195
get_background_color(guchar color[])196 gint get_background_color(guchar color[])
197 {
198 if(optcol<0) return optcol;
199 color[0] = (guchar)(BackColor[optcol][0]*255+0.5);
200 color[1] = (guchar)(BackColor[optcol][1]*255+0.5);
201 color[2] = (guchar)(BackColor[optcol][2]*255+0.5);
202 return optcol;
203 }
204 /*********************************************************************************************/
addFog()205 void addFog()
206 {
207 /*
208 GLdouble fog_c[] = {0.7f, 0.7f, 0.7f, 1.0f};
209 glFogi(GL_FOG_MODE, GL_LINEAR);
210 glFogf(GL_FOG_START, zNear);
211 glFogf(GL_FOG_END, zFar);
212 glFogdv(GL_FOG_COLOR, fog_c);
213 glEnable(GL_FOG);
214 */
215
216 GLdouble fogstart = -0.5;
217 GLdouble fogend = 1.51;
218 GLdouble fogcolor[4] = {0.0, 0.0, 0.0, 1.0};
219
220 glShadeModel(GL_SMOOTH);
221 glFogi(GL_FOG_MODE, GL_LINEAR);
222 glFogdv(GL_FOG_COLOR, fogcolor);
223 glHint(GL_FOG_HINT, GL_DONT_CARE);
224 glFogf(GL_FOG_START, fogstart);
225 glFogf(GL_FOG_END, fogend);
226 }
227 /*********************************************************************************************/
drawChecker()228 void drawChecker()
229 {
230 GLdouble x, y, z;
231 GLint i,j;
232 V4d Diffuse1 = {0.0,0.0,0.0,0.8};
233 V4d Diffuse2 = {0.8,0.8,0.8,0.8};
234 V4d Specular = {0.8,0.8,0.8,0.8 };
235 V4d Ambiant = {0.1,0.1,0.1,0.8};
236 static GLdouble w = 4;
237 static GLint n = 50;
238 static GLdouble x0 = -100;
239 static GLdouble y0 = 0;
240 static GLdouble z0 = -100;
241 GLdouble max = 0;
242
243 if(nCenters>0) max = fabs(GeomOrb[0].C[0]);
244 else max = 10;
245 for(i=0;i<(gint)nCenters;i++)
246 {
247 if(max<fabs(GeomOrb[i].C[0])) max = fabs(GeomOrb[i].C[0]);
248 if(max<fabs(GeomOrb[i].C[1])) max = fabs(GeomOrb[i].C[1]);
249 if(max<fabs(GeomOrb[i].C[2])) max = fabs(GeomOrb[i].C[2]);
250 }
251 /* max *= 45/Zoom;*/
252 if(y0>-5-max) y0 = -5-max;
253
254 glMaterialdv(GL_FRONT_AND_BACK,GL_SPECULAR,Specular);
255 glMaterialdv(GL_FRONT_AND_BACK,GL_DIFFUSE,Diffuse1);
256 glMaterialdv(GL_FRONT_AND_BACK,GL_AMBIENT,Ambiant);
257 glMateriali(GL_FRONT_AND_BACK,GL_SHININESS,100);
258
259 glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
260 glRotatef(-5,0,1,0);
261
262 for(i=0;i<n;i++)
263 for(j=0;j<n;j++)
264 {
265 if((i+j)%2==0)
266 {
267 /*glMaterialdv(GL_FRONT_AND_BACK,GL_DIFFUSE,Diffuse1);*/
268 glMaterialdv(GL_FRONT_AND_BACK,GL_AMBIENT,Diffuse1);
269 }
270 else
271 {
272 /*glMaterialdv(GL_FRONT_AND_BACK,GL_DIFFUSE,Diffuse2);*/
273 glMaterialdv(GL_FRONT_AND_BACK,GL_AMBIENT,Diffuse2);
274 }
275
276 glBegin(GL_POLYGON);
277 glNormal3f(0.0,1.0,0.0);
278 x = x0 + i*w;
279 y = y0;
280 z = z0 + j*w;
281 glVertex3f(x,y,z);
282 glVertex3f(x,y,z+w);
283 glVertex3f(x+w,y,z+w);
284 glVertex3f(x+w,y,z);
285 glEnd();
286 }
287 glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
288 }
289 /*********************************************************************************************/
setAnimatePlanesMapped(gboolean anim)290 void setAnimatePlanesMapped(gboolean anim)
291 {
292 animatePlanesMapped = anim;
293 }
294 /*********************************************************************************************/
setAnimateContours(gboolean anim)295 void setAnimateContours(gboolean anim)
296 {
297 animateContours = anim;
298 }
299 /*********************************************************************************************/
sourceIsOn(gint numsSource)300 gboolean sourceIsOn(gint numsSource)
301 {
302 if(numsSource>=0 && numsSource<=2)
303 return lightOnOff[numsSource];
304 else
305 return FALSE;
306 }
307 /*********************************************************************************************/
get_orgin_molecule(gdouble orig[])308 void get_orgin_molecule(gdouble orig[])
309 {
310 gint i = 0;
311 for(i=0;i<3;i++) orig[i] = Trans[i];
312 /*
313 if(!perspective)
314 for(i=0;i<3;i++) orig[i] /= 10;
315 */
316 }
317 /*********************************************************************************************/
get_camera_values(gdouble * zn,gdouble * zf,gdouble * angle,gdouble * aspect,gboolean * persp)318 void get_camera_values(gdouble* zn, gdouble* zf, gdouble* angle, gdouble* aspect, gboolean* persp)
319 {
320 gdouble width = 500;
321 gdouble height = 500;
322
323 if(GLArea)
324 {
325 width = GLArea->allocation.width;
326 height = GLArea->allocation.height;
327 }
328 *aspect = width/height;
329 *zn = zNear;
330 *zf = zFar;
331 *angle = Zoom;
332 *persp = perspective;
333 }
334 /*********************************************************************************************/
335 static gint redraw(GtkWidget *widget, gpointer data);
336 /*********************************************************************************************/
set_camera_values(gdouble zn,gdouble zf,gdouble zo,gboolean persp)337 void set_camera_values(gdouble zn, gdouble zf, gdouble zo, gboolean persp)
338 {
339 zNear = zn;
340 zFar = zf;
341 Zoom = zo;
342 Trans[2] = -zf/2;
343 perspective = persp;
344 redraw(GLArea,NULL);
345 }
346 /*********************************************************************************************/
get_light(gint num,gdouble v[])347 gboolean get_light(gint num,gdouble v[])
348 {
349 gint i;
350 v[0] = v[1] = v[2] = 0;
351 if(num<0 || num>2) return FALSE;
352 switch(num)
353 {
354 case 0 :
355 for(i=0;i<3;i++)
356 v[i] = light0_position[i];
357 break;
358 case 1 :
359 for(i=0;i<3;i++)
360 v[i] = light1_position[i];
361 break;
362 case 2 :
363 for(i=0;i<3;i++)
364 v[i] = light2_position[i];
365 break;
366 }
367 return lightOnOff[num];
368 }
369 /*********************************************************************************************/
get_light_position(gint num)370 gchar** get_light_position(gint num)
371 {
372 gint i;
373 gchar** t = g_malloc(3*sizeof(gchar*));
374 switch(num)
375 {
376 case 0 :
377 for(i=0;i<3;i++)
378 t[i] = g_strdup_printf("%lf",light0_position[i]);
379 break;
380 case 1 :
381 for(i=0;i<3;i++)
382 t[i] = g_strdup_printf("%lf",light1_position[i]);
383 break;
384 case 2 :
385 for(i=0;i<3;i++)
386 t[i] = g_strdup_printf("%lf",light2_position[i]);
387 break;
388 }
389 return t;
390 }
391 /*********************************************************************************************/
set_light_position(gint num,gdouble v[])392 void set_light_position(gint num,gdouble v[])
393 {
394 gint i;
395 switch(num)
396 {
397 case 0 :
398 for(i=0;i<3;i++)
399 light0_position[i] = v[i];
400 break;
401 case 1 :
402 for(i=0;i<3;i++)
403 light1_position[i] = v[i];
404 break;
405 case 2 :
406 for(i=0;i<3;i++)
407 light2_position[i] = v[i];
408 break;
409 }
410 }
411 /*********************************************************************************************/
set_operation_type(gint i)412 void set_operation_type(gint i)
413 {
414 OperationType = i;
415 }
416 /*********************************************************************************************/
set_light_on_off(gint i)417 void set_light_on_off(gint i)
418 {
419 lightOnOff[i] = !lightOnOff[i] ;
420 }
421 /*********************************************************************************************/
add_surface()422 void add_surface()
423 {
424 numberOfSurfaces++;
425 if(!positiveSurfaces) positiveSurfaces = g_malloc(sizeof(GLuint));
426 else positiveSurfaces = g_realloc(positiveSurfaces, numberOfSurfaces*sizeof(GLuint));
427 positiveSurfaces[numberOfSurfaces-1] = 0;
428
429 if(!negativeSurfaces) negativeSurfaces = g_malloc(sizeof(GLuint));
430 else negativeSurfaces = g_realloc(negativeSurfaces, numberOfSurfaces*sizeof(GLuint));
431 negativeSurfaces[numberOfSurfaces-1] = 0;
432
433 if(!nullSurfaces) nullSurfaces = g_malloc(sizeof(GLuint));
434 else nullSurfaces = g_realloc(nullSurfaces, numberOfSurfaces*sizeof(GLuint));
435 nullSurfaces[numberOfSurfaces-1] = 0;
436
437 RebuildSurf = TRUE;
438 addLastSurface();
439 }
440 /*********************************************************************************************/
add_maps(gint ii0,gint ii1,gint inumPlane,gdouble igap,gboolean newGrid)441 void add_maps(gint ii0, gint ii1, gint inumPlane, gdouble igap, gboolean newGrid)
442 {
443 i0PlaneMapped = ii0;
444 i1PlaneMapped = ii1;
445 numPlaneMaps = inumPlane;
446 gapPlanesMapped = igap;
447 newPlaneGridForPlanesMapped = newGrid;
448 if(numPlaneMaps>=0)
449 {
450 newPlaneMapped = TRUE;
451 nPlanesMapped++;
452 reDrawPlaneMappedPlane = TRUE;
453 if(!planesMappedLists) planesMappedLists = g_malloc(sizeof(GLuint));
454 else planesMappedLists = g_realloc(planesMappedLists, nPlanesMapped*sizeof(GLuint));
455 }
456 }
457 /*********************************************************************************************/
add_void_maps()458 void add_void_maps()
459 {
460 if(nPlanesMapped<1) return;
461 i0PlaneMapped = 0;
462 i1PlaneMapped = 1;
463 numPlaneMaps = -1;
464 gapPlanesMapped = 0;
465 newPlaneGridForPlanesMapped = FALSE;
466 newPlaneMapped = TRUE;
467 nPlanesMapped++;
468 reDrawPlaneMappedPlane = TRUE;
469 if(!planesMappedLists) planesMappedLists = g_malloc(sizeof(GLuint));
470 else planesMappedLists = g_realloc(planesMappedLists, nPlanesMapped*sizeof(GLuint));
471 planesMappedLists[nPlanesMapped-1] = 0;
472 }
473 /********************************************************/
free_planes_mapped_all()474 void free_planes_mapped_all()
475 {
476 if(planesMappedLists)
477 {
478 gint i;
479 for(i=0;i<nPlanesMapped;i++)
480 if (glIsList(planesMappedLists[i]) == GL_TRUE) glDeleteLists(planesMappedLists[i],1);
481 g_free(planesMappedLists);
482 }
483 newPlaneGridForPlanesMapped = FALSE;
484 newPlaneMapped = FALSE;
485 nPlanesMapped = 0;
486 planesMappedLists = NULL;
487 deletePlanesMappedPovRayFile();
488 hideColorMapPlanesMapped();
489 reDrawPlaneMappedPlane = FALSE;
490 }
491 /*********************************************************************************************/
add_void_contours()492 void add_void_contours()
493 {
494 if(nPlanesContours<1) return;
495 if(values) g_free(values);
496 values = NULL;
497 numberOfContours = 0;
498 i0Contours = 0;
499 i1Contours = 1;
500 numPlaneContours = 0;
501 gapContours = 0;
502 newContours = TRUE;
503 nPlanesContours++;
504 if(!contoursLists) contoursLists = g_malloc(sizeof(GLuint));
505 else contoursLists = g_realloc(contoursLists,nPlanesContours*sizeof(GLuint));
506 contoursLists[nPlanesContours-1] = 0;
507 reDrawContoursPlane = TRUE;
508 }
509 /*********************************************************************************************/
set_contours_values(gint N,gdouble * cvalues,gint ii0,gint ii1,gint inumPlane,gdouble igap)510 void set_contours_values(gint N,gdouble* cvalues,gint ii0,gint ii1,gint inumPlane,gdouble igap)
511 {
512 if(values) g_free(values);
513 values = cvalues;
514 numberOfContours = N;
515 i0Contours = ii0;
516 i1Contours = ii1;
517 numPlaneContours = inumPlane;
518 gapContours = igap;
519 if(values)
520 {
521 newContours = TRUE;
522 nPlanesContours++;
523 if(!contoursLists) contoursLists = g_malloc(sizeof(GLuint));
524 else contoursLists = g_realloc(contoursLists,nPlanesContours*sizeof(GLuint));
525 }
526 /* Debug("End set_contours_values\n");*/
527 reDrawContoursPlane = TRUE;
528 }
529 /********************************************************/
set_contours_values_from_plane(gdouble minv,gdouble maxv,gint N,gdouble igap,gboolean linear)530 void set_contours_values_from_plane(gdouble minv,gdouble maxv,gint N,gdouble igap, gboolean linear)
531 {
532 gint i;
533 gdouble* cvalues;
534 gdouble step;
535
536 cvalues = g_malloc(N*sizeof(gdouble));
537 if(linear)
538 {
539 if(N==1) step = (maxv+minv)/2;
540 else step = (maxv-minv)/(N-1);
541
542 for(i=0;i<N;i++) cvalues[i] = minv + step*i;
543 }
544 else
545 {
546 gdouble e = exp(1.0);
547 if(N==1) step = 1.0/2.0;
548 else step = (1.0)/(N-1);
549 for(i=0;i<N;i++) cvalues[i] = minv+(maxv-minv)*log(step*i*(e-1)+1);
550 }
551
552 if(gridPlaneForContours)
553 {
554 /* Debug("begin Set contour\n");*/
555 set_contours_values(N,cvalues,0,1,0,igap);
556 /* Debug("End set contour\n");*/
557 newPlaneGridForContours = TRUE;
558 }
559 else
560 {
561 if(cvalues) g_free(cvalues);
562 }
563 }
564 /********************************************************/
set_background_optcolor(gint i)565 void set_background_optcolor(gint i)
566 {
567 optcol = i;
568 }
569 /********************************************************/
set_background_color()570 static void set_background_color()
571 {
572 if(optcol>=0) glClearColor(BackColor[optcol][0],BackColor[optcol][1],BackColor[optcol][2],BackColor[optcol][3]);
573 else
574 {
575 glClearColor(BackColor[4][0],BackColor[4][1],BackColor[4][2],BackColor[4][3]);
576 }
577 }
578 /********************************************************/
free_contours_all()579 void free_contours_all()
580 {
581 if(contoursLists)
582 {
583 gint i;
584 for(i=0;i<nPlanesContours;i++)
585 if (glIsList(contoursLists[i]) == GL_TRUE) glDeleteLists(contoursLists[i],1);
586 g_free(contoursLists);
587 }
588 set_contours_values(0,NULL,0,1,0,0.0);
589 nPlanesContours = 0;
590 contoursLists = NULL;
591 deleteContoursPovRayFile();
592 hideColorMapContours();
593 reDrawContoursPlane = FALSE;
594 }
595 /********************************************************/
free_iso_all()596 void free_iso_all()
597 {
598 set_status_label_info("IsoSurface","Nothing");
599 if(isopositive) isopositive = iso_free(isopositive);
600 if(isonegative) isonegative = iso_free(isonegative);
601 if(isonull) isonull = iso_free(isonull);
602 RebuildSurf = TRUE;
603 }
604 /********************************************************/
free_surfaces_all()605 void free_surfaces_all()
606 {
607 if(positiveSurfaces)
608 {
609 gint i;
610 for(i=0;i<numberOfSurfaces;i++)
611 if (glIsList(positiveSurfaces[i]) == GL_TRUE) glDeleteLists(positiveSurfaces[i],1);
612 g_free(positiveSurfaces);
613 }
614 if(negativeSurfaces)
615 {
616 gint i;
617 for(i=0;i<numberOfSurfaces;i++)
618 if (glIsList(negativeSurfaces[i]) == GL_TRUE) glDeleteLists(negativeSurfaces[i],1);
619 g_free(negativeSurfaces);
620 }
621 if(nullSurfaces)
622 {
623 gint i;
624 for(i=0;i<numberOfSurfaces;i++)
625 if (glIsList(nullSurfaces[i]) == GL_TRUE) glDeleteLists(nullSurfaces[i],1);
626 g_free(nullSurfaces);
627 }
628 numberOfSurfaces = 0;
629 positiveSurfaces = NULL;
630 negativeSurfaces = NULL;
631 nullSurfaces = NULL;
632 free_iso_all();
633 deleteSurfacesPovRayFile();
634 }
635 /********************************************************/
free_objects_all()636 void free_objects_all()
637 {
638 free_surfaces_all();
639 free_contours_all();
640 delete_rings_all();
641 free_planes_mapped_all();
642 deleteContoursPovRayFile();
643 deletePlanesMappedPovRayFile();
644 }
645 /********************************************************/
free_grid_all()646 void free_grid_all()
647 {
648 set_status_label_info("Grid","Nothing");
649 if(grid)
650 grid = free_grid(grid);
651 }
652 /********************************************************/
add_objects_for_new_grid()653 void add_objects_for_new_grid()
654 {
655 reset_old_geometry();
656 add_void_maps();
657 add_void_contours();
658 if(!showOneSurface || numberOfSurfaces<1 ) add_surface();
659 }
660 /********************************************************/
Define_Iso(gdouble isovalue)661 void Define_Iso(gdouble isovalue)
662 {
663 free_iso_all();
664 set_status_label_info("IsoSurface","Computing");
665
666 /* printf("DefineIso newSUrface = %d\n",newSurface);*/
667 if(grid)
668 {
669 if(newSurface || numberOfSurfaces<1 )
670 if(!showOneSurface || numberOfSurfaces<1 ) add_surface();
671 newSurface = FALSE;
672 isopositive=define_iso_surface(grid,isovalue, grid->mapped );
673 if(fabs(isovalue)>1e-13)
674 isonegative=define_iso_surface(grid,-isovalue, grid->mapped );
675 if(isopositive != NULL || isonegative != NULL) set_status_label_info("IsoSurface","Ok");
676 }
677 RebuildSurf = TRUE;
678 }
679 /********************************************************/
Define_Grid()680 void Define_Grid()
681 {
682 free_grid_all();
683 /*
684 free_contours_all();
685 free_planes_mapped_all();
686 */
687
688 grid = define_grid(NumPoints,limits);
689 if(grid)
690 {
691 if(!showOneSurface || numberOfSurfaces<1 ) add_surface();
692 free_iso_all();
693 limits.MinMax[0][3] = grid->limits.MinMax[0][3];
694 limits.MinMax[1][3] = grid->limits.MinMax[1][3];
695 }
696 }
697 /********************************************************/
698 static V4d Quat;
699 static GLdouble BeginX = 0;
700 static GLdouble BeginY = 0;
701 /*********************************************************************************************/
resetBeginNegative()702 void resetBeginNegative()
703 {
704 BeginX = -1;
705 BeginY = -1;
706 }
707 /*********************************************************************************************/
getQuat(gdouble q[])708 void getQuat(gdouble q[])
709 {
710 gint i;
711 for(i=0;i<4;i++) q[i] = Quat[i];
712 }
713 /*********************************************************************************************/
SetLight()714 static void SetLight()
715 {
716 static float lmodel_ambient[] = {0.1, 0.1, 0.1, 0.1};
717 static float lmodel_twoside[] = {GL_TRUE};
718 static float lmodel_local[] = {GL_FALSE};
719
720 static V4d light0_ambient = {0.5, 0.5, 0.5, 1.0};
721 static V4d light0_diffuse = {1.0, 1.0, 1.0, 0.0};
722 static V4d light0_specular = {1.0, 1.0, 1.0, 0.0};
723
724 static V4d light1_ambient = {1.0, 1.0, 1.0, 1.0};
725 static V4d light1_diffuse = {1.0, 1.0, 1.0, 0.0};
726 static V4d light1_specular = {1.0, 1.0, 1.0, 0.0};
727
728 static V4d light2_ambient = {0.1, 0.1, 0.1, 1.0};
729 static V4d light2_diffuse = {1.0, 1.0, 1.0, 0.0};
730 static V4d light2_specular = {1.0, 1.0, 1.0, 0.0};
731
732 glLightdv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
733 glLightdv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
734 glLightdv(GL_LIGHT0, GL_SPECULAR, light0_specular);
735 glLightdv(GL_LIGHT0, GL_POSITION, light0_position);
736
737 glLightdv(GL_LIGHT1, GL_AMBIENT, light1_ambient);
738 glLightdv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);
739 glLightdv(GL_LIGHT1, GL_SPECULAR, light1_specular);
740 glLightdv(GL_LIGHT1, GL_POSITION, light1_position);
741
742 glLightdv(GL_LIGHT2, GL_AMBIENT, light2_ambient);
743 glLightdv(GL_LIGHT2, GL_DIFFUSE, light2_diffuse);
744 glLightdv(GL_LIGHT2, GL_SPECULAR, light2_specular);
745 glLightdv(GL_LIGHT2, GL_POSITION, light2_position);
746
747 glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, lmodel_local);
748 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
749 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
750 glEnable(GL_LIGHTING);
751 glDisable(GL_LIGHT0);
752 glDisable(GL_LIGHT1);
753 glDisable(GL_LIGHT2);
754 if(lightOnOff[0])
755 glEnable(GL_LIGHT0);
756 if(lightOnOff[1])
757 glEnable(GL_LIGHT1);
758 if(lightOnOff[2])
759 glEnable(GL_LIGHT2);
760 }
761 /*****************************************************************************/
InitGL()762 void InitGL()
763 {
764
765 /* static GLdouble fog_color[4] = { 0.0, 0.0, 0.0, 0.0 };*/
766 /* remove back faces */
767 glEnable(GL_DEPTH_TEST);
768 glDisable(GL_CULL_FACE);
769 glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
770 /*glEnable(GL_COLOR_MATERIAL);*/
771 glEnable(GL_NORMALIZE);
772 glShadeModel(GL_SMOOTH);
773 SetLight();
774 init_labels_font();
775 /*
776 glInitFontsOld();
777 */
778 glInitFonts(&ft2_context);
779 /*
780 glFogi(GL_FOG_MODE, GL_EXP);
781 glFogf(GL_FOG_DENSITY, 0.15);
782 glFogdv(GL_FOG_COLOR, fog_color);
783 */
784 }
785 /*****************************************************************************/
init(GtkWidget * widget)786 gint init(GtkWidget *widget)
787 {
788 GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
789 GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);
790
791 if(!GTK_IS_WIDGET(widget)) return TRUE;
792 if(!GTK_WIDGET_REALIZED(widget)) return TRUE;
793
794 if (gdk_gl_drawable_gl_begin (gldrawable, glcontext))
795 {
796 glViewport(0,0, widget->allocation.width, widget->allocation.height);
797 InitGL();
798 gdk_window_invalidate_rect (gtk_widget_get_parent_window (widget), &widget->allocation, TRUE);
799 /* gdk_window_process_updates (gtk_widget_get_parent_window (widget), TRUE);*/
800 }
801 return TRUE;
802 }
803 /*****************************************************************************/
redrawGeometry()804 static void redrawGeometry()
805 {
806 gint i;
807 if (RebuildGeom || glIsList(GeomList) != GL_TRUE )
808 {
809 /* Debug("Re Gen Geom List\n");*/
810 GeomList = GeomGenList(GeomList, scaleBall, scaleStick, getShowBox());
811 GeomShowList(GeomList);
812 DipList = DipGenList(DipList);
813 DipShowList(DipList);
814
815 axisList = axisGenList(axisList);
816 axisShowList(axisList);
817
818 principalAxisList = principalAxisGenList(principalAxisList);
819 principalAxisShowList(principalAxisList);
820
821 VibList = VibGenList(VibList);
822 VibShowList(VibList);
823 RebuildGeom = FALSE;
824
825 delete_rings_all();
826 }
827 else
828 {
829 /* Debug("from Lists GeomList = %d\n",GeomList);*/
830 GeomShowList(GeomList);
831 DipShowList(DipList);
832 axisShowList(axisList);
833 principalAxisShowList(principalAxisList);
834 VibShowList(VibList);
835
836 for(i=0;i<nMaxListRings;i++)
837 if(selectedListRings[i])
838 IsoRingsAllShowLists(listRings[i]);
839 }
840 }
841 /*****************************************************************************/
redrawSurfaces()842 static void redrawSurfaces()
843 {
844 if (RebuildSurf && numberOfSurfaces>0)
845 {
846 gint i;
847 IsoGenLists(&positiveSurfaces[numberOfSurfaces-1], &negativeSurfaces[numberOfSurfaces-1], &nullSurfaces[numberOfSurfaces-1],isopositive,isonegative,isonull);
848 createLastSurfacePovRay();
849 for(i=0;i<numberOfSurfaces;i++)
850 IsoShowLists(positiveSurfaces[i], negativeSurfaces[i], nullSurfaces[i]);
851 RebuildSurf = FALSE;
852 }
853 else
854 {
855 gint i;
856 for(i=0;i<numberOfSurfaces;i++)
857 IsoShowLists(positiveSurfaces[i], negativeSurfaces[i], nullSurfaces[i]);
858 }
859 }
860 /*****************************************************************************/
redrawBox()861 static void redrawBox()
862 {
863 GLuint box = 0;
864 if(!showBox) return;
865 BoxGenLists(&box);
866 BoxShowLists(box);
867 }
868 /*****************************************************************************/
redrawContours()869 static void redrawContours()
870 {
871 gboolean reBuildFirstPlaneContours = TRUE;
872 gint i;
873
874 if(newContours && nPlanesContours>0)
875 {
876 if(nPlanesContours==1 && !animateContours ) showColorMapContours();
877 else hideColorMapContours();
878
879 if(newPlaneGridForContours)
880 {
881 /*
882 Debug("Begin Contourlist calculation\n");
883 Debug("GridPlans = %d\n",gridPlaneForContours);
884 Debug("numberOfContours = %d\n",numberOfContours);
885 Debug("values = %d\n",values);
886 */
887 contoursLists[nPlanesContours-1]= ContoursGenLists(contoursLists[nPlanesContours-1],gridPlaneForContours,numberOfContours,values,i0Contours,i1Contours,numPlaneContours,gapContours);
888 addContoursPovRay(gridPlaneForContours,numberOfContours,values,i0Contours,i1Contours,numPlaneContours,gapContours);
889 /* Debug("End Contourlist calculation\n");*/
890 newPlaneGridForContours = FALSE;
891
892 if(nPlanesContours!=1)
893 {
894 if(gridPlaneForContours) g_free(gridPlaneForContours);
895 gridPlaneForContours = NULL;
896 }
897
898 }
899 else
900 {
901 contoursLists[nPlanesContours-1]= ContoursGenLists(contoursLists[nPlanesContours-1],grid,numberOfContours,values,i0Contours,i1Contours,numPlaneContours,gapContours);
902 addContoursPovRay(grid,numberOfContours,values,i0Contours,i1Contours,numPlaneContours,gapContours);
903 }
904 newContours = FALSE;
905 reBuildFirstPlaneContours = FALSE;
906
907 }
908 if(nPlanesContours>1 && gridPlaneForContours)
909 {
910 if(gridPlaneForContours) g_free(gridPlaneForContours);
911 gridPlaneForContours = NULL;
912 }
913 if(reBuildFirstPlaneContours && nPlanesContours==1 && BeginX == -1 )
914 {
915 deleteContoursPovRayFile();
916 if(gridPlaneForContours && reDrawContoursPlane)
917 {
918 contoursLists[nPlanesContours-1]= ContoursGenLists(contoursLists[nPlanesContours-1],gridPlaneForContours,numberOfContours,values,i0Contours,i1Contours,numPlaneContours,gapContours);
919 addContoursPovRay(gridPlaneForContours,numberOfContours,values,i0Contours,i1Contours,numPlaneContours,gapContours);
920 }
921 else
922 if(reDrawContoursPlane)
923 {
924 contoursLists[nPlanesContours-1]= ContoursGenLists(contoursLists[nPlanesContours-1],grid,numberOfContours,values,i0Contours,i1Contours,numPlaneContours,gapContours);
925 addContoursPovRay(grid,numberOfContours,values,i0Contours,i1Contours,numPlaneContours,gapContours);
926 }
927 }
928
929 for(i=0;i<nPlanesContours;i++) ContoursShowLists(contoursLists[i]);
930 }
931 /*****************************************************************************/
redrawPlanesMapped()932 static void redrawPlanesMapped()
933 {
934 gboolean reBuildFirstPlaneMapped = TRUE;
935 gint i;
936
937 if(newPlaneMapped && nPlanesMapped>0)
938 {
939 if(nPlanesMapped==1 && !animatePlanesMapped) showColorMapPlanesMapped();
940 else hideColorMapPlanesMapped();
941
942 if(newPlaneGridForPlanesMapped)
943 {
944 planesMappedLists[nPlanesMapped-1]= PlanesMappedGenLists(planesMappedLists[nPlanesMapped-1],gridPlaneForPlanesMapped,i0PlaneMapped,i1PlaneMapped,numPlaneMaps,gapPlanesMapped);
945 addPlaneMappedPovRay(gridPlaneForPlanesMapped,i0PlaneMapped,i1PlaneMapped,numPlaneMaps,gapPlanesMapped);
946
947 newPlaneGridForPlanesMapped = FALSE;
948
949 if(nPlanesMapped!=1)
950 {
951 if(gridPlaneForPlanesMapped) g_free(gridPlaneForPlanesMapped);
952 gridPlaneForPlanesMapped = NULL;
953 }
954
955 }
956 else
957 {
958 planesMappedLists[nPlanesMapped-1]= PlanesMappedGenLists(planesMappedLists[nPlanesMapped-1],grid,i0PlaneMapped,i1PlaneMapped,numPlaneMaps,gapPlanesMapped);
959 addPlaneMappedPovRay(grid,i0PlaneMapped,i1PlaneMapped,numPlaneMaps,gapPlanesMapped);
960 }
961 newPlaneMapped = FALSE;
962 reBuildFirstPlaneMapped = FALSE;
963
964 }
965 if(nPlanesMapped>1 && gridPlaneForPlanesMapped)
966 {
967 if(gridPlaneForPlanesMapped) g_free(gridPlaneForPlanesMapped);
968 gridPlaneForPlanesMapped = NULL;
969 }
970 if(reBuildFirstPlaneMapped && nPlanesMapped==1 && BeginX == -1 )
971 {
972 deletePlanesMappedPovRayFile();
973 if(gridPlaneForPlanesMapped&& reDrawPlaneMappedPlane)
974 {
975 planesMappedLists[nPlanesMapped-1]= PlanesMappedGenLists(planesMappedLists[nPlanesMapped-1],gridPlaneForPlanesMapped,i0PlaneMapped,i1PlaneMapped,numPlaneMaps,gapPlanesMapped);
976 addPlaneMappedPovRay(gridPlaneForPlanesMapped,i0PlaneMapped,i1PlaneMapped,numPlaneMaps,gapPlanesMapped);
977 }
978 else
979 if(reDrawPlaneMappedPlane)
980 {
981 planesMappedLists[nPlanesMapped-1]= PlanesMappedGenLists(planesMappedLists[nPlanesMapped-1],grid,i0PlaneMapped,i1PlaneMapped,numPlaneMaps,gapPlanesMapped);
982 addPlaneMappedPovRay(grid,i0PlaneMapped,i1PlaneMapped,numPlaneMaps,gapPlanesMapped);
983 }
984 }
985
986 for(i=0;i<nPlanesMapped;i++) PlanesMappedShowLists(planesMappedLists[i]);
987 }
988 /*****************************************************************************/
createImagesFiles()989 static void createImagesFiles()
990 {
991 if(createBMPFiles)
992 {
993 gchar* message;
994 gchar* t = g_strdup_printf("The %s%sgab%d.bmp file was created",get_last_directory(),G_DIR_SEPARATOR_S,numBMPFile);
995 message = new_bmp(get_last_directory(), ++numBMPFile);
996 if(message == NULL) setTextInProgress(t);
997 else
998 {
999 GtkWidget* m;
1000 createBMPFiles = FALSE;
1001 numBMPFile = 0;
1002 m = Message(message,"Error",TRUE);
1003 gtk_window_set_modal (GTK_WINDOW (m), TRUE);
1004 }
1005 g_free(t);
1006
1007 }
1008 if(createPPMFiles)
1009 {
1010 gchar* message;
1011 gchar* t = g_strdup_printf("The %s%sgab%d.ppm file was created",get_last_directory(),G_DIR_SEPARATOR_S,numPPMFile);
1012 message = new_ppm(get_last_directory(), ++numPPMFile);
1013 if(message == NULL)
1014 setTextInProgress(t);
1015 else
1016 {
1017 GtkWidget* m;
1018 createPPMFiles = FALSE;
1019 numPPMFile = 0;
1020 m = Message(message,"Error",TRUE);
1021 gtk_window_set_modal (GTK_WINDOW (m), TRUE);
1022 }
1023 g_free(t);
1024
1025 }
1026 if(createPOVFiles)
1027 {
1028 gchar* message;
1029 gchar* t = g_strdup_printf("The %s%sgab%d.pov file was created",get_last_directory(),G_DIR_SEPARATOR_S,numPOVFile);
1030 message = new_pov(get_last_directory(), ++numPOVFile);
1031 if(message == NULL) setTextInProgress(t);
1032 else
1033 {
1034 GtkWidget* m;
1035 createPOVFiles = FALSE;
1036 numPOVFile = 0;
1037 m = Message(message,"Error",TRUE);
1038 gtk_window_set_modal (GTK_WINDOW (m), TRUE);
1039 }
1040 g_free(t);
1041
1042 }
1043 if(!createBMPFiles && !createPPMFiles && !createPOVFiles) setTextInProgress(" ");
1044 }
1045 /*****************************************************************************/
redrawGL2PS()1046 gint redrawGL2PS()
1047 {
1048 GLdouble m[4][4];
1049 GtkWidget *widget = GLArea;
1050 if(!GTK_IS_WIDGET(widget)) return TRUE;
1051 if(!GTK_WIDGET_REALIZED(widget)) return TRUE;
1052
1053 glMatrixMode(GL_PROJECTION);
1054 glLoadIdentity();
1055 addFog();
1056 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
1057 set_background_color();
1058
1059 mYPerspective(45,(GLdouble)widget->allocation.width/(GLdouble)widget->allocation.height,1,100);
1060 glMatrixMode(GL_MODELVIEW);
1061 glLoadIdentity();
1062 if(optcol==-1) drawChecker();
1063
1064 glMatrixMode(GL_PROJECTION);
1065 glLoadIdentity();
1066 if(perspective)
1067 mYPerspective(Zoom,(GLdouble)widget->allocation.width/(GLdouble)widget->allocation.height,zNear,zFar);
1068 else
1069 {
1070 gdouble fw = (GLdouble)widget->allocation.width/(GLdouble)widget->allocation.height;
1071 gdouble fh = 1.0;
1072 glOrtho(-fw,fw,-fh,fh,-1,1);
1073 }
1074
1075 glMatrixMode(GL_MODELVIEW);
1076 glLoadIdentity();
1077 if(perspective)
1078 glTranslatef(Trans[0],Trans[1],Trans[2]);
1079 else
1080 {
1081 glTranslatef(Trans[0]/10,Trans[1]/10,0);
1082 glScalef(1/Zoom*2,1/Zoom*2,1/Zoom*2);
1083 }
1084 SetLight();
1085
1086 build_rotmatrix(m,Quat);
1087 glMultMatrixd(&m[0][0]);
1088
1089 redrawGeometry();
1090 redrawSurfaces();
1091 redrawBox();
1092 redrawContours();
1093 redrawPlanesMapped();
1094 if(get_show_symbols() || get_show_numbers() || get_show_charges()) showLabelSymbolsNumbersCharges(ft2_context);
1095 if(get_show_dipole()) showLabelDipole(ft2_context);
1096 if(get_show_distances()) showLabelDistances(ft2_context);
1097 if(get_show_axes()) showLabelAxes(ft2_context);
1098 if(get_show_axes()) showLabelPrincipalAxes(ft2_context);
1099 showLabelTitle(GLArea->allocation.width,GLArea->allocation.height, ft2_context);
1100
1101 /* Swap backbuffer to front */
1102 glFlush();
1103
1104 return TRUE;
1105 }
1106 /*****************************************************************************/
redraw(GtkWidget * widget,gpointer data)1107 static gint redraw(GtkWidget *widget, gpointer data)
1108 {
1109 GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
1110 GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);
1111 GLdouble m[4][4];
1112 if(!GTK_IS_WIDGET(widget)) return TRUE;
1113 if(!GTK_WIDGET_REALIZED(widget)) return TRUE;
1114
1115 if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) return FALSE;
1116
1117 glMatrixMode(GL_PROJECTION);
1118 glLoadIdentity();
1119 addFog();
1120 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
1121 set_background_color();
1122
1123 mYPerspective(45,(GLdouble)widget->allocation.width/(GLdouble)widget->allocation.height,1,100);
1124 glMatrixMode(GL_MODELVIEW);
1125 glLoadIdentity();
1126 if(optcol==-1) drawChecker();
1127
1128 glMatrixMode(GL_PROJECTION);
1129 glLoadIdentity();
1130 if(perspective)
1131 mYPerspective(Zoom,(GLdouble)widget->allocation.width/(GLdouble)widget->allocation.height,zNear,zFar);
1132 else
1133 {
1134 gdouble fw = (GLdouble)widget->allocation.width/(GLdouble)widget->allocation.height;
1135 gdouble fh = 1.0;
1136 glOrtho(-fw,fw,-fh,fh,-1,1);
1137 }
1138
1139 glMatrixMode(GL_MODELVIEW);
1140 glLoadIdentity();
1141 if(perspective)
1142 glTranslatef(Trans[0],Trans[1],Trans[2]);
1143 else
1144 {
1145 glTranslatef(Trans[0]/10,Trans[1]/10,0);
1146 glScalef(1/Zoom*2,1/Zoom*2,1/Zoom*2);
1147 }
1148 SetLight();
1149
1150 build_rotmatrix(m,Quat);
1151 glMultMatrixd(&m[0][0]);
1152
1153 redrawGeometry();
1154 redrawSurfaces();
1155 redrawBox();
1156 redrawContours();
1157 redrawPlanesMapped();
1158 if(get_show_symbols() || get_show_numbers() || get_show_charges()) showLabelSymbolsNumbersCharges(ft2_context);
1159 if(get_show_dipole()) showLabelDipole(ft2_context);
1160 if(get_show_distances()) showLabelDistances(ft2_context);
1161 if(get_show_axes()) showLabelAxes(ft2_context);
1162 if(get_show_axes()) showLabelPrincipalAxes(ft2_context);
1163 showLabelTitle(GLArea->allocation.width,GLArea->allocation.height, ft2_context);
1164
1165 /*
1166 glEnable(GL_DEPTH_TEST);
1167 glDepthMask(GL_TRUE);
1168 glDepthRange(0.0f,1.0f);
1169 */
1170
1171 if (gdk_gl_drawable_is_double_buffered (gldrawable))
1172 gdk_gl_drawable_swap_buffers (gldrawable);
1173 else glFlush ();
1174 gdk_gl_drawable_gl_end (gldrawable);
1175
1176 while( gtk_events_pending() ) gtk_main_iteration();
1177
1178 createImagesFiles();
1179 /* gtk_widget_queue_draw(PrincipalWindow);*/
1180
1181 return TRUE;
1182 }
1183 /*********************************************************************************/
1184 /* When widget is exposed it's contents are redrawn. */
draw(GtkWidget * widget,GdkEventExpose * event)1185 static gint draw(GtkWidget *widget, GdkEventExpose *event)
1186 {
1187 static gint i = 0;
1188 i++;
1189 if (!GTK_IS_WIDGET(widget)) return TRUE;
1190 if(!GTK_WIDGET_REALIZED(widget)) return TRUE;
1191 /* Draw only last expose. */
1192 if (event->count > 0) return FALSE;
1193
1194 redraw(widget,NULL);
1195
1196 return FALSE;
1197 }
1198
1199 /*****************************************************************************/
1200 /* When GLArea widget size changes, viewport size is set to match the new size */
reshape(GtkWidget * widget,GdkEventConfigure * event)1201 static gint reshape(GtkWidget *widget, GdkEventConfigure *event)
1202 {
1203 GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
1204 GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);
1205
1206 if(!GTK_IS_WIDGET(widget)) return TRUE;
1207 if(!GTK_WIDGET_REALIZED(widget)) return TRUE;
1208
1209 if (gdk_gl_drawable_gl_begin (gldrawable, glcontext))
1210 {
1211 /* pthread_mutex_lock (&theRender_mutex);*/
1212 glViewport(0,0, widget->allocation.width, widget->allocation.height);
1213 glMatrixMode(GL_PROJECTION);
1214 glLoadIdentity();
1215 if(perspective)
1216 mYPerspective(Zoom,(GLdouble)widget->allocation.width/(GLdouble)widget->allocation.height,zNear,zFar);
1217 else
1218 {
1219 gdouble fw = (GLdouble)widget->allocation.width/(GLdouble)widget->allocation.height;
1220 gdouble fh = 1.0;
1221 glOrtho(-fw,fw,-fh,fh,-1,1);
1222 }
1223 glMatrixMode(GL_MODELVIEW);
1224 glLoadIdentity();
1225 gdk_gl_drawable_gl_end (gldrawable);
1226 /* pthread_mutex_unlock (&theRender_mutex);*/
1227
1228 gdk_window_invalidate_rect (gtk_widget_get_parent_window (widget), &widget->allocation, TRUE);
1229 gdk_window_process_updates (gtk_widget_get_parent_window (widget), TRUE);
1230 }
1231 return TRUE;
1232 }
1233
1234 /********************************************************************************/
set_key_press(GtkWidget * wid,GdkEventKey * event,gpointer data)1235 static gint set_key_press(GtkWidget* wid, GdkEventKey *event, gpointer data)
1236 {
1237 if((event->keyval == GDK_Control_L || event->keyval == GDK_Control_R) )
1238 g_object_set_data(G_OBJECT (wid), "ControlKeyPressed", GINT_TO_POINTER(1));
1239 if((event->keyval == GDK_Alt_L || event->keyval == GDK_Alt_R) )
1240 g_object_set_data(G_OBJECT (wid), "ControlKeyPressed", GINT_TO_POINTER(1));
1241
1242 if((event->keyval == GDK_c || event->keyval == GDK_C) )
1243 {
1244 gint ControlKeyPressed = GPOINTER_TO_INT(g_object_get_data(G_OBJECT (wid), "ControlKeyPressed"));
1245 if(ControlKeyPressed)
1246 {
1247 /* printf("Copy to clipboard\n");*/
1248 copy_to_clipboard();
1249 }
1250
1251 }
1252 GTK_WIDGET_GET_CLASS(wid)->key_press_event(wid, event);
1253 return TRUE;
1254
1255 }
1256 /********************************************************************************/
set_key_release(GtkWidget * wid,GdkEventKey * event,gpointer data)1257 static gint set_key_release(GtkWidget* wid, GdkEventKey *event, gpointer data)
1258 {
1259 if((event->keyval == GDK_Control_L || event->keyval == GDK_Control_R) )
1260 g_object_set_data(G_OBJECT (wid), "ControlKeyPressed", GINT_TO_POINTER(0));
1261 if((event->keyval == GDK_Alt_L || event->keyval == GDK_Alt_R) )
1262 g_object_set_data(G_OBJECT (wid), "ControlKeyPressed", GINT_TO_POINTER(0));
1263 return TRUE;
1264 }
1265 /*****************************************************************************
1266 * event_dispatcher
1267 ******************************************************************************/
event_dispatcher(GtkWidget * DrawingArea,GdkEvent * event,gpointer data)1268 static gint event_dispatcher(GtkWidget *DrawingArea, GdkEvent *event, gpointer data)
1269 {
1270 GdkEventButton *bevent;
1271
1272 switch (event->type)
1273 {
1274 case GDK_BUTTON_PRESS:
1275 {
1276 bevent = (GdkEventButton *) event;
1277 if (bevent->button == 3) /* Right Button ==> Popup Menu */
1278 {
1279 PopupMenuIsOpen = TRUE;
1280 popuo_menu_GL(bevent->button, bevent->time);
1281 }
1282 return TRUE;
1283 }
1284 default : return TRUE;
1285 }
1286 return FALSE;
1287 }
1288
1289 /******************************************************************************/
glarea_button_release(GtkWidget * widget,GdkEventButton * event)1290 gint glarea_button_release (GtkWidget *widget, GdkEventButton *event)
1291 {
1292 if (event->button == 1 || event->button == 2)
1293 {
1294 resetBeginNegative();
1295 redraw(widget,NULL);
1296 return TRUE;
1297 }
1298 return FALSE;
1299 }
1300 /******************************************************************************/
glarea_button_press(GtkWidget * widget,GdkEventButton * event)1301 gint glarea_button_press(GtkWidget *widget, GdkEventButton *event)
1302 {
1303 if (event->button == 1 || event->button == 2)
1304 {
1305 /* beginning of drag, reset mouse position */
1306 BeginX= event->x;
1307 BeginY = event->y;
1308 return TRUE;
1309 }
1310 return FALSE;
1311 }
1312
1313 /*****************************************************************/
rotation(GtkWidget * widget,GdkEventMotion * event,gint x,gint y)1314 static void rotation(GtkWidget *widget, GdkEventMotion *event,gint x, gint y)
1315 {
1316 gdouble width;
1317 gdouble height;
1318
1319 width = widget->allocation.width;
1320 height = widget->allocation.height;
1321 GLdouble spin_quat[4];
1322
1323 /* drag in progress, simulate trackball */
1324 trackball(spin_quat,
1325 (2.0*BeginX- width) / width,
1326 ( height - 2.0*BeginY) / height,
1327 ( 2.0*x - width) / width,
1328 ( height - 2.0*y) / height);
1329 add_quats(spin_quat, Quat, Quat);
1330
1331 BeginX = x;
1332 BeginY = y;
1333 }
1334 /*****************************************************************/
rotationAboutAnAxis(GtkWidget * widget,gdouble phi,gint axe)1335 void rotationAboutAnAxis(GtkWidget *widget, gdouble phi, gint axe)
1336 {
1337 GLdouble spin_quat[4] = {0,0,0,0};
1338 gdouble phiRad = phi/180*PI;
1339 if(axe<0 || axe>2) return;
1340 spin_quat[axe] = 1.0;
1341
1342 v3d_scale(spin_quat,sin(phiRad/2));
1343 spin_quat[3] = cos(phiRad/2);
1344
1345 add_quats(spin_quat, Quat, Quat);
1346
1347 }
1348 /*****************************************************************/
rotationXYZ(GtkWidget * widget,GdkEventMotion * event,gint x,gint y,gint axe)1349 static void rotationXYZ(GtkWidget *widget, GdkEventMotion *event,gint x, gint y, gint axe)
1350 {
1351 GLdouble spin_quat[4];
1352 gint width = widget->allocation.width;
1353 gint height = widget->allocation.height;
1354
1355
1356 if(axe==0)
1357 {
1358 BeginX = x = widget->allocation.width/2;
1359 }
1360 if(axe==1)
1361 {
1362 BeginY = y = widget->allocation.height/2;
1363 }
1364 if(axe==2)
1365 {
1366 gdouble phi = 1;
1367 if(abs(BeginX-x)>abs(BeginY-y))
1368 {
1369 gdouble sign = 1.0;
1370 if(BeginY> height/2 && BeginX<x) sign = -1;
1371 if(BeginY< height/2 && BeginX>x) sign = -1;
1372 phi = sign* fabs(BeginX-x)/width*180;
1373 }
1374 else
1375 {
1376 gdouble sign = 1.0;
1377 if(BeginX> width/2 && BeginY>y) sign = -1;
1378 if(BeginX< width/2 && BeginY<y) sign = -1;
1379 phi = sign* fabs(BeginY-y)/height*180;
1380 }
1381 rotationAboutAnAxis(widget, phi, 2);
1382 BeginX = x;
1383 BeginY = y;
1384 return;
1385 }
1386
1387
1388 /* drag in progress, simulate trackball */
1389 trackball(spin_quat,
1390 (2.0*BeginX - width) / width,
1391 (height - 2.0*BeginY) / height,
1392 (2.0*x - width) / width,
1393 (height - 2.0*y) / height);
1394 add_quats(spin_quat, Quat, Quat);
1395
1396 BeginX = x;
1397 BeginY = y;
1398
1399 }
1400 /*****************************************************************/
zoom(GtkWidget * widget,GdkEventMotion * event,gint x,gint y)1401 static void zoom(GtkWidget *widget, GdkEventMotion *event,gint x,gint y)
1402 {
1403
1404 /* gdouble width;*/
1405 gdouble height;
1406
1407 /* width = widget->allocation.width;*/
1408 height = widget->allocation.height;
1409
1410 /* zooming drag */
1411 Zoom -= ((y - BeginY) / height) * 40;
1412 if (Zoom < 0.1) Zoom = 0.1;
1413 if (Zoom > 500) Zoom = 500;
1414
1415 BeginX = x;
1416 BeginY = y;
1417 }
1418 /*****************************************************************/
translate(GtkWidget * widget,GdkEventMotion * event,gint x,gint y)1419 static void translate(GtkWidget *widget, GdkEventMotion *event,gint x,gint y)
1420 {
1421 gdouble width;
1422 gdouble height;
1423
1424 width = widget->allocation.width;
1425 height = widget->allocation.height;
1426
1427 Trans[0] += ((x - BeginX) / width) * 40;
1428 Trans[1] += ((BeginY - y) / height) * 40;
1429
1430 BeginX = x;
1431 BeginY = y;
1432 }
1433 /******************************************************************************/
glarea_motion_notify(GtkWidget * widget,GdkEventMotion * event)1434 gint glarea_motion_notify(GtkWidget *widget, GdkEventMotion *event)
1435 {
1436 gint x, y;
1437 GdkModifierType state;
1438
1439 if (event->is_hint)
1440 {
1441 #if !defined(G_OS_WIN32)
1442 gdk_window_get_pointer(event->window, &x, &y, &state);
1443 #else
1444 state = event->state;
1445 #endif
1446
1447 }
1448 else
1449 state = event->state;
1450
1451 x = event->x;
1452 y = event->y;
1453
1454 if (state & GDK_BUTTON1_MASK)
1455 {
1456 switch(OperationType)
1457 {
1458 case OPERATION_ROTATION_FREE : rotation(widget,event,x,y);
1459 redraw(widget,NULL);
1460 break;
1461 case OPERATION_ROTATION_X : rotationXYZ(widget,event,x,y,0);
1462 redraw(widget,NULL);
1463 break;
1464 case OPERATION_ROTATION_Y : rotationXYZ(widget,event,x,y,1);
1465 redraw(widget,NULL);
1466 break;
1467 case OPERATION_ROTATION_Z : rotationXYZ(widget,event,x,y,2);
1468 redraw(widget,NULL);
1469 break;
1470 case OPERATION_ZOOM : zoom(widget,event,x,y);
1471 redraw(widget,NULL);
1472 break;
1473 case OPERATION_TRANSLATION : translate(widget,event,x,y);
1474 redraw(widget,NULL);
1475 break;
1476 }
1477 }
1478
1479 if (state & GDK_BUTTON2_MASK)
1480 {
1481 rotation(widget,event,x,y);
1482 redraw(widget,NULL);
1483 }
1484
1485 return TRUE;
1486 }
1487 /******************************************************************************/
glarea_rafresh(GtkWidget * widget)1488 gint glarea_rafresh(GtkWidget *widget)
1489 {
1490 if(!widget) return FALSE;
1491 redraw(GLArea,NULL);
1492 return TRUE;
1493 }
1494 /******************************************************************************/
rafresh_window_orb()1495 void rafresh_window_orb()
1496 {
1497 if(GLArea != NULL)
1498 {
1499 gint j;
1500
1501 RebuildGeom = TRUE;
1502 RebuildSurf = TRUE;
1503 for(j=0;j<nCenters;j++)
1504 GeomOrb[j].Prop = prop_atom_get(GeomOrb[j].Symb);
1505
1506 redraw(GLArea,NULL);
1507 }
1508 }
1509 /********************************************************************************************/
1510 /* Configure the OpenGL framebuffer.*/
configure_gl()1511 static GdkGLConfig *configure_gl()
1512 {
1513 GdkGLConfig *glconfig;
1514 GdkGLConfigMode modedouble = GDK_GL_MODE_RGB | GDK_GL_MODE_DEPTH | GDK_GL_MODE_DOUBLE;
1515 GdkGLConfigMode modesimple = GDK_GL_MODE_RGB | GDK_GL_MODE_DEPTH;
1516 GdkGLConfigMode mode = GDK_GL_MODE_RGB;
1517 OpenGLOptions openGLOptions = get_opengl_options();
1518
1519 /* Try the user visual */
1520 if(openGLOptions.rgba !=0) mode = GDK_GL_MODE_RGBA;
1521 if(openGLOptions.depthSize!=0) mode |= GDK_GL_MODE_DEPTH;
1522 if(openGLOptions.alphaSize!=0) mode |= GDK_GL_MODE_ALPHA;
1523 if(openGLOptions.doubleBuffer!=0) mode |= GDK_GL_MODE_DOUBLE;
1524 glconfig = gdk_gl_config_new_by_mode (mode);
1525 if(glconfig!=NULL) return glconfig;
1526
1527
1528 /* Try double-buffered visual */
1529 glconfig = gdk_gl_config_new_by_mode (modedouble);
1530 if (glconfig == NULL)
1531 {
1532 printf ("\n*** Cannot find the double-buffered visual.\n");
1533 printf ("\n*** Trying single-buffered visual.\n");
1534
1535 /* Try single-buffered visual */
1536 glconfig = gdk_gl_config_new_by_mode (modesimple);
1537 if (glconfig == NULL)
1538 {
1539 printf ("*** No appropriate OpenGL-capable visual found.\n");
1540 exit (1);
1541 }
1542 }
1543 return glconfig;
1544 }
1545 /********************************************************************************/
open_menu(GtkWidget * Win,GdkEvent * event,gpointer Menu)1546 static void open_menu(GtkWidget *Win, GdkEvent *event, gpointer Menu)
1547 {
1548 GdkEventButton *bevent;
1549 bevent = (GdkEventButton *) event;
1550 popuo_menu_GL( bevent->button, bevent->time);
1551 }
1552 /********************************************************************************/
add_menu_button(GtkWidget * Win,GtkWidget * box)1553 static void add_menu_button(GtkWidget *Win, GtkWidget *box)
1554 {
1555 GtkWidget* menuButton;
1556 menuButton = gtk_button_new_with_label("M");
1557 gtk_box_pack_start (GTK_BOX (box), menuButton, FALSE, TRUE, 0);
1558
1559 g_signal_connect(G_OBJECT(menuButton), "button_press_event",G_CALLBACK(open_menu), NULL);
1560 gtk_widget_show (menuButton);
1561 }
1562 /********************************************************************************************/
NewGLArea(GtkWidget * vboxwin)1563 gboolean NewGLArea(GtkWidget* vboxwin)
1564 {
1565 GtkWidget* frame;
1566 /*
1567 gchar *info_str;
1568 */
1569 GtkWidget* table;
1570 GtkWidget* hboxtoolbar;
1571 GtkWidget* vbox;
1572
1573 #define DIMAL 13
1574 /* int k = 0;*/
1575 GdkGLConfig *glconfig;
1576
1577 /*
1578 k = 0;
1579 if(openGLOptions.alphaSize!=0)
1580 {
1581 attrlist[k++] = GDK_GL_ALPHA_SIZE;
1582 attrlist[k++] = 1;
1583 }
1584 if(openGLOptions.depthSize!=0)
1585 {
1586 attrlist[k++] = GDK_GL_DEPTH_SIZE;
1587 attrlist[k++] = 1;
1588 }
1589 if(openGLOptions.doubleBuffer!=0) attrlist[k++] = GDK_GL_DOUBLEBUFFER;
1590 */
1591 set_show_symbols(FALSE);
1592 set_show_distances(FALSE);
1593 trackball(Quat , 0.0, 0.0, 0.0, 0.0);
1594
1595 frame = gtk_frame_new (NULL);
1596 gtk_container_set_border_width (GTK_CONTAINER (frame), 0);
1597 gtk_frame_set_shadow_type( GTK_FRAME(frame),GTK_SHADOW_ETCHED_OUT);
1598 gtk_box_pack_start (GTK_BOX (vboxwin), frame, TRUE, TRUE, 0);
1599 gtk_widget_show (frame);
1600
1601 table = gtk_table_new(2,2,FALSE);
1602 gtk_container_add(GTK_CONTAINER(frame),table);
1603 gtk_widget_show(GTK_WIDGET(table));
1604
1605 /*
1606 hboxtoolbar = gtk_hbox_new (FALSE, 0);
1607 gtk_widget_show (hboxtoolbar);
1608 gtk_table_attach(GTK_TABLE(table), hboxtoolbar,0,1,0,1, (GtkAttachOptions)(GTK_FILL | GTK_SHRINK ), (GtkAttachOptions)(GTK_FILL | GTK_EXPAND ), 0,0);
1609 */
1610
1611 vbox = gtk_vbox_new (FALSE, 0);
1612 gtk_table_attach(GTK_TABLE(table), vbox, 0,1, 0,1, GTK_FILL , GTK_FILL, 0, 0);
1613 gtk_widget_show(vbox);
1614 add_menu_button(PrincipalWindow, vbox);
1615 hboxtoolbar = gtk_hbox_new (FALSE, 0);
1616 gtk_box_pack_start (GTK_BOX (vbox), hboxtoolbar, TRUE, TRUE, 0);
1617 gtk_widget_show(hboxtoolbar);
1618
1619
1620 gtk_quit_add_destroy(1, GTK_OBJECT(PrincipalWindow));
1621
1622 /* Create new OpenGL widget. */
1623 /* pthread_mutex_init (&theRender_mutex, NULL);*/
1624 GLArea = gtk_drawing_area_new ();
1625 gtk_drawing_area_size(GTK_DRAWING_AREA(GLArea),(gint)(ScreenHeight*0.2),(gint)(ScreenHeight*0.2));
1626 gtk_table_attach(GTK_TABLE(table),GLArea,1,2,0,1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND ), (GtkAttachOptions)(GTK_FILL | GTK_EXPAND ), 0,0);
1627 gtk_widget_show(GTK_WIDGET(GLArea));
1628 /* Events for widget must be set before X Window is created */
1629 gtk_widget_set_events(GLArea,
1630 GDK_EXPOSURE_MASK|
1631 GDK_BUTTON_PRESS_MASK|
1632 GDK_BUTTON_RELEASE_MASK|
1633 GDK_POINTER_MOTION_MASK|
1634 GDK_POINTER_MOTION_HINT_MASK |
1635 GDK_SCROLL_MASK
1636 );
1637 /* prepare GL */
1638 glconfig = configure_gl();
1639 if (!glconfig) { g_assert_not_reached (); }
1640 if (!gtk_widget_set_gl_capability (GLArea, glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE)) { g_assert_not_reached (); }
1641
1642 g_signal_connect(G_OBJECT(GLArea), "realize", G_CALLBACK(init), NULL);
1643 g_signal_connect(G_OBJECT(GLArea), "configure_event", G_CALLBACK(reshape), NULL);
1644 g_signal_connect(G_OBJECT(GLArea), "expose_event", G_CALLBACK(draw), NULL);
1645 /*gtk_widget_set_size_request(GTK_WIDGET(GLArea ),(gint)(ScreenHeight*0.2),(gint)(ScreenHeight*0.2));*/
1646
1647
1648 gtk_widget_realize(GTK_WIDGET(PrincipalWindow));
1649 /*
1650 info_str = gdk_gl_get_info();
1651 Debug("%s\n",info_str);
1652 g_free(info_str);
1653 */
1654
1655 g_signal_connect (G_OBJECT(GLArea), "button_press_event", G_CALLBACK(glarea_button_press), NULL);
1656 g_signal_connect_after(G_OBJECT(GLArea), "button_press_event", G_CALLBACK(event_dispatcher), NULL);
1657 g_signal_connect_after(G_OBJECT(GLArea), "motion_notify_event", G_CALLBACK(glarea_motion_notify), NULL);
1658 g_signal_connect (G_OBJECT(GLArea), "button_release_event", G_CALLBACK(glarea_button_release), NULL);
1659
1660
1661 create_toolbar_and_popup_menu_GL(hboxtoolbar);
1662 g_signal_connect(G_OBJECT (PrincipalWindow), "key_press_event", (GCallback) set_key_press, GLArea);
1663 g_signal_connect(G_OBJECT (PrincipalWindow), "key_release_event", (GCallback) set_key_release, NULL);
1664
1665
1666 return TRUE;
1667 }
1668 /*****************************************************************************/
1669