1 /* Povray.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 
21 #include "../../Config.h"
22 #include <stdlib.h>
23 #include <math.h>
24 
25 #include "../Common/Global.h"
26 #include "../Utils/UtilsInterface.h"
27 #include "../Geometry/InterfaceGeom.h"
28 #include "../Utils/Utils.h"
29 #include "../Utils/PovrayUtils.h"
30 #include "../Utils/AtomsProp.h"
31 #include "../Utils/Vector3d.h"
32 #include "../Utils/Constants.h"
33 #include "../Utils/Transformation.h"
34 #include "../Geometry/GeomGlobal.h"
35 #include "../Geometry/Measure.h"
36 #include "../Geometry/Fragments.h"
37 #include "../Geometry/DrawGeom.h"
38 #include "../Common/Windows.h"
39 
40 #define PRECISON_CYLINDER 0.001
41 
42 typedef struct _RGB
43 {
44 	/* Red Green Blue */
45  	gdouble Colors[3];
46 }RGB;
47 
48 typedef struct _XYZRC
49 {
50 	/* X=C[0], Y=C[1], Z =C[2] Radius=C[3] */
51  	gdouble C[4];
52 	/* RGB Colors */
53 	RGB P;
54 }XYZRC;
55 
56 /********************************************************************************/
get_pov_matrix_transformation()57 static gchar *get_pov_matrix_transformation()
58 {
59 	gdouble q[4];
60 	gdouble m[4][4];
61 	gchar* temp;
62 
63 	getQuatGeom(q);
64 	build_rotmatrix(m,q);
65 	temp = g_strdup_printf(
66 	 "// Rotation matrix\n"
67 	 "#declare myTransforms = transform {\n"
68 	 "matrix <%lf, %lf ,%lf, %lf, %lf, %lf, %lf, %lf, %lf, %lf, %lf ,%lf>\n"
69 	 "}\n\n",
70 	 m[0][0],m[0][1],m[0][2],
71 	 m[1][0],m[1][1],m[1][2],
72 	 m[2][0],m[2][1],m[2][2],
73 	 m[3][0],m[3][1],m[3][2]
74 	);
75 	return temp;
76 }
77 /********************************************************************************/
get_pov_begin_molecule()78 static gchar *get_pov_begin_molecule()
79 {
80      gchar *temp;
81      temp = g_strdup( "\n# declare molecule = union {\n");
82      return temp;
83 }
84 /********************************************************************************/
get_pov_end_molecule()85 static gchar *get_pov_end_molecule()
86 {
87      gchar *temp;
88      temp = g_strdup("transform { myTransforms }\n}\n\nobject {molecule}");
89      return temp;
90 }
91 /*****************************************************************************/
get_epaisseur(gint i,gint j)92 static gdouble get_epaisseur(gint i, gint j)
93 {
94 	gdouble factorstick = get_factorstick();
95         gdouble ei = 1.0/3.0*factorstick;
96         gdouble ej = 1.0/3.0*factorstick;
97         gdouble e = 1.0/3.0*factorstick;
98 	gdouble sl = 4.5;
99 	gdouble sm = 2;
100 	if(geometry[i].Layer == LOW_LAYER) ei /= sl;
101 	if(geometry[i].Layer == MEDIUM_LAYER) ei /= sm;
102 	if(geometry[j].Layer == LOW_LAYER) ej /= sl;
103 	if(geometry[j].Layer == MEDIUM_LAYER) ej /= sm;
104 	e = (ei<ej)?ei:ej;
105 	return e;
106 }
107 /*****************************************************************************/
get_rayon(gint i)108 static gdouble get_rayon(gint i)
109 {
110         gdouble rayon;
111 	gdouble factorball = get_factorball();
112 	gdouble sl = 4.5;
113 	gdouble sm = 2;
114         if ( !stick_mode() && geometry[i].Layer != LOW_LAYER )
115         {
116 		if(space_fill_mode()) rayon =(geometry[i].Prop.vanDerWaalsRadii*factorball);
117 		else rayon =(geometry[i].Prop.radii*factorball);
118 		if(geometry[i].Layer == LOW_LAYER) rayon /= sl;
119 		if(geometry[i].Layer == MEDIUM_LAYER) rayon /= sm;
120 	}
121 	else rayon = get_epaisseur(i,i);
122 	if(rayon<0.01) rayon = 0.01;
123 	return rayon;
124 }
125 /********************************************************************************/
degenerated_cylinder(gdouble * v1,gdouble * v2)126 static gboolean degenerated_cylinder(gdouble*  v1, gdouble* v2)
127 {
128 	gdouble d = 0;
129 	gint i;
130 	for(i=0;i<3;i++)
131 		d += (v1[i]-v2[i])*(v1[i]-v2[i]);
132 	if(d<PRECISON_CYLINDER) return TRUE;
133 	return FALSE;
134 }
135 /********************************************************************************/
get_prop_center(gint Num)136 static XYZRC get_prop_center(gint Num)
137 {
138         XYZRC PropCenter;
139 
140 	PropCenter.C[0]=geometry[Num].X;
141 	PropCenter.C[1]=geometry[Num].Y;
142 	PropCenter.C[2]=geometry[Num].Z;
143 	PropCenter.C[3]=geometry[Num].Prop.radii;
144 
145 	PropCenter.P.Colors[0]=(gdouble)(geometry[Num].Prop.color.red/65535.0);
146 	PropCenter.P.Colors[1]=(gdouble)(geometry[Num].Prop.color.green/65535.0);
147 	PropCenter.P.Colors[2]=(gdouble)(geometry[Num].Prop.color.blue/65535.0);
148 
149         return  PropCenter;
150 }
151 /********************************************************************************/
get_prop_dipole(gint i)152 static XYZRC get_prop_dipole(gint i)
153 {
154         XYZRC PropCenter;
155 
156 	PropCenter.C[0]=dipole[i][0];
157 	PropCenter.C[1]=dipole[i][1];
158 	PropCenter.C[2]=dipole[i][2];
159 	PropCenter.C[3]=geometry[0].Prop.radii*get_factor()/4*get_factorstick();
160 
161 	if(i<NDIVDIPOLE-1)
162 	{
163 		PropCenter.P.Colors[0]=0;
164 		PropCenter.P.Colors[1]=0;
165 		PropCenter.P.Colors[2]=(gdouble)(50000.0/65535.0);
166 	}
167 	else
168 	{
169 		PropCenter.P.Colors[0]=(gdouble)(50000.0/65535.0);
170 		PropCenter.P.Colors[1]=0;
171 		PropCenter.P.Colors[2]=0;
172 	}
173 
174         return  PropCenter;
175 }
176 /********************************************************************************/
get_pov_cone_dipole()177 static gchar *get_pov_cone_dipole()
178 {
179      XYZRC C1 = get_prop_dipole(NDIVDIPOLE-NDIVDIPOLE/5);
180      XYZRC C2 = get_prop_dipole(NDIVDIPOLE-1);
181      gdouble ep = C1.C[3]*2;
182      if(degenerated_cylinder(C1.C, C2.C)) return g_strdup(" ");
183      gchar* temp = g_strdup_printf(
184 		"cone\n"
185 		"{\n"
186 		"\t<%14.6f,%14.6f,%14.6f>,%14.6f\n"
187 		"\t<%14.6f,%14.6f,%14.6f>,0.0 \n"
188 		"\ttexture { finish { Dull } }\n"
189 		"\tpigment { rgb<%14.6f,%14.6f,%14.6f> }\n}\n",
190 		C1.C[0],C1.C[1],C1.C[2],ep,
191 		C2.C[0],C2.C[1],C2.C[2],
192 		C2.P.Colors[0],C2.P.Colors[1],C2.P.Colors[2]
193 		);
194      return temp;
195 }
196 /********************************************************************************/
get_pov_ball(gint num,gdouble scale)197 static gchar *get_pov_ball(gint num, gdouble scale)
198 {
199      gchar *temp;
200      XYZRC Center = get_prop_center(num);
201      temp = g_strdup_printf(
202 		"sphere\n"
203 		"{\n"
204 		"\t<%14.6f,%14.6f,%14.6f> %14.6f\n"
205 		"\ttexture { finish { Dull } }\n"
206 		"\tpigment { rgb<%14.6f,%14.6f,%14.6f> }\n}\n"
207 		,
208 		Center.C[0],Center.C[1],Center.C[2],Center.C[3]*get_factorball()*scale,
209 		Center.P.Colors[0], Center.P.Colors[1], Center.P.Colors[2]
210 		);
211      return temp;
212 }
213 /********************************************************************************/
get_pov_ball_for_stick(gint num,gdouble scale)214 static gchar *get_pov_ball_for_stick(gint num, gdouble scale)
215 {
216      gchar *temp;
217      XYZRC Center = get_prop_center(num);
218      temp = g_strdup_printf(
219 		"sphere\n"
220 		"{\n"
221 		"\t<%14.6f,%14.6f,%14.6f> %14.6f\n"
222 		"\ttexture { finish { Dull } }\n"
223 		"\tpigment { rgb<%14.6f,%14.6f,%14.6f> }\n}\n"
224 		,
225 		Center.C[0],Center.C[1],Center.C[2],scale*get_rayon(num),
226 		Center.P.Colors[0], Center.P.Colors[1], Center.P.Colors[2]
227 		);
228      return temp;
229 }
230 /********************************************************************************/
get_min(gint k)231 static gdouble get_min(gint k)
232 {
233      gdouble min=0;
234      gint i=0;
235 
236      if(k==0)
237      {
238      	min = geometry[0].X;
239      	for(i=1;i<(gint)Natoms;i++) if(min>geometry[i].X) min = geometry[i].X;
240      }
241      else
242      {
243      	if(k==1)
244      	{
245      		min = geometry[0].Y;
246      		for(i=1;i<(gint)Natoms;i++) if(min>geometry[i].Y) min = geometry[i].Y;
247      	}
248      	else
249      	{
250      		min = geometry[0].Z;
251      		for(i=1;i<(gint)Natoms;i++) if(min>geometry[i].Z) min = geometry[i].Z;
252      	}
253      }
254 
255      min -=100;
256     return min;
257 }
258 /********************************************************************************/
get_pov_cylingre(gdouble C1[],gdouble C2[],gdouble Colors[],gdouble ep)259 static gchar *get_pov_cylingre(gdouble C1[],gdouble C2[],gdouble Colors[],gdouble ep)
260 {
261      gchar* temp = g_strdup_printf(
262 		"cylinder\n"
263 		"{\n"
264 		"\t<%14.6f,%14.6f,%14.6f>,\n"
265 		"\t<%14.6f,%14.6f,%14.6f> \n"
266 		"\t%14.6f\n"
267 		"\ttexture { finish { Dull } }\n"
268 		"\tpigment { rgb<%14.6f,%14.6f,%14.6f> }\n}\n",
269 		C1[0],C1[1],C1[2],
270 		C2[0],C2[1],C2[2],
271 		ep,
272 		Colors[0],Colors[1],Colors[2]
273 		);
274 	return temp;
275 
276 }
277 /********************************************************************************/
get_pov_stick_dipole()278 static gchar *get_pov_stick_dipole()
279 {
280      gchar *temp;
281      XYZRC Center1;
282      XYZRC Center2;
283      gdouble ep;
284 
285      Center1 = get_prop_dipole(0);
286      Center2 = get_prop_dipole(NDIVDIPOLE-NDIVDIPOLE/5);
287      ep = Center1.C[3];
288      if(degenerated_cylinder(Center1.C, Center2.C)) return g_strdup(" ");
289 
290 
291       temp = get_pov_cylingre(Center1.C,Center2.C,Center1.P.Colors,ep);
292       return temp;
293 }
294 /********************************************************************************/
get_pov_one_stick_for_ball(gint i,gint j)295 static gchar *get_pov_one_stick_for_ball(gint i,gint j)
296 {
297      gchar *temp;
298      gchar *temp1;
299      gchar *temp2;
300      XYZRC Center1;
301      XYZRC Center2;
302      gint l;
303      gdouble ep;
304      gdouble poid1;
305      gdouble poid2;
306      gdouble poid;
307      gdouble C[3];
308      gint nc = get_connection_type(i,j);
309 
310      if(nc<1) return " ";
311 
312      if(!getShowMultipleBonds()) nc = 1;
313 
314      Center1 = get_prop_center(i);
315      Center2 = get_prop_center(j);
316 
317      ep =get_epaisseur(i,j);
318 
319      poid1 = geometry[i].Prop.covalentRadii+geometry[i].Prop.radii;
320      poid2 = geometry[j].Prop.covalentRadii+geometry[j].Prop.radii;
321      poid = poid1 + poid2 ;
322 
323      if(nc==3)
324      {
325 	gchar* t;
326 /*
327   	V3d vScal = {ep*0.5,ep*0.5,ep*0.5};
328 	gdouble C1[3];
329 	gdouble C2[3];
330 	V3d cros;
331 	V3d sub;
332 	V3d C0={0,0,0};
333 	gdouble C10[3];
334 	gdouble C20[3];
335 	gdouble CC1[3];
336 	gdouble CC2[3];
337 	for(l=0;l<3;l++) CC1[l] = Center1.C[l];
338 	for(l=0;l<3;l++) CC2[l] = Center2.C[l];
339 	v3d_sub(C0, CC1, C10);
340 	v3d_sub(C0, CC2, C20);
341 	v3d_cross(C10, C20, cros);
342 	v3d_sub(CC1, CC2, sub);
343 	v3d_cross(cros, sub, vScal);
344 	if(v3d_dot(vScal,vScal)!=0)
345 	{
346 		v3d_normal(vScal);
347 		v3d_scale(vScal, ep*0.5);
348 	}
349 	for(l=0;l<3;l++) C1[l] = Center1.C[l]-vScal[l];
350 	for(l=0;l<3;l++) C2[l] = Center2.C[l]-vScal[l];
351      	for(l=0;l<3;l++) C[l] =(C1[l]*poid2+C2[l]*poid1)/poid;
352       	temp1 = get_pov_cylingre(C1,C,Center1.P.Colors,ep/3);
353       	temp2 = get_pov_cylingre(C,C2,Center2.P.Colors,ep/3);
354       	temp = g_strdup_printf("%s%s",temp1,temp2);
355       	g_free(temp1);
356       	g_free(temp2);
357 
358 	for(l=0;l<3;l++) C1[l] = Center1.C[l];
359 	for(l=0;l<3;l++) C2[l] = Center2.C[l];
360      	for(l=0;l<3;l++) C[l] =(C1[l]*poid2+C2[l]*poid1)/poid;
361       	temp1 = get_pov_cylingre(C1,C,Center1.P.Colors,ep/3);
362       	temp2 = get_pov_cylingre(C,C2,Center2.P.Colors,ep/3);
363 	t = temp;
364       	temp = g_strdup_printf("%s%s%s",t,temp1,temp2);
365       	g_free(temp1);
366       	g_free(temp2);
367       	g_free(t);
368 
369 	for(l=0;l<3;l++) C1[l] = Center1.C[l]+vScal[l];
370 	for(l=0;l<3;l++) C2[l] = Center2.C[l]+vScal[l];
371      	for(l=0;l<3;l++) C[l] =(C1[l]*poid2+C2[l]*poid1)/poid;
372       	temp1 = get_pov_cylingre(C1,C,Center1.P.Colors,ep/3);
373       	temp2 = get_pov_cylingre(C,C2,Center2.P.Colors,ep/3);
374 	t = temp;
375       	temp = g_strdup_printf("%s%s%s",t,temp1,temp2);
376       	g_free(temp1);
377       	g_free(temp2);
378       	g_free(t);
379 */
380 		V3d C0;
381 		gdouble r = ep;
382 		gdouble C11[3];
383 		gdouble C12[3];
384 		gdouble C21[3];
385 		gdouble C22[3];
386 		gdouble C31[3];
387 		gdouble C32[3];
388 		gdouble C[3];
389 		gdouble rs[3];
390 		gdouble Ci[3];
391 		gdouble Cj[3];
392 		gint type = 1;
393 		if(geometry[i].Layer == LOW_LAYER || geometry[j].Layer == LOW_LAYER) type = 0;
394 		getOptimalCiCj(i, j, Ci, Cj,C0);
395 		getPositionsRadiusBond3(r, C0, Ci, Cj, C11, C12,  C21,  C22, C31, C32, rs, type);
396 
397      		for(l=0;l<3;l++) C[l] =(C11[l]*poid2+C12[l]*poid1)/poid;
398       		temp1 = get_pov_cylingre(C11,C,Center1.P.Colors,rs[0]);
399       		temp2 = get_pov_cylingre(C,C12,Center2.P.Colors,rs[0]);
400       		temp = g_strdup_printf("%s%s",temp1,temp2);
401       		g_free(temp1);
402       		g_free(temp2);
403 
404      		for(l=0;l<3;l++) C[l] =(C21[l]*poid2+C22[l]*poid1)/poid;
405       		temp1 = get_pov_cylingre(C21,C,Center1.P.Colors,rs[1]);
406       		temp2 = get_pov_cylingre(C,C22,Center2.P.Colors,rs[1]);
407 		t = temp;
408       		temp = g_strdup_printf("%s%s%s",t,temp1,temp2);
409       		g_free(temp1);
410       		g_free(temp2);
411       		g_free(t);
412 
413      		for(l=0;l<3;l++) C[l] =(C31[l]*poid2+C32[l]*poid1)/poid;
414       		temp1 = get_pov_cylingre(C31,C,Center1.P.Colors,rs[2]);
415       		temp2 = get_pov_cylingre(C,C32,Center2.P.Colors,rs[2]);
416 		t = temp;
417       		temp = g_strdup_printf("%s%s%s",t,temp1,temp2);
418       		g_free(temp1);
419       		g_free(temp2);
420       		g_free(t);
421 
422      }
423      else
424      if(nc==2)
425      {
426 	gchar* t;
427 	gdouble r = ep;
428 	gdouble C11[3];
429 	gdouble C12[3];
430 	gdouble C21[3];
431 	gdouble C22[3];
432 	gdouble C[3];
433 	V3d C0;
434 	gdouble rs[3];
435 	gint type = 1;
436 	if(geometry[i].Layer == LOW_LAYER || geometry[j].Layer == LOW_LAYER) type = 0;
437 
438 	getOptimalCiCj(i, j, Center1.C, Center2.C, C0);
439 	getPositionsRadiusBond2(r, C0, Center1.C, Center2.C, C11, C12,  C21,  C22, rs, type);
440 
441      	for(l=0;l<3;l++) C[l] =(C11[l]*poid2+C12[l]*poid1)/poid;
442       	temp1 = get_pov_cylingre(C11,C,Center1.P.Colors,rs[0]);
443       	temp2 = get_pov_cylingre(C,C12,Center2.P.Colors,rs[0]);
444       	temp = g_strdup_printf("%s%s",temp1,temp2);
445       	g_free(temp1);
446       	g_free(temp2);
447 
448      	for(l=0;l<3;l++) C[l] =(C21[l]*poid2+C22[l]*poid1)/poid;
449       	temp1 = get_pov_cylingre(C21,C,Center1.P.Colors,rs[1]);
450       	temp2 = get_pov_cylingre(C,C22,Center2.P.Colors,rs[1]);
451 	t = temp;
452       	temp = g_strdup_printf("%s%s%s",t,temp1,temp2);
453       	g_free(temp1);
454       	g_free(temp2);
455       	g_free(t);
456 
457      }
458      else
459      {
460      	for(l=0;l<3;l++) C[l] =(Center1.C[l]*poid2+Center2.C[l]*poid1)/poid;
461       	temp1 = get_pov_cylingre(Center1.C,C,Center1.P.Colors,ep);
462       	temp2 = get_pov_cylingre(C,Center2.C,Center2.P.Colors,ep);
463       	temp = g_strdup_printf("%s%s",temp1,temp2);
464       	g_free(temp1);
465       	g_free(temp2);
466      }
467 
468       return temp;
469 }
470 /********************************************************************************/
get_pov_one_stick(gint i,gint j)471 static gchar *get_pov_one_stick(gint i,gint j)
472 {
473      gchar *temp;
474      gchar *temp1;
475      gchar *temp2;
476      XYZRC Center1;
477      XYZRC Center2;
478      gint l;
479      gdouble ep;
480      gdouble poid1;
481      gdouble poid2;
482      gdouble poid;
483      gdouble C[3];
484      gint nc = get_connection_type(i,j);
485 
486      if(nc<1) return " ";
487      if(!getShowMultipleBonds()) nc = 1;
488 
489      Center1 = get_prop_center(i);
490      Center2 = get_prop_center(j);
491      get_num_min_rayonIJ(i,j);
492 
493      ep =get_epaisseur(i,j);
494 
495      poid1 = geometry[i].Prop.covalentRadii+geometry[i].Prop.radii;
496      poid2 = geometry[j].Prop.covalentRadii+geometry[j].Prop.radii;
497      poid = poid1 + poid2 ;
498 
499      if(nc==3)
500      {
501 	gchar* t;
502 /*
503   	V3d vScal = {ep,ep,ep};
504 	gdouble C1[3];
505 	gdouble C2[3];
506 	gdouble C12[3];
507 	V3d cros;
508 	V3d sub;
509 	V3d C0={0,0,0};
510 	gdouble C10[3];
511 	gdouble C20[3];
512 	gdouble CC1[3];
513 	gdouble CC2[3];
514 	for(l=0;l<3;l++) CC1[l] = Center1.C[l];
515 	for(l=0;l<3;l++) CC2[l] = Center2.C[l];
516 	v3d_sub(C0, CC1, C10);
517 	v3d_sub(C0, CC2, C20);
518 	v3d_cross(C10, C20, cros);
519 	v3d_sub(CC1, CC2, sub);
520 	v3d_cross(cros, sub, vScal);
521 	if(v3d_dot(vScal,vScal)!=0)
522 	{
523 		v3d_normal(vScal);
524 		v3d_scale(vScal, ep*2);
525 	}
526 	for(l=0;l<3;l++) C1[l] = Center1.C[l]-vScal[l];
527 	for(l=0;l<3;l++) C2[l] = Center2.C[l]-vScal[l];
528      	for(l=0;l<3;l++) C[l] =(C1[l]*poid2+C2[l]*poid1)/poid;
529 
530 	v3d_sub(CC1, CC2, C12);
531 	if(v3d_dot(C12,C12)!=0)
532 	{
533 		v3d_normal(C12);
534 	}
535 	for(l=0;l<3;l++) C1[l] -= C12[l]*ep;
536 	for(l=0;l<3;l++) C2[l] += C12[l]*ep;
537 
538       	temp1 = get_pov_cylingre(C1,C,Center1.P.Colors,ep/2);
539       	temp2 = get_pov_cylingre(C,C2,Center2.P.Colors,ep/2);
540       	temp = g_strdup_printf("%s%s",temp1,temp2);
541       	g_free(temp1);
542       	g_free(temp2);
543 
544 
545 	for(l=0;l<3;l++) C1[l] = Center1.C[l];
546 	for(l=0;l<3;l++) C2[l] = Center2.C[l];
547      	for(l=0;l<3;l++) C[l] =(C1[l]*poid2+C2[l]*poid1)/poid;
548       	temp1 = get_pov_cylingre(C1,C,Center1.P.Colors,ep);
549       	temp2 = get_pov_cylingre(C,C2,Center2.P.Colors,ep);
550 	t = temp;
551       	temp = g_strdup_printf("%s%s%s",t,temp1,temp2);
552       	g_free(temp1);
553       	g_free(temp2);
554       	g_free(t);
555 
556 	for(l=0;l<3;l++) C1[l] = Center1.C[l]+vScal[l];
557 	for(l=0;l<3;l++) C2[l] = Center2.C[l]+vScal[l];
558      	for(l=0;l<3;l++) C[l] =(C1[l]*poid2+C2[l]*poid1)/poid;
559 
560 	for(l=0;l<3;l++) C1[l] -= C12[l]*ep;
561 	for(l=0;l<3;l++) C2[l] += C12[l]*ep;
562 
563       	temp1 = get_pov_cylingre(C1,C,Center1.P.Colors,ep/2);
564       	temp2 = get_pov_cylingre(C,C2,Center2.P.Colors,ep/2);
565 	t = temp;
566       	temp = g_strdup_printf("%s%s%s",t,temp1,temp2);
567       	g_free(temp1);
568       	g_free(temp2);
569       	g_free(t);
570 */
571 		V3d C0;
572 		gdouble r = ep;
573 		gdouble C11[3];
574 		gdouble C12[3];
575 		gdouble C21[3];
576 		gdouble C22[3];
577 		gdouble C31[3];
578 		gdouble C32[3];
579 		gdouble C[3];
580 		gdouble rs[3];
581 		gdouble Ci[3];
582 		gdouble Cj[3];
583 		gint type = 0;
584 		getOptimalCiCj(i, j, Ci, Cj,C0);
585 		getPositionsRadiusBond3(r, C0, Ci, Cj, C11, C12,  C21,  C22, C31, C32, rs, type);
586 
587      		for(l=0;l<3;l++) C[l] =(C11[l]*poid2+C12[l]*poid1)/poid;
588       		temp1 = get_pov_cylingre(C11,C,Center1.P.Colors,rs[0]);
589       		temp2 = get_pov_cylingre(C,C12,Center2.P.Colors,rs[0]);
590       		temp = g_strdup_printf("%s%s",temp1,temp2);
591       		g_free(temp1);
592       		g_free(temp2);
593 
594      		for(l=0;l<3;l++) C[l] =(C21[l]*poid2+C22[l]*poid1)/poid;
595       		temp1 = get_pov_cylingre(C21,C,Center1.P.Colors,rs[1]);
596       		temp2 = get_pov_cylingre(C,C22,Center2.P.Colors,rs[1]);
597 		t = temp;
598       		temp = g_strdup_printf("%s%s%s",t,temp1,temp2);
599       		g_free(temp1);
600       		g_free(temp2);
601       		g_free(t);
602 
603      		for(l=0;l<3;l++) C[l] =(C31[l]*poid2+C32[l]*poid1)/poid;
604       		temp1 = get_pov_cylingre(C31,C,Center1.P.Colors,rs[2]);
605       		temp2 = get_pov_cylingre(C,C32,Center2.P.Colors,rs[2]);
606 		t = temp;
607       		temp = g_strdup_printf("%s%s%s",t,temp1,temp2);
608       		g_free(temp1);
609       		g_free(temp2);
610       		g_free(t);
611 
612      }
613      else
614      if(nc==2)
615      {
616 	gchar* t;
617 	gdouble r = ep;
618 	gdouble C11[3];
619 	gdouble C12[3];
620 	gdouble C21[3];
621 	gdouble C22[3];
622 	gdouble C[3];
623 	gdouble rs[3];
624 	gint type = 0;
625 	V3d C0;
626 	getOptimalCiCj(i, j, Center1.C, Center2.C, C0);
627 	getPositionsRadiusBond2(r, C0, Center1.C, Center2.C, C11, C12,  C21,  C22, rs, type);
628 
629      	for(l=0;l<3;l++) C[l] =(C11[l]*poid2+C12[l]*poid1)/poid;
630       	temp1 = get_pov_cylingre(C11,C,Center1.P.Colors,rs[0]);
631       	temp2 = get_pov_cylingre(C,C12,Center2.P.Colors,rs[0]);
632       	temp = g_strdup_printf("%s%s",temp1,temp2);
633       	g_free(temp1);
634       	g_free(temp2);
635 
636      	for(l=0;l<3;l++) C[l] =(C21[l]*poid2+C22[l]*poid1)/poid;
637       	temp1 = get_pov_cylingre(C21,C,Center1.P.Colors,rs[1]);
638       	temp2 = get_pov_cylingre(C,C22,Center2.P.Colors,rs[1]);
639 	t = temp;
640       	temp = g_strdup_printf("%s%s%s",t,temp1,temp2);
641       	g_free(temp1);
642       	g_free(temp2);
643       	g_free(t);
644      }
645      else
646      {
647      	for(l=0;l<3;l++) C[l] =(Center1.C[l]*poid2+Center2.C[l]*poid1)/poid;
648       	temp1 = get_pov_cylingre(Center1.C,C,Center1.P.Colors,ep);
649       	temp2 = get_pov_cylingre(C,Center2.C,Center2.P.Colors,ep);
650       	temp = g_strdup_printf("%s%s",temp1,temp2);
651       	g_free(temp1);
652       	g_free(temp2);
653      }
654 
655       return temp;
656 }
657 /********************************************************************************/
get_pov_one_hbond(gint i,gint j)658 static gchar *get_pov_one_hbond(gint i,gint j)
659 {
660      gchar *temp;
661      XYZRC Center1;
662      XYZRC Center2;
663      gint l;
664      gdouble ep;
665      gdouble poid1;
666      gdouble poid2;
667      gdouble poid;
668      gint n = 10;
669      gdouble A[3];
670      gdouble B[3];
671      gdouble K[3];
672      gchar *dump;
673      gchar *temp1;
674      gint ibreak;
675      gdouble aspect = 0.3;
676 
677      if( !hbond_connections(i,j)) return " ";
678 
679      Center1 = get_prop_center(i);
680      Center2 = get_prop_center(j);
681 
682      if(geometry[i].Prop.radii<geometry[j].Prop.radii) ep = geometry[i].Prop.radii*aspect;
683      else ep = geometry[j].Prop.radii*aspect;
684 
685 
686      poid1 = geometry[i].Prop.covalentRadii+geometry[i].Prop.radii;
687      poid2 = geometry[j].Prop.covalentRadii+geometry[j].Prop.radii;
688      poid = poid1 + poid2 ;
689 
690      ibreak = (gint)(poid1*n/poid);
691      ibreak = n/2;
692 
693      for(l=0;l<3;l++) K[l] =(Center2.C[l]-Center1.C[l])/(n);
694      for(l=0;l<3;l++) A[l] =Center1.C[l];
695      temp = NULL;
696      for(i=0;i<n;i++)
697      {
698      	for(l=0;l<3;l++) B[l] = A[l] + K[l];
699 	if(i%2==0)
700 	{
701 		if(i<=ibreak) temp1 =  get_pov_cylingre(A,B,Center1.P.Colors,ep/2);
702 		else temp1 =  get_pov_cylingre(A,B,Center2.P.Colors,ep/2);
703 		dump = temp;
704 		if(dump)
705 		{
706      			temp = g_strdup_printf("%s%s",dump,temp1);
707 			g_free(dump);
708 		}
709 		else temp = g_strdup_printf("%s",temp1);
710 		g_free(temp1);
711 		temp1 = NULL;
712 	}
713      	for(l=0;l<3;l++) A[l] = B[l];
714      }
715 
716      if(temp1) g_free(temp1);
717      return temp;
718 }
719 /********************************************************************************/
get_pov_epilogue()720 static gchar *get_pov_epilogue()
721 {
722      gchar *temp;
723      temp = g_strdup(
724 	 "// ****This file was generated by Gabedit ****\n\n"
725 	 "#include \"colors.inc\"\n"
726 	 "#include \"textures.inc\"\n"
727 	 "#include \"shapes.inc\"\n"
728 	 "#include \"stones1.inc\"\n\n"
729 	);
730      return temp;
731 }
732 /********************************************************************************/
get_pov_camera()733 static gchar *get_pov_camera()
734 {
735 	gchar *temp;
736 	gdouble f = 5;
737 	gdouble position = 10;
738 	gdouble zn, zf, angle;
739 	gboolean perspective;
740 	gdouble aspect = 1.0;
741 	gdouble H = 100;
742 	gdouble W = 100;
743 	gdouble fov = 0;
744 	gdouble d = 0;
745 	gdouble origin[3];
746 
747 	get_camera_values_drawgeom(&zn, &zf, &angle, &aspect, &perspective);
748 	get_orgin_molecule_drawgeom(origin);
749 	fov = angle;
750 
751 	position = zf/2;
752 	f = 0;
753 
754 	d = zf-zn;
755 	if(d !=0)
756 	{
757 		H = 2*d*tan(PI/360*angle);
758 		W = aspect*H;
759 		fov = 360/PI*atan(W/2/d);
760 	}
761 	/* if(!perspective) fov = angle;*/
762 	if(fov<0) fov = 360+fov;
763 	if(fov>180) fov = 179.99;
764 
765 
766 
767 
768 	if(perspective)
769 	temp = g_strdup_printf(
770 	 "// CAMERA\n"
771 	 "camera\n"
772 	 "{\n"
773 	 "\tright     %0.14f *x\n"
774 	  "\tup        y\n"
775 	  "\tdirection -z\n"
776 	  "\tangle %0.14f\n"
777 	  "\tlocation  < 0.000000, 0.00000, %0.14f >\n"
778 	  "\tlook_at   < 0.000000, 0.00000, %0.14f >\n"
779 	  "\ttranslate < %0.14f , %0.14f , 0.000000 >\n"
780 	  "}\n\n",
781 	   aspect,
782 	   fov,
783 	   position,f,
784 	   -origin[0],
785 	   -origin[1]
786 	);
787 	else
788 	temp = g_strdup_printf(
789 	 "// CAMERA\n"
790 	 "camera\n"
791  	 "{\torthographic\n"
792 	 "\tright     %0.14f *x\n"
793 	  "\tup        y\n"
794 	  "\tdirection -z\n"
795 	  "\tlocation  < 0.000000, 0.00000, %14.8f >\n"
796 	 "\t scale     %0.14f\n"
797 	  "\ttranslate < %0.14f , %0.14f , 0.000000 >\n"
798 	  "}\n\n",
799 	   aspect,
800 	   position,
801 	   angle,
802 	   -origin[0],
803 	   -origin[1]
804 	   );
805      return temp;
806 }
807 /********************************************************************************/
get_pov_light_source(gchar * title,gchar * color,gdouble x,gdouble y,gdouble z)808 static gchar *get_pov_light_source(gchar* title,gchar* color,gdouble x,gdouble y, gdouble z)
809 {
810 	gchar *temp;
811      	temp = g_strdup_printf("%s%s\t<%10.6f,%10.6f,%10.6f>\n\tcolor %s\n}\n",
812 				title,
813          			"light_source\n"
814          			"{\n",
815 				 x,y,z,color);
816 	return temp;
817 }
818 /********************************************************************************/
get_pov_light_sources()819 static gchar *get_pov_light_sources()
820 {
821      gchar *temp;
822      gchar *dum1;
823      gchar *dum2;
824      gdouble Ymax;
825      gint i=0;
826 /* calcul of Ymax*/
827 
828      Ymax = geometry[0].Y;
829      for(i=1;i<(gint)Natoms;i++)
830 		if(Ymax<geometry[i].Y)
831 			Ymax = geometry[i].Y;
832 
833      Ymax =Ymax*2+100;
834      printf("Ymax = %f\n",Ymax);
835      /* dum1 = get_pov_light_source("// LIGHT 1\n","0.8*White",0,Ymax/10,Ymax);*/
836      dum1 = g_strdup(" ");
837      dum2 = get_pov_light_source("// LIGHT 1\n","0.8*White",0,0,Ymax);
838      temp = g_strdup_printf("%s %s",dum1,dum2);
839      g_free(dum1);
840      g_free(dum2);
841      return temp;
842 }
843 /********************************************************************************/
get_pov_atoms(gdouble scal)844 static gchar *get_pov_atoms(gdouble scal)
845 {
846 	gdouble factorball = get_factorball();
847      	gchar *temp=NULL;
848      	gchar *tempold=NULL;
849      	gchar *t=NULL;
850      	gint i=0;
851      	temp = g_strdup( "// ATOMS \n");
852 	for(i=0;i<(gint)Natoms;i++)
853 	{
854  		gdouble r = scal*get_rayon(i)/(geometry[i].Prop.radii*factorball);
855 		if(!geometry[i].show) continue;
856 		tempold = temp;
857 		t =get_pov_ball(i,r);
858 		if(tempold)
859 		{
860 			temp = g_strdup_printf("%s%s",tempold,t);
861 			g_free(tempold);
862 		}
863 		else
864 			temp = g_strdup_printf("%s",t);
865 		if(t)
866 		  g_free(t);
867 	}
868 
869      return temp;
870 }
871 /********************************************************************************/
get_pov_atoms_for_stick(gdouble scal)872 static gchar *get_pov_atoms_for_stick(gdouble scal)
873 {
874      	gchar *temp=NULL;
875      	gchar *tempold=NULL;
876      	gchar *t=NULL;
877      	gint i=0;
878      	temp = g_strdup( "// ATOMS \n");
879 	for(i=0;i<(gint)Natoms;i++)
880 	{
881 		if(!geometry[i].show) continue;
882 		tempold = temp;
883 		t =get_pov_ball_for_stick(i,scal);
884 		if(tempold)
885 		{
886 			temp = g_strdup_printf("%s%s",tempold,t);
887 			g_free(tempold);
888 		}
889 		else
890 			temp = g_strdup_printf("%s",t);
891 		if(t)
892 		  g_free(t);
893 	}
894 
895      return temp;
896 }
897 /********************************************************************************/
get_pov_bonds(gboolean ballstick)898 static gchar *get_pov_bonds(gboolean ballstick)
899 {
900      gchar *temp = NULL;
901      gint i,j;
902      gchar* t;
903      gchar* tempold;
904      gboolean* Ok = NULL;
905      if(Natoms>0) Ok = g_malloc(Natoms*sizeof(gboolean));
906      for(i=0;i<(gint)Natoms;i++) Ok[i] = FALSE;
907 
908      temp = g_strdup( "// BONDS \n");
909      for(i=0;i<(gint)(Natoms-1);i++)
910      {
911 		if(!geometry[i].show) continue;
912 	for(j=i+1;j<(gint)Natoms;j++)
913 		if(get_connection_type(i,j)>0 && geometry[i].show && geometry[j].show)
914 	 	{
915 			Ok[i] = TRUE;
916 			Ok[j] = TRUE;
917 			tempold = temp;
918 			if(ballstick) t =get_pov_one_stick_for_ball(i,j);
919 			else t =get_pov_one_stick(i,j);
920 			if(tempold)
921                 	{
922                         	temp = g_strdup_printf("%s%s",tempold,t);
923                         	g_free(tempold);
924                 	}
925                 	else temp = g_strdup_printf("%s",t);
926 	 	}
927      		else
928 		{
929 			if(hbond_connections(i,j) && geometry[i].show && geometry[j].show)
930 			{
931 				tempold = temp;
932 				t =get_pov_one_hbond(i,j);
933 				if(tempold)
934                 		{
935                         		temp = g_strdup_printf("%s%s",tempold,t);
936                         		g_free(tempold);
937                 		}
938                 		else temp = g_strdup_printf("%s",t);
939 			}
940 		}
941      }
942      for(i=0;i<(gint)(Natoms-1);i++)
943 	if(!Ok[i] && geometry[i].show)
944 	{
945 		tempold = temp;
946 		t =get_pov_ball(i, 0.5);
947 		if(tempold)
948 		{
949 			temp = g_strdup_printf("%s%s",tempold,t);
950 			g_free(tempold);
951 		}
952 		else
953 			temp = g_strdup_printf("%s",t);
954 		if(t)
955 		  g_free(t);
956 	}
957      return temp;
958 }
959 /********************************************************************************/
get_pov_dipole()960 static gchar *get_pov_dipole()
961 {
962 	gchar* t1;
963 	gchar* t2;
964 	gchar* t = NULL;
965 
966      	t = g_strdup( "// Dipole \n");
967 	t1 = t;
968 	t2 = get_pov_stick_dipole();
969 	t = g_strdup_printf("%s%s",t1,t2);
970 	g_free(t1);
971 	g_free(t2);
972 	t1 = t;
973 	t2 = get_pov_cone_dipole();
974 	t = g_strdup_printf("%s%s",t1,t2);
975 	g_free(t1);
976 	g_free(t2);
977 	return t;
978 }
979 /*****************************************************************************/
get_pov_box()980 static gchar* get_pov_box()
981 {
982 	guint i;
983 	guint j;
984     	gdouble rayon;
985 	gint ni, nj;
986 	gchar tmp[BSIZE];
987 	gint nTv = 0;
988 	gint iTv[3] = {-1,-1,-1};
989 	V3d Base1Pos;
990 	V3d Base2Pos;
991 	V4d Specular = {1.0f,1.0f,1.0f,1.0f};
992         V4d Diffuse  = {1.0f,1.0f,1.0f,1.0f};
993         V4d Ambiant  = {1.0f,1.0f,1.0f,1.0f};
994 	gdouble radius = 0.1;
995 	gdouble Tv[3][3];
996 	gdouble O[3];
997      	gchar *temp;
998      	gchar *temp_all;
999      	XYZRC Center1;
1000      	XYZRC Center2;
1001 	gdouble Orig[3]= {0,0,0};
1002 	gchar* t;
1003 
1004 	if(!testShowBoxGeom()) return g_strdup("\n");
1005 	for(i=0;i<Natoms;i++)
1006 	{
1007 		sprintf(tmp,"%s",geometry[i].Prop.symbol);
1008 		uppercase(tmp);
1009 		if(!strcmp(tmp,"TV")) { iTv[nTv]= i; nTv++;}
1010 	}
1011 	if(nTv<2) return g_strdup("\n");
1012 	get_origine_molecule_drawgeom(Orig);
1013 	for(i=0;i<3;i++) O[i] = -Orig[i];
1014 	for(i=0;i<nTv;i++)
1015 	{
1016 		Tv[i][0] = geometry[iTv[i]].X-O[0];
1017 		Tv[i][1] = geometry[iTv[i]].Y-O[1];
1018 		Tv[i][2] = geometry[iTv[i]].Z-O[2];
1019 	}
1020 	for(i=0;i<3;i++) Base1Pos[i] = O[i];
1021 	for(i=0;i<3;i++) Base2Pos[i] = Base1Pos[i]+Tv[0][i];
1022         temp_all = get_pov_cylingre(Base1Pos,Base2Pos,Specular,radius);
1023 
1024 	for(i=0;i<3;i++) Base1Pos[i] = O[i];
1025 	for(i=0;i<3;i++) Base2Pos[i] = Base1Pos[i]+Tv[1][i];
1026         temp = get_pov_cylingre(Base1Pos,Base2Pos,Specular,radius);
1027 	t = temp_all; temp_all = g_strdup_printf("%s%s",t,temp); g_free(temp); g_free(t);
1028 
1029 	for(i=0;i<3;i++) Base1Pos[i] = O[i]+Tv[0][i];
1030 	for(i=0;i<3;i++) Base2Pos[i] = Base1Pos[i]+Tv[1][i];
1031         temp = get_pov_cylingre(Base1Pos,Base2Pos,Specular,radius);
1032 	t = temp_all; temp_all = g_strdup_printf("%s%s",t,temp); g_free(temp); g_free(t);
1033 
1034 	for(i=0;i<3;i++) Base1Pos[i] = O[i]+Tv[1][i];
1035 	for(i=0;i<3;i++) Base2Pos[i] = Base1Pos[i]+Tv[0][i];
1036         temp = get_pov_cylingre(Base1Pos,Base2Pos,Specular,radius);
1037 	t = temp_all; temp_all = g_strdup_printf("%s%s",t,temp); g_free(temp); g_free(t);
1038 	if(nTv<3) return temp_all;
1039 
1040 	for(i=0;i<3;i++) Base1Pos[i] = O[i];
1041 	for(i=0;i<3;i++) Base2Pos[i] = Base1Pos[i]+Tv[2][i];
1042         temp = get_pov_cylingre(Base1Pos,Base2Pos,Specular,radius);
1043 	t = temp_all; temp_all = g_strdup_printf("%s%s",t,temp); g_free(temp); g_free(t);
1044 
1045 	for(i=0;i<3;i++) Base1Pos[i] = O[i]+Tv[0][i];
1046 	for(i=0;i<3;i++) Base2Pos[i] = Base1Pos[i]+Tv[2][i];
1047         temp = get_pov_cylingre(Base1Pos,Base2Pos,Specular,radius);
1048 	t = temp_all; temp_all = g_strdup_printf("%s%s",t,temp); g_free(temp); g_free(t);
1049 
1050 	for(i=0;i<3;i++) Base1Pos[i] = O[i]+Tv[2][i];
1051 	for(i=0;i<3;i++) Base2Pos[i] = Base1Pos[i]+Tv[0][i];
1052         temp = get_pov_cylingre(Base1Pos,Base2Pos,Specular,radius);
1053 	t = temp_all; temp_all = g_strdup_printf("%s%s",t,temp); g_free(temp); g_free(t);
1054 
1055 	for(i=0;i<3;i++) Base1Pos[i] = O[i]+Tv[1][i];
1056 	for(i=0;i<3;i++) Base2Pos[i] = Base1Pos[i]+Tv[2][i];
1057         temp = get_pov_cylingre(Base1Pos,Base2Pos,Specular,radius);
1058 	t = temp_all; temp_all = g_strdup_printf("%s%s",t,temp); g_free(temp); g_free(t);
1059 
1060 	for(i=0;i<3;i++) Base1Pos[i] = O[i]+Tv[2][i];
1061 	for(i=0;i<3;i++) Base2Pos[i] = Base1Pos[i]+Tv[1][i];
1062         temp = get_pov_cylingre(Base1Pos,Base2Pos,Specular,radius);
1063 	t = temp_all; temp_all = g_strdup_printf("%s%s",t,temp); g_free(temp); g_free(t);
1064 
1065 	for(i=0;i<3;i++) Base1Pos[i] = O[i]+Tv[0][i]+Tv[2][i];
1066 	for(i=0;i<3;i++) Base2Pos[i] = Base1Pos[i]+Tv[1][i];
1067         temp = get_pov_cylingre(Base1Pos,Base2Pos,Specular,radius);
1068 	t = temp_all; temp_all = g_strdup_printf("%s%s",t,temp); g_free(temp); g_free(t);
1069 
1070 	for(i=0;i<3;i++) Base1Pos[i] = O[i]+Tv[0][i]+Tv[1][i];
1071 	for(i=0;i<3;i++) Base2Pos[i] = Base1Pos[i]+Tv[2][i];
1072         temp = get_pov_cylingre(Base1Pos,Base2Pos,Specular,radius);
1073 	t = temp_all; temp_all = g_strdup_printf("%s%s",t,temp); g_free(temp); g_free(t);
1074 
1075 	for(i=0;i<3;i++) Base1Pos[i] = O[i]+Tv[1][i]+Tv[2][i];
1076 	for(i=0;i<3;i++) Base2Pos[i] = Base1Pos[i]+Tv[0][i];
1077         temp = get_pov_cylingre(Base1Pos,Base2Pos,Specular,radius);
1078 	t = temp_all; temp_all = g_strdup_printf("%s%s",t,temp); g_free(temp); g_free(t);
1079 
1080       return temp_all;
1081 
1082 }
1083 /********************************************************************************/
1084 
1085 /********************************************************************************/
export_to_povray(gchar * fileName)1086 static gchar* export_to_povray(gchar* fileName)
1087 {
1088   gchar *temp;
1089   gdouble xmin;
1090   gdouble ymin;
1091   gdouble zmin;
1092   FILE *fd=NULL;
1093   gchar* message = NULL;
1094 
1095  fd = FOpen(fileName, "w");
1096  if(fd)
1097  {
1098 	temp =get_pov_epilogue();
1099 	fprintf(fd,"%s",temp);
1100 	g_free(temp);
1101 
1102 	temp = get_pov_matrix_transformation();
1103 	fprintf(fd,"%s",temp);
1104 	g_free(temp);
1105 
1106 	temp =get_pov_camera();
1107 	fprintf(fd,"%s",temp);
1108 	g_free(temp);
1109 	temp = get_pov_light_sources();
1110 	fprintf(fd,"%s",temp);
1111 	g_free(temp);
1112 
1113 	xmin = get_min(0);
1114 	ymin = get_min(1);
1115 	zmin = get_min(2);
1116 	temp = get_pov_background(xmin, ymin,zmin);
1117 	fprintf(fd,"%s",temp);
1118 	g_free(temp);
1119 
1120      	if(Natoms<1)
1121 	{
1122 		fclose(fd);
1123 	 	message = g_strdup_printf(_("\nSorry, The number of atoms should be >0\n"));
1124 		return message;
1125 	}
1126 	temp = get_pov_begin_molecule();
1127 	fprintf(fd,"%s",temp);
1128 	g_free(temp);
1129 
1130 	if( !stick_mode())
1131 	{
1132 		temp = get_pov_atoms(1.0);
1133 		fprintf(fd,"%s",temp);
1134 		g_free(temp);
1135 	}
1136 	else
1137 	{
1138 		temp = get_pov_atoms_for_stick(get_factorstick());
1139 		fprintf(fd,"%s",temp);
1140 		g_free(temp);
1141 	}
1142 	temp = get_pov_bonds( !stick_mode());
1143 	fprintf(fd,"%s",temp);
1144 	g_free(temp);
1145         if(Ddef && dipole_mode())
1146 	{
1147 		temp = get_pov_dipole();
1148 		fprintf(fd,"%s",temp);
1149 		g_free(temp);
1150 	}
1151 
1152 	temp = get_pov_box();
1153 	fprintf(fd,"%s",temp);
1154 	g_free(temp);
1155 
1156 	temp = get_pov_end_molecule();
1157 	fprintf(fd,"%s",temp);
1158 	g_free(temp);
1159 
1160  	fclose(fd);
1161  }
1162  else
1163  {
1164 	 message = g_strdup_printf(_("\nSorry, I cannot create the %s file\n"),fileName);
1165  }
1166 	return message;
1167 }
1168 /********************************************************************************/
create_images_window(GtkWidget * parent,gchar * fileName,gint width,gint height)1169 static void create_images_window (GtkWidget* parent, gchar* fileName, gint width, gint height)
1170 {
1171 	GtkWidget *window;
1172 	GtkWidget *scrolled_window;
1173 	GtkWidget *table;
1174 	GtkWidget *vbox;
1175 
1176 	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1177 	vbox = create_vbox(window);
1178 	g_signal_connect (window, "destroy", G_CALLBACK (gtk_widget_destroyed), &window);
1179 
1180 	gtk_window_set_title (GTK_WINDOW (window), fileName);
1181 	gtk_container_set_border_width (GTK_CONTAINER (window), 0);
1182 
1183 
1184 	scrolled_window = gtk_scrolled_window_new (NULL, NULL);
1185 	gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 1);
1186 	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1187 	gtk_box_pack_start (GTK_BOX (vbox), scrolled_window, TRUE, TRUE, 0);
1188 	gtk_widget_show (scrolled_window);
1189 
1190 	table = gtk_table_new (1, 1, FALSE);
1191 	gtk_table_set_row_spacings (GTK_TABLE (table), 1);
1192 	gtk_table_set_col_spacings (GTK_TABLE (table), 1);
1193 	gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), table);
1194 	gtk_container_set_focus_hadjustment (GTK_CONTAINER (table),
1195 					   gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
1196 	gtk_container_set_focus_vadjustment (GTK_CONTAINER (table),
1197 					   gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
1198 	gtk_widget_show (table);
1199 
1200 	{
1201 		GtkWidget* image = gtk_image_new_from_file (fileName);
1202 		if(image) gtk_table_attach(GTK_TABLE(table),image, 0,0+1,0,0+1,
1203 			              (GtkAttachOptions)(GTK_FILL|GTK_SHRINK) ,
1204 			              (GtkAttachOptions)(GTK_FILL|GTK_SHRINK),
1205 			              1,1);
1206 
1207 		gtk_widget_show (image);
1208 	}
1209 	gtk_window_set_default_size (GTK_WINDOW (window), width+30, height+30);
1210 	gtk_widget_realize(window);
1211 	gtk_widget_show (window);
1212 	gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
1213 	if(parent)
1214 	{
1215 		gtk_window_set_transient_for(GTK_WINDOW(window),GTK_WINDOW(parent));
1216 	}
1217 }
1218 /*****************************************************************************/
create_cmd_pov(G_CONST_RETURN gchar * command,gchar * fileNameCMD,gchar * fileNamePov,gchar * fileNameIMG)1219 static gboolean create_cmd_pov(G_CONST_RETURN gchar* command, gchar* fileNameCMD, gchar* fileNamePov, gchar* fileNameIMG)
1220 {
1221 	gchar* commandStr = g_strdup(command);
1222         FILE* fcmd = NULL;
1223   	fcmd = FOpen(fileNameCMD, "w");
1224 	if(!fcmd)
1225 	{
1226   		Message(_("\nI can not create cmd file\n "),_("Error"),TRUE);
1227 		return FALSE;
1228 	}
1229 #ifndef G_OS_WIN32
1230 	fprintf(fcmd,"#!/bin/sh\n");
1231 	fprintf(fcmd,"rm %s\n",fileNameIMG);
1232 	fprintf(fcmd,"%s +I%s +O%s\n",commandStr, fileNamePov, fileNameIMG);
1233 #else
1234 	/* fprintf(fcmd,"setlocal\n");*/
1235 	fprintf(fcmd,"set PATH=\"%s\";%cPATH%c\n",povrayDirectory,'%','%');
1236 	fprintf(fcmd,"del %s\n",fileNameIMG);
1237 	fprintf(fcmd,"%s +I%s +O%s\n",commandStr, fileNamePov, fileNameIMG);
1238 	/* fprintf(fcmd,"endlocal");*/
1239 #endif
1240 	fclose(fcmd);
1241 #ifndef G_OS_WIN32
1242 	{
1243 		gchar buffer[BSIZE];
1244   		sprintf(buffer,"chmod u+x %s",fileNameCMD);
1245 		{int ierr = system(buffer);}
1246 	}
1247 #endif
1248 	if(commandStr) g_free(commandStr);
1249 	return TRUE;
1250 }
1251 /*****************************************************************************/
exportPOVRay(GtkWidget * Win,gboolean runPovray)1252 static void exportPOVRay(GtkWidget* Win, gboolean runPovray)
1253 {
1254 	gchar* fileNamePOV = NULL;
1255 	gchar* fileNameIMG = NULL;
1256 	gchar* fileNameCMD = NULL;
1257 	GtkWidget *entryFileName = g_object_get_data(G_OBJECT (Win), "EntryFileName");
1258 	GtkWidget *buttonDirSelector =g_object_get_data(G_OBJECT (Win), "ButtonDirSelector");
1259 	GtkWidget *entryCommand = g_object_get_data(G_OBJECT (Win), "EntryCommand");
1260 	GtkWidget *parent = g_object_get_data(G_OBJECT (Win), "ParentWindow");
1261 	/* fileName */
1262 	if(entryFileName && buttonDirSelector )
1263 	{
1264 		gchar* dirName = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER(buttonDirSelector));
1265 		gchar* tmp = g_strdup(gtk_entry_get_text(GTK_ENTRY(entryFileName)));
1266 		gint l = 0;
1267 		gint i;
1268 		if(tmp) l = strlen(tmp);
1269 		for(i=l-1;i>=1;i--) if(tmp[i]=='.') tmp[i]='\0';
1270 		if(dirName[strlen(dirName)-1] != G_DIR_SEPARATOR)
1271 		{
1272 			fileNamePOV = g_strdup_printf("%s%s%s.pov",dirName, G_DIR_SEPARATOR_S,tmp);
1273 			fileNameIMG = g_strdup_printf("%s%s%s.png",dirName, G_DIR_SEPARATOR_S,tmp);
1274 #ifndef G_OS_WIN32
1275 			fileNameCMD = g_strdup_printf("%s%s%s.cmd",dirName, G_DIR_SEPARATOR_S,tmp);
1276 #else
1277 			fileNameCMD = g_strdup_printf("%s%s%s.bat",dirName, G_DIR_SEPARATOR_S,tmp);
1278 #endif
1279 		}
1280 		else
1281 		{
1282 			fileNamePOV = g_strdup_printf("%s%s.pov",dirName, tmp);
1283 			fileNameIMG = g_strdup_printf("%s%s.png",dirName, tmp);
1284 #ifndef G_OS_WIN32
1285 			fileNameCMD = g_strdup_printf("%s%s.cmd",dirName, tmp);
1286 #else
1287 			fileNameCMD = g_strdup_printf("%s%s.bat",dirName, tmp);
1288 #endif
1289 		}
1290 		g_free(tmp);
1291 		g_free(dirName);
1292 	}
1293 	if(fileNamePOV)
1294 	{
1295 		applyPovrayOptions(NULL,NULL);
1296 		gchar* message = export_to_povray(fileNamePOV);
1297 		if(message)
1298 		{
1299     			GtkWidget *m = Message(message,_("Error"),TRUE);
1300 			gtk_window_set_modal (GTK_WINDOW (m), TRUE);
1301 		}
1302 		else
1303 		{
1304 			G_CONST_RETURN gchar* command = gtk_entry_get_text(GTK_ENTRY(entryCommand));
1305 			if(create_cmd_pov(command, fileNameCMD, fileNamePOV, fileNameIMG))
1306 			{
1307 				 if(runPovray)
1308 				{
1309 					gint width = 500;
1310 					gint height = 500;
1311 					if(GeomDrawingArea->allocation.width)
1312 					{
1313 						width =  GeomDrawingArea->allocation.width;
1314 						height = GeomDrawingArea->allocation.height;
1315 					}
1316 					gtk_widget_hide(Win);
1317 					while( gtk_events_pending() ) gtk_main_iteration();
1318 					{int ierr = system(fileNameCMD);}
1319 					create_images_window (parent,fileNameIMG, width, height);
1320 				}
1321 				else
1322 				{
1323 					gchar* t = g_strdup_printf(
1324 						_(
1325 						"\n2 files was created :\n"
1326 						" -\"%s\" a povray input file\n"
1327 						" -\"%s\" a batch file for run povray\n")
1328 						,fileNamePOV,fileNameCMD);
1329 					GtkWidget* winDlg = Message(t,_("Info"),TRUE);
1330 					gtk_window_set_modal (GTK_WINDOW (winDlg), FALSE);
1331 					g_free(t);
1332 				}
1333 			}
1334 			else
1335 			{
1336 				gchar* t = g_strdup_printf(_("\nSorry, I cannot create the %s file\n"),fileNameCMD);
1337 				GtkWidget* winDlg = Message(t,_("Info"),TRUE);
1338 				gtk_window_set_modal (GTK_WINDOW (winDlg), FALSE);
1339 				g_free(t);
1340 			}
1341 		}
1342 	}
1343 	gtk_widget_destroy(Win);
1344 }
1345 /*****************************************************************************/
savePOVRay(GtkWidget * Win,gpointer data)1346 static void savePOVRay(GtkWidget* Win, gpointer data)
1347 {
1348 	gboolean runPovray = FALSE;
1349 	exportPOVRay(Win, runPovray);
1350 }
1351 /*****************************************************************************/
runPOVRay(GtkWidget * Win,gpointer data)1352 static void runPOVRay(GtkWidget* Win, gpointer data)
1353 {
1354 	gboolean runPovray = TRUE;
1355 	exportPOVRay(Win, runPovray);
1356 }
1357 /**********************************************************************/
AddPOVRayLocationDlg(GtkWidget * box,GtkWidget * Win)1358 static void AddPOVRayLocationDlg(GtkWidget *box, GtkWidget *Win)
1359 {
1360 	gint i = 0;
1361 	gint j = 0;
1362 	GtkWidget *label;
1363 	GtkWidget *buttonDirSelector;
1364 	GtkWidget *entryFileName;
1365 	GtkWidget *table;
1366 
1367 	table = gtk_table_new(2,3,FALSE);
1368 	gtk_box_pack_start (GTK_BOX (box), table, TRUE, TRUE, 0);
1369 
1370 	i++;
1371 	j = 0;
1372 	add_label_table(table,"Folder",(gushort)i,(gushort)j);
1373 /*----------------------------------------------------------------------------------*/
1374 	j = 1;
1375 	label = gtk_label_new(":");
1376 	gtk_table_attach(GTK_TABLE(table),label, j,j+1,i,i+1,
1377                   (GtkAttachOptions)(GTK_FILL|GTK_SHRINK) ,
1378                   (GtkAttachOptions)(GTK_FILL|GTK_SHRINK),
1379                   1,1);
1380 /*----------------------------------------------------------------------------------*/
1381 	j = 2;
1382 	buttonDirSelector =  gabedit_dir_button();
1383 	gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (buttonDirSelector), g_getenv("PWD"));
1384 	gtk_widget_set_size_request(GTK_WIDGET(buttonDirSelector),(gint)(ScreenHeight*0.2),-1);
1385 	gtk_table_attach(GTK_TABLE(table),buttonDirSelector,
1386 			j,j+1,i,i+1,
1387                   (GtkAttachOptions)(GTK_FILL|GTK_EXPAND),
1388                   (GtkAttachOptions)(GTK_FILL|GTK_SHRINK),
1389                   1,1);
1390 /*----------------------------------------------------------------------------------*/
1391 	i++;
1392 	j = 0;
1393 	add_label_table(table,"File name",(gushort)i,(gushort)j);
1394 /*----------------------------------------------------------------------------------*/
1395 	j = 1;
1396 	label = gtk_label_new(":");
1397 	gtk_table_attach(GTK_TABLE(table),label, j,j+1,i,i+1,
1398                   (GtkAttachOptions)(GTK_FILL|GTK_SHRINK) ,
1399                   (GtkAttachOptions)(GTK_FILL|GTK_SHRINK),
1400                   1,1);
1401 /*----------------------------------------------------------------------------------*/
1402 	j = 2;
1403 	entryFileName = gtk_entry_new();
1404 	gtk_table_attach(GTK_TABLE(table),entryFileName,
1405 			j,j+1,i,i+1,
1406                   (GtkAttachOptions)(GTK_FILL|GTK_EXPAND),
1407                   (GtkAttachOptions)(GTK_FILL|GTK_SHRINK),
1408                   1,1);
1409 	gtk_entry_set_text(GTK_ENTRY(entryFileName),"gabeditPOV");
1410 	g_object_set_data(G_OBJECT (Win), "EntryFileName",entryFileName);
1411 	g_object_set_data(G_OBJECT (Win), "ButtonDirSelector",buttonDirSelector);
1412 }
1413 /************************************************************************************************************/
AddPOVRayRunDlg(GtkWidget * box,GtkWidget * Win)1414 static void AddPOVRayRunDlg(GtkWidget *box, GtkWidget *Win)
1415 {
1416 	gint i = 0;
1417 	gint j = 0;
1418 	GtkWidget *entryCommand;
1419 	GtkWidget *table;
1420 	GtkWidget* label;
1421 	gint width = 500;
1422 	gint height = 500;
1423 	gchar* tmp = NULL;
1424 
1425 	if(GeomDrawingArea)
1426 	{
1427 		width =  GeomDrawingArea->allocation.width;
1428 		height = GeomDrawingArea->allocation.height;
1429 	}
1430 
1431 	table = gtk_table_new(2,3,FALSE);
1432 	gtk_box_pack_start (GTK_BOX (box), table, TRUE, TRUE, 0);
1433 
1434 	i = 0;
1435 	j = 0;
1436 	label = gtk_label_new ("Command for run povray : ");
1437 	gtk_table_attach(GTK_TABLE(table),label,
1438 			j,j+1,i,i+1,
1439                   (GtkAttachOptions)(GTK_FILL|GTK_SHRINK),
1440                   (GtkAttachOptions)(GTK_FILL|GTK_SHRINK),
1441                   1,1);
1442 
1443 	j++;
1444 	entryCommand = gtk_entry_new();
1445 	gtk_table_attach(GTK_TABLE(table),entryCommand,
1446 			j,j+1,i,i+1,
1447                   (GtkAttachOptions)(GTK_FILL|GTK_EXPAND),
1448                   (GtkAttachOptions)(GTK_FILL|GTK_EXPAND),
1449                   1,1);
1450 	tmp = g_strdup_printf("%s +W%d +H%d",NameCommandPovray, width,height);
1451 	gtk_entry_set_text(GTK_ENTRY(entryCommand),tmp);
1452 	g_free(tmp);
1453 	g_object_set_data(G_OBJECT (Win), "EntryCommand",entryCommand);
1454     	gtk_widget_set_size_request(GTK_WIDGET(entryCommand),400,-1);
1455 }
1456 /**********************************************************************/
exportPOVGeomDlg(GtkWidget * parentWindow)1457 void exportPOVGeomDlg(GtkWidget *parentWindow)
1458 {
1459 	GtkWidget *button;
1460 	GtkWidget *Win;
1461 	gchar* title = "POV Ray export";
1462 	GtkWidget *hseparator = NULL;
1463 
1464 	Win= gtk_dialog_new ();
1465 	gtk_window_set_position(GTK_WINDOW(Win),GTK_WIN_POS_CENTER);
1466 	gtk_window_set_transient_for(GTK_WINDOW(Win),GTK_WINDOW(parentWindow));
1467 	gtk_window_set_title(&GTK_DIALOG(Win)->window,title);
1468     	gtk_window_set_modal (GTK_WINDOW (Win), TRUE);
1469 
1470 	g_signal_connect(G_OBJECT(Win),"delete_event",(GCallback)gtk_widget_destroy,NULL);
1471 
1472 	createPOVBackgroundFrame(GTK_WIDGET (GTK_DIALOG(Win)->vbox));
1473 	AddPOVRayLocationDlg(GTK_WIDGET (GTK_DIALOG(Win)->vbox), Win);
1474 
1475 	hseparator = gtk_hseparator_new ();
1476 	gtk_box_pack_start (GTK_BOX( GTK_DIALOG(Win)->vbox), hseparator, TRUE, TRUE, 0);
1477 	AddPOVRayRunDlg(GTK_WIDGET (GTK_DIALOG(Win)->vbox), Win);
1478 
1479 
1480 	gtk_widget_realize(Win);
1481 
1482 	button = create_button(Win,"Cancel");
1483 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
1484 	gtk_box_pack_start (GTK_BOX( GTK_DIALOG(Win)->action_area), button, TRUE, TRUE, 0);
1485 	g_signal_connect_swapped(GTK_OBJECT(button), "clicked", G_CALLBACK(gtk_widget_destroy),GTK_OBJECT(Win));
1486 	gtk_widget_show (button);
1487 
1488 	button = create_button(Win,"Save");
1489 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
1490 	gtk_box_pack_start (GTK_BOX( GTK_DIALOG(Win)->action_area), button, TRUE, TRUE, 0);
1491 	g_signal_connect_swapped(GTK_OBJECT(button), "clicked", (GCallback)savePOVRay,GTK_OBJECT(Win));
1492 	gtk_widget_show (button);
1493 
1494 	button = create_button(Win,"Run PovRay");
1495 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
1496 	gtk_box_pack_start (GTK_BOX( GTK_DIALOG(Win)->action_area), button, TRUE, TRUE, 0);
1497 	g_signal_connect_swapped(GTK_OBJECT(button), "clicked", (GCallback)runPOVRay,GTK_OBJECT(Win));
1498 	gtk_widget_show (button);
1499 
1500 	gtk_widget_show_all(Win);
1501 	g_object_set_data(G_OBJECT (Win), "ParentWindow",parentWindow);
1502 }
1503