1 /* DrawGeomGL.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 #ifdef DRAWGEOMGL
22 #include "../../Config.h"
23 #include <gdk/gdkkeysyms.h>
24 #include <gtk/gtkgl.h>
25 #include <stdlib.h>
26 #include <math.h>
27 #include <ctype.h>
28 #include "../../gl2ps/gl2ps.h"
29 #include <GL/gl.h>
30 #include <GL/glu.h>
31 #include <cairo-pdf.h>
32 #include <cairo-ps.h>
33 #include <cairo-svg.h>
34 
35 #include "../Common/Global.h"
36 #include "../Utils/Constants.h"
37 #include "../Utils/UtilsInterface.h"
38 #include "../Geometry/InterfaceGeom.h"
39 #include "../Utils/Utils.h"
40 #include "../Utils/UtilsGL.h"
41 #include "../Utils/PovrayUtils.h"
42 #include "../Utils/AtomsProp.h"
43 #include "../Geometry/GeomGlobal.h"
44 #include "../Geometry/Measure.h"
45 #include "../Geometry/Povray.h"
46 #include "../Common/Windows.h"
47 #include "../Utils/Transformation.h"
48 #include "../Geometry/GeomXYZ.h"
49 #include "../Geometry/GeomZmatrix.h"
50 #include "../Geometry/GeomSymmetry.h"
51 #include "../Files/FileChooser.h"
52 #include "../Geometry/ImagesGeom.h"
53 #include "../Geometry/Fragments.h"
54 #include "../Geometry/FragmentsPPD.h"
55 #include "../Geometry/FragmentsCrystal.h"
56 #include "../Geometry/DrawGeom.h"
57 #include "../Geometry/AxesGeomGL.h"
58 #include "../Geometry/RotFragments.h"
59 #include "../Geometry/GeomConversion.h"
60 #include "../Geometry/PersonalFragments.h"
61 #include "../Geometry/ResultsAnalise.h"
62 #include "../Utils/HydrogenBond.h"
63 #include "../MolecularMechanics/PDBTemplate.h"
64 #include "../MolecularMechanics/CalculTypesAmber.h"
65 #include "../Symmetry/MoleculeSymmetryInterface.h"
66 #include "../Symmetry/MoleculeSymmetry.h"
67 #include "../Utils/Jacobi.h"
68 #include "../Utils/Vector3d.h"
69 #include "../Utils/GabeditTextEdit.h"
70 #include "../Utils/UtilsCairo.h"
71 #include "../Geometry/MenuToolBarGeom.h"
72 #include "../Geometry/PreviewGeom.h"
73 #include "../Geometry/FragmentsSelector.h"
74 #include "../Geometry/SelectionDlg.h"
75 #include "../IsotopeDistribution/IsotopeDistributionCalculatorDlg.h"
76 #include "../Geometry/TreeMolecule.h"
77 #include "../Geometry/BuildCrystal.h"
78 
79 
80 /********************************************************************************/
81 #define MAT 30
82 #define SCALE(i) (i / 65535.)
83 /********************************************************************************/
84 static gdouble scaleAnneau = 1.3;
85 static gboolean ortho = FALSE;
86 
87 static gint xSelection = -1;
88 static gint ySelection = -1;
89 static GLint viewport[4];
90 static GLdouble mvmatrix[16];
91 static GLdouble projmatrix[16];
92 static gboolean lightOnOff[3] = { TRUE,FALSE,FALSE};
93 static V4d light0_position = {0.0, 0.0,50.0,0.0};
94 static V4d light1_position = {0.0, 50.0,50.0,0.0};
95 static V4d light2_position = {50.0, 0.0,50.0,0.0};
96 static gdouble zNear = 1.0;
97 static gdouble zFar = 100.0;
98 static GLdouble Zoom = 45;
99 static gdouble Trans[3] = { 0,0,-50.0};
100 static gdouble Quat[4] = {0.0,0.0,0.0,1.0};
101 static gdouble QuatFrag[4] = {0.0,0.0,0.0,1.0};
102 static gdouble QuatAtom[4] = {0.0,0.0,0.0,1.0};
103 static gdouble Orig[3] = {0.0,0.0,0.0};
104 static gdouble BeginX = 0;
105 static gdouble BeginY = 0;
106 
107 static gdouble CSselectedAtom[3] = {0.0,0.0,0.0};
108 static gint NumSelectedAtom = -1;
109 static gint NumProcheAtom = -1;
110 static gint NumPointedAtom = -1;
111 static gboolean ButtonPressed = FALSE;
112 static gboolean ShiftKeyPressed = FALSE;
113 static gboolean ControlKeyPressed = FALSE;
114 static gboolean FKeyPressed = FALSE;
115 static gboolean GKeyPressed = FALSE;
116 
117 gchar* strToDraw = NULL;
118 
119 static gdouble minDistanceH = 1.50; /* in Agnstrom */
120 static gdouble maxDistanceH = 3.15; /* in Agnstrom */
121 static gdouble minAngleH = 145.0;
122 static gdouble maxAngleH = 215.0;
123 
124 static gboolean showMultipleBonds = TRUE;
125 static gboolean CartoonMode = TRUE;
126 static gboolean ShowHydrogenAtoms = TRUE;
127 static gboolean AdjustHydrogenAtoms = TRUE;
128 static gboolean RebuildConnectionsDuringEdition = FALSE;
129 
130 static gint NumBatoms[2] = {-1,-1};
131 static gint NBatoms = 0;
132 
133 static gint atomToDelete = -1;
134 static gint atomToBondTo = -1;
135 static gint angleTo = -1;
136 static gdouble fragAngle = 180.0;
137 
138 static gdouble factorstick = 1.0;
139 static gdouble factorball = 1.0;
140 static gdouble factordipole = 1.0;
141 
142 static gboolean buttonpress = FALSE;
143 static int optcol = 0;
144 static GLuint GeomList = 0;
145 static GLuint SelectionList = 0;
146 static GLuint DipoleList = 0;
147 
148 static gboolean showBox = TRUE;
149 static GLuint AxesList = 0;
150 
151 static GabEditTypeGeom TypeGeom = GABEDIT_TYPEGEOM_STICK;
152 
153 static PangoContext *ft2_context = NULL;
154 
155 /********************************************************************************/
156 void set_statubar_pop_sel_atom();
157 GtkWidget *AddNoteBookPage(GtkWidget *NoteBook,char *label);
158 void drawGeom();
159 void destroy_all_drawing(GtkWidget *win);
160 void ActivateButtonOperation (GtkWidget *widget, guint data);
161 void delete_selected_atoms();
162 void delete_selected_bond();
163 void change_selected_bond();
164 void add_bond();
165 gint unselected_atom(GdkEventButton *bevent);
166 static gint insert_atom(GdkEventButton *event);
167 static gint insert_fragment(GtkWidget *widget,GdkEvent *event);
168 void set_optimal_geom_view();
169 gboolean if_selected(gint Num);
170 gint index_selected(gint Num);
171 void define_geometry();
172 void buildRotation();
173 void deleteHydrogensConnectedTo(gint n, gint nH);
174 void delete_one_atom(gint NumDel);
175 static gint replace_atom();
176 static void draw_rectangle_selection();
177 /********************************************************************************/
178 static	GdkColor* BackColor=NULL;
179 static cairo_t *cr = NULL;
180 static 	GtkWidget *NoteBookDraw;
181 static	GtkWidget *vboxmeasure;
182 static gdouble TCOS[91],TSIN[91];
183 static GtkWidget *vboxhandle;
184 static GtkWidget *StatusRotation = NULL;
185 static GtkWidget *StatusPopup = NULL;
186 static GtkWidget *StatusOperation = NULL;
187 static guint idStatusRotation = 0;
188 static guint idStatusPopup = 0;
189 static guint idStatusOperation = 0;
190 static GabEditGeomOperation OperationType = ROTATION;
191 static GabEditSelectType SelectType = RECTANGLE;
192 guint LabelOption = LABELNO;
193 
194 static Fragment Frag = {0,NULL};
195 static cairo_t *crExport = NULL;
196 static GList* fifoGeometries = NULL;
197 static GList* currentFifoGeometries = NULL;
198 static gboolean oldNext = FALSE;
199 
200 /**********************************************************************************/
201 static void stop_calcul(GtkWidget *wi, gpointer data);
202 void delete_all_selected_atoms();
203 static void reset_connections_between_selected_atoms();
204 static void reset_connections_between_selected_and_notselected_atoms();
205 
206 static GtkWidget*  NewGeomDrawingArea(GtkWidget* vboxwin, GtkWidget* GeomDlg);
207 static void SetLight();
208 static void gl_build_box();
209 static void gl_build_geometry();
210 static void gl_build_selection();
211 static void gl_build_labels();
212 static void gl_build_dipole();
213 static gint redraw(GtkWidget *widget);
214 /*********************************************************************************************/
getQuatGeom(gdouble q[])215 void getQuatGeom(gdouble q[])
216 {
217 	gint i;
218 	for(i=0;i<4;i++) q[i] = Quat[i];
219 }
220 /********************************************************************************/
destroy_setlight_window(GtkWidget * Win,gpointer data)221 static void destroy_setlight_window(GtkWidget* Win,gpointer data)
222 {
223   GtkWidget**entrys =(GtkWidget**) g_object_get_data(G_OBJECT (Win), "Entrys");
224   gtk_widget_destroy(Win);
225   if(entrys) g_free(entrys);
226 }
227 /*********************************************************************************************/
set_light_geom_on_off(gint i)228 void set_light_geom_on_off(gint i)
229 {
230 	lightOnOff[i] = !lightOnOff[i] ;
231 }
232 /*********************************************************************************************/
get_light_position(gint num)233 static gchar**  get_light_position(gint num)
234 {
235 	gint i;
236 	gchar** t = g_malloc(3*sizeof(gchar*));
237 	switch(num)
238 	{
239 		case 0 :
240 			for(i=0;i<3;i++)
241 				 t[i] = g_strdup_printf("%lf",light0_position[i]);
242 			 break;
243 		case 1 :
244 			for(i=0;i<3;i++)
245 				 t[i] = g_strdup_printf("%lf",light1_position[i]);
246 			 break;
247 		case 2 :
248 			for(i=0;i<3;i++)
249 				 t[i] = g_strdup_printf("%lf",light2_position[i]);
250 			 break;
251 	}
252 	return t;
253 }
254 /*********************************************************************************************/
255 /*
256 static gboolean get_light(gint num,gdouble v[])
257 {
258 	gint i;
259 	v[0] = v[1] = v[2] = 0;
260 	if(num<0 || num>2) return FALSE;
261 	switch(num)
262 	{
263 		case 0 :
264 			for(i=0;i<3;i++)
265 				 v[i] = light0_position[i];
266 			 break;
267 		case 1 :
268 			for(i=0;i<3;i++)
269 				 v[i] = light1_position[i];
270 			 break;
271 		case 2 :
272 			for(i=0;i<3;i++)
273 				 v[i] = light2_position[i];
274 			 break;
275 	}
276 	return lightOnOff[num];
277 }
278 */
279 /*********************************************************************************************/
set_light_position(gint num,gdouble v[])280 static void set_light_position(gint num,gdouble v[])
281 {
282 	gint i;
283 	switch(num)
284 	{
285 		case 0 :
286 			for(i=0;i<3;i++)
287 				 light0_position[i] = v[i];
288 			 break;
289 		case 1 :
290 			for(i=0;i<3;i++)
291 				 light1_position[i] = v[i];
292 			 break;
293 		case 2 :
294 			for(i=0;i<3;i++)
295 				 light2_position[i] = v[i];
296 			 break;
297 	}
298 }
299 /********************************************************************************/
apply_ligth_positions(GtkWidget * Win,gpointer data)300 static void apply_ligth_positions(GtkWidget *Win,gpointer data)
301 {
302 	GtkWidget** Entrys =(GtkWidget**)g_object_get_data(G_OBJECT (Win), "Entrys");
303 	G_CONST_RETURN gchar* temp;
304 	gint i;
305 	gint j;
306 	gdouble v[3];
307 
308 	for(i=0;i<3;i++)
309 	{
310 		for(j=0;j<3;j++)
311 		{
312         		temp	= gtk_entry_get_text(GTK_ENTRY(Entrys[j*3+i]));
313 			v[j] = atof(temp);
314 		}
315 		set_light_position(i,v);
316 
317 	}
318 
319 	destroy_setlight_window(Win,data);
320   	rafresh_drawing();
321 }
322 /********************************************************************************/
create_light_positions_frame(GtkWidget * vboxall,gchar * title)323 static GtkWidget *create_light_positions_frame( GtkWidget *vboxall,gchar* title)
324 {
325 	GtkWidget *frame;
326 	GtkWidget *vboxframe;
327 	GtkWidget **Entrys = g_malloc(9*sizeof(GtkWidget*));
328 	gushort i;
329 	gushort j;
330 	GtkWidget *Table;
331 	gchar** temp[3];
332 #define NLIGNES   3
333 #define NCOLUMNS  3
334 	gchar      *strcolumns[NCOLUMNS] = {" X "," Y "," Z "};
335 	gchar      *strlignes[NLIGNES] = {" Light 1 : "," Light 2 : "," Light 3 : "};
336 
337 	for(i=0;i<3;i++)
338 		temp[i] = get_light_position(i);
339 
340 	frame = gtk_frame_new (title);
341 	gtk_container_set_border_width (GTK_CONTAINER (frame), 5);
342 	gtk_container_add (GTK_CONTAINER (vboxall), frame);
343 	gtk_widget_show (frame);
344 
345 	vboxframe = create_vbox(frame);
346 	Table = gtk_table_new(4,4,FALSE);
347 	gtk_container_add(GTK_CONTAINER(vboxframe),Table);
348 
349 	for(j=1;j<NLIGNES+1;j++)
350 		add_label_at_table(Table,strlignes[j-1],(gushort)j,0,GTK_JUSTIFY_LEFT);
351 
352 	for(i=1;i<NCOLUMNS+1;i++)
353 	{
354 		add_label_at_table(Table,strcolumns[i-1],0,(gushort)i,GTK_JUSTIFY_CENTER);
355 		for(j=1;j<NLIGNES+1;j++)
356 		{
357 			Entrys[(i-1)*NCOLUMNS+j-1] = gtk_entry_new ();
358 			add_widget_table(Table,Entrys[(i-1)*NCOLUMNS+j-1],(gushort)j,(gushort)i);
359 			gtk_entry_set_text(GTK_ENTRY( Entrys[(i-1)*NCOLUMNS+j-1]),temp[j-1][i-1]);
360 		}
361 	}
362 
363 	for(i=0;i<3;i++)
364 	{
365 		for(j=0;j<3;j++)
366 			g_free(temp[i][j]);
367 		g_free(temp[i]);
368 	}
369 	gtk_widget_show_all(frame);
370 	g_object_set_data(G_OBJECT (frame), "Entrys",Entrys);
371 
372 	i = 0;
373 	g_object_set_data(G_OBJECT (Entrys[i]), "Entrys",Entrys);
374 	i = 2;
375 	g_object_set_data(G_OBJECT (Entrys[i]), "Entrys",Entrys);
376 	i = 3;
377 	g_object_set_data(G_OBJECT (Entrys[i]), "Entrys",Entrys);
378 	i = 6;
379 	g_object_set_data(G_OBJECT (Entrys[i]), "Entrys",Entrys);
380 
381   	return frame;
382 }
383 /********************************************************************************/
copyCoordinates2to1(GeomDef * geom1,GeomDef * geom2)384 static void copyCoordinates2to1(GeomDef *geom1, GeomDef *geom2)
385 {
386 	gint i;
387 	if(!geom1) return;
388 	if(!geom2) return;
389 	for (i=0;i<Natoms;i++)
390 	{
391 		geom1[i].X = geom2[i].X;
392 		geom1[i].Y = geom2[i].Y;
393 		geom1[i].Z = geom2[i].Z;
394 	}
395 }
396 /********************************************************************************/
get_min_max_coord(gdouble * xmin,gdouble * xmax)397 static void get_min_max_coord(gdouble* xmin, gdouble* xmax)
398 {
399 	gint i,j;
400 	gdouble min = 0;
401 	gdouble max = 0;
402 	gdouble C[3];
403 	if(!geometry || Natoms<1 )
404 	{
405 		*xmin = min;
406 		*xmax = max;
407 		return;
408 	}
409 
410 	min = geometry[0].X;
411 	max = geometry[0].Y;
412 	for(i=0;i<Natoms;i++)
413 	{
414 		C[0] = geometry[i].X;
415 		C[1] = geometry[i].Y;
416 		C[2] = geometry[i].Z;
417 		for(j=0;j<3;j++)
418 		{
419 			if(min>C[j]) min = C[j];
420 			if(max<C[j]) max = C[j];
421 		}
422 	}
423 	*xmin = min;
424 	*xmax = max;
425 }
426 /*********************************************************************************************/
get_camera_values(gdouble * zn,gdouble * zf,gdouble * angle,gdouble * aspect,gboolean * persp)427 static void  get_camera_values(gdouble* zn, gdouble* zf, gdouble* angle, gdouble* aspect, gboolean* persp)
428 {
429 	gdouble width = 500;
430 	gdouble height = 500;
431 
432 	if(GeomDrawingArea)
433 	{
434 		width =  GeomDrawingArea->allocation.width;
435 		height = GeomDrawingArea->allocation.height;
436 
437 	}
438 	*aspect = width/height;
439 	*zn = zNear;
440 	*zf = zFar;
441 	*angle = Zoom;
442 	*persp = PersMode;
443 }
444 /*********************************************************************************************/
set_camera_values(gdouble zn,gdouble zf,gdouble zo,gboolean persp)445 static void set_camera_values(gdouble zn, gdouble zf, gdouble zo, gboolean persp)
446 {
447 	zNear = zn;
448 	zFar = zf;
449 	Zoom = zo;
450 	PersMode = persp;
451 	Trans[2] = -zf/2;
452 	redraw(GeomDrawingArea);
453 }
454 /********************************************************************************/
set_camera_optimal(GtkWidget * Win,gpointer data)455 static void set_camera_optimal(GtkWidget* Win,gpointer data)
456 {
457 	GtkWidget* EntryZNear = (GtkWidget*)g_object_get_data(G_OBJECT (Win), "EntryZNear");
458 	GtkWidget* EntryZFar = (GtkWidget*)g_object_get_data(G_OBJECT (Win), "EntryZFar");
459 	GtkWidget* EntryZoom = (GtkWidget*)g_object_get_data(G_OBJECT (Win), "EntryZoom");
460 	gchar* temp;
461 	gdouble min = 0;
462 	gdouble max = 0;
463 
464 
465 	get_min_max_coord(&min, &max);
466 	if(min == 0 && max == 0)
467 		return;
468 
469 	temp    = g_strdup("1");
470 	gtk_entry_set_text(GTK_ENTRY(EntryZNear),temp);
471 	temp    = g_strdup_printf("%lf",fabs(max-min)*5);
472 	gtk_entry_set_text(GTK_ENTRY(EntryZFar), temp);
473 	temp    = g_strdup("1.0");
474 	gtk_entry_set_text(GTK_ENTRY(EntryZoom),temp);
475 }
476 /********************************************************************************/
apply_camera(GtkWidget * Win,gpointer data)477 static void apply_camera(GtkWidget* Win,gpointer data)
478 {
479 	GtkWidget* EntryZNear = (GtkWidget*)g_object_get_data(G_OBJECT (Win), "EntryZNear");
480 	GtkWidget* EntryZFar = (GtkWidget*)g_object_get_data(G_OBJECT (Win), "EntryZFar");
481 	GtkWidget* EntryZoom = (GtkWidget*)g_object_get_data(G_OBJECT (Win), "EntryZoom");
482 	GtkWidget* buttonPerspective = (GtkWidget*)g_object_get_data(G_OBJECT (Win), "ButtonPerspective");
483 	G_CONST_RETURN gchar* temp;
484 
485 	gdouble zNear = 1;
486 	gdouble zFar = 100;
487 	gdouble Zoom = 45;
488 	gdouble zn;
489 	gdouble zf;
490 	gdouble zo;
491 	gdouble aspect;
492 	gboolean perspective;
493 
494 	get_camera_values(&zNear, &zFar, &Zoom, &aspect, &perspective);
495 
496 	temp    = gtk_entry_get_text(GTK_ENTRY(EntryZNear));
497 	zn = atof(temp);
498 	if(zn<=0)  zn = zNear;
499 
500 	temp    = gtk_entry_get_text(GTK_ENTRY(EntryZFar));
501 	zf = atof(temp);
502 	if(zf<=0)  zn = zFar;
503 
504 	temp    = gtk_entry_get_text(GTK_ENTRY(EntryZoom));
505 	zo = atof(temp);
506 	if(zo<=0)  zo = Zoom;
507 	else
508 		zo = 1/zo*45;
509 	if(GTK_IS_WIDGET(buttonPerspective))
510 	 perspective =GTK_TOGGLE_BUTTON (buttonPerspective)->active;
511 	set_camera_values(zn, zf, zo, perspective);
512 }
513 /********************************************************************************/
set_sensitive_camera(GtkWidget * buttonPerspective,gpointer data)514 static void set_sensitive_camera(GtkWidget* buttonPerspective, gpointer data)
515 {
516 	if(GTK_IS_WIDGET(buttonPerspective))
517 	{
518 		gboolean perspective = GTK_TOGGLE_BUTTON (buttonPerspective)->active;
519 		GtkWidget* EntryZNear = (GtkWidget*)g_object_get_data(G_OBJECT (buttonPerspective), "EntryZNear");
520 		GtkWidget* EntryZFar = g_object_get_data(G_OBJECT (buttonPerspective), "EntryZFar");
521 		GtkWidget* buttonOptimal = g_object_get_data(G_OBJECT (buttonPerspective), "ButtonOptimal");
522 		GtkWidget* labelZNear = g_object_get_data(G_OBJECT (buttonPerspective), "LabelZNear");
523 		GtkWidget* labelZFar = g_object_get_data(G_OBJECT (buttonPerspective), "LabelZFar");
524 
525 		if(GTK_IS_WIDGET(EntryZNear))gtk_widget_set_sensitive(EntryZNear,perspective);
526 		if(GTK_IS_WIDGET(EntryZFar))gtk_widget_set_sensitive(EntryZFar,perspective);
527 		if(GTK_IS_WIDGET(buttonOptimal))gtk_widget_set_sensitive(buttonOptimal,perspective);
528 		if(GTK_IS_WIDGET(labelZNear))gtk_widget_set_sensitive(labelZNear,perspective);
529 		if(GTK_IS_WIDGET(labelZFar))gtk_widget_set_sensitive(labelZFar,perspective);
530 	}
531 }
532 /********************************************************************************/
create_camera_frame(GtkWidget * Win,GtkWidget * vbox)533 static GtkWidget* create_camera_frame(GtkWidget* Win,GtkWidget *vbox)
534 {
535 	GtkWidget *frame;
536 	GtkWidget *vboxframe;
537 	GtkWidget* buttonOptimal;
538 	GtkWidget* EntryZNear;
539 	GtkWidget* EntryZFar;
540 	GtkWidget* EntryZoom;
541 	GtkWidget *table = gtk_table_new(8,3,FALSE);
542 	GtkWidget *hseparator;
543 	gushort i;
544 	gdouble zNear = 1;
545 	gdouble zFar = 100;
546 	gdouble Zoom = 45;
547 	gdouble aspect = 1;
548 	gboolean perspective = TRUE;
549   	GtkWidget* buttonPerspective;
550   	GtkWidget* buttonNoPerspective;
551 	GtkWidget* labelZFar;
552 	GtkWidget* labelZNear;
553 
554 	get_camera_values(&zNear, &zFar, &Zoom, &aspect, &perspective);
555 
556 	frame = gtk_frame_new (NULL);
557 	gtk_widget_show (frame);
558 	gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
559 	gtk_frame_set_label_align (GTK_FRAME (frame), 0.5, 0.5);
560 
561 	vboxframe = gtk_vbox_new (FALSE, 0);
562 	gtk_widget_show (vboxframe);
563 	gtk_container_add (GTK_CONTAINER (frame), vboxframe);
564 	gtk_box_pack_start (GTK_BOX (vboxframe), table, TRUE, TRUE, 0);
565 /* ------------------------------------------------------------------*/
566 	i = 4;
567 	labelZNear = add_label_table(table,_(" Distance from the viewer to the near clipping plane "),i,0);
568 	add_label_table(table," : ",i,1);
569 	EntryZNear = gtk_entry_new();
570 	add_widget_table(table,EntryZNear,i,2);
571 	gtk_editable_set_editable((GtkEditable*)EntryZNear,TRUE);
572 	gtk_entry_set_text (GTK_ENTRY (EntryZNear),g_strdup_printf("%lf",zNear));
573 /* ------------------------------------------------------------------*/
574 	i = 5;
575 	labelZFar = add_label_table(table,_(" Distance from the viewer to the far clipping plane "),i,0);
576 	add_label_table(table," : ",i,1);
577 	EntryZFar = gtk_entry_new();
578 	add_widget_table(table,EntryZFar,i,2);
579 	gtk_editable_set_editable((GtkEditable*)EntryZFar,TRUE);
580 	gtk_entry_set_text (GTK_ENTRY (EntryZFar),g_strdup_printf("%lf",zFar));
581 /* ------------------------------------------------------------------*/
582 	i = 6;
583 	add_label_table(table,_(" Zoom factor "),i,0);
584 	add_label_table(table," : ",i,1);
585 	EntryZoom = gtk_entry_new();
586 	add_widget_table(table,EntryZoom,i,2);
587 	gtk_editable_set_editable((GtkEditable*)EntryZoom,TRUE);
588 	gtk_entry_set_text (GTK_ENTRY (EntryZoom),g_strdup_printf("%lf",1/Zoom*45.0));
589 /* ------------------------------------------------------------------*/
590 	i=3;
591 	buttonOptimal = gtk_button_new_with_label(_("Get Optimal values") );
592 	add_widget_table(table,buttonOptimal,i,2);
593 	gtk_widget_show (buttonOptimal);
594 	g_object_set_data(G_OBJECT (frame), "EntryZNear",EntryZNear);
595 	g_object_set_data(G_OBJECT (frame), "EntryZFar",EntryZFar);
596 	g_object_set_data(G_OBJECT (frame), "EntryZoom",EntryZoom);
597 	g_signal_connect_swapped(G_OBJECT(buttonOptimal),"clicked",(GCallback)set_camera_optimal,GTK_OBJECT(Win));
598 
599 /* ------------------------------------------------------------------*/
600 	i = 0;
601   	buttonPerspective = gtk_radio_button_new_with_label(NULL,_("Perspective"));
602 	add_widget_table(table,buttonPerspective,i,0);
603 	g_object_set_data(G_OBJECT (buttonPerspective), "EntryZNear",EntryZNear);
604 	g_object_set_data(G_OBJECT (buttonPerspective), "EntryZFar",EntryZFar);
605 	g_object_set_data(G_OBJECT (buttonPerspective), "ButtonOptimal",buttonOptimal);
606 	g_object_set_data(G_OBJECT (buttonPerspective), "LabelZNear",labelZNear);
607 	g_object_set_data(G_OBJECT (buttonPerspective), "LabelZFar",labelZFar);
608 
609 	i = 1;
610   	buttonNoPerspective = gtk_radio_button_new_with_label( gtk_radio_button_get_group (GTK_RADIO_BUTTON (buttonPerspective)), _("No perspective"));
611 	add_widget_table(table,buttonNoPerspective,i,0);
612 	g_signal_connect(G_OBJECT(buttonPerspective),"clicked",(GCallback)set_sensitive_camera,NULL);
613 	if(perspective)
614 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (buttonPerspective), TRUE);
615 	else
616 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (buttonNoPerspective), TRUE);
617 
618 /* ------------------------------------------------------------------*/
619 	i = 2;
620 	hseparator = gtk_hseparator_new ();
621   	gtk_table_attach(GTK_TABLE(table),hseparator,0,3,i,i+1,
622                   (GtkAttachOptions)(GTK_FILL | GTK_EXPAND),
623                   (GtkAttachOptions)(GTK_FILL | GTK_EXPAND),
624                   1,1);
625 
626 
627 	g_object_set_data(G_OBJECT (frame), "ButtonPerspective",buttonPerspective);
628 	g_object_set_data(G_OBJECT (frame), "ButtonNoPerspective",buttonNoPerspective);
629 	gtk_widget_show_all(frame);
630 	return frame;
631 }
632 /********************************************************************************/
set_camera_drawgeom()633 void set_camera_drawgeom()
634 {
635 	GtkWidget *Win;
636 	GtkWidget *frame;
637 	GtkWidget *hbox;
638 	GtkWidget *vboxall;
639 	GtkWidget *vboxwin;
640 	GtkWidget *button;
641 	GtkWidget* EntryZNear;
642 	GtkWidget* EntryZFar;
643 	GtkWidget* EntryZoom;
644 	GtkWidget* buttonPerspective;
645 	GtkWidget* buttonNoPerspective;
646 
647 
648 	Win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
649 	gtk_window_set_title(GTK_WINDOW(Win),_("Camera"));
650 	gtk_window_set_position(GTK_WINDOW(Win),GTK_WIN_POS_CENTER);
651 	gtk_container_set_border_width (GTK_CONTAINER (Win), 5);
652 	gtk_window_set_transient_for(GTK_WINDOW(Win),GTK_WINDOW(GeomDlg));
653 	gtk_window_set_modal (GTK_WINDOW (Win), TRUE);
654 	add_child(GeomDlg,Win,gtk_widget_destroy,"Camera");
655 	g_signal_connect(G_OBJECT(Win),"delete_event",(GCallback)delete_child,NULL);
656 
657 	vboxall = create_vbox(Win);
658 	vboxwin = vboxall;
659 	frame = create_camera_frame(Win,vboxall);
660 	EntryZNear = (GtkWidget*) g_object_get_data(G_OBJECT (frame), "EntryZNear");
661 	EntryZFar = (GtkWidget*) g_object_get_data(G_OBJECT (frame), "EntryZFar");
662 	EntryZoom = (GtkWidget*) g_object_get_data(G_OBJECT (frame), "EntryZoom");
663 	buttonPerspective = (GtkWidget*) g_object_get_data(G_OBJECT (frame), "ButtonPerspective");
664 	buttonNoPerspective = (GtkWidget*) g_object_get_data(G_OBJECT (frame), "ButtonNoPerspective");
665 
666 	g_object_set_data(G_OBJECT (Win), "EntryZNear",EntryZNear);
667 	g_object_set_data(G_OBJECT (Win), "EntryZFar",EntryZFar);
668 	g_object_set_data(G_OBJECT (Win), "EntryZoom",EntryZoom);
669 	g_object_set_data(G_OBJECT (Win), "ButtonPerspective",buttonPerspective);
670 	g_object_set_data(G_OBJECT (Win), "ButtonNoPerspective",buttonNoPerspective);
671 
672 
673 	hbox = create_hbox_false(vboxwin);
674 	gtk_widget_realize(Win);
675 
676 	button = create_button(Win,_("Close"));
677 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
678 	gtk_box_pack_start (GTK_BOX( hbox), button, TRUE, TRUE, 3);
679 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)delete_child, GTK_OBJECT(Win));
680 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)gtk_widget_destroy, GTK_OBJECT(Win));
681 	gtk_widget_show (button);
682 
683 	button = create_button(Win,_("Apply"));
684 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
685 	gtk_box_pack_start (GTK_BOX( hbox), button, TRUE, TRUE, 3);
686 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)apply_camera, GTK_OBJECT(Win));
687 
688 	button = create_button(Win,_("OK"));
689 	gtk_box_pack_start (GTK_BOX( hbox), button, TRUE, TRUE, 3);
690 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
691 	gtk_widget_grab_default(button);
692 	gtk_widget_show (button);
693 
694 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)apply_camera, GTK_OBJECT(Win));
695 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)delete_child, GTK_OBJECT(Win));
696 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)gtk_widget_destroy,GTK_OBJECT(Win));
697 
698 	gtk_widget_show_all (Win);
699 }
700 /********************************************************************************/
set_light_positions_drawgeom(gchar * title)701 void set_light_positions_drawgeom(gchar* title)
702 {
703   GtkWidget *Win;
704   GtkWidget *frame;
705   GtkWidget *hbox;
706   GtkWidget *vboxall;
707   GtkWidget *vboxwin;
708   GtkWidget *button;
709   GtkWidget** Entrys;
710 
711   /* Principal Window */
712   Win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
713   gtk_window_set_title(GTK_WINDOW(Win),title);
714   gtk_window_set_position(GTK_WINDOW(Win),GTK_WIN_POS_CENTER);
715   gtk_container_set_border_width (GTK_CONTAINER (Win), 5);
716   gtk_window_set_transient_for(GTK_WINDOW(Win),GTK_WINDOW(GeomDlg));
717   gtk_window_set_modal (GTK_WINDOW (Win), TRUE);
718 
719   vboxall = create_vbox(Win);
720   vboxwin = vboxall;
721   frame = create_light_positions_frame(vboxall,_("Ligth positions"));
722   Entrys = (GtkWidget**) g_object_get_data(G_OBJECT (frame), "Entrys");
723   g_object_set_data(G_OBJECT (Win), "Entrys",Entrys);
724 
725 
726   /* buttons box */
727   hbox = create_hbox_false(vboxwin);
728   gtk_widget_realize(Win);
729 
730   button = create_button(Win,_("Cancel"));
731   GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
732   gtk_box_pack_start (GTK_BOX( hbox), button, TRUE, TRUE, 3);
733   g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)destroy_setlight_window, GTK_OBJECT(Win));
734   gtk_widget_show (button);
735 
736   button = create_button(Win,_("OK"));
737   gtk_box_pack_start (GTK_BOX( hbox), button, TRUE, TRUE, 3);
738   GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
739   gtk_widget_grab_default(button);
740   gtk_widget_show (button);
741   g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)apply_ligth_positions,GTK_OBJECT(Win));
742 
743 
744   /* Show all */
745   gtk_widget_show_all (Win);
746 }
747 /*********************************************************************************************/
748 /* window to real space conversion primitive */
glGetWorldCoordinates(gdouble x,gdouble y,gdouble * w)749 static void glGetWorldCoordinates(gdouble x, gdouble y, gdouble *w)
750 {
751 	gint i;
752 	GLdouble r[3];
753 	GLfloat winX, winY,winZ;
754 
755 
756 	winX = (float)x;
757 	winY = (float)viewport[3] - (float)y;
758 	glEnable(GL_DEPTH_TEST);
759 	glDepthMask(GL_TRUE);
760 	glDepthRange(0.0f,1.0f);
761 	glReadPixels( (GLint)x, (GLint)(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );
762 	if(fabs(winZ-1)<1e-10 && Natoms>1)
763 	{
764 		GLdouble View2D[3];
765 		gdouble mindist = -1;
766 		gdouble xii,yii,d1;
767 		for(i=Natoms-1;i>=0;i--)
768 		{
769 			gluProject(geometry[i].X, geometry[i].Y, geometry[i].Z,mvmatrix, projmatrix, viewport, &View2D[0], &View2D[1], &View2D[2]);
770 			xii = View2D[0]-winX;
771 			yii = View2D[1]-winY;
772 			d1 = xii*xii+yii*yii;
773 			if(mindist<0 || mindist>d1)
774 			{
775 				mindist = d1;
776 				winZ = View2D[2];
777 			}
778 		}
779 	}
780 	gluUnProject( winX, winY, winZ, mvmatrix, projmatrix, viewport, &r[0], &r[1], &r[2]);
781 	for(i=0;i<3;i++) w[i] = r[i];
782 }
783 /*********************************************************************************************************/
getW(gdouble x1,gdouble y1,gdouble w[])784 static void getW(gdouble x1, gdouble y1, gdouble w[])
785 {
786 	gint i = 0;
787 	GLdouble View2D[3];
788 	if(Natoms<1)
789 	{
790 		glGetWorldCoordinates(x1, y1, w);
791 		return;
792 	}
793 	gluProject(geometry[i].X, geometry[i].Y, geometry[i].Z,mvmatrix, projmatrix, viewport, &View2D[0], &View2D[1], &View2D[2]);
794 	gluUnProject( (float)x1, (float)viewport[3] - (float)y1, View2D[2], mvmatrix, projmatrix, viewport, &w[0], &w[1], &w[2]);
795 }
796 /*********************************************************************************************************/
Projected_Rectangle_Draw(gdouble x1,gdouble y1,gdouble width,gdouble height)797 static void Projected_Rectangle_Draw(gdouble x1, gdouble y1, gdouble width, gdouble height)
798 {
799 	gdouble w[3];
800 	glLineWidth(3);
801 	glEnable (GL_LINE_STIPPLE);
802 	/*glLineStipple (1, 0x0101);*/   /*  dotted   */
803 	/*glLineStipple (1, 0x00FF);*/   /*  dashed   */
804 	/*glLineStipple (1, 0x1C47);*/   /*  dash/dot/dash   */
805 	/* glLineStipple (2, 0xAAAA);  */
806 	glLineStipple (3, 0x5555);
807 	glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
808 	glBegin(GL_POLYGON);
809 	getW(x1, y1, w);
810 	glVertex3d(w[0],w[1],w[2]);
811 	getW(x1+width, y1, w);
812 	glVertex3d(w[0],w[1],w[2]);
813 	getW(x1+width, y1+height, w);
814 	glVertex3d(w[0],w[1],w[2]);
815 	getW(x1, y1+height, w);
816 	glVertex3d(w[0],w[1],w[2]);
817 	glEnd();
818 	glLineWidth(1.5);
819 	glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
820 	glDisable (GL_LINE_STIPPLE);
821 }
822 /*********************************************************************************************/
reset_origine_molecule_drawgeom()823 void  reset_origine_molecule_drawgeom()
824 {
825 	Orig[0] = 0.0;
826 	Orig[1] = 0.0;
827 	Orig[2] = 0.0;
828 }
829 /*********************************************************************************************/
get_origine_molecule_drawgeom(gdouble orig[])830 void  get_origine_molecule_drawgeom(gdouble orig[])
831 {
832 	orig[0] = Orig[0];
833 	orig[1] = Orig[1];
834 	orig[2] = Orig[2];
835 }
836 /*********************************************************************************************/
get_symprec_from_geomdlg()837 gdouble  get_symprec_from_geomdlg()
838 {
839 	gdouble symprec = 1e-4;
840 	gchar* tmp = NULL;
841 	if(GeomDlg) tmp = g_object_get_data(G_OBJECT(GeomDlg), "SymPrecision");
842 	if(tmp) symprec = atof(tmp);
843 	return symprec;
844 }
845 /**********************************************************************************/
getFormulaOfTheMolecule()846 static gchar* getFormulaOfTheMolecule()
847 {
848 	gint i,j;
849 	gchar* formula = NULL;
850 	gchar* dum = NULL;
851 	gint *tag = NULL;
852 	if(Natoms<1) return formula;
853 	tag = g_malloc(Natoms*sizeof(gint));
854 	if(!tag) return formula;
855         for(i=0;i<Natoms;i++) tag[i] = 1;
856 
857         for(i=0;i<Natoms-1;i++)
858 	{
859 		if(tag[i]<=0) continue;
860         	for(j=i+1;j<Natoms;j++)
861 			if(!strcmp(geometry0[i].Prop.symbol,geometry0[j].Prop.symbol))
862 			{
863 				tag[i]++;
864 				tag[j]--;
865 			}
866 	}
867 	formula = g_strdup("");
868         for(i=0;i<Natoms;i++)
869 	{
870 		if(tag[i]<=0) continue;
871 		dum = formula;
872 		formula = g_strdup_printf("%s%s%d",formula,geometry0[i].Prop.symbol,tag[i]);
873 		g_free(dum);
874 	}
875 	if(tag) g_free(tag);
876 	if(formula && strlen(formula)<1)
877 	{
878 		g_free(formula);
879 		formula = NULL;
880 		return formula;
881 
882 	}
883 	return formula;
884 }
885 /**********************************************************************************/
createIstopeDistributionCalculationFromDrawGeom()886 void createIstopeDistributionCalculationFromDrawGeom()
887 {
888 	gchar* formula = getFormulaOfTheMolecule();
889 	compute_distribution_dlg(Fenetre, formula);
890 }
891 /*********************************************************************************************/
copy_screen_geom_clipboard()892 void  copy_screen_geom_clipboard()
893 {
894 	 while( gtk_events_pending() ) gtk_main_iteration();
895 	gabedit_save_image(GeomDrawingArea, NULL, NULL);
896 }
897 /*********************************************************************************************/
get_orgin_molecule_drawgeom(gdouble orig[])898 void  get_orgin_molecule_drawgeom(gdouble orig[])
899 {
900 	orig[0] = 0;
901 	orig[1] = 0;
902 	orig[2] = 0.0;
903 
904 	gint i = 0;
905 	for(i=0;i<3;i++) orig[i] = Trans[i];
906 }
907 /*********************************************************************************************/
get_camera_values_drawgeom(gdouble * zn,gdouble * zf,gdouble * angle,gdouble * aspect,gboolean * persp)908 void  get_camera_values_drawgeom(gdouble* zn, gdouble* zf, gdouble* angle, gdouble* aspect, gboolean* persp)
909 {
910 	get_camera_values(zn, zf, angle, aspect, persp);
911 }
912 /**********************************************************************************/
free_geometries_from_current_to_end()913 static void free_geometries_from_current_to_end()
914 {
915 	if( !fifoGeometries) return;
916 	if( !currentFifoGeometries) return;
917 	if( g_list_last(fifoGeometries) == currentFifoGeometries) return;
918 	if( fifoGeometries && currentFifoGeometries)
919 	{
920 		GList* list;
921 		if(currentFifoGeometries)
922 		for(list=currentFifoGeometries;list!=NULL;list=list->next)
923 		{
924 			GeomDraw* geom = NULL;
925 			geom = (GeomDraw*)list->data;
926 			if(geom && geom->atoms ) Free_One_Geom(geom->atoms,geom->nAtoms);
927 			list->data = NULL;
928 		}
929 		if(currentFifoGeometries->prev)
930 			currentFifoGeometries->prev->next = NULL;
931 		else fifoGeometries = NULL;
932 		g_list_free(currentFifoGeometries);
933 		currentFifoGeometries = g_list_last(fifoGeometries);
934 	}
935 }
936 /**********************************************************************************/
add_geometry_to_fifo()937 void add_geometry_to_fifo()
938 {
939 	gint i,j;
940 	GeomDraw* geom = g_malloc(sizeof(GeomDraw));
941 	geom->nAtoms = Natoms;
942 	if(Natoms>0) geom->atoms = g_malloc(Natoms*sizeof(GeomDef));
943 	else geom->atoms = NULL;
944         for(i=0;i<Natoms;i++)
945 	{
946 		geom->atoms[i].X = geometry0[i].X;
947 		geom->atoms[i].Y = geometry0[i].Y;
948 		geom->atoms[i].Z = geometry0[i].Z;
949 		geom->atoms[i].Xi = geometry0[i].Xi;
950 		geom->atoms[i].Yi = geometry0[i].Yi;
951 		geom->atoms[i].Prop = prop_atom_get(geometry0[i].Prop.symbol);
952 		geom->atoms[i].mmType = g_strdup(geometry0[i].mmType);
953 		geom->atoms[i].pdbType = g_strdup(geometry0[i].pdbType);
954 		geom->atoms[i].Residue = g_strdup(geometry0[i].Residue);
955 		geom->atoms[i].ResidueNumber = geometry0[i].ResidueNumber;
956 		geom->atoms[i].show = geometry0[i].show;
957 		geom->atoms[i].Charge = geometry0[i].Charge;
958 		geom->atoms[i].Layer = geometry0[i].Layer;
959 		geom->atoms[i].N = geometry0[i].N;
960 		geom->atoms[i].Variable = geometry0[i].Variable;
961 		geom->atoms[i].ColorAlloc = geometry0[i].ColorAlloc;
962 		geom->atoms[i].Rayon = geometry0[i].Rayon;
963 		geom->atoms[i].Coefpers = geometry0[i].Coefpers;
964 		if(geometry0[i].typeConnections)
965 		{
966 			geom->atoms[i].typeConnections = g_malloc(Natoms*sizeof(gint));
967 			for(j=0;j<Natoms;j++)
968 				geom->atoms[i].typeConnections[j] = geometry0[i].typeConnections[j];
969 		}
970 		else geom->atoms[i].typeConnections = NULL;
971 	}
972 	free_geometries_from_current_to_end();
973 	fifoGeometries = g_list_append(fifoGeometries,geom);
974 	currentFifoGeometries = g_list_last(fifoGeometries);
975 	oldNext = FALSE;
976 }
977 /**********************************************************************************/
get_geometry_from_fifo(gboolean toNext)978 void get_geometry_from_fifo(gboolean toNext)
979 {
980 	gint i,j;
981 	GeomDraw* geom = NULL;
982 	GList* list = NULL;
983 	if(!fifoGeometries) return;
984 	if(!currentFifoGeometries) return;
985 	if(toNext)
986 	{
987 		GList* last = g_list_last(fifoGeometries);
988 		if(currentFifoGeometries == last) return;
989 		list = g_list_next(currentFifoGeometries);
990 		currentFifoGeometries  = list;
991 		oldNext = TRUE;
992 
993 	}
994 	else
995 	{
996 		if( !oldNext && currentFifoGeometries == g_list_last(fifoGeometries))
997 		{
998 			add_geometry_to_fifo();
999 		}
1000 		if(g_list_previous(currentFifoGeometries))
1001 			currentFifoGeometries = g_list_previous(currentFifoGeometries);
1002 		list = currentFifoGeometries;
1003 		oldNext = FALSE;
1004 	}
1005 	geom = (GeomDraw*)list->data;
1006 	if(!geom) return;
1007 	geometry0 = Free_One_Geom(geometry0,Natoms);
1008 	geometry = Free_One_Geom(geometry,Natoms);
1009 	Natoms = geom->nAtoms;
1010 	if(Natoms>0)
1011 	{
1012 		geometry0 = g_malloc(Natoms*sizeof(GeomDef));
1013 		geometry = g_malloc(Natoms*sizeof(GeomDef));
1014 	}
1015         for(i=0;i<Natoms;i++)
1016 	{
1017 		geometry0[i].X = geom->atoms[i].X;
1018 		geometry0[i].Y = geom->atoms[i].Y;
1019 		geometry0[i].Z = geom->atoms[i].Z;
1020 		geometry0[i].Xi = geom->atoms[i].Xi;
1021 		geometry0[i].Yi = geom->atoms[i].Yi;
1022 		geometry0[i].Prop = prop_atom_get(geom->atoms[i].Prop.symbol);
1023 		geometry0[i].mmType = g_strdup(geom->atoms[i].mmType);
1024 		geometry0[i].pdbType = g_strdup(geom->atoms[i].pdbType);
1025 		geometry0[i].Residue = g_strdup(geom->atoms[i].Residue);
1026 		geometry0[i].ResidueNumber = geom->atoms[i].ResidueNumber;
1027 		geometry0[i].show = geom->atoms[i].show;
1028 		geometry0[i].Charge = geom->atoms[i].Charge;
1029 		geometry0[i].Layer = geom->atoms[i].Layer;
1030 		geometry0[i].N = geom->atoms[i].N;
1031 		geometry0[i].Variable = geom->atoms[i].Variable;
1032 		geometry0[i].ColorAlloc = geom->atoms[i].ColorAlloc;
1033 		geometry0[i].Rayon = geom->atoms[i].Rayon;
1034 		geometry0[i].Coefpers = geom->atoms[i].Coefpers;
1035 		if(geom->atoms[i].typeConnections)
1036 		{
1037 			geometry0[i].typeConnections = g_malloc(Natoms*sizeof(gint));
1038 			for(j=0;j<Natoms;j++)
1039 				geometry0[i].typeConnections[j] = geom->atoms[i].typeConnections[j];
1040 		}
1041 		else
1042 		{
1043 			geometry0[i].typeConnections = NULL;
1044 		}
1045 	}
1046         for(i=0;i<Natoms;i++)
1047 	{
1048 		geometry[i].X = geom->atoms[i].X;
1049 		geometry[i].Y = geom->atoms[i].Y;
1050 		geometry[i].Z = geom->atoms[i].Z;
1051 		geometry[i].Xi = geom->atoms[i].Xi;
1052 		geometry[i].Yi = geom->atoms[i].Yi;
1053 		geometry[i].Prop = prop_atom_get(geom->atoms[i].Prop.symbol);
1054 		geometry[i].mmType = g_strdup(geom->atoms[i].mmType);
1055 		geometry[i].pdbType = g_strdup(geom->atoms[i].pdbType);
1056 		geometry[i].Residue = g_strdup(geom->atoms[i].Residue);
1057 		geometry[i].ResidueNumber = geom->atoms[i].ResidueNumber;
1058 		geometry[i].show = geom->atoms[i].show;
1059 		geometry[i].Charge = geom->atoms[i].Charge;
1060 		geometry[i].Layer = geom->atoms[i].Layer;
1061 		geometry[i].N = geom->atoms[i].N;
1062 		geometry[i].Variable = geom->atoms[i].Variable;
1063 		geometry[i].ColorAlloc = geom->atoms[i].ColorAlloc;
1064 		geometry[i].Rayon = geom->atoms[i].Rayon;
1065 		geometry[i].Coefpers = geom->atoms[i].Coefpers;
1066 		if(geom->atoms[i].typeConnections)
1067 		{
1068 			geometry[i].typeConnections = g_malloc(Natoms*sizeof(gint));
1069 			for(j=0;j<Natoms;j++)
1070 				geometry[i].typeConnections[j] = geom->atoms[i].typeConnections[j];
1071 		}
1072 		else
1073 		{
1074 			geometry[i].typeConnections = NULL;
1075 		}
1076 	}
1077 	/* if(!fifoGeometries) printf("fifoGeometries is void\n");*/
1078 	change_of_center(NULL,NULL);
1079 	create_GeomXYZ_from_draw_grometry();
1080 	RebuildGeom=TRUE;
1081 }
1082 /**********************************************************************************/
get_indice(gint n)1083 static gint get_indice(gint n)
1084 {
1085 	gint i;
1086 	if(n<0) return n;
1087 	for(i=0;i<(gint)Natoms;i++)
1088 		if(geometry[i].N==n)return i;
1089 	return -1;
1090 }
1091 /*****************************************************************************/
get_epaisseur(gint i,gint j)1092 static gdouble get_epaisseur(gint i, gint j)
1093 {
1094 	/* gdouble factorstick = get_factorstick();*/
1095         gdouble ei = 1.0/3.0*factorstick;
1096         gdouble ej = 1.0/3.0*factorstick;
1097         gdouble e = 1.0/3.0*factorstick;
1098 	gdouble sl = 4.5;
1099 	gdouble sm = 2;
1100 	if(geometry[i].Layer == LOW_LAYER) ei /= sl;
1101 	if(geometry[i].Layer == MEDIUM_LAYER) ei /= sm;
1102 	if(geometry[j].Layer == LOW_LAYER) ej /= sl;
1103 	if(geometry[j].Layer == MEDIUM_LAYER) ej /= sm;
1104 	e = (ei<ej)?ei:ej;
1105 	return e;
1106 }
1107 /*****************************************************************************/
get_rayon(gint i)1108 static gdouble get_rayon(gint i)
1109 {
1110         gdouble rayon;
1111 	/* gdouble factorball = get_factorball();*/
1112 	gdouble sl = 4.5;
1113 	gdouble sm = 2;
1114         if ( TypeGeom!= GABEDIT_TYPEGEOM_STICK && geometry[i].Layer != LOW_LAYER )
1115         {
1116 		if(space_fill_mode()) rayon =(geometry[i].Prop.vanDerWaalsRadii*factorball);
1117 		else rayon =(geometry[i].Prop.radii*factorball);
1118 		if(geometry[i].Layer == LOW_LAYER) rayon /= sl;
1119 		if(geometry[i].Layer == MEDIUM_LAYER) rayon /= sm;
1120 	}
1121 	else rayon = get_epaisseur(i,i);
1122 	if(rayon<0.01) rayon = 0.01;
1123 	return rayon;
1124 }
1125 /*****************************************************************************/
get_rayon_selection(gint i)1126 static gdouble get_rayon_selection(gint i)
1127 {
1128 	return scaleAnneau*1.2*get_rayon(i);
1129 }
1130 /**********************************************************************************/
create_drawmolecule_file()1131 void create_drawmolecule_file()
1132 {
1133 	gchar *drawMolecule;
1134 	FILE *fd;
1135 
1136 	drawMolecule = g_strdup_printf("%s%sdrawmolecule",gabedit_directory(),G_DIR_SEPARATOR_S);
1137 
1138 	fd = FOpen(drawMolecule, "w");
1139 	if(fd !=NULL)
1140 	{
1141 		if(BackColor) fprintf(fd,"%d %d %d\n",BackColor->red, BackColor->green, BackColor->blue);
1142 		else fprintf(fd,"0 0 0\n");
1143 		fprintf(fd,"%d\n",AdjustHydrogenAtoms);
1144 		fprintf(fd,"%d\n",RebuildConnectionsDuringEdition);
1145 		fprintf(fd,"%f\n",fragAngle);
1146 		fprintf(fd,"%f\n",factorstick);
1147 		fprintf(fd,"%f\n",factorball);
1148 		fclose(fd);
1149 	}
1150 	g_free(drawMolecule);
1151 }
1152 /*************************************************************************************/
read_drawmolecule_file()1153 void read_drawmolecule_file()
1154 {
1155 	gchar *drawMolecule;
1156 	FILE *fd;
1157 	gint r = 0;
1158 	gint g = 0;
1159 	gint b = 0;
1160 	gint sh = 1;
1161 	gint rc = 0;
1162 
1163 	drawMolecule = g_strdup_printf("%s%sdrawmolecule",gabedit_directory(),G_DIR_SEPARATOR_S);
1164 	fragAngle = 180;
1165 	factor_stick_default(NULL,NULL);
1166 	factor_ball_default(NULL,NULL);
1167 
1168 	fd = fopen(drawMolecule, "rb");
1169 	if(fd !=NULL)
1170 	{
1171  		guint taille = BSIZE;
1172  		gchar t[BSIZE];
1173  		if(fgets(t,taille,fd))
1174 			if(sscanf(t,"%d %d %d",&r, &g, &b)!=3)
1175 			{
1176 				printf("t=%s\n",t);
1177 				r = 0;
1178 				g = 0;
1179 				b = 0;
1180 			}
1181  		if(fgets(t,taille,fd))
1182 			if(sscanf(t,"%d",&sh)!=1) sh = 1;
1183  		if(fgets(t,taille,fd))
1184 			if(sscanf(t,"%d",&rc)!=1) rc = 0;
1185  		if(fgets(t,taille,fd))
1186 			if(sscanf(t,"%lf",&fragAngle)!=1) fragAngle = 180;
1187  		if(fgets(t,taille,fd))
1188 			if(sscanf(t,"%lf",&factorstick)!=1) factor_stick_default(NULL,NULL);
1189  		if(fgets(t,taille,fd))
1190 			if(sscanf(t,"%lf",&factorball)!=1) factor_ball_default(NULL,NULL);
1191 
1192 		fclose(fd);
1193 	}
1194 	g_free(drawMolecule);
1195 	if(r==0 && g == 0 && b == 0) r = g = b = 20000;
1196 	{
1197 		BackColor = g_malloc(sizeof(GdkColor));
1198 		BackColor->red = r;
1199 		BackColor->green = g;
1200 		BackColor->blue = b;
1201 
1202 	}
1203 	AdjustHydrogenAtoms = (gboolean)sh;
1204 	RebuildConnectionsDuringEdition = (gboolean)rc;
1205 }
1206 /*************************************************************************************/
copyGeometry(GeomDef * geom0)1207 GeomDef* copyGeometry(GeomDef* geom0)
1208 {
1209 	gint i;
1210 	GeomDef* geom = NULL;
1211 	if(Natoms<1) return geom;
1212 	geom =g_malloc(Natoms*sizeof(GeomDef));
1213 	for(i=0;i<Natoms;i++)
1214 	{
1215 		geom[i].X = geom0[i].X;
1216 		geom[i].Y = geom0[i].Y;
1217 		geom[i].Z = geom0[i].Z;
1218 		geom[i].N = geom0[i].N;
1219         	geom[i].typeConnections = NULL;
1220 		geom[i].Prop = prop_atom_get(geom0[i].Prop.symbol);
1221 		geom[i].mmType = g_strdup(geom0[i].mmType);
1222 		geom[i].pdbType = g_strdup(geom0[i].pdbType);
1223 		geom[i].Layer = geom0[i].Layer;
1224 		geom[i].Variable = geom0[i].Variable;
1225 		geom[i].Residue = g_strdup(geom0[i].Residue);
1226 		geom[i].ResidueNumber = geom0[i].ResidueNumber;
1227 		geom[i].show = geom0[i].show;
1228 		geom[i].Charge = geom0[i].Charge;
1229 	}
1230 	return geom;
1231 }
1232 /*****************************************************************************/
freeGeometry(GeomDef * geom)1233 void freeGeometry(GeomDef* geom)
1234 {
1235 	gint i;
1236 	if(!geom) return;
1237 	if(Natoms<1) return;
1238 	for(i=0;i<Natoms;i++)
1239 	{
1240 		if(geom[i].Prop.name) g_free(geom[i].Prop.name);
1241 		if(geom[i].Prop.symbol) g_free(geom[i].Prop.symbol);
1242 		if(geom[i].mmType) g_free(geom[i].mmType);
1243 		if(geom[i].pdbType) g_free(geom[i].pdbType);
1244 		if(geom[i].Residue) g_free(geom[i].Residue);
1245 		if(geom[i].typeConnections) g_free(geom[i].typeConnections);
1246 	}
1247 	g_free(geom);
1248 }
1249 /*****************************************************************************/
get_factorstick()1250 gdouble get_factorstick()
1251 {
1252 	return factorstick;
1253 }
1254 /*****************************************************************************/
get_factorball()1255 gdouble get_factorball()
1256 {
1257 	return factorball;
1258 }
1259 /*****************************************************************************/
get_factordipole()1260 gdouble get_factordipole()
1261 {
1262 	return factordipole;
1263 }
1264 /*****************************************************************************/
get_factor()1265 gdouble get_factor()
1266 {
1267 	return Zoom/45.0;
1268 }
1269 /*****************************************************************************/
get_connection_type(gint i,gint j)1270 gint get_connection_type(gint i, gint j)
1271 {
1272 	gint nj = 0;
1273 	if(i<0 || j<0 || i>=Natoms || j>=Natoms ) return 0;
1274 	if(!geometry[i].typeConnections)return 0;
1275 	nj = geometry[j].N-1;
1276 	if(geometry[i].typeConnections[nj]>0) return geometry[i].typeConnections[nj];
1277 	return 0;
1278 }
1279 /*****************************************************************************/
set_fix_variable_of_selected_atoms(gboolean variable)1280 static void set_fix_variable_of_selected_atoms(gboolean variable)
1281 {
1282 	gint i;
1283 	for (i=0;i<(gint)Natoms;i++)
1284 	{
1285 		if(if_selected(i))
1286 		{
1287 			geometry[i].Variable = variable;
1288 			geometry0[i].Variable = variable;
1289 		}
1290 	}
1291 	create_GeomXYZ_from_draw_grometry();
1292 	drawGeom();
1293 }
1294 /*****************************************************************************/
set_fix_selected_atoms()1295 void set_fix_selected_atoms()
1296 {
1297 	gint i;
1298 	gint nf=0;
1299 	for (i=0;i<(gint)Natoms;i++)
1300 			if(geometry[i].Variable) nf++;
1301 	if(nf==0)
1302 	{
1303 		for (i=0;i<(gint)Natoms;i++)
1304 		{
1305 			geometry[i].Variable = TRUE;
1306 			geometry0[i].Variable = TRUE;
1307 		}
1308 	}
1309 	set_fix_variable_of_selected_atoms(FALSE);
1310 }
1311 /*****************************************************************************/
set_variable_selected_atoms()1312 void set_variable_selected_atoms()
1313 {
1314 	set_fix_variable_of_selected_atoms(TRUE);
1315 }
1316 /*****************************************************************************/
hide_selected_atoms()1317 void hide_selected_atoms()
1318 {
1319 	gint i;
1320 	for (i=0;i<(gint)Natoms;i++)
1321 	{
1322 		if(if_selected(i))
1323 		{
1324 			geometry[i].show = FALSE;
1325 			geometry0[i].show = FALSE;
1326 		}
1327 	}
1328 	unselect_all_atoms();
1329 	RebuildGeom=TRUE;
1330 	drawGeom();
1331 }
1332 /*****************************************************************************/
hide_not_selected_atoms()1333 void hide_not_selected_atoms()
1334 {
1335 	gint i;
1336 	for (i=0;i<(gint)Natoms;i++)
1337 	{
1338 		if(!if_selected(i))
1339 		{
1340 			geometry[i].show = FALSE;
1341 			geometry0[i].show = FALSE;
1342 		}
1343 	}
1344 	RebuildGeom=TRUE;
1345 	drawGeom();
1346 }
1347 /*****************************************************************************/
show_hydrogen_atoms()1348 void show_hydrogen_atoms()
1349 {
1350 	gint i;
1351 	gint j;
1352 	gint ni;
1353 	gint nj;
1354 	for (i=0;i<(gint)Natoms;i++)
1355 	{
1356 		ni = geometry[i].N-1;
1357 		if(!geometry[i].show) continue;
1358 		for (j=0;j<(gint)Natoms;j++)
1359 		{
1360 			nj = geometry[j].N-1;
1361 			if(!geometry[i].typeConnections) continue;
1362 			if(geometry[i].typeConnections[nj]<1) continue;
1363 			if(!strcmp(geometry[j].Prop.symbol,"H"))
1364 			{
1365 				geometry[j].show = TRUE;
1366 				geometry0[j].show = TRUE;
1367 			}
1368 		}
1369 
1370 	}
1371 	RebuildGeom=TRUE;
1372 	drawGeom();
1373 	ShowHydrogenAtoms = TRUE;
1374 }
1375 /*****************************************************************************/
show_all_atoms()1376 void show_all_atoms()
1377 {
1378 	gint i;
1379 	for (i=0;i<(gint)Natoms;i++)
1380 	{
1381 		geometry[i].show = TRUE;
1382 		geometry0[i].show = TRUE;
1383 	}
1384 	RebuildGeom=TRUE;
1385 	drawGeom();
1386 	ShowHydrogenAtoms = TRUE;
1387 }
1388 /********************************************************************************/
testAmberTypesDefine()1389 static gint testAmberTypesDefine()
1390 {
1391 	gint i;
1392 	gint k;
1393 	if(Natoms<1)return 0;
1394 	for(i=0;i<(gint)Natoms;i++)
1395 		if(geometry[i].mmType && strlen(geometry[i].mmType)>2)
1396 		{
1397 			printf("Problem with %s\n",geometry[i].mmType);
1398 			return -1;
1399 		}
1400 	k = 0;
1401 	for(i=0;i<(gint)Natoms;i++)
1402 		if(geometry[i].mmType && strcmp(geometry[i].mmType,geometry[i].Prop.symbol)==0) k++;
1403 	if(k==Natoms) return -2;
1404 	return 0;
1405 }
1406 /********************************************************************************/
messageAmberTypesDefine()1407 void messageAmberTypesDefine()
1408 {
1409 	gint k = testAmberTypesDefine();
1410 	if(k==0) return;
1411 	if(k==-1)
1412 	{
1413     		GtkWidget* m;
1414 		m = Message(_("The type of One (or several) of atoms is not a Amber type.\n"
1415 		        "You can set the types of atoms by : \n"
1416 		        "                  \"Set/Atom Type&Charge using PDB Template\" \n"
1417 		        "                  \"Or\" \n"
1418 		        "                  \"Set/Atom Types using connections types\" \n"
1419 			)
1420 			,_("Warning"),TRUE);
1421 		gtk_window_set_modal (GTK_WINDOW (m), TRUE);
1422 	}
1423 	if(k==-2)
1424 	{
1425     		GtkWidget* m;
1426 		m = Message(_("The types of the atoms are identical to the symbols of these atoms.\n"
1427 		        "You can set the types of atoms by \n"
1428 		        "\"Set/Atom Types using connections types\" \n"
1429 			)
1430 			,_("Warning"),TRUE);
1431 		gtk_window_set_modal (GTK_WINDOW (m), TRUE);
1432 	}
1433 }
1434 /*****************************************************************************/
getShowMultipleBonds()1435 gboolean getShowMultipleBonds()
1436 {
1437 	return showMultipleBonds;
1438 }
1439 /*****************************************************************************/
RenderMultipleBonds(GtkWidget * win,gboolean show)1440 void RenderMultipleBonds(GtkWidget *win,gboolean show)
1441 {
1442 	showMultipleBonds = show;
1443 	RebuildGeom=TRUE;
1444 	drawGeom();
1445 }
1446 /*****************************************************************************/
resetConnections()1447 void resetConnections()
1448 {
1449 	reset_all_connections();
1450 	RebuildGeom=TRUE;
1451 	drawGeom();
1452 }
1453 /*****************************************************************************/
resetConnectionsBetweenSelectedAndNotSelectedAtoms()1454 void resetConnectionsBetweenSelectedAndNotSelectedAtoms()
1455 {
1456 	reset_connections_between_selected_and_notselected_atoms();
1457 	RebuildGeom=TRUE;
1458 	drawGeom();
1459 }
1460 /*****************************************************************************/
resetConnectionsBetweenSelectedAtoms()1461 void resetConnectionsBetweenSelectedAtoms()
1462 {
1463 	reset_connections_between_selected_atoms();
1464 	RebuildGeom=TRUE;
1465 	drawGeom();
1466 }
1467 /*****************************************************************************/
resetMultipleConnections()1468 void resetMultipleConnections()
1469 {
1470 	reset_multiple_bonds();
1471 	RebuildGeom=TRUE;
1472 	drawGeom();
1473 }
1474 /*****************************************************************************/
getOperationType()1475 GabEditGeomOperation getOperationType()
1476 {
1477 	return OperationType;
1478 }
1479 /*****************************************************************************/
get_real_distance2(GeomDef * g,gint i,gint j)1480 gdouble get_real_distance2(GeomDef* g,gint i,gint j)
1481 {
1482  	gdouble xx;
1483 	gdouble d;
1484 
1485 	xx = g[i].X-g[j].X;
1486 	d = xx*xx;
1487 	xx = g[i].Y-g[j].Y;
1488 	d += xx*xx;
1489 	xx = g[i].Z-g[j].Z;
1490 	d += xx*xx;
1491 
1492 	return d;
1493 }
1494 /*******************************************************************/
adjust_multiple_bonds_with_one_atom(gint n)1495 void adjust_multiple_bonds_with_one_atom(gint n)
1496 {
1497 	if(Natoms<2) return;
1498 	if(!geometry[n].typeConnections) return;
1499 	{
1500 		gint ni = 0;
1501 		gint nj = 0;
1502 		gint i,j;
1503 		gint nBonds = 0;
1504 
1505 		i = n;
1506 		ni = geometry[i].N-1;
1507 		for(j=0;j<(gint)Natoms;j++)
1508 		{
1509 			if(j==i) continue;
1510 			nj = geometry[j].N-1;
1511 		 	if(geometry[i].typeConnections[nj]>0)
1512 		 	{
1513 				nBonds += geometry[i].typeConnections[nj];
1514 		 	}
1515 		}
1516 		if(nBonds<=geometry[i].Prop.maximumBondValence) return;
1517 		for(j=0;j<(gint)Natoms;j++)
1518 		{
1519 			nj = geometry[j].N-1;
1520 			if(i==j) continue;
1521 			if(geometry[i].typeConnections[nj]<=1) continue;
1522 			geometry[i].typeConnections[nj] -=1;
1523 			geometry[j].typeConnections[ni] -=1;
1524 			nBonds--;
1525 			if(nBonds<=geometry[i].Prop.maximumBondValence) return;
1526 		}
1527 		copy_connections(geometry0, geometry, Natoms);
1528 	}
1529 }
1530 /*******************************************************************/
reset_connection_with_one_atom(gint n)1531 void reset_connection_with_one_atom(gint n)
1532 {
1533 	if(Natoms<2) return;
1534 	if(!geometry[n].typeConnections) return;
1535 	{
1536 		gint ni = 0;
1537 		gint nj = 0;
1538 		gint i,j;
1539 		gint* nBonds = g_malloc(Natoms*sizeof(gint));
1540 
1541 		for(i=0;i<(gint)Natoms;i++) nBonds[i] = 0;
1542 		for(i=0;i<(gint)Natoms-1;i++)
1543 		{
1544 			if(i==n) continue;
1545 			for(j=i+1;j<(gint)Natoms;j++)
1546 			{
1547 				if(j==n) continue;
1548 				nj = geometry[j].N-1;
1549 			 	if(geometry[i].typeConnections[nj]>0)
1550 			 	{
1551 					nBonds[i] += geometry[i].typeConnections[nj];
1552 				 	nBonds[j] += geometry[i].typeConnections[nj];
1553 			 	}
1554 			}
1555 		}
1556 		i = n;
1557 		ni = geometry[i].N-1;
1558 		for(j=0;j<(gint)Natoms;j++)
1559 		{
1560 			if(i==j) continue;
1561 			nj = geometry[j].N-1;
1562 			if(draw_lines_yes_no(i,j)) geometry[i].typeConnections[nj]= 1;
1563 			else geometry[i].typeConnections[nj]=0;
1564 
1565 			if(geometry[j].typeConnections)
1566 				geometry[j].typeConnections[ni] = geometry[i].typeConnections[nj];
1567 
1568 			nBonds[i]+= geometry[i].typeConnections[nj];
1569 			nBonds[j]+= geometry[i].typeConnections[nj];
1570 			if(nBonds[i]>geometry[i].Prop.maximumBondValence ||
1571 			nBonds[j]>geometry[j].Prop.maximumBondValence
1572 					)
1573 			{
1574 				geometry[i].typeConnections[nj]= 0;
1575 				if(geometry[j].typeConnections)
1576 					geometry[j].typeConnections[ni] = 0;
1577 				nBonds[i]--;
1578 				nBonds[j]--;
1579 
1580 			}
1581 		}
1582 		for(j=0;j<(gint)Natoms;j++)
1583 		{
1584 			nj = geometry[j].N-1;
1585 			if(i==j) continue;
1586 			if(geometry[i].typeConnections[nj]==0) continue;
1587 			if(
1588 		 	nBonds[i] < geometry[i].Prop.maximumBondValence &&
1589 		 	nBonds[j] < geometry[j].Prop.maximumBondValence
1590 			)
1591 			{
1592 				geometry[i].typeConnections[nj] = geometry[j].typeConnections[ni] = 2;
1593 				nBonds[i] += 1;
1594 				nBonds[j] += 1;
1595 			}
1596 		}
1597 		for(j=0;j<(gint)Natoms;j++)
1598 		{
1599 			nj = geometry[j].N-1;
1600 			if(i==j) continue;
1601 			if(geometry[i].typeConnections[nj]==0) continue;
1602 			if(
1603 		 	nBonds[i] < geometry[i].Prop.maximumBondValence &&
1604 		 	nBonds[j] < geometry[j].Prop.maximumBondValence
1605 			)
1606 			{
1607 				geometry[i].typeConnections[nj] = geometry[j].typeConnections[ni] = 3;
1608 				nBonds[i] += 1;
1609 				nBonds[j] += 1;
1610 			}
1611 		}
1612 		copy_connections(geometry0, geometry, Natoms);
1613 	}
1614 }
1615 /*****************************************************************************/
init_connections()1616 static void init_connections()
1617 {
1618 	gint i;
1619 	gint j;
1620 	if(Natoms<1) return;
1621 	if(geometry)
1622 	for(i=0;i<(gint)Natoms;i++)
1623 	{
1624 		geometry[i].typeConnections = g_malloc(Natoms*sizeof(gint));
1625 		for(j=0;j<(gint)Natoms;j++) geometry[i].typeConnections[j] = 0;
1626 	}
1627 	if(geometry0)
1628 	for(i=0;i<(gint)Natoms;i++)
1629 	{
1630 		geometry0[i].typeConnections = g_malloc(Natoms*sizeof(gint));
1631 		for(j=0;j<(gint)Natoms;j++) geometry0[i].typeConnections[j] = 0;
1632 	}
1633 }
1634 /************************************************************************/
reSetSimpleConnections()1635 static void reSetSimpleConnections()
1636 {
1637 	gint* nBonds = NULL;
1638 	gint* num = NULL;
1639 	gint* numConn = NULL;
1640 	gdouble* dists = NULL;
1641 	gint i;
1642 	gint j;
1643 	gint ni;
1644 	gint nj;
1645 	gint k;
1646 	gint kmax;
1647 	gint nb0;
1648 	if(Natoms<1) return;
1649 	nBonds = g_malloc(Natoms*sizeof(gint));
1650 	num = g_malloc(Natoms*sizeof(gint));
1651 	numConn = g_malloc(Natoms*sizeof(gint));
1652 	dists = g_malloc(Natoms*sizeof(gdouble));
1653 	for(i=0;i<(gint)Natoms;i++) num[i] = i;
1654 
1655 	for(i=0;i<(gint)Natoms-1;i++)
1656 	{
1657 		gint k = i;
1658 		for(j=i+1;j<(gint)Natoms;j++)
1659 			if(geometry[num[j]].N<geometry[num[k]].N) k = j;
1660 		if(k!=i)
1661 		{
1662 			gint t = num[i];
1663 			num[i] = num[k];
1664 			num[k] = t;
1665 		}
1666 	}
1667 
1668 	for(i=0;i<(gint)Natoms;i++) nBonds[i] = 0;
1669 	for(i=0;i<(gint)Natoms;i++)
1670 	{
1671 		ni = geometry[num[i]].N-1;
1672 		for(j=i+1;j<(gint)Natoms;j++)
1673 		{
1674 			nj = geometry[num[j]].N-1;
1675 			 if(geometry[num[i]].typeConnections[nj]>0)
1676 			 {
1677 				 nBonds[i] += 1;
1678 				 nBonds[j] += 1;
1679 			 }
1680 		}
1681 	}
1682 	/* remove H1-H2 connections if H1 and H2 are not connected to others atoms */
1683 	for(i=0;i<(gint)Natoms;i++)
1684 	{
1685 		ni = geometry[num[i]].N-1;
1686 		if( nBonds[i] <= geometry[num[i]].Prop.maximumBondValence) continue;
1687 		if( geometry[num[i]].Prop.maximumBondValence>1) continue;
1688 		for(k=0;k<(gint)nBonds[i];k++) numConn[k] = -1;
1689 		k = 0;
1690 		for(j=0;j<(gint)Natoms;j++)
1691 		{
1692 			nj = geometry[num[j]].N-1;
1693 			if(i!=j && geometry[num[i]].typeConnections[nj]>0)
1694 			{
1695         			gdouble p = geometry[num[i]].Prop.covalentRadii+geometry[num[j]].Prop.covalentRadii;
1696 				p = p*p;
1697 				numConn[k] = j;
1698 				dists[k] = get_real_distance2(geometry, num[i], num[j])/p;
1699 				if( geometry[num[j]].Prop.maximumBondValence>1) numConn[k] =-1;
1700 				k++;
1701 			}
1702 		}
1703 		nb0 = nBonds[i];
1704 		do{
1705 			kmax = -1;
1706 			for(k=0;k<nb0;k++) if(numConn[k]>-1) { kmax = k; break;}
1707 			if(kmax<0) break;
1708 			for(k=0;k<nb0;k++) if(numConn[k]>-1 && dists[k]>dists[kmax]) kmax = k;
1709 		 	nBonds[i] -= 1;
1710 		 	j = numConn[kmax];
1711 		 	nBonds[j] -= 1;
1712 		 	nj = geometry[num[j]].N-1;
1713 			geometry[num[i]].typeConnections[nj] = 0;
1714 			geometry[num[j]].typeConnections[ni] = 0;
1715 		 	numConn[kmax]=-1;
1716 		}while( nBonds[i] > geometry[num[i]].Prop.maximumBondValence);
1717 	}
1718 	/* remove A-H-B connections */
1719 	for(i=0;i<(gint)Natoms;i++)
1720 	{
1721 		ni = geometry[num[i]].N-1;
1722 		if( nBonds[i] <= geometry[num[i]].Prop.maximumBondValence) continue;
1723 		if( geometry[num[i]].Prop.maximumBondValence>1) continue;
1724 		for(k=0;k<(gint)nBonds[i];k++) numConn[k] = -1;
1725 		k = 0;
1726 		for(j=0;j<(gint)Natoms;j++)
1727 		{
1728 			nj = geometry[num[j]].N-1;
1729 			if(i!=j && geometry[num[i]].typeConnections[nj]>0)
1730 			{
1731         			gdouble p = geometry[num[i]].Prop.covalentRadii+geometry[num[j]].Prop.covalentRadii;
1732 				p = p*p;
1733 				numConn[k] = j;
1734 				dists[k] = get_real_distance2(geometry, num[i], num[j])/p;
1735 				k++;
1736 			}
1737 		}
1738 		nb0 = nBonds[i];
1739 		do{
1740 			kmax = -1;
1741 			for(k=0;k<nb0;k++) if(numConn[k]>-1) { kmax = k; break;}
1742 			if(kmax<0) break;
1743 			for(k=0;k<nb0;k++) if(numConn[k]>-1 && dists[k]>dists[kmax]) kmax = k;
1744 		 	nBonds[i] -= 1;
1745 		 	j = numConn[kmax];
1746 		 	nBonds[j] -= 1;
1747 		 	nj = geometry[num[j]].N-1;
1748 			geometry[num[i]].typeConnections[nj] = 0;
1749 			geometry[num[j]].typeConnections[ni] = 0;
1750 		 	numConn[kmax]=-1;
1751 		}while( nBonds[i] > geometry[num[i]].Prop.maximumBondValence);
1752 	}
1753 	/* remove H-B connections if B saturated */
1754 	for(i=0;i<(gint)Natoms;i++)
1755 	{
1756 		gint nV = geometry[num[i]].Prop.maximumBondValence;
1757 		if(geometry[num[i]].mmType && !strcmp(geometry[num[i]].mmType,"N3")) nV++;
1758 		if( nBonds[i] <= nV) continue;
1759 		if( nV<=1) continue;
1760 		ni = geometry[num[i]].N-1;
1761 		for(k=0;k<(gint)nBonds[i];k++) numConn[k] = -1;
1762 		k = 0;
1763 		for(j=0;j<(gint)Natoms;j++)
1764 		{
1765 			nj = geometry[num[j]].N-1;
1766 			if(i!=j && geometry[num[i]].typeConnections[nj]>0)
1767 			{
1768         			gdouble p = geometry[num[i]].Prop.covalentRadii+geometry[num[j]].Prop.covalentRadii;
1769 				p = p*p;
1770 				numConn[k] = j;
1771 				dists[k] = get_real_distance2(geometry, num[i], num[j])/p;
1772 				if( geometry[num[j]].Prop.maximumBondValence>1) numConn[k] =-1;
1773 				k++;
1774 			}
1775 		}
1776 		nb0 = nBonds[i];
1777 		do{
1778 			kmax = -1;
1779 			for(k=0;k<nb0;k++) if(numConn[k]>-1) { kmax = k; break;}
1780 			if(kmax<0) break;
1781 			for(k=0;k<nb0;k++) if(numConn[k]>-1 && dists[k]>dists[kmax]) kmax = k;
1782 		 	nBonds[i] -= 1;
1783 		 	j = numConn[kmax];
1784 		 	nBonds[j] -= 1;
1785 		 	nj = geometry[num[j]].N-1;
1786 			geometry[num[i]].typeConnections[nj] = 0;
1787 			geometry[num[j]].typeConnections[ni] = 0;
1788 		 	numConn[kmax]=-1;
1789 		}while( nBonds[i] > geometry[num[i]].Prop.maximumBondValence);
1790 	}
1791 	/* remove A-B connections if A or B saturated */
1792 	for(i=0;i<(gint)Natoms;i++)
1793 	{
1794 		ni = geometry[num[i]].N-1;
1795 		if( geometry[num[i]].Prop.maximumBondValence<=1) continue;
1796 		if( nBonds[i] <= geometry[num[i]].Prop.maximumBondValence) continue;
1797 		if(geometry[num[i]].mmType && !strcmp(geometry[num[i]].mmType,"N3") && nBonds[i] <= geometry[num[i]].Prop.maximumBondValence+1) continue;
1798 		for(k=0;k<(gint)nBonds[i];k++) numConn[k] = -1;
1799 		k = 0;
1800 		for(j=0;j<(gint)Natoms;j++)
1801 		{
1802 			nj = geometry[num[j]].N-1;
1803 			if(i!=j && geometry[num[i]].typeConnections[nj]>0)
1804 			{
1805         			gdouble p = geometry[num[i]].Prop.covalentRadii+geometry[num[j]].Prop.covalentRadii;
1806 				p = p*p;
1807 				numConn[k] = j;
1808 				dists[k] = get_real_distance2(geometry, num[i], num[j])/p;
1809 				k++;
1810 			}
1811 		}
1812 		nb0 = nBonds[i];
1813 		do{
1814 			kmax = -1;
1815 			for(k=0;k<nb0;k++) if(numConn[k]>-1) { kmax = k; break;}
1816 			if(kmax<0) break;
1817 			for(k=0;k<nb0;k++) if(numConn[k]>-1 && dists[k]>dists[kmax]) kmax = k;
1818 		 	nBonds[i] -= 1;
1819 		 	j = numConn[kmax];
1820 		 	nBonds[j] -= 1;
1821 		 	nj = geometry[num[j]].N-1;
1822 			geometry[num[i]].typeConnections[nj] = 0;
1823 			geometry[num[j]].typeConnections[ni] = 0;
1824 		 	numConn[kmax]=-1;
1825 		}while( nBonds[i] > geometry[num[i]].Prop.maximumBondValence);
1826 	}
1827 
1828 	g_free(nBonds);
1829 	g_free(num);
1830 	g_free(numConn);
1831 	g_free(dists);
1832 }
1833 /************************************************************************/
setMultipleBonds()1834 static void setMultipleBonds()
1835 {
1836 	gint* nBonds = NULL;
1837 	gint* num = NULL;
1838 	gint i;
1839 	gint j;
1840 	gint ni;
1841 	gint nj;
1842 	if(Natoms<1) return;
1843 	nBonds = g_malloc(Natoms*sizeof(gint));
1844 	num = g_malloc(Natoms*sizeof(gint));
1845 	for(i=0;i<(gint)Natoms;i++) num[i] = i;
1846 
1847 	for(i=0;i<(gint)Natoms-1;i++)
1848 	{
1849 		gint k = i;
1850 		for(j=i+1;j<(gint)Natoms;j++)
1851 			if(geometry[num[j]].N<geometry[num[k]].N) k = j;
1852 		if(k!=i)
1853 		{
1854 			gint t = num[i];
1855 			num[i] = num[k];
1856 			num[k] = t;
1857 		}
1858 	}
1859 
1860 	for(i=0;i<(gint)Natoms;i++) nBonds[i] = 0;
1861 	for(i=0;i<(gint)Natoms;i++)
1862 	{
1863 		ni = geometry[num[i]].N-1;
1864 		for(j=i+1;j<(gint)Natoms;j++)
1865 		{
1866 			nj = geometry[num[j]].N-1;
1867 			 if(geometry[num[i]].typeConnections[nj]>0)
1868 			 {
1869 				 nBonds[i] += 1;
1870 				 nBonds[j] += 1;
1871 			 }
1872 		}
1873 	}
1874 // sort atoms nBonds min at first
1875 	for(i=0;i<(gint)Natoms-1;i++)
1876 	{
1877 		gint k = i;
1878 		for(j=i+1;j<(gint)Natoms;j++)
1879 			if(nBonds[j]<nBonds[k])  k = j;
1880 		if(k!=i)
1881 		{
1882 			gint t = num[i];
1883 			num[i] = num[k];
1884 			num[k] = t;
1885 			t = nBonds[i];
1886 			nBonds[i] = nBonds[k];
1887 			nBonds[k] = t;
1888 		}
1889 	}
1890 /*
1891 	for(i=0;i<(gint)Natoms;i++)
1892 		printf("%s[%d] %d\n",geometry[num[i]].Prop.symbol, geometry[num[i]].N,nBonds[i]);
1893 */
1894 
1895 	for(i=0;i<(gint)Natoms;i++)
1896 	{
1897 		ni = geometry[num[i]].N-1;
1898 		for(j=i+1;j<(gint)Natoms;j++)
1899 		{
1900 			nj = geometry[num[j]].N-1;
1901 			if(geometry[num[i]].typeConnections[nj]==0) continue;
1902 			if(
1903 		 	nBonds[i] < geometry[num[i]].Prop.maximumBondValence &&
1904 		 	nBonds[j] < geometry[num[j]].Prop.maximumBondValence
1905 			)
1906 			{
1907 				geometry[num[i]].typeConnections[nj] = geometry[num[j]].typeConnections[ni] = 2;
1908 				nBonds[i] += 1;
1909 				nBonds[j] += 1;
1910 			}
1911 		}
1912 	}
1913 /*
1914 	for(i=0;i<(gint)Natoms;i++)
1915 		printf("=====>%s[%d] %d\n",geometry[num[i]].Prop.symbol, geometry[num[i]].N,nBonds[i]);
1916 */
1917 	for(i=0;i<(gint)Natoms;i++)
1918 	{
1919 		ni = geometry[num[i]].N-1;
1920 		for(j=i+1;j<(gint)Natoms;j++)
1921 		{
1922 			nj = geometry[num[j]].N-1;
1923 			if(geometry[num[i]].typeConnections[nj]==0) continue;
1924 			if(
1925 		 	nBonds[i] < geometry[num[i]].Prop.maximumBondValence &&
1926 		 	nBonds[j] < geometry[num[j]].Prop.maximumBondValence
1927 			)
1928 			{
1929 				geometry[num[i]].typeConnections[nj] = geometry[num[j]].typeConnections[ni] = 3;
1930 				nBonds[i] += 1;
1931 				nBonds[j] += 1;
1932 			}
1933 		}
1934 	}
1935 /*
1936 	for(i=0;i<(gint)Natoms;i++)
1937 		printf("33=====>%s[%d] %d\n",geometry[num[i]].Prop.symbol, geometry[num[i]].N,nBonds[i]);
1938 */
1939 	g_free(nBonds);
1940 	g_free(num);
1941 }
1942 /*****************************************************************************/
set_connections()1943 static void set_connections()
1944 {
1945 	gint i;
1946 	gint j;
1947 	gint ni;
1948 	gint nj;
1949 
1950 	init_connections();
1951 	for(i=0;i<(gint)Natoms;i++)
1952 	{
1953 		ni = geometry[i].N-1;
1954 		for(j=i+1;j<(gint)Natoms;j++)
1955 		{
1956 			nj = geometry[j].N-1;
1957 			if(draw_lines_yes_no(i,j)) geometry[i].typeConnections[nj]= 1;
1958 			else geometry[i].typeConnections[nj]=0;
1959 			geometry[j].typeConnections[ni] = geometry[i].typeConnections[nj];
1960 		}
1961 	}
1962 	reSetSimpleConnections();
1963 	setMultipleBonds();
1964 }
1965 /*****************************************************************************/
set_Hconnections()1966 static void set_Hconnections()
1967 {
1968 	gint i;
1969 	gint j;
1970 	gint k;
1971 	gboolean Ok;
1972 	gdouble distance2;
1973 	gdouble dx;
1974 	gdouble dy;
1975 	gdouble dz;
1976 	gdouble angle;
1977 	gchar* strAngle;
1978 	gdouble minDistanceH2;
1979 	gdouble maxDistanceH2;
1980         Point A;
1981         Point B;
1982 	gint ni, nj, nk;
1983 
1984 	minDistanceH = getMinDistanceHBonds();
1985 	minDistanceH2 = minDistanceH*minDistanceH*ANG_TO_BOHR*ANG_TO_BOHR;
1986 
1987 	maxDistanceH = getMaxDistanceHBonds();
1988 	maxDistanceH2 = maxDistanceH*maxDistanceH*ANG_TO_BOHR*ANG_TO_BOHR;
1989 
1990 	minAngleH = getMinAngleHBonds();
1991 	maxAngleH = getMaxAngleHBonds();
1992 
1993 	for(i=0;i<(gint)Natoms;i++)
1994 	{
1995 		ni = geometry[i].N-1;
1996 		Ok = FALSE;
1997 		Ok = atomCanDoHydrogenBond(geometry[i].Prop.symbol);
1998 		if(!Ok) continue;
1999 		for(j=0;j<(gint)Natoms;j++)
2000 		{
2001 			nj = geometry[j].N-1;
2002 			if(geometry[i].typeConnections[nj]>0) continue;
2003 			if(i==j) continue;
2004 			if(strcmp(geometry[j].Prop.symbol, "H")!=0)continue;
2005 
2006 			dx = geometry[i].X-geometry[j].X;
2007 			dy = geometry[i].Y-geometry[j].Y;
2008 			dz = geometry[i].Z-geometry[j].Z;
2009 			distance2 = (dx*dx+dy*dy+dz*dz);
2010 			if(distance2<minDistanceH2 || distance2>maxDistanceH2) continue;
2011 
2012 
2013 			Ok = FALSE;
2014 			for(k=0;k<(gint)Natoms;k++)
2015 			{
2016 				nk = geometry[k].N-1;
2017 				if(k==j) continue;
2018 				if(k==i) continue;
2019 				if(geometry[j].typeConnections[nk]<=0) continue;
2020 				A.C[0]=geometry[i].X-geometry[j].X;
2021 				A.C[1]=geometry[i].Y-geometry[j].Y;
2022 				A.C[2]=geometry[i].Z-geometry[j].Z;
2023 
2024 				B.C[0]=geometry[k].X-geometry[j].X;
2025 				B.C[1]=geometry[k].Y-geometry[j].Y;
2026 				B.C[2]=geometry[k].Z-geometry[j].Z;
2027 
2028         			strAngle = get_angle_vectors(A,B);
2029 				angle = atof(strAngle);
2030 				if(strAngle) g_free(strAngle);
2031 				if(angle>=minAngleH &&angle<=maxAngleH)
2032 				{
2033 					Ok = TRUE;
2034 					break;
2035 				}
2036 			}
2037 			if(Ok)
2038 			{
2039 				geometry[i].typeConnections[nj]=-1;
2040 				geometry[j].typeConnections[ni]=-1;
2041 			}
2042 		}
2043 	}
2044 }
2045 /*****************************************************************************/
copy_connections(GeomDef * geom0,GeomDef * geom,gint n)2046 void copy_connections(GeomDef* geom0, GeomDef* geom, gint n)
2047 {
2048 	gint i;
2049 	gint j;
2050 	if(!geom) return;
2051 	if(!geom0) return;
2052 	for(i=0;i<n;i++)
2053 	{
2054 		if(!geom[i].typeConnections) continue;
2055 		for(j=0;j<n;j++)
2056 		{
2057 			gint nj = geom[j].N-1;
2058 			if(!geom0[j].typeConnections) continue;
2059 			geom0[i].typeConnections[nj] = geom[i].typeConnections[nj];
2060 		}
2061 	}
2062 }
2063 /************************************************************************************************************/
get_number_of_model_connections()2064 static gint get_number_of_model_connections()
2065 {
2066 	gint i;
2067 	gint j;
2068 	gint nc = 0;
2069 	gint NC = Natoms;
2070 	if(Natoms<1) return 0;
2071     	for(i=0;i<NC;i++)
2072 	{
2073 		if(geometry[i].Layer==MEDIUM_LAYER || geometry[i].Layer==LOW_LAYER) continue;
2074     		for(j=0;j<NC;j++)
2075 		{
2076 			gint nj = geometry[j].N-1;
2077 			if(i==j) continue;
2078 			if(geometry[j].Layer==MEDIUM_LAYER || geometry[j].Layer==LOW_LAYER) continue;
2079 			if(geometry[i].typeConnections[nj]>0) nc++;
2080 		}
2081 	}
2082 	return nc;
2083 }
2084 /************************************************************************************************************/
get_number_of_inter_connections()2085 static gint get_number_of_inter_connections()
2086 {
2087 	gint i;
2088 	gint j;
2089 	gint nc = 0;
2090 	gint NC = Natoms;
2091     	for(i=0;i<NC;i++)
2092 	{
2093 		if(geometry[i].Layer==HIGH_LAYER || geometry[i].Layer==LOW_LAYER) continue;
2094     		for(j=0;j<NC;j++)
2095 		{
2096 			gint nj = geometry[j].N-1;
2097 			if(i==j) continue;
2098 			if(geometry[j].Layer==HIGH_LAYER || geometry[j].Layer==LOW_LAYER) continue;
2099 			if(geometry[i].typeConnections[nj]>0) nc++;
2100 		}
2101 	}
2102 	return nc;
2103 }
2104 /*************************************************************************************/
get_number_of_electrons(guint type)2105 static guint get_number_of_electrons(guint type)
2106 {
2107 /*
2108    type = 1 : Medium and High
2109    type = 2 : High
2110    type = other : All
2111 */
2112    guint i;
2113    guint Ne=0;
2114    SAtomsProp Atom;
2115    for(i=0;i<Natoms;i++)
2116    {
2117        Atom = geometry[i].Prop;
2118        switch (type)
2119        {
2120       	case 1 : if( geometry[i].Layer==HIGH_LAYER ||  geometry[i].Layer==MEDIUM_LAYER) Ne += Atom.atomicNumber;
2121 		 break;
2122        	case 2 : if( geometry[i].Layer==HIGH_LAYER) Ne += Atom.atomicNumber;
2123 		 break;
2124        	default : Ne += Atom.atomicNumber;
2125         }
2126    }
2127    return Ne;
2128 }
2129 /************************************************************************************************************/
reset_spin_of_electrons()2130 static void reset_spin_of_electrons()
2131 {
2132         gint i;
2133         guint NumberElectrons[3];
2134         guint SpinElectrons[3];
2135 	gint n = 1;
2136 	gint nL = 0;
2137 	gint nM = 0;
2138 	gint nH = 0;
2139 
2140 	if(Natoms<1) return;
2141 
2142         NumberElectrons[2]= get_number_of_electrons(2);
2143         NumberElectrons[1]= get_number_of_electrons(1);
2144         NumberElectrons[0]= get_number_of_electrons(0);
2145 
2146 
2147         for(i=0;i<3;i++)
2148 		SpinElectrons[i]=0;
2149     	for(i=0;i<Natoms;i++)
2150 	{
2151 		if(geometry[i].Layer==LOW_LAYER) nH =1;
2152 		if(geometry[i].Layer==MEDIUM_LAYER) nM =1;
2153 		if(geometry[i].Layer==HIGH_LAYER) nH =1;
2154 	}
2155 	n = nH + nM + nL;
2156         if(n==3)
2157 	{
2158         	NumberElectrons[2] += get_number_of_model_connections();
2159         	NumberElectrons[1] += get_number_of_inter_connections();
2160 	}
2161         if(n==2)
2162 	{
2163         	NumberElectrons[1] += get_number_of_model_connections();
2164 	}
2165 
2166         for(i=0;(guint)i<n;i++)
2167         	if((NumberElectrons[i]-TotalCharges[i])%2==0)
2168 			SpinElectrons[i]=1;
2169                 else
2170 			SpinElectrons[i]=2;
2171 
2172         for(i=0;(guint)i<n;i++)
2173 	{
2174 		if(SpinMultiplicities[i]%2 != SpinElectrons[i]%2)
2175 			SpinMultiplicities[i] = SpinElectrons[i];
2176 	}
2177 }
2178 /*****************************************************************************/
reset_charges_multiplicities()2179 void reset_charges_multiplicities()
2180 {
2181 	gint i;
2182 	if(Natoms<1) return;
2183 	for(i=0;i<3;i++)
2184 		TotalCharges[i] = 0;
2185 	reset_spin_of_electrons();
2186 
2187 }
2188 /*****************************************************************************/
reset_hydrogen_bonds()2189 void reset_hydrogen_bonds()
2190 {
2191 	if(Natoms<1) return;
2192 	if(ShowHBonds)
2193 	{
2194 		set_Hconnections();
2195 		copy_connections(geometry0, geometry, Natoms);
2196 		RebuildGeom = TRUE;
2197 	}
2198 }
2199 /*****************************************************************************/
reset_multiple_bonds()2200 void reset_multiple_bonds()
2201 {
2202 	gint i;
2203 	gint j;
2204     	for(i=0;i<Natoms;i++)
2205 	{
2206     		for(j=0;j<Natoms;j++)
2207 		{
2208 			gint nj = geometry[j].N-1;
2209 			if(geometry[i].typeConnections[nj]>1)
2210 				geometry[i].typeConnections[nj] = 1;
2211 		}
2212 	}
2213 	setMultipleBonds();
2214 	RebuildGeom = TRUE;
2215 }
2216 /*****************************************************************************/
reset_all_connections()2217 void reset_all_connections()
2218 {
2219 	if(Natoms<1) return;
2220 	set_connections();
2221 	if(ShowHBonds) set_Hconnections();
2222 	copy_connections(geometry0, geometry, Natoms);
2223 	RebuildGeom = TRUE;
2224 }
2225 /*****************************************************************************/
reset_connections_between_selected_atoms()2226 static void reset_connections_between_selected_atoms()
2227 {
2228 	gint i;
2229 	gint j;
2230 	gint ni;
2231 	gint nj;
2232 	gint* nBonds = NULL;
2233 	gint* num = NULL;
2234 
2235 	if(Natoms<2) return;
2236 	nBonds = g_malloc(Natoms*sizeof(gint));
2237 	num = g_malloc(Natoms*sizeof(gint));
2238 	for(i=0;i<(gint)Natoms;i++) num[i] = i;
2239 	for(i=0;i<(gint)Natoms-1;i++)
2240 	{
2241 		gint k = i;
2242 		for(j=i+1;j<(gint)Natoms;j++)
2243 			if(geometry[num[j]].N<geometry[num[k]].N) k = j;
2244 		if(k!=i)
2245 		{
2246 			gint t = num[i];
2247 			num[i] = num[k];
2248 			num[k] = t;
2249 		}
2250 	}
2251 
2252 	for(i=0;i<(gint)Natoms;i++) nBonds[i] = 0;
2253 	for(i=0;i<(gint)Natoms-1;i++)
2254 	{
2255 		gboolean isa = if_selected(num[i]);
2256 		ni = geometry[num[i]].N-1;
2257 		if(geometry[num[i]].typeConnections)
2258 		for(j=i+1;j<(gint)Natoms;j++)
2259 		{
2260 			gboolean jsa = if_selected(num[j]);
2261 			if(isa==jsa) continue;
2262 			nj = geometry[num[j]].N-1;
2263 			 if(geometry[num[i]].typeConnections[nj]>0)
2264 			 {
2265 				 nBonds[i] += geometry[num[i]].typeConnections[nj];
2266 				 nBonds[j] += geometry[num[i]].typeConnections[nj];
2267 			 }
2268 		}
2269 	}
2270 	for(i=0;i<(gint)Natoms;i++)
2271 	{
2272 		gboolean isa = if_selected(num[i]);
2273 		if(!isa) continue;
2274 		ni = geometry[num[i]].N-1;
2275 		if(geometry[num[i]].typeConnections)
2276 		for(j=i+1;j<(gint)Natoms;j++)
2277 		{
2278 			gboolean jsa = if_selected(num[j]);
2279 			if(!jsa) continue;
2280 			nj = geometry[num[j]].N-1;
2281 			if(draw_lines_yes_no(num[i],num[j])) geometry[num[i]].typeConnections[nj]= 1;
2282 			else geometry[num[i]].typeConnections[nj]=0;
2283 
2284 			if(geometry[num[j]].typeConnections)
2285 				geometry[num[j]].typeConnections[ni] = geometry[num[i]].typeConnections[nj];
2286 
2287 			nBonds[i]+= geometry[num[i]].typeConnections[nj];
2288 			nBonds[j]+= geometry[num[i]].typeConnections[nj];
2289 			if(nBonds[i]>geometry[num[i]].Prop.maximumBondValence ||
2290 			nBonds[j]>geometry[num[j]].Prop.maximumBondValence
2291 					)
2292 			{
2293 				geometry[num[i]].typeConnections[nj]= 0;
2294 				if(geometry[num[j]].typeConnections)
2295 					geometry[num[j]].typeConnections[ni] = 0;
2296 				nBonds[i]--;
2297 				nBonds[j]--;
2298 
2299 			}
2300 		}
2301 	}
2302 	for(i=0;i<(gint)Natoms;i++)
2303 
2304 	{
2305 		gboolean isa = if_selected(num[i]);
2306 		ni = geometry[num[i]].N-1;
2307 		if(!isa) continue;
2308 		for(j=i+1;j<(gint)Natoms;j++)
2309 		{
2310 			gboolean jsa = if_selected(num[j]);
2311 			if(!jsa) continue;
2312 			nj = geometry[num[j]].N-1;
2313 			if(geometry[num[i]].typeConnections[nj]==0) continue;
2314 			if(
2315 		 	nBonds[i] < geometry[num[i]].Prop.maximumBondValence &&
2316 		 	nBonds[j] < geometry[num[j]].Prop.maximumBondValence
2317 			)
2318 			{
2319 				geometry[num[i]].typeConnections[nj] = geometry[num[j]].typeConnections[ni] = 2;
2320 				nBonds[i] += 1;
2321 				nBonds[j] += 1;
2322 			}
2323 		}
2324 	}
2325 	for(i=0;i<(gint)Natoms;i++)
2326 	{
2327 		gboolean isa = if_selected(num[i]);
2328 		if(!isa) continue;
2329 		ni = geometry[num[i]].N-1;
2330 		for(j=i+1;j<(gint)Natoms;j++)
2331 		{
2332 			gboolean jsa = if_selected(num[j]);
2333 			if(!jsa) continue;
2334 			nj = geometry[num[j]].N-1;
2335 			if(geometry[num[i]].typeConnections[nj]==0) continue;
2336 			if(
2337 		 	nBonds[i] < geometry[num[i]].Prop.maximumBondValence &&
2338 		 	nBonds[j] < geometry[num[j]].Prop.maximumBondValence
2339 			)
2340 			{
2341 				geometry[num[i]].typeConnections[nj] = geometry[num[j]].typeConnections[ni] = 3;
2342 				nBonds[i] += 1;
2343 				nBonds[j] += 1;
2344 			}
2345 		}
2346 	}
2347 	g_free(nBonds);
2348 	g_free(num);
2349 	copy_connections(geometry0, geometry, Natoms);
2350 	RebuildGeom = TRUE;
2351 }
2352 /*****************************************************************************/
reset_connections_between_selected_and_notselected_atoms()2353 static void reset_connections_between_selected_and_notselected_atoms()
2354 {
2355 	gint i;
2356 	gint j;
2357 	gint ni;
2358 	gint nj;
2359 	gint* nBonds = NULL;
2360 	gint* num = NULL;
2361 
2362 	if(Natoms<2) return;
2363 	nBonds = g_malloc(Natoms*sizeof(gint));
2364 	num = g_malloc(Natoms*sizeof(gint));
2365 	for(i=0;i<(gint)Natoms;i++) num[i] = i;
2366 	for(i=0;i<(gint)Natoms-1;i++)
2367 	{
2368 		gint k = i;
2369 		for(j=i+1;j<(gint)Natoms;j++)
2370 			if(geometry[num[j]].N<geometry[num[k]].N) k = j;
2371 		if(k!=i)
2372 		{
2373 			gint t = num[i];
2374 			num[i] = num[k];
2375 			num[k] = t;
2376 		}
2377 	}
2378 
2379 	for(i=0;i<(gint)Natoms;i++) nBonds[i] = 0;
2380 	for(i=0;i<(gint)Natoms-1;i++)
2381 	{
2382 		gboolean isa = if_selected(num[i]);
2383 		ni = geometry[num[i]].N-1;
2384 		if(geometry[num[i]].typeConnections)
2385 		for(j=i+1;j<(gint)Natoms;j++)
2386 		{
2387 			gboolean jsa = if_selected(num[j]);
2388 			if(isa!=jsa) continue;
2389 			nj = geometry[num[j]].N-1;
2390 			 if(geometry[num[i]].typeConnections[nj]>0)
2391 			 {
2392 				 nBonds[i] += geometry[num[i]].typeConnections[nj];
2393 				 nBonds[j] += geometry[num[i]].typeConnections[nj];
2394 			 }
2395 		}
2396 	}
2397 	for(i=0;i<(gint)Natoms;i++)
2398 	{
2399 		gboolean isa = if_selected(num[i]);
2400 		ni = geometry[num[i]].N-1;
2401 		if(geometry[num[i]].typeConnections)
2402 		for(j=i+1;j<(gint)Natoms;j++)
2403 		{
2404 			gboolean jsa = if_selected(num[j]);
2405 			if(isa==jsa) continue;
2406 			nj = geometry[num[j]].N-1;
2407 			if(draw_lines_yes_no(num[i],num[j])) geometry[num[i]].typeConnections[nj]= 1;
2408 			else geometry[num[i]].typeConnections[nj]=0;
2409 
2410 			if(geometry[num[j]].typeConnections)
2411 				geometry[num[j]].typeConnections[ni] = geometry[num[i]].typeConnections[nj];
2412 
2413 			nBonds[i]+= geometry[num[i]].typeConnections[nj];
2414 			nBonds[j]+= geometry[num[i]].typeConnections[nj];
2415 			if(nBonds[i]>geometry[num[i]].Prop.maximumBondValence ||
2416 			nBonds[j]>geometry[num[j]].Prop.maximumBondValence
2417 					)
2418 			{
2419 				geometry[num[i]].typeConnections[nj]= 0;
2420 				if(geometry[num[j]].typeConnections)
2421 					geometry[num[j]].typeConnections[ni] = 0;
2422 				nBonds[i]--;
2423 				nBonds[j]--;
2424 
2425 			}
2426 		}
2427 	}
2428 	for(i=0;i<(gint)Natoms;i++)
2429 
2430 	{
2431 		gboolean isa = if_selected(num[i]);
2432 		ni = geometry[num[i]].N-1;
2433 		for(j=i+1;j<(gint)Natoms;j++)
2434 		{
2435 			gboolean jsa = if_selected(num[j]);
2436 			nj = geometry[num[j]].N-1;
2437 			if(geometry[num[i]].typeConnections[nj]==0) continue;
2438 			if(
2439 		 	nBonds[i] < geometry[num[i]].Prop.maximumBondValence &&
2440 		 	nBonds[j] < geometry[num[j]].Prop.maximumBondValence
2441 			)
2442 			{
2443 				if(isa != jsa)
2444 				{
2445 				geometry[num[i]].typeConnections[nj] = geometry[num[j]].typeConnections[ni] = 2;
2446 				nBonds[i] += 1;
2447 				nBonds[j] += 1;
2448 				}
2449 			}
2450 		}
2451 	}
2452 	for(i=0;i<(gint)Natoms;i++)
2453 	{
2454 		gboolean isa = if_selected(num[i]);
2455 		ni = geometry[num[i]].N-1;
2456 		for(j=i+1;j<(gint)Natoms;j++)
2457 		{
2458 			gboolean jsa = if_selected(num[j]);
2459 			nj = geometry[num[j]].N-1;
2460 			if(geometry[num[i]].typeConnections[nj]==0) continue;
2461 			if(
2462 		 	nBonds[i] < geometry[num[i]].Prop.maximumBondValence &&
2463 		 	nBonds[j] < geometry[num[j]].Prop.maximumBondValence
2464 			)
2465 			{
2466 				if(isa != jsa)
2467 				{
2468 				geometry[num[i]].typeConnections[nj] = geometry[num[j]].typeConnections[ni] = 3;
2469 				nBonds[i] += 1;
2470 				nBonds[j] += 1;
2471 				}
2472 			}
2473 		}
2474 	}
2475 	g_free(nBonds);
2476 	g_free(num);
2477 	copy_connections(geometry0, geometry, Natoms);
2478 	RebuildGeom = TRUE;
2479 }
2480 /*****************************************************************************/
hbond_connections(gint i,gint j)2481 gboolean hbond_connections(gint i, gint j)
2482 {
2483 
2484 	if(ShowHBonds)
2485 	{
2486 		gint nj = geometry[j].N-1;
2487 		if(i<(gint)Natoms && j<(gint)Natoms && geometry[i].typeConnections[nj]==-1) return TRUE;
2488 		else return FALSE;
2489 	}
2490 	else return FALSE;
2491 }
2492 /*****************************************************************************/
init_quat(gdouble quat[])2493 void init_quat(gdouble quat[])
2494 {
2495 	gint i;
2496 	for(i=0;i<3;i++) quat[i] = 0.0;
2497 	quat[3] = 1.0;
2498 }
2499 /********************************************************************************/
set_origin_to_point(gdouble center[])2500 static void set_origin_to_point(gdouble center[])
2501 {
2502 	gint i;
2503 	for(i=0;i<(gint)Natoms;i++)
2504 	{
2505 		if(mystrcasestr(geometry0[i].Prop.symbol,"TV"))
2506 		{
2507 		 geometry0[i].X -= center[0]-Orig[0];
2508 		 geometry0[i].Y -= center[1]-Orig[1];
2509 		 geometry0[i].Z -= center[2]-Orig[2];
2510 		}
2511 		else
2512 		{
2513 		 geometry0[i].X -= center[0];
2514 		 geometry0[i].Y -= center[1];
2515 		 geometry0[i].Z -= center[2];
2516 		}
2517 	}
2518         for(i=0;i<3;i++) Orig[i] = 0;
2519 	copyCoordinates2to1(geometry, geometry0);
2520 }
2521 /********************************************************************************/
set_origin_to_center_of_fragment()2522 void set_origin_to_center_of_fragment()
2523 {
2524 
2525 	gdouble C[3] = {0,0,0};
2526 	gint j = 0;
2527 	gint i;
2528 	for (i=0;i<(gint)Natoms;i++)
2529 	{
2530 		if(if_selected(i))
2531 		{
2532 			j++;
2533 			C[0] += geometry0[i].X;
2534 			C[1] += geometry0[i].Y;
2535 			C[2] += geometry0[i].Z;
2536 		}
2537 	}
2538 	if(j==0) return;
2539 	for (i=0;i<3;i++) C[i] /= j;
2540 	set_origin_to_point(C);
2541 	create_GeomXYZ_from_draw_grometry();
2542 	Trans[0] = 0;
2543 	Trans[1] = 0;
2544 	RebuildGeom = TRUE;
2545 	drawGeom();
2546 }
2547 /********************************************************************************/
set_geom_to_axes(gdouble axis1[],gdouble axis2[],gdouble axis3[])2548 static void set_geom_to_axes(gdouble axis1[], gdouble axis2[], gdouble axis3[])
2549 {
2550 	gdouble **m0 = NULL;
2551 	gdouble** minv;
2552 	gint i,j;
2553 	guint n;
2554 
2555 	gdouble A[3];
2556 	gdouble B[3];
2557 	guint k;
2558 	gdouble* X;
2559 	gdouble* Y;
2560 	gdouble* Z;
2561 
2562 	if(Natoms<1) return;
2563 
2564 	m0 = g_malloc(3*sizeof(gdouble*));
2565 	X = g_malloc(Natoms*sizeof(gdouble));
2566 	Y = g_malloc(Natoms*sizeof(gdouble));
2567 	Z = g_malloc(Natoms*sizeof(gdouble));
2568 
2569 	for(i=0;i<3;i++)
2570 		m0[i] = g_malloc(3*sizeof(gdouble));
2571 
2572 
2573 	m0[0][0] = axis1[0];
2574 	m0[0][1] = axis1[1];
2575 	m0[0][2] = axis1[2];
2576 
2577 	m0[1][0] = axis2[0];
2578 	m0[1][1] = axis2[1];
2579 	m0[1][2] = axis2[2];
2580 
2581 	m0[2][0] = axis3[0];
2582 	m0[2][1] = axis3[1];
2583 	m0[2][2] = axis3[2];
2584 
2585 	minv = Inverse(m0,3,1e-7);
2586 
2587 	for(n = 0;n<Natoms;n++)
2588 	{
2589 		A[0] = geometry[n].X;
2590 		A[1] = geometry[n].Y;
2591 		A[2] = geometry[n].Z;
2592 
2593 		for(j=0;j<3;j++)
2594 		{
2595 			B[j] = 0.0;
2596 			for(k=0;k<3;k++)
2597 				B[j] += minv[k][j]*A[k];
2598 		}
2599 
2600 		X[n] = B[0];
2601 		Y[n] = B[1];
2602 		Z[n] = B[2];
2603 	}
2604 	for(n = 0;n<Natoms;n++)
2605 	{
2606 			geometry0[n].X = X[n];
2607 			geometry0[n].Y = Y[n];
2608 			geometry0[n].Z = Z[n];
2609 
2610 			geometry[n].X = X[n];
2611 			geometry[n].Y = Y[n];
2612 			geometry[n].Z = Z[n];
2613 	}
2614 
2615 	for(i=0;i<3;i++) if(minv[i]) g_free(minv[i]);
2616 	if(minv) g_free(minv);
2617 
2618 	for(i=0;i<3;i++) if(m0[i]) g_free(m0[i]);
2619 	if(m0) g_free(m0);
2620 
2621 	if(X) g_free(X);
2622 	if(Y) g_free(Y);
2623 	if(Z) g_free(Z);
2624 	RebuildGeom = TRUE;
2625 }
2626 /********************************************************************************/
move_the_center_of_selected_or_not_selected_atoms_to_origin(gboolean sel)2627 void move_the_center_of_selected_or_not_selected_atoms_to_origin(gboolean sel)
2628 {
2629 
2630 	gdouble C[3] = {0,0,0};
2631 	gdouble C0[3] = {0,0,0};
2632 	gdouble mt = 0;
2633 	gint i;
2634 	for (i=0;i<(gint)Natoms;i++)
2635 	{
2636 		if(if_selected(i)==sel)
2637 		{
2638 			gdouble m = geometry[i].Prop.masse;
2639 			mt += m;
2640 			C[0] += m*geometry[i].X;
2641 			C[1] += m*geometry[i].Y;
2642 			C[2] += m*geometry[i].Z;
2643 			C0[0] += m*geometry0[i].X;
2644 			C0[1] += m*geometry0[i].Y;
2645 			C0[2] += m*geometry0[i].Z;
2646 		}
2647 	}
2648 	if(mt==0) return;
2649 	for (i=0;i<3;i++) C[i] /= mt;
2650 	for (i=0;i<3;i++) C0[i] /= mt;
2651 	for (i=0;i<(gint)Natoms;i++)
2652 	{
2653 		if(if_selected(i)==sel)
2654 		{
2655 			geometry[i].X -= C[0];
2656 			geometry[i].Y -= C[1];
2657 			geometry[i].Z -= C[2];
2658 
2659 			geometry0[i].X -= C0[0];
2660 			geometry0[i].Y -= C0[1];
2661 			geometry0[i].Z -= C0[2];
2662 		}
2663 	}
2664 	RebuildGeom = TRUE;
2665 	// set Origin to 0 0 0
2666 	//printf("set Origin to 0 0 0\n");
2667 	//reset_origine_molecule_drawgeom();
2668 }
2669 /*****************************************************************************/
set_fragment_rotational_matrix(gdouble m[6],gdouble C[],gboolean sel)2670 static int set_fragment_rotational_matrix(gdouble m[6], gdouble C[], gboolean sel)
2671 {
2672 	gint i;
2673 	gint ip;
2674 	gint j;
2675 	gint k;
2676 	gdouble a;
2677 	gdouble* XYZ[3];
2678 	gdouble mt = 0;
2679 	gint nFrag = 0;
2680 	gint* numAtoms;
2681 
2682 	for(i=0;i<3;i++)
2683 	{
2684 		XYZ[i] = g_malloc(Natoms*sizeof(gdouble));
2685 		C[i] = 0.0;
2686 	}
2687 	numAtoms = g_malloc(Natoms*sizeof(gint));
2688 
2689 
2690 	for(j=0;j<(gint)Natoms;j++)
2691 	{
2692 		if(if_selected(j)==sel)
2693 		{
2694 			numAtoms[nFrag] = j;
2695 			mt += geometry[j].Prop.masse;
2696 			XYZ[0][nFrag] = geometry[j].X;
2697 			XYZ[1][nFrag] = geometry[j].Y;
2698 			XYZ[2][nFrag] = geometry[j].Z;
2699 			nFrag++;
2700 		}
2701 	}
2702 	for(i=0;i<3;i++)
2703 		for(j=0;j<nFrag;j++)
2704 			C[i] += geometry[numAtoms[j]].Prop.masse*XYZ[i][j];
2705 	if(mt != 0)
2706 	for(i=0;i<3;i++) C[i] /= mt;
2707 
2708 	for(j=0;j<nFrag;j++)
2709 		for(i=0;i<3;i++)
2710 			XYZ[i][j] -= C[i];
2711 
2712 	k = 0;
2713 	for(i=0;i<3;i++)
2714 		for(ip=i;ip<3;ip++)
2715 	{
2716 		m[k] = 0.0;
2717 
2718 		for(j=0;j<nFrag;j++)
2719 		{
2720 			if(i==ip)
2721 			a = XYZ[(i+1)%3][j]*XYZ[(ip+1)%3][j]
2722 			  + XYZ[(i+2)%3][j]*XYZ[(ip+2)%3][j];
2723 			else
2724 			{
2725 				a =-XYZ[i][j]*XYZ[ip][j];
2726 			}
2727 			m[k] += geometry[numAtoms[j]].Prop.masse*a;
2728 		}
2729 		k++;
2730 	}
2731 
2732 	for(i=0;i<3;i++) g_free(XYZ[i]);
2733 	g_free(numAtoms);
2734 	return nFrag;
2735 }
2736 /********************************************************************************/
compute_fragment_principal_axes(gdouble axis1[],gdouble axis2[],gdouble axis3[],gdouble C[],gboolean sel)2737 static int compute_fragment_principal_axes(gdouble axis1[], gdouble axis2[], gdouble axis3[], gdouble C[], gboolean sel)
2738 {
2739 	gdouble m[6];
2740 	gdouble I[3];
2741 	gdouble** v = NULL;
2742 	gint nrot;
2743 	gint i;
2744 	gint nFrag;
2745 
2746 
2747 	if(Natoms<1) return 0;
2748 
2749 	nFrag = set_fragment_rotational_matrix(m, C,sel);
2750 	if(nFrag == 0) return 0;
2751 
2752 	v = g_malloc(3*sizeof(gdouble*));
2753 	for(i=0;i<3;i++) v[i] = g_malloc(3*sizeof(gdouble));
2754 
2755 	jacobi(m, 3,I,v,&nrot);
2756 
2757 	for(i=0;i<3;i++) axis1[i] =  v[i][0];
2758 	for(i=0;i<3;i++) axis2[i] =  v[i][1];
2759 	for(i=0;i<3;i++) axis3[i] =  v[(i+1)%3][0]*v[(i+2)%3][1]-v[(i+2)%3][0]*v[(i+1)%3][1];
2760 	/*
2761 	for(i=0;i<3;i++) axis3[i] =  v[i][2];
2762 	*/
2763 
2764 	for(i=0;i<3;i++) g_free(v[i]);
2765 	g_free(v);
2766 	printf("I= %f %f %f\n",I[0],I[1],I[2]);
2767 	return nFrag;
2768 }
2769 /********************************************************************************/
rotate_slected_atoms_minimize_rmsd()2770 static void rotate_slected_atoms_minimize_rmsd()
2771 {
2772 	gint i,j;
2773 
2774 	gint nA = 0;
2775 	const gint N = 8;
2776         gdouble d[8];
2777         gdouble w[8][3] = {
2778                 {1,1,1},
2779                 {-1,1,1},
2780                 {1,-1,1},
2781                 {1,1,-1},
2782                 {-1,-1,1},
2783                 {-1,1,-1},
2784                 {1,-1,-1},
2785                 {-1,-1,-1}
2786         };
2787         gdouble x, y, z;
2788 	gint* numA = NULL;
2789 	gint* numB = NULL;
2790 	gint iA, iB;
2791 
2792 	if(Natoms<1) return;
2793 
2794 	j = 0;
2795 	for(i = 0;i<Natoms;i++)
2796 		if(if_selected(i)) nA++;
2797 
2798 	if(nA != Natoms - nA || nA == 0) return;
2799 	numA = g_malloc(nA*sizeof(gint));
2800 	numB = g_malloc(nA*sizeof(gint));
2801         for (i=0;i<nA;i++) numA[i] = -1;
2802         for (i=0;i<nA;i++) numB[i] = -1;
2803 
2804 	iA = iB = 0;
2805 	for(i = 0;i<Natoms;i++)
2806 		if(if_selected(i)) numA[iA++] = i;
2807 		else numB[iB++] = i;
2808 
2809 	for(i = 0;i<nA;i++)
2810 	if(strcmp(geometry[numA[i]].Prop.symbol, geometry[numB[i]].Prop.symbol))
2811 	{
2812 		g_free(numA);
2813 		g_free(numB);
2814 		return;
2815 	}
2816 
2817         for (j=0;j<N;j++) d[j] = 0;
2818         for (i=0;i<nA;i++)
2819         {
2820                 for (j=0;j<N;j++)
2821                 {
2822                 x = geometry[numA[i]].X - w[j][0]*geometry[numB[i]].X;
2823                 y = geometry[numA[i]].Y - w[j][1]*geometry[numB[i]].Y;
2824                 z = geometry[numA[i]].Z - w[j][2]*geometry[numB[i]].Z;
2825                 d[j] += x*x + y*y + z*z;
2826                 }
2827         }
2828         double dmin = d[0];
2829 	int jmin = 0;
2830         for (j=1;j<N;j++) if(dmin>d[j]) {dmin=d[j]; jmin = j;}
2831         for (i=0;i<nA;i++)
2832 	{
2833                 geometry[numB[i]].X *=  w[jmin][0];
2834                 geometry[numB[i]].Y *=  w[jmin][1];
2835                 geometry[numB[i]].Z *=  w[jmin][2];
2836 
2837                 geometry0[numB[i]].X *=  w[jmin][0];
2838                 geometry0[numB[i]].Y *=  w[jmin][1];
2839                 geometry0[numB[i]].Z *=  w[jmin][2];
2840 	}
2841 
2842 
2843 	RebuildGeom = TRUE;
2844 }
2845 /********************************************************************************/
2846 /* type = 0 all atoms, type = 1 selected atoms, type = 2 not selected atoms */
set_xyz_to_standard_orientation(gint type)2847 static void set_xyz_to_standard_orientation(gint type)
2848 {
2849 	gint i,j;
2850 
2851 	gdouble* X;
2852 	gdouble* Y;
2853 	gdouble* Z;
2854 	gchar** symbols;
2855 	gint nA = 0;
2856 
2857 	if(Natoms<1) return;
2858 
2859 	X = g_malloc(Natoms*sizeof(gdouble));
2860 	Y = g_malloc(Natoms*sizeof(gdouble));
2861 	Z = g_malloc(Natoms*sizeof(gdouble));
2862 	symbols = g_malloc(Natoms*sizeof(gchar*));
2863 	for(i = 0;i<Natoms;i++) symbols[i] = NULL;
2864 
2865 	j = 0;
2866 	for(i = 0;i<Natoms;i++)
2867 	{
2868 		if(type == 0 || (type==1 && if_selected(i))  || (type==2 && !if_selected(i)))
2869 		{
2870 			X[j] = geometry[i].X;
2871 			Y[j] = geometry[i].Y;
2872 			Z[j] = geometry[i].Z;
2873 			symbols[j] = g_strdup(geometry[i].Prop.symbol);
2874 			j++;
2875 		}
2876 	}
2877 
2878 	buildStandardOrientation(j, symbols, X, Y, Z);
2879 
2880 	j = 0;
2881 	for(i = 0;i<Natoms;i++)
2882 	{
2883 		if(type == 0 || (type==1 && if_selected(i))  || (type==2 && !if_selected(i)))
2884 		{
2885 			geometry0[i].X = X[j];
2886 			geometry0[i].Y = Y[j];
2887 			geometry0[i].Z = Z[j];
2888 
2889 			geometry[i].X = X[j];
2890 			geometry[i].Y = Y[j];
2891 			geometry[i].Z = Z[j];
2892 			j++;
2893 		}
2894 	}
2895 
2896 	if(symbols) for(i = 0;i<Natoms;i++) if(symbols[i]) g_free(symbols[i]);
2897 	if(symbols) g_free(symbols);
2898 
2899 	if(X) g_free(X);
2900 	if(Y) g_free(Y);
2901 	if(Z) g_free(Z);
2902 
2903 	RebuildGeom = TRUE;
2904 }
2905 /********************************************************************************/
set_xyz_to_standard_orientation_all()2906 void set_xyz_to_standard_orientation_all()
2907 {
2908 	set_xyz_to_standard_orientation(0);
2909 	create_GeomXYZ_from_draw_grometry();
2910 	init_quat(Quat);
2911 	RebuildGeom = TRUE;
2912 	drawGeom();
2913 }
2914 /********************************************************************************/
set_xyz_to_standard_orientation_selected_atoms()2915 void set_xyz_to_standard_orientation_selected_atoms()
2916 {
2917 	set_xyz_to_standard_orientation(1);
2918 	create_GeomXYZ_from_draw_grometry();
2919 	init_quat(Quat);
2920 	RebuildGeom = TRUE;
2921 	drawGeom();
2922 }
2923 /********************************************************************************/
set_xyz_to_standard_orientation_not_selected_atoms()2924 void set_xyz_to_standard_orientation_not_selected_atoms()
2925 {
2926 	set_xyz_to_standard_orientation(2);
2927 	create_GeomXYZ_from_draw_grometry();
2928 	init_quat(Quat);
2929 	RebuildGeom = TRUE;
2930 	drawGeom();
2931 }
2932 /********************************************************************************/
set_xyz_to_standard_orientation_selected_and_not_selected_atoms()2933 void set_xyz_to_standard_orientation_selected_and_not_selected_atoms()
2934 {
2935 	set_xyz_to_standard_orientation(1);
2936 	set_xyz_to_standard_orientation(2);
2937 	rotate_slected_atoms_minimize_rmsd();
2938 	create_GeomXYZ_from_draw_grometry();
2939 	init_quat(Quat);
2940 	RebuildGeom = TRUE;
2941 	drawGeom();
2942 }
2943 /********************************************************************************/
set_xyz_to_principal_axes_of_selected_atoms(gpointer data,guint Operation,GtkWidget * wid)2944 void set_xyz_to_principal_axes_of_selected_atoms(gpointer data, guint Operation,GtkWidget* wid)
2945 {
2946 	gdouble axis1[3] = {1,0,0};
2947 	gdouble axis2[3] = {0,1,0};
2948 	gdouble axis3[3] = {0,0,1};
2949 	gdouble C[3] = {0,0,0};
2950 	int nFrag = compute_fragment_principal_axes(axis1,axis2,axis3,C,TRUE);
2951 	if(nFrag <2 ) return;
2952 	set_origin_to_point(C);
2953 	if(Operation == 0) set_geom_to_axes(axis1, axis2, axis3);
2954 	else set_geom_to_axes(axis3, axis2, axis1);
2955 	create_GeomXYZ_from_draw_grometry();
2956 	init_quat(Quat);
2957 	RebuildGeom = TRUE;
2958 	drawGeom();
2959 }
2960 /********************************************************************************/
create_tolerance_window(GtkWidget * w,gpointer data)2961 void create_tolerance_window(GtkWidget*w, gpointer data)
2962 {
2963 	createToleranceWindow(GeomDlg, NULL);
2964 }
2965 /********************************************************************************/
get_abelian_orientation_with_reduction(GtkWidget * w,gpointer data)2966 void get_abelian_orientation_with_reduction(GtkWidget*w, gpointer data)
2967 {
2968 	gchar** symbols = NULL;
2969 	gdouble* X = NULL;
2970 	gdouble* Y = NULL;
2971 	gdouble* Z = NULL;
2972 	gint i;
2973 	gint numberOfAtoms = Natoms;
2974 	gchar pointGroupSymbol[BSIZE];
2975 	gchar abelianPointGroupSymbol[BSIZE];
2976 
2977 	if(Natoms<1)
2978 	{
2979 		 Message(_("Sorry, the number of atoms is not positive"),_("Error"),TRUE);
2980 		return;
2981 	}
2982 	symbols = (gchar**)g_malloc(sizeof(gchar*)*(Natoms));
2983 	if(symbols == NULL) return;
2984 
2985 	X = (gdouble*)g_malloc(sizeof(gdouble)*(Natoms));
2986 	if(X == NULL) return;
2987 	Y = (gdouble*)g_malloc(sizeof(gdouble)*(Natoms));
2988 	if(Y == NULL) return;
2989 	Z = (gdouble*)g_malloc(sizeof(gdouble)*(Natoms));
2990 	if(Z == NULL) return;
2991 
2992 	for (i=0;i<(gint)Natoms;i++)
2993 	{
2994 		symbols[i] = g_strdup(geometry0[i].Prop.symbol);
2995 		X[i] = geometry0[i].X*BOHR_TO_ANG;
2996 		Y[i] = geometry0[i].Y*BOHR_TO_ANG;
2997 		Z[i] = geometry0[i].Z*BOHR_TO_ANG;
2998 	}
2999 	createGeometryAbelianGroupWindow(numberOfAtoms, symbols, X, Y, Z, pointGroupSymbol, abelianPointGroupSymbol);
3000 
3001 	for (i=0;i<(gint)Natoms;i++)
3002 		g_free( symbols[i]);
3003 	g_free( symbols);
3004 	g_free(X);
3005 	g_free(Y);
3006 	g_free(Z);
3007 	return;
3008 }
3009 /********************************************************************************/
get_standard_orientation_with_reduction(GtkWidget * w,gpointer data)3010 void get_standard_orientation_with_reduction(GtkWidget*w, gpointer data)
3011 {
3012 	gchar** symbols = NULL;
3013 	gdouble* X = NULL;
3014 	gdouble* Y = NULL;
3015 	gdouble* Z = NULL;
3016 	gint i;
3017 	gint numberOfAtoms = Natoms;
3018 	gchar groupeSymbol[BSIZE];
3019 
3020 	if(Natoms<1)
3021 	{
3022 		 Message(_("Sorry, the number of atoms is not positive"),_("Error"),TRUE);
3023 		return;
3024 	}
3025 	symbols = (gchar**)g_malloc(sizeof(gchar*)*(Natoms));
3026 	if(symbols == NULL) return;
3027 
3028 	X = (gdouble*)g_malloc(sizeof(gdouble)*(Natoms));
3029 	if(X == NULL) return;
3030 	Y = (gdouble*)g_malloc(sizeof(gdouble)*(Natoms));
3031 	if(Y == NULL) return;
3032 	Z = (gdouble*)g_malloc(sizeof(gdouble)*(Natoms));
3033 	if(Z == NULL) return;
3034 
3035 	for (i=0;i<(gint)Natoms;i++)
3036 	{
3037 		symbols[i] = g_strdup(geometry0[i].Prop.symbol);
3038 		X[i] = geometry0[i].X*BOHR_TO_ANG;
3039 		Y[i] = geometry0[i].Y*BOHR_TO_ANG;
3040 		Z[i] = geometry0[i].Z*BOHR_TO_ANG;
3041 	}
3042 	createGeometrySymmetryWindow(numberOfAtoms,symbols,X, Y, Z, groupeSymbol);
3043 
3044 	for (i=0;i<(gint)Natoms;i++)
3045 		g_free( symbols[i]);
3046 	g_free( symbols);
3047 	g_free(X);
3048 	g_free(Y);
3049 	g_free(Z);
3050 	return;
3051 }
3052 /********************************************************************************/
get_standard_orientation_with_symmetrization(GtkWidget * w,gpointer data)3053 void get_standard_orientation_with_symmetrization(GtkWidget*w, gpointer data)
3054 {
3055 	gchar** symbols = NULL;
3056 	gdouble* X = NULL;
3057 	gdouble* Y = NULL;
3058 	gdouble* Z = NULL;
3059 	gint i;
3060 	gint numberOfAtoms = Natoms;
3061 	gchar groupeSymbol[BSIZE];
3062 
3063 	if(Natoms<1)
3064 	{
3065 		 Message(_("Sorry, the number of atoms is not positive"),_("Error"),TRUE);
3066 		return;
3067 	}
3068 	symbols = (gchar**)g_malloc(sizeof(gchar*)*(Natoms));
3069 	if(symbols == NULL) return;
3070 
3071 	X = (gdouble*)g_malloc(sizeof(gdouble)*(Natoms));
3072 	if(X == NULL) return;
3073 	Y = (gdouble*)g_malloc(sizeof(gdouble)*(Natoms));
3074 	if(Y == NULL) return;
3075 	Z = (gdouble*)g_malloc(sizeof(gdouble)*(Natoms));
3076 	if(Z == NULL) return;
3077 
3078 	for (i=0;i<(gint)Natoms;i++)
3079 	{
3080 		symbols[i] = g_strdup(geometry0[i].Prop.symbol);
3081 		X[i] = geometry0[i].X*BOHR_TO_ANG;
3082 		Y[i] = geometry0[i].Y*BOHR_TO_ANG;
3083 		Z[i] = geometry0[i].Z*BOHR_TO_ANG;
3084 	}
3085 	createGeometrySymmetrizationWindow(numberOfAtoms,symbols,X, Y, Z, groupeSymbol);
3086 
3087 // reset geometry0
3088 	for(i = 0;i<numberOfAtoms;i++)
3089 	{
3090 		g_free(geometry0[i].Prop.symbol);
3091 		geometry0[i].Prop = prop_atom_get(symbols[i]);
3092 		geometry0[i].mmType = g_strdup(symbols[i]);
3093 		geometry0[i].pdbType = g_strdup(symbols[i]);
3094 		geometry0[i].Residue = g_strdup(symbols[i]);
3095 		geometry0[i].Charge = 0.0;
3096 		geometry0[i].X = X[i]/BOHR_TO_ANG;
3097 		geometry0[i].Y = Y[i]/BOHR_TO_ANG;
3098 		geometry0[i].Z = Z[i]/BOHR_TO_ANG;
3099 
3100 		g_free(geometry[i].Prop.symbol);
3101 		geometry[i].Prop = prop_atom_get(symbols[i]);
3102 		geometry[i].mmType = g_strdup(symbols[i]);
3103 		geometry[i].pdbType = g_strdup(symbols[i]);
3104 		geometry[i].Residue = g_strdup(symbols[i]);
3105 		geometry[i].Charge = 0.0;
3106 		geometry[i].X = geometry0[i].X;
3107 		geometry[i].Y = geometry0[i].Y;
3108 		geometry[i].Z = geometry0[i].Z;
3109 	}
3110 	resetConnections();
3111 	create_GeomXYZ_from_draw_grometry();
3112 	for (i=0;i<(gint)Natoms;i++) g_free( symbols[i]);
3113 	g_free( symbols);
3114 	g_free(X);
3115 	g_free(Y);
3116 	g_free(Z);
3117 	return;
3118 }
3119 /********************************************************************************/
set_key_press(GtkWidget * wid,GdkEventKey * event,gpointer data)3120 static gint set_key_press(GtkWidget* wid, GdkEventKey *event, gpointer data)
3121 {
3122 	if((event->keyval == GDK_Shift_L || event->keyval == GDK_Shift_R) )
3123 		ShiftKeyPressed = TRUE;
3124 	else if((event->keyval == GDK_Control_L || event->keyval == GDK_Control_R) )
3125 	{
3126 		ControlKeyPressed = TRUE;
3127 	}
3128 	else if((event->keyval == GDK_Alt_L || event->keyval == GDK_Alt_R) )
3129 	{
3130 		ControlKeyPressed = TRUE;
3131 	}
3132 	else if((event->keyval == GDK_F || event->keyval == GDK_f) )
3133 	{
3134 		FKeyPressed = TRUE;
3135 	}
3136 	else if((event->keyval == GDK_G || event->keyval == GDK_g) )
3137 	{
3138 		GKeyPressed = TRUE;
3139 	}
3140 	else if((event->keyval == GDK_A || event->keyval == GDK_a)  && ControlKeyPressed)
3141 	{
3142 		SelectAllAtoms();
3143 	}
3144 	else if((event->keyval == GDK_u || event->keyval == GDK_U))
3145 	{
3146         	switch(OperationType)
3147         	{
3148 			case MOVEFRAG :
3149 			case DELETEOBJECTS :
3150 			case MEASURE     :
3151 			case EDITOBJECTS :
3152 			case ADDFRAGMENT :
3153 			case ROTLOCFRAG :
3154 			case ROTZLOCFRAG :
3155 				get_geometry_from_fifo( event->keyval == GDK_U);
3156 				drawGeom();
3157 				break;
3158 			default:break;
3159 		}
3160 	}
3161 	else if((event->keyval == GDK_z || event->keyval == GDK_y) && ControlKeyPressed)
3162 	{
3163         	switch(OperationType)
3164         	{
3165 			case MOVEFRAG :
3166 			case DELETEOBJECTS :
3167 			case MEASURE     :
3168 			case EDITOBJECTS :
3169 			case ADDFRAGMENT :
3170 			case ROTLOCFRAG :
3171 			case ROTZLOCFRAG :
3172 				get_geometry_from_fifo(event->keyval == GDK_y);
3173 				drawGeom();
3174 				break;
3175 			default:break;
3176 		}
3177 	}
3178 	GTK_WIDGET_GET_CLASS(wid)->key_press_event(wid, event);
3179 	return TRUE;
3180 
3181 }
3182 /********************************************************************************/
set_key_release(GtkWidget * wid,GdkEventKey * event,gpointer data)3183 static gint set_key_release(GtkWidget* wid, GdkEventKey *event, gpointer data)
3184 {
3185 	if((event->keyval == GDK_Shift_L || event->keyval == GDK_Shift_R) )
3186 		ShiftKeyPressed = FALSE;
3187 	else if((event->keyval == GDK_Control_L || event->keyval == GDK_Control_R) )
3188 		ControlKeyPressed = FALSE;
3189 	else if((event->keyval == GDK_Alt_L || event->keyval == GDK_Alt_R) )
3190 		ControlKeyPressed = FALSE;
3191 	else if((event->keyval == GDK_F || event->keyval == GDK_f) )
3192 		FKeyPressed = FALSE;
3193 	else if((event->keyval == GDK_G || event->keyval == GDK_g) )
3194 		GKeyPressed = FALSE;
3195 	return TRUE;
3196 }
3197 /********************************************************************************/
setMMTypesChargesFromPDBTpl(guint Operation)3198 void setMMTypesChargesFromPDBTpl(guint Operation)
3199 {
3200 	gint i;
3201 	gchar* mmType = NULL;
3202 	gdouble charge = 0.0;
3203 	for(i=0;i<(gint)Natoms;i++)
3204 	{
3205 		if(Operation!=3)
3206 		{
3207 			mmType = getMMTypeFromPDBTpl(geometry[i].Residue,geometry[i].pdbType,&charge);
3208 			if(!strcmp(mmType,"UNK"))
3209 			{
3210 				g_free(mmType);
3211 				continue;
3212 			}
3213 		}
3214 		switch(Operation)
3215 		{
3216 			case 0: geometry[i].Charge = charge;
3217 				geometry0[i].Charge = charge;
3218 				break;
3219 			case 1: g_free(geometry[i].mmType);
3220 				g_free(geometry0[i].mmType);
3221 				geometry[i].mmType = g_strdup(mmType);
3222 				geometry0[i].mmType = g_strdup(mmType);
3223 				break;
3224 			case 2: g_free(geometry[i].mmType);
3225 				g_free(geometry0[i].mmType);
3226 				geometry[i].mmType = g_strdup(mmType);
3227 				geometry0[i].mmType = g_strdup(mmType);
3228 				geometry[i].Charge = charge;
3229 				geometry0[i].Charge = charge;
3230 				break;
3231 			case 3:geometry[i].Charge = charge;
3232 			       geometry0[i].Charge = charge;
3233 			       break;
3234 			default: break;
3235 		}
3236 		if(Operation!=3) g_free(mmType);
3237 	}
3238 }
3239 /********************************************************************************/
setMMTypesCharges(gpointer data,guint Operation,GtkWidget * wid)3240 void setMMTypesCharges(gpointer data, guint Operation,GtkWidget* wid)
3241 {
3242 	if(Operation==4)
3243 	{
3244 		gint i;
3245 		calculTypesAmber(geometry, (gint)Natoms);
3246 		for(i=0;i<(gint)Natoms;i++)
3247 		{
3248 			geometry0[i].mmType = g_strdup(geometry[i].mmType);
3249 			geometry0[i].pdbType = g_strdup(geometry[i].pdbType);
3250 		}
3251 	}
3252 	else setMMTypesChargesFromPDBTpl(Operation);
3253 	create_GeomXYZ_from_draw_grometry();
3254 	drawGeom();
3255 }
3256 /*****************************************************************************/
Free_One_Geom(GeomDef * geom,gint N)3257 GeomDef* Free_One_Geom(GeomDef* geom,gint N)
3258 {
3259 	gint i;
3260 	if(!geom)  return NULL;
3261 	for (i=0;i<N;i++)
3262 	{
3263 		g_free(geom[i].Prop.name);
3264 		g_free(geom[i].Prop.symbol);
3265 		g_free(geom[i].mmType);
3266 		g_free(geom[i].pdbType);
3267 		g_free(geom[i].Residue);
3268 		if(geom[i].typeConnections) g_free(geom[i].typeConnections);
3269 	}
3270 	g_free(geom);
3271 	return NULL;
3272 }
3273 /*****************************************************************************/
free_text_to_draw()3274 void free_text_to_draw()
3275 {
3276 	if(strToDraw)
3277 		g_free(strToDraw);
3278 	strToDraw = NULL;
3279 }
3280 /*****************************************************************************/
set_text_to_draw(gchar * str)3281 void set_text_to_draw(gchar* str)
3282 {
3283 	free_text_to_draw();
3284 
3285 	strToDraw = g_strdup(str);
3286 }
3287 /********************************************************************************/
set_statubar_operation_str(gchar * str)3288 void set_statubar_operation_str(gchar* str)
3289 {
3290 	if(str && GeomDrawingArea)
3291 	{
3292 		gtk_statusbar_pop(GTK_STATUSBAR(StatusOperation),idStatusOperation);
3293 		gtk_statusbar_push(GTK_STATUSBAR(StatusOperation),idStatusOperation,str);
3294 	}
3295 }
3296 /*****************************************************************************/
draw_text(gchar * str)3297 void draw_text(gchar* str)
3298 {
3299 	V4d color  = {1.0,1.0,1.0,1.0 };
3300 	gdouble x  = GeomDrawingArea->allocation.width/20.0;
3301 	gdouble y  = GeomDrawingArea->allocation.height-GeomDrawingArea->allocation.height/10.0;
3302 	gdouble w[3];
3303 
3304 	//glInitFontsUsingOld(FontsStyleLabel.fontname);
3305 	glInitFontsUsing(FontsStyleLabel.fontname, &ft2_context);
3306 	color[0] = FontsStyleLabel.TextColor.red/65535.0;
3307 	color[1] = FontsStyleLabel.TextColor.green/65535.0;
3308 	color[2] = FontsStyleLabel.TextColor.blue/65535.0;
3309 	glDisable ( GL_LIGHTING ) ;
3310 	glColor4dv(color);
3311 	getW(x,y,w);
3312 	/* glPrintOrthoOld(w[0], w[1], w[2], str,FALSE,TRUE);*/
3313 	glPrintOrtho(w[0], w[1], w[2], str,FALSE,TRUE, ft2_context);
3314 	glEnable ( GL_LIGHTING ) ;
3315 	glDeleteFontsList();
3316 
3317 }
3318 /*****************************************************************************/
select_atoms_by_groupe()3319 gboolean select_atoms_by_groupe()
3320 {
3321 	gint i;
3322 	gdouble x1=0;
3323 	gdouble y1=0;
3324 	gdouble xi;
3325 	gdouble yi;
3326 	gdouble zi;
3327 	gdouble d = 0;
3328 	gint j;
3329 	gint k;
3330 	gboolean OK = FALSE;
3331 	gdouble w[3];
3332 	gdouble rayon;
3333 
3334 	x1 = BeginX;
3335 	y1 = BeginY;
3336 
3337 	glGetWorldCoordinates(x1,y1,w);
3338 
3339 	for(i=0;i<(gint)Natoms;i++)
3340 	{
3341 		if(!geometry[i].show) continue;
3342 		xi = w[0]-geometry[i].X;
3343 		yi = w[1]-geometry[i].Y;
3344 		zi = w[2]-geometry[i].Z;
3345 		d = xi*xi + yi*yi + zi*zi;
3346 		rayon = get_rayon_selection(i);
3347 		if(d<=rayon*rayon)
3348 		{
3349 			if(NumFatoms == NULL) NumFatoms = g_malloc((NFatoms+1)*sizeof(gint));
3350 			else NumFatoms = g_realloc(NumFatoms, (NFatoms+1)*sizeof(gint));
3351 			NumFatoms[NFatoms] = geometry[i].N;
3352 			NFatoms+=1;
3353 
3354 			for(j=0;j<(gint)Natoms;j++)
3355 			{
3356 				if(get_connection_type(i,j)>0)
3357 				{
3358 
3359 					gint nGroupAtoms=0;
3360 					gint * listGroupAtoms = getListGroupe(&nGroupAtoms, geometry0, Natoms, i, j,-1,-1);
3361 					if(NumFatoms == NULL) NumFatoms = g_malloc((NFatoms+nGroupAtoms+1)*sizeof(gint));
3362 					else NumFatoms = g_realloc(NumFatoms, (NFatoms+nGroupAtoms+1)*sizeof(gint));
3363 
3364 					NumFatoms[NFatoms] = geometry[j].N;
3365 					for(k=NFatoms+1;k<NFatoms+nGroupAtoms+1;k++)
3366 						NumFatoms[k] = geometry[listGroupAtoms[k-NFatoms-1]].N;
3367 					NFatoms+=nGroupAtoms+1;
3368 					if(listGroupAtoms) g_free(listGroupAtoms);
3369 					OK = TRUE;
3370 				}
3371 			}
3372 			break;
3373 
3374 		}
3375 	}
3376 	drawGeom();
3377 	return OK;
3378 }
3379 /*****************************************************************************/
select_atoms_by_residues()3380 gboolean select_atoms_by_residues()
3381 {
3382 	gint i;
3383 	gdouble x1=0;
3384 	gdouble y1=0;
3385 	gdouble xi;
3386 	gdouble yi;
3387 	gdouble zi;
3388 	gdouble d = 0;
3389 	gint j;
3390 	gint k;
3391 	gboolean del = FALSE;
3392 	gint selectedj;
3393 	gboolean OK = FALSE;
3394 	gdouble rayon;
3395 	gdouble w[3];
3396 
3397 
3398 	x1 = BeginX;
3399 	y1 = BeginY;
3400 	glGetWorldCoordinates(x1,y1,w);
3401 
3402 	for(i=0;i<(gint)Natoms;i++)
3403 	{
3404 		if(!geometry[i].show) continue;
3405 		xi = w[0]-geometry[i].X;
3406 		yi = w[1]-geometry[i].Y;
3407 		zi = w[2]-geometry[i].Z;
3408 		d = xi*xi + yi*yi + zi*zi;
3409 		rayon = get_rayon_selection(i);
3410 		if(d<=rayon*rayon)
3411 		{
3412 			OK = TRUE;
3413 			del = if_selected(i);
3414 			for(j=0;j<(gint)Natoms;j++)
3415 			{
3416 				if(geometry[i].ResidueNumber == geometry[j].ResidueNumber)
3417 				{
3418 					selectedj = index_selected(j);
3419 					if(selectedj<0 && !del)
3420 					{
3421 						if(NumFatoms == NULL)
3422 							NumFatoms = g_malloc((NFatoms+1)*sizeof(gint));
3423 						else
3424 							NumFatoms = g_realloc(NumFatoms,
3425 									(NFatoms+1)*sizeof(gint));
3426 						NumFatoms[NFatoms] = geometry[j].N;
3427 						NFatoms++;
3428 					}
3429 					if(selectedj>=0 && del)
3430 					{
3431 						if((NFatoms-1)>0)
3432 						{
3433 							for(k=selectedj;k<(gint)(NFatoms-1);k++)
3434 								NumFatoms[k] = NumFatoms[k+1];
3435 
3436 							NumFatoms = g_realloc(NumFatoms,
3437 									(NFatoms-1)*sizeof(gint));
3438 							NFatoms--;
3439 						}
3440 						else
3441 						{
3442 							g_free(NumFatoms);
3443 							NumFatoms = NULL;
3444 							NFatoms = 0;
3445 						}
3446 					}
3447 
3448 				}
3449 			}
3450 			break;
3451 
3452 		}
3453 	}
3454 	drawGeom();
3455 	return OK;
3456 }
3457 /*****************************************************************************/
select_atoms_by_rectangle(gdouble x,gdouble y)3458 void select_atoms_by_rectangle(gdouble x,gdouble y)
3459 {
3460 	gint i;
3461 	gdouble x1=0;
3462 	gdouble y1=0;
3463 	gdouble x2=0;
3464 	gdouble y2=0;
3465 	gdouble xi;
3466 	gdouble yi;
3467 	GLdouble View2D[3];
3468 
3469 	if(x>BeginX)
3470 	{
3471 		x1 = BeginX;
3472 		x2 = x;
3473 	}
3474 	else
3475 	{
3476 		x1 = x;
3477 		x2 = BeginX;
3478 	}
3479 	if(y>BeginY)
3480 	{
3481 		y1 = BeginY;
3482 		y2 = y;
3483 	}
3484 	else
3485 	{
3486 		y1 = y;
3487 		y2 = BeginY;
3488 	}
3489 	if(!ShiftKeyPressed)
3490 	{
3491 		if(!NumFatoms) g_free(NumFatoms);
3492 		NumFatoms = NULL;
3493 		NFatoms = 0;
3494 	}
3495 	for(i=0;i<(gint)Natoms;i++)
3496 	{
3497 		if(!geometry[i].show) continue;
3498 		gluProject(geometry[i].X, geometry[i].Y, geometry[i].Z,mvmatrix, projmatrix, viewport, &View2D[0], &View2D[1], &View2D[2]);
3499 		xi = View2D[0];
3500 		yi = viewport[3]-View2D[1];
3501 		if(xi>=x1 && xi<=x2 && yi>=y1 && yi<=y2 && !if_selected(i))
3502 		{
3503 			if(NumFatoms == NULL) NumFatoms = g_malloc((NFatoms+1)*sizeof(gint));
3504 			else NumFatoms = g_realloc(NumFatoms,(NFatoms+1)*sizeof(gint));
3505 			NumFatoms[NFatoms] = geometry[i].N;
3506 			NFatoms++;
3507 		}
3508 	}
3509 	redraw(GeomDrawingArea);
3510 }
3511 /********************************************************************************/
draw_selection_rectangle(gdouble x,gdouble y)3512 void draw_selection_rectangle(gdouble x,gdouble y)
3513 {
3514 	xSelection = x;
3515 	ySelection = y;
3516 }
3517 /********************************************************************************/
draw_selection_circle(gdouble x,gdouble y)3518 void draw_selection_circle(gdouble x,gdouble y)
3519 {
3520 }
3521 /********************************************************************************/
delete_molecule()3522 static void delete_molecule()
3523 {
3524 	if(Natoms<1) return;
3525 
3526 	add_geometry_to_fifo();
3527 	geometry0 =Free_One_Geom(geometry0,Natoms);
3528 	geometry =Free_One_Geom(geometry,Natoms);
3529 	Natoms = 0;
3530 
3531 	if(NumFatoms) g_free(NumFatoms);
3532   	NumFatoms = NULL;
3533   	NFatoms = 0;
3534 
3535 	create_GeomXYZ_from_draw_grometry();
3536 
3537 	Ddef = FALSE;
3538 	RebuildGeom=TRUE;
3539 	drawGeom();
3540 	set_statubar_pop_sel_atom();
3541 	free_text_to_draw();
3542 	change_of_center(NULL,NULL);
3543 	reset_origine_molecule_drawgeom();
3544 }
3545 /********************************************************************************/
copySelectedAtoms()3546 void copySelectedAtoms()
3547 {
3548 	Fragment F;
3549 	gint i;
3550 	gint k;
3551 
3552 	if(Frag.NAtoms) FreeFragment(&Frag);
3553 	Frag.NAtoms = 0;
3554 	Frag.Atoms = NULL;
3555 	if(NFatoms<1) return;
3556 	F.NAtoms = NFatoms;
3557 	F.Atoms = g_malloc(F.NAtoms*sizeof(Atom));
3558 
3559 	for (k=0;k<(gint)NFatoms;k++)
3560 	{
3561 		for (i=0;i<(gint)Natoms;i++)
3562 		{
3563 			if(NumFatoms[k]==geometry[i].N)
3564 			{
3565 				F.Atoms[k].Symb=g_strdup(geometry[i].Prop.symbol);
3566 				F.Atoms[k].mmType=g_strdup(geometry[i].mmType);
3567 				F.Atoms[k].pdbType=g_strdup(geometry[i].pdbType);
3568 				F.Atoms[k].Residue = g_strdup(geometry[i].Residue);
3569 				F.Atoms[k].Coord[0]=geometry[i].X;
3570 				F.Atoms[k].Coord[1]=geometry[i].Y;
3571 				F.Atoms[k].Coord[2]=geometry[i].Z;
3572 				F.Atoms[k].Charge=geometry[i].Charge;
3573 				break;
3574 			}
3575 		}
3576 		if(i==Natoms) break;
3577 	}
3578 	if(k!=NFatoms)
3579 	{
3580 		if(F.Atoms) g_free(F.Atoms);
3581 		return;
3582 	}
3583 
3584 	F.atomToDelete = -1;
3585 	F.atomToBondTo = -1;
3586 	F.angleAtom    = -1;
3587 
3588 	CenterFrag(&F);
3589 
3590 	Frag = F;
3591 	SetOperation (NULL,ADDFRAGMENT);
3592 }
3593 /********************************************************************************/
freeList(gchar ** strs,gint nlist)3594 static gchar** freeList(gchar** strs, gint nlist)
3595 {
3596 	gint i;
3597 
3598 	for(i=0;i<nlist;i++)
3599 		if(strs[i])
3600 			g_free(strs[i]);
3601 
3602 	g_free(strs);
3603 
3604 	return NULL;
3605 }
3606 /********************************************************************************/
setMMTypeOfselectedAtoms(GtkWidget * button,GtkWidget * entry)3607 static void setMMTypeOfselectedAtoms(GtkWidget* button, GtkWidget* entry)
3608 {
3609 	gint i;
3610 	gint k = 0;
3611 	G_CONST_RETURN gchar *tName;
3612 
3613 
3614 	if(Natoms<1) return;
3615 	tName = gtk_entry_get_text(GTK_ENTRY(entry));
3616 	if(strlen(tName)<1) return;
3617 	if(NFatoms<1) return;
3618 	if(!NumFatoms) return;
3619 
3620 	for (k=0;k<(gint)NFatoms;k++)
3621 	for (i=0;i<(gint)Natoms;i++)
3622 	{
3623 		if(geometry[i].N== NumFatoms[k])
3624 		{
3625 			if(geometry[i].mmType) g_free(geometry[i].mmType);
3626 			geometry[i].mmType = g_strdup(tName);
3627 			if(geometry0[i].mmType) g_free(geometry0[i].mmType);
3628 			geometry0[i].mmType = g_strdup(tName);
3629 		}
3630 	}
3631 	create_GeomXYZ_from_draw_grometry();
3632 	if(!strcmp(tName,"N3")) reset_all_connections();
3633 	drawGeom();
3634 }
3635 /********************************************************************************/
setMMTypeOfselectedAtomsDlg()3636 void setMMTypeOfselectedAtomsDlg()
3637 {
3638 	GtkWidget *winDlg;
3639 	GtkWidget *button;
3640 	GtkWidget *hbox;
3641 	GtkWidget *entry;
3642 	GtkWidget *frame;
3643 	GtkWidget *vboxframe;
3644 	gint n=0;
3645 	gchar** t = NULL;
3646 	gchar tmp[100] = "UNK";
3647 	gint i;
3648 	gint k;
3649 
3650 	if(Natoms<1) return;
3651 	if(NFatoms<1) return;
3652 	if(!NumFatoms) return;
3653 
3654 	k=0;
3655 	for (i=0;i<(gint)Natoms;i++)
3656 	{
3657 		if(geometry[i].N == NumFatoms[k])
3658 		{
3659 			sprintf(tmp,"%s",geometry[i].mmType);
3660 			break;
3661 		}
3662 	}
3663 
3664 	winDlg = gtk_dialog_new();
3665 	gtk_window_set_title(GTK_WINDOW(winDlg),_("Set MM Type of selected atoms"));
3666 	gtk_window_set_position(GTK_WINDOW(winDlg),GTK_WIN_POS_CENTER);
3667 	gtk_window_set_transient_for(GTK_WINDOW(winDlg),GTK_WINDOW(GeomDlg));
3668 
3669 	add_child(GeomDlg,winDlg,gtk_widget_destroy,_(" Set Sel. Type."));
3670 	g_signal_connect(G_OBJECT(winDlg),"delete_event",(GCallback)delete_child,NULL);
3671 
3672 	frame = gtk_frame_new (NULL);
3673 	gtk_frame_set_shadow_type( GTK_FRAME(frame),GTK_SHADOW_ETCHED_OUT);
3674 
3675 	gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
3676 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->vbox), frame,TRUE,TRUE,0);
3677 
3678 	gtk_widget_show (frame);
3679 
3680 	vboxframe = create_vbox(frame);
3681 	hbox=create_hbox_false(vboxframe);
3682 	n=0;
3683 	t = getListGeomMMTypes(&n);
3684 	entry = create_label_combo(hbox,_(" Type Name : "),t,n, TRUE,-1,-1);
3685 	if(strcmp(tmp,"UNK")) gtk_entry_set_text(GTK_ENTRY(entry),tmp);
3686 	gtk_editable_set_editable((GtkEditable*) entry,TRUE);
3687 	if(t) freeList(t,n);
3688 
3689 	gtk_widget_realize(winDlg);
3690 
3691 	button = create_button(winDlg,_("Cancel"));
3692 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->action_area), button,TRUE,TRUE,0);
3693 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)delete_child,GTK_OBJECT(winDlg));
3694 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
3695 
3696 	button = create_button(winDlg,_("OK"));
3697 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->action_area), button,TRUE,TRUE,0);
3698 	g_signal_connect(G_OBJECT(button), "clicked",(GCallback)setMMTypeOfselectedAtoms,entry);
3699 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)delete_child,GTK_OBJECT(winDlg));
3700 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
3701 	gtk_widget_grab_default(button);
3702 
3703 
3704 	gtk_widget_show_all(winDlg);
3705 }
3706 /********************************************************************************/
setPDBTypeOfselectedAtoms(GtkWidget * button,GtkWidget * entry)3707 static void setPDBTypeOfselectedAtoms(GtkWidget* button, GtkWidget* entry)
3708 {
3709 	gint i;
3710 	gint k = 0;
3711 	G_CONST_RETURN gchar *tName;
3712 
3713 
3714 	if(Natoms<1) return;
3715 	tName = gtk_entry_get_text(GTK_ENTRY(entry));
3716 	if(strlen(tName)<1) return;
3717 	if(NFatoms<1) return;
3718 	if(!NumFatoms) return;
3719 
3720 	for (k=0;k<(gint)NFatoms;k++)
3721 	for (i=0;i<(gint)Natoms;i++)
3722 	{
3723 		if(geometry[i].N== NumFatoms[k])
3724 		{
3725 			if(geometry[i].pdbType) g_free(geometry[i].pdbType);
3726 			geometry[i].pdbType = g_strdup(tName);
3727 			if(geometry0[i].pdbType) g_free(geometry0[i].pdbType);
3728 			geometry0[i].pdbType = g_strdup(tName);
3729 		}
3730 	}
3731 	create_GeomXYZ_from_draw_grometry();
3732 	drawGeom();
3733 }
3734 /********************************************************************************/
setPDBTypeOfselectedAtomsDlg()3735 void setPDBTypeOfselectedAtomsDlg()
3736 {
3737 	GtkWidget *winDlg;
3738 	GtkWidget *button;
3739 	GtkWidget *hbox;
3740 	GtkWidget *entry;
3741 	GtkWidget *frame;
3742 	GtkWidget *vboxframe;
3743 	gint n=0;
3744 	gchar** t = NULL;
3745 	gchar tmp[100] = "UNK";
3746 	gint i;
3747 	gint k;
3748 
3749 	if(Natoms<1) return;
3750 	if(NFatoms<1) return;
3751 	if(!NumFatoms) return;
3752 
3753 	k=0;
3754 	for (i=0;i<(gint)Natoms;i++)
3755 	{
3756 		if(geometry[i].N == NumFatoms[k])
3757 		{
3758 			sprintf(tmp,"%s",geometry[i].pdbType);
3759 			break;
3760 		}
3761 	}
3762 
3763 	winDlg = gtk_dialog_new();
3764 	gtk_window_set_title(GTK_WINDOW(winDlg),_("Set PDB Type of selected atoms"));
3765 	gtk_window_set_position(GTK_WINDOW(winDlg),GTK_WIN_POS_CENTER);
3766 	gtk_window_set_transient_for(GTK_WINDOW(winDlg),GTK_WINDOW(GeomDlg));
3767 
3768 	add_child(GeomDlg,winDlg,gtk_widget_destroy,_(" Set Sel. Type."));
3769 	g_signal_connect(G_OBJECT(winDlg),"delete_event",(GCallback)delete_child,NULL);
3770 
3771 	frame = gtk_frame_new (NULL);
3772 	gtk_frame_set_shadow_type( GTK_FRAME(frame),GTK_SHADOW_ETCHED_OUT);
3773 
3774 	gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
3775 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->vbox), frame,TRUE,TRUE,0);
3776 
3777 	gtk_widget_show (frame);
3778 
3779 	vboxframe = create_vbox(frame);
3780 	hbox=create_hbox_false(vboxframe);
3781 	n=0;
3782 	t = getListPDBTypesFromGeom(&n);
3783 	entry = create_label_combo(hbox,_(" Type Name : "),t,n, TRUE,-1,-1);
3784 	if(strcmp(tmp,"UNK")) gtk_entry_set_text(GTK_ENTRY(entry),tmp);
3785 	gtk_editable_set_editable((GtkEditable*) entry,TRUE);
3786 	if(t) freeList(t,n);
3787 
3788 	gtk_widget_realize(winDlg);
3789 
3790 	button = create_button(winDlg,_("Cancel"));
3791 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->action_area), button,TRUE,TRUE,0);
3792 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)delete_child,GTK_OBJECT(winDlg));
3793 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
3794 
3795 	button = create_button(winDlg,_("OK"));
3796 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->action_area), button,TRUE,TRUE,0);
3797 	g_signal_connect(G_OBJECT(button), "clicked",(GCallback)setPDBTypeOfselectedAtoms,entry);
3798 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)delete_child,GTK_OBJECT(winDlg));
3799 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
3800 	gtk_widget_grab_default(button);
3801 
3802 
3803 	gtk_widget_show_all(winDlg);
3804 }
3805 /********************************************************************************/
setResidueNameOfselectedAtoms(GtkWidget * button,GtkWidget * entry)3806 static void setResidueNameOfselectedAtoms(GtkWidget* button, GtkWidget* entry)
3807 {
3808 	gint i;
3809 	gint k = 0;
3810 	G_CONST_RETURN gchar *tName;
3811 
3812 
3813 	if(Natoms<1) return;
3814 	tName = gtk_entry_get_text(GTK_ENTRY(entry));
3815 	if(strlen(tName)<1) return;
3816 	if(NFatoms<1) return;
3817 	if(!NumFatoms) return;
3818 
3819 	for (k=0;k<(gint)NFatoms;k++)
3820 	for (i=0;i<(gint)Natoms;i++)
3821 	{
3822 		if(geometry[i].N== NumFatoms[k])
3823 		{
3824 			if(geometry[i].Residue) g_free(geometry[i].Residue);
3825 			geometry[i].Residue = g_strdup(tName);
3826 			if(geometry0[i].Residue) g_free(geometry0[i].Residue);
3827 			geometry0[i].Residue = g_strdup(tName);
3828 		}
3829 	}
3830 	create_GeomXYZ_from_draw_grometry();
3831 	drawGeom();
3832 }
3833 /********************************************************************************/
getResidueNameOfselectedAtoms()3834 static gchar* getResidueNameOfselectedAtoms()
3835 {
3836 	gint i;
3837 	gint k = 0;
3838 
3839 	if(Natoms<1) return g_strdup("DUM");
3840 	if(NFatoms<1) return  g_strdup("DUM");
3841 	if(!NumFatoms) return  g_strdup("DUM");
3842 
3843 	for (k=0;k<(gint)NFatoms;k++)
3844 	for (i=0;i<(gint)Natoms;i++)
3845 	{
3846 		if(geometry[i].N== NumFatoms[k])
3847 		{
3848 			 g_strdup(geometry[i].Residue);
3849 		}
3850 	}
3851 	return  g_strdup("DUM");
3852 }
3853 /********************************************************************************/
setResidueNameOfselectedAtomsDlg()3854 void setResidueNameOfselectedAtomsDlg()
3855 {
3856 	GtkWidget *winDlg;
3857 	GtkWidget *button;
3858 	GtkWidget *hbox;
3859 	GtkWidget *entry;
3860 	GtkWidget *frame;
3861 	GtkWidget *vboxframe;
3862 	gint n=0;
3863 	gchar** t = NULL;
3864 	gchar tmp[100] = "UNK";
3865 	gint i;
3866 	gint k;
3867 
3868 	if(Natoms<1) return;
3869 	if(NFatoms<1) return;
3870 	if(!NumFatoms) return;
3871 
3872 	k=0;
3873 	for (i=0;i<(gint)Natoms;i++)
3874 	{
3875 		if(geometry[i].N == NumFatoms[k])
3876 		{
3877 			sprintf(tmp,"%s",geometry[i].pdbType);
3878 			break;
3879 		}
3880 	}
3881 
3882 	winDlg = gtk_dialog_new();
3883 	gtk_window_set_title(GTK_WINDOW(winDlg),_("Set Residue name of selected atoms"));
3884 	gtk_window_set_position(GTK_WINDOW(winDlg),GTK_WIN_POS_CENTER);
3885 	gtk_window_set_transient_for(GTK_WINDOW(winDlg),GTK_WINDOW(GeomDlg));
3886 
3887 	add_child(GeomDlg,winDlg,gtk_widget_destroy,_(" Set Sel. Type."));
3888 	g_signal_connect(G_OBJECT(winDlg),"delete_event",(GCallback)delete_child,NULL);
3889 
3890 	frame = gtk_frame_new (NULL);
3891 	gtk_frame_set_shadow_type( GTK_FRAME(frame),GTK_SHADOW_ETCHED_OUT);
3892 
3893 	gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
3894 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->vbox), frame,TRUE,TRUE,0);
3895 
3896 	gtk_widget_show (frame);
3897 
3898 	vboxframe = create_vbox(frame);
3899 	hbox=create_hbox_false(vboxframe);
3900 	n=1;
3901 	t = g_malloc(sizeof(gchar*)*2);
3902 	t[0]  = NULL;
3903 	t[1]  = NULL;
3904 	t[0] = getResidueNameOfselectedAtoms();
3905 
3906 	entry = create_label_combo(hbox,_(" Residue Name : "),t,n, TRUE,-1,-1);
3907 	g_free(t[0]);
3908 	g_free(t);
3909 	if(strcmp(tmp,"UNK")) gtk_entry_set_text(GTK_ENTRY(entry),tmp);
3910 	gtk_editable_set_editable((GtkEditable*) entry,TRUE);
3911 
3912 	gtk_widget_realize(winDlg);
3913 
3914 	button = create_button(winDlg,_("Cancel"));
3915 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->action_area), button,TRUE,TRUE,0);
3916 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)delete_child,GTK_OBJECT(winDlg));
3917 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
3918 
3919 	button = create_button(winDlg,_("OK"));
3920 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->action_area), button,TRUE,TRUE,0);
3921 	g_signal_connect(G_OBJECT(button), "clicked",(GCallback)setResidueNameOfselectedAtoms,entry);
3922 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)delete_child,GTK_OBJECT(winDlg));
3923 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
3924 	gtk_widget_grab_default(button);
3925 
3926 
3927 	gtk_widget_show_all(winDlg);
3928 }
3929 /********************************************************************************/
setSymbolOfselectedAtoms(GtkWidget * button,gpointer data)3930 static void setSymbolOfselectedAtoms(GtkWidget *button,gpointer data)
3931 {
3932 	GtkWidget* winDlg  = (GtkWidget*) g_object_get_data(G_OBJECT (button), "WinDlg");
3933 	gchar* symbol = NULL;
3934 	if(data && (gchar*) data) symbol = (gchar*) data;
3935 	/* fprintf(stderr,"%s\n",symbol);*/
3936 	if(symbol && Natoms>0 && NFatoms>0 && NumFatoms)
3937 	{
3938 		gint k,i;
3939 		for (k=0;k<(gint)NFatoms;k++)
3940 		for (i=0;i<(gint)Natoms;i++)
3941 		{
3942 			if(geometry[i].N== NumFatoms[k])
3943 			{
3944 				if(geometry0[i].Prop.name) g_free(geometry0[i].Prop.name);
3945 				if(geometry0[i].Prop.symbol) g_free(geometry0[i].Prop.symbol);
3946 				geometry0[i].Prop = prop_atom_get(symbol);
3947 				if(geometry[i].Prop.name) g_free(geometry[i].Prop.name);
3948 				if(geometry[i].Prop.symbol) g_free(geometry[i].Prop.symbol);
3949 				geometry[i].Prop = prop_atom_get(symbol);
3950 			}
3951 		}
3952 		reset_all_connections();
3953         	reset_charges_multiplicities();
3954         	drawGeom();
3955         	set_optimal_geom_view();
3956         	create_GeomXYZ_from_draw_grometry();
3957 	}
3958 	gtk_widget_destroy(winDlg);
3959 }
3960 /********************************************************************************/
setSymbolOfselectedAtomsDlg()3961 void setSymbolOfselectedAtomsDlg()
3962 {
3963 	GtkWidget* Table;
3964 	GtkWidget* button;
3965 	GtkWidget* frame;
3966 	guint i;
3967 	guint j;
3968         GtkStyle *button_style;
3969         GtkStyle *style;
3970 
3971 	gchar*** Symb = get_periodic_table();
3972 	GtkWidget* winDlg = gtk_window_new(GTK_WINDOW_TOPLEVEL);
3973 	gtk_window_set_modal(GTK_WINDOW(winDlg),TRUE);
3974 	gtk_window_set_title(GTK_WINDOW(winDlg),_("Select your atom"));
3975 	gtk_window_set_default_size (GTK_WINDOW(winDlg),(gint)(ScreenWidth*0.5),(gint)(ScreenHeight*0.4));
3976 
3977 	frame = gtk_frame_new (NULL);
3978 	gtk_frame_set_shadow_type( GTK_FRAME(frame),GTK_SHADOW_ETCHED_OUT);
3979 	gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
3980 
3981 	gtk_container_add(GTK_CONTAINER(winDlg),frame);
3982 	gtk_widget_show (frame);
3983 
3984 	Table = gtk_table_new(PERIODIC_TABLE_N_ROWS-1,PERIODIC_TABLE_N_COLUMNS,TRUE);
3985 	gtk_container_add(GTK_CONTAINER(frame),Table);
3986 	 button_style = gtk_widget_get_style(winDlg);
3987 
3988 	for ( i = 0;i<PERIODIC_TABLE_N_ROWS-1;i++)
3989 	for ( j = 0;j<PERIODIC_TABLE_N_COLUMNS;j++)
3990 	{
3991 	  if(strcmp(Symb[j][i],"00"))
3992 	  {
3993 	  	button = gtk_button_new_with_label(Symb[j][i]);
3994           	style=set_button_style(button_style,button,Symb[j][i]);
3995 		g_object_set_data(G_OBJECT (button), "WinDlg",winDlg);
3996           	g_signal_connect(G_OBJECT(button), "clicked", (GCallback)setSymbolOfselectedAtoms,(gpointer )Symb[j][i]);
3997 	  	gtk_table_attach(GTK_TABLE(Table),button,j,j+1,i,i+1,
3998 		  (GtkAttachOptions)(GTK_FILL | GTK_EXPAND) ,
3999 		  (GtkAttachOptions)(GTK_FILL | GTK_EXPAND),
4000 		  1,1);
4001 	  }
4002 	}
4003 
4004 	gtk_widget_show_all(winDlg);
4005 }
4006 /********************************************************************************/
getListCharges(gint * nlist)4007 gchar** getListCharges(gint* nlist)
4008 {
4009 
4010 	gchar** t = NULL;
4011 
4012 	gint i;
4013 	gint j;
4014 
4015 	*nlist = 0;
4016 	if(Natoms<1) return NULL;
4017 
4018 	t = g_malloc(Natoms*sizeof(gchar*));
4019 	*nlist = 1;
4020 	t[*nlist-1] =  g_strdup_printf("%f",geometry0[0].Charge);
4021 
4022 
4023 	for(i=1;i<Natoms;i++)
4024 	{
4025 		gboolean inList = FALSE;
4026 		for(j=0;j<*nlist;j++)
4027 		{
4028 			if(geometry0[i].Charge==atof(t[j]))
4029 			{
4030 				inList = TRUE;
4031 				break;
4032 			}
4033 		}
4034 		if(!inList)
4035 		{
4036 			(*nlist)++;
4037 			t[*nlist-1] =  g_strdup_printf("%f",geometry0[i].Charge);
4038 		}
4039 	}
4040 	t = g_realloc(t,*nlist*sizeof(gchar*));
4041 
4042 	return t;
4043 }
4044 /********************************************************************************/
setChargeOfselectedAtoms(GtkWidget * button,GtkWidget * entry)4045 static void setChargeOfselectedAtoms(GtkWidget* button, GtkWidget* entry)
4046 {
4047 	gint i;
4048 	gint k = 0;
4049 	G_CONST_RETURN gchar *tValue;
4050 
4051 
4052 	if(Natoms<1) return;
4053 	tValue = gtk_entry_get_text(GTK_ENTRY(entry));
4054 	if(strlen(tValue)<1) return;
4055 	if(NFatoms<1) return;
4056 	if(!NumFatoms) return;
4057 
4058 	for (k=0;k<(gint)NFatoms;k++)
4059 	for (i=0;i<(gint)Natoms;i++)
4060 	{
4061 		if(geometry[i].N== NumFatoms[k])
4062 		{
4063 			geometry[i].Charge = atof(tValue);
4064 			geometry0[i].Charge = atof(tValue);
4065 		}
4066 	}
4067 	create_GeomXYZ_from_draw_grometry();
4068 
4069 	drawGeom();
4070 }
4071 /********************************************************************************/
setChargeOfselectedAtomsDlg()4072 void setChargeOfselectedAtomsDlg()
4073 {
4074 	GtkWidget *winDlg;
4075 	GtkWidget *button;
4076 	GtkWidget *hbox;
4077 	GtkWidget *entry;
4078 	GtkWidget *frame;
4079 	GtkWidget *vboxframe;
4080 	gint n=0;
4081 	gchar** t = NULL;
4082 	gchar tmp[100] = "UNK";
4083 	gint i;
4084 	gint k;
4085 
4086 	if(Natoms<1) return;
4087 	if(NFatoms<1) return;
4088 	if(!NumFatoms) return;
4089 
4090 	k=0;
4091 	for (i=0;i<(gint)Natoms;i++)
4092 	{
4093 		if(geometry[i].N == NumFatoms[k])
4094 		{
4095 			sprintf(tmp,"%f",geometry[i].Charge);
4096 			break;
4097 		}
4098 	}
4099 
4100 	winDlg = gtk_dialog_new();
4101 	gtk_window_set_title(GTK_WINDOW(winDlg),_("Set Charge of selected atoms"));
4102 	gtk_window_set_position(GTK_WINDOW(winDlg),GTK_WIN_POS_CENTER);
4103 	gtk_window_set_transient_for(GTK_WINDOW(winDlg),GTK_WINDOW(GeomDlg));
4104 
4105 	add_child(GeomDlg,winDlg,gtk_widget_destroy,_(" Set Sel. Charge."));
4106 	g_signal_connect(G_OBJECT(winDlg),"delete_event",(GCallback)delete_child,NULL);
4107 
4108 	frame = gtk_frame_new (NULL);
4109 	gtk_frame_set_shadow_type( GTK_FRAME(frame),GTK_SHADOW_ETCHED_OUT);
4110 
4111 	gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
4112 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->vbox), frame,TRUE,TRUE,0);
4113 
4114 	gtk_widget_show (frame);
4115 
4116 	vboxframe = create_vbox(frame);
4117 	hbox=create_hbox_false(vboxframe);
4118 	n=0;
4119 	t = getListCharges(&n);
4120 	entry = create_label_combo(hbox, _(" Charge : "),t,n, TRUE,-1,-1);
4121 	if(strcmp(tmp,"UNK")) gtk_entry_set_text(GTK_ENTRY(entry),tmp);
4122 	gtk_editable_set_editable((GtkEditable*) entry,TRUE);
4123 	if(t) freeList(t,n);
4124 
4125 	gtk_widget_realize(winDlg);
4126 
4127 	button = create_button(winDlg,_("Cancel"));
4128 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->action_area), button,TRUE,TRUE,0);
4129 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)delete_child,GTK_OBJECT(winDlg));
4130 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
4131 
4132 	button = create_button(winDlg,_("OK"));
4133 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->action_area), button,TRUE,TRUE,0);
4134 	g_signal_connect(G_OBJECT(button), "clicked",(GCallback)setChargeOfselectedAtoms,entry);
4135 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)delete_child,GTK_OBJECT(winDlg));
4136 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
4137 	gtk_widget_grab_default(button);
4138 
4139 
4140 	gtk_widget_show_all(winDlg);
4141 }
4142 /********************************************************************************/
scaleChargesOfSelectedAtoms(GtkWidget * button,GtkWidget * entry)4143 static void scaleChargesOfSelectedAtoms(GtkWidget* button, GtkWidget* entry)
4144 {
4145 	gint i;
4146 	gint k;
4147 	G_CONST_RETURN gchar *strEntry;
4148 	gdouble factor = 1.0;
4149 
4150 
4151 	if(Natoms<1) return;
4152 	if(NFatoms<1) return;
4153 	if(!NumFatoms) return;
4154 	strEntry = gtk_entry_get_text(GTK_ENTRY(entry));
4155 	if(strlen(strEntry)<1) return;
4156 	factor = atof(strEntry);
4157 
4158 	for (k=0;k<(gint)NFatoms;k++)
4159 	for (i=0;i<(gint)Natoms;i++)
4160 	{
4161 		if(geometry[i].N== NumFatoms[k])
4162 		{
4163 			geometry[i].Charge *= factor;
4164 			geometry0[i].Charge *= factor;
4165 		}
4166 	}
4167 
4168 	drawGeom();
4169 }
4170 /********************************************************************************/
scaleChargesOfSelectedAtomsDlg()4171 void scaleChargesOfSelectedAtomsDlg()
4172 {
4173 	GtkWidget *winDlg;
4174 	GtkWidget *button;
4175 	GtkWidget *hbox;
4176 	GtkWidget *label;
4177 	GtkWidget *entry;
4178 	GtkWidget *frame;
4179 	GtkWidget *vboxframe;
4180 
4181 	winDlg = gtk_dialog_new();
4182 	gtk_window_set_title(GTK_WINDOW(winDlg),_("Scale charges of selected atoms"));
4183 	gtk_window_set_position(GTK_WINDOW(winDlg),GTK_WIN_POS_CENTER);
4184 	gtk_window_set_transient_for(GTK_WINDOW(winDlg),GTK_WINDOW(GeomDlg));
4185 
4186 	add_child(GeomDlg,winDlg,gtk_widget_destroy,_(" Scal. Char. "));
4187 	g_signal_connect(G_OBJECT(winDlg),"delete_event",(GCallback)delete_child,NULL);
4188 
4189 	frame = gtk_frame_new (NULL);
4190 	gtk_frame_set_shadow_type( GTK_FRAME(frame),GTK_SHADOW_ETCHED_OUT);
4191 
4192 	gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
4193 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->vbox), frame,TRUE,TRUE,0);
4194 
4195 	gtk_widget_show (frame);
4196 
4197 	vboxframe = create_vbox(frame);
4198 	hbox=create_hbox_false(vboxframe);
4199 	label = gtk_label_new(_(" Factor : "));
4200 	gtk_box_pack_start( GTK_BOX(hbox), label,TRUE,TRUE,0);
4201 	entry = gtk_entry_new();
4202 	gtk_entry_set_text(GTK_ENTRY(entry),"1.0");
4203 	gtk_box_pack_start( GTK_BOX(hbox), entry,TRUE,TRUE,0);
4204 
4205 	gtk_widget_realize(winDlg);
4206 
4207 	button = create_button(winDlg,_("Cancel"));
4208 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->action_area), button,TRUE,TRUE,0);
4209 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)delete_child,GTK_OBJECT(winDlg));
4210 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
4211 
4212 	button = create_button(winDlg,_("OK"));
4213 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->action_area), button,TRUE,TRUE,0);
4214 	g_signal_connect(G_OBJECT(button), "clicked",(GCallback)scaleChargesOfSelectedAtoms,entry);
4215 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)delete_child,GTK_OBJECT(winDlg));
4216 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
4217 	gtk_widget_grab_default(button);
4218 
4219 
4220 	gtk_widget_show_all(winDlg);
4221 }
4222 /*****************************************************************************/
set_vect_ij(gint i,gint j,gdouble V[])4223 static void set_vect_ij(gint i, gint j, gdouble V[])
4224 {
4225 	V[0] = geometry0[j].X-geometry0[i].X;
4226 	V[1] = geometry0[j].Y-geometry0[i].Y;
4227 	V[2] = geometry0[j].Z-geometry0[i].Z;
4228 }
4229 /*****************************************************************************/
add_hydrogen_atoms(gint addToI,gint nH,gchar * HType)4230 static void add_hydrogen_atoms(gint addToI, gint nH, gchar* HType)
4231 {
4232 	static SAtomsProp propH = {0};
4233 	static gint begin = 0;
4234 	gint i;
4235 	gint k;
4236 	gdouble dist = 1.0;
4237 	gint geom = 0; /* 0=3D, 1=planar, 2=linear */
4238 	gdouble angle = 109.5*PI/180.0;
4239 	gint nV;
4240 	gint nC;
4241 	gint* listOfConnectedAtoms = NULL;
4242 
4243 	if(begin==0)
4244 	{
4245 		begin++;
4246 		propH = prop_atom_get("H");
4247 	}
4248 	dist = (geometry[addToI].Prop.covalentRadii+propH.covalentRadii)*0.9;
4249 	if(nH==1 && strcmp(geometry0[addToI].Prop.symbol,"N"))
4250 	{
4251 		angle = 180.0*PI/180.0;
4252 		geom = 2;
4253 	}
4254 	if(nH==2 && !strcmp(geometry0[addToI].Prop.symbol,"N"))
4255 	{
4256 		angle = 120.0*PI/180.0;
4257 		geom = 1;
4258 	}
4259 	nV =geometry[addToI].Prop.maximumBondValence;
4260 	if(nV<1) return;
4261 	listOfConnectedAtoms = g_malloc(nV*sizeof(gint));
4262 
4263 	if(Natoms>0)
4264 	{
4265 		geometry0 = g_realloc(geometry0,(Natoms+nH)*sizeof(GeomDef));
4266 		geometry = g_realloc(geometry,(Natoms+nH)*sizeof(GeomDef));
4267 	}
4268 	else
4269 	{
4270 		geometry0 = g_malloc(nH*sizeof(GeomDef));
4271 		geometry = g_malloc(nH*sizeof(GeomDef));
4272 	}
4273 
4274 
4275 	nC = 0;
4276 	for(i=0;i<(gint)Natoms;i++)
4277 	{
4278 		gint ni = geometry[i].N-1;
4279 		if(geometry[addToI].typeConnections[ni]>0)
4280 		{
4281 			listOfConnectedAtoms[nC] = i;
4282 			nC++;
4283 		}
4284 	}
4285 
4286 	for(i=0;i<nH;i++)
4287 	{
4288 		gdouble v1[3];
4289 		gdouble v2[3];
4290 		gdouble v3[3];
4291 		gdouble v4[3];
4292 		gdouble v5[3];
4293 		for(k=0;k<3;k++)
4294 			v1[k] = rand()/(gdouble)RAND_MAX-0.5;
4295 		v3d_normal(v1);
4296 
4297 		switch (nC)
4298 		{
4299 			case 1:
4300 				{
4301 					set_vect_ij(addToI, listOfConnectedAtoms[0], v2);
4302 					v3d_normal(v2);
4303 					v3d_cross(v1,v2,v3);
4304 					v3d_normal(v3);
4305 					v3d_scale(v2,cos(angle));
4306 					v3d_scale(v3,sin(angle));
4307 					v3d_add(v2,v3,v1);
4308 					break;
4309 				}
4310 			case 2:
4311 				{
4312 					set_vect_ij(addToI, listOfConnectedAtoms[0], v2);
4313 					v3d_normal(v2);
4314 					set_vect_ij(addToI, listOfConnectedAtoms[1], v3);
4315 					v3d_normal(v3);
4316 					if(geom==0 || nH>1)
4317 					{
4318 						v3d_add(v2,v3,v4);
4319 						if(v3d_length(v4)>1e-2) v3d_normal(v4);
4320 						v3d_scale(v4,-1.0);
4321 						v3d_cross(v2,v3,v5);
4322 						if(v3d_length(v5)<1e-2)
4323 							for(k=0;k<3;k++) v5[k] = rand()/(gdouble)RAND_MAX-0.5;
4324 						v3d_normal(v5);
4325 						v3d_scale(v4,0.5);
4326 						v3d_scale(v5,0.5);
4327 						v3d_add(v4,v5,v1);
4328 						v3d_normal(v1);
4329 					}
4330 					else
4331 					{
4332 						v3d_add(v2,v3,v1);
4333 						v3d_normal(v1);
4334 						v3d_scale(v1,-1.0);
4335 					}
4336 					break;
4337 				}
4338 			default:
4339 				if(nC>=3)
4340 				{
4341 					set_vect_ij(addToI, listOfConnectedAtoms[nC-3], v2);
4342 					v3d_normal(v2);
4343 					set_vect_ij(addToI, listOfConnectedAtoms[nC-2], v3);
4344 					v3d_normal(v3);
4345 					set_vect_ij(addToI, listOfConnectedAtoms[nC-1], v4);
4346 					v3d_normal(v4);
4347 					v3d_add(v2,v3,v5);
4348 					v3d_add(v5,v4,v1);
4349 					if(v3d_length(v1)<2e-1) v3d_cross(v2,v3,v1);
4350 					v3d_normal(v1);
4351 					v3d_scale(v1,-1.0);
4352 					break;
4353 				}
4354 
4355 		}
4356 		geometry[Natoms].X= geometry0[addToI].X + dist*v1[0];
4357 		geometry[Natoms].Y= geometry0[addToI].Y + dist*v1[1];
4358 		geometry[Natoms].Z= geometry0[addToI].Z + dist*v1[2];
4359 		geometry[Natoms].Prop = prop_atom_get("H");
4360 		geometry[Natoms].pdbType = g_strdup(HType);
4361 		if(Natoms==0)
4362 		{
4363 			geometry[Natoms].Residue = g_strdup("H");
4364 			geometry[Natoms].ResidueNumber = 0;
4365 		}
4366 		else
4367 		{
4368 			geometry[Natoms].Residue = g_strdup(geometry[addToI].Residue);
4369 			geometry[Natoms].ResidueNumber = geometry[addToI].ResidueNumber;
4370 		}
4371 		{
4372 			gdouble charge;
4373 			gchar* mmType = getMMTypeFromPDBTpl(geometry[Natoms].Residue,geometry[Natoms].pdbType,&charge);
4374 			if(!strcmp(mmType,"UNK"))
4375 			{
4376 				geometry[Natoms].mmType = g_strdup(HType);
4377 				g_free(mmType);
4378 			}
4379 			else geometry[Natoms].mmType = mmType;
4380 		}
4381 		geometry[Natoms].Layer = geometry[addToI].Layer;
4382 		geometry[Natoms].N = Natoms+1;
4383 		geometry[Natoms].typeConnections = NULL;
4384 		geometry[Natoms].Charge = 0.0;
4385 		geometry[Natoms].Variable = TRUE;
4386 		geometry[Natoms].show = ShowHydrogenAtoms;
4387 
4388 		geometry0[Natoms].X = geometry[Natoms].X;
4389 		geometry0[Natoms].Y = geometry[Natoms].Y;
4390 		geometry0[Natoms].Z = geometry[Natoms].Z;
4391 		geometry0[Natoms].Prop = prop_atom_get("H");
4392 		geometry0[Natoms].mmType = g_strdup(geometry[Natoms].mmType);
4393 		geometry0[Natoms].pdbType = g_strdup(geometry[Natoms].pdbType);
4394 		geometry0[Natoms].Layer = geometry[Natoms].Layer;
4395 		geometry0[Natoms].Residue = g_strdup(geometry[Natoms].Residue);
4396 		geometry0[Natoms].ResidueNumber = geometry[Natoms].ResidueNumber;
4397 		geometry0[Natoms].Charge = 0.0;
4398 		geometry0[Natoms].Variable = TRUE;
4399 		geometry0[Natoms].N = geometry[Natoms].N;
4400 		geometry0[Natoms].show = geometry[Natoms].show;
4401 		geometry0[Natoms].typeConnections = NULL;
4402 
4403 		Natoms++;
4404 		nC++;
4405 		listOfConnectedAtoms = g_realloc(listOfConnectedAtoms, nC*sizeof(gint));
4406 		listOfConnectedAtoms[nC-1] = Natoms-1;
4407 	}
4408 	{
4409 		gint i,j;
4410 		for(i=0;i<(gint)Natoms-nH;i++)
4411 		{
4412 			geometry[i].typeConnections = g_realloc(geometry[i].typeConnections,Natoms*sizeof(gint));
4413 			for(j=Natoms-nH;j<(gint)Natoms;j++) geometry[i].typeConnections[j] = 0;
4414 			geometry0[i].typeConnections = g_realloc(geometry0[i].typeConnections,Natoms*sizeof(gint));
4415 			for(j=Natoms-nH;j<(gint)Natoms;j++) geometry0[i].typeConnections[j] = 0;
4416 		}
4417 		for(i=(gint)Natoms-nH;i<(gint)Natoms;i++)
4418 		{
4419 			geometry[i].typeConnections = g_malloc(Natoms*sizeof(gint));
4420 			for(j=0;j<(gint)Natoms;j++) geometry[i].typeConnections[j] = 0;
4421 			geometry0[i].typeConnections = g_malloc(Natoms*sizeof(gint));
4422 			for(j=0;j<(gint)Natoms;j++) geometry0[i].typeConnections[j] = 0;
4423 		}
4424 		for(i=(gint)Natoms-nH;i<(gint)Natoms;i++)
4425 		{
4426 			geometry[addToI].typeConnections[geometry[i].N-1] = 1;
4427 			geometry0[addToI].typeConnections[geometry0[i].N-1] = 1;
4428 			geometry[i].typeConnections[geometry[addToI].N-1] = 1;
4429 			geometry0[i].typeConnections[geometry0[addToI].N-1] = 1;
4430 		}
4431 		/* adjust_multiple_bonds_with_one_atom(addToI);*/
4432 	}
4433 	if(listOfConnectedAtoms) g_free(listOfConnectedAtoms);
4434 }
4435 /*****************************************************************************/
add_hydrogen_atom(gint addToI)4436 static gboolean add_hydrogen_atom(gint addToI)
4437 {
4438 	gint nMultiple = 0;
4439 	gint nAll = 0;
4440 	gchar HType[100] = "H";
4441 	gint j;
4442 	gint nV = 0;
4443 	gint nH = 0;
4444 
4445 
4446 	if(Natoms<1 ) return FALSE;
4447 	if(addToI>Natoms-1) return FALSE;
4448 
4449 	nV =geometry[addToI].Prop.maximumBondValence;
4450 	if(nV<1) return FALSE;
4451 
4452 	for(j=0;j<(gint)Natoms;j++)
4453 	{
4454 		gint nj = geometry[j].N-1;
4455 		if(geometry[addToI].typeConnections[nj]>1) nMultiple++;
4456 		nAll += geometry[addToI].typeConnections[nj];
4457 	}
4458 
4459 	nH = nV - nAll;
4460 	if(nH<1)
4461 	{
4462 		return FALSE;
4463 	}
4464 	if(nAll>=geometry[addToI].Prop.maximumBondValence && nMultiple==0)
4465 	{
4466 		return FALSE;
4467 	}
4468 
4469 
4470 	if(!strcmp(geometry[addToI].pdbType,"CA")) sprintf(HType,"HA");
4471 	else if(!strcmp(geometry[addToI].pdbType,"OH")) sprintf(HType,"HO");
4472 	else if(strstr(geometry[addToI].pdbType,"OE")) sprintf(HType,"HO");
4473 	else if(strstr(geometry[addToI].pdbType,"OD")) sprintf(HType,"HO");
4474 	else if(!strcmp(geometry[addToI].pdbType,"OG1")) sprintf(HType,"HG1");
4475 	else if(!strcmp(geometry[addToI].pdbType,"CT")) sprintf(HType,"HT");
4476 	else if(!strcmp(geometry[addToI].pdbType,"CB")) sprintf(HType,"HB1");
4477 	else if(!strcmp(geometry[addToI].pdbType,"SG")) sprintf(HType,"HG");
4478 	else if(!strcmp(geometry[addToI].pdbType,"CD1")) sprintf(HType,"HD11");
4479 	else if(!strcmp(geometry[addToI].pdbType,"CD2")) sprintf(HType,"HD22");
4480 	else if(strstr(geometry[addToI].pdbType,"CD")) sprintf(HType,"HD1");
4481 	else if(!strcmp(geometry[addToI].pdbType,"CG1")) sprintf(HType,"HG11");
4482 	else if(!strcmp(geometry[addToI].pdbType,"CG2")) sprintf(HType,"HG22");
4483 	else if(strstr(geometry[addToI].pdbType,"CG")) sprintf(HType,"HG1");
4484 	else if(!strcmp(geometry[addToI].pdbType,"CE1")) sprintf(HType,"HE1");
4485 	else if(!strcmp(geometry[addToI].pdbType,"CE2")) sprintf(HType,"HE2");
4486 	else if(strstr(geometry[addToI].pdbType,"CE")) sprintf(HType,"HE2");
4487 	else if(strstr(geometry[addToI].pdbType,"NZ")) sprintf(HType,"HZ2");
4488 	else if(strstr(geometry[addToI].pdbType,"NZ")) sprintf(HType,"HZ2");
4489 	else if(!strcmp(geometry[addToI].pdbType,"CZ1")) sprintf(HType,"HZ1");
4490 	else if(!strcmp(geometry[addToI].pdbType,"CZ2")) sprintf(HType,"HZ2");
4491 	else if(!strcmp(geometry[addToI].pdbType,"CZ3")) sprintf(HType,"HZ3");
4492 	else if(strstr(geometry[addToI].pdbType,"CZ")) sprintf(HType,"HZ");
4493 	else if(!strcmp(geometry[addToI].pdbType,"NE")) sprintf(HType,"HE");
4494 	else if(!strcmp(geometry[addToI].pdbType,"N")) sprintf(HType,"H");
4495 	else if(!strcmp(geometry[addToI].pdbType,"NE1")) sprintf(HType,"HE1");
4496 	else if(!strcmp(geometry[addToI].pdbType,"NH1")) sprintf(HType,"HH11");
4497 	else if(!strcmp(geometry[addToI].pdbType,"NH2")) sprintf(HType,"HH21");
4498 	else if(!strcmp(geometry[addToI].pdbType,"CH1")) sprintf(HType,"HH1");
4499 	else if(!strcmp(geometry[addToI].pdbType,"CH2")) sprintf(HType,"HH2");
4500 	else if(!strcmp(geometry[addToI].pdbType,"CH3")) sprintf(HType,"H2");
4501 	else
4502 	{
4503 		sprintf(HType,"%s1",geometry[addToI].pdbType);
4504 		if(strlen(HType)>0) HType[0] = 'H';
4505 	}
4506 	add_hydrogen_atoms(addToI, nH, HType);
4507 
4508 	reset_charges_multiplicities();
4509 	return TRUE;
4510 }
4511 /*****************************************************************************/
add_max_hydrogen_atom(gint addToI)4512 static gboolean add_max_hydrogen_atom(gint addToI)
4513 {
4514 	gint nAll = 0;
4515 	gchar HType[100] = "H";
4516 	gint j;
4517 	gint nV = 0;
4518 	gint nH = 0;
4519 
4520 
4521 	if(Natoms<1 ) return FALSE;
4522 	if(addToI>Natoms-1) return FALSE;
4523 
4524 	nV =geometry[addToI].Prop.maximumBondValence;
4525 	if(nV<1) return FALSE;
4526 
4527 	for(j=0;j<(gint)Natoms;j++)
4528 	{
4529 		gint nj = geometry[j].N-1;
4530 		if(geometry[addToI].typeConnections[nj]>0)
4531 		nAll += 1;
4532 	}
4533 	/*
4534 	printf("Type = %s res = %s\n", geometry[addToI].mmType, geometry[addToI].Residue);
4535 	*/
4536 
4537 	nH = nV - nAll;
4538 	if(nH<1)
4539 	{
4540 		return FALSE;
4541 	}
4542 
4543 	if(!strcmp(geometry[addToI].pdbType,"CA")) sprintf(HType,"HA");
4544 	else if(!strcmp(geometry[addToI].pdbType,"OH")) sprintf(HType,"HO");
4545 	else if(strstr(geometry[addToI].pdbType,"OE")) sprintf(HType,"HO");
4546 	else if(strstr(geometry[addToI].pdbType,"OD")) sprintf(HType,"HO");
4547 	else if(!strcmp(geometry[addToI].pdbType,"OG1")) sprintf(HType,"HG1");
4548 	else if(!strcmp(geometry[addToI].pdbType,"CT")) sprintf(HType,"HT");
4549 	else if(!strcmp(geometry[addToI].pdbType,"CB")) sprintf(HType,"HB1");
4550 	else if(!strcmp(geometry[addToI].pdbType,"SG")) sprintf(HType,"HG");
4551 	else if(!strcmp(geometry[addToI].pdbType,"CD1")) sprintf(HType,"HD11");
4552 	else if(!strcmp(geometry[addToI].pdbType,"CD2")) sprintf(HType,"HD22");
4553 	else if(strstr(geometry[addToI].pdbType,"CD")) sprintf(HType,"HD1");
4554 	else if(!strcmp(geometry[addToI].pdbType,"CG1")) sprintf(HType,"HG11");
4555 	else if(!strcmp(geometry[addToI].pdbType,"CG2")) sprintf(HType,"HG22");
4556 	else if(strstr(geometry[addToI].pdbType,"CG")) sprintf(HType,"HG1");
4557 	else if(!strcmp(geometry[addToI].pdbType,"CE1")) sprintf(HType,"HE1");
4558 	else if(!strcmp(geometry[addToI].pdbType,"CE2")) sprintf(HType,"HE2");
4559 	else if(strstr(geometry[addToI].pdbType,"CE")) sprintf(HType,"HE2");
4560 	else if(strstr(geometry[addToI].pdbType,"NZ")) sprintf(HType,"HZ2");
4561 	else if(strstr(geometry[addToI].pdbType,"NZ")) sprintf(HType,"HZ2");
4562 	else if(!strcmp(geometry[addToI].pdbType,"CZ1")) sprintf(HType,"HZ1");
4563 	else if(!strcmp(geometry[addToI].pdbType,"CZ2")) sprintf(HType,"HZ2");
4564 	else if(!strcmp(geometry[addToI].pdbType,"CZ3")) sprintf(HType,"HZ3");
4565 	else if(strstr(geometry[addToI].pdbType,"CZ")) sprintf(HType,"HZ");
4566 	else if(!strcmp(geometry[addToI].pdbType,"NE")) sprintf(HType,"HE");
4567 	else if(!strcmp(geometry[addToI].pdbType,"N")) sprintf(HType,"H");
4568 	else if(!strcmp(geometry[addToI].pdbType,"NE1")) sprintf(HType,"HE1");
4569 	else if(!strcmp(geometry[addToI].pdbType,"NH1")) sprintf(HType,"HH11");
4570 	else if(!strcmp(geometry[addToI].pdbType,"NH2")) sprintf(HType,"HH21");
4571 	else if(!strcmp(geometry[addToI].pdbType,"CH1")) sprintf(HType,"HH1");
4572 	else if(!strcmp(geometry[addToI].pdbType,"CH2")) sprintf(HType,"HH2");
4573 	else if(!strcmp(geometry[addToI].pdbType,"CH3")) sprintf(HType,"H2");
4574 	else
4575 	{
4576 		sprintf(HType,"%s1",geometry[addToI].pdbType);
4577 		if(strlen(HType)>0) HType[0] = 'H';
4578 	}
4579 	add_hydrogen_atoms(addToI, nH, HType);
4580 
4581 	setMultipleBonds();
4582 	reset_charges_multiplicities();
4583 	RebuildGeom=TRUE;
4584 	return TRUE;
4585 }
4586 /*****************************************************************************/
add_one_hydrogen_atom(gint addToI)4587 static gboolean add_one_hydrogen_atom(gint addToI)
4588 {
4589 	gint nMultiple = 0;
4590 	gint nAll = 0;
4591 	gchar HType[100] = "H";
4592 	gint j;
4593 	gint nV = 0;
4594 	gint nH = 0;
4595 	gint nC = 0;
4596 
4597 
4598 	if(Natoms<1 ) return FALSE;
4599 	if(addToI>Natoms-1) return FALSE;
4600 
4601 	nV =geometry[addToI].Prop.maximumBondValence;
4602 	if(nV<1) return FALSE;
4603 
4604 	for(j=0;j<(gint)Natoms;j++)
4605 	{
4606 		gint nj = geometry[j].N-1;
4607 		if(geometry[addToI].typeConnections[nj]>0) nC++;
4608 		if(geometry[addToI].typeConnections[nj]>1) nMultiple++;
4609 		nAll += geometry[addToI].typeConnections[nj];
4610 	}
4611 
4612 	nH = nV - nC;
4613 	if(nH<1)
4614 	{
4615 		return FALSE;
4616 	}
4617 	else nH = 1;
4618 	if(nAll>=geometry[addToI].Prop.maximumBondValence && nMultiple==0)
4619 	{
4620 		return FALSE;
4621 	}
4622 
4623 
4624 	if(!strcmp(geometry[addToI].pdbType,"CA")) sprintf(HType,"HA");
4625 	else if(!strcmp(geometry[addToI].pdbType,"OH")) sprintf(HType,"HO");
4626 	else if(strstr(geometry[addToI].pdbType,"OE")) sprintf(HType,"HO");
4627 	else if(strstr(geometry[addToI].pdbType,"OD")) sprintf(HType,"HO");
4628 	else if(!strcmp(geometry[addToI].pdbType,"OG1")) sprintf(HType,"HG1");
4629 	else if(!strcmp(geometry[addToI].pdbType,"CT")) sprintf(HType,"HT");
4630 	else if(!strcmp(geometry[addToI].pdbType,"CB")) sprintf(HType,"HB1");
4631 	else if(!strcmp(geometry[addToI].pdbType,"SG")) sprintf(HType,"HG");
4632 	else if(!strcmp(geometry[addToI].pdbType,"CD1")) sprintf(HType,"HD11");
4633 	else if(!strcmp(geometry[addToI].pdbType,"CD2")) sprintf(HType,"HD22");
4634 	else if(strstr(geometry[addToI].pdbType,"CD")) sprintf(HType,"HD1");
4635 	else if(!strcmp(geometry[addToI].pdbType,"CG1")) sprintf(HType,"HG11");
4636 	else if(!strcmp(geometry[addToI].pdbType,"CG2")) sprintf(HType,"HG22");
4637 	else if(strstr(geometry[addToI].pdbType,"CG")) sprintf(HType,"HG1");
4638 	else if(!strcmp(geometry[addToI].pdbType,"CE1")) sprintf(HType,"HE1");
4639 	else if(!strcmp(geometry[addToI].pdbType,"CE2")) sprintf(HType,"HE2");
4640 	else if(strstr(geometry[addToI].pdbType,"CE")) sprintf(HType,"HE2");
4641 	else if(strstr(geometry[addToI].pdbType,"NZ")) sprintf(HType,"HZ2");
4642 	else if(strstr(geometry[addToI].pdbType,"NZ")) sprintf(HType,"HZ2");
4643 	else if(!strcmp(geometry[addToI].pdbType,"CZ1")) sprintf(HType,"HZ1");
4644 	else if(!strcmp(geometry[addToI].pdbType,"CZ2")) sprintf(HType,"HZ2");
4645 	else if(!strcmp(geometry[addToI].pdbType,"CZ3")) sprintf(HType,"HZ3");
4646 	else if(strstr(geometry[addToI].pdbType,"CZ")) sprintf(HType,"HZ");
4647 	else if(!strcmp(geometry[addToI].pdbType,"NE")) sprintf(HType,"HE");
4648 	else if(!strcmp(geometry[addToI].pdbType,"N")) sprintf(HType,"H");
4649 	else if(!strcmp(geometry[addToI].pdbType,"NE1")) sprintf(HType,"HE1");
4650 	else if(!strcmp(geometry[addToI].pdbType,"NH1")) sprintf(HType,"HH11");
4651 	else if(!strcmp(geometry[addToI].pdbType,"NH2")) sprintf(HType,"HH21");
4652 	else if(!strcmp(geometry[addToI].pdbType,"CH1")) sprintf(HType,"HH1");
4653 	else if(!strcmp(geometry[addToI].pdbType,"CH2")) sprintf(HType,"HH2");
4654 	else if(!strcmp(geometry[addToI].pdbType,"CH3")) sprintf(HType,"H2");
4655 	else
4656 	{
4657 		sprintf(HType,"%s1",geometry[addToI].pdbType);
4658 		if(strlen(HType)>0) HType[0] = 'H';
4659 	}
4660 	add_hydrogen_atoms(addToI, nH, HType);
4661 	RebuildGeom=TRUE;
4662 
4663 	return TRUE;
4664 }
4665 /********************************************************************************/
addMaxHydrogens()4666 void addMaxHydrogens()
4667 {
4668 	gint i;
4669 	gint k = 0;
4670 
4671 
4672 	if(Natoms<1) return;
4673 	if(!NumFatoms) SelectAllAtoms();
4674 	if(NFatoms<1) return;
4675 	if(!NumFatoms) return;
4676 
4677 	for (k=0;k<(gint)NFatoms;k++)
4678 	for (i=0;i<(gint)Natoms;i++)
4679 	{
4680 		if(geometry[i].N== NumFatoms[k])
4681 		{
4682 			add_max_hydrogen_atom(i);
4683 			break;
4684 		}
4685 	}
4686 	reset_multiple_bonds();
4687 	create_GeomXYZ_from_draw_grometry();
4688 	reset_charges_multiplicities();
4689 	RebuildGeom=TRUE;
4690 	drawGeom();
4691 }
4692 /********************************************************************************/
addHydrogens()4693 void addHydrogens()
4694 {
4695 	gint i;
4696 	gint k = 0;
4697 
4698 
4699 	if(Natoms<1) return;
4700 	if(!NumFatoms) SelectAllAtoms();
4701 	if(NFatoms<1) return;
4702 	if(!NumFatoms) return;
4703 
4704 	for (k=0;k<(gint)NFatoms;k++)
4705 	for (i=0;i<(gint)Natoms;i++)
4706 	{
4707 		if(geometry[i].N== NumFatoms[k])
4708 		{
4709 			add_hydrogen_atom(i);
4710 			break;
4711 		}
4712 	}
4713 	create_GeomXYZ_from_draw_grometry();
4714 	reset_charges_multiplicities();
4715 	RebuildGeom=TRUE;
4716 	drawGeom();
4717 }
4718 /********************************************************************************/
addOneHydrogen()4719 void addOneHydrogen()
4720 {
4721 	gint i;
4722 	gint k = 0;
4723 
4724 
4725 	if(Natoms<1) return;
4726 	if(!NumFatoms) SelectAllAtoms();
4727 	if(NFatoms<1) return;
4728 	if(!NumFatoms) return;
4729 
4730 	for (k=0;k<(gint)NFatoms;k++)
4731 	for (i=0;i<(gint)Natoms;i++)
4732 	{
4733 		if(geometry[i].N== NumFatoms[k])
4734 		{
4735 			add_one_hydrogen_atom(i);
4736 			break;
4737 		}
4738 	}
4739 	create_GeomXYZ_from_draw_grometry();
4740 	reset_charges_multiplicities();
4741 	RebuildGeom=TRUE;
4742 	drawGeom();
4743 }
4744 /*******************************************************************/
adjust_hydrogens_connected_to_atom(gint ia)4745 void adjust_hydrogens_connected_to_atom(gint ia)
4746 {
4747 	if(Natoms<1) return;
4748 	if(ia<0 || ia>Natoms-1) return;
4749 	{
4750 		gint nj = 0;
4751 		gint j;
4752 		gint nBondsA = 0;
4753 
4754 		for(j=0;j<(gint)Natoms;j++)
4755 		{
4756 			nj = geometry[j].N-1;
4757 			if(geometry[ia].typeConnections && geometry[ia].typeConnections[nj]>0)
4758 				nBondsA += geometry[ia].typeConnections[nj];
4759 		}
4760 		if( nBondsA==geometry[ia].Prop.maximumBondValence ) return;
4761 		if(nBondsA<geometry[ia].Prop.maximumBondValence)
4762 		{
4763 			gint nHA = geometry[ia].Prop.maximumBondValence-nBondsA;
4764 			for(j=0;j<nHA;j++) add_hydrogen_atom(ia);
4765 			copy_connections(geometry0, geometry, Natoms);
4766 		}
4767 		if(nBondsA>geometry[ia].Prop.maximumBondValence)
4768 		{
4769 			gint nHA = nBondsA-geometry[ia].Prop.maximumBondValence;
4770 			deleteHydrogensConnectedTo(ia, nHA);
4771 		}
4772 		reset_charges_multiplicities();
4773 	}
4774 }
4775 /*******************************************************************/
adjust_hydrogens_connected_to_atoms(gint ia,gint ib)4776 void adjust_hydrogens_connected_to_atoms(gint ia, gint ib)
4777 {
4778 	if(Natoms<2) return;
4779 	if(ia<0 || ib<0 || ia>Natoms-1 || ib>Natoms-1) return;
4780 	if(!geometry[ia].typeConnections) return;
4781 	if(!geometry[ib].typeConnections) return;
4782 	{
4783 		gint nj = 0;
4784 		gint j;
4785 		gint nBondsA = 0;
4786 		gint nBondsB = 0;
4787 
4788 		for(j=0;j<(gint)Natoms;j++)
4789 		{
4790 			nj = geometry[j].N-1;
4791 		 	if(geometry[ia].typeConnections[nj]>0)
4792 				nBondsA += geometry[ia].typeConnections[nj];
4793 		 	if(geometry[ib].typeConnections[nj]>0)
4794 				nBondsB += geometry[ib].typeConnections[nj];
4795 		}
4796 		if(
4797 			nBondsA==geometry[ia].Prop.maximumBondValence &&
4798 			nBondsB==geometry[ib].Prop.maximumBondValence
4799 		) return;
4800 		if(nBondsA<geometry[ia].Prop.maximumBondValence)
4801 		{
4802 			gint nHA = geometry[ia].Prop.maximumBondValence-nBondsA;
4803 			for(j=0;j<nHA;j++) add_hydrogen_atom(ia);
4804 			copy_connections(geometry0, geometry, Natoms);
4805 		}
4806 		if(nBondsB<geometry[ib].Prop.maximumBondValence)
4807 		{
4808 			gint nHB = geometry[ib].Prop.maximumBondValence-nBondsB;
4809 			for(j=0;j<nHB;j++) add_hydrogen_atom(ib);
4810 			copy_connections(geometry0, geometry, Natoms);
4811 		}
4812 		if(nBondsA>geometry[ia].Prop.maximumBondValence && nBondsB<=geometry[ib].Prop.maximumBondValence)
4813 		{
4814 			gint nHA = nBondsA-geometry[ia].Prop.maximumBondValence;
4815 			deleteHydrogensConnectedTo(ia, nHA);
4816 		}
4817 		if(nBondsB>geometry[ib].Prop.maximumBondValence && nBondsA<=geometry[ia].Prop.maximumBondValence)
4818 		{
4819 			gint nHB = nBondsA-geometry[ib].Prop.maximumBondValence;
4820 			deleteHydrogensConnectedTo(ib, nHB);
4821 		}
4822 		if(nBondsA>geometry[ia].Prop.maximumBondValence && nBondsB>geometry[ib].Prop.maximumBondValence)
4823 		{
4824 			gint nHA = nBondsA-geometry[ia].Prop.maximumBondValence;
4825 			gint nHB = nBondsB-geometry[ib].Prop.maximumBondValence;
4826 			gint* numHA = NULL;
4827 			gint* numHB = NULL;
4828 			gint kA = 0;
4829 			gint kB = 0;
4830 			gint k;
4831 			gint i;
4832 			GeomDef tmp;
4833 			gint* oldN = NULL;
4834 
4835 			if(nHA>0) numHA = g_malloc(nHA*sizeof(gint));
4836 			if(nHB>0) numHB = g_malloc(nHB*sizeof(gint));
4837 			for(j=0;j<nHA;j++) numHA[j] = -1;
4838 			for(j=0;j<nHB;j++) numHB[j] = -1;
4839 
4840 			kA = 0;
4841 			for(j=0;j<(gint)Natoms;j++)
4842 			{
4843 				if(j==ia) continue;
4844 				nj = geometry[j].N-1;
4845 				if(geometry[ia].typeConnections[nj] &&
4846 				!strcmp(geometry[j].Prop.symbol,"H"))
4847 				{
4848 					numHA[kA++] = geometry[j].N;
4849 					if(kA>=nHA) break;
4850 				}
4851 			}
4852 			kB = 0;
4853 			for(j=0;j<(gint)Natoms;j++)
4854 			{
4855 				if(j==ib) continue;
4856 				nj = geometry[j].N-1;
4857 				if(geometry[ib].typeConnections[nj] &&
4858 				!strcmp(geometry[j].Prop.symbol,"H"))
4859 				{
4860 					numHB[kB++] = geometry[j].N;
4861 					if(kB>=nHB) break;
4862 				}
4863 			}
4864 			copy_connections(geometry0, geometry, Natoms);
4865 			for (i=0;i<(gint)Natoms-1;i++)
4866 			{
4867 				gboolean toDelete = FALSE;
4868 				for(k=0;k<kA;k++) if(geometry[i].N==numHA[k]) {toDelete = TRUE; break;}
4869 				if(!toDelete) for(k=0;k<kB;k++) if(geometry[i].N==numHB[k]) {toDelete = TRUE; break;}
4870 				if(!toDelete) continue;
4871 				for(j=i+1;j<(gint)Natoms;j++)
4872 				{
4873 					gboolean toDelete = FALSE;
4874 					for(k=0;k<kA;k++) if(geometry[j].N==numHA[k]) {toDelete = TRUE; break;}
4875 					if(!toDelete) for(k=0;k<kB;k++) if(geometry[j].N==numHB[k]) {toDelete = TRUE; break;}
4876 					if(toDelete) continue;
4877 					tmp = geometry0[i];
4878 					geometry0[i] = geometry0[j];
4879 					geometry0[j] = tmp ;
4880 					tmp = geometry[i];
4881 					geometry[i] = geometry[j];
4882 					geometry[j] = tmp ;
4883 					break;
4884 				}
4885 			}
4886 			j = 0;
4887 			for (i=0;i<(gint)Natoms;i++)
4888 			{
4889 				gboolean toDelete = FALSE;
4890 				for(k=0;k<kA;k++) if(geometry[i].N==numHA[k]) {toDelete = TRUE; break;}
4891 				if(!toDelete) for(k=0;k<kB;k++) if(geometry[i].N==numHB[k]) {toDelete = TRUE; break;}
4892 				if(!toDelete) continue;
4893 				if(geometry0[i].typeConnections) g_free(geometry0[i].typeConnections);
4894 				if(geometry[i].typeConnections) g_free(geometry[i].typeConnections);
4895 				geometry0[i].typeConnections=NULL;
4896 				geometry[i].typeConnections=NULL;
4897 				j++;
4898 			}
4899 			if(numHA) g_free(numHA);
4900 			if(numHB) g_free(numHB);
4901 
4902 			oldN = g_malloc(Natoms*sizeof(gint));
4903 			for (i=0;i<(gint)Natoms;i++) oldN[i] = geometry0[i].N-1;
4904 			Natoms-=kA+kB;
4905 
4906 			for(j=0;j<(gint)NFatoms;j++)
4907 			{
4908 				for (i=0;i<(gint)Natoms;i++)
4909 					if(NumFatoms[j] ==(gint) geometry[i].N) { NumFatoms[j] = i+1; break;}
4910 				if(i==(gint)Natoms)  NumFatoms[j] =-1;
4911 			}
4912 			for(j=0;j<(gint)NFatoms;j++)
4913 				if( NumFatoms[j]<0)
4914 				{
4915 					for (i=j;i<(gint)NFatoms-1;i++)
4916 				 		NumFatoms[i]= NumFatoms[i+1];
4917 					NFatoms--;
4918 					j--;
4919 				}
4920 			for (i=0;i<(gint)Natoms;i++)
4921 			{
4922 				geometry0[i].N = i+1;
4923 				geometry[i].N = i+1;
4924 			}
4925 			/* in geometry0 : old connections , in geometry new connection */
4926 			for (i=0;i<(gint)Natoms;i++)
4927 			{
4928 				if(geometry[i].typeConnections)
4929 				{
4930 					for(j=0;j<(gint)Natoms;j++)
4931 					{
4932 						geometry[i].typeConnections[j] = geometry0[i].typeConnections[oldN[j]];
4933 					}
4934 				}
4935 			}
4936 			if(oldN) g_free(oldN);
4937 			copy_connections(geometry0, geometry, Natoms);
4938 			if(Natoms>0)
4939 			{
4940 				geometry0 = g_realloc(geometry0,Natoms*sizeof(GeomDef));
4941 				geometry = g_realloc(geometry,Natoms*sizeof(GeomDef));
4942 			}
4943 			else
4944 			{
4945 				if(geometry0) g_free(geometry0); geometry0 = NULL;
4946 				if(geometry) g_free(geometry);
4947 				geometry = NULL;
4948 				Natoms = 0;
4949 			}
4950 			Ddef = FALSE;
4951 			reset_charges_multiplicities();
4952 		}
4953 	}
4954 }
4955 /*****************************************************************************/
add_hydrogen_atoms_tpl(gint addToI,gint nA)4956 static void add_hydrogen_atoms_tpl(gint addToI, gint nA)
4957 {
4958 	static SAtomsProp propH = {0};
4959 	static gint begin = 0;
4960 	gint i;
4961 	gint k;
4962 	gdouble dist = 1.0;
4963 	gint geom = 0; /* 0=3D, 1=planar, 2=linear */
4964 	gdouble angle = 109.5*PI/180.0;
4965 	gint nV;
4966 	gint nC;
4967 	gint* listOfConnectedAtoms = NULL;
4968 	gint nH;
4969 	gchar* hAtoms[10];
4970 	gint nAll;
4971 	gint nOldH = 0;
4972 
4973 	nV =geometry[addToI].Prop.maximumBondValence;
4974 	if(nV<1) return;
4975 	nAll = 0;
4976 	nOldH = 0;
4977 	for(i=0;i<(gint)nA;i++)
4978 	{
4979 		gint ni = geometry[i].N-1;
4980 		if(geometry[addToI].typeConnections[ni]>0)
4981 		{
4982 			nAll += 1;
4983 		}
4984 	}
4985 	if(!strcmp(geometry[addToI].Prop.symbol,"N")) nV++;
4986 
4987 	for(i=0;i<10;i++)
4988 		hAtoms[i] = g_malloc(sizeof(gchar)*100);
4989 	nH = getHydrogensFromPDBTpl(geometry[addToI].Residue,geometry[addToI].pdbType, hAtoms);
4990 	nH -= nOldH;
4991 
4992 	if(nH<1)
4993 	{
4994 		for(i=0;i<10;i++)
4995 			g_free(hAtoms[i]);
4996 		return;
4997 	}
4998 
4999 	if(begin==0)
5000 	{
5001 		begin++;
5002 		propH = prop_atom_get("H");
5003 	}
5004 	dist = (geometry[addToI].Prop.covalentRadii+propH.covalentRadii)*0.9;
5005 	listOfConnectedAtoms = g_malloc(nV*sizeof(gint));
5006 
5007 	if(Natoms>0)
5008 	{
5009 		geometry0 = g_realloc(geometry0,(Natoms+nH)*sizeof(GeomDef));
5010 		geometry = g_realloc(geometry,(Natoms+nH)*sizeof(GeomDef));
5011 	}
5012 	else
5013 	{
5014 		geometry0 = g_malloc(nH*sizeof(GeomDef));
5015 		geometry = g_malloc(nH*sizeof(GeomDef));
5016 	}
5017 
5018 
5019 	nC = 0;
5020 	for(i=0;i<(gint)nA;i++)
5021 	{
5022 		gint ni = geometry[i].N-1;
5023 		if(geometry[addToI].typeConnections[ni]>0)
5024 		{
5025 			listOfConnectedAtoms[nC] = i;
5026 			nC++;
5027 		}
5028 	}
5029 
5030 	for(i=0;i<nH;i++)
5031 	{
5032 		gdouble v1[3];
5033 		gdouble v2[3];
5034 		gdouble v3[3];
5035 		gdouble v4[3];
5036 		gdouble v5[3];
5037 		for(k=0;k<3;k++)
5038 			v1[k] = rand()/(gdouble)RAND_MAX-0.5;
5039 		v3d_normal(v1);
5040 
5041 		switch (nC)
5042 		{
5043 			case 1:
5044 				{
5045 					set_vect_ij(addToI, listOfConnectedAtoms[0], v2);
5046 					v3d_normal(v2);
5047 					v3d_cross(v1,v2,v3);
5048 					v3d_normal(v3);
5049 					v3d_scale(v2,cos(angle));
5050 					v3d_scale(v3,sin(angle));
5051 					v3d_add(v2,v3,v1);
5052 					break;
5053 				}
5054 			case 2:
5055 				{
5056 					set_vect_ij(addToI, listOfConnectedAtoms[0], v2);
5057 					v3d_normal(v2);
5058 					set_vect_ij(addToI, listOfConnectedAtoms[1], v3);
5059 					v3d_normal(v3);
5060 					if(geom==0)
5061 					{
5062 						v3d_add(v2,v3,v4);
5063 						v3d_normal(v4);
5064 						v3d_scale(v4,-1.0);
5065 						v3d_cross(v2,v3,v5);
5066 						v3d_normal(v5);
5067 						v3d_scale(v4,0.5);
5068 						v3d_scale(v5,0.5);
5069 						v3d_add(v4,v5,v1);
5070 						v3d_normal(v1);
5071 					}
5072 					else
5073 					{
5074 						v3d_add(v2,v3,v1);
5075 						v3d_normal(v1);
5076 						v3d_scale(v1,-1.0);
5077 					}
5078 					break;
5079 				}
5080 			default:
5081 				if(nC>=3)
5082 				{
5083 					set_vect_ij(addToI, listOfConnectedAtoms[nC-3], v2);
5084 					v3d_normal(v2);
5085 					set_vect_ij(addToI, listOfConnectedAtoms[nC-2], v3);
5086 					v3d_normal(v3);
5087 					set_vect_ij(addToI, listOfConnectedAtoms[nC-1], v4);
5088 					v3d_normal(v4);
5089 					v3d_add(v2,v3,v5);
5090 					v3d_add(v5,v4,v1);
5091 					v3d_normal(v1);
5092 					v3d_scale(v1,-1.0);
5093 					break;
5094 				}
5095 
5096 		}
5097 		geometry[Natoms].X= geometry0[addToI].X + dist*v1[0];
5098 		geometry[Natoms].Y= geometry0[addToI].Y + dist*v1[1];
5099 		geometry[Natoms].Z= geometry0[addToI].Z + dist*v1[2];
5100 		geometry[Natoms].Prop = prop_atom_get("H");
5101 		geometry[Natoms].mmType = g_strdup(hAtoms[i]);
5102 		geometry[Natoms].pdbType = g_strdup(hAtoms[i]);
5103 		geometry[Natoms].Layer = geometry[addToI].Layer;
5104 		geometry[Natoms].N = Natoms+1;
5105 		geometry[Natoms].typeConnections = NULL;
5106 		if(Natoms==0)
5107 		{
5108 			geometry[Natoms].Residue = g_strdup("H");
5109 			geometry[Natoms].ResidueNumber = 0;
5110 		}
5111 		else
5112 		{
5113 			geometry[Natoms].Residue = g_strdup(geometry[addToI].Residue);
5114 			geometry[Natoms].ResidueNumber = geometry[addToI].ResidueNumber;
5115 		}
5116 		geometry[Natoms].Charge = 0.0;
5117 		geometry[Natoms].Variable = TRUE;
5118 		geometry[Natoms].show = ShowHydrogenAtoms;
5119 
5120 		geometry0[Natoms].X = geometry[Natoms].X;
5121 		geometry0[Natoms].Y = geometry[Natoms].Y;
5122 		geometry0[Natoms].Z = geometry[Natoms].Z;
5123 		geometry0[Natoms].Prop = prop_atom_get("H");
5124 		geometry0[Natoms].mmType = g_strdup(geometry[Natoms].mmType);
5125 		geometry0[Natoms].pdbType = g_strdup(geometry[Natoms].pdbType);
5126 		geometry0[Natoms].Layer = geometry[Natoms].Layer;
5127 		geometry0[Natoms].Residue = g_strdup(geometry[Natoms].Residue);
5128 		geometry0[Natoms].ResidueNumber = geometry[Natoms].ResidueNumber;
5129 		geometry0[Natoms].Charge = 0.0;
5130 		geometry0[Natoms].Variable = TRUE;
5131 		geometry0[Natoms].N = geometry[Natoms].N;
5132 		geometry0[Natoms].show = geometry[Natoms].show;
5133 		geometry0[Natoms].typeConnections = NULL;
5134 
5135 		Natoms++;
5136 
5137 		nC++;
5138 		listOfConnectedAtoms = g_realloc(listOfConnectedAtoms, nC*sizeof(gint));
5139 		listOfConnectedAtoms[nC-1] = Natoms-1;
5140 	}
5141 	{
5142 		gint i,j;
5143 		for(i=0;i<(gint)Natoms-nH;i++)
5144 		{
5145 			geometry[i].typeConnections = g_realloc(geometry[i].typeConnections,Natoms*sizeof(gint));
5146 			for(j=Natoms-nH;j<(gint)Natoms;j++) geometry[i].typeConnections[j] = 0;
5147 			geometry0[i].typeConnections = g_realloc(geometry0[i].typeConnections,Natoms*sizeof(gint));
5148 			for(j=Natoms-nH;j<(gint)Natoms;j++) geometry0[i].typeConnections[j] = 0;
5149 		}
5150 		for(i=(gint)Natoms-nH;i<(gint)Natoms;i++)
5151 		{
5152 			geometry[i].typeConnections = g_malloc(Natoms*sizeof(gint));
5153 			for(j=0;j<(gint)Natoms;j++) geometry[i].typeConnections[j] = 0;
5154 			geometry0[i].typeConnections = g_malloc(Natoms*sizeof(gint));
5155 			for(j=0;j<(gint)Natoms;j++) geometry0[i].typeConnections[j] = 0;
5156 		}
5157 		for(i=(gint)Natoms-nH;i<(gint)Natoms;i++)
5158 		{
5159 			geometry[addToI].typeConnections[geometry[i].N-1] = 1;
5160 			geometry0[addToI].typeConnections[geometry0[i].N-1] = 1;
5161 			geometry[i].typeConnections[geometry[addToI].N-1] = 1;
5162 			geometry0[i].typeConnections[geometry0[addToI].N-1] = 1;
5163 		}
5164 		adjust_multiple_bonds_with_one_atom(addToI);
5165 	}
5166 	if(listOfConnectedAtoms) g_free(listOfConnectedAtoms);
5167 	for(i=0;i<10;i++)
5168 		g_free(hAtoms[i]);
5169 }
5170 /********************************************************************************/
addHydrogensTpl()5171 void addHydrogensTpl()
5172 {
5173 	gint i;
5174 	gint k = 0;
5175 	gint nA = Natoms;
5176 
5177 
5178 	if(Natoms<1) return;
5179 	if(!NumFatoms) SelectAllAtoms();
5180 	if(NFatoms<1) return;
5181 	if(!NumFatoms) return;
5182 
5183 	for (k=0;k<(gint)NFatoms;k++)
5184 	for (i=0;i<(gint)nA;i++)
5185 	{
5186 		if(geometry[i].N== NumFatoms[k])
5187 		{
5188 			add_hydrogen_atoms_tpl(i,nA);
5189 			break;
5190 		}
5191 	}
5192 	setMMTypesChargesFromPDBTpl(2);
5193 	create_GeomXYZ_from_draw_grometry();
5194 	reset_charges_multiplicities();
5195 	RebuildGeom=TRUE;
5196 	drawGeom();
5197 }
5198 /********************************************************************************/
DeleteMolecule()5199 void DeleteMolecule()
5200 {
5201 	gchar *t =N_("Do you want to really destroy this molecule?");
5202 	if(Natoms>0)
5203 		Continue_YesNo(delete_molecule, NULL,t);
5204 	else
5205 		Message(_("No molecule to delete\n"),_("Warning"),TRUE);
5206 }
5207 /********************************************************************************/
SetOriginAtCenter(gpointer data,guint Operation,GtkWidget * wid)5208 void SetOriginAtCenter(gpointer data, guint Operation,GtkWidget* wid)
5209 {
5210 	gdouble C[3];
5211 	gint i;
5212 	gint n=0;
5213 
5214 	if(Natoms<1) return;
5215 
5216 	for(i=0;i<3;i++) C[i] = 0.0;
5217 
5218 	for(i=0;i<(gint)Natoms;i++)
5219 	{
5220 		if(mystrcasestr(geometry0[i].Prop.symbol,"TV"))  continue;
5221 		C[0] += geometry0[i].X;
5222 		C[1] += geometry0[i].Y;
5223 		C[2] += geometry0[i].Z;
5224 		n++;
5225 	}
5226 	if(n>0) for(i=0;i<3;i++) C[i] /= n;
5227 
5228 	for(i=0;i<(gint)Natoms;i++)
5229 	{
5230 		if(mystrcasestr(geometry0[i].Prop.symbol,"TV"))
5231 		{
5232 		 geometry0[i].X -= C[0]-Orig[0];
5233 		 geometry0[i].Y -= C[1]-Orig[1];
5234 		 geometry0[i].Z -= C[2]-Orig[2];
5235 		}
5236 		else
5237 		{
5238 		 geometry0[i].X -= C[0];
5239 		 geometry0[i].Y -= C[1];
5240 		 geometry0[i].Z -= C[2];
5241 		}
5242 	}
5243 	Ddef = FALSE;
5244 	Trans[0] = 0;
5245 	Trans[0] = 0;
5246         for(i=0;i<3;i++) Orig[i] = 0;
5247 
5248 	copyCoordinates2to1(geometry, geometry0);
5249 
5250 	RebuildGeom=TRUE;
5251 	drawGeom();
5252 	set_statubar_pop_sel_atom();
5253 	create_GeomXYZ_from_draw_grometry();
5254 
5255 	return;
5256 }
5257 /********************************************************************************/
TraitementGeom(gpointer data,guint Operation,GtkWidget * wid)5258 void TraitementGeom(gpointer data, guint Operation,GtkWidget* wid)
5259 {
5260   switch((GabEditGeomOperation)Operation)
5261   {
5262 	case SAVEJPEG:
5263  		file_chooser_save(save_geometry_jpeg_file,_("Save image in jpeg file format"),GABEDIT_TYPEFILE_JPEG,GABEDIT_TYPEWIN_GEOM);
5264 		break;
5265 	case SAVEPPM:
5266  		file_chooser_save(save_geometry_ppm_file,_("Save image in ppm file format"),GABEDIT_TYPEFILE_PPM,GABEDIT_TYPEWIN_GEOM);
5267 		break;
5268 	case SAVEBMP:
5269  		file_chooser_save(save_geometry_bmp_file,_("Save image in bmp file format"),GABEDIT_TYPEFILE_BMP,GABEDIT_TYPEWIN_GEOM);
5270 		break;
5271 	case SAVEPS:
5272  		file_chooser_save(save_geometry_ps_file,_("Save image in ps file format"),GABEDIT_TYPEFILE_PS,GABEDIT_TYPEWIN_GEOM);
5273 		break;
5274 	default:
5275 		printf("Operation = %d\n",Operation);
5276   }
5277 }
5278 /********************************************************************************/
get_drawing_pixmap()5279 GdkPixmap *get_drawing_pixmap()
5280 {
5281   return NULL;
5282 }
5283 /********************************************************************************/
get_drawing_cairo()5284 cairo_t *get_drawing_cairo()
5285 {
5286   return cr;
5287 }
5288 /********************************************************************************/
get_drawing_colormap()5289 GdkColormap* get_drawing_colormap()
5290 {
5291   GdkColormap *colormap = gdk_drawable_get_colormap(GeomDrawingArea->window);
5292 
5293   return colormap;
5294 }
5295 /********************************************************************************/
read_geometries_convergence(gpointer data,guint Operation,GtkWidget * wid)5296 void read_geometries_convergence(gpointer data, guint Operation,GtkWidget* wid)
5297 {
5298 	switch(Operation)
5299 	{
5300 		case FGEOMCONVDALTON:
5301  			  	  file_chooser_open(read_geometries_conv_dalton,_("Load Geom. Conv. From Dalton Output file"),
5302 				  GABEDIT_TYPEFILE_DALTON,GABEDIT_TYPEWIN_GEOM);
5303 				  break;
5304 		case FGEOMCONVGAMESS:
5305  			  	  file_chooser_open(read_geometries_conv_dalton,_("Load Geom. Conv. From Gamess Output file"),
5306 				  GABEDIT_TYPEFILE_GAMESS,GABEDIT_TYPEWIN_GEOM);
5307 				  break;
5308 		case FGEOMCONVGAUSS:
5309  			  	  file_chooser_open(read_geometries_conv_gaussian,_("Load Geom. Conv. From Gaussian Output file"),
5310 				  GABEDIT_TYPEFILE_GAUSSIAN,GABEDIT_TYPEWIN_GEOM);
5311 				  break;
5312 		case FGEOMCONVMOLPRO:
5313  			  	  file_chooser_open(read_geometries_conv_molpro,_("Load Geom. Conv. From Molpro log file"),
5314 				  GABEDIT_TYPEFILE_MOLPRO_LOG,GABEDIT_TYPEWIN_GEOM);
5315 				  break;
5316 		case FGEOMCONVMOLDEN:
5317  			  	  file_chooser_open(read_geometries_conv_molden,_("Load Geom. Conv. From Molden file"),
5318 				  GABEDIT_TYPEFILE_MOLDEN,GABEDIT_TYPEWIN_GEOM);
5319 				  break;
5320 		case FGEOMCONVGABEDIT:
5321  			  	  file_chooser_open(read_geometries_conv_gabedit,_("Load Geom. Conv. From Gabedit file"),
5322 				  GABEDIT_TYPEFILE_GABEDIT,GABEDIT_TYPEWIN_GEOM);
5323 				  break;
5324 		case FGEOMCONVMPQC:
5325  			  	  file_chooser_open(read_geometries_conv_mpqc,_("Load Geom. Conv. From MPQC output file"),
5326 				  GABEDIT_TYPEFILE_MPQC,GABEDIT_TYPEWIN_GEOM);
5327 				  break;
5328 		case FGEOMCONVXYZ:
5329  			  	  file_chooser_open(read_geometries_conv_xyz,_("Load Geom. Conv. From XYZ"),
5330 				  GABEDIT_TYPEFILE_XYZ,GABEDIT_TYPEWIN_GEOM);
5331 				  break;
5332 		default : break;
5333 	}
5334 }
5335 /********************************************************************************/
save_geometry(gpointer data,guint Operation,GtkWidget * wid)5336 void save_geometry(gpointer data, guint Operation,GtkWidget* wid)
5337 {
5338 	if(Natoms<1)
5339 	{
5340 		Message(_("Sorry,No molecule to save\n"),_("Warning"),TRUE);
5341 		return;
5342 	}
5343 	switch(Operation)
5344 	{
5345 		case FXYZ 	: create_GeomXYZ_from_draw_grometry();
5346  			  	  file_chooser_save(save_geometry_xyz_file,_("Save geometry in xyz file"),
5347 				  GABEDIT_TYPEFILE_XYZ,GABEDIT_TYPEWIN_GEOM);
5348 				  break;
5349 		case FMOL2 	: create_GeomXYZ_from_draw_grometry();
5350  			  	  file_chooser_save(save_geometry_mol2_file,_("Save geometry in mol2 file"),
5351 				  GABEDIT_TYPEFILE_MOL2,GABEDIT_TYPEWIN_GEOM);
5352 				  break;
5353 		case FTINKER 	: create_GeomXYZ_from_draw_grometry();
5354  			  	  file_chooser_save(save_geometry_tinker_file,_("Save geometry in tinker file"),
5355 				  GABEDIT_TYPEFILE_TINKER,GABEDIT_TYPEWIN_GEOM);
5356 				  break;
5357 		case FPDB 	: create_GeomXYZ_from_draw_grometry();
5358  			  	  file_chooser_save(save_geometry_pdb_file,_("Save geometry in pdb file"),
5359 				  GABEDIT_TYPEFILE_PDB,GABEDIT_TYPEWIN_GEOM);
5360 				  break;
5361 		case FHIN 	: create_GeomXYZ_from_draw_grometry();
5362  			  	  file_chooser_save(save_geometry_hin_file,_("Save geometry in hyperchem file"),
5363 				  GABEDIT_TYPEFILE_HIN,GABEDIT_TYPEWIN_GEOM);
5364 				  break;
5365 		case FGABEDIT 	: create_GeomXYZ_from_draw_grometry();
5366  			  	  file_chooser_save(save_geometry_gabedit_file,_("Save geometry in gabedit file"),
5367 				  GABEDIT_TYPEFILE_GABEDIT,GABEDIT_TYPEWIN_GEOM);
5368 				  break;
5369 		case FMZMAT 	: create_GeomXYZ_from_draw_grometry();
5370 				  if(!xyz_to_zmat())
5371 				  {
5372 					Message(_("Sorry\nConversion is not possible from XYZ to Zmat"),_("Error"),TRUE);
5373 					return;
5374 				  }
5375  			  	  file_chooser_save(save_geometry_mzmatrix_file,_("Save geometry in mopac z-matrix file"),
5376 				  GABEDIT_TYPEFILE_MZMAT,GABEDIT_TYPEWIN_GEOM);
5377 				  create_GeomXYZ_from_draw_grometry();
5378 				  MethodeGeom = GEOM_IS_XYZ;
5379 				  break;
5380 		case FGZMAT 	: create_GeomXYZ_from_draw_grometry();
5381 				  if(!xyz_to_zmat())
5382 				  {
5383 					Message(_("Sorry\nConversion is not possible from XYZ to Zmat"),_("Error"),TRUE);
5384 					return;
5385 				  }
5386  			  	  file_chooser_save(save_geometry_gzmatrix_file,_("Save geometry in gaussian z-matrix file"),
5387 				  GABEDIT_TYPEFILE_GZMAT,GABEDIT_TYPEWIN_GEOM);
5388 				  create_GeomXYZ_from_draw_grometry();
5389 				  MethodeGeom = GEOM_IS_XYZ;
5390 				  break;
5391 		default : break;
5392 	}
5393 }
5394 /********************************************************************************/
read_geometry(gpointer data,guint Operation,GtkWidget * wid)5395 void read_geometry(gpointer data, guint Operation,GtkWidget* wid)
5396 {
5397 	switch(Operation)
5398 	{
5399 		case FXYZ 	:  MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_XYZ);break;
5400 		case FGZMAT 	:  MethodeGeom = GEOM_IS_ZMAT;selc_ZMatrix_file();break;
5401 		case FMZMAT 	:  MethodeGeom = GEOM_IS_ZMAT;selc_ZMatrix_mopac_file();break;
5402 		case FMOL2 	:  MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_MOL2);break;
5403 		case FTINKER 	: MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_TINKER);break;
5404 		case FPDB 	: MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_PDB);break;
5405 		case FHIN 	: MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_HIN);break;
5406 
5407 		case FDALTONIN : break;
5408 		case FDALTONFIRST: MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_DALTONFIRST);break;
5409 		case FDALTONLAST : MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_DALTONLAST);break;
5410 
5411 		case FGAUSSIN : selc_all_input_file(_("Read Geometry from a Gaussian input file"));break;
5412 		case FGAUSSOUTFIRST: MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_GAUSSOUTFIRST);break;
5413 		case FGAUSSOUTLAST : MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_GAUSSOUTLAST);break;
5414 
5415 		case FMOLCASIN : selc_all_input_file(_("Read Geometry from a Molcas input file"));break;
5416 		case FMOLCASOUTFIRST: MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_MOLCASOUTFIRST);break;
5417 		case FMOLCASOUTLAST : MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_MOLCASOUTLAST);break;
5418 
5419 		case FMOLPROIN : selc_all_input_file(_("Read Geometry from a Molpro input file"));break;
5420 		case FMOLPROOUTFIRST: MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_MOLPROOUTFIRST);break;
5421 		case FMOLPROOUTLAST : MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_MOLPROOUTLAST);break;
5422 
5423 		case FMPQCIN : selc_all_input_file(_("Read Geometry from a MPQC input file"));break;
5424 		case FMPQCOUTFIRST: MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_MPQCOUTFIRST);break;
5425 		case FMPQCOUTLAST : MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_MPQCOUTLAST);break;
5426 	}
5427 }
5428 /********************************************************************************/
label_option()5429 guint label_option()
5430 {
5431 	return LabelOption;
5432 }
5433 /********************************************************************************/
dipole_draw_mode()5434 gboolean dipole_draw_mode()
5435 {
5436 	return DrawDipole;
5437 }
5438 /********************************************************************************/
ortho_mode()5439 gboolean ortho_mode()
5440 {
5441 	return ortho;
5442 }
5443 /********************************************************************************/
distances_draw_mode()5444 gboolean distances_draw_mode()
5445 {
5446 	return DrawDistance;
5447 }
5448 /********************************************************************************/
dipole_mode()5449 gboolean dipole_mode()
5450 {
5451 	return ShowDipole;
5452 }
5453 /********************************************************************************/
stick_mode()5454 gboolean stick_mode()
5455 {
5456 	if( TypeGeom == GABEDIT_TYPEGEOM_STICK ) return TRUE;
5457 	return FALSE;
5458 }
5459 /********************************************************************************/
space_fill_mode()5460 gboolean space_fill_mode()
5461 {
5462 	if( TypeGeom == GABEDIT_TYPEGEOM_SPACE ) return TRUE;
5463 	return FALSE;
5464 }
5465 /********************************************************************************/
pers_mode()5466 gboolean pers_mode()
5467 {
5468 	return PersMode;
5469 }
5470 /********************************************************************************/
shad_mode()5471 gboolean shad_mode()
5472 {
5473 	return ShadMode;
5474 }
5475 /********************************************************************************/
light_mode()5476 gboolean light_mode()
5477 {
5478 	return LightMode;
5479 }
5480 /********************************************************************************/
ortep_mode()5481 gboolean ortep_mode()
5482 {
5483 	return OrtepMode;
5484 }
5485 /********************************************************************************/
cartoon_mode()5486 gboolean cartoon_mode()
5487 {
5488 	return CartoonMode;
5489 }
5490 /********************************************************************************/
get_frag_angle()5491 gdouble get_frag_angle()
5492 {
5493 	return fragAngle;
5494 }
5495 /********************************************************************************/
set_frag_angle(gdouble a)5496 void set_frag_angle(gdouble a)
5497 {
5498 	fragAngle = a;
5499 }
5500 /********************************************************************************/
set_HBonds_dialog_geom(GtkWidget * win,guint data)5501 void set_HBonds_dialog_geom(GtkWidget *win, guint data)
5502 {
5503 	set_HBonds_dialog (GeomDlg);
5504 }
5505 /********************************************************************************/
set_povray_options_geom(GtkWidget * win,guint data)5506 void set_povray_options_geom(GtkWidget *win, guint data)
5507 {
5508 	 createPovrayOptionsWindow(GeomDlg);
5509 }
5510 /********************************************************************************/
HideShowMeasure(gboolean hiding)5511 void HideShowMeasure(gboolean hiding)
5512 {
5513 	if(hiding)
5514 	{
5515   		gtk_widget_hide(vboxhandle);
5516   		gtk_widget_hide(GeomDrawingArea);
5517   		gtk_widget_show(GeomDrawingArea);
5518     		while( gtk_events_pending() ) gtk_main_iteration();
5519 	}
5520 	else gtk_widget_show(vboxhandle);
5521 
5522    	MeasureIsHide=hiding;
5523 }
5524 /********************************************************************************/
AdjustHydrogensYesNo(gboolean adjust)5525 void AdjustHydrogensYesNo(gboolean adjust)
5526 {
5527 	AdjustHydrogenAtoms = adjust;
5528 }
5529 /********************************************************************************/
getAdjustHydrogensYesNo()5530 gboolean getAdjustHydrogensYesNo()
5531 {
5532 	return AdjustHydrogenAtoms;
5533 }
5534 /********************************************************************************/
RebuildConnectionsDuringEditionYesNo(gboolean rebuild)5535 void RebuildConnectionsDuringEditionYesNo(gboolean rebuild)
5536 {
5537 	RebuildConnectionsDuringEdition = rebuild;
5538 }
5539 /********************************************************************************/
getRebuildConnectionsDuringEditionYesNo()5540 gboolean getRebuildConnectionsDuringEditionYesNo()
5541 {
5542 	return RebuildConnectionsDuringEdition;
5543 }
5544 /********************************************************************************/
ScaleByMouse(gpointer data)5545 static gint ScaleByMouse(gpointer data)
5546 {
5547 	GdkEventButton *bevent=(GdkEventButton *)data;
5548 	gdouble height = GeomDrawingArea->allocation.height;
5549 
5550         switch(OperationType)
5551         {
5552 	case SCALEGEOM :
5553 			Zoom -= ((bevent->y - BeginY) / height) * 40;
5554 			if (Zoom < 0.1) Zoom = 0.1;
5555 			if (Zoom > 500) Zoom = 500;
5556 			drawGeom();
5557 		break;
5558 	case SCALESTICK :
5559 			factorstick +=((bevent->y - BeginY) / GeomDrawingArea->allocation.height) * 5;
5560 			if(factorstick <0.1) factorstick  = 0.1;
5561 			if(factorstick >10) factorstick = 10;
5562 			RebuildGeom=TRUE;
5563 			drawGeom();
5564 
5565 		break;
5566 	case SCALEBALL :
5567 			factorball +=((bevent->y - BeginY) / GeomDrawingArea->allocation.height) * 5;
5568 			if(factorball <0.1) factorball  = 0.1;
5569 			if(factorball >10) factorball = 10;
5570 			RebuildGeom=TRUE;
5571 			drawGeom();
5572 		break;
5573 	case SCALEDIPOLE :
5574 			factordipole +=((bevent->y - BeginY) / GeomDrawingArea->allocation.height) * 5;
5575 			if(factordipole <0.1) factordipole  = 0.1;
5576 			if(factordipole >100) factordipole = 100;
5577 			RebuildGeom=TRUE;
5578 			drawGeom();
5579 		break;
5580 	default : break;
5581 
5582         }
5583 	BeginX = bevent->x;
5584 	BeginY = bevent->y;
5585 
5586 
5587  	return TRUE;
5588 }
5589 /********************************************************************************/
TranslationByMouse(GtkWidget * widget,GdkEventMotion * event)5590 static gint TranslationByMouse(GtkWidget *widget, GdkEventMotion *event)
5591 {
5592 	int x, y;
5593 	GdkModifierType state;
5594 	gdouble width, height;
5595 
5596 	if (event->is_hint)
5597 	{
5598 #if !defined(G_OS_WIN32)
5599 		gdk_window_get_pointer(event->window, &x, &y, &state);
5600 #else
5601 		x = event->x;
5602 		y = event->y;
5603 		state = event->state;
5604 #endif
5605 	}
5606 	else
5607 	{
5608 		x = event->x;
5609 		y = event->y;
5610 		state = event->state;
5611 	}
5612 
5613 	width  = widget->allocation.width;
5614 	height = widget->allocation.height;
5615 
5616 	Trans[0] += ((x - BeginX) / width) * 40;
5617 	Trans[1] += ((BeginY - y) / height) * 40;
5618 
5619 	drawGeom();
5620 
5621 	BeginX = x;
5622 	BeginY = y;
5623  return TRUE;
5624 }
5625 /********************************************************************************/
RotationByMouse(GtkWidget * widget,GdkEventMotion * event)5626 static gint RotationByMouse(GtkWidget *widget, GdkEventMotion *event)
5627 {
5628 	int x, y;
5629 	GdkRectangle area;
5630 	GdkModifierType state;
5631 	gdouble spin_quat[4];
5632 
5633 	if (event->is_hint)
5634 	{
5635 #if !defined(G_OS_WIN32)
5636 		gdk_window_get_pointer(event->window, &x, &y, &state);
5637 #else
5638 		x = event->x;
5639 		y = event->y;
5640 		state = event->state;
5641 #endif
5642 	}
5643 	else
5644 	{
5645 		x = event->x;
5646 		y = event->y;
5647 		state = event->state;
5648 	}
5649 
5650 	area.x = 0;
5651 	area.y = 0;
5652 	area.width  = widget->allocation.width;
5653 	area.height = widget->allocation.height;
5654 
5655 
5656 	trackball(spin_quat,
5657 		(2.0*BeginX  - area.width) / area.width,
5658 		(area.height - 2.0*BeginY) / area.height,
5659 		(2.0*x       - area.width) / area.width,
5660 		(area.height - 2.0*y     ) / area.height);
5661 	add_quats(spin_quat, Quat, Quat);
5662 	drawGeom();
5663 
5664 	BeginX = x;
5665 	BeginY = y;
5666  return TRUE;
5667 }
5668 /********************************************************************************/
RotationZByMouse(GtkWidget * widget,GdkEventMotion * event)5669 static gint RotationZByMouse(GtkWidget *widget, GdkEventMotion *event)
5670 {
5671 	int x, y;
5672 	GdkModifierType state;
5673 	gdouble spin_quat[4] = {0,0,0,0};
5674 	gdouble phi = 1.0/180*PI;
5675 	gdouble width;
5676 	gdouble height;
5677 	gint Xi;
5678 	gint Yi;
5679 
5680 	if (event->is_hint)
5681 	{
5682 #if !defined(G_OS_WIN32)
5683 		gdk_window_get_pointer(event->window, &x, &y, &state);
5684 #else
5685 		x = event->x;
5686 		y = event->y;
5687 		state = event->state;
5688 #endif
5689 	}
5690 	else
5691 	{
5692 		x = event->x;
5693 		y = event->y;
5694 		state = event->state;
5695 	}
5696 
5697 	width  = widget->allocation.width;
5698 	height = widget->allocation.height;
5699 
5700 	Xi = width/2 + Trans[0];
5701 	Yi = height/2 + Trans[1];
5702 
5703 
5704 	if(abs(BeginX-x)>abs(BeginY-y))
5705 	 {
5706 		  gdouble sign  = 1.0;
5707 		  if(BeginY> Yi && BeginX<x) sign = -1;
5708 		  if(BeginY< Yi && BeginX>x) sign = -1;
5709 		  phi = sign* fabs(BeginX-x)/width*PI;
5710 	  }
5711 	  else
5712 	  {
5713 		  gdouble sign = 1.0;
5714 		  if(BeginX> Xi && BeginY>y) sign = -1;
5715 		  if(BeginX< Xi && BeginY<y) sign = -1;
5716 		  phi = sign* fabs(BeginY-y)/height*PI;
5717 	  }
5718 	spin_quat[2] = 1.0;
5719 	phi /=10;
5720 
5721 	spin_quat[2]= sin(phi/2);
5722 	spin_quat[3] = cos(phi/2);
5723 
5724 	add_quats(spin_quat, Quat, Quat);
5725 	drawGeom();
5726 
5727 	BeginX = x;
5728 	BeginY = y;
5729 	return TRUE;
5730 }
5731 /********************************************************************************/
rotation_fragment_quat(gdouble m[4][4],gdouble C[])5732 static void rotation_fragment_quat(gdouble m[4][4],gdouble C[])
5733 {
5734 	gdouble A[3];
5735 	gdouble B[3];
5736 	guint i,j,k;
5737 	gdouble M[4][4];
5738 	gdouble O[3];
5739 	gdouble mr[3][3];
5740 	gdouble mrinv[3][3];
5741 
5742 	build_rotmatrix(M,Quat);
5743 	for (i=0;i<Natoms;i++)
5744 	{
5745 		A[0] = geometry[i].X-C[0];
5746 		A[1] = geometry[i].Y-C[1];
5747 		A[2] = geometry[i].Z-C[2];
5748 		for(j=0;j<3;j++)
5749 		{
5750 			B[j] = 0.0;
5751 			for(k=0;k<3;k++)
5752 				B[j] += M[k][j]*A[k];
5753 		}
5754 		geometry[i].X=B[0];
5755 		geometry[i].Y=B[1];
5756 		geometry[i].Z=B[2];
5757 	}
5758 	for (i=0;i<Natoms;i++)
5759 	{
5760 		if(if_selected(i))
5761 		{
5762 			A[0] = geometry[i].X;
5763 			A[1] = geometry[i].Y;
5764 			A[2] = geometry[i].Z;
5765 			for(j=0;j<3;j++)
5766 			{
5767 				B[j] = 0.0;
5768 				for(k=0;k<3;k++)
5769 					B[j] += m[k][j]*A[k];
5770 			}
5771 			geometry[i].X=B[0];
5772 			geometry[i].Y=B[1];
5773 			geometry[i].Z=B[2];
5774 		}
5775 	}
5776 	for(i=0;i<3;i++)
5777 		for(j=0;j<3;j++)
5778 			mr[i][j] = M[i][j];
5779 
5780 	if(InverseMat3D(mrinv, mr))
5781 	//if(1==2)
5782 	{
5783 		for (i=0;i<Natoms;i++)
5784 		{
5785 			A[0] = geometry[i].X;
5786 			A[1] = geometry[i].Y;
5787 			A[2] = geometry[i].Z;
5788 			for(j=0;j<3;j++)
5789 			{
5790 				B[j] = 0.0;
5791 				for(k=0;k<3;k++)
5792 					B[j] += mrinv[k][j]*A[k];
5793 			}
5794 			geometry[i].X=B[0]+C[0];
5795 			geometry[i].Y=B[1]+C[1];
5796 			geometry[i].Z=B[2]+C[2];
5797 		}
5798 		init_quat(QuatFrag);
5799 	}
5800 	else
5801 	{
5802 		for(i=0;i<3;i++) O[i] = Orig[i];
5803 		for(j=0;j<3;j++)
5804 		{
5805 			B[j] = 0.0;
5806 			for(k=0;k<3;k++)
5807 				B[j] += M[k][j]*O[k];
5808 		}
5809 		for(i=0;i<3;i++) Orig[i] = B[i];
5810 		init_quat(Quat);
5811 		init_quat(QuatFrag);
5812 	}
5813 
5814 	Ddef = FALSE;
5815 	for (i=0;i<Natoms;i++)
5816 	{
5817 		geometry0[i].X=geometry[i].X;
5818 		geometry0[i].Y=geometry[i].Y;
5819 		geometry0[i].Z=geometry[i].Z;
5820 	}
5821 
5822 }
5823 /********************************************************************************/
local_zrotate_fragment(GtkWidget * widget,GdkEventMotion * event)5824 static gint local_zrotate_fragment(GtkWidget *widget, GdkEventMotion *event)
5825 {
5826 	int x, y;
5827 	GdkModifierType state;
5828 	gdouble spin_quat[4] = {0,0,0,0};
5829 	gdouble m[4][4];
5830 	gdouble C[3]={0,0,0};/* Center of Fragment */
5831 	gint i;
5832 	gint j;
5833 	gint k;
5834 	gint Xi;
5835 	gint Yi;
5836 	gdouble width;
5837 	gdouble height;
5838 	gdouble phi = 1.0/180*PI;
5839 	gdouble ModelView[16];
5840 	gdouble ProjView[16];
5841 	gint Viewport[4];
5842 	GLdouble View2D[3];
5843 
5844 	glGetDoublev(GL_MODELVIEW_MATRIX, ModelView);
5845 	glGetDoublev(GL_PROJECTION_MATRIX, ProjView);
5846 	glGetIntegerv(GL_VIEWPORT, Viewport);
5847 
5848 	j=0;
5849 	for (i=0;i<(gint)Natoms;i++)
5850 	{
5851 		if(if_selected(i))
5852 		{
5853 			j++;
5854 			C[0] += geometry[i].X;
5855 			C[1] += geometry[i].Y;
5856 			C[2] += geometry[i].Z;
5857 		}
5858 	}
5859 	if(j<1) return FALSE;
5860 
5861 	for(k=0;k<3;k++) C[k] /= (gdouble)j;
5862 
5863 	gluProject(C[0], C[1], C[2],ModelView, ProjView, Viewport, &View2D[0], &View2D[1], &View2D[2]);
5864 
5865 	Xi = View2D[0];
5866 	Yi = viewport[3]-View2D[1];
5867 
5868 	Xi = Xi + Trans[0];
5869 	Yi = Yi + Trans[1];
5870 
5871 	if (event->is_hint)
5872 	{
5873 #if !defined(G_OS_WIN32)
5874 		gdk_window_get_pointer(event->window, &x, &y, &state);
5875 #else
5876 		x = event->x;
5877 		y = event->y;
5878 		state = event->state;
5879 		gdk_window_get_pointer(event->window, &x, &y, &state);
5880 #endif
5881 	}
5882 	else
5883 	{
5884 		x = event->x;
5885 		y = event->y;
5886 		state = event->state;
5887 	}
5888 
5889 	width  = widget->allocation.width;
5890 	height = widget->allocation.height;
5891 
5892 	if(abs(BeginX-x)>abs(BeginY-y))
5893 	 {
5894 		  gdouble sign  = 1.0;
5895 		  if(BeginY> Yi && BeginX<x) sign = -1;
5896 		  if(BeginY< Yi && BeginX>x) sign = -1;
5897 		  phi = sign* fabs(BeginX-x)/width*PI;
5898 	  }
5899 	  else
5900 	  {
5901 		  gdouble sign = 1.0;
5902 		  if(BeginX> Xi && BeginY>y) sign = -1;
5903 		  if(BeginX< Xi && BeginY<y) sign = -1;
5904 		  phi = sign* fabs(BeginY-y)/height*PI;
5905 	  }
5906 	spin_quat[2] = 1.0;
5907 
5908 	phi /=10;
5909 
5910 	spin_quat[2]= sin(phi/2);
5911 	spin_quat[3] = cos(phi/2);
5912 
5913 	add_quats(spin_quat, QuatFrag, QuatFrag);
5914 	build_rotmatrix(m,QuatFrag);
5915 	rotation_fragment_quat(m,C);
5916 
5917 	if(RebuildConnectionsDuringEdition)
5918 		reset_connections_between_selected_and_notselected_atoms();
5919 	/* reset_all_connections();*/
5920 	drawGeom();
5921 	BeginX = x;
5922 	BeginY = y;
5923 
5924 
5925 	return TRUE;
5926 }
5927 /********************************************************************************/
local_rotate_fragment(GtkWidget * widget,GdkEventMotion * event)5928 static gint local_rotate_fragment(GtkWidget *widget, GdkEventMotion *event)
5929 {
5930 	int x, y;
5931 	GdkModifierType state;
5932 	gdouble spin_quat[4];
5933 	gdouble m[4][4];
5934 	gdouble C[3]={0,0,0};/* Center of Fragment */
5935 	gint i;
5936 	gint j;
5937 	gint k;
5938 	gint Xi;
5939 	gint Yi;
5940 	gdouble width;
5941 	gdouble height;
5942 	gdouble ModelView[16];
5943 	gdouble ProjView[16];
5944 	gint Viewport[4];
5945 	GLdouble View2D[3];
5946 
5947 	glGetDoublev(GL_MODELVIEW_MATRIX, ModelView);
5948 	glGetDoublev(GL_PROJECTION_MATRIX, ProjView);
5949 	glGetIntegerv(GL_VIEWPORT, Viewport);
5950 
5951 	j=0;
5952 	for (i=0;i<(gint)Natoms;i++)
5953 	{
5954 		if(if_selected(i))
5955 		{
5956 			j++;
5957 			C[0] += geometry[i].X;
5958 			C[1] += geometry[i].Y;
5959 			C[2] += geometry[i].Z;
5960 		}
5961 	}
5962 	if(j<1) return FALSE;
5963 
5964 	for(k=0;k<3;k++) C[k] /= (gdouble)j;
5965 
5966 	gluProject(C[0], C[1], C[2],ModelView, ProjView, Viewport, &View2D[0], &View2D[1], &View2D[2]);
5967 
5968 	Xi = View2D[0];
5969 	Yi = viewport[3]-View2D[1];
5970 
5971 
5972 	Xi = Xi + Trans[0];
5973 	Yi = Yi + Trans[1];
5974 
5975 	if (event->is_hint)
5976 	{
5977 #if !defined(G_OS_WIN32)
5978 		gdk_window_get_pointer(event->window, &x, &y, &state);
5979 #else
5980 		x = event->x;
5981 		y = event->y;
5982 		state = event->state;
5983 #endif
5984 	}
5985 	else
5986 	{
5987 		x = event->x;
5988 		y = event->y;
5989 		state = event->state;
5990 	}
5991 
5992 	width  = widget->allocation.width;
5993 	height = widget->allocation.height;
5994 
5995 
5996 	trackball(spin_quat,
5997 		(2.0*(width/2+BeginX-Xi)  - (width)) / (width),
5998 		((height) - 2.0*(height/2+BeginY-Yi)) / (height),
5999 		(2.0*(width/2+x-Xi)       - (width)) / (width),
6000 		((height) - 2.0*(height/2+y-Yi)     ) / (height));
6001 
6002 	add_quats(spin_quat, QuatFrag, QuatFrag);
6003 	build_rotmatrix(m,QuatFrag);
6004 	rotation_fragment_quat(m,C);
6005 
6006 	if(RebuildConnectionsDuringEdition)
6007 		reset_connections_between_selected_and_notselected_atoms();
6008 	/* reset_all_connections();*/
6009 	drawGeom();
6010 	BeginX = x;
6011 	BeginY = y;
6012 
6013  return TRUE;
6014 }
6015 /********************************************************************************/
set_statubar_pop_sel_atom()6016 void set_statubar_pop_sel_atom()
6017 {
6018 	gchar* temp = NULL;
6019 	if(NumSelectedAtom >=0 && OperationType == DELETEFRAG)
6020 	{
6021 		temp = g_strdup_printf(_("%s[%d] ; Coord (Ang) : %f %f %f ; Move your mouse to cancel the operation "),
6022 			geometry0[NumSelectedAtom].Prop.symbol,NumSelectedAtom+1,
6023 			geometry0[NumSelectedAtom].X*BOHR_TO_ANG,
6024 			geometry0[NumSelectedAtom].Y*BOHR_TO_ANG,
6025 			geometry0[NumSelectedAtom].Z*BOHR_TO_ANG);
6026 	}
6027 	if(OperationType == CUTBOND || OperationType == CHANGEBOND)
6028 	{
6029 		temp = g_strdup_printf(_("Move your mouse to cancel the operation "));
6030 	}
6031 	if(temp)
6032 	{
6033 		gtk_statusbar_pop(GTK_STATUSBAR(StatusOperation),idStatusOperation);
6034 		gtk_statusbar_push(GTK_STATUSBAR(StatusOperation),idStatusOperation,temp);
6035 		g_free(temp);
6036 	}
6037 }
6038 /********************************************************************************/
move_one_atom(GdkEventMotion * event)6039 static gint move_one_atom(GdkEventMotion *event)
6040 {
6041 	int x, y;
6042 	GdkModifierType state;
6043 	gdouble w[3];
6044 	gint i;
6045 	GLdouble View2D[3];
6046 
6047 	if(NumSelectedAtom<0) return -1;
6048 
6049 	if (event->is_hint)
6050 	{
6051 #if !defined(G_OS_WIN32)
6052 		gdk_window_get_pointer(event->window, &x, &y, &state);
6053 #else
6054 		x = event->x;
6055 		y = event->y;
6056 		state = event->state;
6057 #endif
6058 	}
6059 	else
6060 	{
6061 		x = event->x;
6062 		y = event->y;
6063 		state = event->state;
6064 	}
6065 	i = NumSelectedAtom;
6066 	gluProject(geometry[i].X, geometry[i].Y, geometry[i].Z,mvmatrix, projmatrix, viewport, &View2D[0], &View2D[1], &View2D[2]);
6067 	gluUnProject( (float)x, (float)viewport[3] - (float)y, View2D[2], mvmatrix, projmatrix, viewport, &w[0], &w[1], &w[2]);
6068 
6069 	geometry0[i].X=w[0];
6070 	geometry0[i].Y=w[1];
6071 	geometry0[i].Z=w[2];
6072 
6073 	geometry[i].X=w[0];
6074 	geometry[i].Y=w[1];
6075 	geometry[i].Z=w[2];
6076 
6077 	Ddef = FALSE;
6078 
6079 	drawGeom();
6080 	set_statubar_pop_sel_atom();
6081 	return TRUE;
6082 }
6083 
6084 /***********************************************************************************/
move_all_selected_atoms(GtkWidget * widget,GdkEventMotion * event)6085 static gint move_all_selected_atoms(GtkWidget *widget, GdkEventMotion *event)
6086 {
6087 	int x, y;
6088 	GdkModifierType state;
6089 	gdouble X;
6090 	gdouble Y;
6091 	gdouble Z;
6092 	gdouble w[3];
6093 	GLdouble View2D[3];
6094 	gint i = NumSelectedAtom;
6095 
6096 	if(NumSelectedAtom<0) return -1;
6097 
6098 
6099 	if (event->is_hint)
6100 	{
6101 #if !defined(G_OS_WIN32)
6102 		gdk_window_get_pointer(event->window, &x, &y, &state);
6103 #else
6104 		x = event->x;
6105 		y = event->y;
6106 		state = event->state;
6107 #endif
6108 	}
6109 	else
6110 	{
6111 		x = event->x;
6112 		y = event->y;
6113 		state = event->state;
6114 	}
6115 	gluProject(geometry[i].X, geometry[i].Y, geometry[i].Z,mvmatrix, projmatrix, viewport, &View2D[0], &View2D[1], &View2D[2]);
6116 	gluUnProject( (float)x, (float)viewport[3] - (float)y, View2D[2], mvmatrix, projmatrix, viewport, &w[0], &w[1], &w[2]);
6117 
6118 	X = w[0];
6119 	Y = w[1];
6120 	Z = w[2];
6121 
6122 	{
6123 		gint j;
6124 		gdouble B[3]={X,Y,Z};
6125 		B[0] -=geometry[i].X;
6126 		B[1] -=geometry[i].Y;
6127 		B[2] -=geometry[i].Z;
6128 
6129 		for(i=0;i<(gint)Natoms;i++)
6130 		for(j=0;j<(gint)NFatoms;j++)
6131 			if(NumFatoms[j]==(gint)geometry0[i].N)
6132 			{
6133 				geometry[i].X += B[0];
6134 				geometry[i].Y += B[1];
6135 				geometry[i].Z += B[2];
6136 			}
6137 	}
6138 	for (i=0;i<Natoms;i++)
6139 	{
6140 		geometry0[i].X=geometry[i].X;
6141 		geometry0[i].Y=geometry[i].Y;
6142 		geometry0[i].Z=geometry[i].Z;
6143 	}
6144 	Ddef = FALSE;
6145 	if(RebuildConnectionsDuringEdition)
6146 		reset_connections_between_selected_and_notselected_atoms();
6147 	drawGeom();
6148 	set_statubar_pop_sel_atom();
6149 	return TRUE;
6150 }
6151 /********************************************************************************/
MoveAtomByMouse(GtkWidget * widget,GdkEventMotion * event)6152 static gint MoveAtomByMouse(GtkWidget *widget, GdkEventMotion *event)
6153 {
6154 	gboolean MoveAll = FALSE;
6155 	gint i;
6156 	gint j;
6157 
6158 	if(NumSelectedAtom<0) return FALSE;
6159 	for(i=0;i<(gint)Natoms;i++)
6160 		if((gint)i==NumSelectedAtom)
6161 		{
6162 			for(j = 0;j<(gint)NFatoms;j++)
6163 				if(NumFatoms[j] == (gint)geometry[i].N)
6164 					MoveAll = TRUE;
6165 			break;
6166 		}
6167 	if(!MoveAll)
6168 	{
6169 		move_one_atom(event);
6170 		if(RebuildConnectionsDuringEdition)
6171 			reset_connection_with_one_atom(NumSelectedAtom);
6172 		return TRUE;
6173 	}
6174 	move_all_selected_atoms(widget, event);
6175 	return TRUE;
6176 }
6177 /*****************************************************************************/
set_proche_atom(GdkEventButton * bevent)6178 gint set_proche_atom(GdkEventButton *bevent)
6179 {
6180 	gdouble xi,yi,xii,yii,zii;
6181 	gint i;
6182 	gdouble mindist = -1;
6183 	gdouble d1 ;
6184 	gdouble w[3];
6185 
6186 	xi = bevent->x;
6187 	yi = bevent->y;
6188 	glGetWorldCoordinates(xi,yi,w);
6189 
6190 	NumProcheAtom = -1;
6191 	for(i=Natoms-1;i>=0;i--)
6192 	{
6193 		xii = w[0]-geometry[i].X;
6194 		yii = w[1]-geometry[i].Y;
6195 		zii = w[2]-geometry[i].Z;
6196 		d1 = xii*xii+yii*yii+zii*zii;
6197 		if(mindist<0)
6198 		{
6199 			mindist = fabs(d1);
6200 			NumProcheAtom = i;
6201 		}
6202 		if(mindist>fabs(d1))
6203 		{
6204 			mindist = fabs(d1);
6205 			NumProcheAtom = i;
6206 		}
6207 	}
6208 	return NumProcheAtom;
6209 }
6210 /*****************************************************************************/
set_selected_atoms(GdkEventButton * bevent)6211 gint set_selected_atoms(GdkEventButton *bevent)
6212 {
6213 	gdouble xi,yi,xii,yii,zii;
6214 	gint i;
6215 	gdouble mindist = -1;
6216 	gdouble d2 ;
6217 	gdouble d1 ;
6218 	gint ns = -1;
6219 	gdouble w[3];
6220 
6221 	xi = bevent->x;
6222 	yi = bevent->y;
6223 	glGetWorldCoordinates(xi,yi,w);
6224 
6225 	for(i=Natoms-1;i>=0;i--)
6226 	{
6227 		gdouble rayon = get_rayon_selection(i);
6228 		xii = w[0]-geometry[i].X;
6229 		yii = w[1]-geometry[i].Y;
6230 		zii = w[2]-geometry[i].Z;
6231 		d1 = xii*xii+yii*yii+zii*zii;
6232 		d2 = d1-rayon*rayon;
6233 		if(d2<0)
6234 		{
6235 			if(mindist<0)
6236 			{
6237 				mindist = fabs(d1);
6238 				ns = i;
6239 			}
6240 			if(mindist>fabs(d1))
6241 			{
6242 				mindist = fabs(d1);
6243 				ns = i;
6244 			}
6245 		}
6246 	}
6247 	if(ns != -1)
6248 	{
6249 		gboolean Ok = FALSE;
6250 		for(i=0;i<4;i++)
6251 			if(NumSelAtoms[i] ==(gint) geometry[ns].N)
6252 			{
6253 				NumSelAtoms[i] = -1;
6254 				Ok = TRUE;
6255 				break;
6256 			}
6257 		if(!Ok)
6258 		for(i=0;i<4;i++)
6259 			if(NumSelAtoms[i] == -1 || NumSelAtoms[i] >(gint)Natoms)
6260 			{
6261 				NumSelAtoms[i] = geometry[ns].N;
6262 				Ok = TRUE;
6263 				break;
6264 			}
6265 
6266 		if(!Ok)
6267 		{
6268 			for(i=0;i<3;i++)
6269 				NumSelAtoms[i] = NumSelAtoms[i+1];
6270 			NumSelAtoms[3] = geometry[ns].N;
6271 		}
6272 	}
6273 	for(i=0;i<3;i++)
6274 		if(NumSelAtoms[i] == -1)
6275 		{
6276 			NumSelAtoms[i] = NumSelAtoms[i+1];
6277 			NumSelAtoms[i+1] = -1;
6278 		}
6279 	drawGeom();
6280 	change_of_center(NULL,NULL);
6281 	set_statubar_pop_sel_atom();
6282 	return ns;
6283 }
6284 /*****************************************************************************/
unselected_atom(GdkEventButton * bevent)6285 gint unselected_atom(GdkEventButton *bevent)
6286 {
6287 	gdouble xi,yi,xii,yii;
6288 
6289 	xi = bevent->x;
6290 	yi = bevent->y;
6291 
6292 	xii = xi-BeginX;
6293 	yii = yi-BeginY;
6294 	if(xii*xii+yii*yii > 8)
6295 	{
6296 		NumSelectedAtom = -1;
6297 		drawGeom();
6298 		SetOperation (NULL,OperationType);
6299 	}
6300 	return NumSelectedAtom;
6301 }
6302 /*****************************************************************************/
unselected_bond(GdkEventButton * bevent)6303 gint unselected_bond(GdkEventButton *bevent)
6304 {
6305 	gdouble xi,yi,xii,yii;
6306 
6307 	xi = bevent->x;
6308 	yi = bevent->y;
6309 
6310 	xii = xi-BeginX;
6311 	yii = yi-BeginY;
6312 	if(xii*xii+yii*yii > 8)
6313 	{
6314 		NumBatoms[0] = NumBatoms[1] = -1;
6315 		NBatoms = 0;
6316 		drawGeom();
6317 		SetOperation (NULL,OperationType);
6318 	}
6319 	return 0;
6320 }
6321 /*****************************************************************************/
set_selected_second_atom_bond(GdkEventButton * bevent)6322 gint set_selected_second_atom_bond(GdkEventButton *bevent)
6323 {
6324 	gdouble xi,yi,xa,ya,za;
6325 	gint i;
6326 	gdouble da ;
6327 	gint nb=0;
6328 	gdouble w[3];
6329 
6330 	xi = bevent->x;
6331 	yi = bevent->y;
6332 	glGetWorldCoordinates(xi,yi,w);
6333 
6334 	for(i=Natoms-1;i>=0;i--)
6335 	{
6336 		gdouble rayon = get_rayon_selection(i);
6337 		if(geometry[i].N==geometry[NumSelectedAtom].N) continue;
6338 		if(geometry[i].N==NumBatoms[0]) continue;
6339 		xa = w[0]-geometry[i].X;
6340 		ya = w[1]-geometry[i].Y;
6341 		za = w[2]-geometry[i].Z;
6342 		da = xa*xa+ya*ya+za*za;
6343 		if(da<rayon*rayon)
6344 		{
6345 			nb = (gint) geometry[i].N;
6346 			break;
6347 		}
6348 	}
6349 	if(nb<=0 &&NumPointedAtom>=0 && Natoms>1)
6350 	{
6351 		/* NumPointedAtom could be on top of an atom, Search it */
6352 		gdouble rb = 0;
6353 		gdouble rmin = 1000;
6354 		if(NumPointedAtom>=0) rb = get_rayon_selection(Natoms-1);
6355 		for(i=Natoms-2;i>=0;i--)
6356 		{
6357 			gchar *dist = NULL;
6358 			gdouble d = 0;
6359 			gdouble rcut = 0.0;
6360 			if(geometry[i].N==geometry[NumSelectedAtom].N) continue;
6361 			if(i == NumPointedAtom) continue;
6362 			if(geometry[i].N==NumBatoms[0]) continue;
6363 			dist = get_distance(geometry[i].N, geometry[Natoms-1].N);
6364 			if(dist) rcut = get_rayon_selection(i)+rb;
6365 			if(dist)  d = atof(dist) / BOHR_TO_ANG;
6366 			if(d<rmin) rmin = d;
6367 			if(dist && d<rcut)
6368 			{
6369 				nb = (gint) geometry[i].N;
6370 				break;
6371 			}
6372 		}
6373 /*
6374 		gdouble rmin = 1000;
6375 		gdouble rb = get_rayon_selection(Natoms-1);
6376 		GLdouble View2D[3];
6377 		gdouble mindist = -1;
6378 		gint imin = -1;
6379 		gdouble winX, winY, winZ;
6380 		gdouble xii,yii,d1;
6381 		i = Natoms-1;
6382 		gluProject(geometry[i].X, geometry[i].Y, geometry[i].Z,mvmatrix, projmatrix, viewport, &winX, &winY, &winZ);
6383 		for(i=Natoms-2;i>=0;i--)
6384 		{
6385 			gluProject(geometry[i].X, geometry[i].Y, geometry[i].Z,mvmatrix, projmatrix, viewport, &View2D[0], &View2D[1], &View2D[2]);
6386 			xii = View2D[0]-winX;
6387 			yii = View2D[1]-winY;
6388 			d1 = xii*xii+yii*yii;
6389 			if(mindist<0 || mindist>d1)
6390 			{
6391 				mindist = d1;
6392 				imin = i;
6393 			}
6394 		}
6395 		i =imin;
6396 		gluProject(geometry[i].X, geometry[i].Y, geometry[i].Z,mvmatrix, projmatrix, viewport, &View2D[0], &View2D[1], &View2D[2]);
6397 		printf("imin = %d mindis = %f winz = %f  winz2 = %f \n",imin,sqrt(mindist),winZ, View2D[2] );
6398 		if(imin>0 && sqrt(mindist)<get_rayon_selection(imin)+rb)
6399 		{
6400 			nb = (gint) geometry[imin].N;
6401 		}
6402 */
6403 	}
6404 	if(nb>0 && nb !=  NumBatoms[0])
6405 	//if(nb>0)
6406 	{
6407 		NBatoms = 2;
6408 		NumBatoms[1] = nb;
6409 	}
6410 	else
6411 	{
6412 		NBatoms = 1;
6413 	}
6414 	drawGeom();
6415 	change_of_center(NULL,NULL);
6416 	set_statubar_pop_sel_atom();
6417 	return NBatoms;
6418 }
6419 /*****************************************************************************/
set_selected_atom(GdkEventButton * bevent)6420 gint set_selected_atom(GdkEventButton *bevent)
6421 {
6422 	gdouble xi,yi,xii,yii,zii;
6423 	gint i;
6424 	gdouble mindist = -1;
6425 	gdouble d2 ;
6426 	gdouble d1 ;
6427 	gdouble w[3];
6428 
6429 	xi = bevent->x;
6430 	yi = bevent->y;
6431 	glGetWorldCoordinates(xi,yi,w);
6432 
6433 	NumSelectedAtom = -1;
6434 	for(i=Natoms-1;i>=0;i--)
6435 	{
6436 		gdouble rayon;
6437 		if(!geometry[i].show) continue;
6438 		rayon = get_rayon_selection(i);
6439 		xii = w[0]-geometry[i].X;
6440 		yii = w[1]-geometry[i].Y;
6441 		zii = w[2]-geometry[i].Z;
6442 		d1 = xii*xii+yii*yii+zii*zii;
6443 		d2 = d1-rayon*rayon;
6444 		if(d2<0)
6445 		{
6446 			if(mindist<0)
6447 			{
6448 				mindist = fabs(d1);
6449 				NumSelectedAtom = i;
6450 			}
6451 			if(mindist>fabs(d1))
6452 			{
6453 				mindist = fabs(d1);
6454 				NumSelectedAtom = i;
6455 			}
6456 		}
6457 	}
6458 	for(i=0;i<3;i++)
6459 		QuatAtom[i] = 0;
6460 	QuatAtom[3] = 1;
6461 	if(NumSelectedAtom>=0)
6462 	{
6463 	CSselectedAtom[0] = geometry0[NumSelectedAtom].X;
6464 	CSselectedAtom[1] = geometry0[NumSelectedAtom].Y;
6465 	CSselectedAtom[2] = geometry0[NumSelectedAtom].Z;
6466 	}
6467 	drawGeom();
6468 	set_statubar_pop_sel_atom();
6469 	return NumSelectedAtom;
6470 }
6471 /*****************************************************************************/
set_selected_bond(GdkEventButton * bevent)6472 gint set_selected_bond(GdkEventButton *bevent)
6473 {
6474 	gdouble xi,yi,xa,ya,za,xb,yb,zb;
6475 	gint i,j;
6476 	gdouble da ;
6477 	gdouble db ;
6478 	gint na = -1;
6479 	gint nb = -1;
6480 	gdouble w[3];
6481 
6482 	xi = bevent->x;
6483 	yi = bevent->y;
6484 	glGetWorldCoordinates(xi,yi,w);
6485 
6486 	NumBatoms[0] = NumBatoms[1] = -1;
6487 	NBatoms = 0;
6488 
6489 	for(i=Natoms-1;i>=0;i--)
6490 	{
6491 		gdouble rayoni;
6492 		if(!geometry[i].show) continue;
6493 		xa = w[0]-geometry[i].X;
6494 		ya = w[1]-geometry[i].Y;
6495 		za = w[2]-geometry[i].Z;
6496 		da = xa*xa+ya*ya+za*za;
6497 		rayoni = get_rayon_selection(i);
6498 		rayoni = rayoni*rayoni;
6499 		for(j=Natoms-1;j>=0;j--)
6500 		{
6501 			gdouble rayonj;
6502 			gdouble minrayon;
6503 			if(i==j)  continue;
6504 			if(!geometry[j].show) continue;
6505 			gint nj = geometry[j].N-1;
6506 			if(geometry[i].typeConnections[nj]<1)  continue;
6507 			xb = w[0]-geometry[j].X;
6508 			yb = w[1]-geometry[j].Y;
6509 			zb = w[2]-geometry[j].Z;
6510 			db = xb*xb+yb*yb+zb*zb;
6511 			rayonj = get_rayon_selection(j);
6512 			rayonj = rayonj*rayonj;
6513 			minrayon = rayoni;
6514 			if(minrayon>rayonj) minrayon = rayonj;
6515 
6516 			if( da<minrayon || db<minrayon)
6517 			{
6518 				na = i;
6519 				nb = j;
6520 				break;
6521 			}
6522 
6523 			if( fabs((xa*xb+ya*yb+za*zb)/sqrt(da*db)+1.0)<0.2)
6524 			{
6525 				na = i;
6526 				nb = j;
6527 				break;
6528 			}
6529 
6530 		}
6531 		if(na>-1 && nb>-1) break;
6532 	}
6533 	if(na != -1 && nb != -1)
6534 	{
6535 		NBatoms = 2;
6536 		NumBatoms[0] = (gint) geometry[na].N;
6537 		NumBatoms[1] = (gint) geometry[nb].N;
6538 	}
6539 	drawGeom();
6540 	change_of_center(NULL,NULL);
6541 	set_statubar_pop_sel_atom();
6542 	return NBatoms;
6543 }
6544 /*****************************************************************************/
set_selected_atom_bond(GdkEventButton * bevent)6545 gint set_selected_atom_bond(GdkEventButton *bevent)
6546 {
6547 	gdouble xi,yi,xa,ya,za;
6548 	gint i;
6549 	gdouble da ;
6550 	gdouble w[3];
6551 
6552 	xi = bevent->x;
6553 	yi = bevent->y;
6554 	glGetWorldCoordinates(xi,yi,w);
6555 
6556 	NumBatoms[0] = NumBatoms[1] = -1;
6557 	NBatoms = 0;
6558 
6559 	for(i=Natoms-1;i>=0;i--)
6560 	{
6561 		gdouble rayon = get_rayon_selection(i);
6562 		xa = w[0]-geometry[i].X;
6563 		ya = w[1]-geometry[i].Y;
6564 		za = w[2]-geometry[i].Z;
6565 		da = xa*xa+ya*ya+za*za;
6566 		if(da<rayon*rayon)
6567 		{
6568 			NBatoms = 1;
6569 			NumBatoms[0] = (gint) geometry[i].N;
6570 			break;
6571 		}
6572 	}
6573 	drawGeom();
6574 	change_of_center(NULL,NULL);
6575 	set_statubar_pop_sel_atom();
6576 	return NBatoms;
6577 }
6578 /*****************************************************************************/
get_atom_to_select(GdkEventButton * bevent,gdouble f)6579 gint get_atom_to_select(GdkEventButton *bevent, gdouble f)
6580 {
6581 	gdouble xi,yi,xii,yii,zii;
6582 	gint i;
6583 	gdouble d2 ;
6584 	gdouble d1 ;
6585 	gdouble w[3];
6586 
6587 	xi = bevent->x;
6588 	yi = bevent->y;
6589 
6590 	glGetWorldCoordinates(xi,yi,w);
6591 
6592 	for(i=Natoms-1;i>=0;i--)
6593 	{
6594 		gdouble rayon;
6595 		if(!geometry[i].show) continue;
6596 		if(i==NumSelectedAtom) continue;
6597 		xii = w[0]-geometry[i].X;
6598 		yii = w[1]-geometry[i].Y;
6599 		zii = w[2]-geometry[i].Z;
6600 		d1 = xii*xii+yii*yii+zii*zii;
6601 		rayon = f*get_rayon_selection(i);
6602 		d2 = d1-rayon*rayon;
6603 		/* printf("i=%d, d1 = %f , d2 = %f\n",i,d1,d2);*/
6604 		if(d2<0) return i;
6605 	}
6606 	return -1;
6607 }
6608 /*****************************************************************************/
set_selected_atom_or_bond_to_delete(GdkEventButton * bevent)6609 gint set_selected_atom_or_bond_to_delete(GdkEventButton *bevent)
6610 {
6611 	NumSelectedAtom = -1;
6612 	if(get_atom_to_select(bevent,1.0)>=0)
6613 	{
6614 		OperationType = DELETEFRAG;
6615 		return set_selected_atom(bevent);
6616 	}
6617 	OperationType = CUTBOND;
6618 	return set_selected_bond(bevent);
6619 }
6620 /*****************************************************************************/
add_begin_atoms_bond(GdkEventButton * bevent)6621 gint add_begin_atoms_bond(GdkEventButton *bevent)
6622 {
6623 	gint ni,nj,i,j;
6624 	if(NBatoms==1 && NumBatoms[0]>0)
6625 	{
6626 		insert_atom(bevent);
6627 		j = Natoms-1;
6628 		nj = geometry[j].N-1;
6629 		for(i=0;i<(gint)Natoms;i++)
6630 			if(geometry[i].N==NumBatoms[0])
6631 			{
6632 				ni = geometry[i].N-1;
6633 				geometry0[j].typeConnections[ni] = 1;
6634 				geometry0[i].typeConnections[nj] = 1;
6635 				geometry[j].typeConnections[ni] = 1;
6636 				geometry[i].typeConnections[nj] = 1;
6637 				break;
6638 			}
6639 		NumSelectedAtom = Natoms-1;
6640 		return 1;
6641 	}
6642 	insert_atom(bevent);
6643 	NumProcheAtom = Natoms-1;
6644 	insert_atom(bevent);
6645 	j = Natoms-1;
6646 	i = Natoms-2;
6647 	ni = geometry[i].N-1;
6648 	nj = geometry[j].N-1;
6649 	geometry0[j].typeConnections[ni] = 1;
6650 	geometry0[i].typeConnections[nj] = 1;
6651 	geometry[j].typeConnections[ni] = 1;
6652 	geometry[i].typeConnections[nj] = 1;
6653 	NumSelectedAtom = Natoms-1;
6654 	NumBatoms[0] = -(geometry0[i].N+Natoms);
6655 	return 2;
6656 }
6657 /*****************************************************************************/
set_selected_atom_or_bond_to_edit(GdkEventButton * bevent)6658 gint set_selected_atom_or_bond_to_edit(GdkEventButton *bevent)
6659 {
6660 	gint res = -1;
6661 	NumSelectedAtom = -1;
6662 	res = get_atom_to_select(bevent,1.0);
6663 	/* printf("res = %d\n",res);*/
6664 	if(res==-1)
6665 	{
6666 		set_selected_bond(bevent);
6667 		/* printf("NBatoms = %d\n",NBatoms);*/
6668 		if(NBatoms==2)
6669 		{
6670 			OperationType = CHANGEBOND;
6671 			return NBatoms;
6672 		}
6673 	}
6674 	set_selected_atom_bond(bevent);
6675 	OperationType = ADDATOMSBOND;
6676 	res = set_selected_atom(bevent);
6677 	set_proche_atom(bevent);
6678 	return res;
6679 }
6680 /*****************************************************************************/
atom_noni_connected_to(gint i,gint k)6681 static gint atom_noni_connected_to(gint i, gint k)
6682 {
6683 	gint j;
6684 	gint l;
6685 	if(Natoms<3) return -1;
6686 	if(geometry[i].typeConnections)
6687 	for(j=0;j<Natoms;j++)
6688 	{
6689 		gint nj = geometry[j].N-1;
6690 		if(j==i) continue;
6691 		if(geometry[j].typeConnections)
6692 		for(l=0;l<Natoms;l++)
6693 		{
6694 			gint nl = geometry[l].N-1;
6695 			if(k==geometry[l].N && ( geometry[l].typeConnections[nj]>0 || geometry[j].typeConnections[nl]>0)
6696 					&& geometry[l].Prop.symbol[0] !='H') return geometry[j].N;
6697 		}
6698 	}
6699 	for(j=0;j<Natoms;j++)
6700 	{
6701 		gint nj = geometry[j].N-1;
6702 		if(j==i) continue;
6703 		if(geometry[j].typeConnections)
6704 		for(l=0;l<Natoms;l++)
6705 			if(k==geometry[l].N && geometry[l].typeConnections && geometry[l].typeConnections[nj]>0) return geometry[j].N;
6706 	}
6707 	return -1;
6708 }
6709 /*****************************************************************************/
set_selected_atoms_for_insert_frag(GdkEventButton * bevent)6710 gint set_selected_atoms_for_insert_frag(GdkEventButton *bevent)
6711 {
6712 	gint nb = 0;
6713 	gint i;
6714 	gint j;
6715 
6716 	NumSelectedAtom = -1;
6717 	angleTo = -1;
6718 	atomToBondTo = -1;
6719 	NumSelectedAtom = -1;
6720 
6721 	i = get_atom_to_select(bevent,1.0);
6722 	if(i<0)  return i;
6723 	atomToDelete = geometry[i].N;
6724 
6725 	atomToBondTo = -1;
6726 	for (j=0;j<(gint)Natoms;j++)
6727 	if(geometry[j].typeConnections && geometry[j].typeConnections[atomToDelete-1]>0)
6728 	{
6729 		nb++;
6730 		atomToBondTo = geometry[j].N;
6731 		angleTo = atom_noni_connected_to( i, atomToBondTo);
6732 	}
6733 	if(nb != 1 || atomToBondTo==-1)
6734 	{
6735 		atomToDelete = -1;
6736 		atomToBondTo = -1;
6737 		angleTo = -1;
6738 	}
6739 	if(Frag.NAtoms>0 && Frag.atomToDelete != -1) drawGeom();
6740 	return atomToDelete;
6741 }
6742 /*****************************************************************************
6743 *  event_dispatcher
6744 ******************************************************************************/
button_press(GtkWidget * DrawingArea,GdkEvent * event,gpointer Menu)6745 gint button_press(GtkWidget *DrawingArea, GdkEvent *event, gpointer Menu)
6746 {
6747 	GdkEventButton *bevent;
6748 
6749 
6750 	switch (event->type)
6751 	{
6752 		case GDK_BUTTON_PRESS:
6753 		{
6754 			buttonpress = TRUE;
6755 			bevent = (GdkEventButton *) event;
6756 			if (bevent->button == 3) /* Right Button ==> Popup Menu */
6757 			{
6758 				buttonpress = FALSE;
6759 				popup_menu_geom( bevent->button, bevent->time);
6760 			}
6761 			else
6762 			if (bevent->button == 1 && ControlKeyPressed)
6763 			{
6764 
6765 				BeginX= bevent->x;
6766 				BeginY = bevent->y;
6767 				return TRUE;
6768 			}
6769 			else
6770 			if (bevent->button == 1)
6771 			{
6772 				/* beginning of drag, reset mouse position */
6773 				BeginX= bevent->x;
6774 				BeginY = bevent->y;
6775         			switch(OperationType)
6776         			{
6777 					case SELECTOBJECTS :
6778 						if(GKeyPressed && select_atoms_by_groupe())
6779 							SetOperation(NULL,SELECTRESIDUE);
6780 						else
6781 						if(!FKeyPressed && select_atoms_by_residues())
6782 							SetOperation(NULL,SELECTRESIDUE);
6783 						else
6784 							SetOperation(NULL,SELECTFRAG);
6785 						break;
6786 					case MOVEFRAG :
6787 						add_geometry_to_fifo();
6788 						set_selected_atom(bevent); break;
6789 					case DELETEOBJECTS :
6790 						add_geometry_to_fifo();
6791 						set_selected_atom_or_bond_to_delete(bevent);break;
6792 					case MEASURE     : set_selected_atoms(bevent);break;
6793 					case EDITOBJECTS :
6794 							  add_geometry_to_fifo();
6795 							  set_selected_atom_or_bond_to_edit(bevent);
6796 							  if(NBatoms<2) add_begin_atoms_bond(bevent);
6797 							  RebuildGeom = TRUE;
6798 							  drawGeom();
6799 							  break;
6800 					case ADDFRAGMENT :
6801 							  add_geometry_to_fifo();
6802 							  set_selected_atoms_for_insert_frag(bevent);
6803 							  set_proche_atom(bevent);break;
6804 					case ROTLOCFRAG :
6805 							  add_geometry_to_fifo();
6806 							  init_quat(QuatFrag);
6807 							  ButtonPressed = TRUE;
6808 							  drawGeom();
6809 							  break;
6810 					case ROTZLOCFRAG :
6811 							  add_geometry_to_fifo();
6812 							  init_quat(QuatFrag);
6813 							  ButtonPressed = TRUE;
6814 							  drawGeom();
6815 							  break;
6816 					default:break;
6817 				}
6818 			return TRUE;
6819 			}
6820 			else
6821 			if (bevent->button == 2)
6822 			{
6823 				BeginX= bevent->x;
6824 				BeginY = bevent->y;
6825 				return TRUE;
6826 			}
6827 		}
6828 		default: break;
6829 	}
6830 	return FALSE;
6831 }
6832 /*************************/
unselect_all_atoms()6833 void unselect_all_atoms()
6834 {
6835 	NFatoms = 0;
6836 	if(NumFatoms)
6837 	       g_free(NumFatoms);
6838 	NumFatoms = NULL;
6839 }
6840 /*****************************************************************************
6841 *  event_release
6842 ******************************************************************************/
button_release(GtkWidget * DrawingArea,GdkEvent * event,gpointer Menu)6843 gint button_release(GtkWidget *DrawingArea, GdkEvent *event, gpointer Menu)
6844 {
6845 	GdkEventButton *bevent;
6846 	buttonpress = FALSE;
6847 	if(event->type == GDK_BUTTON_RELEASE)
6848 	{
6849 		bevent = (GdkEventButton *) event;
6850 		xSelection = -1;
6851 		ySelection = -1;
6852 		if (bevent->button == 3) return TRUE;
6853 		if (bevent->button == 2) { drawGeom(); return TRUE;}
6854 		if (bevent->button == 1 && ControlKeyPressed) return TRUE;
6855 	}
6856 	if(NumSelectedAtom !=-1)
6857 	{
6858 		switch(OperationType)
6859 		{
6860 		case MOVEFRAG :
6861 			create_GeomXYZ_from_draw_grometry();
6862 			NumSelectedAtom = -1;
6863 			if(GeomIsOpen)
6864 				unselect_all_atoms();
6865 
6866 			free_text_to_draw();
6867 			RebuildGeom = TRUE;
6868 			drawGeom();
6869 			SetOperation (NULL,MOVEFRAG);
6870 			change_of_center(NULL,NULL);
6871 			break;
6872 		case DELETEFRAG :
6873 			delete_selected_atoms();
6874 			create_GeomXYZ_from_draw_grometry();
6875 			NumSelectedAtom = -1;
6876 			free_text_to_draw();
6877 			RebuildGeom = TRUE;
6878 			drawGeom();
6879 			SetOperation (NULL,DELETEOBJECTS);
6880 			change_of_center(NULL,NULL);
6881 			break;
6882 		default:break;
6883 
6884 		}
6885 	}
6886 	switch(OperationType)
6887 	{
6888 	case SELECTRESIDUE : SetOperation(NULL,SELECTOBJECTS);  break;
6889 	case SELECTFRAG : SetOperation(NULL,SELECTOBJECTS);  break;
6890 	case ADDATOMSBOND :
6891 /*
6892 		printf("NBatoms=%d NumBatoms=%d %d\n",NBatoms, NumBatoms[0], NumBatoms[1]);
6893 		if(NBatoms==2 && NumBatoms[0]>0 &&  NumBatoms[1]>0 && NumBatoms[0]==NumBatoms[1])
6894 		{
6895 			delete_one_atom(NumSelectedAtom);
6896 		}
6897 		else
6898 */
6899 		if(NBatoms==2 && NumBatoms[0]>0 &&  NumBatoms[1]>0 && NumBatoms[0]!=NumBatoms[1])
6900 		{
6901 			delete_one_atom(NumSelectedAtom);
6902 			add_bond();
6903 		}
6904 		else if(NBatoms==2 && NumBatoms[0]<-Natoms &&  NumBatoms[1]>0)
6905 		{
6906 			NumBatoms[0] = -NumBatoms[0]-Natoms;
6907 			delete_one_atom(NumSelectedAtom);
6908 			if( NumBatoms[0] != NumBatoms[1]) add_bond();
6909 		}
6910 		else if(NumBatoms[0]>0 && NumSelectedAtom>-1)
6911 		{
6912 			gchar *dist = get_distance(geometry[NumSelectedAtom].N,NumBatoms[0]);
6913 			gdouble d = 0;
6914 			gdouble rcut = get_rayon_selection(NumSelectedAtom)+get_rayon_selection(get_indice(NumBatoms[0]));
6915 			if(dist)  d = atof(dist) / BOHR_TO_ANG;
6916 /*
6917 			printf("distance = %f\n",d);
6918 			printf("rcut = %f\n",rcut);
6919 			printf("NumSelectedatom = %d\n",NumSelectedAtom);
6920 			printf("Numbatom = %d\n",get_indice(NumBatoms[0]));
6921 */
6922 
6923 
6924 			//if(res != -1)
6925 			if(dist && d<rcut)
6926 			{
6927 				delete_one_atom(NumSelectedAtom);
6928 				replace_atom(get_indice(NumBatoms[0]));
6929 				if(AdjustHydrogenAtoms) adjust_hydrogens_connected_to_atom(get_indice(NumBatoms[0]));
6930 			}
6931 			else if(AdjustHydrogenAtoms)
6932 			{
6933 				adjust_hydrogens_connected_to_atoms(NumSelectedAtom,get_indice(NumBatoms[0]));
6934 			}
6935 		}
6936 		else if(NumBatoms[0]<-Natoms)
6937 		{
6938 			gint res = -1;
6939 			NumBatoms[0] = -NumBatoms[0]-Natoms;
6940 			res = get_atom_to_select((GdkEventButton *)event,1.0);
6941 			if(res != -1)
6942 			{
6943 				delete_one_atom(NumSelectedAtom);
6944 				if(AdjustHydrogenAtoms) adjust_hydrogens_connected_to_atom(get_indice(NumBatoms[0]));
6945 			}
6946 			else if(AdjustHydrogenAtoms)
6947 			{
6948 				adjust_hydrogens_connected_to_atoms(NumSelectedAtom,get_indice(NumBatoms[0]));
6949 			}
6950 		}
6951 		create_GeomXYZ_from_draw_grometry();
6952 		reset_charges_multiplicities();
6953 		SetOperation (NULL,EDITOBJECTS);
6954 		change_of_center(NULL,NULL);
6955 		NumProcheAtom = -1;
6956 		NumPointedAtom = -1;
6957 		NumSelectedAtom = -1;
6958 		free_text_to_draw();
6959 		NBatoms = 0;
6960 		NumBatoms[0] = NumBatoms[1] = -1;
6961 		RebuildGeom = TRUE;
6962 		drawGeom();
6963 		break;
6964 	case ADDFRAGMENT :
6965 		insert_fragment(DrawingArea,event);
6966 		create_GeomXYZ_from_draw_grometry();
6967 		NumProcheAtom = -1;
6968 		NumPointedAtom = -1;
6969 		atomToDelete = -1;
6970 		atomToBondTo = -1;
6971 		angleTo = -1;
6972 		free_text_to_draw();
6973 		RebuildGeom = TRUE;
6974 		drawGeom();
6975 		/*activate_rotation();*/
6976 		SetOperation (NULL,ADDFRAGMENT);
6977 		change_of_center(NULL,NULL);
6978 		break;
6979 	case ROTLOCFRAG :
6980 		ButtonPressed = FALSE;
6981 		create_GeomXYZ_from_draw_grometry();
6982 		RebuildGeom = TRUE;
6983 		drawGeom();
6984 		change_of_center(NULL,NULL);
6985 		break;
6986 	case ROTZLOCFRAG :
6987 		ButtonPressed = FALSE;
6988 		create_GeomXYZ_from_draw_grometry();
6989 		RebuildGeom = TRUE;
6990 		drawGeom();
6991 		change_of_center(NULL,NULL);
6992 		break;
6993 	case CUTBOND :
6994 		delete_selected_bond();
6995 		free_text_to_draw();
6996 		create_GeomXYZ_from_draw_grometry();
6997 		reset_charges_multiplicities();
6998 		RebuildGeom = TRUE;
6999 		drawGeom();
7000 		SetOperation (NULL,DELETEOBJECTS);
7001 		break;
7002 	case CHANGEBOND :
7003 		change_selected_bond();
7004 		free_text_to_draw();
7005 		create_GeomXYZ_from_draw_grometry();
7006 		reset_charges_multiplicities();
7007 		RebuildGeom = TRUE;
7008 		drawGeom();
7009 		SetOperation (NULL,EDITOBJECTS);
7010 		break;
7011 
7012 	default:
7013 		drawGeom();
7014 	}
7015 
7016 	return TRUE;
7017 
7018 }
7019 /*****************************************************************************
7020 *  event_dispatcher
7021 ******************************************************************************/
event_dispatcher(GtkWidget * DrawingArea,GdkEvent * event,gpointer Menu)7022 gint event_dispatcher(GtkWidget *DrawingArea, GdkEvent *event, gpointer Menu)
7023 {
7024 	return button_press(DrawingArea,event,Menu);
7025 
7026 }
7027 /********************************************************************************/
7028 /* Moption Notify */
7029 /********************************************************************************/
motion_notify(GtkWidget * widget,GdkEventMotion * event)7030 gint motion_notify(GtkWidget *widget, GdkEventMotion *event)
7031 {
7032 	GdkModifierType state;
7033 
7034 	if (event->is_hint)
7035 	{
7036 #if !defined(G_OS_WIN32)
7037 		int x, y;
7038 		gdk_window_get_pointer(event->window, &x, &y, &state);
7039 #else
7040 		state = event->state;
7041 #endif
7042 
7043 	}
7044 	else
7045 		state = event->state;
7046 	if (state & GDK_BUTTON1_MASK)
7047 	{
7048 		if(ControlKeyPressed)
7049 		{
7050 			RotationByMouse(widget,event);
7051 			return TRUE;
7052 		}
7053 	}
7054 	if(OperationType==EDITOBJECTS && !(state & GDK_BUTTON2_MASK))
7055 	{
7056 		NumPointedAtom = get_atom_to_select((GdkEventButton*)event,1.0);
7057 		drawGeom();
7058 	}
7059 	if (state & GDK_BUTTON1_MASK)
7060 	{
7061 		switch(OperationType)
7062 		{
7063 			case ROTATION 	: RotationByMouse(widget,event);break;
7064 			case ROTATIONZ 	: RotationZByMouse(widget,event);break;
7065 			case TRANSMOVIE : TranslationByMouse(widget,event);break;
7066 			case SCALEGEOM 	:
7067 			case SCALESTICK	:
7068 			case SCALEBALL 	:
7069 			case SCALEDIPOLE: ScaleByMouse((gpointer)event);break;
7070 			case SELECTFRAG :
7071 					  switch(SelectType)
7072 					  {
7073 						case CIRCLE :
7074 							draw_selection_circle(event->x,event->y);
7075 							break;
7076 						case RECTANGLE:
7077 							draw_selection_rectangle(event->x,event->y);
7078 							select_atoms_by_rectangle(event->x,event->y);
7079 							break;
7080 						default:break;
7081 					  }
7082 					  break;
7083 			case MOVEFRAG   :
7084 					  RebuildGeom = TRUE;
7085 					  MoveAtomByMouse(widget,event);
7086 					  free_text_to_draw();
7087 					  change_of_center(NULL,NULL);
7088 					  break;
7089 			case ROTLOCFRAG :
7090 					  RebuildGeom = TRUE;
7091 					local_rotate_fragment(widget,event);
7092 					free_text_to_draw();
7093 					change_of_center(NULL,NULL);
7094 					break;
7095 			case ROTZLOCFRAG :
7096 					  RebuildGeom = TRUE;
7097 					local_zrotate_fragment(widget,event);
7098 					free_text_to_draw();
7099 					change_of_center(NULL,NULL);
7100 					break;
7101 			case DELETEFRAG :
7102 					  RebuildGeom = TRUE;
7103 					  if(unselected_atom((GdkEventButton *)event)==-1)
7104 					  {
7105 					  	OperationType = DELETEOBJECTS;
7106 					  	unselected_atom((GdkEventButton *)event);
7107 					  }
7108 					  free_text_to_draw();
7109 					  change_of_center(NULL,NULL);
7110 					  break;
7111 			case CUTBOND :
7112 					  RebuildGeom = TRUE;
7113 					  OperationType = DELETEOBJECTS;
7114 					  unselected_bond((GdkEventButton *)event);
7115 					  free_text_to_draw();
7116 					  drawGeom();
7117 					  break;
7118 			case CHANGEBOND :
7119 					  RebuildGeom = TRUE;
7120 					 unselected_bond((GdkEventButton *)event);
7121 					  free_text_to_draw();
7122 					  break;
7123 			case ADDATOMSBOND :
7124 					  RebuildGeom = TRUE;
7125 					  move_one_atom(event);
7126 					  set_selected_second_atom_bond((GdkEventButton *)event);
7127 					  free_text_to_draw();
7128 					  break;
7129 			case ADDFRAGMENT :
7130 					  RebuildGeom = TRUE;
7131 					  if(atomToDelete>-1)
7132 					  {
7133 						gint j = get_atom_to_select((GdkEventButton *)event,1.0);
7134 						if(j>=0 && geometry[j].N != atomToDelete && geometry[j].N != atomToBondTo &&
7135 							fabs(atof(get_angle(atomToDelete,atomToBondTo,geometry[j].N))-180)>0.1)
7136 						{
7137 							angleTo = geometry[j].N;
7138 							drawGeom();
7139 						}
7140 					  }
7141             default : return FALSE;
7142 		}
7143 	}
7144 
7145 	if (state & GDK_BUTTON2_MASK)
7146 	{
7147 		RotationByMouse(widget,event);
7148 	}
7149 	return TRUE;
7150 }
7151 /*********************************************************************************************/
drawChecker()7152 static void drawChecker()
7153 {
7154 	GLdouble x, y, z;
7155 	GLint i,j;
7156 	V4d Diffuse1  = {0.0,0.0,0.0,0.8};
7157 	V4d Diffuse2  = {0.8,0.8,0.8,0.8};
7158 	V4d Specular = {0.8,0.8,0.8,0.8 };
7159 	V4d Ambiant  = {0.1,0.1,0.1,0.8};
7160 	static GLdouble w = 4;
7161 	static GLint n = 50;
7162 	static GLdouble x0 = -100;
7163 	static GLdouble y0 = 0;
7164 	static GLdouble z0 = -100;
7165 	GLdouble max = 0;
7166 
7167 /*
7168 	if(Ncenters>0) max = fabs(geometry[0].C[0]);
7169 	else max = 10;
7170 	for(i=0;i<(gint)Ncenters;i++)
7171 	{
7172 		if(max<fabs(geometry[i].C[0])) max = fabs(geometry[i].C[0]);
7173 		if(max<fabs(geometry[i].C[1])) max = fabs(geometry[i].C[1]);
7174 		if(max<fabs(geometry[i].C[2])) max = fabs(geometry[i].C[2]);
7175 	}
7176 */
7177 	/* max *= 45/Zoom;*/
7178 	if(y0>-5-max) y0 = -5-max;
7179 
7180 	glMaterialdv(GL_FRONT_AND_BACK,GL_SPECULAR,Specular);
7181 	glMaterialdv(GL_FRONT_AND_BACK,GL_DIFFUSE,Diffuse1);
7182 	glMaterialdv(GL_FRONT_AND_BACK,GL_AMBIENT,Ambiant);
7183 	glMateriali(GL_FRONT_AND_BACK,GL_SHININESS,100);
7184 
7185 	glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
7186 	glRotatef(-5,0,1,0);
7187 
7188 	for(i=0;i<n;i++)
7189 	for(j=0;j<n;j++)
7190 	{
7191 		if((i+j)%2==0)
7192 		{
7193 			/*glMaterialdv(GL_FRONT_AND_BACK,GL_DIFFUSE,Diffuse1);*/
7194 			glMaterialdv(GL_FRONT_AND_BACK,GL_AMBIENT,Diffuse1);
7195 		}
7196 		else
7197 		{
7198 			/*glMaterialdv(GL_FRONT_AND_BACK,GL_DIFFUSE,Diffuse2);*/
7199 			glMaterialdv(GL_FRONT_AND_BACK,GL_AMBIENT,Diffuse2);
7200 		}
7201 
7202 		glBegin(GL_POLYGON);
7203 		glNormal3f(0.0,1.0,0.0);
7204 		x = x0 + i*w;
7205 		y = y0;
7206 		z = z0 + j*w;
7207 		glVertex3f(x,y,z);
7208 		glVertex3f(x,y,z+w);
7209 		glVertex3f(x+w,y,z+w);
7210 		glVertex3f(x+w,y,z);
7211 		glEnd();
7212 	}
7213 	glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
7214 }
7215 /*********************************************************************************************/
addFog()7216 static void  addFog()
7217 {
7218 	/*
7219     GLdouble fog_c[] = {0.7f, 0.7f, 0.7f, 1.0f};
7220     glFogi(GL_FOG_MODE, GL_LINEAR);
7221     glFogf(GL_FOG_START, zNear);
7222     glFogf(GL_FOG_END, zFar);
7223     glFogdv(GL_FOG_COLOR, fog_c);
7224     glEnable(GL_FOG);
7225     */
7226 
7227   GLdouble fogstart =  -0.5;
7228   GLdouble fogend = 1.51;
7229   GLdouble fogcolor[4] = {0.0, 0.0, 0.0, 1.0};
7230 
7231   glShadeModel(GL_SMOOTH);
7232   glFogi(GL_FOG_MODE, GL_LINEAR);
7233   glFogdv(GL_FOG_COLOR, fogcolor);
7234   glHint(GL_FOG_HINT, GL_DONT_CARE);
7235   glFogf(GL_FOG_START, fogstart);
7236   glFogf(GL_FOG_END, fogend);
7237 }
7238 /********************************************************/
set_background_color()7239 static void set_background_color()
7240 {
7241 	gdouble r = 0;
7242 	gdouble g = 0;
7243 	gdouble b = 0;
7244 	gdouble o = 1.0;
7245 	if(BackColor)
7246 	{
7247 		r = BackColor->red/65535.0;
7248 		g = BackColor->green/65535.0;
7249 		b = BackColor->blue/65535.0;
7250 	}
7251 	glClearColor(r,g,b,o);
7252 }
7253 /*****************************************************************************/
redrawGeometry()7254 static void redrawGeometry()
7255 {
7256 	if (RebuildGeom || glIsList(GeomList) != GL_TRUE )
7257 	{
7258 		if (glIsList(GeomList) == GL_TRUE) glDeleteLists(GeomList,1);
7259 		GeomList = glGenLists(1);
7260 		glNewList(GeomList, GL_COMPILE);
7261 		gl_build_geometry();
7262 		glEndList();
7263 		glCallList(GeomList);
7264 		RebuildGeom = FALSE;
7265 	}
7266 	else
7267 	{
7268 		glCallList(GeomList);
7269 	}
7270 }
7271 /*****************************************************************************/
redrawSelection()7272 static void redrawSelection()
7273 {
7274 	/*if (RebuildSelection || glIsList(SelectionList) != GL_TRUE )*/
7275 	{
7276 		if (glIsList(SelectionList) == GL_TRUE) glDeleteLists(SelectionList,1);
7277 		SelectionList = glGenLists(1);
7278 		glNewList(SelectionList, GL_COMPILE);
7279 		gl_build_selection();
7280 		glEndList();
7281 		glCallList(SelectionList);
7282 		/*RebuildSelection = TRUE;*/
7283 	}
7284 	/*else
7285 	{
7286 		glCallList(SelectionList);
7287 	}*/
7288 }
7289 /*****************************************************************************/
redrawLabels()7290 static void redrawLabels()
7291 {
7292 	gl_build_labels();
7293 }
7294 /*****************************************************************************/
7295 /*
7296 static void getOriginAxes(gdouble* w)
7297 {
7298 	gint x  = GeomDrawingArea->allocation.width/20;
7299 	gint y  = GeomDrawingArea->allocation.height-GeomDrawingArea->allocation.height/10;
7300 	if(Natoms>0)
7301 	{
7302 		gint i = 0;
7303 		GLdouble View2D[3];
7304 		gluProject(geometry[i].X, geometry[i].Y, geometry[i].Z,mvmatrix, projmatrix, viewport, &View2D[0], &View2D[1], &View2D[2]);
7305 		gluUnProject( (float)x, (float)viewport[3] - (float)y, View2D[2], mvmatrix, projmatrix, viewport, &w[0], &w[1], &w[2]);
7306 	}
7307 	else
7308 	{
7309 		gint i;
7310 		for(i=0;i<3;i++)w[i] = 0;
7311 	}
7312 }
7313 */
7314 /*****************************************************************************/
redrawAxes()7315 static void redrawAxes()
7316 {
7317 	/*gdouble w[3]={0,0,0};*/
7318 	if(!testShowAxesGeom()) return;
7319 	/*if (RebuildAxes || glIsList(AxesList) != GL_TRUE )*/
7320 	{
7321 		if (glIsList(AxesList) == GL_TRUE) glDeleteLists(AxesList,1);
7322 		AxesList = glGenLists(1);
7323 		glNewList(AxesList, GL_COMPILE);
7324 		/*getOriginAxes(w);*/
7325 		/*gl_build_axes(w);*/
7326 		gl_build_axes(NULL);
7327 		glEndList();
7328 		glCallList(AxesList);
7329 		/*RebuildAxes = TRUE;*/
7330 	}
7331 	/*else
7332 	{
7333 		glCallList(AxesList);
7334 	}*/
7335 }
7336 /*****************************************************************************/
redrawDipole()7337 static void redrawDipole()
7338 {
7339 	if(!ShowDipole) return;
7340 	if(!Dipole.def) return;
7341 	/*if (RebuildDipole || glIsList(DipoleList) != GL_TRUE )*/
7342 	{
7343 		if (glIsList(DipoleList) == GL_TRUE) glDeleteLists(DipoleList,1);
7344 		DipoleList = glGenLists(1);
7345 		glNewList(DipoleList, GL_COMPILE);
7346 		gl_build_dipole();
7347 		glEndList();
7348 		glCallList(DipoleList);
7349 		/*RebuildSelection = TRUE;*/
7350 	}
7351 	/*else
7352 	{
7353 		glCallList(DipoleList);
7354 	}*/
7355 }
7356 /********************************************************************************/
redraw(GtkWidget * widget)7357 static gint redraw(GtkWidget *widget)
7358 {
7359 	GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
7360 	GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);
7361 	GLdouble m[4][4];
7362 	if(Zoom>=180) Zoom = 160;
7363 	if(!GTK_IS_WIDGET(widget)) return TRUE;
7364 	if(!GTK_WIDGET_REALIZED(widget)) return TRUE;
7365 
7366 	if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) return FALSE;
7367 
7368     	glMatrixMode(GL_PROJECTION);
7369     	glLoadIdentity();
7370 	addFog();
7371 	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
7372 	glClearDepth(1.0);
7373 	set_background_color();
7374 
7375 	mYPerspective(45,(GLdouble)widget->allocation.width/(GLdouble)widget->allocation.height,1,100);
7376     	glMatrixMode(GL_MODELVIEW);
7377 	glLoadIdentity();
7378 	if(optcol==-1) drawChecker();
7379 
7380     	glMatrixMode(GL_PROJECTION);
7381     	glLoadIdentity();
7382 	if(PersMode)
7383 		mYPerspective(Zoom,(GLdouble)widget->allocation.width/(GLdouble)widget->allocation.height,zNear,zFar);
7384 	else
7385 	{
7386 	  	gdouble fw = (GLdouble)widget->allocation.width/(GLdouble)widget->allocation.height;
7387 	  	gdouble fh = 1.0;
7388 		glOrtho(-fw,fw,-fh,fh,-1,1);
7389 	}
7390 
7391     	glMatrixMode(GL_MODELVIEW);
7392 	glLoadIdentity();
7393 	if(PersMode)
7394 		glTranslatef(Trans[0],Trans[1],Trans[2]);
7395 	else
7396 	{
7397 		 glTranslatef(Trans[0]/10,Trans[1]/10,0);
7398 		 glScalef(1/Zoom*2,1/Zoom*2,1/Zoom*2);
7399 	}
7400 	SetLight();
7401 
7402 	build_rotmatrix(m,Quat);
7403 	glMultMatrixd(&m[0][0]);
7404 
7405 	redrawGeometry();
7406 	redrawSelection();
7407 	redrawDipole();
7408 	redrawLabels();
7409 	redrawAxes();
7410 	if(strToDraw) draw_text(strToDraw);
7411 
7412         if(OperationType==SELECTFRAG) draw_rectangle_selection();
7413 
7414 	glGetIntegerv(GL_VIEWPORT, viewport);
7415 	glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix);
7416 	glGetDoublev(GL_PROJECTION_MATRIX, projmatrix);
7417 
7418 	glEnable(GL_DEPTH_TEST);
7419 	glDepthMask(GL_TRUE);
7420 	glDepthRange(0.0f,1.0f);
7421 	if (gdk_gl_drawable_is_double_buffered (gldrawable))
7422 		gdk_gl_drawable_swap_buffers (gldrawable);
7423 	else glFlush ();
7424 	gdk_gl_drawable_gl_end (gldrawable);
7425 
7426         while( gtk_events_pending() ) gtk_main_iteration();
7427 
7428 	return TRUE;
7429 }
7430 /********************************************************************************/
redrawGeomGL2PS()7431 void redrawGeomGL2PS()
7432 {
7433 	GtkWidget* widget = GeomDrawingArea;
7434 	GLdouble m[4][4];
7435 	if(Zoom>=180) Zoom = 160;
7436 
7437 	if(!GTK_IS_WIDGET(widget)) return;
7438 	if(!GTK_WIDGET_REALIZED(widget)) return;
7439 
7440     	glMatrixMode(GL_PROJECTION);
7441     	glLoadIdentity();
7442 	addFog();
7443 	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
7444 	set_background_color();
7445 
7446 	mYPerspective(45,(GLdouble)widget->allocation.width/(GLdouble)widget->allocation.height,1,100);
7447     	glMatrixMode(GL_MODELVIEW);
7448 	glLoadIdentity();
7449 	if(optcol==-1) drawChecker();
7450 
7451     	glMatrixMode(GL_PROJECTION);
7452     	glLoadIdentity();
7453 	if(PersMode)
7454 		mYPerspective(Zoom,(GLdouble)widget->allocation.width/(GLdouble)widget->allocation.height,zNear,zFar);
7455 	else
7456 	{
7457 	  	gdouble fw = (GLdouble)widget->allocation.width/(GLdouble)widget->allocation.height;
7458 	  	gdouble fh = 1.0;
7459 		glOrtho(-fw,fw,-fh,fh,-1,1);
7460 	}
7461 
7462     	glMatrixMode(GL_MODELVIEW);
7463 	glLoadIdentity();
7464 	if(PersMode)
7465 		glTranslatef(Trans[0],Trans[1],Trans[2]);
7466 	else
7467 	{
7468 		 glTranslatef(Trans[0]/10,Trans[1]/10,0);
7469 		 glScalef(1/Zoom*2,1/Zoom*2,1/Zoom*2);
7470 	}
7471 	SetLight();
7472 
7473 	build_rotmatrix(m,Quat);
7474 	glMultMatrixd(&m[0][0]);
7475 
7476 	gl_build_geometry();
7477 	gl_build_selection();
7478 	gl_build_labels();
7479 	gl_build_dipole();
7480 	if(testShowAxesGeom()) redrawAxes();
7481 
7482 	glFlush ();
7483 }
7484 /********************************************************************************/
configure_event(GtkWidget * widget,GdkEventConfigure * event)7485 static gint configure_event( GtkWidget *widget, GdkEventConfigure *event )
7486 {
7487 	drawGeom();
7488 
7489 	return TRUE;
7490 }
7491 /********************************************************************************/
expose_event(GtkWidget * widget,GdkEventExpose * event)7492 static gint expose_event( GtkWidget *widget, GdkEventExpose *event )
7493 {
7494 	if(event->count >0) return FALSE;
7495 	drawGeom();
7496 	return FALSE;
7497 }
7498 /*****************************************************************************/
SetCosSin()7499 void SetCosSin()
7500 {
7501   int i;
7502 
7503   for ( i=0; i < 91; i++ ) {
7504         TSIN[i] = sin((PI*i)/180.0);
7505         TCOS[i] = cos((PI*i)/180.0);
7506   }
7507 }
7508 /*****************************************************************************/
RenderStick()7509 void RenderStick()
7510 {
7511 	TypeGeom = GABEDIT_TYPEGEOM_STICK;
7512 	RebuildGeom = TRUE;
7513 	drawGeom();
7514 }
7515 /*****************************************************************************/
RenderBallStick()7516 void RenderBallStick()
7517 {
7518 	TypeGeom = GABEDIT_TYPEGEOM_BALLSTICK;
7519 	RebuildGeom = TRUE;
7520 	drawGeom();
7521 }
7522 /*****************************************************************************/
RenderSpaceFill()7523 void RenderSpaceFill()
7524 {
7525 	TypeGeom = GABEDIT_TYPEGEOM_SPACE;
7526 	RebuildGeom = TRUE;
7527 	drawGeom();
7528 }
7529 /*****************************************************************************/
ActivateButtonOperation(GtkWidget * widget,guint data)7530 void ActivateButtonOperation (GtkWidget *widget, guint data)
7531 {
7532 	SetOperation (widget,data);
7533 }
7534 /*****************************************************************************/
SetOperation(GtkWidget * widget,guint data)7535 void SetOperation (GtkWidget *widget, guint data)
7536 {
7537 	gchar* temp = NULL;
7538 
7539 	if(data == CENTER)
7540 	{
7541 			Trans[0] = 0;
7542 			Trans[1] = 0;
7543 
7544 			drawGeom();
7545 		return;
7546 	}
7547 
7548 	OperationType = data ;
7549 	if( OperationType != ADDFRAGMENT)
7550 		hide_fragments_selector();
7551 	switch(data)
7552 	{
7553 		case ROTATION	: temp = g_strdup(_(" Press the Left mouse button and move your mouse for a \"Rotate molecule\". "));break;
7554 		case ROTATIONZ	: temp = g_strdup(_(" Press the Left mouse button and move your mouse for a \"Rotate molecule about z axis\". "));break;
7555 		case TRANSMOVIE : temp = g_strdup(_(" Press the Left mouse button and move your mouse for a \"Translation\". "));break;
7556 		case SCALEGEOM	: temp = g_strdup(_(" Press the Left mouse button and move your mouse for a \"Zoom\". "));break;
7557 		case SCALESTICK : temp = g_strdup(_(" Press the Left mouse button and move your mouse for \"Scale Stick\". "));break;
7558 		case SCALEBALL  :  temp = g_strdup(_(" Press the Left mouse button and move your mouse for \"Scale Ball\". "));break;
7559 		case SCALEDIPOLE:  temp = g_strdup(_(" Press the Left mouse button and move your mouse for \"Scale Dipole\". "));break;
7560 		case SELECTOBJECTS :  temp = g_strdup(_("Pick an atom to select a residue, G key + pick an atom to select a group, Or F key + move your mouse to select a fragment. Use shift key for more selections."));break;
7561 		case SELECTFRAG :  temp = g_strdup(_(" Press the Left mouse button and move your mouse for \"select a fragment\".Use shift key for more selections. "));break;
7562 		case SELECTRESIDUE :  temp = g_strdup(_("  Press the Left mouse button for pick an atom, all atoms for residue of this atom are selected(or unselected)."));break;
7563 		case DELETEFRAG :  temp = g_strdup(_(" Press the Left mouse button(for pick an atom or all selected atoms) and release for \"Delete selected atom(s)\". "));break;
7564 		case ROTLOCFRAG :  temp = g_strdup(_(" Press the Left mouse button and move your mouse for \"Rotatation of selected atom(s)[Local Rotation]\". "));break;
7565 		case ROTZLOCFRAG :  temp = g_strdup(_(" Press the Left mouse button and move your mouse for \"Rotation, about z axis, of selected atom(s)[Local Rotation]\". "));break;
7566 		case MOVEFRAG   :  temp = g_strdup(_(" Press the Left mouse button(for pick an atom or all selected atoms) and move your mouse for \"Move selected atom(s)\". "));break;
7567 		case EDITOBJECTS :  temp = g_strdup(_(" Press and release the Left mouse button for \"Insert/Change atom(s)/bond\".\"Pick an atom for replace it.\""));break;
7568 		case ADDATOMSBOND :  temp = g_strdup(_(" Press and release the Left mouse button for \"Insert atom(s)/bond\".\"Pick an atom for replace it.\""));break;
7569 		case CHANGEBOND :  temp = g_strdup(_(" Press the Left mouse button(for pick a bond) and release for \"Change selected bond\". "));break;
7570 		case CUTBOND :  temp = g_strdup(_(" Press the Left mouse button(for pick a bond) and release for \"Delete selected bond\". "));break;
7571 		case MEASURE		:  temp = g_strdup(_(" Press and release the Left mouse button for \"Select your atoms\". "));
7572 							HideShowMeasure(FALSE);
7573 							change_of_center(NULL,NULL);
7574 							drawGeom();
7575 							break;
7576 		case ADDFRAGMENT :  temp = g_strdup(_(" Press and release the Left mouse button for \"Insert a Fragment\". "));break;
7577 	}
7578 	if(temp)
7579 	{
7580 		gtk_statusbar_pop(GTK_STATUSBAR(StatusOperation),idStatusOperation);
7581 		gtk_statusbar_push(GTK_STATUSBAR(StatusOperation),idStatusOperation,temp);
7582 		g_free(temp);
7583 	}
7584 	drawGeom();
7585 }
7586 /*****************************************************************************/
setPersonalFragment(Fragment F)7587 void setPersonalFragment(Fragment F)
7588 {
7589 	gint i;
7590 	Frag.NAtoms = F.NAtoms;
7591 	Frag.Atoms = g_malloc(Frag.NAtoms*sizeof(Atom));
7592 	for(i=0;i<F.NAtoms;i++)
7593 	{
7594 		Frag.Atoms[i].Residue = g_strdup(F.Atoms[i].Residue);
7595 		Frag.Atoms[i].Symb = g_strdup(F.Atoms[i].Symb);
7596 		Frag.Atoms[i].mmType = g_strdup(F.Atoms[i].mmType);
7597 		Frag.Atoms[i].pdbType = g_strdup(F.Atoms[i].pdbType);
7598 		Frag.Atoms[i].Coord[0] = F.Atoms[i].Coord[0];
7599 		Frag.Atoms[i].Coord[1] = F.Atoms[i].Coord[1];
7600 		Frag.Atoms[i].Coord[2] = F.Atoms[i].Coord[2];
7601 		Frag.Atoms[i].Charge = F.Atoms[i].Charge;
7602 	}
7603 	Frag.atomToDelete = F.atomToDelete;
7604 	Frag.atomToBondTo = F.atomToBondTo;
7605 	Frag.angleAtom    = F.angleAtom;
7606 
7607 	SetOperation (NULL,ADDFRAGMENT);
7608 }
7609 /*****************************************************************************/
AddFragment(GtkWidget * widget,guint data)7610 void AddFragment(GtkWidget *widget, guint data)
7611 {
7612 	FreeFragment(&Frag);
7613 	Frag = GetFragment(FragItems[data].Name);
7614 	SetOperation (NULL,ADDFRAGMENT);
7615 }
7616 /*****************************************************************************/
add_a_fragment(GtkWidget * button,gchar * fragName)7617 void add_a_fragment(GtkWidget* button, gchar* fragName)
7618 {
7619 	GtkWidget* drawingArea = NULL;
7620 	gchar* slash = NULL;
7621 	if(!fragName) return;
7622 	FreeFragment(&Frag);
7623 	slash = strstr(fragName,"/");
7624 	if(slash && strlen(fragName)>strlen(slash))
7625 	{
7626 		Frag = GetFragment(slash+1);
7627 		if(Frag.NAtoms>1 && strstr(fragName,"Fullerenes"))
7628 		{
7629 			AddHToAtomPDB(&Frag,"C");
7630 		}
7631 		if(Frag.NAtoms<1)
7632 		{
7633 			gint OC1 = -1;
7634 			gint C = -1;
7635 			gint N = -1;
7636 			gint i ;
7637 
7638 			Frag = GetFragmentPPD(slash+1);
7639 			for(i=0;i<Frag.NAtoms;i++)
7640 			{
7641 				if(!strcmp(Frag.Atoms[i].pdbType,"OC1")) OC1 =  i;
7642 				if(!strcmp(Frag.Atoms[i].pdbType,"C")) C =  i;
7643 				if(!strcmp(Frag.Atoms[i].pdbType,"N")) N =  i;
7644 			}
7645 			/* printf("%s\n",Frag.Atoms[0].Residue);*/
7646 			if(Frag.NAtoms>1)
7647 			{
7648 				if(C != -1 && N == -1) AddHToAtomPDB(&Frag,"C");
7649 				else if(C == -1 && N != -1) AddHToAtomPDB(&Frag,"N");
7650 				else if(strlen(Frag.Atoms[0].Residue)<4) AddHToAtomPDB(&Frag,"C");
7651 				else if(strlen(Frag.Atoms[0].Residue)==4)
7652 				{
7653 					if( toupper(Frag.Atoms[0].Residue[0])=='C' || toupper(Frag.Atoms[0].Residue[0])=='O' ) AddHToAtomPDB(&Frag,"N");
7654 					else AddHToAtomPDB(&Frag,"C");
7655 				}
7656 			}
7657 		}
7658 		if(Frag.NAtoms<1)
7659 		{
7660 			Frag = GetFragmentCrystal(slash+1);
7661 		}
7662 		if(Frag.NAtoms<1)
7663 			addPersonalFragment(fragName, 0, NULL);
7664 	}
7665 	else
7666 		Frag = GetFragment(fragName);
7667 
7668 	drawingArea = g_object_get_data(G_OBJECT(button), "DrawingArea");
7669 	if(drawingArea) add_frag_to_preview_geom(drawingArea, &Frag);
7670 }
7671 /*****************************************************************************/
addAFragment(gchar * fragName)7672 void addAFragment(gchar* fragName)
7673 {
7674 	FreeFragment(&Frag);
7675 	if(fragName) Frag = GetFragment(fragName);
7676 	else return;
7677 	SetOperation (NULL,ADDFRAGMENT);
7678 }
7679 /*****************************************************************************/
initLabelOptions(guint data)7680 void initLabelOptions (guint data)
7681 {
7682 	LabelOption = data ;
7683 }
7684 /*****************************************************************************/
SetLabelOptions(GtkWidget * widget,guint data)7685 void SetLabelOptions (GtkWidget *widget, guint data)
7686 {
7687 	if(LabelOption != data)
7688 	{
7689 		LabelOption = data ;
7690 		drawGeom();
7691 	}
7692 }
7693 /*****************************************************************************/
SetLabelDistances(GtkWidget * win,gboolean YesNo)7694 void SetLabelDistances(GtkWidget *win,gboolean YesNo)
7695 {
7696 	DrawDistance = !DrawDistance;
7697 	drawGeom();
7698 }
7699 /*****************************************************************************/
SetLabelDipole(GtkWidget * win,gboolean YesNo)7700 void SetLabelDipole(GtkWidget *win,gboolean YesNo)
7701 {
7702 	DrawDipole = !DrawDipole;
7703 	drawGeom();
7704 }
7705 /*****************************************************************************/
SetLabelsOrtho(GtkWidget * win,gboolean YesNo)7706 void SetLabelsOrtho(GtkWidget *win,gboolean YesNo)
7707 {
7708 	ortho = !ortho;
7709 	drawGeom();
7710 }
7711 /*****************************************************************************/
RenderShad(GtkWidget * win,gboolean YesNo)7712 void RenderShad(GtkWidget *win,gboolean YesNo)
7713 {
7714 	ShadMode = !ShadMode;
7715 	drawGeom();
7716 }
7717 /*****************************************************************************/
RenderPers(GtkWidget * win,gboolean YesNo)7718 void RenderPers(GtkWidget *win,gboolean YesNo)
7719 {
7720 	PersMode = !PersMode;
7721 	drawGeom();
7722 }
7723 /*****************************************************************************/
RenderLight(GtkWidget * win,gboolean YesNo)7724 void RenderLight(GtkWidget *win,gboolean YesNo)
7725 {
7726 	LightMode = !LightMode;
7727 	drawGeom();
7728 }
7729 /*****************************************************************************/
RenderOrtep(GtkWidget * win,gboolean YesNo)7730 void RenderOrtep(GtkWidget *win,gboolean YesNo)
7731 {
7732 	OrtepMode = !OrtepMode;
7733 	drawGeom();
7734 }
7735 /*****************************************************************************/
RenderCartoon(GtkWidget * win,gboolean YesNo)7736 void RenderCartoon(GtkWidget *win,gboolean YesNo)
7737 {
7738 	CartoonMode = !CartoonMode;
7739 	drawGeom();
7740 }
7741 /*****************************************************************************/
RenderHBonds(GtkWidget * win,gboolean YesNo)7742 void RenderHBonds(GtkWidget *win,gboolean YesNo)
7743 {
7744 	ShowHBonds = !ShowHBonds;
7745 	if(ShowHBonds) set_Hconnections();
7746 	RebuildGeom=TRUE;
7747 	drawGeom();
7748 }
7749 /*****************************************************************************/
RenderHAtoms(GtkWidget * win,gboolean YesNo)7750 void RenderHAtoms(GtkWidget *win,gboolean YesNo)
7751 {
7752 	gint i;
7753 	for (i=0;i<(gint)Natoms;i++)
7754 	{
7755 		if(!strcmp(geometry0[i].Prop.symbol,"H"))
7756 		{
7757 			geometry[i].show = YesNo;
7758 			geometry0[i].show = YesNo;
7759 		}
7760 	}
7761 	RebuildGeom=TRUE;
7762 	drawGeom();
7763 	ShowHydrogenAtoms = YesNo;
7764 }
7765 /*****************************************************************************/
RenderDipole(GtkWidget * win,gboolean YesNo)7766 void RenderDipole(GtkWidget *win,gboolean YesNo)
7767 {
7768 	ShowDipole = !ShowDipole;
7769 	drawGeom();
7770 }
7771 /*****************************************************************************/
RenderAxes(GtkWidget * win,gboolean YesNo)7772 void RenderAxes(GtkWidget *win,gboolean YesNo)
7773 {
7774 	if(testShowAxesGeom()) hideAxesGeom();
7775 	else showAxesGeom();
7776 	drawGeom();
7777 }
7778 /*****************************************************************************/
RenderBox(GtkWidget * win,gboolean YesNo)7779 void RenderBox(GtkWidget *win,gboolean YesNo)
7780 {
7781 	if(testShowBoxGeom()) showBox = FALSE;
7782 	else showBox = TRUE;
7783 	RebuildGeom = TRUE;
7784 	drawGeom();
7785 }
7786 /*****************************************************************************/
set_dipole_from_charges()7787 void set_dipole_from_charges()
7788 {
7789 	gint i;
7790 	gint j;
7791 
7792 	create_GeomXYZ_from_draw_grometry();
7793 	NumSelectedAtom = -1;
7794 	unselect_all_atoms();
7795 	Dipole.def = TRUE;
7796 	for(i=0;i<3;i++) Dipole.value[i] = 0.0;
7797 	for(i=0;i<3;i++) Dipole.origin[i] = 0.0;
7798 	for(j=0;j<(gint)Natoms;j++)
7799 	{
7800 		Dipole.value[0] += geometry0[j].X*geometry0[j].Charge;
7801 		Dipole.value[1] += geometry0[j].Y*geometry0[j].Charge;
7802 		Dipole.value[2] += geometry0[j].Z*geometry0[j].Charge;
7803 
7804 	}
7805 	drawGeom();
7806 }
7807 /*****************************************************************************/
get_sum_charges()7808 gdouble get_sum_charges()
7809 {
7810 	gdouble c = 0;
7811 	gint j;
7812 
7813 	for(j=0;j<(gint)Natoms;j++)
7814 		c += geometry0[j].Charge;
7815 	return c;
7816 }
7817 /*****************************************************************************/
compute_total_charge()7818 void compute_total_charge()
7819 {
7820 	gdouble c = 0;
7821 	gdouble cNeg = 0;
7822 	gdouble cPos = 0;
7823 	gint j;
7824     	GtkWidget* m;
7825 	gchar tmp[BSIZE];
7826 
7827 	for(j=0;j<(gint)Natoms;j++)
7828 	{
7829 		if(geometry0[j].Charge>0) cPos += geometry0[j].Charge;
7830 		if(geometry0[j].Charge<0) cNeg += geometry0[j].Charge;
7831 		c += geometry0[j].Charge;
7832 
7833 	}
7834 	if(cNeg !=0 && cPos != 0)
7835 	sprintf(tmp,
7836 			_(
7837 			"Total Charge = %f\n"
7838 			"Sum of positive charges = %f\n"
7839 			"Sum of negative charges = %f\n"
7840 			"positive/negative       = %f\n"
7841 			"negative/positive       = %f\n"
7842 			)
7843 			,
7844 			c, cPos, cNeg, cPos/cNeg, cNeg/cPos);
7845 	else
7846 	sprintf(tmp,
7847 			_(
7848 			"Total Charge = %f\n"
7849 			"Sum of positive charges = %f\n"
7850 			"Sum of negative charges = %f\n"
7851 			)
7852 			,
7853 			c, cPos, cNeg);
7854 	m = Message(tmp,_("Info"),TRUE);
7855 	gtk_window_set_modal (GTK_WINDOW (m), TRUE);
7856 }
7857 /*****************************************************************************/
compute_charge_of_selected_atoms()7858 void compute_charge_of_selected_atoms()
7859 {
7860 	gdouble c = 0;
7861 	gdouble cNeg = 0;
7862 	gdouble cPos = 0;
7863 	gint j;
7864     	GtkWidget* m;
7865 	gchar tmp[BSIZE];
7866 
7867 	for(j=0;j<(gint)Natoms;j++)
7868 	{
7869 		if(!if_selected(j)) continue;
7870 
7871 		if(geometry0[j].Charge>0) cPos += geometry0[j].Charge;
7872 		if(geometry0[j].Charge<0) cNeg += geometry0[j].Charge;
7873 		c += geometry0[j].Charge;
7874 
7875 	}
7876 	if(cNeg !=0 && cPos != 0)
7877 	sprintf(tmp,
7878 			_(
7879 			"Total Charge = %f\n"
7880 			"Sum of positive charges = %f\n"
7881 			"Sum of negative charges = %f\n"
7882 			"positive/negative       = %f\n"
7883 			"negative/positive       = %f\n"
7884 			)
7885 			,
7886 			c, cPos, cNeg, cPos/cNeg, cNeg/cPos);
7887 	else
7888 	sprintf(tmp,
7889 			_(
7890 			"Total Charge = %f\n"
7891 			"Sum of positive charges = %f\n"
7892 			"Sum of negative charges = %f\n"
7893 			)
7894 			,
7895 			c, cPos, cNeg);
7896 	m = Message(tmp,_("Info"),TRUE);
7897 	gtk_window_set_modal (GTK_WINDOW (m), TRUE);
7898 }
7899 /********************************************************************************/
create_text_win(gchar * title)7900 static GtkWidget* create_text_win(gchar* title)
7901 {
7902 	GtkWidget *Win;
7903 	GtkWidget *frame;
7904 	GtkWidget *vboxall;
7905 	GtkWidget *vboxwin;
7906 	GtkWidget *text;
7907 
7908 	/* Principal Window */
7909 	Win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
7910 	gtk_window_set_title(GTK_WINDOW(Win),title);
7911 	gtk_window_set_position(GTK_WINDOW(Win),GTK_WIN_POS_CENTER);
7912 	gtk_window_set_transient_for(GTK_WINDOW(Win),GTK_WINDOW(Fenetre));
7913 	gtk_window_set_modal (GTK_WINDOW (Win), TRUE);
7914 
7915 	gtk_widget_realize(Win);
7916 	g_signal_connect(G_OBJECT(Win),"delete_event",(GCallback)gtk_widget_destroy,NULL);
7917 
7918 	gtk_container_set_border_width (GTK_CONTAINER (Win), 5);
7919 	vboxall = create_vbox(Win);
7920 	vboxwin = vboxall;
7921 
7922 	frame = gtk_frame_new (NULL);
7923 	gtk_container_set_border_width (GTK_CONTAINER (frame), 5);
7924 	gtk_frame_set_shadow_type( GTK_FRAME(frame),GTK_SHADOW_ETCHED_OUT);
7925 	gtk_container_add(GTK_CONTAINER(vboxall),frame);
7926 	gtk_widget_show (frame);
7927 	text = create_text(Win,frame,TRUE);
7928 	set_font (text,FontsStyleResult.fontname);
7929 	set_base_style(text,FontsStyleResult.BaseColor.red ,FontsStyleResult.BaseColor.green ,FontsStyleResult.BaseColor.blue);
7930 	set_text_style(text,FontsStyleResult.TextColor.red ,FontsStyleResult.TextColor.green ,FontsStyleResult.TextColor.blue);
7931 	g_object_set_data(G_OBJECT (Win), "Text", text);
7932 	return Win;
7933 }
7934 /*****************************************************************************/
compute_charge_by_residue()7935 void compute_charge_by_residue()
7936 {
7937 	gint i;
7938 	gint j;
7939 	gint k;
7940 	gdouble* charges = NULL;
7941 	gint nr = 0;
7942 	GtkWidget *win;
7943 	GtkWidget *text;
7944 	gchar tmp[BSIZE];
7945 	gint* nums = NULL;
7946 
7947 	if(Natoms<1) return;
7948 
7949 	for(j=0;j<(gint)Natoms;j++)
7950 	{
7951 		if( nr<geometry0[j].ResidueNumber+1) nr = geometry0[j].ResidueNumber+1;
7952 	}
7953 	if(nr<1) return;
7954 
7955 	charges = g_malloc(nr*sizeof(gdouble));
7956 	nums = g_malloc(nr*sizeof(gint));
7957 
7958 	for(k=0;k<nr;k++) charges[k] = 0;
7959 	for(k=0;k<nr;k++) nums[k] = 0;
7960 
7961 
7962 	for(j=0;j<(gint)Natoms;j++)
7963 	{
7964 		k =  geometry0[j].ResidueNumber;
7965 		charges[k] += geometry0[j].Charge;
7966 		nums[k] = j;
7967 	}
7968 	for(i=0;i<nr-1;i++)
7969 	{
7970 		k = i;
7971 		for(j=i+1;j<nr;j++)
7972 			if(geometry0[nums[k]].ResidueNumber>geometry0[nums[j]].ResidueNumber) k = j;
7973 		if(i!=k)
7974 		{
7975 			gdouble x;
7976 			gint ix;
7977 			x = charges[k];
7978 			charges[k] = charges[i];
7979 			charges[i] = x;
7980 			ix = nums[k];
7981 			nums[k] = nums[i];
7982 			nums[i] = ix;
7983 
7984 		}
7985 	}
7986 	win = create_text_win(_("Charge by residues"));
7987     	gtk_widget_set_size_request(GTK_WIDGET(win),(gint)(ScreenHeight*0.5),(gint)(ScreenHeight*0.5));
7988 	text = g_object_get_data(G_OBJECT (win), "Text");
7989 	if(text)
7990 	for(k=0;k<nr;k++)
7991 	{
7992 		j = nums[k]+1;
7993 		sprintf(tmp,_("%s[%d] Charge = %f\n"),
7994 				geometry0[j-1].Residue,geometry0[j-1].ResidueNumber+1,charges[k]);
7995 		gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL,tmp,-1);
7996 	}
7997 	if(nums)g_free(nums);
7998 	if(charges)g_free(charges);
7999 	gtk_widget_show_all(win);
8000 }
8001 /*****************************************************************************/
compute_dipole_from_charges()8002 void compute_dipole_from_charges()
8003 {
8004 	gint j;
8005 	gdouble D[3] = {0,0,0};
8006     	GtkWidget* m;
8007 	gchar tmp[100];
8008 	gdouble tot = 0;
8009 
8010 	for(j=0;j<(gint)Natoms;j++)
8011 	{
8012 		D[0] += geometry0[j].X*geometry0[j].Charge;
8013 		D[1] += geometry0[j].Y*geometry0[j].Charge;
8014 		D[2] += geometry0[j].Z*geometry0[j].Charge;
8015 	}
8016 	for(j=0;j<3;j++)
8017 		D[j] *= AUTODEB;
8018 
8019 	for(j=0;j<3;j++)
8020 		tot += D[j]*D[j];
8021 	tot = sqrt(tot);
8022 
8023 	sprintf(tmp,_("Dipole (Debye) : X= %f Y= %f Z= %f  Tot=%f\n"),D[0] ,  D[1], D[2],tot);
8024 	m = Message(tmp,_("Info"),TRUE);
8025 	gtk_window_set_modal (GTK_WINDOW (m), TRUE);
8026 }
8027 /*****************************************************************************/
get_distance(gint i,gint j)8028 gchar *get_distance(gint i,gint j)
8029 {
8030         Point A;
8031         Point B;
8032         guint k;
8033         guint Ni=-1;
8034         guint Nj=-1;
8035         gchar *serr;
8036 
8037        for (k=0;k<Natoms;k++)
8038 	  if(geometry[k].N== (guint)i)
8039 		Ni = k;
8040        for (k=0;k<Natoms;k++)
8041 	  if(geometry[k].N== (guint)j)
8042 		Nj = k;
8043 
8044         if(Ni==-1 || Nj == -1)
8045         {
8046            serr=g_strdup("ERROR");
8047            return serr;
8048         }
8049 
8050 	A.C[0]=geometry[Ni].X;
8051 	A.C[1]=geometry[Ni].Y;
8052 	A.C[2]=geometry[Ni].Z;
8053 
8054 	B.C[0]=geometry[Nj].X;
8055 	B.C[1]=geometry[Nj].Y;
8056 	B.C[2]=geometry[Nj].Z;
8057 
8058         return get_distance_points(A,B,FALSE);
8059 }
8060 /*****************************************************************************/
get_angle(gint i,gint j,gint l)8061 gchar *get_angle(gint i,gint j,gint l)
8062 {
8063         Point A;
8064         Point B;
8065         guint k;
8066         guint Ni=0;
8067         guint Nj=0;
8068         guint Nl=0;
8069 
8070        for (k=0;k<Natoms;k++)
8071 	  if(geometry[k].N== (guint)i)
8072 		Ni = k;
8073        for (k=0;k<Natoms;k++)
8074 	  if(geometry[k].N== (guint)j)
8075 		Nj = k;
8076        for (k=0;k<Natoms;k++)
8077 	  if(geometry[k].N== (guint)l)
8078 		Nl = k;
8079 
8080 
8081 	A.C[0]=geometry[Ni].X-geometry[Nj].X;
8082 	A.C[1]=geometry[Ni].Y-geometry[Nj].Y;
8083 	A.C[2]=geometry[Ni].Z-geometry[Nj].Z;
8084 
8085 	B.C[0]=geometry[Nl].X-geometry[Nj].X;
8086 	B.C[1]=geometry[Nl].Y-geometry[Nj].Y;
8087 	B.C[2]=geometry[Nl].Z-geometry[Nj].Z;
8088 
8089         return get_angle_vectors(A,B);
8090 }
8091 /*****************************************************************************/
get_dihedral(gint i,gint j,gint l,gint m)8092 gchar *get_dihedral(gint i,gint j,gint l,gint m)
8093 {
8094         Point A;
8095         Point B;
8096         Point V1;
8097         Point V2;
8098         Point W1;
8099         guint k;
8100         guint Ni=0;
8101         guint Nj=0;
8102         guint Nl=0;
8103         guint Nm=0;
8104 	gdouble angle;
8105 	gdouble dihsgn;
8106 
8107        for (k=0;k<Natoms;k++)
8108 	  if(geometry[k].N== (guint)i)
8109 		Ni = k;
8110        for (k=0;k<Natoms;k++)
8111 	  if(geometry[k].N==(guint)j)
8112 		Nj = k;
8113        for (k=0;k<Natoms;k++)
8114 	  if(geometry[k].N== (guint)l)
8115 		Nl = k;
8116        for (k=0;k<Natoms;k++)
8117 	  if(geometry[k].N== (guint)m)
8118 		Nm = k;
8119 
8120 
8121 	V1.C[0]=geometry[Ni].X-geometry[Nj].X;
8122 	V1.C[1]=geometry[Ni].Y-geometry[Nj].Y;
8123 	V1.C[2]=geometry[Ni].Z-geometry[Nj].Z;
8124 
8125 	V2.C[0]=geometry[Nl].X-geometry[Nj].X;
8126 	V2.C[1]=geometry[Nl].Y-geometry[Nj].Y;
8127 	V2.C[2]=geometry[Nl].Z-geometry[Nj].Z;
8128 
8129         A = get_produit_vectoriel(V1,V2);
8130 
8131 	V1.C[0]=geometry[Nm].X-geometry[Nl].X;
8132 	V1.C[1]=geometry[Nm].Y-geometry[Nl].Y;
8133 	V1.C[2]=geometry[Nm].Z-geometry[Nl].Z;
8134 
8135 	V2.C[0]=geometry[Nj].X-geometry[Nl].X;
8136 	V2.C[1]=geometry[Nj].Y-geometry[Nl].Y;
8137 	V2.C[2]=geometry[Nj].Z-geometry[Nl].Z;
8138 
8139         B = get_produit_vectoriel(V2,V1);
8140 
8141         angle = atof(get_angle_vectors(A,B));
8142 
8143         W1 = get_produit_vectoriel(A,B);
8144         if (get_module(W1)<1e-5 )
8145               dihsgn = 1.0e0;
8146         else
8147 	{
8148         dihsgn = get_scalaire(W1,V2);
8149         if (dihsgn>0)
8150             dihsgn = -1.0e0;
8151         else
8152            dihsgn = 1.0e0;
8153 	}
8154           angle *=dihsgn;
8155 	return g_strdup_printf("%f",angle);
8156 }
8157 /*****************************************************************************/
geometry_in_au()8158 void geometry_in_au()
8159 {
8160         guint i;
8161         for(i=0;i<Natoms;i++)
8162 	{
8163            geometry[i].X *=ANG_TO_BOHR ;
8164            geometry[i].Y *=ANG_TO_BOHR ;
8165            geometry[i].Z *=ANG_TO_BOHR ;
8166         }
8167 }
8168 /*****************************************************************************/
set_layer(gchar * layer,GabEditLayerType * l)8169 static void set_layer(gchar* layer, GabEditLayerType* l)
8170 {
8171 	if(strstr(layer,"Low")) *l = LOW_LAYER;
8172 	else if(strstr(layer,"Medium")) *l= MEDIUM_LAYER;
8173 	else *l = HIGH_LAYER;
8174 }
8175 /*****************************************************************************/
set_constant_variable(gint i,gboolean xyz)8176 static void set_constant_variable(gint i, gboolean xyz)
8177 {
8178 	if(xyz)
8179 	{
8180         	if(!test(GeomXYZ[i].X) || !test(GeomXYZ[i].Y) || !test(GeomXYZ[i].Z))
8181 			geometry[i].Variable = TRUE;
8182 		else
8183 			geometry[i].Variable = FALSE;
8184 	}
8185 	else
8186 	{
8187 		if( i<1)
8188 		{
8189 			geometry[i].Variable = FALSE;
8190 			return;
8191 		}
8192 		if(i>0 && !test(Geom[i].R))
8193 		{
8194 			geometry[i].Variable = TRUE;
8195 			return;
8196 		}
8197 		if(i>1 && !test(Geom[i].Angle))
8198 		{
8199 			geometry[i].Variable = TRUE;
8200 			return;
8201 		}
8202 		if(i>2 && !test(Geom[i].Dihedral))
8203 		{
8204 			geometry[i].Variable = TRUE;
8205 			return;
8206 		}
8207 		geometry[i].Variable = FALSE;
8208 	}
8209 }
8210 /*****************************************************************************/
set_layer_of_selected_atoms(GabEditLayerType l)8211 void set_layer_of_selected_atoms(GabEditLayerType l)
8212 {
8213 	gint i;
8214 	for (i=0;i<(gint)Natoms;i++)
8215 	{
8216 		if(if_selected(i))
8217 		{
8218 			geometry[i].Layer = l;
8219 			geometry0[i].Layer = l;
8220 		}
8221 	}
8222 	create_GeomXYZ_from_draw_grometry();
8223 	RebuildGeom = TRUE;
8224 	drawGeom();
8225 }
8226 /*****************************************************************************/
define_geometry_from_xyz()8227 void define_geometry_from_xyz()
8228 {
8229         guint i;
8230 
8231         for(i=0;i<Natoms;i++)
8232 	{
8233          if(!test(GeomXYZ[i].X))
8234                  geometry[i].X = get_value_variableXYZ(GeomXYZ[i].X);
8235           else
8236 		geometry[i].X = atof(GeomXYZ[i].X);
8237          if(!test(GeomXYZ[i].Y))
8238                  geometry[i].Y = get_value_variableXYZ(GeomXYZ[i].Y);
8239           else
8240 		geometry[i].Y = atof(GeomXYZ[i].Y);
8241          if(!test(GeomXYZ[i].Z))
8242                  geometry[i].Z = get_value_variableXYZ(GeomXYZ[i].Z);
8243           else
8244 		geometry[i].Z = atof(GeomXYZ[i].Z);
8245 	geometry[i].Prop = prop_atom_get(GeomXYZ[i].Symb);
8246 	geometry[i].mmType = g_strdup(GeomXYZ[i].mmType);
8247 	geometry[i].pdbType = g_strdup(GeomXYZ[i].pdbType);
8248 	geometry[i].Residue = g_strdup(GeomXYZ[i].Residue);
8249 	geometry[i].ResidueNumber = GeomXYZ[i].ResidueNumber;
8250 	geometry[i].show = TRUE;
8251 	geometry[i].Charge = atof(GeomXYZ[i].Charge);
8252 	set_layer(GeomXYZ[i].Layer, &geometry[i].Layer);
8253 	set_constant_variable(i, TRUE);
8254 	geometry[i].N = i+1;
8255 	geometry[i].typeConnections = NULL;
8256 	}
8257 	for(i=0;i<Natoms;i++)
8258 	{
8259 		gint j;
8260 		geometry[i].typeConnections = g_malloc(Natoms*sizeof(gint));
8261 		for(j=0;j<(gint)Natoms;j++) geometry[i].typeConnections[j] = 0;
8262 		if(GeomXYZ[i].typeConnections)
8263 		{
8264 			for(j=0;j<Natoms;j++)
8265 			geometry[i].typeConnections[j] = GeomXYZ[i].typeConnections[j];
8266 		}
8267 	}
8268 }
8269 /*****************************************************************************/
define_geometry_from_zmat()8270 gboolean define_geometry_from_zmat()
8271 {
8272   gdouble cosph,sinph,costh,sinth,coskh,sinkh;
8273   gdouble cosa,sina,cosd,sind;
8274   gdouble dist,angle,dihed;
8275   gdouble xpd,ypd,zpd,xqd,yqd,zqd;
8276   gdouble xa,ya,za,xb,yb,zb;
8277   gdouble rbc,xyb,yza,temp;
8278   gdouble xpa,ypa,zqa;
8279   gdouble xd,yd,zd;
8280   gboolean flag;
8281   gint i, na, nb, nc;
8282 
8283   if (Natoms == 0)
8284     return( FALSE );
8285   /* Atom #1 */
8286   geometry[0].X = 0.0;
8287   geometry[0].Y = 0.0;
8288   geometry[0].Z = 0.0;
8289   geometry[0].N = 1;
8290   geometry[0].typeConnections = NULL;
8291 
8292   if (Natoms == 1)
8293   {
8294     geometry[0].Prop = prop_atom_get(Geom[0].Symb);
8295     geometry[0].mmType   = g_strdup(Geom[0].mmType);
8296     geometry[0].pdbType   = g_strdup(Geom[0].pdbType);
8297     geometry[0].Residue   = g_strdup(Geom[0].Residue);
8298     geometry[0].ResidueNumber   = Geom[0].ResidueNumber;
8299     geometry[0].show   = TRUE;
8300     geometry[0].Charge = atof(Geom[0].Charge);
8301     set_layer(Geom[0].Layer, &geometry[0].Layer);
8302     set_constant_variable(0, FALSE);
8303     return( TRUE );
8304   }
8305 
8306   /* Atom #2 */
8307   if(!test(Geom[1].R))
8308     geometry[1].X = get_value_variableZmat(Geom[1].R);
8309   else
8310     geometry[1].X = atof(Geom[1].R);
8311   geometry[1].Y = 0.0;
8312   geometry[1].Z = 0.0;
8313   geometry[1].N = 2;
8314   geometry[1].typeConnections = NULL;
8315 
8316   if( Natoms == 2 )
8317   {
8318     geometry[0].Prop = prop_atom_get(Geom[0].Symb);
8319     geometry[1].Prop = prop_atom_get(Geom[1].Symb);
8320     geometry[0].mmType = g_strdup(Geom[0].mmType);
8321     geometry[1].mmType = g_strdup(Geom[1].mmType);
8322     geometry[0].pdbType = g_strdup(Geom[0].pdbType);
8323     geometry[1].pdbType = g_strdup(Geom[1].pdbType);
8324     geometry[0].Residue = g_strdup(Geom[0].Residue);
8325     geometry[1].Residue = g_strdup(Geom[1].Residue);
8326     geometry[0].ResidueNumber   = Geom[0].ResidueNumber;
8327     geometry[1].ResidueNumber   = Geom[1].ResidueNumber;
8328     geometry[0].show   = TRUE;
8329     geometry[1].show   = TRUE;
8330     geometry[0].Charge = atof(Geom[0].Charge);
8331     geometry[1].Charge = atof(Geom[1].Charge);
8332     set_layer(Geom[0].Layer, &geometry[0].Layer);
8333     set_layer(Geom[1].Layer, &geometry[1].Layer);
8334     set_constant_variable(0, FALSE);
8335     set_constant_variable(1, FALSE);
8336     return( TRUE );
8337   }
8338 
8339   /* Atom #3 */
8340   if(!test(Geom[2].R))
8341     dist = get_value_variableZmat(Geom[2].R);
8342   else
8343     dist = atof(Geom[2].R);
8344 
8345   if(!test(Geom[2].Angle))
8346     angle = get_value_variableZmat(Geom[2].Angle);
8347   else
8348     angle = atof(Geom[2].Angle);
8349 
8350     angle *=  DEG_TO_RAD;
8351 
8352   cosa = cos(angle);
8353   sina = sin(angle);
8354 
8355   if( atoi (Geom[2].NAngle) == 2 )
8356   	geometry[2].X =  geometry[0].X + cosa*dist;
8357   else
8358   	geometry[2].X =  geometry[1].X - cosa*dist;
8359 
8360   geometry[2].Y =  sina*dist;
8361   geometry[2].Z = 0.0;
8362   geometry[2].N = 3;
8363   geometry[2].typeConnections = NULL;
8364 
8365   for (i = 3; i <(gint)Natoms; i++)
8366   {
8367   if(!test(Geom[i].R))
8368     dist = get_value_variableZmat(Geom[i].R);
8369   else
8370     dist = atof(Geom[i].R);
8371 
8372   if(!test(Geom[i].Angle))
8373     angle = get_value_variableZmat(Geom[i].Angle);
8374   else
8375     angle = atof(Geom[i].Angle) ;
8376 
8377   if(!test(Geom[i].Dihedral))
8378     dihed = get_value_variableZmat(Geom[i].Dihedral);
8379   else
8380     dihed = atof(Geom[i].Dihedral) ;
8381 
8382     angle *= DEG_TO_RAD;
8383     dihed *= DEG_TO_RAD;
8384 
8385     na = atoi(Geom[i].NR)-1;
8386     nb = atoi(Geom[i].NAngle)-1;
8387     nc = atoi(Geom[i].NDihedral)-1;
8388 
8389     xb = geometry[nb].X - geometry[na].X;
8390     yb = geometry[nb].Y - geometry[na].Y;
8391     zb = geometry[nb].Z - geometry[na].Z;
8392 
8393     rbc = xb*xb + yb*yb + zb*zb;
8394     if( rbc < 0.0001 )
8395       return( FALSE );
8396     rbc = 1.0/sqrt(rbc);
8397 
8398     cosa = cos(angle);
8399     sina = sin(angle);
8400 
8401 
8402     if( fabs(cosa) >= 0.999999 )
8403     {
8404       /* Colinear */
8405       temp = dist*rbc*cosa;
8406       geometry[i].X  = geometry[na].X + temp*xb;
8407       geometry[i].Y  = geometry[na].Y + temp*yb;
8408       geometry[i].Z  = geometry[na].Z + temp*zb;
8409       geometry[i].N = i+1;
8410       geometry[i].typeConnections = NULL;
8411     }
8412     else
8413     {
8414       xa = geometry[nc].X - geometry[na].X;
8415       ya = geometry[nc].Y - geometry[na].Y;
8416       za = geometry[nc].Z - geometry[na].Z;
8417 
8418       sind = -sin(dihed);
8419       cosd = cos(dihed);
8420 
8421       xd = dist*cosa;
8422       yd = dist*sina*cosd;
8423       zd = dist*sina*sind;
8424 
8425       xyb = sqrt(xb*xb + yb*yb);
8426       if( xyb < 0.1 )
8427       {
8428 	/* Rotate about y-axis! */
8429 	temp = za; za = -xa; xa = temp;
8430 	temp = zb; zb = -xb; xb = temp;
8431 	xyb = sqrt(xb*xb + yb*yb);
8432 	flag = TRUE;
8433       }
8434       else
8435 	flag = FALSE;
8436 
8437       costh = xb/xyb;
8438       sinth = yb/xyb;
8439       xpa = costh*xa + sinth*ya;
8440       ypa = costh*ya - sinth*xa;
8441 
8442       sinph = zb*rbc;
8443       cosph = sqrt(1.0 - sinph*sinph);
8444       zqa = cosph*za  - sinph*xpa;
8445 
8446       yza = sqrt(ypa*ypa + zqa*zqa);
8447 
8448       if( yza > 1.0E-10 )
8449       {
8450 	coskh = ypa/yza;
8451 	sinkh = zqa/yza;
8452 
8453 	ypd = coskh*yd - sinkh*zd;
8454 	zpd = coskh*zd + sinkh*yd;
8455       }
8456       else
8457       {
8458 	/* coskh = 1.0; */
8459 	/* sinkh = 0.0; */
8460 	ypd = yd;
8461 	zpd = zd;
8462       }
8463 
8464       xpd = cosph*xd  - sinph*zpd;
8465       zqd = cosph*zpd + sinph*xd;
8466       xqd = costh*xpd - sinth*ypd;
8467       yqd = costh*ypd + sinth*xpd;
8468 
8469       if( flag )
8470       {
8471 	/* Rotate about y-axis! */
8472 	geometry[i].X = geometry[na].X - zqd;
8473 	geometry[i].Y = geometry[na].Y + yqd;
8474 	geometry[i].Z = geometry[na].Z + xqd;
8475         geometry[i].N = i+1;
8476         geometry[i].typeConnections = NULL;
8477       }
8478       else
8479       {
8480 	geometry[i].X = geometry[na].X + xqd;
8481 	geometry[i].Y = geometry[na].Y + yqd;
8482 	geometry[i].Z = geometry[na].Z + zqd;
8483         geometry[i].N = i+1;
8484         geometry[i].typeConnections = NULL;
8485       }
8486     }
8487   }
8488   for(i=0;i<(gint)Natoms;i++)
8489   {
8490 	geometry[i].Prop = prop_atom_get(Geom[i].Symb);
8491     	geometry[i].mmType = g_strdup(Geom[i].mmType);
8492     	geometry[i].pdbType = g_strdup(Geom[i].pdbType);
8493     	geometry[i].Residue = g_strdup(Geom[i].Residue);
8494     	geometry[i].ResidueNumber = Geom[i].ResidueNumber;
8495     	geometry[i].Charge = atof(Geom[i].Charge);
8496     	geometry[i].show   = TRUE;
8497     	set_layer(Geom[i].Layer, &geometry[i].Layer);
8498     	set_constant_variable(i, FALSE);
8499   }
8500   return( TRUE );
8501 }
8502 /********************************************************************************/
set_optimal_geom_view()8503 void set_optimal_geom_view()
8504 {
8505 	gint i,j;
8506 	gdouble min = 0;
8507 	gdouble max = 0;
8508   	gboolean perspective = FALSE;
8509   	gdouble zn, zf, zo;
8510   	gdouble aspect;
8511 	gdouble C[3];
8512 	gdouble X0[3];
8513 
8514 	if(!geometry || Natoms<1 ) return;
8515 
8516         for(i=0;i<3;i++) X0[i] = 0.0;
8517 	min = geometry[0].X;
8518 	max = geometry[0].Y;
8519 	for(i=0;i<Natoms;i++)
8520 	{
8521 		C[0] = geometry[i].X;
8522 		C[1] = geometry[i].Y;
8523 		C[2] = geometry[i].Z;
8524 		for(j=0;j<3;j++)
8525 		{
8526 			if(min>C[j]) min = C[j];
8527 			if(max<C[j]) max = C[j];
8528 		}
8529 		X0[0] +=geometry[i].X;
8530 		X0[1] +=geometry[i].Y;
8531 		X0[2] +=geometry[i].Z;
8532 	}
8533         for(i=0;i<3;i++) X0[i] /= Natoms;
8534 	get_camera_values(&zn, &zf, &zo, &aspect, &perspective);
8535 	zn = 1;
8536 	zf = fabs(max-min)*5;
8537 	if(Natoms<2) zf = 100;
8538 	if(PersMode) zo = 1.0;
8539 	else
8540 	{
8541 		gdouble d = fabs(max-min);
8542 		if(d>1e-10) zo = 20/d;
8543 		else zo = 1.0;
8544 	}
8545 	zo = 1/zo*45;
8546 	set_camera_values(zn,zf,zo,perspective);
8547 	Trans[0]=0;
8548 	Trans[1]=0;
8549 
8550         for(i=0;i<Natoms;i++)
8551 	{
8552 		geometry[i].X -= X0[0];
8553 		geometry[i].Y -= X0[1];
8554 		geometry[i].Z -= X0[2];
8555 
8556 		geometry0[i].X -= X0[0];
8557 		geometry0[i].Y -= X0[1];
8558 		geometry0[i].Z -= X0[2];
8559 	}
8560 	RebuildGeom = TRUE;
8561 
8562 // TO DO
8563         //for(i=0;i<3;i++) Orig[i] -= X0[i];
8564         for(i=0;i<3;i++) Orig[i] += X0[i];
8565 	drawGeom();
8566 }
8567 /********************************************************************************/
define_good_factor()8568 void define_good_factor()
8569 {
8570 	set_optimal_geom_view();
8571 }
8572 /********************************************************************************/
set_color_shad(GdkColor * color,guint i)8573 void set_color_shad(GdkColor *color,guint i)
8574 {
8575 }
8576 /*****************************************************************************/
rotationGen(gdouble alpha,gdouble Axe[],gdouble A[],gdouble B[])8577 void rotationGen(gdouble alpha,gdouble Axe[],gdouble A[],gdouble B[])
8578 {
8579 /* Axe est un tableau de 2 elements qui definit l'axe de rotation qui se trouve dans le paln xOy*/
8580 /* theta angle entre l'axe de rotation et l'axe x. l'axe de rotation se trouve dans le plan xoy */
8581 /* alpha angle rotation autour de l'axe de rotation defini par theta */
8582 	gdouble cosa = cos(alpha/180*PI);
8583 	gdouble sina = sin(alpha/180*PI);
8584         gdouble cost=Axe[0]/sqrt(Axe[0]*Axe[0] + Axe[1]*Axe[1] );
8585         gdouble sint=Axe[1]/sqrt(Axe[0]*Axe[0] + Axe[1]*Axe[1] );
8586 
8587 	B[0] = A[0]*cost*cost + A[1]*sint*cost + A[0]*sint*sint*cosa - A[1]*cost*cosa*sint+A[2]*sint*sina;
8588 	B[1] = A[0]*cost*sint + A[1]*sint*sint - A[0]*sint*cost*cosa + A[1]*cost*cosa*cost-A[2]*cost*sina;
8589 	B[2] = -A[0]*sint*sina + A[1]*cost*sina + A[2]*cosa;
8590 }
8591 /*****************************************************************************/
replace_atom(gint i)8592 static gint replace_atom(gint i)
8593 {
8594 	g_free(geometry[i].Prop.symbol);
8595 	geometry[i].Prop = prop_atom_get(AtomToInsert);
8596 	g_free(geometry0[i].Prop.symbol);
8597 	geometry0[i].Prop = prop_atom_get(AtomToInsert);
8598 
8599 	g_free(geometry[i].mmType);
8600 	geometry[i].mmType = g_strdup(AtomToInsert);
8601 	g_free(geometry0[i].mmType);
8602 	geometry0[i].mmType = g_strdup(AtomToInsert);
8603 
8604 	g_free(geometry[i].pdbType);
8605 	geometry[i].pdbType = g_strdup(AtomToInsert);
8606 	g_free(geometry0[i].pdbType);
8607 	geometry0[i].pdbType = g_strdup(AtomToInsert);
8608 	return 1;
8609 }
8610 /*****************************************************************************/
insert_atom(GdkEventButton * bevent)8611 static gint insert_atom(GdkEventButton *bevent)
8612 {
8613 	int x, y;
8614 	gdouble X;
8615 	gdouble Y;
8616 	gdouble Z;
8617 	gdouble w[3];
8618 
8619 	if(Natoms>0 && NumProcheAtom<0) return -1;
8620 	if(Natoms>0)
8621 	{
8622 		geometry0 = g_realloc(geometry0,(Natoms+1)*sizeof(GeomDef));
8623 		geometry = g_realloc(geometry,(Natoms+1)*sizeof(GeomDef));
8624 	}
8625 	else
8626 	{
8627 		geometry0 = g_malloc(sizeof(GeomDef));
8628 		geometry = g_malloc(sizeof(GeomDef));
8629 	}
8630 
8631 	Ddef = FALSE;
8632 
8633 	x = bevent->x;
8634 	y = bevent->y;
8635 	glGetWorldCoordinates(x,y,w);
8636 	X = w[0];
8637 	Y = w[1];
8638 	Z = w[2];
8639 
8640 	if(Natoms==0) geometry[Natoms].Prop = prop_atom_get(AtomToInsert);
8641 
8642 /*
8643 	if(Natoms>0 && NumProcheAtom>-1) Z = geometry[NumProcheAtom].Z;
8644 	else Z = 0.0;
8645 */
8646 	//if(Natoms==0) Z = 0;
8647 
8648 	geometry[Natoms].X=X;
8649 	geometry[Natoms].Y=Y;
8650 	geometry[Natoms].Z=Z;
8651 	geometry[Natoms].Prop = prop_atom_get(AtomToInsert);
8652 	geometry[Natoms].mmType = g_strdup(AtomToInsert);
8653 	geometry[Natoms].pdbType = g_strdup(AtomToInsert);
8654 	geometry[Natoms].Layer = HIGH_LAYER;
8655 	geometry[Natoms].show = TRUE;
8656 	geometry[Natoms].N = Natoms+1;
8657        	geometry[Natoms].typeConnections = NULL;
8658 	if(Natoms==0)
8659 	{
8660 		geometry[Natoms].Residue = g_strdup(AtomToInsert);
8661 		geometry[Natoms].ResidueNumber = 0;
8662 	}
8663 	else
8664 	{
8665 		gint k;
8666 		gint proche = 0;
8667 		gdouble d;
8668 		gdouble d1;
8669 		d = get_real_distance2(geometry,0,Natoms);
8670 		for(k=1;k<(gint)Natoms;k++)
8671 		{
8672 
8673 			d1 = get_real_distance2(geometry,k,Natoms);
8674 			if(d1<d)
8675 			{
8676 				proche = k;
8677 				d = d1;
8678 			}
8679 		}
8680 		geometry[Natoms].Residue = g_strdup(geometry[proche].Residue);
8681 		geometry[Natoms].ResidueNumber = geometry[proche].ResidueNumber;
8682 	}
8683 
8684 	geometry[Natoms].Charge = 0.0;
8685 
8686 	geometry0[Natoms].Prop = prop_atom_get(AtomToInsert);
8687 	geometry0[Natoms].mmType = g_strdup(AtomToInsert);
8688 	geometry0[Natoms].pdbType = g_strdup(AtomToInsert);
8689 	geometry0[Natoms].Layer = HIGH_LAYER;
8690 	geometry0[Natoms].Variable = TRUE;
8691 	geometry0[Natoms].Residue = g_strdup(geometry[Natoms].Residue);
8692 	geometry0[Natoms].ResidueNumber = geometry[Natoms].ResidueNumber;
8693 	geometry0[Natoms].show = geometry[Natoms].show;
8694 	geometry0[Natoms].X = geometry[Natoms].X;
8695 	geometry0[Natoms].Y = geometry[Natoms].Y;
8696 	geometry0[Natoms].Z = geometry[Natoms].Z;
8697 	geometry0[Natoms].Charge = 0.0;
8698 	geometry0[Natoms].N = Natoms+1;
8699        	geometry0[Natoms].typeConnections = NULL;
8700 
8701 	Natoms++;
8702 
8703 	Ddef = FALSE;
8704 	{
8705 		gint i;
8706 		gint j;
8707 		for(i=0;i<(gint)Natoms-1;i++)
8708 		{
8709 			geometry[i].typeConnections = g_realloc(geometry[i].typeConnections,Natoms*sizeof(gint));
8710 			geometry[i].typeConnections[Natoms-1] = 0;
8711 			geometry0[i].typeConnections = g_realloc(geometry0[i].typeConnections,Natoms*sizeof(gint));
8712 		}
8713 		i = Natoms-1;
8714 		geometry[i].typeConnections = g_malloc(Natoms*sizeof(gint));
8715 		for(j=0;j<(gint)Natoms;j++) geometry[i].typeConnections[j] = 0;
8716 		geometry0[i].typeConnections = g_malloc(Natoms*sizeof(gint));
8717 		for(j=0;j<(gint)Natoms;j++) geometry0[i].typeConnections[j] = 0;
8718 	}
8719 	reset_charges_multiplicities();
8720 	return TRUE;
8721 }
8722 /*****************************************************************************/
select_fragment(gint NDelAtom)8723 static void select_fragment(gint NDelAtom)
8724 {
8725 	gint i;
8726 
8727 	if(!NumFatoms)
8728 		g_free(NumFatoms);
8729 	NumFatoms = NULL;
8730 
8731 	NFatoms = Frag.NAtoms-NDelAtom;
8732 	if(NFatoms<1)
8733 		return;
8734 	NumFatoms = g_malloc(NFatoms*sizeof(gint));
8735 	for(i=0;i<(gint)NFatoms;i++)
8736 	{
8737 			NumFatoms[i] = geometry[i+Natoms-NFatoms].N;
8738 	}
8739 }
8740 /*****************************************************************************/
get_number_new_residue()8741 static gint get_number_new_residue()
8742 {
8743 	gint numMax =-1;
8744 	gint i;
8745 	if(Natoms<1 || !geometry0)
8746 		return numMax + 1;
8747 	for(i=0;i<(gint)Natoms;i++)
8748 		if(numMax<geometry0[i].ResidueNumber)
8749 			numMax = geometry0[i].ResidueNumber;
8750 	return numMax +1;
8751 }
8752 /*****************************************************************************/
insert_fragment_without_delete_an_atom(GtkWidget * widget,GdkEvent * event)8753 static gint insert_fragment_without_delete_an_atom(GtkWidget *widget,GdkEvent *event)
8754 {
8755 	int x, y;
8756 	GdkEventButton *bevent=(GdkEventButton *)event;
8757 	gdouble X;
8758 	gdouble Y;
8759 	gdouble Z;
8760 	gint i;
8761 	gint iBegin;
8762 	gint j;
8763 	gdouble w[3]={0,0,0};
8764 
8765 	if(Natoms>0 && NumProcheAtom<0)
8766 	{
8767 		FreeFragment(&Frag);
8768 		return 0;
8769 	}
8770 	if(Frag.NAtoms<=0)
8771 	{
8772 		FreeFragment(&Frag);
8773 		return 0;
8774 	}
8775 
8776 	if(Natoms>0)
8777 	{
8778 		geometry0 = g_realloc(geometry0,(Natoms+Frag.NAtoms)*sizeof(GeomDef));
8779 		geometry  = g_realloc(geometry,(Natoms+Frag.NAtoms)*sizeof(GeomDef));
8780 	}
8781 	else
8782 	{
8783 		geometry0 = g_malloc(Frag.NAtoms*sizeof(GeomDef));
8784 		geometry  = g_malloc(Frag.NAtoms*sizeof(GeomDef));
8785 	}
8786 
8787 	Ddef = FALSE;
8788 
8789 	x = bevent->x;
8790 	y = bevent->y;
8791 	if(Natoms>0) glGetWorldCoordinates(x,y,w);
8792 	X = w[0];
8793 	Y = w[1];
8794 	Z = w[2];
8795 
8796 	{
8797 		gint i,j;
8798 
8799 		gdouble B[3];
8800 
8801 		{
8802 			B[0] = X;
8803 			B[1] = Y;
8804 			B[2] = Z;
8805 			j = -1;
8806 
8807 			for(i=0;i<Frag.NAtoms;i++)
8808 			{
8809 				j++;
8810 				geometry0[Natoms+j].X=B[0]+Frag.Atoms[i].Coord[0];
8811 				geometry0[Natoms+j].Y=B[1]+Frag.Atoms[i].Coord[1];
8812 				geometry0[Natoms+j].Z=B[2]+Frag.Atoms[i].Coord[2];
8813 				geometry0[Natoms+j].Prop = prop_atom_get(Frag.Atoms[i].Symb);
8814 				geometry0[Natoms+j].mmType =g_strdup(Frag.Atoms[i].mmType);
8815 				geometry0[Natoms+j].pdbType =g_strdup(Frag.Atoms[i].pdbType);
8816 				geometry0[Natoms+j].Layer = HIGH_LAYER;
8817 				geometry0[Natoms+j].Variable = TRUE;
8818 				geometry0[Natoms+j].Residue =g_strdup(Frag.Atoms[i].Residue);
8819 				geometry0[Natoms+j].ResidueNumber= get_number_new_residue();
8820 				geometry0[Natoms+j].show= TRUE;
8821 				geometry0[Natoms+j].Charge = Frag.Atoms[i].Charge;
8822 				geometry0[Natoms+j].N = Natoms+j+1;
8823         			geometry0[Natoms+j].typeConnections = NULL;
8824 
8825 				geometry[Natoms+j].Prop = prop_atom_get(Frag.Atoms[i].Symb);
8826 				geometry[Natoms+j].mmType =g_strdup(Frag.Atoms[i].mmType);
8827 				geometry[Natoms+j].pdbType =g_strdup(Frag.Atoms[i].pdbType);
8828 				geometry[Natoms+j].Layer = HIGH_LAYER;
8829 				geometry[Natoms+j].Residue =g_strdup(Frag.Atoms[i].Residue);
8830 				geometry[Natoms+j].ResidueNumber=geometry0[Natoms+j].ResidueNumber;
8831 				geometry[Natoms+j].show=geometry0[Natoms+j].show;
8832 				geometry[Natoms+j].Charge = Frag.Atoms[i].Charge;
8833 				geometry[Natoms+j].N = Natoms+j+1;
8834         			geometry[Natoms+j].typeConnections = NULL;
8835 
8836 				geometry[Natoms+j].X= geometry0[Natoms+j].X;
8837 				geometry[Natoms+j].Y= geometry0[Natoms+j].Y;
8838 				geometry[Natoms+j].Z= geometry0[Natoms+j].Z;
8839 			}
8840 			Natoms+=Frag.NAtoms;
8841 		}
8842 	}
8843 	Ddef = FALSE;
8844 	iBegin = Natoms-Frag.NAtoms;
8845 	for(i=0;i<iBegin;i++)
8846 	{
8847 		if(!geometry[i].typeConnections) continue;
8848 		geometry[i].typeConnections = g_realloc(geometry[i].typeConnections,Natoms*sizeof(gint));
8849 		for(j=iBegin;j<Natoms;j++) geometry[i].typeConnections[j] = 0;
8850 
8851 		if(!geometry0[i].typeConnections) continue;
8852 		geometry0[i].typeConnections = g_realloc(geometry0[i].typeConnections,Natoms*sizeof(gint));
8853 		for(j=iBegin;j<Natoms;j++) geometry0[i].typeConnections[j] = 0;
8854 	}
8855 	for(i=iBegin;i<Natoms;i++)
8856 	{
8857 		geometry[i].typeConnections = g_malloc(Natoms*sizeof(gint));
8858 		for(j=0;j<Natoms;j++) geometry[i].typeConnections[j] = 0;
8859 
8860 		geometry0[i].typeConnections = g_malloc(Natoms*sizeof(gint));
8861 		for(j=0;j<Natoms;j++) geometry0[i].typeConnections[j] = 0;
8862 	}
8863 	for(i=iBegin;i<Natoms;i++)
8864 	{
8865 		for(j=i+1;j<Natoms;j++)
8866 		{
8867 			if(draw_lines_yes_no(i,j)) geometry[i].typeConnections[j]= 1;
8868 			geometry[j].typeConnections[i] = geometry[i].typeConnections[j];
8869 		}
8870 	}
8871 	reset_multiple_bonds();
8872 	if(iBegin==0) set_optimal_geom_view();
8873 	reset_charges_multiplicities();
8874 	/* SetOriginAtCenter(NULL,0,NULL);*/
8875 	set_statubar_pop_sel_atom();
8876 	return 1;
8877 }
8878 /********************************************************************************/
insert_fragment_connected_to_an_atom(gint toD,gint toB,gint toA)8879 static gint insert_fragment_connected_to_an_atom(gint toD, gint toB, gint toA)
8880 {
8881 	gint i;
8882 	gint toBond=-1;
8883 	gint toAngle=-1;
8884 	gint* atomlist = NULL;
8885 	gint toDel = -1;
8886 	gdouble B[3];
8887 	gint j;
8888 	gint iBegin;
8889 	gdouble  bondLength;
8890 
8891 	if(toD <0 || toB <0 || Frag.atomToDelete<0 || Frag.atomToBondTo<0) return 0;
8892 	if(toD >= Natoms || toB>= Natoms || Frag.atomToDelete>= Frag.NAtoms || Frag.atomToBondTo>= Frag.NAtoms) return 0;
8893 
8894 	if(Natoms>0)
8895 	{
8896 		geometry0 = g_realloc(geometry0,(Natoms+Frag.NAtoms)*sizeof(GeomDef));
8897 		geometry  = g_realloc(geometry,(Natoms+Frag.NAtoms)*sizeof(GeomDef));
8898 	}
8899 	else
8900 	{
8901 		geometry0 = g_malloc(Frag.NAtoms*sizeof(GeomDef));
8902 		geometry  = g_malloc(Frag.NAtoms*sizeof(GeomDef));
8903 	}
8904 
8905 	Ddef = FALSE;
8906 
8907 	atomlist = g_malloc((Frag.NAtoms)*sizeof(gint));
8908 	B[0] = geometry[toB].X - Frag.Atoms[Frag.atomToDelete].Coord[0];
8909 	B[1] = geometry[toB].Y - Frag.Atoms[Frag.atomToDelete].Coord[1];
8910 	B[2] = geometry[toB].Z - Frag.Atoms[Frag.atomToDelete].Coord[2];
8911 
8912 	j = -1;
8913 	toBond = -1;
8914 	toAngle = -1;
8915 	toDel = -1;
8916 	for(i=0;i<Frag.NAtoms;i++)
8917 	{
8918 		j++;
8919 		geometry0[Natoms+j].X=B[0]+Frag.Atoms[i].Coord[0];
8920 		geometry0[Natoms+j].Y=B[1]+Frag.Atoms[i].Coord[1];
8921 		geometry0[Natoms+j].Z=B[2]+Frag.Atoms[i].Coord[2];
8922 
8923 		if(i==Frag.atomToDelete) toDel = Natoms+j;
8924 		if(i==Frag.atomToBondTo) toBond = Natoms+j;
8925 		if(i==Frag.angleAtom) toAngle = Natoms+j;
8926 		atomlist[j] = Natoms+j;
8927 
8928 		geometry0[Natoms+j].Prop = prop_atom_get(Frag.Atoms[i].Symb);
8929 		geometry0[Natoms+j].mmType =g_strdup(Frag.Atoms[i].mmType);
8930 		geometry0[Natoms+j].pdbType =g_strdup(Frag.Atoms[i].pdbType);
8931 		geometry0[Natoms+j].Layer = HIGH_LAYER;
8932 		geometry0[Natoms+j].Variable = TRUE;
8933 		geometry0[Natoms+j].Residue =g_strdup(Frag.Atoms[i].Residue);
8934 		geometry0[Natoms+j].ResidueNumber= get_number_new_residue();
8935 		geometry0[Natoms+j].show= TRUE;
8936 		geometry0[Natoms+j].Charge = Frag.Atoms[i].Charge;
8937 		geometry0[Natoms+j].N = Natoms+j+1;
8938         	geometry0[Natoms+j].typeConnections = NULL;
8939 
8940 		geometry[Natoms+j].Prop = prop_atom_get(Frag.Atoms[i].Symb);
8941 		geometry[Natoms+j].mmType =g_strdup(Frag.Atoms[i].mmType);
8942 		geometry[Natoms+j].pdbType =g_strdup(Frag.Atoms[i].pdbType);
8943 		geometry[Natoms+j].Layer = HIGH_LAYER;
8944 		geometry[Natoms+j].Residue =g_strdup(Frag.Atoms[i].Residue);
8945 		geometry[Natoms+j].ResidueNumber=geometry0[Natoms+j].ResidueNumber;
8946 		geometry[Natoms+j].show=geometry0[Natoms+j].show;
8947 		geometry[Natoms+j].Charge = Frag.Atoms[i].Charge;
8948 		geometry[Natoms+j].N = Natoms+j+1;
8949         	geometry[Natoms+j].typeConnections = NULL;
8950 
8951 		geometry[Natoms+j].X= geometry0[Natoms+j].X;
8952 		geometry[Natoms+j].Y= geometry0[Natoms+j].Y;
8953 		geometry[Natoms+j].Z= geometry0[Natoms+j].Z;
8954 	}
8955 
8956 	Natoms +=Frag.NAtoms;
8957 
8958 	/* Set Distance toB-toD to radius toB + radius Frag.atomToBondTo */
8959 	bondLength = geometry[toB].Prop.covalentRadii + geometry[toBond].Prop.covalentRadii;
8960 	bondLength /= (ANG_TO_BOHR);
8961 	bondLength *= 0.85;
8962 	SetBondDistance(geometry,toB, toBond, bondLength,atomlist, Frag.NAtoms);
8963 
8964 	SetAngle(Natoms,geometry,toD, toB, toBond,0.0,atomlist, Frag.NAtoms);
8965 
8966 	if(toA>-1 && toAngle>-1)
8967 	{
8968 		SetTorsion(Natoms,geometry, toA,toB, toBond, toAngle, fragAngle,atomlist, Frag.NAtoms);
8969 	}
8970 
8971 	if(!atomlist) g_free(atomlist);
8972 
8973 	iBegin = Natoms-Frag.NAtoms;
8974 	for(i=0;i<iBegin;i++)
8975 	{
8976 		if(!geometry[i].typeConnections) continue;
8977 		geometry[i].typeConnections = g_realloc(geometry[i].typeConnections,Natoms*sizeof(gint));
8978 		for(j=iBegin;j<Natoms;j++) geometry[i].typeConnections[j] = 0;
8979 
8980 		if(!geometry0[i].typeConnections) continue;
8981 		geometry0[i].typeConnections = g_realloc(geometry0[i].typeConnections,Natoms*sizeof(gint));
8982 		for(j=iBegin;j<Natoms;j++) geometry0[i].typeConnections[j] = 0;
8983 	}
8984 	for(i=iBegin;i<Natoms;i++)
8985 	{
8986 		geometry[i].typeConnections = g_malloc(Natoms*sizeof(gint));
8987 		for(j=0;j<Natoms;j++) geometry[i].typeConnections[j] = 0;
8988 
8989 		geometry0[i].typeConnections = g_malloc(Natoms*sizeof(gint));
8990 		for(j=0;j<Natoms;j++) geometry0[i].typeConnections[j] = 0;
8991 	}
8992 	for(i=iBegin;i<Natoms;i++)
8993 	{
8994 		for(j=i+1;j<Natoms;j++)
8995 		{
8996 			if(draw_lines_yes_no(i,j)) geometry[i].typeConnections[j]= 1;
8997 			geometry[j].typeConnections[i] = geometry[i].typeConnections[j];
8998 		}
8999 	}
9000 	geometry[toB].typeConnections[toBond] =1;
9001 	geometry[toBond].typeConnections[geometry[toB].N-1]=1;
9002 
9003 	if(!NumFatoms) g_free(NumFatoms);
9004 	NumFatoms = NULL;
9005 
9006 	NFatoms = 2;
9007 	NumFatoms = g_malloc(2*sizeof(gint));
9008 	NumFatoms[0] = geometry[toD].N;
9009 	NumFatoms[1] = geometry[toDel].N;
9010 	delete_all_selected_atoms();
9011 	copyCoordinates2to1(geometry0, geometry);
9012 	copy_connections(geometry0, geometry, Natoms);
9013 	select_fragment(2);
9014 
9015 	Ddef = FALSE;
9016 	reset_multiple_bonds();
9017 	reset_charges_multiplicities();
9018 
9019 	/* SetOriginAtCenter(NULL,0,NULL);*/
9020 	set_statubar_pop_sel_atom();
9021 	return 1;
9022 }
9023 /*****************************************************************************/
insert_fragment(GtkWidget * widget,GdkEvent * event)9024 static gint insert_fragment(GtkWidget *widget,GdkEvent *event)
9025 {
9026 	if(Natoms>0 && NumProcheAtom<0)
9027 	{
9028 		FreeFragment(&Frag);
9029 		return 0;
9030 	}
9031 	if(Frag.NAtoms<=0)
9032 	{
9033 		FreeFragment(&Frag);
9034 		return 0;
9035 	}
9036 	if(isItACrystalFragment(&Frag)) delete_molecule();
9037 	if(atomToDelete>=0)
9038 	{
9039 		return insert_fragment_connected_to_an_atom(
9040 				get_indice(atomToDelete),
9041 				get_indice(atomToBondTo),get_indice(angleTo));
9042 	}
9043 	else if(Frag.NAtoms>0 && Frag.atomToDelete<0)
9044 		return insert_fragment_without_delete_an_atom(widget,event);
9045 	else if(Natoms==0)
9046 		return insert_fragment_without_delete_an_atom(widget,event);
9047 	return 0;
9048 }
9049 /*****************************************************************************/
delete_one_atom(gint NumDel)9050 void delete_one_atom(gint NumDel)
9051 {
9052 
9053 	gint i;
9054 	gint j;
9055 	gint* oldN = NULL;
9056 
9057 	if(Natoms<1) return;
9058 	copy_connections(geometry0, geometry, Natoms);
9059 	i = NumDel;
9060 	if(geometry0[i].typeConnections) g_free(geometry0[i].typeConnections);
9061 	if(geometry[i].typeConnections) g_free(geometry[i].typeConnections);
9062 
9063 
9064 	for (i=NumDel;i<(gint)Natoms-1;i++)
9065 	{
9066 		geometry0[i]=geometry0[i+1];
9067 		geometry[i]=geometry[i+1];
9068 	}
9069 	oldN = g_malloc(Natoms*sizeof(gint));
9070 	for (i=0;i<(gint)Natoms;i++) oldN[i] = geometry0[i].N-1;
9071 	Natoms--;
9072 	for(j=0;j<(gint)NFatoms;j++)
9073 	{
9074 		for (i=0;i<(gint)Natoms;i++)
9075 			if(NumFatoms[j] ==(gint) geometry[i].N) { NumFatoms[j] = i+1; break;}
9076 		if(i==Natoms)  NumFatoms[j] =-1;
9077 	}
9078 	for(j=0;j<(gint)NFatoms;j++)
9079 		if( NumFatoms[j]<0)
9080 		{
9081 			for (i=j;i<(gint)NFatoms-1;i++)
9082 				 NumFatoms[i]= NumFatoms[i+1];
9083 			NFatoms--;
9084 			j--;
9085 		}
9086 
9087 	for(j=0;j<2;j++)
9088 		for (i=0;i<(gint)Natoms;i++)
9089 			if(NumBatoms[j]==(gint) geometry[i].N) {NumBatoms[j] = i+1; break;}
9090 	for (i=0;i<(gint)Natoms;i++)
9091 	{
9092 		geometry0[i].N = i+1;
9093 		geometry[i].N = i+1;
9094 	}
9095 	/* in geometry0 : old connections , in geometry new connection */
9096 	for (i=0;i<(gint)Natoms;i++)
9097 	{
9098 		if(geometry[i].typeConnections)
9099 		{
9100 			for(j=0;j<(gint)Natoms;j++)
9101 			{
9102 				geometry[i].typeConnections[j] = geometry0[i].typeConnections[oldN[j]];
9103 			}
9104 		}
9105 	}
9106 	if(oldN) g_free(oldN);
9107 	copy_connections(geometry0, geometry, Natoms);
9108 	if(Natoms>0)
9109 	{
9110 		geometry0 = g_realloc(geometry0,Natoms*sizeof(GeomDef));
9111 		geometry = g_realloc(geometry,Natoms*sizeof(GeomDef));
9112 	}
9113 	else
9114 	{
9115 		if(geometry0) g_free(geometry0); geometry0 = NULL;
9116 		if(geometry) g_free(geometry);
9117 		geometry = NULL;
9118 		Natoms = 0;
9119 	}
9120 	Ddef = FALSE;
9121 	reset_charges_multiplicities();
9122 	RebuildGeom=TRUE;
9123 }
9124 /********************************************************************************/
deleteHydrogensConnectedTo(gint n,gint nH)9125 void deleteHydrogensConnectedTo(gint n, gint nH)
9126 {
9127 	gint i;
9128 	gint k = 0;
9129 	gint ni;
9130 
9131 	if(Natoms<1) return;
9132 
9133 	add_geometry_to_fifo();
9134 	for (i=0;i<(gint)Natoms;i++)
9135 	{
9136 		ni = geometry[i].N-1;
9137 		if(geometry[n].typeConnections[ni] &&
9138 		!strcmp(geometry[i].Prop.symbol,"H"))
9139 		{
9140 			delete_one_atom(i);
9141 			k++;
9142 			if(k>=nH) break;
9143 		}
9144 	}
9145 }
9146 /*****************************************************************************/
index_selected(gint Num)9147 gint index_selected(gint Num)
9148 {
9149 	gint j;
9150 	if(NFatoms<1 || !NumFatoms )
9151 		return -1;
9152 
9153 	for(j=0;j<(gint)NFatoms;j++)
9154 		if(NumFatoms[j] == (gint)geometry[Num].N)
9155 			return j;
9156 	return -1;
9157 }
9158 /*****************************************************************************/
if_selected(gint Num)9159 gboolean if_selected(gint Num)
9160 {
9161 	gint j;
9162 	if(NFatoms<1 || !NumFatoms )
9163 		return FALSE;
9164 
9165 	for(j=0;j<(gint)NFatoms;j++)
9166 		if(NumFatoms[j] == (gint)geometry[Num].N)
9167 			return TRUE;
9168 	return FALSE;
9169 }
9170 /*****************************************************************************/
delete_all_selected_atoms()9171 void delete_all_selected_atoms()
9172 {
9173 
9174 	gint i;
9175 	gint j;
9176 	GeomDef tmp;
9177 	gint* oldN = NULL;
9178 
9179 	if(Natoms<1) return;
9180 
9181 	copy_connections(geometry0, geometry, Natoms);
9182 
9183 	for (i=0;i<(gint)Natoms-1;i++)
9184 	{
9185 		if(!if_selected(i)) continue;
9186 
9187 		for(j=i+1;j<(gint)Natoms;j++)
9188 			if(!if_selected(j))
9189 			{
9190 				tmp = geometry0[i];
9191 				geometry0[i] = geometry0[j];
9192 				geometry0[j] = tmp ;
9193 				tmp = geometry[i];
9194 				geometry[i] = geometry[j];
9195 				geometry[j] = tmp ;
9196 				break;
9197 			}
9198 	}
9199 	oldN = g_malloc(Natoms*sizeof(gint));
9200 	for (i=0;i<(gint)Natoms;i++) oldN[i] = geometry0[i].N-1;
9201 
9202 	if(NFatoms>Natoms)
9203 	{
9204 		printf("internal error\n");
9205 		Natoms = 0;
9206 	}
9207 	else
9208 	{
9209 		for (i=(gint)Natoms-NFatoms;i<(gint)Natoms;i++)
9210 		{
9211 			if(geometry0[i].typeConnections) g_free(geometry0[i].typeConnections);
9212 			if(geometry[i].typeConnections) g_free(geometry[i].typeConnections);
9213 		}
9214 		Natoms-=NFatoms;
9215 	}
9216 	for(j=0;j<(gint)NBatoms;j++)
9217 		for (i=0;i<(gint)Natoms;i++)
9218 			if(NumBatoms[j] ==(gint) geometry[i].N) NumBatoms[j] = i+1;
9219 
9220 	for (i=0;i<(gint)Natoms;i++)
9221 	{
9222 		geometry0[i].N = i+1;
9223 		geometry[i].N = i+1;
9224 	}
9225 	/* in geometry0 : old connections , in geometry new connection */
9226 	for (i=0;i<(gint)Natoms;i++)
9227 	{
9228 		if(geometry[i].typeConnections)
9229 		{
9230 			for(j=0;j<(gint)Natoms;j++)
9231 			{
9232 				geometry[i].typeConnections[j] = geometry0[i].typeConnections[oldN[j]];
9233 			}
9234 		}
9235 	}
9236 	if(oldN) g_free(oldN);
9237 	copy_connections(geometry0, geometry, Natoms);
9238 
9239 	if(Natoms>0)
9240 	{
9241 		geometry0 = g_realloc(geometry0,Natoms*sizeof(GeomDef));
9242 		geometry = g_realloc(geometry,Natoms*sizeof(GeomDef));
9243 	}
9244 	else
9245 	{
9246 		if(geometry0)
9247 			g_free(geometry0);
9248 		geometry0 = NULL;
9249 		if(geometry)
9250 			g_free(geometry);
9251 		geometry = NULL;
9252 		Natoms = 0;
9253 	}
9254 	NFatoms = 0;
9255 	if(NumFatoms)
9256 		g_free(NumFatoms);
9257 	NumFatoms = NULL;
9258 	Ddef = FALSE;
9259 	reset_charges_multiplicities();
9260 }
9261 /********************************************************************************/
rotate_frag_for_set_its_principal_axes_to_xyz(gboolean sel)9262 static void rotate_frag_for_set_its_principal_axes_to_xyz(gboolean sel)
9263 {
9264 	gdouble **m0 = NULL;
9265 	gdouble** minv;
9266 	gint i,j;
9267 	guint n;
9268 
9269 	gdouble A[3];
9270 	gdouble B[3];
9271 	guint k;
9272 	gdouble* X;
9273 	gdouble* Y;
9274 	gdouble* Z;
9275 	gdouble axis1[3] = {1,0,0};
9276 	gdouble axis2[3] = {0,1,0};
9277 	gdouble axis3[3] = {0,0,1};
9278 	gdouble C[3] = {0,0,0};
9279 	gint nFrag = 0;
9280 
9281 	if(Natoms<1) return;
9282 	nFrag = compute_fragment_principal_axes(axis1,axis2,axis3,C,sel);
9283 	if(nFrag <2 ) return;
9284 	printf("nFrag = %d\n",nFrag);
9285 
9286 	m0 = g_malloc(3*sizeof(gdouble*));
9287 	X = g_malloc(Natoms*sizeof(gdouble));
9288 	Y = g_malloc(Natoms*sizeof(gdouble));
9289 	Z = g_malloc(Natoms*sizeof(gdouble));
9290 
9291 	for(i=0;i<3;i++) m0[i] = g_malloc(3*sizeof(gdouble));
9292 
9293 
9294 	m0[0][0] = axis1[0];
9295 	m0[0][1] = axis1[1];
9296 	m0[0][2] = axis1[2];
9297 
9298 	m0[1][0] = axis2[0];
9299 	m0[1][1] = axis2[1];
9300 	m0[1][2] = axis2[2];
9301 
9302 	m0[2][0] = axis3[0];
9303 	m0[2][1] = axis3[1];
9304 	m0[2][2] = axis3[2];
9305 
9306 	minv = Inverse(m0,3,1e-7);
9307 
9308 	for(n = 0;n<Natoms;n++)
9309 	{
9310 		if(if_selected(n)!=sel) continue;
9311 		A[0] = geometry[n].X-C[0];
9312 		A[1] = geometry[n].Y-C[1];
9313 		A[2] = geometry[n].Z-C[2];
9314 
9315 		for(j=0;j<3;j++)
9316 		{
9317 			B[j] = 0.0;
9318 			for(k=0;k<3;k++)
9319 				B[j] += minv[k][j]*A[k];
9320 		}
9321 
9322 		X[n] = B[0]+C[0];
9323 		Y[n] = B[1]+C[1];
9324 		Z[n] = B[2]+C[2];
9325 	}
9326 	for(n = 0;n<Natoms;n++)
9327 	{
9328 		if(if_selected(n)!=sel)
9329 		{
9330 			geometry0[n].X = geometry[n].X;
9331 			geometry0[n].Y = geometry[n].Y;
9332 			geometry0[n].Z = geometry[n].Z;
9333 		}
9334 		else
9335 		{
9336 			geometry0[n].X = X[n];
9337 			geometry0[n].Y = Y[n];
9338 			geometry0[n].Z = Z[n];
9339 
9340 			geometry[n].X = X[n];
9341 			geometry[n].Y = Y[n];
9342 			geometry[n].Z = Z[n];
9343 		}
9344 	}
9345 
9346 	if(minv!=m0)
9347 	{
9348 	for(i=0;i<3;i++) if(minv[i]) g_free(minv[i]);
9349 	if(minv) g_free(minv);
9350 	}
9351 
9352 	for(i=0;i<3;i++) if(m0[i]) g_free(m0[i]);
9353 	if(m0) g_free(m0);
9354 
9355 	if(X) g_free(X);
9356 	if(Y) g_free(Y);
9357 	if(Z) g_free(Z);
9358 }
9359 /*****************************************************************************/
alignPrincipalAxesOfSelectedAtomsToXYZ()9360 void alignPrincipalAxesOfSelectedAtomsToXYZ()
9361 {
9362 	add_geometry_to_fifo();
9363 	rotate_frag_for_set_its_principal_axes_to_xyz(TRUE);
9364 	create_GeomXYZ_from_draw_grometry();
9365 	init_quat(Quat);
9366 	RebuildGeom=TRUE;
9367 	drawGeom();
9368 	activate_edit_objects();
9369 }
9370 /*****************************************************************************/
alignSelectedAndNotSelectedAtoms()9371 void alignSelectedAndNotSelectedAtoms()
9372 {
9373 	add_geometry_to_fifo();
9374 	move_the_center_of_selected_or_not_selected_atoms_to_origin(TRUE);
9375 	move_the_center_of_selected_or_not_selected_atoms_to_origin(FALSE);
9376 	create_GeomXYZ_from_draw_grometry();
9377 	init_quat(Quat);
9378 	RebuildGeom=TRUE;
9379 	drawGeom();
9380 	activate_edit_objects();
9381 }
9382 /*****************************************************************************/
deleteSelectedAtoms()9383 void deleteSelectedAtoms()
9384 {
9385 	add_geometry_to_fifo();
9386 	delete_all_selected_atoms();
9387 	create_GeomXYZ_from_draw_grometry();
9388 	RebuildGeom=TRUE;
9389 	drawGeom();
9390 	activate_edit_objects();
9391 }
9392 /*****************************************************************************/
moveCenterOfSelectedAtomsToOrigin()9393 void moveCenterOfSelectedAtomsToOrigin()
9394 {
9395 	add_geometry_to_fifo();
9396 	move_the_center_of_selected_or_not_selected_atoms_to_origin(TRUE);
9397 	create_GeomXYZ_from_draw_grometry();
9398 	RebuildGeom=TRUE;
9399 	drawGeom();
9400 	activate_edit_objects();
9401 }
9402 /*****************************************************************************/
delete_hydrogen_atoms()9403 void delete_hydrogen_atoms()
9404 {
9405 
9406 	gint i;
9407 	gint j;
9408 	GeomDef tmp;
9409 	gint nA = 0;
9410 	gint* oldN = NULL;
9411 
9412 	add_geometry_to_fifo();
9413 
9414 	for (i=0;i<(gint)Natoms-1;i++)
9415 	{
9416 		if(strcmp(geometry[i].Prop.symbol,"H")) continue;
9417 
9418 		for(j=i+1;j<(gint)Natoms;j++)
9419 			if(strcmp(geometry[j].Prop.symbol,"H"))
9420 			{
9421 				tmp = geometry0[i];
9422 				geometry0[i] = geometry0[j];
9423 				geometry0[j] = tmp ;
9424 				tmp = geometry[i];
9425 				geometry[i] = geometry[j];
9426 				geometry[j] = tmp ;
9427 				break;
9428 			}
9429 	}
9430 	nA = 0;
9431 	for (i=0;i<(gint)Natoms;i++)
9432 		if(strcmp(geometry[i].Prop.symbol,"H")) nA++;
9433 
9434 
9435 	if(Natoms>0) oldN = g_malloc(Natoms*sizeof(gint));
9436 	for (i=0;i<(gint)Natoms;i++) oldN[i] = geometry0[i].N-1;
9437 	Natoms = nA;
9438 
9439 	for(j=0;j<(gint)NFatoms;j++)
9440 	{
9441 		for (i=0;i<(gint)Natoms;i++)
9442 			if(NumFatoms[j] ==(gint) geometry[i].N) { NumFatoms[j] = i+1; break;}
9443 		if(i==(gint)Natoms)  NumFatoms[j] =-1;
9444 	}
9445 	for(j=0;j<(gint)NFatoms;j++)
9446 		if( NumFatoms[j]<0)
9447 		{
9448 			for (i=j;i<(gint)NFatoms-1;i++)
9449 		 		NumFatoms[i]= NumFatoms[i+1];
9450 			NFatoms--;
9451 			j--;
9452 		}
9453 	for (i=0;i<(gint)Natoms;i++)
9454 	{
9455 		geometry0[i].N = i+1;
9456 		geometry[i].N = i+1;
9457 	}
9458 	/* in geometry0 : old connections , in geometry new connection */
9459 	for (i=0;i<(gint)Natoms;i++)
9460 	{
9461 		if(geometry[i].typeConnections)
9462 		{
9463 			for(j=0;j<(gint)Natoms;j++)
9464 			{
9465 				geometry[i].typeConnections[j] = geometry0[i].typeConnections[oldN[j]];
9466 			}
9467 		}
9468 	}
9469 	if(oldN) g_free(oldN);
9470 	copy_connections(geometry0, geometry, Natoms);
9471 
9472 	if(Natoms>0)
9473 	{
9474 		geometry0 = g_realloc(geometry0,Natoms*sizeof(GeomDef));
9475 		geometry = g_realloc(geometry,Natoms*sizeof(GeomDef));
9476 	}
9477 	else
9478 	{
9479 		if(geometry0) g_free(geometry0);
9480 		geometry0 = NULL;
9481 		if(geometry) g_free(geometry);
9482 		geometry = NULL;
9483 		Natoms = 0;
9484 	}
9485 	Ddef = FALSE;
9486 	/* reset_all_connections();*/
9487 	reset_charges_multiplicities();
9488 	create_GeomXYZ_from_draw_grometry();
9489 	RebuildGeom=TRUE;
9490 	drawGeom();
9491 	activate_edit_objects();
9492 }
9493 /********************************************************************************/
deleteHydrogenAtoms()9494 void deleteHydrogenAtoms()
9495 {
9496 	gchar *t =N_("Do you want to really remove all hydrogen atoms?");
9497 	if(Natoms>0) Continue_YesNo(delete_hydrogen_atoms, NULL,t);
9498 	else Message(_("No hydrogen atoms to remove\n"),_("Warning"),TRUE);
9499 }
9500 /*****************************************************************************/
delete_selected_atoms()9501 void delete_selected_atoms()
9502 {
9503 
9504 	gint i;
9505 	gint j;
9506 	gboolean DelAll = FALSE;
9507 
9508 	if(NumSelectedAtom<0)
9509 		return;
9510 
9511 	add_geometry_to_fifo();
9512 	for(i=0;i<(gint)Natoms;i++)
9513 		if((gint)i==NumSelectedAtom)
9514 		{
9515 			for(j = 0;j<(gint)NFatoms;j++)
9516 				if(NumFatoms[j] == (gint)geometry[i].N)
9517 					DelAll = TRUE;
9518 			break;
9519 		}
9520 	if(DelAll==FALSE)
9521 	{
9522 		delete_one_atom(NumSelectedAtom);
9523 		return;
9524 	}
9525 	delete_all_selected_atoms();
9526 }
9527 /*****************************************************************************/
delete_selected_bond()9528 void delete_selected_bond()
9529 {
9530 
9531 	if(NBatoms!=2) return;
9532 	if(NBatoms>Natoms)
9533 	{
9534 		printf("internal error\n");
9535 		Natoms = 0;
9536 	}
9537 	if(NumBatoms[0]>0 && NumBatoms[1]>0)
9538 	{
9539 		gint na = NumBatoms[0]-1;
9540 		gint nb = NumBatoms[1]-1;
9541 		gint ia = -1;
9542 		gint ib = -1;
9543 		gint i;
9544 		for(i=0;i<(gint)Natoms;i++)
9545 		if(geometry[i].N-1==na) { ia = i; break; }
9546 		for(i=0;i<(gint)Natoms;i++)
9547 		if(geometry[i].N-1==nb) { ib = i; break; }
9548 
9549 		if(ia>=0 && ib>=0)
9550 		{
9551 			geometry[ia].typeConnections[nb] = 0;
9552 			geometry[ib].typeConnections[na] = 0;
9553 		}
9554 		if(ia>=0 && ib>=0 &&  AdjustHydrogenAtoms)
9555 			adjust_hydrogens_connected_to_atoms(ia,ib);
9556 	}
9557 	copy_connections(geometry0, geometry, Natoms);
9558 	NBatoms = 0;
9559 	NumBatoms[0] = NumBatoms[1] = -1;
9560 }
9561 /*****************************************************************************/
change_selected_bond()9562 void change_selected_bond()
9563 {
9564 
9565 	if(NBatoms!=2) return;
9566 	if(NBatoms>Natoms)
9567 	{
9568 		printf("internal error\n");
9569 		Natoms = 0;
9570 	}
9571 	if(NumBatoms[0]>0 && NumBatoms[1]>0)
9572 	{
9573 		gint na = NumBatoms[0]-1;
9574 		gint nb = NumBatoms[1]-1;
9575 		gint newC = 1;
9576 		gint i;
9577 		gint ni=-1;
9578 		gint nj=-1;
9579 		gint nBondsA = 0;
9580 		gint nBondsB = 0;
9581 
9582 		for(i=0;i<(gint)Natoms;i++) if(geometry[i].N-1==na) { ni = i; break; }
9583 		for(i=0;i<(gint)Natoms;i++) if(geometry[i].N-1==nb) { nj = i; break; }
9584 		if(ni>=0)
9585 		newC = geometry[ni].typeConnections[nb]+1;
9586 		if(newC>3) newC = 1;
9587 		if(newC==1)
9588 		{
9589 			if(ni>=0 && nj>=0)
9590 				geometry[ni].typeConnections[nb] = geometry[nj].typeConnections[na] = newC;
9591 		}
9592 		else
9593 		{
9594 
9595 			if(ni>=0 && nj>=0)
9596 			for(i=0;i<(gint)Natoms;i++)
9597 			{
9598 				gint nk = geometry[i].N-1;
9599 				if(i==ni) continue;
9600 				if(i==nj) continue;
9601 				if(geometry[ni].typeConnections[nk]==0) continue;
9602 				if(!strcmp(geometry[i].Prop.symbol, "H") && AdjustHydrogenAtoms)continue;
9603 				nBondsA+=geometry[ni].typeConnections[nk];
9604 			}
9605 			if(ni>=0 && nj>=0)
9606 			for(i=0;i<(gint)Natoms;i++)
9607 			{
9608 				gint nk = geometry[i].N-1;
9609 				if(i==ni) continue;
9610 				if(i==nj) continue;
9611 				if(geometry[nj].typeConnections[nk]==0) continue;
9612 				if(!strcmp(geometry[i].Prop.symbol, "H") && AdjustHydrogenAtoms )continue;
9613 				nBondsB+=geometry[nj].typeConnections[nk];
9614 			}
9615 			if(    !( ni>=0 && nj>=0 &&
9616 				((gint)geometry[ni].Prop.maximumBondValence-(nBondsA+newC))>=0 &&
9617 				((gint)geometry[nj].Prop.maximumBondValence-(nBondsB+newC))>=0
9618 				)
9619 			) newC = 1;
9620 			if(ni>=0 && nj>=0)
9621 				geometry[ni].typeConnections[nb] = geometry[nj].typeConnections[na] = newC;
9622 		}
9623 		if(ni>=0 && nj>=0 &&  AdjustHydrogenAtoms)
9624 			adjust_hydrogens_connected_to_atoms(ni,nj);
9625 	}
9626 	copyCoordinates2to1(geometry0, geometry);
9627 	copy_connections(geometry0, geometry, Natoms);
9628 	NBatoms = 0;
9629 	NumBatoms[0] = NumBatoms[1] = -1;
9630 }
9631 /*****************************************************************************/
add_bond()9632 void add_bond()
9633 {
9634 	if(NBatoms==1)
9635 	{
9636 		NBatoms = 0;
9637 		NumBatoms[0] = NumBatoms[1] = -1;
9638 	}
9639 	if(NBatoms!=2) return;
9640 	if(NBatoms>Natoms)
9641 	{
9642 		printf("internal error\n");
9643 		Natoms = 0;
9644 	}
9645 	if(NumBatoms[0]>0 && NumBatoms[1]>0)
9646 	{
9647 		gint na = NumBatoms[0]-1;
9648 		gint nb = NumBatoms[1]-1;
9649 		gint newC = 1;
9650 		gint i;
9651 		gint ni=-1;
9652 		gint nj=-1;
9653 		gint nBondsA = 0;
9654 		gint nBondsB = 0;
9655 		{
9656 			for(i=0;i<(gint)Natoms;i++)
9657 			if(geometry[i].N-1==na)
9658 			{
9659 				ni = i;
9660 				break;
9661 			}
9662 			if(ni>=0)
9663 			for(i=0;i<(gint)Natoms;i++)
9664 			if(geometry[i].N-1==nb)
9665 			{
9666 				nj = i;
9667 				break;
9668 			}
9669 			if(ni>=0 && nj>=0)
9670 			for(i=0;i<(gint)Natoms;i++)
9671 			{
9672 				gint nk = geometry[i].N-1;
9673 				if(i==ni) continue;
9674 				if(i==nj) continue;
9675 				if(geometry[ni].typeConnections[nk]==0) continue;
9676 				if(!strcmp(geometry[i].Prop.symbol, "H") && AdjustHydrogenAtoms )continue;
9677 				nBondsA+=geometry[ni].typeConnections[nk];
9678 			}
9679 			if(ni>=0 && nj>=0)
9680 			for(i=0;i<(gint)Natoms;i++)
9681 			{
9682 				gint nk = geometry[i].N-1;
9683 				if(i==ni) continue;
9684 				if(i==nj) continue;
9685 				if(geometry[nj].typeConnections[nk]==0) continue;
9686 				if(!strcmp(geometry[i].Prop.symbol, "H"))continue;
9687 				nBondsB+=geometry[nj].typeConnections[nk];
9688 			}
9689 			if(    !( ni>=0 && nj>=0 &&
9690 				((gint)geometry[ni].Prop.maximumBondValence-(nBondsA+newC))>=0 &&
9691 				((gint)geometry[nj].Prop.maximumBondValence-(nBondsB+newC))>=0
9692 				)
9693 			) newC = 0;
9694 			if(ni>=0 && nj>=0)
9695 				geometry[ni].typeConnections[nb] = geometry[nj].typeConnections[na] = newC;
9696 		}
9697 		if(ni>=0 && nj>=0 &&  AdjustHydrogenAtoms)
9698 			adjust_hydrogens_connected_to_atoms(ni,nj);
9699 	}
9700 	copyCoordinates2to1(geometry0, geometry);
9701 	copy_connections(geometry0, geometry, Natoms);
9702 	NBatoms = 0;
9703 	NumBatoms[0] = NumBatoms[1] = -1;
9704 }
9705 /*****************************************************************************/
rotation_atom_quat(gint i,gdouble m[4][4])9706 void rotation_atom_quat(gint i,gdouble m[4][4])
9707 {
9708 	gdouble A[3];
9709 	gdouble B[3];
9710 	guint j,k;
9711 
9712 	A[0] = CSselectedAtom[0] ;
9713 	A[1] = CSselectedAtom[1] ;
9714 	A[2] = CSselectedAtom[2] ;
9715 	for(j=0;j<3;j++)
9716 	{
9717 		B[j] = 0.0;
9718 		for(k=0;k<3;k++)
9719 			B[j] += m[k][j]*A[k];
9720 	}
9721 	geometry0[i].X=B[0];
9722 	geometry0[i].Y=B[1];
9723 	geometry0[i].Z=B[2];
9724 }
9725 /*****************************************************************************/
rotation(double a,double b,double angle,double * ap,double * bp)9726 void rotation(double a,double b,double angle,double *ap,double *bp)
9727 {
9728 	double cosangle = cos(angle/180*PI);
9729 	double sinangle = sin(angle/180*PI);
9730 
9731 	*ap = a*cosangle - b *sinangle;
9732 	*bp = b*cosangle + a *sinangle;
9733 }
9734 /*****************************************************************************/
define_geometry()9735 void define_geometry()
9736 {
9737         guint i;
9738         guint j;
9739         gdouble X0[3];
9740 	gint nC = 0;
9741 
9742 	if(geometry != NULL)
9743 	{
9744                 for (i=0;i<Natoms;i++)
9745 			g_free(geometry[i].Prop.symbol);
9746 
9747 		g_free(geometry);
9748 		geometry = NULL;
9749 	}
9750         if(MethodeGeom == GEOM_IS_XYZ) Natoms = NcentersXYZ;
9751         else Natoms = NcentersZmat;
9752 
9753 	geometry =g_malloc(Natoms*sizeof(GeomDef));
9754 
9755         if((MethodeGeom == GEOM_IS_XYZ) && (GeomXYZ  != NULL) ) define_geometry_from_xyz();
9756         if((MethodeGeom == GEOM_IS_ZMAT) && (Geom  != NULL) )
9757 	{
9758 		if(!define_geometry_from_zmat()) Message(_("Error in  conversion\n Zmatix to xyz "),_("Warning"),TRUE);
9759 		for(i=0;i<Natoms;i++)
9760 		{
9761 			gint j;
9762 			geometry[i].typeConnections = g_malloc(Natoms*sizeof(gint));
9763 			for(j=0;j<(gint)Natoms;j++) geometry[i].typeConnections[j] = 0;
9764 		}
9765 	}
9766 
9767          if(Units == 1 ) geometry_in_au();
9768 /* Center of molecule */
9769         if(Natoms<1) return;
9770         for(i=0;i<3;i++) X0[i] = 0.0;
9771         for(i=0;i<Natoms;i++)
9772 	{
9773 	X0[0] +=geometry[i].X;
9774 	X0[1] +=geometry[i].Y;
9775 	X0[2] +=geometry[i].Z;
9776 	}
9777         for(i=0;i<3;i++)
9778 		X0[i] /= Natoms;
9779         for(i=0;i<Natoms;i++)
9780 	{
9781 	geometry[i].X -= X0[0];
9782 	geometry[i].Y -= X0[1];
9783 	geometry[i].Z -= X0[2];
9784 	}
9785 
9786 	Ddef = Dipole.def;
9787         for(i=0;i<3;i++) Orig[i] = X0[i];
9788 
9789 	if(geometry0) g_free(geometry0);
9790 	geometry0 = NULL;
9791 
9792 	geometry0 =g_malloc(Natoms*sizeof(GeomDef));
9793 	for(i=0;i<Natoms;i++)
9794 	{
9795 	geometry0[i].X = geometry[i].X;
9796 	geometry0[i].Y = geometry[i].Y;
9797 	geometry0[i].Z = geometry[i].Z;
9798 	geometry0[i].N = geometry[i].N;
9799         geometry0[i].typeConnections = NULL;
9800 	geometry0[i].Prop = prop_atom_get(geometry[i].Prop.symbol);
9801 	geometry0[i].mmType = g_strdup(geometry[i].mmType);
9802 	geometry0[i].pdbType = g_strdup(geometry[i].pdbType);
9803 	geometry0[i].Layer = geometry[i].Layer;
9804 	geometry0[i].Variable = geometry[i].Variable;
9805 	geometry0[i].Residue = g_strdup(geometry[i].Residue);
9806 	geometry0[i].ResidueNumber = geometry[i].ResidueNumber;
9807 	geometry0[i].show = geometry[i].show;
9808 	geometry0[i].Charge = geometry[i].Charge;
9809 	geometry0[i].typeConnections = NULL;
9810 	}
9811 
9812 	nC = 0;
9813 	for(i=0;i<Natoms;i++)
9814 	{
9815 		geometry0[i].typeConnections = g_malloc(Natoms*sizeof(gint));
9816 		for(j=0;j<(gint)Natoms;j++) geometry0[i].typeConnections[j] = 0;
9817 	}
9818 	copy_connections(geometry0,geometry,Natoms);
9819 	nC = 0;
9820 	for(i=0;i<Natoms;i++)
9821 		for(j=0;j<(gint)Natoms;j++) nC+= geometry[i].typeConnections[j];
9822 	if(nC==0) reset_all_connections();
9823 	free_text_to_draw();
9824 	/* define_good_trans();*/
9825 
9826 	/* reset_charges_multiplicities();*/
9827 	reset_spin_of_electrons();
9828 	RebuildGeom = TRUE;
9829 
9830 }
9831 /*****************************************************************************/
get_num_min_rayonIJ(guint i,guint j)9832 guint get_num_min_rayonIJ(guint i,guint j)
9833 {
9834 	if(get_rayon(i) > get_rayon(j)) return j;
9835 	return i;
9836 
9837 }
9838 /*****************************************************************************/
draw_rectangle_selection()9839 static void draw_rectangle_selection()
9840 {
9841 	gdouble x1, y1, w, h;
9842 	V4d Ambiant  = {1.0f,1.0f,1.0f,1.0f};
9843 
9844 	if(Natoms<1) return;
9845 	if(xSelection<0) return;
9846 	x1 = BeginX;
9847 	y1 = BeginY;
9848 	w = xSelection-BeginX;
9849 	h = ySelection-BeginY;
9850 
9851 	if(w<0)
9852 	{
9853 		x1 = xSelection;
9854 		w = -w;
9855 	}
9856 	if(h<0)
9857 	{
9858 		y1 = ySelection;
9859 		h = -h;
9860 	}
9861  	glDisable ( GL_LIGHTING ) ;
9862         glColor4dv(Ambiant);
9863 	Projected_Rectangle_Draw(x1, y1, w,  h);
9864  	glEnable ( GL_LIGHTING ) ;
9865 }
9866 /*****************************************************************************/
get_color_string(guint i)9867 GdkColor get_color_string(guint i)
9868 {
9869  GdkColor color;
9870  color.pixel = 0;
9871  if (ShadMode)
9872  {
9873   color.red   =(gushort)(65535-geometry[i].Prop.color.red*geometry[i].Coefpers);
9874   color.green =(gushort)(65535-geometry[i].Prop.color.green*geometry[i].Coefpers);
9875   color.blue  =(gushort)(65535-geometry[i].Prop.color.blue*geometry[i].Coefpers);
9876  }
9877  else
9878  {
9879   color.red   =FontsStyleLabel.TextColor.red;
9880   color.green =FontsStyleLabel.TextColor.green;
9881   color.blue  =FontsStyleLabel.TextColor.blue;
9882  }
9883  return color;
9884 }
9885 /*****************************************************************************/
draw_label_dipole()9886 void draw_label_dipole()
9887 {
9888         gdouble P[3];
9889 	gchar* t= NULL;
9890 	gdouble d = 0.0;
9891 	V3d Base1Pos  = {Dipole.origin[0],Dipole.origin[1],Dipole.origin[2]};
9892 	V3d Base2Pos  = {Dipole.origin[0]+Dipole.value[0],Dipole.origin[1]+Dipole.value[1],Dipole.origin[2]+Dipole.value[2]};
9893 
9894 	GLdouble scal = 2*factordipole;
9895 	gint i;
9896 	GLdouble radius = Dipole.radius;
9897 	if(radius<0.1) radius = 0.1;
9898 
9899 	for(i=0;i<3;i++)
9900 	{
9901 		d += Dipole.value[i]*Dipole.value[i];
9902 		P[i]=(Dipole.value[i]*scal+Base1Pos[i]+Base1Pos[i])/2;
9903 	}
9904 	t = g_strdup_printf("%0.3f D",sqrt(d)*AUTODEB);
9905 
9906 	/*
9907 	if(ortho) glPrintOrthoOld(P[0], P[1], P[2], t, TRUE, TRUE);
9908 	else glPrintScaleOld(P[0], P[1], P[2], 1.1*radius,t);
9909 	*/
9910 	if(ortho) glPrintOrtho(P[0], P[1], P[2], t, TRUE, TRUE, ft2_context);
9911 	else glPrintScale(P[0], P[1], P[2], 1.1*radius,t, ft2_context);
9912 	g_free(t);
9913 }
9914 /*****************************************************************************/
draw_distance(gint i,gint j)9915 void draw_distance(gint i,gint j)
9916 {
9917         gdouble P[3];
9918 	gchar* t= NULL;
9919 
9920    	if(!geometry[i].show) return;
9921    	if(!geometry[j].show) return;
9922 	P[0]=(geometry[i].X+geometry[j].X)/2;
9923 	P[1]=(geometry[i].Y+geometry[j].Y)/2;
9924 	P[2]=(geometry[i].Z+geometry[j].Z)/2;
9925 
9926         Point A;
9927         Point B;
9928 
9929 	A.C[0]=geometry[i].X;
9930 	A.C[1]=geometry[i].Y;
9931 	A.C[2]=geometry[i].Z;
9932 
9933 	B.C[0]=geometry[j].X;
9934 	B.C[1]=geometry[j].Y;
9935 	B.C[2]=geometry[j].Z;
9936 
9937 	t = get_distance_points(A,B,TRUE);
9938 	/*
9939 	if(ortho) glPrintOrthoOld(P[0], P[1], P[2], t, TRUE, TRUE);
9940 	else glPrintScaleOld(P[0], P[1], P[2], 1.1*get_rayon(i),t);
9941 	*/
9942 	if(ortho) glPrintOrtho(P[0], P[1], P[2], t, TRUE, TRUE, ft2_context);
9943 	else glPrintScale(P[0], P[1], P[2], 1.1*get_rayon(i),t, ft2_context);
9944 	g_free(t);
9945 }
9946 /*****************************************************************************/
draw_anneau(gdouble X,gdouble Y,gdouble Z,GLdouble radii,GdkColor * color)9947 static void draw_anneau(gdouble X, gdouble Y, gdouble Z, GLdouble radii, GdkColor* color)
9948 {
9949 	int k;
9950 	gdouble alpha = 0.5;
9951 	V4d Specular = {1.0f,1.0f,1.0f,alpha};
9952 	V4d Diffuse  = {0.0f,0.0f,0.0f,alpha};
9953 	V4d Ambiant  = {0.0f,0.0f,0.0f,alpha};
9954 	V3d position = {X,Y,Z};
9955 
9956 	Specular[0] = color->red/(gdouble)65535;
9957 	Specular[1] = color->green/(gdouble)65535;
9958 	Specular[2] = color->blue/(gdouble)65535;
9959 	for(k=0;k<3;k++) Diffuse[k] = Specular[k]*0.8;
9960 	for(k=0;k<3;k++) Ambiant[k] = Specular[k]*0.5;
9961 	for(k=0;k<3;k++) Specular[k] = 0.8;
9962 	for(k=0;k<3;k++) Ambiant[k] = 0.0;
9963 
9964 	glEnable(GL_BLEND);
9965 	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
9966 	Sphere_Draw_Color(scaleAnneau*radii,position,Specular,Diffuse,Ambiant);
9967 	glDisable(GL_BLEND);
9968 
9969 }
9970 /*****************************************************************************/
draw_lines_yes_no(guint i,guint j)9971 gboolean draw_lines_yes_no(guint i,guint j)
9972 {
9973   gdouble distance;
9974   gdouble rcut;
9975   gdouble x,y,z;
9976   x = geometry[i].X-geometry[j].X;
9977   y = geometry[i].Y-geometry[j].Y;
9978   z = geometry[i].Z-geometry[j].Z;
9979   distance = x*x+y*y+z*z;
9980   rcut = geometry[i].Prop.covalentRadii+geometry[j].Prop.covalentRadii;
9981   rcut = rcut* rcut;
9982 
9983   if(distance<rcut)
9984 	return TRUE;
9985   else
9986 	return FALSE;
9987 }
9988 /*****************************************************************************/
draw_symb(guint i)9989 void draw_symb(guint i)
9990 {
9991 	gchar* t= g_strdup_printf("%s", geometry[i].Prop.symbol);
9992 	/*
9993 	if(ortho) glPrintOrthoOld(geometry[i].X, geometry[i].Y, geometry[i].Z, t , TRUE, TRUE);
9994 	else glPrintScaleOld(geometry[i].X, geometry[i].Y, geometry[i].Z, 1.1*geometry[i].Prop.radii,t);
9995 	*/
9996 	if(ortho) glPrintOrtho(geometry[i].X, geometry[i].Y, geometry[i].Z, t , TRUE, TRUE, ft2_context);
9997 	else glPrintScale(geometry[i].X, geometry[i].Y, geometry[i].Z, 1.1*geometry[i].Prop.radii,t, ft2_context);
9998 	g_free(t);
9999 
10000 }
10001 /*****************************************************************************/
draw_numb(guint i)10002 void draw_numb(guint i)
10003 {
10004         gchar *t =g_strdup_printf("%d",geometry[i].N);
10005 /*
10006 	if(ortho) glPrintOrthoOld(geometry[i].X, geometry[i].Y, geometry[i].Z, t, TRUE, TRUE);
10007 	else glPrintScaleOld(geometry[i].X, geometry[i].Y, geometry[i].Z, 1.1*geometry[i].Prop.radii,t);
10008 */
10009 	if(ortho) glPrintOrtho(geometry[i].X, geometry[i].Y, geometry[i].Z, t, TRUE, TRUE, ft2_context);
10010 	else glPrintScale(geometry[i].X, geometry[i].Y, geometry[i].Z, 1.1*geometry[i].Prop.radii,t, ft2_context);
10011 	g_free(t);
10012 }
10013 /*****************************************************************************/
draw_layer(guint i)10014 void draw_layer(guint i)
10015 {
10016 	gchar* t= NULL;
10017 
10018 	if(geometry[i].Layer==LOW_LAYER) t= g_strdup_printf("L");
10019 	else if(geometry[i].Layer==MEDIUM_LAYER) t= g_strdup_printf("M");
10020 	else t= g_strdup_printf(" ");
10021 	/*
10022 	if(ortho) glPrintOrthoOld(geometry[i].X, geometry[i].Y, geometry[i].Z, t,  TRUE, TRUE);
10023 	else glPrintScaleOld(geometry[i].X, geometry[i].Y, geometry[i].Z, 1.1*geometry[i].Prop.radii,t);
10024 	*/
10025 
10026 	if(ortho) glPrintOrtho(geometry[i].X, geometry[i].Y, geometry[i].Z, t,  TRUE, TRUE, ft2_context);
10027 	else glPrintScale(geometry[i].X, geometry[i].Y, geometry[i].Z, 1.1*geometry[i].Prop.radii,t, ft2_context);
10028 
10029 	g_free(t);
10030 
10031 }
10032 /*****************************************************************************/
draw_mmtyp(guint i)10033 void draw_mmtyp(guint i)
10034 {
10035 	gchar* t= g_strdup_printf("%s", geometry[i].mmType);
10036 	/*
10037 	if(ortho) glPrintOrthoOld(geometry[i].X, geometry[i].Y, geometry[i].Z, t , TRUE, TRUE);
10038 	else glPrintScaleOld(geometry[i].X, geometry[i].Y, geometry[i].Z, 1.1*geometry[i].Prop.radii,t);
10039 	*/
10040 	if(ortho) glPrintOrtho(geometry[i].X, geometry[i].Y, geometry[i].Z, t , TRUE, TRUE, ft2_context);
10041 	else glPrintScale(geometry[i].X, geometry[i].Y, geometry[i].Z, 1.1*geometry[i].Prop.radii,t, ft2_context);
10042 	g_free(t);
10043 
10044 }
10045 /*****************************************************************************/
draw_pdbtyp(guint i)10046 void draw_pdbtyp(guint i)
10047 {
10048 	gchar* t= g_strdup_printf("%s", geometry[i].pdbType);
10049 	/*
10050 	if(ortho) glPrintOrthoOld(geometry[i].X, geometry[i].Y, geometry[i].Z, t, TRUE, TRUE);
10051 	else glPrintScaleOld(geometry[i].X, geometry[i].Y, geometry[i].Z, 1.1*geometry[i].Prop.radii,t);
10052 	*/
10053 	if(ortho) glPrintOrtho(geometry[i].X, geometry[i].Y, geometry[i].Z, t, TRUE, TRUE,ft2_context);
10054 	else glPrintScale(geometry[i].X, geometry[i].Y, geometry[i].Z, 1.1*geometry[i].Prop.radii,t, ft2_context);
10055 	g_free(t);
10056 
10057 }
10058 /*****************************************************************************/
draw_numb_symb(guint i)10059 void draw_numb_symb(guint i)
10060 {
10061         gchar *t;
10062         t = g_strdup_printf("%s[%d]",geometry[i].Prop.symbol,geometry[i].N);
10063 	/*
10064 	if(ortho) glPrintOrthoOld(geometry[i].X, geometry[i].Y, geometry[i].Z, t, TRUE, TRUE);
10065 	else glPrintScaleOld(geometry[i].X, geometry[i].Y, geometry[i].Z, 1.1*geometry[i].Prop.radii,t);
10066 	*/
10067 
10068 	if(ortho) glPrintOrtho(geometry[i].X, geometry[i].Y, geometry[i].Z, t, TRUE, TRUE, ft2_context);
10069 	else glPrintScale(geometry[i].X, geometry[i].Y, geometry[i].Z, 1.1*geometry[i].Prop.radii,t, ft2_context);
10070 	g_free(t);
10071 }
10072 /*****************************************************************************/
draw_charge(guint i)10073 void draw_charge(guint i)
10074 {
10075         gchar *t;
10076         t = g_strdup_printf("%0.3f",geometry[i].Charge);
10077 	/*
10078 	if(ortho) glPrintOrthoOld(geometry[i].X, geometry[i].Y, geometry[i].Z, t, TRUE, TRUE);
10079 	else glPrintScaleOld(geometry[i].X, geometry[i].Y, geometry[i].Z, 1.1*geometry[i].Prop.radii,t);
10080 	*/
10081 
10082 	if(ortho) glPrintOrtho(geometry[i].X, geometry[i].Y, geometry[i].Z, t, TRUE, TRUE, ft2_context);
10083 	else glPrintScale(geometry[i].X, geometry[i].Y, geometry[i].Z, 1.1*geometry[i].Prop.radii,t, ft2_context);
10084 	g_free(t);
10085 }
10086 /*****************************************************************************/
draw_symb_charge(guint i)10087 void draw_symb_charge(guint i)
10088 {
10089         gchar *t;
10090         t = g_strdup_printf("%s[%0.3f]",geometry[i].Prop.symbol,geometry[i].Charge);
10091 	/*
10092 	if(ortho) glPrintOrthoOld(geometry[i].X, geometry[i].Y, geometry[i].Z, t, TRUE, TRUE);
10093 	else glPrintScaleOld(geometry[i].X, geometry[i].Y, geometry[i].Z, 1.1*geometry[i].Prop.radii,t);
10094 	*/
10095 
10096 	if(ortho) glPrintOrtho(geometry[i].X, geometry[i].Y, geometry[i].Z, t, TRUE, TRUE, ft2_context);
10097 	else glPrintScale(geometry[i].X, geometry[i].Y, geometry[i].Z, 1.1*geometry[i].Prop.radii,t, ft2_context);
10098 	g_free(t);
10099 }
10100 /*****************************************************************************/
draw_numb_charge(guint i)10101 void draw_numb_charge(guint i)
10102 {
10103         gchar *t;
10104         t = g_strdup_printf("%d[%0.3f]",geometry[i].N,geometry[i].Charge);
10105 	/*
10106 	if(ortho) glPrintOrthoOld(geometry[i].X, geometry[i].Y, geometry[i].Z, t, TRUE, TRUE);
10107 	else glPrintScaleOld(geometry[i].X, geometry[i].Y, geometry[i].Z, 1.1*geometry[i].Prop.radii,t);
10108 	*/
10109 	if(ortho) glPrintOrtho(geometry[i].X, geometry[i].Y, geometry[i].Z, t, TRUE, TRUE, ft2_context);
10110 	else glPrintScale(geometry[i].X, geometry[i].Y, geometry[i].Z, 1.1*geometry[i].Prop.radii,t, ft2_context);
10111 	g_free(t);
10112 }
10113 /*****************************************************************************/
draw_residues(guint i)10114 void draw_residues(guint i)
10115 {
10116         gchar *t;
10117         t = g_strdup_printf("%s[%d]",geometry[i].Residue,geometry[i].ResidueNumber+1);
10118 	/*
10119 	if(ortho) glPrintOrthoOld(geometry[i].X, geometry[i].Y, geometry[i].Z, t, TRUE, TRUE);
10120 	else glPrintScaleOld(geometry[i].X, geometry[i].Y, geometry[i].Z, 1.1*geometry[i].Prop.radii,t);
10121 	*/
10122 	if(ortho) glPrintOrtho(geometry[i].X, geometry[i].Y, geometry[i].Z, t, TRUE, TRUE, ft2_context);
10123 	else glPrintScale(geometry[i].X, geometry[i].Y, geometry[i].Z, 1.1*geometry[i].Prop.radii,t, ft2_context);
10124 	g_free(t);
10125 }
10126 /*****************************************************************************/
draw_coordinates(guint i)10127 void draw_coordinates(guint i)
10128 {
10129         gchar *t;
10130         t = g_strdup_printf("%s[%0.3f,%0.3f,%0.3f] Ang",
10131 			geometry0[i].Prop.symbol,
10132 			geometry0[i].X*BOHR_TO_ANG,
10133 			geometry0[i].Y*BOHR_TO_ANG,
10134 			geometry0[i].Z*BOHR_TO_ANG);
10135 	/*
10136 	if(ortho) glPrintOrthoOld(geometry[i].X, geometry[i].Y, geometry[i].Z, t, TRUE, TRUE);
10137 	else glPrintScaleOld(geometry[i].X, geometry[i].Y, geometry[i].Z, 1.1*geometry[i].Prop.radii,t);
10138 	*/
10139 
10140 	if(ortho) glPrintOrtho(geometry[i].X, geometry[i].Y, geometry[i].Z, t, TRUE, TRUE, ft2_context);
10141 	else glPrintScale(geometry[i].X, geometry[i].Y, geometry[i].Z, 1.1*geometry[i].Prop.radii,t, ft2_context);
10142 	g_free(t);
10143 }
10144 /*****************************************************************************/
draw_label(guint i)10145 void draw_label(guint i)
10146 {
10147    if(!geometry[i].show) return;
10148    switch(LabelOption)
10149    {
10150    case LABELSYMB: draw_symb(i);break;
10151    case LABELNUMB: draw_numb(i);break;
10152    case LABELMMTYP: draw_mmtyp(i);break;
10153    case LABELPDBTYP: draw_pdbtyp(i);break;
10154    case LABELLAYER: draw_layer(i);break;
10155    case LABELSYMBNUMB: draw_numb_symb(i);break;
10156    case LABELCHARGE: draw_charge(i);break;
10157    case LABELSYMBCHARGE: draw_symb_charge(i);break;
10158    case LABELNUMBCHARGE: draw_numb_charge(i);break;
10159    case LABELRESIDUES: draw_residues(i);break;
10160    case LABELCOORDINATES: draw_coordinates(i);break;
10161    }
10162 }
10163 /*****************************************************************************/
draw_ball(gdouble X,gdouble Y,gdouble Z,GLdouble radii,GdkColor * color)10164 static void draw_ball(gdouble X, gdouble Y, gdouble Z, GLdouble radii, GdkColor* color)
10165 {
10166 	int k;
10167 	V4d Specular = {1.0f,1.0f,1.0f,1.0f};
10168 	V4d Diffuse  = {0.0f,0.0f,0.0f,1.0f};
10169 	V4d Ambiant  = {0.0f,0.0f,0.0f,1.0f};
10170 	V3d position = {X,Y,Z};
10171 
10172 	Specular[0] = color->red/(gdouble)65535;
10173 	Specular[1] = color->green/(gdouble)65535;
10174 	Specular[2] = color->blue/(gdouble)65535;
10175 	for(k=0;k<3;k++) Diffuse[k] = Specular[k]*0.8;
10176 	for(k=0;k<3;k++) Ambiant[k] = Specular[k]*0.5;
10177 	for(k=0;k<3;k++) Specular[k] = 0.8;
10178 	for(k=0;k<3;k++) Ambiant[k] = 0.0;
10179 
10180 	if(TypeGeom == GABEDIT_TYPEGEOM_SPACE)
10181 	{
10182 		OpenGLOptions openGLOptions = get_opengl_options();
10183 		Sphere_Draw_Color_Precision(radii,position,Specular,Diffuse,Ambiant, (GLint)openGLOptions.numberOfSubdivisionsSphere*2);
10184 	}
10185 	else
10186 	Sphere_Draw_Color(radii,position,Specular,Diffuse,Ambiant);
10187 
10188 }
10189 /************************************************************************/
getOptimalCiCj(gint i,gint j,gdouble * Ci,gdouble * Cj,gdouble * C0)10190 void getOptimalCiCj(gint i, gint j, gdouble* Ci, gdouble* Cj, gdouble* C0)
10191 {
10192 	C0[0] = 0;
10193 	C0[1] = 0;
10194 	C0[2] = 0;
10195 
10196 	Ci[0] = geometry[i].X;
10197 	Ci[1] = geometry[i].Y;
10198 	Ci[2] = geometry[i].Z;
10199 
10200 	Cj[0] = geometry[j].X;
10201 	Cj[1] = geometry[j].Y;
10202 	Cj[2] = geometry[j].Z;
10203 
10204 /* serach a one none hydrogen atom connected to i or j atoms */
10205 	if(geometry[i].typeConnections)
10206 	{
10207 		gint l;
10208 		gint nl;
10209 		for(l=0, nl = geometry[l].N-1;l<Natoms;l++, nl = geometry[l].N-1)
10210 			if(l != j && l != i &&  geometry[i].typeConnections[nl]>0 && strcmp(geometry[l].Prop.symbol,"H"))
10211 			{
10212 				C0[0] = geometry[l].X;
10213 				C0[1] = geometry[l].Y;
10214 				C0[2] = geometry[l].Z;
10215 				/* printf("---%s\n",geometry[l].Prop.symbol);*/
10216 				return;
10217 			}
10218 	}
10219 	if(geometry[j].typeConnections)
10220 	{
10221 		gint l;
10222 		gint nl;
10223 		for(l=0, nl = geometry[l].N-1;l<Natoms;l++, nl = geometry[l].N-1)
10224 			if(l != j && l != i &&  geometry[j].typeConnections[nl]>0  && strcmp(geometry[l].Prop.symbol,"H"))
10225 			{
10226 				C0[0] = geometry[l].X;
10227 				C0[1] = geometry[l].Y;
10228 				C0[2] = geometry[l].Z;
10229 				/* printf("--%s\n",geometry[l].Prop.symbol);*/
10230 				return;
10231 			}
10232 	}
10233 	if(geometry[i].typeConnections)
10234 	{
10235 		gint l;
10236 		gint nl;
10237 		for(l=0, nl = geometry[l].N-1;l<Natoms;l++, nl = geometry[l].N-1)
10238 			if(l != j && l != i &&  geometry[i].typeConnections[nl]>0)
10239 			{
10240 				C0[0] = geometry[l].X;
10241 				C0[1] = geometry[l].Y;
10242 				C0[2] = geometry[l].Z;
10243 				/* printf("%s\n",geometry[l].Prop.symbol);*/
10244 				return;
10245 			}
10246 	}
10247 	if(geometry[j].typeConnections)
10248 	{
10249 		gint l;
10250 		gint nl;
10251 		for(l=0, nl = geometry[l].N-1;l<Natoms;l++, nl = geometry[l].N-1)
10252 			if(l != j && l != i &&  geometry[j].typeConnections[nl]>0)
10253 			{
10254 				C0[0] = geometry[l].X;
10255 				C0[1] = geometry[l].Y;
10256 				C0[2] = geometry[l].Z;
10257 				/* printf("%s\n",geometry[l].Prop.symbol);*/
10258 				return;
10259 			}
10260 	}
10261 }
10262 /************************************************************************/
draw_hbond(int i,int j,GLdouble scal)10263 static void draw_hbond(int i,int j,GLdouble scal)
10264 {
10265 
10266 	int k;
10267 	GLdouble g;
10268 	V4d Specular1 = {1.0f,1.0f,1.0f,1.0f};
10269 	V4d Diffuse1  = {0.0f,0.0f,0.0f,1.0f};
10270 	V4d Ambiant1  = {0.0f,0.0f,0.0f,1.0f};
10271 	V4d Specular2 = {1.0f,1.0f,1.0f,1.0f};
10272 	V4d Diffuse2  = {0.0f,0.0f,0.0f,1.0f};
10273 	V4d Ambiant2  = {0.0f,0.0f,0.0f,1.0f};
10274 	GLdouble aspect = scal;
10275 	GLdouble p1;
10276 	GLdouble p2;
10277      	gdouble A[3];
10278      	gdouble B[3];
10279      	gdouble K[3];
10280      	static gint n = 10;
10281 	gint kbreak;
10282 	gdouble Ci[3] = {geometry[i].X, geometry[i].Y,geometry[i].Z};
10283 	gdouble Cj[3] = {geometry[j].X, geometry[j].Y,geometry[j].Z};
10284 
10285 
10286 	if(geometry[i].Prop.radii<geometry[j].Prop.radii) g = geometry[i].Prop.radii*aspect;
10287 	else g = geometry[j].Prop.radii*aspect;
10288 
10289 	Specular1[0] = geometry[i].Prop.color.red/(gdouble)65535;
10290 	Specular1[1] = geometry[i].Prop.color.green/(gdouble)65535;
10291 	Specular1[2] = geometry[i].Prop.color.blue/(gdouble)65535;
10292 
10293 	Specular2[0] = geometry[j].Prop.color.red/(gdouble)65535;
10294 	Specular2[1] = geometry[j].Prop.color.green/(gdouble)65535;
10295 	Specular2[2] = geometry[j].Prop.color.blue/(gdouble)65535;
10296 
10297 	for(k=0;k<3;k++)
10298 	{
10299 		Diffuse1[k] = Specular1[k]*0.8;
10300 		Diffuse2[k] = Specular2[k]*0.8;
10301 	}
10302 	for(k=0;k<3;k++)
10303 	{
10304 		Ambiant1[k] = Specular1[k]*0.5;
10305 		Ambiant2[k] = Specular2[k]*0.5;
10306 	}
10307 
10308 	p1 = geometry[i].Prop.covalentRadii+geometry[i].Prop.radii;
10309 	p2 = geometry[j].Prop.covalentRadii+geometry[j].Prop.radii;
10310 
10311 	kbreak = (gint)(p1*n/(p1+p2));
10312 	kbreak = n/2;
10313 
10314 	for(k=0;k<3;k++) K[k] =(Cj[k]-Ci[k])/(n);
10315 	for(k=0;k<3;k++) A[k] =Ci[k];
10316 	for(i=0;i<n;i++)
10317 	{
10318      		for(k=0;k<3;k++) B[k] = A[k] + K[k];
10319 		if(i%2==0)
10320 		{
10321 			if(i<=kbreak) Cylinder_Draw_Color(g,A,B,Specular1,Diffuse1,Ambiant1);
10322 			else Cylinder_Draw_Color(g,A,B,Specular2,Diffuse2,Ambiant2);
10323 		}
10324      		for(k=0;k<3;k++) A[k] = B[k];
10325      }
10326 }
10327 /************************************************************************/
draw_bond(int i,int j,GLdouble scal,gint connectionType)10328 static void draw_bond(int i,int j,GLdouble scal, gint connectionType)
10329 {
10330 
10331 	int k;
10332 	GLdouble g;
10333 	V4d Specular1 = {1.0f,1.0f,1.0f,1.0f};
10334 	V4d Diffuse1  = {0.0f,0.0f,0.0f,1.0f};
10335 	V4d Ambiant1  = {0.0f,0.0f,0.0f,1.0f};
10336 	V4d Specular2 = {1.0f,1.0f,1.0f,1.0f};
10337 	V4d Diffuse2  = {0.0f,0.0f,0.0f,1.0f};
10338 	V4d Ambiant2  = {0.0f,0.0f,0.0f,1.0f};
10339 	GLdouble aspect = scal;
10340 	GLdouble p1;
10341 	GLdouble p2;
10342 	V3d Ci = {geometry[i].X, geometry[i].Y,geometry[i].Z};
10343 	V3d Cj = {geometry[j].X, geometry[j].Y,geometry[j].Z};
10344 	GabEditBondType bondType = connectionType-1;
10345 
10346 	/*
10347 	if(geometry[i].Prop.radii<geometry[j].Prop.radii) g = geometry[i].Prop.radii*aspect;
10348 	else g = geometry[j].Prop.radii*aspect;
10349 	*/
10350 	g = get_epaisseur(i,j)*aspect;
10351 
10352 	Specular1[0] = geometry[i].Prop.color.red/(gdouble)65535;
10353 	Specular1[1] = geometry[i].Prop.color.green/(gdouble)65535;
10354 	Specular1[2] = geometry[i].Prop.color.blue/(gdouble)65535;
10355 
10356 	Specular2[0] = geometry[j].Prop.color.red/(gdouble)65535;
10357 	Specular2[1] = geometry[j].Prop.color.green/(gdouble)65535;
10358 	Specular2[2] = geometry[j].Prop.color.blue/(gdouble)65535;
10359 
10360 	for(k=0;k<3;k++)
10361 	{
10362 		Diffuse1[k] = Specular1[k]*0.8;
10363 		Diffuse2[k] = Specular2[k]*0.8;
10364 	}
10365 	for(k=0;k<3;k++)
10366 	{
10367 		Ambiant1[k] = Specular1[k]*0.5;
10368 		Ambiant2[k] = Specular2[k]*0.5;
10369 	}
10370 
10371 	for(k=0;k<3;k++)
10372 	{
10373 		Ambiant1[k] = 0.1;
10374 		Ambiant2[k] = 0.1;
10375 	}
10376 	for(k=0;k<3;k++)
10377 	{
10378 		Specular1[k] = 0.8;
10379 		Specular2[k] = 0.8;
10380 	}
10381 
10382 	p1 = geometry[i].Prop.covalentRadii+geometry[i].Prop.radii;
10383 	p2 = geometry[j].Prop.covalentRadii+geometry[j].Prop.radii;
10384 
10385 	if(      bondType == GABEDIT_BONDTYPE_SINGLE ||
10386 		( !showMultipleBonds &&
10387 		 (bondType == GABEDIT_BONDTYPE_DOUBLE || bondType == GABEDIT_BONDTYPE_TRIPLE)
10388 		 )
10389 	    )
10390 		Cylinder_Draw_Color_Two(g,Ci,Cj,
10391 				Specular1,Diffuse1,Ambiant1,
10392 				Specular2,Diffuse2,Ambiant2,
10393 				p1,p2);
10394 
10395 	else
10396 	if(bondType == GABEDIT_BONDTYPE_DOUBLE && showMultipleBonds)
10397 	{
10398 		/* printf("Double bond\n");*/
10399 		gdouble r = g/aspect;
10400 		gdouble C11[3];
10401 		gdouble C12[3];
10402 		gdouble C21[3];
10403 		gdouble C22[3];
10404 		gdouble rs[3];
10405 		gdouble C0[3];
10406 		gint type = 1;
10407 		if(TypeGeom== GABEDIT_TYPEGEOM_STICK) type = 0;
10408 		else if(geometry[i].Layer == LOW_LAYER || geometry[j].Layer == LOW_LAYER) type = 0;
10409 		getOptimalCiCj(i, j, Ci, Cj,C0);
10410 		getPositionsRadiusBond2(r, C0, Ci, Cj, C11, C12,  C21,  C22, rs, type);
10411 		/*
10412 		printf("1 C11 = %f %f %f\n",C11[0],C11[1],C11[2]);
10413 		printf("1 C21 = %f %f %f\n",C21[0],C21[1],C21[2]);
10414 		printf("2 C12 = %f %f %f\n",C12[0],C12[1],C12[2]);
10415 		printf("2 C22 = %f %f %f\n",C22[0],C22[1],C22[2]);
10416 		*/
10417 		Cylinder_Draw_Color_Two(rs[0],C11,C12, Specular1,Diffuse1,Ambiant1, Specular2,Diffuse2,Ambiant2, p1,p2);
10418 		Cylinder_Draw_Color_Two(rs[1],C21,C22, Specular1,Diffuse1,Ambiant1, Specular2,Diffuse2,Ambiant2, p1,p2);
10419 	}
10420 	else
10421 	if(bondType == GABEDIT_BONDTYPE_TRIPLE && showMultipleBonds)
10422 	{
10423 		V3d C0;
10424 		gdouble r = g/aspect;
10425 		gdouble C11[3];
10426 		gdouble C12[3];
10427 		gdouble C21[3];
10428 		gdouble C22[3];
10429 		gdouble C31[3];
10430 		gdouble C32[3];
10431 		gdouble rs[3];
10432 		gint type = 1;
10433 		if(TypeGeom== GABEDIT_TYPEGEOM_STICK) type = 0;
10434 		getOptimalCiCj(i, j, Ci, Cj,C0);
10435 		getPositionsRadiusBond3(r, C0, Ci, Cj, C11, C12,  C21,  C22, C31, C32, rs, type);
10436 		Cylinder_Draw_Color_Two(rs[0],C11,C12, Specular1,Diffuse1,Ambiant1, Specular2,Diffuse2,Ambiant2, p1,p2);
10437 		Cylinder_Draw_Color_Two(rs[1],C21,C22, Specular1,Diffuse1,Ambiant1, Specular2,Diffuse2,Ambiant2, p1,p2);
10438 		Cylinder_Draw_Color_Two(rs[2],C31,C32, Specular1,Diffuse1,Ambiant1, Specular2,Diffuse2,Ambiant2, p1,p2);
10439 
10440 	}
10441 }
10442 /************************************************************************/
draw_bond_blend(int i,int j,GLdouble scal,gint connectionType,GdkColor * color)10443 static void draw_bond_blend(int i,int j,GLdouble scal, gint connectionType, GdkColor* color)
10444 {
10445 
10446 	int k;
10447 	GLdouble g;
10448 	gdouble a = 0.5;
10449 	V4d Specular1 = {1.0f,1.0f,1.0f,a};
10450 	V4d Diffuse1  = {0.0f,0.0f,0.0f,a};
10451 	V4d Ambiant1  = {0.0f,0.0f,0.0f,a};
10452 	V4d Specular2 = {1.0f,1.0f,1.0f,a};
10453 	V4d Diffuse2  = {0.0f,0.0f,0.0f,a};
10454 	V4d Ambiant2  = {0.0f,0.0f,0.0f,a};
10455 	GLdouble aspect = scal;
10456 	GLdouble p1;
10457 	GLdouble p2;
10458 	V3d Ci = {geometry[i].X, geometry[i].Y,geometry[i].Z};
10459 	V3d Cj = {geometry[j].X, geometry[j].Y,geometry[j].Z};
10460 
10461 	/*
10462 	if(geometry[i].Prop.radii<geometry[j].Prop.radii) g = geometry[i].Prop.radii*aspect;
10463 	else g = geometry[j].Prop.radii*aspect;
10464 	*/
10465 	g = get_epaisseur(i,j)*aspect;
10466 
10467 	Specular1[0] = color->red/(gdouble)65535;
10468 	Specular1[1] = color->green/(gdouble)65535;
10469 	Specular1[2] = color->blue/(gdouble)65535;
10470 
10471 	Specular2[0] = color->red/(gdouble)65535;
10472 	Specular2[1] = color->green/(gdouble)65535;
10473 	Specular2[2] = color->blue/(gdouble)65535;
10474 
10475 	for(k=0;k<3;k++)
10476 	{
10477 		Diffuse1[k] = Specular1[k]*0.8;
10478 		Diffuse2[k] = Specular2[k]*0.8;
10479 	}
10480 	for(k=0;k<3;k++)
10481 	{
10482 		Ambiant1[k] = Specular1[k]*0.5;
10483 		Ambiant2[k] = Specular2[k]*0.5;
10484 	}
10485 
10486 	for(k=0;k<3;k++)
10487 	{
10488 		Ambiant1[k] = 0.1;
10489 		Ambiant2[k] = 0.1;
10490 	}
10491 	for(k=0;k<3;k++)
10492 	{
10493 		Specular1[k] = 0.8;
10494 		Specular2[k] = 0.8;
10495 	}
10496 
10497 	p1 = geometry[i].Prop.covalentRadii+geometry[i].Prop.radii;
10498 	p2 = geometry[j].Prop.covalentRadii+geometry[j].Prop.radii;
10499 
10500 	glEnable(GL_BLEND);
10501 	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
10502 	Cylinder_Draw_Color_Two(g,Ci,Cj, Specular1,Diffuse1,Ambiant1, Specular2,Diffuse2,Ambiant2, p1,p2);
10503 	glDisable(GL_BLEND);
10504 }
10505 /*****************************************************************************/
testShowBoxGeom()10506 gboolean testShowBoxGeom()
10507 {
10508 	return showBox;
10509 }
10510 /*****************************************************************************/
gl_build_box()10511 static void gl_build_box()
10512 {
10513 	guint i;
10514 	guint j;
10515 	GdkColor colorRed;
10516 	GdkColor colorGreen;
10517 	GdkColor colorBlue;
10518 	GdkColor colorYellow;
10519 	GdkColor colorFrag;
10520     	gdouble rayon;
10521 	gint ni, nj;
10522 	gchar tmp[BSIZE];
10523 	gint nTv = 0;
10524 	gint iTv[3] = {-1,-1,-1};
10525 	V3d Base1Pos;
10526 	V3d Base2Pos;
10527 	V4d Specular = {1.0f,1.0f,1.0f,1.0f};
10528         V4d Diffuse  = {1.0f,1.0f,1.0f,1.0f};
10529         V4d Ambiant  = {1.0f,1.0f,1.0f,1.0f};
10530 	gdouble radius = 0.1;
10531 	gdouble Tv[3][3];
10532 	gdouble O[3];
10533 
10534 	if(!testShowBoxGeom()) return;
10535 	for(i=0;i<Natoms;i++)
10536 	{
10537 		sprintf(tmp,"%s",geometry[i].Prop.symbol);
10538 		uppercase(tmp);
10539 		if(!strcmp(tmp,"TV")) { iTv[nTv]= i; nTv++;}
10540 	}
10541 	if(nTv<2) return;
10542 	for(i=0;i<3;i++) O[i] = -Orig[i];
10543 	for(i=0;i<nTv;i++)
10544 	{
10545 		Tv[i][0] = geometry[iTv[i]].X-O[0];
10546 		Tv[i][1] = geometry[iTv[i]].Y-O[1];
10547 		Tv[i][2] = geometry[iTv[i]].Z-O[2];
10548 	}
10549 
10550 	for(i=0;i<3;i++) Base1Pos[i] = O[i];
10551 	for(i=0;i<3;i++) Base2Pos[i] = Base1Pos[i]+Tv[0][i];
10552 	Cylinder_Draw_Color(radius, Base1Pos, Base2Pos, Specular, Diffuse, Ambiant);
10553 
10554 	for(i=0;i<3;i++) Base1Pos[i] = O[i];
10555 	for(i=0;i<3;i++) Base2Pos[i] = Base1Pos[i]+Tv[1][i];
10556 	Cylinder_Draw_Color(radius, Base1Pos, Base2Pos, Specular, Diffuse, Ambiant);
10557 
10558 	for(i=0;i<3;i++) Base1Pos[i] = O[i]+Tv[0][i];
10559 	for(i=0;i<3;i++) Base2Pos[i] = Base1Pos[i]+Tv[1][i];
10560 	Cylinder_Draw_Color(radius, Base1Pos, Base2Pos, Specular, Diffuse, Ambiant);
10561 
10562 	for(i=0;i<3;i++) Base1Pos[i] = O[i]+Tv[1][i];
10563 	for(i=0;i<3;i++) Base2Pos[i] = Base1Pos[i]+Tv[0][i];
10564 	Cylinder_Draw_Color(radius, Base1Pos, Base2Pos, Specular, Diffuse, Ambiant);
10565 	if(nTv<3) return;
10566 
10567 	for(i=0;i<3;i++) Base1Pos[i] = O[i];
10568 	for(i=0;i<3;i++) Base2Pos[i] = Base1Pos[i]+Tv[2][i];
10569 	Cylinder_Draw_Color(radius, Base1Pos, Base2Pos, Specular, Diffuse, Ambiant);
10570 
10571 	for(i=0;i<3;i++) Base1Pos[i] = O[i]+Tv[0][i];
10572 	for(i=0;i<3;i++) Base2Pos[i] = Base1Pos[i]+Tv[2][i];
10573 	Cylinder_Draw_Color(radius, Base1Pos, Base2Pos, Specular, Diffuse, Ambiant);
10574 
10575 	for(i=0;i<3;i++) Base1Pos[i] = O[i]+Tv[2][i];
10576 	for(i=0;i<3;i++) Base2Pos[i] = Base1Pos[i]+Tv[0][i];
10577 	Cylinder_Draw_Color(radius, Base1Pos, Base2Pos, Specular, Diffuse, Ambiant);
10578 
10579 	for(i=0;i<3;i++) Base1Pos[i] = O[i]+Tv[1][i];
10580 	for(i=0;i<3;i++) Base2Pos[i] = Base1Pos[i]+Tv[2][i];
10581 	Cylinder_Draw_Color(radius, Base1Pos, Base2Pos, Specular, Diffuse, Ambiant);
10582 
10583 	for(i=0;i<3;i++) Base1Pos[i] = O[i]+Tv[2][i];
10584 	for(i=0;i<3;i++) Base2Pos[i] = Base1Pos[i]+Tv[1][i];
10585 	Cylinder_Draw_Color(radius, Base1Pos, Base2Pos, Specular, Diffuse, Ambiant);
10586 
10587 	for(i=0;i<3;i++) Base1Pos[i] = O[i]+Tv[0][i]+Tv[2][i];
10588 	for(i=0;i<3;i++) Base2Pos[i] = Base1Pos[i]+Tv[1][i];
10589 	Cylinder_Draw_Color(radius, Base1Pos, Base2Pos, Specular, Diffuse, Ambiant);
10590 
10591 	for(i=0;i<3;i++) Base1Pos[i] = O[i]+Tv[0][i]+Tv[1][i];
10592 	for(i=0;i<3;i++) Base2Pos[i] = Base1Pos[i]+Tv[2][i];
10593 	Cylinder_Draw_Color(radius, Base1Pos, Base2Pos, Specular, Diffuse, Ambiant);
10594 
10595 	for(i=0;i<3;i++) Base1Pos[i] = O[i]+Tv[1][i]+Tv[2][i];
10596 	for(i=0;i<3;i++) Base2Pos[i] = Base1Pos[i]+Tv[0][i];
10597 	Cylinder_Draw_Color(radius, Base1Pos, Base2Pos, Specular, Diffuse, Ambiant);
10598 
10599 }
10600 /*****************************************************************************/
gl_build_geometry()10601 static void gl_build_geometry()
10602 {
10603 	guint i;
10604 	guint j;
10605 	GdkColor colorRed;
10606 	GdkColor colorGreen;
10607 	GdkColor colorBlue;
10608 	GdkColor colorYellow;
10609 	GdkColor colorFrag;
10610     	gdouble rayon;
10611 	gint ni, nj;
10612 
10613 	colorRed.red   = 40000;
10614 	colorRed.green = 0;
10615 	colorRed.blue  = 0;
10616 	colorRed.pixel  = 0;
10617 
10618 	colorGreen.red   = 0;
10619 	colorGreen.green = 40000;
10620 	colorGreen.blue  = 0;
10621 	colorGreen.pixel  = 0;
10622 
10623 	colorBlue.red   = 0;
10624 	colorBlue.green = 0;
10625 	colorBlue.blue  = 40000;
10626 
10627 	colorYellow.red   = 40000;
10628 	colorYellow.green = 40000;
10629 	colorYellow.blue  = 0;
10630 
10631 	colorFrag = colorGreen;
10632 
10633 
10634 	for(i=0;i<Natoms;i++)
10635 	if((gint)i==NumSelectedAtom)
10636 	{
10637 		for(j = 0;j<NFatoms;j++)
10638 		if(NumFatoms[j] == (gint)geometry[i].N) colorFrag = colorRed;
10639 		break;
10640 	}
10641         if(ButtonPressed && OperationType==ROTLOCFRAG) colorFrag = colorRed;
10642         if(ButtonPressed && OperationType==ROTZLOCFRAG) colorFrag = colorRed;
10643 
10644 	for(i=0;i<Natoms;i++)
10645         {
10646 		ni = geometry[i].N-1;
10647 		rayon = get_rayon(i);
10648 		if(!geometry[i].show) continue;
10649 		draw_ball(geometry[i].X,geometry[i].Y,geometry[i].Z, get_rayon(i), &geometry[i].Prop.color);
10650 		if(TypeGeom==GABEDIT_TYPEGEOM_SPACE) continue;
10651 		for(j=i+1, nj = geometry[j].N-1;j<Natoms;j++, nj = geometry[j].N-1)
10652                 if(geometry[i].typeConnections[nj]>0)
10653 		{
10654 			if(!geometry[j].show) continue;
10655 			draw_bond(i, j,1.0, geometry[i].typeConnections[nj]);
10656 		}
10657 		else
10658 		{
10659 			if(geometry[i].show && geometry[j].show && ShowHBonds && geometry[i].typeConnections[nj]==-1)
10660 			{
10661 				draw_hbond(i,j,0.2);
10662 			}
10663 		}
10664         }
10665 	gl_build_box();
10666 /*
10667 	for(i=0;i<Natoms;i++)
10668 		for(j=i+1, nj = geometry[j].N-1;j<Natoms;j++, nj = geometry[j].N-1)
10669 			printf("%s[%d]-%s[%d] %d\n", geometry[i].Prop.symbol, geometry[i].N, geometry[j].Prop.symbol, geometry[j].N, geometry[i].typeConnections[nj]);
10670 */
10671 }
10672 /*****************************************************************************/
gl_build_selection()10673 static void gl_build_selection()
10674 {
10675 	guint i;
10676 	guint j;
10677 	GdkColor colorRed;
10678 	GdkColor colorGreen;
10679 	GdkColor colorBlue;
10680 	GdkColor colorYellow;
10681 	GdkColor colorFrag;
10682     	gdouble rayon;
10683 	gint ni, nj;
10684 
10685 	colorRed.red   = 40000;
10686 	colorRed.green = 0;
10687 	colorRed.blue  = 0;
10688 	colorRed.pixel  = 0;
10689 
10690 	colorGreen.red   = 0;
10691 	colorGreen.green = 40000;
10692 	colorGreen.blue  = 0;
10693 
10694 	colorBlue.red   = 0;
10695 	colorBlue.green = 0;
10696 	colorBlue.blue  = 40000;
10697 
10698 	colorYellow.red   = 40000;
10699 	colorYellow.green = 40000;
10700 	colorYellow.blue  = 0;
10701 
10702 	colorFrag = colorGreen;
10703 
10704 
10705 	for(i=0;i<Natoms;i++)
10706 	if((gint)i==NumSelectedAtom)
10707 	{
10708 		for(j = 0;j<NFatoms;j++)
10709 		if(NumFatoms[j] == (gint)geometry[i].N) colorFrag = colorRed;
10710 		break;
10711 	}
10712         if(ButtonPressed && OperationType==ROTLOCFRAG) colorFrag = colorRed;
10713         if(ButtonPressed && OperationType==ROTZLOCFRAG) colorFrag = colorRed;
10714 
10715 	for(i=0;i<Natoms;i++)
10716         {
10717 		ni = geometry[i].N-1;
10718 		rayon = get_rayon(i);
10719 		if(!geometry[i].show) continue;
10720 		for(j=i+1, nj = geometry[j].N-1;j<Natoms;j++, nj = geometry[j].N-1)
10721                 if(geometry[i].typeConnections[nj]>0)
10722 		{
10723 			if(!geometry[j].show) continue;
10724         		if((OperationType==CUTBOND || OperationType==CHANGEBOND)
10725 			&& NBatoms==2 && NumBatoms[0]>0 && NumBatoms[1]>0)
10726 			{
10727 				gint na = NumBatoms[0];
10728 				gint nb = NumBatoms[1];
10729 				if(
10730 			    		(na == (gint)geometry[i].N && geometry[i].show &&
10731 			    		nb == (gint)geometry[j].N && geometry[j].show)
10732 					||
10733 			    		(nb == (gint)geometry[i].N && geometry[i].show &&
10734 			    		na == (gint)geometry[j].N && geometry[j].show)
10735 					)
10736 				{
10737 					gdouble s  = get_rayon_selection(i)/rayon;
10738 					if(OperationType==CUTBOND)
10739 					draw_bond_blend(i, j,s, geometry[i].typeConnections[nj],&colorRed);
10740 					else
10741 					draw_bond_blend(i, j,s, geometry[i].typeConnections[nj],&colorFrag);
10742 				}
10743 			}
10744 		}
10745 		else
10746 		{
10747         		if(OperationType==ADDATOMSBOND && NFatoms==2 && NumFatoms[0]>0 && NumFatoms[1]>0)
10748 			{
10749 				gint na = NumFatoms[0];
10750 				gint nb = NumFatoms[1];
10751 				gdouble s  = get_rayon_selection(i)/rayon;
10752 			if(
10753 			    (na == (gint)geometry[i].N && geometry[i].show &&
10754 			    nb == (gint)geometry[j].N && geometry[j].show)
10755 					||
10756 			    (nb == (gint)geometry[i].N && geometry[i].show &&
10757 			    na == (gint)geometry[j].N && geometry[j].show)
10758 					)
10759 				draw_bond_blend(i, j,s, geometry[i].typeConnections[nj],&colorFrag);
10760 			}
10761 		}
10762 		if((gint)i==NumSelectedAtom) draw_anneau(geometry[i].X, geometry[i].Y, geometry[i].Z, rayon,&colorRed);
10763 		else if(GeomIsOpen)
10764 		{
10765 			if(NSA[0]>-1 && (gint)geometry[i].N == NSA[0]) draw_anneau(geometry[i].X, geometry[i].Y, geometry[i].Z, rayon,&colorRed);
10766 			if(NSA[1]>-1 && (gint)geometry[i].N == NSA[1]) draw_anneau(geometry[i].X, geometry[i].Y, geometry[i].Z, rayon,&colorGreen);
10767 			if(NSA[2]>-1 && (gint)geometry[i].N == NSA[2]) draw_anneau(geometry[i].X, geometry[i].Y, geometry[i].Z, rayon,&colorBlue);
10768 			if(NSA[3]>-1 && (gint)geometry[i].N == NSA[3]) draw_anneau(geometry[i].X, geometry[i].Y, geometry[i].Z, rayon,&colorYellow);
10769 		}
10770 		if(EDITOBJECTS==OperationType &&(gint)i==NumPointedAtom) draw_anneau(geometry[i].X, geometry[i].Y, geometry[i].Z, rayon,&colorRed);
10771 		if(OperationType == MEASURE)
10772 		for(j = 0;j<4;j++)
10773 			if(NumSelAtoms[j] == (gint)geometry[i].N) draw_anneau(geometry[i].X, geometry[i].Y, geometry[i].Z, rayon,&colorGreen);
10774 
10775         	switch(OperationType)
10776 		{
10777 			case ADDFRAGMENT :
10778 				if(atomToDelete == (gint)geometry[i].N) draw_anneau(geometry[i].X, geometry[i].Y, geometry[i].Z, rayon,&colorRed);
10779 				if(atomToBondTo == (gint)geometry[i].N) draw_anneau(geometry[i].X, geometry[i].Y, geometry[i].Z, rayon,&colorGreen);
10780 				if(angleTo == (gint)geometry[i].N) draw_anneau(geometry[i].X, geometry[i].Y, geometry[i].Z, rayon,&colorBlue);
10781 			break;
10782 			case SELECTOBJECTS :
10783 			case SELECTFRAG :
10784 			case SELECTRESIDUE :
10785 			case DELETEFRAG :
10786 			case DELETEOBJECTS :
10787 			case ROTLOCFRAG :
10788 			case ROTZLOCFRAG :
10789 			case MOVEFRAG :
10790 			for(j = 0;j<NFatoms;j++)
10791 			if(NumFatoms[j] == (gint)geometry[i].N) draw_anneau(geometry[i].X, geometry[i].Y, geometry[i].Z, rayon,&colorFrag);
10792 			break;
10793 			case CUTBOND :
10794 			for(j = 0;j<NBatoms;j++)
10795 			if(NumBatoms[j] == (gint)geometry[i].N) draw_anneau(geometry[i].X, geometry[i].Y, geometry[i].Z, rayon,&colorRed);
10796 			break;
10797 			case CHANGEBOND :
10798 			case ADDATOMSBOND :
10799 			for(j = 0;j<NBatoms;j++)
10800 			if(NumBatoms[j] == (gint)geometry[i].N) draw_anneau(geometry[i].X, geometry[i].Y, geometry[i].Z, rayon,&colorFrag);
10801 			break;
10802 			default : break;
10803 		}
10804         }
10805 }
10806 /*****************************************************************************/
gl_build_labels()10807 static void gl_build_labels()
10808 {
10809 	guint i,j;
10810 	V4d color  = {0.8,0.8,0.8,1.0 };
10811     	if (LabelOption == 0) return;
10812 
10813 	//glInitFontsUsingOld(FontsStyleLabel.fontname);
10814 	glInitFontsUsing(FontsStyleLabel.fontname, &ft2_context);
10815 
10816 	color[0] = FontsStyleLabel.TextColor.red/65535.0;
10817 	color[1] = FontsStyleLabel.TextColor.green/65535.0;
10818 	color[2] = FontsStyleLabel.TextColor.blue/65535.0;
10819 	glDisable ( GL_LIGHTING ) ;
10820 	glColor4dv(color);
10821 	for(i=0;i<Natoms;i++) draw_label(i);
10822 
10823 	if(DrawDistance)
10824 	for(i=0;i<Natoms;i++)
10825 		for(j=i+1;j<Natoms;j++)
10826                 	if(geometry[i].typeConnections[geometry[j].N-1]>0) draw_distance(i,j);
10827 	if(ShowDipole && Dipole.def) draw_label_dipole();
10828 	showLabelAxesGeom(ortho,NULL, ft2_context);
10829 	glEnable ( GL_LIGHTING ) ;
10830 	glDeleteFontsList();
10831 }
10832 /*****************************************************************************/
gl_build_dipole()10833 static void gl_build_dipole()
10834 {
10835 	V4d Specular = {1.0f,1.0f,1.0f,1.0f};
10836 	V4d Diffuse  = {0.0f,0.0f,1.0f,1.0f};
10837 	V4d Ambiant  = {0.0f,0.0f,0.1f,1.0f};
10838 	V3d Base1Pos  = {Dipole.origin[0],Dipole.origin[1],Dipole.origin[2]};
10839 	V3d Base2Pos  = {Dipole.origin[0]+Dipole.value[0],Dipole.origin[1]+Dipole.value[1],Dipole.origin[2]+Dipole.value[2]};
10840 	GLdouble radius = Dipole.radius;
10841 	V3d Center;
10842 	GLdouble scal = 2*factordipole;
10843 	V3d Direction;
10844 	double lengt;
10845 	gint i;
10846 
10847 	if(!ShowDipole) return;
10848 	if(!Dipole.def) return;
10849 
10850 	for(i=0;i<3;i++)
10851 	{
10852 		Diffuse[i] = Dipole.color[i]/65535.0;
10853 		Ambiant[i] = Diffuse[i]/10;
10854 	}
10855 
10856 	Direction[0] = Base2Pos[0]-Base1Pos[0];
10857 	Direction[1] = Base2Pos[1]-Base1Pos[1];
10858 	Direction[2] = Base2Pos[2]-Base1Pos[2];
10859 	lengt = v3d_length(Direction);
10860 	if(radius<0.1) radius = 0.1;
10861 
10862 	Base2Pos[0] = Base1Pos[0] + Direction[0]*scal;
10863 	Base2Pos[1] = Base1Pos[1] + Direction[1]*scal;
10864 	Base2Pos[2] = Base1Pos[2] + Direction[2]*scal;
10865 
10866 	Direction[0] /= lengt;
10867 	Direction[1] /= lengt;
10868 	Direction[2] /= lengt;
10869 
10870 
10871 	Center[0] = Base2Pos[0];
10872 	Center[1] = Base2Pos[1];
10873 	Center[2] = Base2Pos[2];
10874 
10875 	Base2Pos[0] += Direction[0]*2*radius;
10876 	Base2Pos[1] += Direction[1]*2*radius;
10877 	Base2Pos[2] += Direction[2]*2*radius;
10878 
10879 	Cylinder_Draw_Color(radius/2,Base1Pos,Center,Specular,Diffuse,Ambiant);
10880 	for(i=0;i<3;i++)
10881 	{
10882 		Diffuse[i] *=0.6;
10883 		Ambiant[i] *=0.6;
10884 	}
10885 	Diffuse[1] = Diffuse[2];
10886 	Prism_Draw_Color(radius/1.5,Center,Base2Pos,Specular,Diffuse,Ambiant);
10887 }
10888 /*****************************************************************************/
buildRotation()10889 void buildRotation()
10890 {
10891 	gdouble m[4][4];
10892 	build_rotmatrix(m,Quat);
10893 }
10894 /*****************************************************************************/
drawGeom()10895 void drawGeom()
10896 {
10897 	if(!GeomDrawingArea) return;
10898 	if(!GTK_IS_WIDGET(GeomDrawingArea)) return;
10899 	redraw(GeomDrawingArea);
10900 }
10901 /*****************************************************************************/
rafresh_drawing()10902 void rafresh_drawing()
10903 {
10904 	guint i;
10905 	HideShowMeasure(MeasureIsHide);
10906 	i= gtk_notebook_get_current_page(GTK_NOTEBOOK(NoteBookDraw));
10907 	define_geometry();
10908 	if(ShowHBonds) set_Hconnections();
10909 	gtk_notebook_remove_page((GtkNotebook *)NoteBookDraw,0);
10910 	vboxmeasure =AddNoteBookPage(NoteBookDraw,_("Measure"));
10911 	AddMeasure(GeomDlg,vboxmeasure);
10912 
10913 	gtk_widget_hide_all(NoteBookDraw);
10914 	gtk_widget_show_all(NoteBookDraw);
10915 	gtk_notebook_set_current_page((GtkNotebook*)NoteBookDraw,i);
10916 
10917 
10918 	drawGeom();
10919 	change_of_center(NULL,NULL);
10920 }
10921 /*****************************************************************************/
multi_geometry_by_factor(gdouble fa0)10922 void multi_geometry_by_factor(gdouble fa0)
10923 {
10924         guint i;
10925 
10926         for(i=0;i<Natoms;i++)
10927 	{
10928           geometry[i].X *= fa0;
10929           geometry[i].Y *= fa0;
10930           geometry[i].Z *= fa0;
10931 	}
10932 }
10933 /*****************************************************************************/
multi_geometry_by_a0(GtkWidget * win,gpointer d)10934 void multi_geometry_by_a0(GtkWidget *win, gpointer d)
10935 {
10936 	multi_geometry_by_factor(BOHR_TO_ANG);
10937 	RebuildGeom=TRUE;
10938 	drawGeom();
10939 }
10940 /*****************************************************************************/
divide_geometry_by_a0(GtkWidget * win,gpointer d)10941 void divide_geometry_by_a0(GtkWidget *win, gpointer d)
10942 {
10943  multi_geometry_by_factor(1.0/BOHR_TO_ANG);
10944 	RebuildGeom=TRUE;
10945  drawGeom();
10946 }
10947 /*****************************************************************************/
factor_default(GtkWidget * win,gpointer d)10948 void factor_default(GtkWidget *win,gpointer d)
10949 {
10950 	Zoom = 45;
10951 	drawGeom();
10952 }
10953 /*****************************************************************************/
factor_stick_default(GtkWidget * win,gpointer d)10954 void factor_stick_default(GtkWidget *win,gpointer d)
10955 {
10956 	factorstick =1.0;
10957 	RebuildGeom=TRUE;
10958 	drawGeom();
10959 }
10960 /*****************************************************************************/
factor_ball_default(GtkWidget * win,gpointer d)10961 void factor_ball_default(GtkWidget *win,gpointer d)
10962 {
10963 	factorball =1.0;
10964 	RebuildGeom=TRUE;
10965 	drawGeom();
10966 }
10967 /*****************************************************************************/
factor_dipole_default(GtkWidget * win,gpointer d)10968 void factor_dipole_default(GtkWidget *win,gpointer d)
10969 {
10970 	factordipole =1.0;
10971 	RebuildGeom=TRUE;
10972 	drawGeom();
10973 }
10974 /*****************************************************************************/
factor_all_default(GtkWidget * win,gpointer d)10975 void factor_all_default(GtkWidget *win,gpointer d)
10976 {
10977 	factorball =1.0;
10978 	factorstick =1.0;
10979 	Zoom =45;
10980 	factordipole =1.0;
10981 	RebuildGeom=TRUE;
10982 	SetOperation(NULL,     	CENTER);
10983 }
10984 /*****************************************************************************/
set_back_color_black()10985 void set_back_color_black()
10986 {
10987 
10988 	if(BackColor)
10989         {
10990 		gdk_color_free(BackColor);
10991 		BackColor=NULL;
10992         }
10993         drawGeom();
10994 }
10995 /*****************************************************************************/
set_back_color(GtkColorSelection * Sel,gpointer * d)10996 void set_back_color(GtkColorSelection *Sel,gpointer *d)
10997 {
10998 	GdkColor color;
10999 	gtk_color_selection_get_current_color(Sel, &color);
11000         BackColor = gdk_color_copy(&color);
11001 
11002         drawGeom();
11003 
11004 }
11005 /*****************************************************************************/
set_back_color_grey()11006 void set_back_color_grey()
11007 {
11008 	GdkColor color;
11009 
11010 	color.red = 80*257;
11011 	color.green = 80*257;
11012 	color.blue = 80*257;
11013         BackColor = gdk_color_copy(&color);
11014 
11015         drawGeom();
11016 }
11017 /*****************************************************************************/
set_back_color_default()11018 void set_back_color_default()
11019 {
11020 	static gint first = 0;
11021 	GdkColor color;
11022 
11023 	if(!BackColor)
11024 	{
11025 		set_back_color_grey();
11026 		return;
11027 	}
11028 	color.red = BackColor->red;
11029 	color.green = BackColor->green;
11030 	color.blue = BackColor->blue;
11031 
11032 	if(first==0)
11033 	{
11034 		g_free(BackColor);
11035 		first = 1;
11036 	}
11037         BackColor = gdk_color_copy(&color);
11038 
11039 
11040         drawGeom();
11041 }
11042 /*****************************************************************************/
open_color_dlg(GtkWidget * win,gpointer * DrawingArea)11043 void open_color_dlg(GtkWidget *win,gpointer *DrawingArea)
11044 {
11045 
11046 	GtkColorSelectionDialog *ColorDlg;
11047 	ColorDlg =
11048 		(GtkColorSelectionDialog *)gtk_color_selection_dialog_new(
11049 		_("Set Background Color"));
11050 	gtk_window_set_modal (GTK_WINDOW (ColorDlg), TRUE);
11051 	gtk_window_set_transient_for(GTK_WINDOW(ColorDlg),GTK_WINDOW(Fenetre));
11052 
11053 	gtk_widget_hide(ColorDlg->help_button);
11054 
11055 	g_signal_connect_swapped(G_OBJECT(ColorDlg->ok_button),"clicked",
11056 		(GCallback)set_back_color,GTK_OBJECT(ColorDlg->colorsel));
11057 
11058 	g_signal_connect_swapped(G_OBJECT(ColorDlg->ok_button),"clicked",
11059 		(GCallback)gtk_widget_destroy,GTK_OBJECT(ColorDlg));
11060 
11061 	g_signal_connect_swapped(G_OBJECT(ColorDlg->cancel_button),"clicked",
11062 		(GCallback)gtk_widget_destroy,GTK_OBJECT(ColorDlg));
11063 
11064 	gtk_widget_show(GTK_WIDGET(ColorDlg));
11065 
11066 }
11067 /*****************************************************************************/
create_frame_in_vbox(gchar * title,GtkWidget * win,GtkWidget * vbox,gboolean type)11068 GtkWidget *create_frame_in_vbox(gchar *title,GtkWidget *win,GtkWidget *vbox,gboolean type)
11069 {
11070   GtkWidget *frame;
11071   frame = gtk_frame_new (title);
11072   gtk_frame_set_shadow_type( GTK_FRAME(frame),GTK_SHADOW_ETCHED_OUT);
11073   g_object_ref (frame);
11074   gtk_container_set_border_width (GTK_CONTAINER (frame), 1);
11075   gtk_box_pack_start(GTK_BOX(vbox), frame,type,type,1);
11076   gtk_widget_show (frame);
11077   return frame;
11078 
11079 }
11080 /*****************************************************************************/
create_vbox_in_hbox(GtkWidget * win,GtkWidget * hbox,gboolean type)11081 GtkWidget *create_vbox_in_hbox(GtkWidget *win,GtkWidget *hbox,gboolean type)
11082 {
11083 	GtkWidget *vbox;
11084 	vbox = gtk_vbox_new (FALSE, 0);
11085 	g_object_ref (vbox);
11086 	gtk_widget_show (vbox);
11087 	gtk_box_pack_start (GTK_BOX (hbox), vbox, type, type, 1);
11088 
11089 	return vbox;
11090 }
11091 /*****************************************************************************/
create_hbox_in_vbox(GtkWidget * vbox)11092 GtkWidget *create_hbox_in_vbox(GtkWidget *vbox)
11093 {
11094 	GtkWidget *hbox;
11095 	hbox = gtk_hbox_new (FALSE, 0);
11096 	g_object_ref (hbox);
11097 	gtk_widget_show (hbox);
11098 	gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
11099 	return hbox;
11100 }
11101 /*****************************************************************************/
destroy_drawing_and_children(GtkWidget * win,gpointer data)11102 void destroy_drawing_and_children(GtkWidget *win,gpointer data)
11103 {
11104   destroy_children(GeomDlg);
11105 }
11106 /*****************************************************************************/
destroy_all_drawing(GtkWidget * win)11107 void destroy_all_drawing(GtkWidget *win)
11108 {
11109 
11110   stop_calcul(win, NULL);
11111   while( gtk_events_pending() ) gtk_main_iteration();
11112   geometry  = Free_One_Geom(geometry ,Natoms);
11113   geometry0 = Free_One_Geom(geometry0,Natoms);
11114 
11115   g_free(NumFatoms);
11116   NumFatoms = NULL;
11117   NFatoms = 0;
11118   Natoms = 0;
11119 
11120  gtk_widget_destroy(GeomDrawingArea);
11121  GeomDrawingArea = NULL;
11122  gtk_widget_destroy(GeomDlg);
11123 
11124  if (cr) cairo_destroy (cr);
11125  cr = NULL;
11126 
11127 
11128  Orig[0] = Orig[1] = Orig[2] = 0.0;
11129 }
11130 /*****************************************************************************/
AddNoteBookPage(GtkWidget * NoteBook,char * label)11131 GtkWidget *AddNoteBookPage(GtkWidget *NoteBook,char *label)
11132 {
11133   GtkWidget *vboxpage;
11134   GtkWidget *Frame;
11135 
11136 
11137   Frame = gtk_frame_new(NULL);
11138   gtk_container_set_border_width(GTK_CONTAINER(Frame), 2);
11139 
11140   gtk_notebook_append_page_menu(GTK_NOTEBOOK(NoteBook),
11141                                 Frame,
11142                                 NULL, NULL);
11143 
11144   g_object_set_data(G_OBJECT (Frame), "Frame", Frame);
11145 
11146   gtk_widget_show(Frame);
11147   vboxpage = create_vbox(Frame);
11148 
11149   return vboxpage;
11150 }
11151 /********************************************************************************/
set_sensitive_stop_button(gboolean sens)11152 void set_sensitive_stop_button(gboolean sens)
11153 {
11154 	if(GeomDrawingArea) gtk_widget_set_sensitive(StopButton, sens);
11155 }
11156 /********************************************************************************************/
stop_calcul(GtkWidget * wi,gpointer data)11157 static void stop_calcul(GtkWidget *wi, gpointer data)
11158 {
11159 	StopCalcul = TRUE;
11160 }
11161 /********************************************************************************/
add_stop_button(GtkWidget * Win,GtkWidget * box)11162 void add_stop_button(GtkWidget *Win, GtkWidget *box)
11163 {
11164   StopButton = gtk_button_new_with_label("Cancel");
11165   gtk_box_pack_start (GTK_BOX (box), StopButton, FALSE, TRUE, 0);
11166   gtk_widget_set_sensitive(StopButton, FALSE);
11167 
11168   g_signal_connect(G_OBJECT(StopButton), "clicked", G_CALLBACK (stop_calcul), NULL);
11169 }
11170 /********************************************************************************/
open_menu(GtkWidget * Win,GdkEvent * event,gpointer Menu)11171 static void open_menu(GtkWidget *Win,  GdkEvent *event, gpointer Menu)
11172 {
11173 	GdkEventButton *bevent;
11174 	bevent = (GdkEventButton *) event;
11175 	popup_menu_geom( bevent->button, bevent->time);
11176 }
11177 /********************************************************************************/
add_menu_button(GtkWidget * Win,GtkWidget * box)11178 static void add_menu_button(GtkWidget *Win, GtkWidget *box)
11179 {
11180 	GtkWidget* menuButton;
11181         menuButton = gtk_button_new_with_label("M");
11182   	gtk_box_pack_start (GTK_BOX (box), menuButton, FALSE, TRUE, 0);
11183 
11184 	g_signal_connect(G_OBJECT(menuButton), "button_press_event",G_CALLBACK(open_menu), NULL);
11185 	gtk_widget_show (menuButton);
11186 }
11187 /********************************************************************************/
draw_geometry(GtkWidget * w,gpointer d)11188 void draw_geometry(GtkWidget *w,gpointer d)
11189 {
11190  if(GeomDrawingArea == NULL)
11191           create_window_drawing();
11192  else
11193 	rafresh_drawing();
11194 }
11195 /*****************************************************************************/
export_geometry(gchar * fileName,gchar * fileType)11196 void export_geometry(gchar* fileName, gchar* fileType)
11197 {
11198 	if(!fileName) return;
11199 	if(!fileType) return;
11200 	if(!GeomDrawingArea) return;
11201 	if(!strcmp(fileType,"pdf"))
11202 	{
11203 
11204 		cairo_surface_t *surface;
11205 		surface = cairo_pdf_surface_create(fileName, GeomDrawingArea->allocation.width, GeomDrawingArea->allocation.height);
11206 		crExport = cairo_create(surface);
11207 		drawGeom();
11208 		cairo_show_page(crExport);
11209 		cairo_surface_destroy(surface);
11210 		cairo_destroy(crExport);
11211 		crExport = NULL;
11212 		return;
11213 	}
11214 	else
11215 	if(!strcmp(fileType,"ps"))
11216 	{
11217 
11218 		cairo_surface_t *surface;
11219 		surface = cairo_ps_surface_create(fileName, GeomDrawingArea->allocation.width, GeomDrawingArea->allocation.height);
11220 		crExport = cairo_create(surface);
11221 		drawGeom();
11222 		cairo_show_page(crExport);
11223 		cairo_surface_destroy(surface);
11224 		cairo_destroy(crExport);
11225 		crExport = NULL;
11226 		return;
11227 	}
11228 	else
11229 	if(!strcmp(fileType,"eps"))
11230 	{
11231 
11232 		cairo_surface_t *surface;
11233 		surface = cairo_ps_surface_create(fileName, GeomDrawingArea->allocation.width, GeomDrawingArea->allocation.height);
11234 		cairo_ps_surface_set_eps(surface, TRUE);
11235 		crExport = cairo_create(surface);
11236 		drawGeom();
11237 		cairo_show_page(crExport);
11238 		cairo_surface_destroy(surface);
11239 		cairo_destroy(crExport);
11240 		crExport = NULL;
11241 		return;
11242 	}
11243 	else
11244 	if(!strcmp(fileType,"svg"))
11245 	{
11246 
11247 		cairo_surface_t *surface;
11248 		surface = cairo_svg_surface_create(fileName, GeomDrawingArea->allocation.width, GeomDrawingArea->allocation.height);
11249 		crExport = cairo_create(surface);
11250 		drawGeom();
11251 		cairo_show_page(crExport);
11252 		cairo_surface_destroy(surface);
11253 		cairo_destroy(crExport);
11254 		crExport = NULL;
11255 		return;
11256 	}
11257 }
11258 /******************************************************************************/
glgeom_rafresh(GtkWidget * widget)11259 gint glgeom_rafresh(GtkWidget *widget)
11260 {
11261 	if(!widget) return FALSE;
11262 	redraw(GeomDrawingArea);
11263 	return TRUE;
11264 }
11265 /******************************************************************************/
rafresh_window_geom()11266 void rafresh_window_geom()
11267 {
11268 	 if(GeomDrawingArea != NULL)
11269 	 {
11270 		RebuildGeom = TRUE;
11271 		copyCoordinates2to1(geometry, geometry0);
11272 		redraw(GeomDrawingArea);
11273 	 }
11274 }
11275 /*********************************************************************************************/
SetLight()11276 static void SetLight()
11277 {
11278 	static float lmodel_ambient[] = {0.1, 0.1, 0.1, 0.1};
11279 	static float lmodel_twoside[] = {GL_TRUE};
11280 	static float lmodel_local[] = {GL_FALSE};
11281 
11282 	static V4d light0_ambient  = {0.5, 0.5, 0.5, 1.0};
11283 	static V4d light0_diffuse  = {1.0, 1.0, 1.0, 0.0};
11284 	static V4d light0_specular = {1.0, 1.0, 1.0, 0.0};
11285 
11286 	static V4d light1_ambient  = {1.0, 1.0, 1.0, 1.0};
11287 	static V4d light1_diffuse  = {1.0, 1.0, 1.0, 0.0};
11288 	static V4d light1_specular = {1.0, 1.0, 1.0, 0.0};
11289 
11290 	static V4d light2_ambient  = {0.1, 0.1, 0.1, 1.0};
11291 	static V4d light2_diffuse  = {1.0, 1.0, 1.0, 0.0};
11292 	static V4d light2_specular = {1.0, 1.0, 1.0, 0.0};
11293 
11294 	glLightdv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
11295 	glLightdv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
11296 	glLightdv(GL_LIGHT0, GL_SPECULAR, light0_specular);
11297 	glLightdv(GL_LIGHT0, GL_POSITION, light0_position);
11298 
11299 	glLightdv(GL_LIGHT1, GL_AMBIENT, light1_ambient);
11300 	glLightdv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);
11301 	glLightdv(GL_LIGHT1, GL_SPECULAR, light1_specular);
11302 	glLightdv(GL_LIGHT1, GL_POSITION, light1_position);
11303 
11304 	glLightdv(GL_LIGHT2, GL_AMBIENT, light2_ambient);
11305 	glLightdv(GL_LIGHT2, GL_DIFFUSE, light2_diffuse);
11306 	glLightdv(GL_LIGHT2, GL_SPECULAR, light2_specular);
11307 	glLightdv(GL_LIGHT2, GL_POSITION, light2_position);
11308 
11309 	glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, lmodel_local);
11310 	glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
11311 	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
11312 	glEnable(GL_LIGHTING);
11313 	glDisable(GL_LIGHT0);
11314 	glDisable(GL_LIGHT1);
11315 	glDisable(GL_LIGHT2);
11316 	if(lightOnOff[0])
11317 		glEnable(GL_LIGHT0);
11318 	if(lightOnOff[1])
11319 		glEnable(GL_LIGHT1);
11320 	if(lightOnOff[2])
11321 		glEnable(GL_LIGHT2);
11322 }
11323 /*********************************************************************************/
11324 /* When widget is exposed it's contents are redrawn. */
draw(GtkWidget * widget,GdkEventExpose * event)11325 static gint draw(GtkWidget *widget, GdkEventExpose *event)
11326 {
11327 	static gint i = 0;
11328 	i++;
11329 	if (!GTK_IS_WIDGET(widget)) return TRUE;
11330 	if(!GTK_WIDGET_REALIZED(widget)) return TRUE;
11331 	/* Draw only last expose. */
11332 	if (event->count > 0) return FALSE;
11333 
11334 	redraw(widget);
11335 
11336 	return FALSE;
11337 }
11338 
11339 /*****************************************************************************/
11340 /* When GLArea widget size changes, viewport size is set to match the new size */
reshape(GtkWidget * widget,GdkEventConfigure * event)11341 static gint reshape(GtkWidget *widget, GdkEventConfigure *event)
11342 {
11343 	GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
11344 	GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);
11345 
11346 	if(!GTK_IS_WIDGET(widget)) return TRUE;
11347 	if(!GTK_WIDGET_REALIZED(widget)) return TRUE;
11348 
11349 	if (gdk_gl_drawable_gl_begin (gldrawable, glcontext))
11350 	{
11351 		/* pthread_mutex_lock (&theRender_mutex);*/
11352 		glViewport(0,0, widget->allocation.width, widget->allocation.height);
11353 		glMatrixMode(GL_PROJECTION);
11354 		glLoadIdentity();
11355 		if(PersMode)
11356 		{
11357 			mYPerspective(Zoom,(GLdouble)widget->allocation.width/(GLdouble)widget->allocation.height,zNear,zFar);
11358 		}
11359 		else
11360 		{
11361 			gdouble fw = (GLdouble)widget->allocation.width/(GLdouble)widget->allocation.height;
11362 			gdouble fh = 1.0;
11363 			glOrtho(-fw,fw,-fh,fh,-1,1);
11364 		}
11365 		glMatrixMode(GL_MODELVIEW);
11366 		glLoadIdentity();
11367 		gdk_gl_drawable_gl_end (gldrawable);
11368 		/* pthread_mutex_unlock (&theRender_mutex);*/
11369 
11370 		gdk_window_invalidate_rect (gtk_widget_get_parent_window (widget), &widget->allocation, TRUE);
11371 		gdk_window_process_updates (gtk_widget_get_parent_window (widget), TRUE);
11372 	}
11373 	return TRUE;
11374 }
11375 /*****************************************************************************/
initGL()11376 static void initGL()
11377 {
11378 
11379 	/* static GLdouble fog_color[4] = { 0.0, 0.0, 0.0, 0.0 };*/
11380  	/* remove back faces */
11381 	glEnable(GL_DEPTH_TEST);
11382 	glDisable(GL_CULL_FACE);
11383 	glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
11384 	/*glEnable(GL_COLOR_MATERIAL);*/
11385     	glEnable(GL_NORMALIZE);
11386 	glShadeModel(GL_SMOOTH);
11387 	SetLight();
11388 	/*
11389 	glInitFontsOld();
11390 	*/
11391 	glInitFonts(&ft2_context);
11392 	/*
11393 	glFogi(GL_FOG_MODE, GL_EXP);
11394 	glFogf(GL_FOG_DENSITY, 0.15);
11395 	glFogdv(GL_FOG_COLOR, fog_color);
11396 	*/
11397 }
11398 /*****************************************************************************/
init(GtkWidget * widget)11399 static gint init(GtkWidget *widget)
11400 {
11401 	GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
11402 	GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);
11403 
11404 	if(!GTK_IS_WIDGET(widget)) return TRUE;
11405 	if(!GTK_WIDGET_REALIZED(widget)) return TRUE;
11406 
11407 	if (gdk_gl_drawable_gl_begin (gldrawable, glcontext))
11408 	{
11409 		glViewport(0,0, widget->allocation.width, widget->allocation.height);
11410 		initGL();
11411 		gdk_window_invalidate_rect (gtk_widget_get_parent_window (widget), &widget->allocation, TRUE);
11412 		/* gdk_window_process_updates (gtk_widget_get_parent_window (widget), TRUE);*/
11413 	}
11414 	return TRUE;
11415 }
11416 /********************************************************************************************/
11417 /* Configure the OpenGL framebuffer.*/
configure_gl()11418 static GdkGLConfig *configure_gl()
11419 {
11420 	GdkGLConfig *glconfig;
11421 	GdkGLConfigMode modedouble = GDK_GL_MODE_RGB    | GDK_GL_MODE_DEPTH  | GDK_GL_MODE_DOUBLE;
11422 	GdkGLConfigMode modesimple = GDK_GL_MODE_RGB    | GDK_GL_MODE_DEPTH;
11423 	GdkGLConfigMode mode = GDK_GL_MODE_RGB;
11424 
11425 	/* Try the user visual */
11426 	if(openGLOptions.rgba !=0)  mode = GDK_GL_MODE_RGBA;
11427 	if(openGLOptions.depthSize!=0) mode |= GDK_GL_MODE_DEPTH;
11428 	if(openGLOptions.alphaSize!=0) mode |= GDK_GL_MODE_ALPHA;
11429 	if(openGLOptions.doubleBuffer!=0) mode |= GDK_GL_MODE_DOUBLE;
11430 	glconfig = gdk_gl_config_new_by_mode (mode);
11431 	if(glconfig!=NULL) return glconfig;
11432 
11433 
11434 	/* Try double-buffered visual */
11435 	glconfig = gdk_gl_config_new_by_mode (modedouble);
11436 	if (glconfig == NULL)
11437 	{
11438       		printf ("\n*** Cannot find the double-buffered visual.\n");
11439       		printf ("\n*** Trying single-buffered visual.\n");
11440 
11441 		/* Try single-buffered visual */
11442 		glconfig = gdk_gl_config_new_by_mode (modesimple);
11443 		if (glconfig == NULL)
11444 		{
11445 	  		printf ("*** No appropriate OpenGL-capable visual found.\n");
11446 	  		exit (1);
11447 		}
11448 	}
11449 	return glconfig;
11450 }
11451 /********************************************************************************************/
NewGeomDrawingArea(GtkWidget * vboxwin,GtkWidget * GeomDlg)11452 static GtkWidget* NewGeomDrawingArea(GtkWidget* vboxwin, GtkWidget* GeomDlg)
11453 {
11454 	GtkWidget* frame;
11455   /*
11456 	gchar *info_str;
11457   */
11458 	GtkWidget* table;
11459 	GtkWidget* hboxtoolbar;
11460 
11461 #define DIMAL 13
11462 	int k = 0;
11463 	GdkGLConfig *glconfig;
11464 
11465 	{
11466 		gint i;
11467 		Zoom = 45;
11468 		/*
11469 		factorstick=1.0;
11470 		factorball=1.0;
11471 		*/
11472 		factordipole=1.0;
11473 		Trans[0]=0;
11474 		Trans[1]=0;
11475 		SetCosSin();
11476 		Ddef = FALSE;
11477 		AtomToInsert = g_strdup("C");
11478 		for(i=0;i<4;i++) NumSelAtoms[i] = -1;
11479 		TypeGeom  = GABEDIT_TYPEGEOM_STICK;
11480 		ShadMode = FALSE;
11481 		PersMode = FALSE;
11482 		LightMode = FALSE;
11483 		OrtepMode = FALSE;
11484 		CartoonMode = TRUE;
11485 		DrawDistance=FALSE;
11486 		DrawDipole = FALSE;
11487 		StopCalcul = FALSE;
11488 		ShowHBonds = FALSE;
11489 		Frag.NAtoms = 0;
11490 		Frag.Atoms = NULL;
11491 		FragItems = NULL;
11492 		NFrags = 0;
11493 		OperationType = ROTATION ;
11494 	}
11495 
11496 	k = 0;
11497 	/*
11498 	if(openGLOptions.alphaSize!=0)
11499 	{
11500 		attrlist[k++] = GDK_GL_ALPHA_SIZE;
11501 		attrlist[k++] = 1;
11502 	}
11503 	if(openGLOptions.depthSize!=0)
11504 	{
11505 		attrlist[k++] = GDK_GL_DEPTH_SIZE;
11506 		attrlist[k++] = 1;
11507 	}
11508 	if(openGLOptions.doubleBuffer!=0) attrlist[k++] = GDK_GL_DOUBLEBUFFER;
11509 	*/
11510 	trackball(Quat , 0.0, 0.0, 0.0, 0.0);
11511 
11512 	frame = gtk_frame_new (NULL);
11513 	gtk_container_set_border_width (GTK_CONTAINER (frame), 0);
11514   	gtk_frame_set_shadow_type( GTK_FRAME(frame),GTK_SHADOW_ETCHED_OUT);
11515 	gtk_box_pack_start (GTK_BOX (vboxwin), frame, TRUE, TRUE, 0);
11516 	gtk_widget_show (frame);
11517 
11518 	table = gtk_table_new(2,2,FALSE);
11519 	gtk_container_add(GTK_CONTAINER(frame),table);
11520 	gtk_widget_show(GTK_WIDGET(table));
11521 	hboxtoolbar = gtk_hbox_new (FALSE, 0);
11522 	gtk_widget_show (hboxtoolbar);
11523 	gtk_table_attach(GTK_TABLE(table), hboxtoolbar,0,1,0,1, (GtkAttachOptions)(GTK_FILL | GTK_SHRINK  ), (GtkAttachOptions)(GTK_FILL | GTK_EXPAND ), 0,0);
11524 
11525 	gtk_quit_add_destroy(1, GTK_OBJECT(GeomDlg));
11526 
11527 	/* Create new OpenGL widget. */
11528 	/* pthread_mutex_init (&theRender_mutex, NULL);*/
11529 	GeomDrawingArea = gtk_drawing_area_new ();
11530 	gtk_drawing_area_size(GTK_DRAWING_AREA(GeomDrawingArea),(gint)(ScreenHeight*0.2),(gint)(ScreenHeight*0.2));
11531 	gtk_table_attach(GTK_TABLE(table),GeomDrawingArea,1,2,0,1, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND  ), (GtkAttachOptions)(GTK_FILL | GTK_EXPAND ), 0,0);
11532 	gtk_widget_show(GTK_WIDGET(GeomDrawingArea));
11533 	/* Events for widget must be set before X Window is created */
11534 	gtk_widget_set_events(GeomDrawingArea,
11535 			GDK_EXPOSURE_MASK|
11536 			GDK_BUTTON_PRESS_MASK|
11537 			GDK_BUTTON_RELEASE_MASK|
11538 			GDK_POINTER_MOTION_MASK|
11539 			GDK_POINTER_MOTION_HINT_MASK |
11540 			GDK_SCROLL_MASK
11541 			);
11542 	/* prepare GL */
11543 	glconfig = configure_gl();
11544 	if (!glconfig) { g_assert_not_reached (); }
11545 	if (!gtk_widget_set_gl_capability (GeomDrawingArea, glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE)) { g_assert_not_reached (); }
11546 
11547 	g_signal_connect(G_OBJECT(GeomDrawingArea), "realize", G_CALLBACK(init), NULL);
11548 	g_signal_connect(G_OBJECT(GeomDrawingArea), "configure_event", G_CALLBACK(reshape), NULL);
11549 	g_signal_connect(G_OBJECT(GeomDrawingArea), "expose_event", G_CALLBACK(draw), NULL);
11550 
11551 
11552 	gtk_widget_realize(GTK_WIDGET(GeomDlg));
11553 	/*
11554 	info_str = gdk_gl_get_info();
11555 	Debug("%s\n",info_str);
11556 	g_free(info_str);
11557 	*/
11558 
11559 	g_signal_connect(G_OBJECT(GeomDrawingArea), "button_press_event",G_CALLBACK(event_dispatcher), NULL);
11560 	g_signal_connect(G_OBJECT(GeomDrawingArea), "motion_notify_event",G_CALLBACK(motion_notify), NULL);
11561 	g_signal_connect(G_OBJECT(GeomDrawingArea), "button_release_event",G_CALLBACK(button_release), NULL);
11562 
11563 
11564 	g_signal_connect(G_OBJECT (GeomDlg), "key_press_event", (GCallback) set_key_press, GeomDlg);
11565 	g_signal_connect(G_OBJECT (GeomDlg), "key_release_event", (GCallback) set_key_release, NULL);
11566 
11567 	return GeomDrawingArea;
11568 }
11569 /*****************************************************************************/
create_window_drawing()11570 void create_window_drawing()
11571 {
11572 	GtkWidget *vboxframe;
11573 	GtkWidget *frame;
11574 	GtkWidget *hboxframe;
11575 	GtkWidget *vbox;
11576 	GtkWidget *hbox;
11577 	GtkWidget *hboxoperation;
11578 	GtkWidget *DrawingArea;
11579 	GtkWidget *vboxleft;
11580 	GtkWidget *vboxright;
11581 	GtkWidget *NoteBook;
11582 	GtkWidget *Table;
11583 	GtkWidget *handelbox;
11584 	GtkWidget *Status;
11585 	GtkWidget *VboxWin;
11586 	GtkWidget *hboxtoolbar;
11587   	GtkWidget* handlebox;
11588   	GtkWidget* table;
11589   	GtkWidget* vboxda;
11590 
11591 	{
11592 		gint i;
11593 		Zoom=45;
11594 		/*
11595 		factorstick=1.0;
11596 		factorball=1.0;
11597 		*/
11598 		factordipole=1.0;
11599 		Trans[0]=0;
11600 		Trans[1]=0;
11601 		SetCosSin();
11602 		Ddef = FALSE;
11603 		AtomToInsert = g_strdup("C");
11604 		for(i=0;i<4;i++) NumSelAtoms[i] = -1;
11605 		TypeGeom  = GABEDIT_TYPEGEOM_STICK;
11606 		ShadMode = FALSE;
11607 		PersMode = FALSE;
11608 		LightMode = FALSE;
11609 		OrtepMode = FALSE;
11610 		CartoonMode = TRUE;
11611 		DrawDistance=FALSE;
11612 		DrawDipole = FALSE;
11613 		StopCalcul = FALSE;
11614 		ShowHBonds = FALSE;
11615 		Frag.NAtoms = 0;
11616 		Frag.Atoms = NULL;
11617 		FragItems = NULL;
11618 		NFrags = 0;
11619 		OperationType = ROTATION ;
11620 		RebuildGeom = TRUE;
11621 	}
11622 
11623 
11624 	geometry = NULL;
11625 	geometry0 = NULL;
11626 	Natoms = 0;
11627 
11628 	NumFatoms = NULL;
11629 	NFatoms = 0;
11630 
11631 	define_geometry();
11632 
11633 	GeomDlg = NULL ;
11634 	GeomDlg = gtk_window_new(GTK_WINDOW_TOPLEVEL);
11635 	VboxWin = gtk_vbox_new (TRUE, 0);
11636 	gtk_container_add(GTK_CONTAINER(GeomDlg),VboxWin);
11637 	gtk_widget_show(VboxWin);
11638 	gtk_window_set_title(GTK_WINDOW(GeomDlg),_("Gabedit : Draw Geometry "));
11639 	gtk_window_set_transient_for(GTK_WINDOW(GeomDlg),GTK_WINDOW(Fenetre));
11640 
11641 	gtk_window_move(GTK_WINDOW(GeomDlg),0,0);
11642 	init_child(GeomDlg,destroy_all_drawing,_(" Draw Geom. "));
11643 	g_signal_connect(G_OBJECT(GeomDlg),"delete_event",(GCallback)destroy_children,NULL);
11644 
11645 	frame = create_frame_in_vbox(NULL,GeomDlg,VboxWin,TRUE);
11646 	gtk_widget_show (frame);
11647 	vboxframe = create_vbox(frame);
11648 	gtk_widget_show (vboxframe);
11649 
11650 	hboxframe = gtk_hbox_new (FALSE, 0);
11651 	gtk_box_pack_start (GTK_BOX (vboxframe), hboxframe, TRUE, TRUE, 0);
11652 	gtk_widget_show (hboxframe);
11653 
11654 
11655 	/* DrawingArea */
11656 	vbox = create_vbox_in_hbox(frame,hboxframe,TRUE);
11657 	frame = create_frame_in_vbox(NULL,GeomDlg,vbox,TRUE);
11658 	hbox = create_hbox_in_vbox(vbox);
11659 	vbox = create_vbox(frame);
11660 	vboxleft= vbox;
11661 
11662 	vbox = create_vbox_in_hbox(frame,hboxframe,FALSE);
11663 	vboxhandle = vbox;
11664 
11665 	handelbox =gtk_handle_box_new ();
11666 	gtk_handle_box_set_shadow_type(GTK_HANDLE_BOX(handelbox),GTK_SHADOW_NONE);
11667 	gtk_handle_box_set_handle_position  (GTK_HANDLE_BOX(handelbox),GTK_POS_TOP);
11668 	gtk_container_add( GTK_CONTAINER (vbox), handelbox);
11669 	gtk_widget_show (handelbox);
11670 	vbox = gtk_vbox_new (FALSE, 0);
11671 	gtk_container_add( GTK_CONTAINER(handelbox), vbox);
11672 	gtk_widget_show (vbox);
11673 
11674 	vboxright= vbox;
11675 	vbox = vboxleft;
11676 
11677 	/* The Table */
11678 	Table = gtk_table_new(1, 2, FALSE);
11679 	gtk_container_add(GTK_CONTAINER(vbox), Table);
11680 	gtk_widget_show(Table);
11681 
11682 	vboxda = gtk_vbox_new (FALSE, 0);
11683 	gtk_table_attach(GTK_TABLE(Table), vboxda, 1,2, 0,1, GTK_EXPAND|GTK_FILL , GTK_EXPAND |GTK_FILL, 0, 0);
11684 	gtk_widget_show(vboxda);
11685 	DrawingArea = NewGeomDrawingArea(vboxda, GeomDlg);
11686 	gtk_widget_set_size_request(GTK_WIDGET(DrawingArea ),(gint)(ScreenHeight*0.5),(gint)(ScreenHeight*0.5));
11687 
11688 	GeomDrawingArea = DrawingArea;
11689 	g_signal_connect(G_OBJECT(GeomDrawingArea),"configure_event", (GCallback)configure_event,NULL);
11690 
11691 /*
11692 	hboxtoolbar = gtk_hbox_new (FALSE, 0);
11693 	gtk_table_attach(GTK_TABLE(Table), hboxtoolbar, 0,1, 0,1, GTK_FILL , GTK_SHRINK |GTK_FILL, 0, 0);
11694 	gtk_widget_show(hboxtoolbar);
11695 */
11696 
11697 	vbox = gtk_vbox_new (FALSE, 0);
11698 	gtk_table_attach(GTK_TABLE(Table), vbox, 0,1, 0,1, GTK_FILL , GTK_FILL, 0, 0);
11699 	gtk_widget_show(vbox);
11700 	add_menu_button(GeomDlg, vbox);
11701 	hboxtoolbar = gtk_hbox_new (FALSE, 0);
11702   	gtk_box_pack_start (GTK_BOX (vbox), hboxtoolbar, TRUE, TRUE, 0);
11703 	gtk_widget_show(hboxtoolbar);
11704 
11705 	gtk_widget_set_events (GeomDrawingArea, GDK_EXPOSURE_MASK
11706 					| GDK_LEAVE_NOTIFY_MASK
11707 					| GDK_CONTROL_MASK
11708 					| GDK_BUTTON_PRESS_MASK
11709 					| GDK_BUTTON_RELEASE_MASK
11710 					| GDK_POINTER_MOTION_MASK
11711 					| GDK_POINTER_MOTION_HINT_MASK);
11712 
11713 
11714 	gtk_widget_realize(GeomDlg);
11715 
11716 	NoteBook = gtk_notebook_new();
11717 	gtk_notebook_set_show_tabs(GTK_NOTEBOOK(NoteBook), FALSE);
11718 	gtk_notebook_set_show_border(GTK_NOTEBOOK(NoteBook), FALSE);
11719 
11720 	NoteBookDraw = NoteBook;
11721 	gtk_box_pack_start(GTK_BOX (vboxright), NoteBook,TRUE, TRUE, 0);
11722 
11723 	vboxmeasure =AddNoteBookPage(NoteBook,_("Measure"));
11724 
11725 
11726 	AddMeasure(GeomDlg,vboxmeasure);
11727 	gtk_widget_show(NoteBook);
11728 	gtk_widget_show_all(vboxmeasure);
11729 	change_of_center(NULL,NULL);
11730 	gtk_widget_show(vboxright);
11731 
11732 
11733   	handlebox = gtk_handle_box_new ();
11734   	gtk_handle_box_set_shadow_type(GTK_HANDLE_BOX(handlebox),GTK_SHADOW_NONE);
11735 	gtk_handle_box_set_handle_position  (GTK_HANDLE_BOX(handlebox),GTK_POS_LEFT);
11736   	gtk_widget_show (handlebox);
11737 	gtk_box_pack_start(GTK_BOX (hbox), handlebox,TRUE, TRUE, 0);
11738 
11739 	table = gtk_table_new(2,2,FALSE);
11740 	gtk_container_add (GTK_CONTAINER (handlebox), table);
11741 	gtk_widget_show(table);
11742 	/* Rotation Status */
11743 	Status = gtk_statusbar_new();
11744 	gtk_table_attach(GTK_TABLE(table),Status,0,1,0,1,
11745 					(GtkAttachOptions)(GTK_FILL | GTK_EXPAND),
11746 					(GtkAttachOptions)(GTK_FILL | GTK_EXPAND),
11747 					1,1);
11748 	idStatusRotation = gtk_statusbar_get_context_id(GTK_STATUSBAR(Status),_("Rotation"));
11749 	StatusRotation = Status;
11750 	gtk_statusbar_pop(GTK_STATUSBAR(StatusRotation),idStatusRotation);
11751 	gtk_statusbar_push(GTK_STATUSBAR(StatusRotation),idStatusRotation,
11752 		_(" Press the Middle mouse button and move your mouse for a \"Rotation\". "));
11753 
11754 
11755 	/* Mode Status */
11756 	Status = gtk_statusbar_new();
11757 	gtk_table_attach(GTK_TABLE(table),Status,1,2,0,1,
11758 					(GtkAttachOptions)(GTK_FILL | GTK_EXPAND),
11759 					(GtkAttachOptions)(GTK_FILL | GTK_EXPAND),
11760 					1,1);
11761 	idStatusPopup= gtk_statusbar_get_context_id(GTK_STATUSBAR(Status),"Ball&Stick");
11762 	StatusPopup = Status;
11763 	gtk_statusbar_pop(GTK_STATUSBAR(StatusPopup),idStatusPopup);
11764 	gtk_statusbar_push(GTK_STATUSBAR(StatusPopup),idStatusPopup,
11765 		_(" Press the Right mouse button for display the popup menu. "));
11766 
11767 	/* Operation Status */
11768 	Status = gtk_statusbar_new();
11769 	hboxoperation = gtk_hbox_new (FALSE, 0);
11770 	gtk_table_attach(GTK_TABLE(table), hboxoperation,0,2,1,2,
11771 					(GtkAttachOptions)(GTK_FILL | GTK_EXPAND),
11772 					(GtkAttachOptions)(GTK_FILL | GTK_EXPAND),
11773 					1,1);
11774 	gtk_box_pack_start (GTK_BOX(hboxoperation),Status, TRUE, TRUE, 1);
11775 
11776 	idStatusOperation = gtk_statusbar_get_context_id(GTK_STATUSBAR(Status),_("Rotation"));
11777 	StatusOperation = Status;
11778 	gtk_statusbar_pop(GTK_STATUSBAR(StatusOperation),idStatusOperation);
11779 	gtk_statusbar_push(GTK_STATUSBAR(StatusOperation),idStatusOperation,
11780 		_(" Press the Left mouse button and move your mouse for a \"Rotation\". "));
11781 
11782 	add_stop_button(GeomDlg, hboxoperation);
11783 	gtk_widget_show_all(hbox);
11784 	gtk_widget_show_all(hboxoperation);
11785 	gtk_widget_show_all(vbox);
11786 
11787 
11788 	gtk_widget_show(frame);
11789 
11790 	if(MeasureIsHide)
11791 	{
11792   		gtk_widget_hide(vboxhandle);
11793 	}
11794 	else
11795 		gtk_widget_show(vboxhandle);
11796 
11797 	gtk_window_set_default_size (GTK_WINDOW(GeomDlg), (gint)(ScreenHeight*0.85), (gint)(ScreenHeight*0.85));
11798 
11799 
11800 	g_object_set_data(G_OBJECT(GeomDlg), "StatusBox",handlebox);
11801 	create_toolbar_and_popup_menu_geom(hboxtoolbar);
11802 
11803 
11804 	/* Evenments */
11805 	g_signal_connect(G_OBJECT(GeomDrawingArea),"expose_event",(GCallback)expose_event,NULL);
11806 	g_signal_connect(G_OBJECT(GeomDrawingArea), "button_press_event",G_CALLBACK(event_dispatcher), NULL);
11807 	g_signal_connect(G_OBJECT(GeomDrawingArea), "motion_notify_event",G_CALLBACK(motion_notify), NULL);
11808 	g_signal_connect(G_OBJECT(GeomDrawingArea), "button_release_event",G_CALLBACK(button_release), NULL);
11809 	g_signal_connect(G_OBJECT (GeomDlg), "key_press_event", (GCallback) set_key_press, GeomDlg);
11810 	g_signal_connect(G_OBJECT (GeomDlg), "key_release_event", (GCallback) set_key_release, NULL);
11811 	gtk_widget_show(GeomDlg);
11812 
11813 	gtk_window_move(GTK_WINDOW(GeomDlg),0,0);
11814 
11815 
11816 	/* set_back_color_black();*/
11817 	/* set_back_color_grey();*/
11818 	set_back_color_default();
11819 	set_icone(GeomDlg);
11820 	/*if(Natoms == 0) SetOperation(NULL,EDITOBJECTS);*/
11821 	/*define_good_trans();*/
11822 	setSymmetryPrecision(GeomDlg, "1e-4");
11823 }
11824 #endif /* DRAWGEOMGL*/
11825