1 /* DrawGeom.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 #ifndef DRAWGEOMGL
22 #include "../../Config.h"
23 #include <stdlib.h>
24 #include <math.h>
25 #include <ctype.h>
26 #include <cairo-pdf.h>
27 #include <cairo-ps.h>
28 #include <cairo-svg.h>
29 
30 #include "../Common/Global.h"
31 #include "../Utils/Constants.h"
32 #include "../Utils/UtilsInterface.h"
33 #include "../Geometry/InterfaceGeom.h"
34 #include "../Utils/Utils.h"
35 #include "../Utils/PovrayUtils.h"
36 #include "../Utils/AtomsProp.h"
37 #include "../Geometry/GeomGlobal.h"
38 #include "../Geometry/Measure.h"
39 #include "../Geometry/Povray.h"
40 #include "../Common/Windows.h"
41 #include "../Utils/Transformation.h"
42 #include "../Geometry/GeomXYZ.h"
43 #include "../Geometry/GeomZmatrix.h"
44 #include "../Geometry/GeomSymmetry.h"
45 #include "../Files/FileChooser.h"
46 #include "../Geometry/ImagesGeom.h"
47 #include "../Geometry/Fragments.h"
48 #include "../Geometry/FragmentsPPD.h"
49 #include "../Geometry/DrawGeom.h"
50 #include "../Geometry/RotFragments.h"
51 #include "../Geometry/GeomConversion.h"
52 #include "../Geometry/PersonalFragments.h"
53 #include "../Geometry/ResultsAnalise.h"
54 #include "../Utils/HydrogenBond.h"
55 #include "../MolecularMechanics/PDBTemplate.h"
56 #include "../MolecularMechanics/CalculTypesAmber.h"
57 #include "../Symmetry/MoleculeSymmetryInterface.h"
58 #include "../Utils/Jacobi.h"
59 #include "../Utils/Vector3d.h"
60 #include "../Utils/GabeditTextEdit.h"
61 #include "../Utils/UtilsCairo.h"
62 #include "../Geometry/MenuToolBarGeom.h"
63 #include "../Geometry/PreviewGeom.h"
64 #include "../Geometry/FragmentsSelector.h"
65 #include "../Geometry/SelectionDlg.h"
66 #include "../IsotopeDistribution/IsotopeDistributionCalculatorDlg.h"
67 #include "../Geometry/TreeMolecule.h"
68 #include "../Geometry/BuildCrystal.h"
69 
70 
71 /********************************************************************************/
72 #define MAT 30
73 #define SCALE(i) (i / 65535.)
74 /********************************************************************************/
75 
76 static gdouble Quat[4] = {0.0,0.0,0.0,1.0};
77 static gdouble QuatFrag[4] = {0.0,0.0,0.0,1.0};
78 static gdouble QuatAtom[4] = {0.0,0.0,0.0,1.0};
79 static gdouble Orig[3] = {0.0,0.0,0.0};
80 static gdouble BeginX = 0;
81 static gdouble BeginY = 0;
82 static Camera camera = { 10,5};
83 
84 static gdouble CSselectedAtom[3] = {0.0,0.0,0.0};
85 static gint NumSelectedAtom = -1;
86 static gint NumProcheAtom = -1;
87 static gboolean ButtonPressed = FALSE;
88 static gboolean ShiftKeyPressed = FALSE;
89 static gboolean ControlKeyPressed = FALSE;
90 static gboolean FKeyPressed = FALSE;
91 static gboolean GKeyPressed = FALSE;
92 
93 gchar* strToDraw = NULL;
94 
95 static gdouble minDistanceH = 1.50; /* in Agnstrom */
96 static gdouble maxDistanceH = 3.15; /* in Agnstrom */
97 static gdouble minAngleH = 145.0;
98 static gdouble maxAngleH = 215.0;
99 
100 static gboolean showMultipleBonds = TRUE;
101 static gboolean CartoonMode = TRUE;
102 static gboolean ShowHydrogenAtoms = TRUE;
103 static gboolean AdjustHydrogenAtoms = TRUE;
104 static gboolean RebuildConnectionsDuringEdition = FALSE;
105 
106 static gint NumBatoms[2] = {-1,-1};
107 static gint NBatoms = 0;
108 
109 static gint atomToDelete = -1;
110 static gint atomToBondTo = -1;
111 static gint angleTo = -1;
112 static gdouble fragAngle = 180.0;
113 
114 static gdouble factor = 1.0;
115 static gdouble factorstick = 1.0;
116 static gdouble factorball = 1.0;
117 static gdouble factordipole = 1.0;
118 
119 static gboolean buttonpress = FALSE;
120 
121 static GabEditTypeGeom TypeGeom = GABEDIT_TYPEGEOM_STICK;
122 
123 /********************************************************************************/
124 void set_statubar_pop_sel_atom();
125 void calcul_ndipole();
126 void redefine_dipole();
127 void drawGeom_dipole();
128 GtkWidget *AddNoteBookPage(GtkWidget *NoteBook,char *label);
129 void drawGeom();
130 void destroy_all_drawing(GtkWidget *win);
131 void ActivateButtonOperation (GtkWidget *widget, guint data);
132 void delete_selected_atoms();
133 void delete_selected_bond();
134 void change_selected_bond();
135 void add_bond();
136 gint unselected_atom(GdkEventButton *bevent);
137 static gint insert_atom(GdkEventButton *event);
138 static gint insert_fragment(GtkWidget *widget,GdkEvent *event);
139 void define_good_factor();
140 void set_optimal_geom_view();
141 void define_coefs_pers();
142 gboolean if_selected(gint Num);
143 gint index_selected(gint Num);
144 void sort_with_zaxis();
145 void define_geometry();
146 void buildRotation();
147 void deleteHydrogensConnectedTo(gint n, gint nH);
148 void delete_one_atom(gint NumDel);
149 static gint replace_atom();
150 /********************************************************************************/
151 static  GdkGC* gc=NULL;
152 static	GdkColor* BackColor=NULL;
153 static GdkPixmap *pixmap = NULL;
154 static cairo_t *cr = NULL;
155 static 	GtkWidget *NoteBookDraw;
156 static	GtkWidget *vboxmeasure;
157 static gdouble TCOS[91],TSIN[91];
158 static gdouble CenterCoor[2];
159 static GtkWidget *vboxhandle;
160 static GtkWidget *StatusRotation = NULL;
161 static GtkWidget *StatusPopup = NULL;
162 static GtkWidget *StatusOperation = NULL;
163 static guint idStatusRotation = 0;
164 static guint idStatusPopup = 0;
165 static guint idStatusOperation = 0;
166 static GabEditGeomOperation OperationType = ROTATION;
167 static GabEditSelectType SelectType = RECTANGLE;
168 guint LabelOption = LABELNO;
169 
170 static Fragment Frag = {0,NULL};
171 static cairo_t *crExport = NULL;
172 static GList* fifoGeometries = NULL;
173 static GList* currentFifoGeometries = NULL;
174 static gboolean oldNext = FALSE;
175 
176 /**********************************************************************************/
177 static void stop_calcul(GtkWidget *wi, gpointer data);
178 void delete_all_selected_atoms();
179 static void reset_connections_between_selected_atoms();
180 static void reset_connections_between_selected_and_notselected_atoms();
181 /*********************************************************************************************/
testShowBoxGeom()182 gboolean testShowBoxGeom()
183 {
184         return FALSE;
185 }
186 /*********************************************************************************************/
getQuatGeom(gdouble q[])187 void getQuatGeom(gdouble q[])
188 {
189 	gint i;
190 	/*for(i=0;i<4;i++) q[i] = Quat[i];*/
191 	for(i=0;i<4;i++) q[i] = 0.0;
192 }
193 /*********************************************************************************************/
reset_origine_molecule_drawgeom()194 void  reset_origine_molecule_drawgeom()
195 {
196 	Orig[0] = 0.0;
197 	Orig[1] = 0.0;
198 	Orig[2] = 0.0;
199 }
200 /*********************************************************************************************/
get_origine_molecule_drawgeom(gdouble orig[])201 void  get_origine_molecule_drawgeom(gdouble orig[])
202 {
203 	orig[0] = Orig[0];
204 	orig[1] = Orig[1];
205 	orig[2] = Orig[2];
206 }
207 /*********************************************************************************************/
get_symprec_from_geomdlg()208 gdouble  get_symprec_from_geomdlg()
209 {
210 	gdouble symprec = 1e-4;
211 	gchar* tmp = g_object_get_data(G_OBJECT(GeomDlg), "SymPrecision");
212 	if(tmp) symprec = atof(tmp);
213 	return symprec;
214 }
215 /**********************************************************************************/
getFormulaOfTheMolecule()216 static gchar* getFormulaOfTheMolecule()
217 {
218 	gint i,j;
219 	gchar* formula = NULL;
220 	gchar* dum = NULL;
221 	gint *tag = NULL;
222 	if(Natoms<1) return formula;
223 	tag = g_malloc(Natoms*sizeof(gint));
224 	if(!tag) return formula;
225         for(i=0;i<Natoms;i++) tag[i] = 1;
226 
227         for(i=0;i<Natoms-1;i++)
228 	{
229 		if(tag[i]<=0) continue;
230         	for(j=i+1;j<Natoms;j++)
231 			if(!strcmp(geometry0[i].Prop.symbol,geometry0[j].Prop.symbol))
232 			{
233 				tag[i]++;
234 				tag[j]--;
235 			}
236 	}
237 	formula = g_strdup("");
238         for(i=0;i<Natoms;i++)
239 	{
240 		if(tag[i]<=0) continue;
241 		dum = formula;
242 		formula = g_strdup_printf("%s%s%d",formula,geometry0[i].Prop.symbol,tag[i]);
243 		g_free(dum);
244 	}
245 	if(tag) g_free(tag);
246 	if(formula && strlen(formula)<1)
247 	{
248 		g_free(formula);
249 		formula = NULL;
250 		return formula;
251 
252 	}
253 	return formula;
254 }
255 /**********************************************************************************/
createIstopeDistributionCalculationFromDrawGeom()256 void createIstopeDistributionCalculationFromDrawGeom()
257 {
258 	gchar* formula = getFormulaOfTheMolecule();
259 	compute_distribution_dlg(Fenetre, formula);
260 }
261 /*********************************************************************************************/
copy_screen_geom_clipboard()262 void  copy_screen_geom_clipboard()
263 {
264 	 while( gtk_events_pending() ) gtk_main_iteration();
265 	gabedit_save_image(GeomDrawingArea, NULL, NULL);
266 }
267 /*********************************************************************************************/
get_orgin_molecule_drawgeom(gdouble orig[])268 void  get_orgin_molecule_drawgeom(gdouble orig[])
269 {
270 	gdouble Rmax, Cmax;
271 	orig[0] = 0;
272 	orig[1] = 0;
273 	orig[2] = 0.0;
274 
275 	Rmax = GeomDrawingArea->allocation.width;
276 	if(Rmax<GeomDrawingArea->allocation.height) Rmax = GeomDrawingArea->allocation.height;
277 
278 	if(PersMode) Cmax  = coordmaxmin.Cmax*camera.f/(camera.position);
279 	else Cmax = coordmaxmin.Cmax;
280 	orig[0] = TransX *2*Cmax/factor/Rmax;
281 	orig[1] = -TransY *2*Cmax/factor/Rmax;
282 }
283 /*********************************************************************************************/
get_camera_values_drawgeom(gdouble * zn,gdouble * zf,gdouble * angle,gdouble * aspect,gboolean * persp)284 void  get_camera_values_drawgeom(gdouble* zn, gdouble* zf, gdouble* angle, gdouble* aspect, gboolean* persp)
285 {
286 	gdouble width = 500;
287 	gdouble height = 500;
288 
289 	if(GeomDrawingArea)
290 	{
291 		width =  GeomDrawingArea->allocation.width;
292 		height = GeomDrawingArea->allocation.height;
293 	}
294 	*aspect = width/height;
295 	if(PersMode)
296 	{
297 		*zf = camera.position;
298 		*zn = camera.f;
299 		*angle = 45.0*1.2/factor;
300 		if(*angle>=180) *angle = 160;
301 	}
302 	else
303 	{
304 		gdouble Cmax = coordmaxmin.Cmax;
305 		gdouble Rmax = GeomDrawingArea->allocation.width;
306 
307 		if(Rmax<GeomDrawingArea->allocation.height) Rmax = GeomDrawingArea->allocation.height;
308 		*zf = Cmax*Rmax;
309 		*zn = 10;
310 		*angle = *aspect/factor*45*36*(Cmax/Rmax);
311 		if(*angle>=180) *angle = 160;
312 	}
313 	*persp = PersMode;
314 }
315 /**********************************************************************************/
free_geometries_from_current_to_end()316 static void free_geometries_from_current_to_end()
317 {
318 	if( !fifoGeometries) return;
319 	if( !currentFifoGeometries) return;
320 	if( g_list_last(fifoGeometries) == currentFifoGeometries) return;
321 	if( fifoGeometries && currentFifoGeometries)
322 	{
323 		GList* list;
324 		if(currentFifoGeometries)
325 		for(list=currentFifoGeometries;list!=NULL;list=list->next)
326 		{
327 			GeomDraw* geom = NULL;
328 			geom = (GeomDraw*)list->data;
329 			if(geom && geom->atoms ) Free_One_Geom(geom->atoms,geom->nAtoms);
330 			list->data = NULL;
331 		}
332 		if(currentFifoGeometries->prev)
333 			currentFifoGeometries->prev->next = NULL;
334 		else fifoGeometries = NULL;
335 		g_list_free(currentFifoGeometries);
336 		currentFifoGeometries = g_list_last(fifoGeometries);
337 	}
338 }
339 /**********************************************************************************/
add_geometry_to_fifo()340 void add_geometry_to_fifo()
341 {
342 	gint i,j;
343 	GeomDraw* geom = g_malloc(sizeof(GeomDraw));
344 	geom->nAtoms = Natoms;
345 	if(Natoms>0) geom->atoms = g_malloc(Natoms*sizeof(GeomDef));
346 	else geom->atoms = NULL;
347         for(i=0;i<Natoms;i++)
348 	{
349 		geom->atoms[i].X = geometry0[i].X;
350 		geom->atoms[i].Y = geometry0[i].Y;
351 		geom->atoms[i].Z = geometry0[i].Z;
352 		geom->atoms[i].Xi = geometry0[i].Xi;
353 		geom->atoms[i].Yi = geometry0[i].Yi;
354 		geom->atoms[i].Prop = prop_atom_get(geometry0[i].Prop.symbol);
355 		geom->atoms[i].mmType = g_strdup(geometry0[i].mmType);
356 		geom->atoms[i].pdbType = g_strdup(geometry0[i].pdbType);
357 		geom->atoms[i].Residue = g_strdup(geometry0[i].Residue);
358 		geom->atoms[i].ResidueNumber = geometry0[i].ResidueNumber;
359 		geom->atoms[i].show = geometry0[i].show;
360 		geom->atoms[i].Charge = geometry0[i].Charge;
361 		geom->atoms[i].Layer = geometry0[i].Layer;
362 		geom->atoms[i].N = geometry0[i].N;
363 		geom->atoms[i].Variable = geometry0[i].Variable;
364 		geom->atoms[i].ColorAlloc = geometry0[i].ColorAlloc;
365 		geom->atoms[i].Rayon = geometry0[i].Rayon;
366 		geom->atoms[i].Coefpers = geometry0[i].Coefpers;
367 		if(geometry0[i].typeConnections)
368 		{
369 			geom->atoms[i].typeConnections = g_malloc(Natoms*sizeof(gint));
370 			for(j=0;j<Natoms;j++)
371 				geom->atoms[i].typeConnections[j] = geometry0[i].typeConnections[j];
372 		}
373 		else geom->atoms[i].typeConnections = NULL;
374 	}
375 	free_geometries_from_current_to_end();
376 	fifoGeometries = g_list_append(fifoGeometries,geom);
377 	currentFifoGeometries = g_list_last(fifoGeometries);
378 	oldNext = FALSE;
379 }
380 /**********************************************************************************/
get_geometry_from_fifo(gboolean toNext)381 void get_geometry_from_fifo(gboolean toNext)
382 {
383 	gint i,j;
384 	GeomDraw* geom = NULL;
385 	GList* list = NULL;
386 	if(!fifoGeometries) return;
387 	if(!currentFifoGeometries) return;
388 	if(toNext)
389 	{
390 		GList* last = g_list_last(fifoGeometries);
391 		if(currentFifoGeometries == last) return;
392 		list = g_list_next(currentFifoGeometries);
393 		currentFifoGeometries  = list;
394 		oldNext = TRUE;
395 
396 	}
397 	else
398 	{
399 		if( !oldNext && currentFifoGeometries == g_list_last(fifoGeometries))
400 		{
401 			add_geometry_to_fifo();
402 		}
403 		if(g_list_previous(currentFifoGeometries))
404 			currentFifoGeometries = g_list_previous(currentFifoGeometries);
405 		list = currentFifoGeometries;
406 		oldNext = FALSE;
407 	}
408 	geom = (GeomDraw*)list->data;
409 	if(!geom) return;
410 	geometry0 = Free_One_Geom(geometry0,Natoms);
411 	geometry = Free_One_Geom(geometry,Natoms);
412 	Natoms = geom->nAtoms;
413 	if(Natoms>0)
414 	{
415 		geometry0 = g_malloc(Natoms*sizeof(GeomDef));
416 		geometry = g_malloc(Natoms*sizeof(GeomDef));
417 	}
418         for(i=0;i<Natoms;i++)
419 	{
420 		geometry0[i].X = geom->atoms[i].X;
421 		geometry0[i].Y = geom->atoms[i].Y;
422 		geometry0[i].Z = geom->atoms[i].Z;
423 		geometry0[i].Xi = geom->atoms[i].Xi;
424 		geometry0[i].Yi = geom->atoms[i].Yi;
425 		geometry0[i].Prop = prop_atom_get(geom->atoms[i].Prop.symbol);
426 		geometry0[i].mmType = g_strdup(geom->atoms[i].mmType);
427 		geometry0[i].pdbType = g_strdup(geom->atoms[i].pdbType);
428 		geometry0[i].Residue = g_strdup(geom->atoms[i].Residue);
429 		geometry0[i].ResidueNumber = geom->atoms[i].ResidueNumber;
430 		geometry0[i].show = geom->atoms[i].show;
431 		geometry0[i].Charge = geom->atoms[i].Charge;
432 		geometry0[i].Layer = geom->atoms[i].Layer;
433 		geometry0[i].N = geom->atoms[i].N;
434 		geometry0[i].Variable = geom->atoms[i].Variable;
435 		geometry0[i].ColorAlloc = geom->atoms[i].ColorAlloc;
436 		geometry0[i].Rayon = geom->atoms[i].Rayon;
437 		geometry0[i].Coefpers = geom->atoms[i].Coefpers;
438 		if(geom->atoms[i].typeConnections)
439 		{
440 			geometry0[i].typeConnections = g_malloc(Natoms*sizeof(gint));
441 			for(j=0;j<Natoms;j++)
442 				geometry0[i].typeConnections[j] = geom->atoms[i].typeConnections[j];
443 		}
444 		else
445 		{
446 			geometry0[i].typeConnections = NULL;
447 		}
448 	}
449         for(i=0;i<Natoms;i++)
450 	{
451 		geometry[i].X = geom->atoms[i].X;
452 		geometry[i].Y = geom->atoms[i].Y;
453 		geometry[i].Z = geom->atoms[i].Z;
454 		geometry[i].Xi = geom->atoms[i].Xi;
455 		geometry[i].Yi = geom->atoms[i].Yi;
456 		geometry[i].Prop = prop_atom_get(geom->atoms[i].Prop.symbol);
457 		geometry[i].mmType = g_strdup(geom->atoms[i].mmType);
458 		geometry[i].pdbType = g_strdup(geom->atoms[i].pdbType);
459 		geometry[i].Residue = g_strdup(geom->atoms[i].Residue);
460 		geometry[i].ResidueNumber = geom->atoms[i].ResidueNumber;
461 		geometry[i].show = geom->atoms[i].show;
462 		geometry[i].Charge = geom->atoms[i].Charge;
463 		geometry[i].Layer = geom->atoms[i].Layer;
464 		geometry[i].N = geom->atoms[i].N;
465 		geometry[i].Variable = geom->atoms[i].Variable;
466 		geometry[i].ColorAlloc = geom->atoms[i].ColorAlloc;
467 		geometry[i].Rayon = geom->atoms[i].Rayon;
468 		geometry[i].Coefpers = geom->atoms[i].Coefpers;
469 		if(geom->atoms[i].typeConnections)
470 		{
471 			geometry[i].typeConnections = g_malloc(Natoms*sizeof(gint));
472 			for(j=0;j<Natoms;j++)
473 				geometry[i].typeConnections[j] = geom->atoms[i].typeConnections[j];
474 		}
475 		else
476 		{
477 			geometry[i].typeConnections = NULL;
478 		}
479 	}
480 	/* if(!fifoGeometries) printf("fifoGeometries is void\n");*/
481 	change_of_center(NULL,NULL);
482 	create_GeomXYZ_from_draw_grometry();
483 }
484 /**********************************************************************************/
get_indice(gint n)485 static gint get_indice(gint n)
486 {
487 	gint i;
488 	if(n<0) return n;
489 	for(i=0;i<(gint)Natoms;i++)
490 		if(geometry[i].N==n)return i;
491 	return -1;
492 }
493 /*****************************************************************************/
get_epaisseur()494 static gushort get_epaisseur()
495 {
496         gushort e;
497 	if(Natoms>0) e = (gushort)(7.0/1200*GeomDrawingArea->allocation.width*factorstick);
498 	else e = 3;
499 	if(e<3) e = 3;
500 	return e;
501 }
502 /*****************************************************************************/
get_rayon(gint i)503 static gushort get_rayon(gint i)
504 {
505         gushort rayon;
506         if ( !stick_mode() && geometry[i].Layer != LOW_LAYER )
507         {
508                 rayon =(gushort)(0.8*geometry[i].Rayon*factorball);
509     		if (PersMode) rayon =(gushort)(geometry[i].Coefpers*geometry[i].Rayon*factorball);
510 		if(geometry[i].Layer == LOW_LAYER) rayon /= 6;
511 		if(geometry[i].Layer == MEDIUM_LAYER) rayon /= 2;
512 	}
513 	else rayon = get_epaisseur();
514 	if(rayon<5) rayon = 5;
515 	return rayon;
516 }
517 /**********************************************************************************/
create_drawmolecule_file()518 void create_drawmolecule_file()
519 {
520 	gchar *drawMolecule;
521 	FILE *fd;
522 
523 	drawMolecule = g_strdup_printf("%s%sdrawmolecule",gabedit_directory(),G_DIR_SEPARATOR_S);
524 
525 	fd = FOpen(drawMolecule, "w");
526 	if(fd !=NULL)
527 	{
528 		if(BackColor) fprintf(fd,"%d %d %d\n",BackColor->red, BackColor->green, BackColor->blue);
529 		else fprintf(fd,"0 0 0\n");
530 		fprintf(fd,"%d\n",AdjustHydrogenAtoms);
531 		fprintf(fd,"%d\n",RebuildConnectionsDuringEdition);
532 		fprintf(fd,"%f\n",fragAngle);
533 		fprintf(fd,"%f\n",factorstick);
534 		fprintf(fd,"%f\n",factorball);
535 		fclose(fd);
536 	}
537 	g_free(drawMolecule);
538 }
539 /*************************************************************************************/
read_drawmolecule_file()540 void read_drawmolecule_file()
541 {
542 	gchar *drawMolecule;
543 	FILE *fd;
544 	gint r = 0;
545 	gint g = 0;
546 	gint b = 0;
547 	gint sh = 1;
548 	gint rc = 0;
549 
550 	drawMolecule = g_strdup_printf("%s%sdrawmolecule",gabedit_directory(),G_DIR_SEPARATOR_S);
551 	fragAngle = 180;
552 	factor_stick_default(NULL,NULL);
553 	factor_ball_default(NULL,NULL);
554 
555 	fd = fopen(drawMolecule, "rb");
556 	if(fd !=NULL)
557 	{
558  		guint taille = BSIZE;
559  		gchar t[BSIZE];
560  		if(fgets(t,taille,fd))
561 			if(sscanf(t,"%d %d %d",&r, &g, &b)!=3)
562 			{
563 				printf("t=%s\n",t);
564 				r = 0;
565 				g = 0;
566 				b = 0;
567 			}
568  		if(fgets(t,taille,fd))
569 			if(sscanf(t,"%d",&sh)!=1) sh = 1;
570  		if(fgets(t,taille,fd))
571 			if(sscanf(t,"%d",&rc)!=1) rc = 0;
572  		if(fgets(t,taille,fd))
573 			if(sscanf(t,"%lf",&fragAngle)!=1) fragAngle = 180;
574  		if(fgets(t,taille,fd))
575 			if(sscanf(t,"%lf",&factorstick)!=1) factor_stick_default(NULL,NULL);
576  		if(fgets(t,taille,fd))
577 			if(sscanf(t,"%lf",&factorball)!=1) factor_ball_default(NULL,NULL);
578 
579 		fclose(fd);
580 	}
581 	g_free(drawMolecule);
582 	if(r==0 && g == 0 && b == 0) r = g = b = 20000;
583 	{
584 		BackColor = g_malloc(sizeof(GdkColor));
585 		BackColor->red = r;
586 		BackColor->green = g;
587 		BackColor->blue = b;
588 
589 	}
590 	AdjustHydrogenAtoms = (gboolean)sh;
591 	RebuildConnectionsDuringEdition = (gboolean)rc;
592 }
593 /*************************************************************************************/
copyGeometry(GeomDef * geom0)594 GeomDef* copyGeometry(GeomDef* geom0)
595 {
596 	gint i;
597 	GeomDef* geom = NULL;
598 	if(Natoms<1) return geom;
599 	geom =g_malloc(Natoms*sizeof(GeomDef));
600 	for(i=0;i<Natoms;i++)
601 	{
602 		geom[i].X = geom0[i].X;
603 		geom[i].Y = geom0[i].Y;
604 		geom[i].Z = geom0[i].Z;
605 		geom[i].N = geom0[i].N;
606         	geom[i].typeConnections = NULL;
607 		geom[i].Prop = prop_atom_get(geom0[i].Prop.symbol);
608 		geom[i].mmType = g_strdup(geom0[i].mmType);
609 		geom[i].pdbType = g_strdup(geom0[i].pdbType);
610 		geom[i].Layer = geom0[i].Layer;
611 		geom[i].Variable = geom0[i].Variable;
612 		geom[i].Residue = g_strdup(geom0[i].Residue);
613 		geom[i].ResidueNumber = geom0[i].ResidueNumber;
614 		geom[i].show = geom0[i].show;
615 		geom[i].Charge = geom0[i].Charge;
616 	}
617 	return geom;
618 }
619 /*****************************************************************************/
freeGeometry(GeomDef * geom)620 void freeGeometry(GeomDef* geom)
621 {
622 	gint i;
623 	if(!geom) return;
624 	if(Natoms<1) return;
625 	for(i=0;i<Natoms;i++)
626 	{
627 		if(geom[i].Prop.name) g_free(geom[i].Prop.name);
628 		if(geom[i].Prop.symbol) g_free(geom[i].Prop.symbol);
629 		if(geom[i].mmType) g_free(geom[i].mmType);
630 		if(geom[i].pdbType) g_free(geom[i].pdbType);
631 		if(geom[i].Residue) g_free(geom[i].Residue);
632 		if(geom[i].typeConnections) g_free(geom[i].typeConnections);
633 	}
634 	g_free(geom);
635 }
636 /*****************************************************************************/
get_factorstick()637 gdouble get_factorstick()
638 {
639 	return factorstick;
640 }
641 /*****************************************************************************/
get_factorball()642 gdouble get_factorball()
643 {
644 	return factorball;
645 }
646 /*****************************************************************************/
get_factordipole()647 gdouble get_factordipole()
648 {
649 	return factordipole;
650 }
651 /*****************************************************************************/
get_factor()652 gdouble get_factor()
653 {
654 	return factor;
655 }
656 /*****************************************************************************/
get_connection_type(gint i,gint j)657 gint get_connection_type(gint i, gint j)
658 {
659 	gint nj = 0;
660 	if(i<0 || j<0 || i>=Natoms || j>=Natoms ) return 0;
661 	if(!geometry[i].typeConnections)return 0;
662 	nj = geometry[j].N-1;
663 	if(geometry[i].typeConnections[nj]>0) return geometry[i].typeConnections[nj];
664 	return 0;
665 }
666 /*****************************************************************************/
set_fix_variable_of_selected_atoms(gboolean variable)667 static void set_fix_variable_of_selected_atoms(gboolean variable)
668 {
669 	gint i;
670 	for (i=0;i<(gint)Natoms;i++)
671 	{
672 		if(if_selected(i))
673 		{
674 			geometry[i].Variable = variable;
675 			geometry0[i].Variable = variable;
676 		}
677 	}
678 	create_GeomXYZ_from_draw_grometry();
679 	drawGeom();
680 }
681 /*****************************************************************************/
set_fix_selected_atoms()682 void set_fix_selected_atoms()
683 {
684 	gint i;
685 	gint nf=0;
686 	for (i=0;i<(gint)Natoms;i++)
687 			if(geometry[i].Variable) nf++;
688 	if(nf==0)
689 	{
690 		for (i=0;i<(gint)Natoms;i++)
691 		{
692 			geometry[i].Variable=TRUE;
693 			geometry0[i].Variable = TRUE;
694 		}
695 	}
696 	set_fix_variable_of_selected_atoms(FALSE);
697 }
698 /*****************************************************************************/
set_variable_selected_atoms()699 void set_variable_selected_atoms()
700 {
701 	set_fix_variable_of_selected_atoms(TRUE);
702 }
703 /*****************************************************************************/
hide_selected_atoms()704 void hide_selected_atoms()
705 {
706 	gint i;
707 	for (i=0;i<(gint)Natoms;i++)
708 	{
709 		if(if_selected(i))
710 		{
711 			geometry[i].show = FALSE;
712 			geometry0[i].show = FALSE;
713 		}
714 	}
715 	unselect_all_atoms();
716 	drawGeom();
717 }
718 /*****************************************************************************/
hide_not_selected_atoms()719 void hide_not_selected_atoms()
720 {
721 	gint i;
722 	for (i=0;i<(gint)Natoms;i++)
723 	{
724 		if(!if_selected(i))
725 		{
726 			geometry[i].show = FALSE;
727 			geometry0[i].show = FALSE;
728 		}
729 	}
730 	drawGeom();
731 }
732 /*****************************************************************************/
show_hydrogen_atoms()733 void show_hydrogen_atoms()
734 {
735 	gint i;
736 	gint j;
737 	gint ni;
738 	gint nj;
739 	for (i=0;i<(gint)Natoms;i++)
740 	{
741 		ni = geometry[i].N-1;
742 		if(!geometry[i].show) continue;
743 		for (j=0;j<(gint)Natoms;j++)
744 		{
745 			nj = geometry[j].N-1;
746 			if(!geometry[i].typeConnections) continue;
747 			if(geometry[i].typeConnections[nj]<1) continue;
748 			if(!strcmp(geometry[j].Prop.symbol,"H"))
749 			{
750 				geometry[j].show = TRUE;
751 				geometry0[j].show = TRUE;
752 			}
753 		}
754 
755 	}
756 	drawGeom();
757 	ShowHydrogenAtoms = TRUE;
758 }
759 /*****************************************************************************/
show_all_atoms()760 void show_all_atoms()
761 {
762 	gint i;
763 	for (i=0;i<(gint)Natoms;i++)
764 	{
765 		geometry[i].show = TRUE;
766 		geometry0[i].show = TRUE;
767 	}
768 	drawGeom();
769 	ShowHydrogenAtoms = TRUE;
770 }
771 /********************************************************************************/
testAmberTypesDefine()772 static gint testAmberTypesDefine()
773 {
774 	gint i;
775 	gint k;
776 	if(Natoms<1)return 0;
777 	for(i=0;i<(gint)Natoms;i++)
778 		if(geometry[i].mmType && strlen(geometry[i].mmType)>2)
779 		{
780 			printf("Problem with %s\n",geometry[i].mmType);
781 			return -1;
782 		}
783 	k = 0;
784 	for(i=0;i<(gint)Natoms;i++)
785 		if(geometry[i].mmType && strcmp(geometry[i].mmType,geometry[i].Prop.symbol)==0) k++;
786 	if(k==Natoms) return -2;
787 	return 0;
788 }
789 /********************************************************************************/
messageAmberTypesDefine()790 void messageAmberTypesDefine()
791 {
792 	gint k = testAmberTypesDefine();
793 	if(k==0) return;
794 	if(k==-1)
795 	{
796     		GtkWidget* m;
797 		m = Message(_("The type of One (or several) of atoms is not a Amber type.\n"
798 		        "You can set the types of atoms by : \n"
799 		        "                  \"Set/Atom Type&Charge using PDB Template\" \n"
800 		        "                  \"Or\" \n"
801 		        "                  \"Set/Atom Types using connections types\" \n"
802 			)
803 			,_("Warning"),TRUE);
804 		gtk_window_set_modal (GTK_WINDOW (m), TRUE);
805 	}
806 	if(k==-2)
807 	{
808     		GtkWidget* m;
809 		m = Message(_("The types of the atoms are identical to the symbols of these atoms.\n"
810 		        "You can set the types of atoms by \n"
811 		        "\"Set/Atom Types using connections types\" \n"
812 			)
813 			,_("Warning"),TRUE);
814 		gtk_window_set_modal (GTK_WINDOW (m), TRUE);
815 	}
816 }
817 /*****************************************************************************/
getShowMultipleBonds()818 gboolean getShowMultipleBonds()
819 {
820 	return showMultipleBonds;
821 }
822 /*****************************************************************************/
RenderMultipleBonds(GtkWidget * win,gboolean show)823 void RenderMultipleBonds(GtkWidget *win,gboolean show)
824 {
825 	showMultipleBonds = show;
826 	drawGeom();
827 }
828 /*****************************************************************************/
resetConnections()829 void resetConnections()
830 {
831 	reset_all_connections();
832 	drawGeom();
833 }
834 /*****************************************************************************/
resetConnectionsBetweenSelectedAndNotSelectedAtoms()835 void resetConnectionsBetweenSelectedAndNotSelectedAtoms()
836 {
837 	reset_connections_between_selected_and_notselected_atoms();
838 	drawGeom();
839 }
840 /*****************************************************************************/
resetConnectionsBetweenSelectedAtoms()841 void resetConnectionsBetweenSelectedAtoms()
842 {
843 	reset_connections_between_selected_atoms();
844 	drawGeom();
845 }
846 /*****************************************************************************/
resetMultipleConnections()847 void resetMultipleConnections()
848 {
849 	reset_multiple_bonds();
850 	drawGeom();
851 }
852 /*****************************************************************************/
getOperationType()853 GabEditGeomOperation getOperationType()
854 {
855 	return OperationType;
856 }
857 /*****************************************************************************/
get_real_distance2(GeomDef * g,gint i,gint j)858 gdouble get_real_distance2(GeomDef* g,gint i,gint j)
859 {
860  	gdouble xx;
861 	gdouble d;
862 
863 	xx = g[i].X-g[j].X;
864 	d = xx*xx;
865 	xx = g[i].Y-g[j].Y;
866 	d += xx*xx;
867 	xx = g[i].Z-g[j].Z;
868 	d += xx*xx;
869 
870 	return d;
871 }
872 /*******************************************************************/
adjust_multiple_bonds_with_one_atom(gint n)873 void adjust_multiple_bonds_with_one_atom(gint n)
874 {
875 	if(Natoms<2) return;
876 	if(!geometry[n].typeConnections) return;
877 	{
878 		gint ni = 0;
879 		gint nj = 0;
880 		gint i,j;
881 		gint nBonds = 0;
882 
883 		i = n;
884 		ni = geometry[i].N-1;
885 		for(j=0;j<(gint)Natoms;j++)
886 		{
887 			if(j==i) continue;
888 			nj = geometry[j].N-1;
889 		 	if(geometry[i].typeConnections[nj]>0)
890 		 	{
891 				nBonds += geometry[i].typeConnections[nj];
892 		 	}
893 		}
894 		if(nBonds<=geometry[i].Prop.maximumBondValence) return;
895 		for(j=0;j<(gint)Natoms;j++)
896 		{
897 			nj = geometry[j].N-1;
898 			if(i==j) continue;
899 			if(geometry[i].typeConnections[nj]<=1) continue;
900 			geometry[i].typeConnections[nj] -=1;
901 			geometry[j].typeConnections[ni] -=1;
902 			nBonds--;
903 			if(nBonds<=geometry[i].Prop.maximumBondValence) return;
904 		}
905 		copy_connections(geometry0, geometry, Natoms);
906 	}
907 }
908 /*******************************************************************/
reset_connection_with_one_atom(gint n)909 void reset_connection_with_one_atom(gint n)
910 {
911 	if(Natoms<2) return;
912 	if(!geometry[n].typeConnections) return;
913 	{
914 		gint ni = 0;
915 		gint nj = 0;
916 		gint i,j;
917 		gint* nBonds = g_malloc(Natoms*sizeof(gint));
918 
919 		for(i=0;i<(gint)Natoms;i++) nBonds[i] = 0;
920 		for(i=0;i<(gint)Natoms-1;i++)
921 		{
922 			if(i==n) continue;
923 			for(j=i+1;j<(gint)Natoms;j++)
924 			{
925 				if(j==n) continue;
926 				nj = geometry[j].N-1;
927 			 	if(geometry[i].typeConnections[nj]>0)
928 			 	{
929 					nBonds[i] += geometry[i].typeConnections[nj];
930 				 	nBonds[j] += geometry[i].typeConnections[nj];
931 			 	}
932 			}
933 		}
934 		i = n;
935 		ni = geometry[i].N-1;
936 		for(j=0;j<(gint)Natoms;j++)
937 		{
938 			if(i==j) continue;
939 			nj = geometry[j].N-1;
940 			if(draw_lines_yes_no(i,j)) geometry[i].typeConnections[nj]= 1;
941 			else geometry[i].typeConnections[nj]=0;
942 
943 			if(geometry[j].typeConnections)
944 				geometry[j].typeConnections[ni] = geometry[i].typeConnections[nj];
945 
946 			nBonds[i]+= geometry[i].typeConnections[nj];
947 			nBonds[j]+= geometry[i].typeConnections[nj];
948 			if(nBonds[i]>geometry[i].Prop.maximumBondValence ||
949 			nBonds[j]>geometry[j].Prop.maximumBondValence
950 					)
951 			{
952 				geometry[i].typeConnections[nj]= 0;
953 				if(geometry[j].typeConnections)
954 					geometry[j].typeConnections[ni] = 0;
955 				nBonds[i]--;
956 				nBonds[j]--;
957 
958 			}
959 		}
960 		for(j=0;j<(gint)Natoms;j++)
961 		{
962 			nj = geometry[j].N-1;
963 			if(i==j) continue;
964 			if(geometry[i].typeConnections[nj]==0) continue;
965 			if(
966 		 	nBonds[i] < geometry[i].Prop.maximumBondValence &&
967 		 	nBonds[j] < geometry[j].Prop.maximumBondValence
968 			)
969 			{
970 				geometry[i].typeConnections[nj] = geometry[j].typeConnections[ni] = 2;
971 				nBonds[i] += 1;
972 				nBonds[j] += 1;
973 			}
974 		}
975 		for(j=0;j<(gint)Natoms;j++)
976 		{
977 			nj = geometry[j].N-1;
978 			if(i==j) continue;
979 			if(geometry[i].typeConnections[nj]==0) continue;
980 			if(
981 		 	nBonds[i] < geometry[i].Prop.maximumBondValence &&
982 		 	nBonds[j] < geometry[j].Prop.maximumBondValence
983 			)
984 			{
985 				geometry[i].typeConnections[nj] = geometry[j].typeConnections[ni] = 3;
986 				nBonds[i] += 1;
987 				nBonds[j] += 1;
988 			}
989 		}
990 		copy_connections(geometry0, geometry, Natoms);
991 	}
992 }
993 /*****************************************************************************/
init_connections()994 static void init_connections()
995 {
996 	gint i;
997 	gint j;
998 	if(Natoms<1) return;
999 	if(geometry)
1000 	for(i=0;i<(gint)Natoms;i++)
1001 	{
1002 		geometry[i].typeConnections = g_malloc(Natoms*sizeof(gint));
1003 		for(j=0;j<(gint)Natoms;j++) geometry[i].typeConnections[j] = 0;
1004 	}
1005 	if(geometry0)
1006 	for(i=0;i<(gint)Natoms;i++)
1007 	{
1008 		geometry0[i].typeConnections = g_malloc(Natoms*sizeof(gint));
1009 		for(j=0;j<(gint)Natoms;j++) geometry0[i].typeConnections[j] = 0;
1010 	}
1011 }
1012 /************************************************************************/
reSetSimpleConnections()1013 static void reSetSimpleConnections()
1014 {
1015 	gint* nBonds = NULL;
1016 	gint* num = NULL;
1017 	gint* numConn = NULL;
1018 	gdouble* dists = NULL;
1019 	gint i;
1020 	gint j;
1021 	gint ni;
1022 	gint nj;
1023 	gint k;
1024 	gint kmax;
1025 	gint nb0;
1026 	if(Natoms<1) return;
1027 	nBonds = g_malloc(Natoms*sizeof(gint));
1028 	num = g_malloc(Natoms*sizeof(gint));
1029 	numConn = g_malloc(Natoms*sizeof(gint));
1030 	dists = g_malloc(Natoms*sizeof(gdouble));
1031 	for(i=0;i<(gint)Natoms;i++) num[i] = i;
1032 
1033 	for(i=0;i<(gint)Natoms-1;i++)
1034 	{
1035 		gint k = i;
1036 		for(j=i+1;j<(gint)Natoms;j++)
1037 			if(geometry[num[j]].N<geometry[num[k]].N) k = j;
1038 		if(k!=i)
1039 		{
1040 			gint t = num[i];
1041 			num[i] = num[k];
1042 			num[k] = t;
1043 		}
1044 	}
1045 
1046 	for(i=0;i<(gint)Natoms;i++) nBonds[i] = 0;
1047 	for(i=0;i<(gint)Natoms;i++)
1048 	{
1049 		ni = geometry[num[i]].N-1;
1050 		for(j=i+1;j<(gint)Natoms;j++)
1051 		{
1052 			nj = geometry[num[j]].N-1;
1053 			 if(geometry[num[i]].typeConnections[nj]>0)
1054 			 {
1055 				 nBonds[i] += 1;
1056 				 nBonds[j] += 1;
1057 			 }
1058 		}
1059 	}
1060 	/* remove H1-H2 connections if H1 and H2 are not connected to others atoms */
1061 	for(i=0;i<(gint)Natoms;i++)
1062 	{
1063 		ni = geometry[num[i]].N-1;
1064 		if( nBonds[i] <= geometry[num[i]].Prop.maximumBondValence) continue;
1065 		if( geometry[num[i]].Prop.maximumBondValence>1) continue;
1066 		for(k=0;k<(gint)nBonds[i];k++) numConn[k] = -1;
1067 		k = 0;
1068 		for(j=0;j<(gint)Natoms;j++)
1069 		{
1070 			nj = geometry[num[j]].N-1;
1071 			if(i!=j && geometry[num[i]].typeConnections[nj]>0)
1072 			{
1073         			gdouble p = geometry[num[i]].Prop.covalentRadii+geometry[num[j]].Prop.covalentRadii;
1074 				p = p*p;
1075 				numConn[k] = j;
1076 				dists[k] = get_real_distance2(geometry, num[i], num[j])/p;
1077 				if( geometry[num[j]].Prop.maximumBondValence>1) numConn[k] =-1;
1078 				k++;
1079 			}
1080 		}
1081 		nb0 = nBonds[i];
1082 		do{
1083 			kmax = -1;
1084 			for(k=0;k<nb0;k++) if(numConn[k]>-1) { kmax = k; break;}
1085 			if(kmax<0) break;
1086 			for(k=0;k<nb0;k++) if(numConn[k]>-1 && dists[k]>dists[kmax]) kmax = k;
1087 		 	nBonds[i] -= 1;
1088 		 	j = numConn[kmax];
1089 		 	nBonds[j] -= 1;
1090 		 	nj = geometry[num[j]].N-1;
1091 			geometry[num[i]].typeConnections[nj] = 0;
1092 			geometry[num[j]].typeConnections[ni] = 0;
1093 		 	numConn[kmax]=-1;
1094 		}while( nBonds[i] > geometry[num[i]].Prop.maximumBondValence);
1095 	}
1096 	/* remove A-H-B connections */
1097 	for(i=0;i<(gint)Natoms;i++)
1098 	{
1099 		ni = geometry[num[i]].N-1;
1100 		if( nBonds[i] <= geometry[num[i]].Prop.maximumBondValence) continue;
1101 		if( geometry[num[i]].Prop.maximumBondValence>1) continue;
1102 		for(k=0;k<(gint)nBonds[i];k++) numConn[k] = -1;
1103 		k = 0;
1104 		for(j=0;j<(gint)Natoms;j++)
1105 		{
1106 			nj = geometry[num[j]].N-1;
1107 			if(i!=j && geometry[num[i]].typeConnections[nj]>0)
1108 			{
1109         			gdouble p = geometry[num[i]].Prop.covalentRadii+geometry[num[j]].Prop.covalentRadii;
1110 				p = p*p;
1111 				numConn[k] = j;
1112 				dists[k] = get_real_distance2(geometry, num[i], num[j])/p;
1113 				k++;
1114 			}
1115 		}
1116 		nb0 = nBonds[i];
1117 		do{
1118 			kmax = -1;
1119 			for(k=0;k<nb0;k++) if(numConn[k]>-1) { kmax = k; break;}
1120 			if(kmax<0) break;
1121 			for(k=0;k<nb0;k++) if(numConn[k]>-1 && dists[k]>dists[kmax]) kmax = k;
1122 		 	nBonds[i] -= 1;
1123 		 	j = numConn[kmax];
1124 		 	nBonds[j] -= 1;
1125 		 	nj = geometry[num[j]].N-1;
1126 			geometry[num[i]].typeConnections[nj] = 0;
1127 			geometry[num[j]].typeConnections[ni] = 0;
1128 		 	numConn[kmax]=-1;
1129 		}while( nBonds[i] > geometry[num[i]].Prop.maximumBondValence);
1130 	}
1131 	/* remove H-B connections if B saturated */
1132 	for(i=0;i<(gint)Natoms;i++)
1133 	{
1134 		gint nV = geometry[num[i]].Prop.maximumBondValence;
1135 		if(geometry[num[i]].mmType && !strcmp(geometry[num[i]].mmType,"N3")) nV++;
1136 		if( nBonds[i] <= nV) continue;
1137 		if( nV<=1) continue;
1138 		ni = geometry[num[i]].N-1;
1139 		for(k=0;k<(gint)nBonds[i];k++) numConn[k] = -1;
1140 		k = 0;
1141 		for(j=0;j<(gint)Natoms;j++)
1142 		{
1143 			nj = geometry[num[j]].N-1;
1144 			if(i!=j && geometry[num[i]].typeConnections[nj]>0)
1145 			{
1146         			gdouble p = geometry[num[i]].Prop.covalentRadii+geometry[num[j]].Prop.covalentRadii;
1147 				p = p*p;
1148 				numConn[k] = j;
1149 				dists[k] = get_real_distance2(geometry, num[i], num[j])/p;
1150 				if( geometry[num[j]].Prop.maximumBondValence>1) numConn[k] =-1;
1151 				k++;
1152 			}
1153 		}
1154 		nb0 = nBonds[i];
1155 		do{
1156 			kmax = -1;
1157 			for(k=0;k<nb0;k++) if(numConn[k]>-1) { kmax = k; break;}
1158 			if(kmax<0) break;
1159 			for(k=0;k<nb0;k++) if(numConn[k]>-1 && dists[k]>dists[kmax]) kmax = k;
1160 		 	nBonds[i] -= 1;
1161 		 	j = numConn[kmax];
1162 		 	nBonds[j] -= 1;
1163 		 	nj = geometry[num[j]].N-1;
1164 			geometry[num[i]].typeConnections[nj] = 0;
1165 			geometry[num[j]].typeConnections[ni] = 0;
1166 		 	numConn[kmax]=-1;
1167 		}while( nBonds[i] > geometry[num[i]].Prop.maximumBondValence);
1168 	}
1169 	/* remove A-B connections if A or B saturated */
1170 	for(i=0;i<(gint)Natoms;i++)
1171 	{
1172 		ni = geometry[num[i]].N-1;
1173 		if( geometry[num[i]].Prop.maximumBondValence<=1) continue;
1174 		if( nBonds[i] <= geometry[num[i]].Prop.maximumBondValence) continue;
1175 		if(geometry[num[i]].mmType && !strcmp(geometry[num[i]].mmType,"N3") && nBonds[i] <= geometry[num[i]].Prop.maximumBondValence+1) continue;
1176 		for(k=0;k<(gint)nBonds[i];k++) numConn[k] = -1;
1177 		k = 0;
1178 		for(j=0;j<(gint)Natoms;j++)
1179 		{
1180 			nj = geometry[num[j]].N-1;
1181 			if(i!=j && geometry[num[i]].typeConnections[nj]>0)
1182 			{
1183         			gdouble p = geometry[num[i]].Prop.covalentRadii+geometry[num[j]].Prop.covalentRadii;
1184 				p = p*p;
1185 				numConn[k] = j;
1186 				dists[k] = get_real_distance2(geometry, num[i], num[j])/p;
1187 				k++;
1188 			}
1189 		}
1190 		nb0 = nBonds[i];
1191 		do{
1192 			kmax = -1;
1193 			for(k=0;k<nb0;k++) if(numConn[k]>-1) { kmax = k; break;}
1194 			if(kmax<0) break;
1195 			for(k=0;k<nb0;k++) if(numConn[k]>-1 && dists[k]>dists[kmax]) kmax = k;
1196 		 	nBonds[i] -= 1;
1197 		 	j = numConn[kmax];
1198 		 	nBonds[j] -= 1;
1199 		 	nj = geometry[num[j]].N-1;
1200 			geometry[num[i]].typeConnections[nj] = 0;
1201 			geometry[num[j]].typeConnections[ni] = 0;
1202 		 	numConn[kmax]=-1;
1203 		}while( nBonds[i] > geometry[num[i]].Prop.maximumBondValence);
1204 	}
1205 
1206 	g_free(nBonds);
1207 	g_free(num);
1208 	g_free(numConn);
1209 	g_free(dists);
1210 }
1211 /************************************************************************/
setMultipleBonds()1212 static void setMultipleBonds()
1213 {
1214 	gint* nBonds = NULL;
1215 	gint* num = NULL;
1216 	gint i;
1217 	gint j;
1218 	gint ni;
1219 	gint nj;
1220 	if(Natoms<1) return;
1221 	nBonds = g_malloc(Natoms*sizeof(gint));
1222 	num = g_malloc(Natoms*sizeof(gint));
1223 	for(i=0;i<(gint)Natoms;i++) num[i] = i;
1224 
1225 	for(i=0;i<(gint)Natoms-1;i++)
1226 	{
1227 		gint k = i;
1228 		for(j=i+1;j<(gint)Natoms;j++)
1229 			if(geometry[num[j]].N<geometry[num[k]].N) k = j;
1230 		if(k!=i)
1231 		{
1232 			gint t = num[i];
1233 			num[i] = num[k];
1234 			num[k] = t;
1235 		}
1236 	}
1237 
1238 	for(i=0;i<(gint)Natoms;i++) nBonds[i] = 0;
1239 	for(i=0;i<(gint)Natoms;i++)
1240 	{
1241 		ni = geometry[num[i]].N-1;
1242 		for(j=i+1;j<(gint)Natoms;j++)
1243 		{
1244 			nj = geometry[num[j]].N-1;
1245 			 if(geometry[num[i]].typeConnections[nj]>0)
1246 			 {
1247 				 nBonds[i] += 1;
1248 				 nBonds[j] += 1;
1249 			 }
1250 		}
1251 	}
1252 // sort atoms nBonds min at first
1253 	for(i=0;i<(gint)Natoms-1;i++)
1254 	{
1255 		gint k = i;
1256 		for(j=i+1;j<(gint)Natoms;j++)
1257 			if(nBonds[j]<nBonds[k])  k = j;
1258 		if(k!=i)
1259 		{
1260 			gint t = num[i];
1261 			num[i] = num[k];
1262 			num[k] = t;
1263 			t = nBonds[i];
1264 			nBonds[i] = nBonds[k];
1265 			nBonds[k] = t;
1266 		}
1267 	}
1268 	for(i=0;i<(gint)Natoms;i++)
1269 	{
1270 		ni = geometry[num[i]].N-1;
1271 		for(j=i+1;j<(gint)Natoms;j++)
1272 		{
1273 			nj = geometry[num[j]].N-1;
1274 			if(geometry[num[i]].typeConnections[nj]==0) continue;
1275 			if(
1276 		 	nBonds[i] < geometry[num[i]].Prop.maximumBondValence &&
1277 		 	nBonds[j] < geometry[num[j]].Prop.maximumBondValence
1278 			)
1279 			{
1280 				geometry[num[i]].typeConnections[nj] = geometry[num[j]].typeConnections[ni] = 2;
1281 				nBonds[i] += 1;
1282 				nBonds[j] += 1;
1283 			}
1284 		}
1285 	}
1286 	for(i=0;i<(gint)Natoms;i++)
1287 	{
1288 		ni = geometry[num[i]].N-1;
1289 		for(j=i+1;j<(gint)Natoms;j++)
1290 		{
1291 			nj = geometry[num[j]].N-1;
1292 			if(geometry[num[i]].typeConnections[nj]==0) continue;
1293 			if(
1294 		 	nBonds[i] < geometry[num[i]].Prop.maximumBondValence &&
1295 		 	nBonds[j] < geometry[num[j]].Prop.maximumBondValence
1296 			)
1297 			{
1298 				geometry[num[i]].typeConnections[nj] = geometry[num[j]].typeConnections[ni] = 3;
1299 				nBonds[i] += 1;
1300 				nBonds[j] += 1;
1301 			}
1302 		}
1303 	}
1304 	g_free(nBonds);
1305 	g_free(num);
1306 }
1307 /*****************************************************************************/
set_connections()1308 static void set_connections()
1309 {
1310 	gint i;
1311 	gint j;
1312 	gint ni;
1313 	gint nj;
1314 
1315 	init_connections();
1316 	for(i=0;i<(gint)Natoms;i++)
1317 	{
1318 		ni = geometry[i].N-1;
1319 		for(j=i+1;j<(gint)Natoms;j++)
1320 		{
1321 			nj = geometry[j].N-1;
1322 			if(draw_lines_yes_no(i,j)) geometry[i].typeConnections[nj]= 1;
1323 			else geometry[i].typeConnections[nj]=0;
1324 			geometry[j].typeConnections[ni] = geometry[i].typeConnections[nj];
1325 		}
1326 	}
1327 	reSetSimpleConnections();
1328 	setMultipleBonds();
1329 }
1330 /*****************************************************************************/
set_Hconnections()1331 static void set_Hconnections()
1332 {
1333 	gint i;
1334 	gint j;
1335 	gint k;
1336 	gboolean Ok;
1337 	gdouble distance2;
1338 	gdouble dx;
1339 	gdouble dy;
1340 	gdouble dz;
1341 	gdouble angle;
1342 	gchar* strAngle;
1343 	gdouble minDistanceH2;
1344 	gdouble maxDistanceH2;
1345         Point A;
1346         Point B;
1347 	gint ni, nj, nk;
1348 
1349 	minDistanceH = getMinDistanceHBonds();
1350 	minDistanceH2 = minDistanceH*minDistanceH*ANG_TO_BOHR*ANG_TO_BOHR;
1351 
1352 	maxDistanceH = getMaxDistanceHBonds();
1353 	maxDistanceH2 = maxDistanceH*maxDistanceH*ANG_TO_BOHR*ANG_TO_BOHR;
1354 
1355 	minAngleH = getMinAngleHBonds();
1356 	maxAngleH = getMaxAngleHBonds();
1357 
1358 	for(i=0;i<(gint)Natoms;i++)
1359 	{
1360 		ni = geometry[i].N-1;
1361 		Ok = FALSE;
1362 		Ok = atomCanDoHydrogenBond(geometry[i].Prop.symbol);
1363 		if(!Ok) continue;
1364 		for(j=0;j<(gint)Natoms;j++)
1365 		{
1366 			nj = geometry[j].N-1;
1367 			if(geometry[i].typeConnections[nj]>0) continue;
1368 			if(i==j) continue;
1369 			if(strcmp(geometry[j].Prop.symbol, "H")!=0)continue;
1370 
1371 			dx = geometry[i].X-geometry[j].X;
1372 			dy = geometry[i].Y-geometry[j].Y;
1373 			dz = geometry[i].Z-geometry[j].Z;
1374 			distance2 = (dx*dx+dy*dy+dz*dz);
1375 			if(distance2<minDistanceH2 || distance2>maxDistanceH2) continue;
1376 
1377 
1378 			Ok = FALSE;
1379 			for(k=0;k<(gint)Natoms;k++)
1380 			{
1381 				nk = geometry[k].N-1;
1382 				if(k==j) continue;
1383 				if(k==i) continue;
1384 				if(geometry[j].typeConnections[nk]<=0) continue;
1385 				A.C[0]=geometry[i].X-geometry[j].X;
1386 				A.C[1]=geometry[i].Y-geometry[j].Y;
1387 				A.C[2]=geometry[i].Z-geometry[j].Z;
1388 
1389 				B.C[0]=geometry[k].X-geometry[j].X;
1390 				B.C[1]=geometry[k].Y-geometry[j].Y;
1391 				B.C[2]=geometry[k].Z-geometry[j].Z;
1392 
1393         			strAngle = get_angle_vectors(A,B);
1394 				angle = atof(strAngle);
1395 				if(strAngle) g_free(strAngle);
1396 				if(angle>=minAngleH &&angle<=maxAngleH)
1397 				{
1398 					Ok = TRUE;
1399 					break;
1400 				}
1401 			}
1402 			if(Ok)
1403 			{
1404 				geometry[i].typeConnections[nj]=-1;
1405 				geometry[j].typeConnections[ni]=-1;
1406 			}
1407 		}
1408 	}
1409 }
1410 /*****************************************************************************/
copy_connections(GeomDef * geom0,GeomDef * geom,gint n)1411 void copy_connections(GeomDef* geom0, GeomDef* geom, gint n)
1412 {
1413 	gint i;
1414 	gint j;
1415 	if(!geom) return;
1416 	if(!geom0) return;
1417 	for(i=0;i<n;i++)
1418 	{
1419 		if(!geom[i].typeConnections) continue;
1420 		for(j=0;j<n;j++)
1421 		{
1422 			gint nj = geom[j].N-1;
1423 			if(!geom0[j].typeConnections) continue;
1424 			geom0[i].typeConnections[nj] = geom[i].typeConnections[nj];
1425 		}
1426 	}
1427 }
1428 /************************************************************************************************************/
get_number_of_model_connections()1429 static gint get_number_of_model_connections()
1430 {
1431 	gint i;
1432 	gint j;
1433 	gint nc = 0;
1434 	gint NC = Natoms;
1435 	if(Natoms<1) return 0;
1436     	for(i=0;i<NC;i++)
1437 	{
1438 		if(geometry[i].Layer==MEDIUM_LAYER || geometry[i].Layer==LOW_LAYER) continue;
1439     		for(j=0;j<NC;j++)
1440 		{
1441 			gint nj = geometry[j].N-1;
1442 			if(i==j) continue;
1443 			if(geometry[j].Layer==MEDIUM_LAYER || geometry[j].Layer==LOW_LAYER) continue;
1444 			if(geometry[i].typeConnections[nj]>0) nc++;
1445 		}
1446 	}
1447 	return nc;
1448 }
1449 /************************************************************************************************************/
get_number_of_inter_connections()1450 static gint get_number_of_inter_connections()
1451 {
1452 	gint i;
1453 	gint j;
1454 	gint nc = 0;
1455 	gint NC = Natoms;
1456     	for(i=0;i<NC;i++)
1457 	{
1458 		if(geometry[i].Layer==HIGH_LAYER || geometry[i].Layer==LOW_LAYER) continue;
1459     		for(j=0;j<NC;j++)
1460 		{
1461 			gint nj = geometry[j].N-1;
1462 			if(i==j) continue;
1463 			if(geometry[j].Layer==HIGH_LAYER || geometry[j].Layer==LOW_LAYER) continue;
1464 			if(geometry[i].typeConnections[nj]>0) nc++;
1465 		}
1466 	}
1467 	return nc;
1468 }
1469 /*************************************************************************************/
get_number_of_electrons(guint type)1470 static guint get_number_of_electrons(guint type)
1471 {
1472 /*
1473    type = 1 : Medium and High
1474    type = 2 : High
1475    type = other : All
1476 */
1477    guint i;
1478    guint Ne=0;
1479    SAtomsProp Atom;
1480    for(i=0;i<Natoms;i++)
1481    {
1482        Atom = geometry[i].Prop;
1483        switch (type)
1484        {
1485       	case 1 : if( geometry[i].Layer==HIGH_LAYER ||  geometry[i].Layer==MEDIUM_LAYER) Ne += Atom.atomicNumber;
1486 		 break;
1487        	case 2 : if( geometry[i].Layer==HIGH_LAYER) Ne += Atom.atomicNumber;
1488 		 break;
1489        	default : Ne += Atom.atomicNumber;
1490         }
1491    }
1492    return Ne;
1493 }
1494 /************************************************************************************************************/
reset_spin_of_electrons()1495 static void reset_spin_of_electrons()
1496 {
1497         gint i;
1498         guint NumberElectrons[3];
1499         guint SpinElectrons[3];
1500 	gint n = 1;
1501 	gint nL = 0;
1502 	gint nM = 0;
1503 	gint nH = 0;
1504 
1505 	if(Natoms<1) return;
1506 
1507         NumberElectrons[2]= get_number_of_electrons(2);
1508         NumberElectrons[1]= get_number_of_electrons(1);
1509         NumberElectrons[0]= get_number_of_electrons(0);
1510 
1511 
1512         for(i=0;i<3;i++)
1513 		SpinElectrons[i]=0;
1514     	for(i=0;i<Natoms;i++)
1515 	{
1516 		if(geometry[i].Layer==LOW_LAYER) nH =1;
1517 		if(geometry[i].Layer==MEDIUM_LAYER) nM =1;
1518 		if(geometry[i].Layer==HIGH_LAYER) nH =1;
1519 	}
1520 	n = nH + nM + nL;
1521         if(n==3)
1522 	{
1523         	NumberElectrons[2] += get_number_of_model_connections();
1524         	NumberElectrons[1] += get_number_of_inter_connections();
1525 	}
1526         if(n==2)
1527 	{
1528         	NumberElectrons[1] += get_number_of_model_connections();
1529 	}
1530 
1531         for(i=0;(guint)i<n;i++)
1532         	if((NumberElectrons[i]-TotalCharges[i])%2==0)
1533 			SpinElectrons[i]=1;
1534                 else
1535 			SpinElectrons[i]=2;
1536 
1537         for(i=0;(guint)i<n;i++)
1538 	{
1539 		if(SpinMultiplicities[i]%2 != SpinElectrons[i]%2)
1540 			SpinMultiplicities[i] = SpinElectrons[i];
1541 	}
1542 }
1543 /*****************************************************************************/
reset_charges_multiplicities()1544 void reset_charges_multiplicities()
1545 {
1546 	gint i;
1547 	if(Natoms<1) return;
1548 	for(i=0;i<3;i++)
1549 		TotalCharges[i] = 0;
1550 	reset_spin_of_electrons();
1551 
1552 }
1553 /*****************************************************************************/
reset_hydrogen_bonds()1554 void reset_hydrogen_bonds()
1555 {
1556 	if(Natoms<1) return;
1557 	if(ShowHBonds)
1558 	{
1559 		set_Hconnections();
1560 		copy_connections(geometry0, geometry, Natoms);
1561 	}
1562 }
1563 /*****************************************************************************/
reset_multiple_bonds()1564 void reset_multiple_bonds()
1565 {
1566 	gint i;
1567 	gint j;
1568     	for(i=0;i<Natoms;i++)
1569 	{
1570     		for(j=0;j<Natoms;j++)
1571 		{
1572 			gint nj = geometry[j].N-1;
1573 			if(geometry[i].typeConnections[nj]>1)
1574 				geometry[i].typeConnections[nj] = 1;
1575 		}
1576 	}
1577 	setMultipleBonds();
1578 }
1579 /*****************************************************************************/
reset_all_connections()1580 void reset_all_connections()
1581 {
1582 	if(Natoms<1) return;
1583 	buildRotation();
1584 	set_connections();
1585 	if(ShowHBonds) set_Hconnections();
1586 	copy_connections(geometry0, geometry, Natoms);
1587 }
1588 /*****************************************************************************/
reset_connections_between_selected_atoms()1589 static void reset_connections_between_selected_atoms()
1590 {
1591 	gint i;
1592 	gint j;
1593 	gint ni;
1594 	gint nj;
1595 	gint* nBonds = NULL;
1596 	gint* num = NULL;
1597 
1598 	if(Natoms<2) return;
1599 	nBonds = g_malloc(Natoms*sizeof(gint));
1600 	num = g_malloc(Natoms*sizeof(gint));
1601 	for(i=0;i<(gint)Natoms;i++) num[i] = i;
1602 	for(i=0;i<(gint)Natoms-1;i++)
1603 	{
1604 		gint k = i;
1605 		for(j=i+1;j<(gint)Natoms;j++)
1606 			if(geometry[num[j]].N<geometry[num[k]].N) k = j;
1607 		if(k!=i)
1608 		{
1609 			gint t = num[i];
1610 			num[i] = num[k];
1611 			num[k] = t;
1612 		}
1613 	}
1614 
1615 	for(i=0;i<(gint)Natoms;i++) nBonds[i] = 0;
1616 	for(i=0;i<(gint)Natoms-1;i++)
1617 	{
1618 		gboolean isa = if_selected(num[i]);
1619 		ni = geometry[num[i]].N-1;
1620 		if(geometry[num[i]].typeConnections)
1621 		for(j=i+1;j<(gint)Natoms;j++)
1622 		{
1623 			gboolean jsa = if_selected(num[j]);
1624 			if(isa==jsa) continue;
1625 			nj = geometry[num[j]].N-1;
1626 			 if(geometry[num[i]].typeConnections[nj]>0)
1627 			 {
1628 				 nBonds[i] += geometry[num[i]].typeConnections[nj];
1629 				 nBonds[j] += geometry[num[i]].typeConnections[nj];
1630 			 }
1631 		}
1632 	}
1633 	for(i=0;i<(gint)Natoms;i++)
1634 	{
1635 		gboolean isa = if_selected(num[i]);
1636 		if(!isa) continue;
1637 		ni = geometry[num[i]].N-1;
1638 		if(geometry[num[i]].typeConnections)
1639 		for(j=i+1;j<(gint)Natoms;j++)
1640 		{
1641 			gboolean jsa = if_selected(num[j]);
1642 			if(!jsa) continue;
1643 			nj = geometry[num[j]].N-1;
1644 			if(draw_lines_yes_no(num[i],num[j])) geometry[num[i]].typeConnections[nj]= 1;
1645 			else geometry[num[i]].typeConnections[nj]=0;
1646 
1647 			if(geometry[num[j]].typeConnections)
1648 				geometry[num[j]].typeConnections[ni] = geometry[num[i]].typeConnections[nj];
1649 
1650 			nBonds[i]+= geometry[num[i]].typeConnections[nj];
1651 			nBonds[j]+= geometry[num[i]].typeConnections[nj];
1652 			if(nBonds[i]>geometry[num[i]].Prop.maximumBondValence ||
1653 			nBonds[j]>geometry[num[j]].Prop.maximumBondValence
1654 					)
1655 			{
1656 				geometry[num[i]].typeConnections[nj]= 0;
1657 				if(geometry[num[j]].typeConnections)
1658 					geometry[num[j]].typeConnections[ni] = 0;
1659 				nBonds[i]--;
1660 				nBonds[j]--;
1661 
1662 			}
1663 		}
1664 	}
1665 	for(i=0;i<(gint)Natoms;i++)
1666 
1667 	{
1668 		gboolean isa = if_selected(num[i]);
1669 		ni = geometry[num[i]].N-1;
1670 		if(!isa) continue;
1671 		for(j=i+1;j<(gint)Natoms;j++)
1672 		{
1673 			gboolean jsa = if_selected(num[j]);
1674 			if(!jsa) continue;
1675 			nj = geometry[num[j]].N-1;
1676 			if(geometry[num[i]].typeConnections[nj]==0) continue;
1677 			if(
1678 		 	nBonds[i] < geometry[num[i]].Prop.maximumBondValence &&
1679 		 	nBonds[j] < geometry[num[j]].Prop.maximumBondValence
1680 			)
1681 			{
1682 				geometry[num[i]].typeConnections[nj] = geometry[num[j]].typeConnections[ni] = 2;
1683 				nBonds[i] += 1;
1684 				nBonds[j] += 1;
1685 			}
1686 		}
1687 	}
1688 	for(i=0;i<(gint)Natoms;i++)
1689 	{
1690 		gboolean isa = if_selected(num[i]);
1691 		if(!isa) continue;
1692 		ni = geometry[num[i]].N-1;
1693 		for(j=i+1;j<(gint)Natoms;j++)
1694 		{
1695 			gboolean jsa = if_selected(num[j]);
1696 			if(!jsa) continue;
1697 			nj = geometry[num[j]].N-1;
1698 			if(geometry[num[i]].typeConnections[nj]==0) continue;
1699 			if(
1700 		 	nBonds[i] < geometry[num[i]].Prop.maximumBondValence &&
1701 		 	nBonds[j] < geometry[num[j]].Prop.maximumBondValence
1702 			)
1703 			{
1704 				geometry[num[i]].typeConnections[nj] = geometry[num[j]].typeConnections[ni] = 3;
1705 				nBonds[i] += 1;
1706 				nBonds[j] += 1;
1707 			}
1708 		}
1709 	}
1710 	g_free(nBonds);
1711 	g_free(num);
1712 	copy_connections(geometry0, geometry, Natoms);
1713 }
1714 /*****************************************************************************/
reset_connections_between_selected_and_notselected_atoms()1715 static void reset_connections_between_selected_and_notselected_atoms()
1716 {
1717 	gint i;
1718 	gint j;
1719 	gint ni;
1720 	gint nj;
1721 	gint* nBonds = NULL;
1722 	gint* num = NULL;
1723 
1724 	if(Natoms<2) return;
1725 	nBonds = g_malloc(Natoms*sizeof(gint));
1726 	num = g_malloc(Natoms*sizeof(gint));
1727 	for(i=0;i<(gint)Natoms;i++) num[i] = i;
1728 	for(i=0;i<(gint)Natoms-1;i++)
1729 	{
1730 		gint k = i;
1731 		for(j=i+1;j<(gint)Natoms;j++)
1732 			if(geometry[num[j]].N<geometry[num[k]].N) k = j;
1733 		if(k!=i)
1734 		{
1735 			gint t = num[i];
1736 			num[i] = num[k];
1737 			num[k] = t;
1738 		}
1739 	}
1740 
1741 	for(i=0;i<(gint)Natoms;i++) nBonds[i] = 0;
1742 	for(i=0;i<(gint)Natoms-1;i++)
1743 	{
1744 		gboolean isa = if_selected(num[i]);
1745 		ni = geometry[num[i]].N-1;
1746 		if(geometry[num[i]].typeConnections)
1747 		for(j=i+1;j<(gint)Natoms;j++)
1748 		{
1749 			gboolean jsa = if_selected(num[j]);
1750 			if(isa!=jsa) continue;
1751 			nj = geometry[num[j]].N-1;
1752 			 if(geometry[num[i]].typeConnections[nj]>0)
1753 			 {
1754 				 nBonds[i] += geometry[num[i]].typeConnections[nj];
1755 				 nBonds[j] += geometry[num[i]].typeConnections[nj];
1756 			 }
1757 		}
1758 	}
1759 	for(i=0;i<(gint)Natoms;i++)
1760 	{
1761 		gboolean isa = if_selected(num[i]);
1762 		ni = geometry[num[i]].N-1;
1763 		if(geometry[num[i]].typeConnections)
1764 		for(j=i+1;j<(gint)Natoms;j++)
1765 		{
1766 			gboolean jsa = if_selected(num[j]);
1767 			if(isa==jsa) continue;
1768 			nj = geometry[num[j]].N-1;
1769 			if(draw_lines_yes_no(num[i],num[j])) geometry[num[i]].typeConnections[nj]= 1;
1770 			else geometry[num[i]].typeConnections[nj]=0;
1771 
1772 			if(geometry[num[j]].typeConnections)
1773 				geometry[num[j]].typeConnections[ni] = geometry[num[i]].typeConnections[nj];
1774 
1775 			nBonds[i]+= geometry[num[i]].typeConnections[nj];
1776 			nBonds[j]+= geometry[num[i]].typeConnections[nj];
1777 			if(nBonds[i]>geometry[num[i]].Prop.maximumBondValence ||
1778 			nBonds[j]>geometry[num[j]].Prop.maximumBondValence
1779 					)
1780 			{
1781 				geometry[num[i]].typeConnections[nj]= 0;
1782 				if(geometry[num[j]].typeConnections)
1783 					geometry[num[j]].typeConnections[ni] = 0;
1784 				nBonds[i]--;
1785 				nBonds[j]--;
1786 
1787 			}
1788 		}
1789 	}
1790 	for(i=0;i<(gint)Natoms;i++)
1791 
1792 	{
1793 		gboolean isa = if_selected(num[i]);
1794 		ni = geometry[num[i]].N-1;
1795 		for(j=i+1;j<(gint)Natoms;j++)
1796 		{
1797 			gboolean jsa = if_selected(num[j]);
1798 			nj = geometry[num[j]].N-1;
1799 			if(geometry[num[i]].typeConnections[nj]==0) continue;
1800 			if(
1801 		 	nBonds[i] < geometry[num[i]].Prop.maximumBondValence &&
1802 		 	nBonds[j] < geometry[num[j]].Prop.maximumBondValence
1803 			)
1804 			{
1805 				if(isa != jsa)
1806 				{
1807 				geometry[num[i]].typeConnections[nj] = geometry[num[j]].typeConnections[ni] = 2;
1808 				nBonds[i] += 1;
1809 				nBonds[j] += 1;
1810 				}
1811 			}
1812 		}
1813 	}
1814 	for(i=0;i<(gint)Natoms;i++)
1815 	{
1816 		gboolean isa = if_selected(num[i]);
1817 		ni = geometry[num[i]].N-1;
1818 		for(j=i+1;j<(gint)Natoms;j++)
1819 		{
1820 			gboolean jsa = if_selected(num[j]);
1821 			nj = geometry[num[j]].N-1;
1822 			if(geometry[num[i]].typeConnections[nj]==0) continue;
1823 			if(
1824 		 	nBonds[i] < geometry[num[i]].Prop.maximumBondValence &&
1825 		 	nBonds[j] < geometry[num[j]].Prop.maximumBondValence
1826 			)
1827 			{
1828 				if(isa != jsa)
1829 				{
1830 				geometry[num[i]].typeConnections[nj] = geometry[num[j]].typeConnections[ni] = 3;
1831 				nBonds[i] += 1;
1832 				nBonds[j] += 1;
1833 				}
1834 			}
1835 		}
1836 	}
1837 	g_free(nBonds);
1838 	g_free(num);
1839 	copy_connections(geometry0, geometry, Natoms);
1840 }
1841 /*****************************************************************************/
hbond_connections(gint i,gint j)1842 gboolean hbond_connections(gint i, gint j)
1843 {
1844 
1845 	if(ShowHBonds)
1846 	{
1847 		gint nj = geometry[j].N-1;
1848 		if(i<(gint)Natoms && j<(gint)Natoms && geometry[i].typeConnections[nj]==-1) return TRUE;
1849 		else return FALSE;
1850 	}
1851 	else return FALSE;
1852 }
1853 /*****************************************************************************/
init_quat(gdouble quat[])1854 void init_quat(gdouble quat[])
1855 {
1856 	gint i;
1857 	for(i=0;i<3;i++) quat[i] = 0.0;
1858 	quat[3] = 1.0;
1859 }
1860 /********************************************************************************/
set_origin_to_point(gdouble center[])1861 static void set_origin_to_point(gdouble center[])
1862 {
1863 	gint n;
1864 	for(n = 0;n<(gint)Natoms;n++)
1865 	{
1866 			geometry0[n].X -= center[0];
1867 			geometry0[n].Y -= center[1];
1868 			geometry0[n].Z -= center[2];
1869 
1870 			geometry[n].X -= center[0];
1871 			geometry[n].Y -= center[1];
1872 			geometry[n].Z -= center[2];
1873 	}
1874 	for (n=0;n<3;n++) Orig[n] += center[n];
1875 }
1876 /********************************************************************************/
set_origin_to_center_of_fragment()1877 void set_origin_to_center_of_fragment()
1878 {
1879 
1880 	gdouble C[3] = {0,0,0};
1881 	gint j = 0;
1882 	gint i;
1883 	for (i=0;i<(gint)Natoms;i++)
1884 	{
1885 		if(if_selected(i))
1886 		{
1887 			j++;
1888 			C[0] += geometry0[i].X;
1889 			C[1] += geometry0[i].Y;
1890 			C[2] += geometry0[i].Z;
1891 		}
1892 	}
1893 	if(j==0) return;
1894 	for (i=0;i<3;i++) C[i] /= j;
1895 	set_origin_to_point(C);
1896 	create_GeomXYZ_from_draw_grometry();
1897 	TransX = 0;
1898 	TransY = 0;
1899 	drawGeom();
1900 }
1901 /********************************************************************************/
set_geom_to_axes(gdouble axis1[],gdouble axis2[],gdouble axis3[])1902 static void set_geom_to_axes(gdouble axis1[], gdouble axis2[], gdouble axis3[])
1903 {
1904 	gdouble **m0 = NULL;
1905 	gdouble** minv;
1906 	gint i,j;
1907 	guint n;
1908 
1909 	gdouble A[3];
1910 	gdouble B[3];
1911 	guint k;
1912 	gdouble* X;
1913 	gdouble* Y;
1914 	gdouble* Z;
1915 
1916 	if(Natoms<1) return;
1917 
1918 	m0 = g_malloc(3*sizeof(gdouble*));
1919 	X = g_malloc(Natoms*sizeof(gdouble));
1920 	Y = g_malloc(Natoms*sizeof(gdouble));
1921 	Z = g_malloc(Natoms*sizeof(gdouble));
1922 
1923 	for(i=0;i<3;i++)
1924 		m0[i] = g_malloc(3*sizeof(gdouble));
1925 
1926 
1927 	m0[0][0] = axis1[0];
1928 	m0[0][1] = axis1[1];
1929 	m0[0][2] = axis1[2];
1930 
1931 	m0[1][0] = axis2[0];
1932 	m0[1][1] = axis2[1];
1933 	m0[1][2] = axis2[2];
1934 
1935 	m0[2][0] = axis3[0];
1936 	m0[2][1] = axis3[1];
1937 	m0[2][2] = axis3[2];
1938 
1939 	minv = Inverse(m0,3,1e-7);
1940 
1941 	for(n = 0;n<Natoms;n++)
1942 	{
1943 		A[0] = geometry[n].X;
1944 		A[1] = geometry[n].Y;
1945 		A[2] = geometry[n].Z;
1946 
1947 		for(j=0;j<3;j++)
1948 		{
1949 			B[j] = 0.0;
1950 			for(k=0;k<3;k++)
1951 				B[j] += minv[k][j]*A[k];
1952 		}
1953 
1954 		X[n] = B[0];
1955 		Y[n] = B[1];
1956 		Z[n] = B[2];
1957 	}
1958 	for(n = 0;n<Natoms;n++)
1959 	{
1960 			geometry0[n].X = X[n];
1961 			geometry0[n].Y = Y[n];
1962 			geometry0[n].Z = Z[n];
1963 
1964 			geometry[n].X = X[n];
1965 			geometry[n].Y = Y[n];
1966 			geometry[n].Z = Z[n];
1967 	}
1968 
1969 	for(i=0;i<3;i++) if(minv[i]) g_free(minv[i]);
1970 	if(minv) g_free(minv);
1971 
1972 	for(i=0;i<3;i++) if(m0[i]) g_free(m0[i]);
1973 	if(m0) g_free(m0);
1974 
1975 	if(X) g_free(X);
1976 	if(Y) g_free(Y);
1977 	if(Z) g_free(Z);
1978 }
1979 /********************************************************************************/
move_the_center_of_selected_or_not_selected_atoms_to_origin(gboolean sel)1980 void move_the_center_of_selected_or_not_selected_atoms_to_origin(gboolean sel)
1981 {
1982 
1983 	gdouble C[3] = {0,0,0};
1984 	gdouble C0[3] = {0,0,0};
1985 	gdouble mt = 0;
1986 	gint i;
1987 	for (i=0;i<(gint)Natoms;i++)
1988 	{
1989 		if(if_selected(i)==sel)
1990 		{
1991 			gdouble m = geometry[i].Prop.masse;
1992 			mt += m;
1993 			C[0] += m*geometry[i].X;
1994 			C[1] += m*geometry[i].Y;
1995 			C[2] += m*geometry[i].Z;
1996 			C0[0] += m*geometry0[i].X;
1997 			C0[1] += m*geometry0[i].Y;
1998 			C0[2] += m*geometry0[i].Z;
1999 		}
2000 	}
2001 	if(mt==0) return;
2002 	for (i=0;i<3;i++) C[i] /= mt;
2003 	for (i=0;i<3;i++) C0[i] /= mt;
2004 	for (i=0;i<(gint)Natoms;i++)
2005 	{
2006 		if(if_selected(i)==sel)
2007 		{
2008 			geometry[i].X -= C[0];
2009 			geometry[i].Y -= C[1];
2010 			geometry[i].Z -= C[2];
2011 
2012 			geometry0[i].X -= C0[0];
2013 			geometry0[i].Y -= C0[1];
2014 			geometry0[i].Z -= C0[2];
2015 		}
2016 	}
2017 }
2018 /*****************************************************************************/
set_fragment_rotational_matrix(gdouble m[6],gdouble C[],gboolean sel)2019 static int set_fragment_rotational_matrix(gdouble m[6], gdouble C[], gboolean sel)
2020 {
2021 	gint i;
2022 	gint ip;
2023 	gint j;
2024 	gint k;
2025 	gdouble a;
2026 	gdouble* XYZ[3];
2027 	gdouble mt = 0;
2028 	gint nFrag = 0;
2029 	gint* numAtoms;
2030 
2031 	for(i=0;i<3;i++)
2032 	{
2033 		XYZ[i] = g_malloc(Natoms*sizeof(gdouble));
2034 		C[i] = 0.0;
2035 	}
2036 	numAtoms = g_malloc(Natoms*sizeof(gint));
2037 
2038 
2039 	for(j=0;j<(gint)Natoms;j++)
2040 	{
2041 		if(if_selected(j)==sel)
2042 		{
2043 			numAtoms[nFrag] = j;
2044 			mt += geometry[j].Prop.masse;
2045 			XYZ[0][nFrag] = geometry[j].X;
2046 			XYZ[1][nFrag] = geometry[j].Y;
2047 			XYZ[2][nFrag] = geometry[j].Z;
2048 			nFrag++;
2049 		}
2050 	}
2051 	for(i=0;i<3;i++)
2052 		for(j=0;j<nFrag;j++)
2053 			C[i] += geometry[numAtoms[j]].Prop.masse*XYZ[i][j];
2054 	if(mt != 0)
2055 	for(i=0;i<3;i++) C[i] /= mt;
2056 
2057 	for(j=0;j<nFrag;j++)
2058 		for(i=0;i<3;i++)
2059 			XYZ[i][j] -= C[i];
2060 
2061 	k = 0;
2062 	for(i=0;i<3;i++)
2063 		for(ip=i;ip<3;ip++)
2064 	{
2065 		m[k] = 0.0;
2066 
2067 		for(j=0;j<nFrag;j++)
2068 		{
2069 			if(i==ip)
2070 			a = XYZ[(i+1)%3][j]*XYZ[(ip+1)%3][j]
2071 			  + XYZ[(i+2)%3][j]*XYZ[(ip+2)%3][j];
2072 			else
2073 			{
2074 				a =-XYZ[i][j]*XYZ[ip][j];
2075 			}
2076 			m[k] += geometry[numAtoms[j]].Prop.masse*a;
2077 		}
2078 		k++;
2079 	}
2080 
2081 	for(i=0;i<3;i++) g_free(XYZ[i]);
2082 	g_free(numAtoms);
2083 	return nFrag;
2084 }
2085 /********************************************************************************/
compute_fragment_principal_axes(gdouble axis1[],gdouble axis2[],gdouble axis3[],gdouble C[],gboolean sel)2086 static int compute_fragment_principal_axes(gdouble axis1[], gdouble axis2[], gdouble axis3[], gdouble C[], gboolean sel)
2087 {
2088 	gdouble m[6];
2089 	gdouble I[3];
2090 	gdouble** v = NULL;
2091 	gint nrot;
2092 	gint i;
2093 	gint nFrag;
2094 
2095 
2096 	if(Natoms<1) return 0;
2097 
2098 	nFrag = set_fragment_rotational_matrix(m, C,sel);
2099 	if(nFrag == 0) return 0;
2100 
2101 	v = g_malloc(3*sizeof(gdouble*));
2102 	for(i=0;i<3;i++) v[i] = g_malloc(3*sizeof(gdouble));
2103 
2104 	jacobi(m, 3,I,v,&nrot);
2105 
2106 	for(i=0;i<3;i++) axis1[i] =  v[i][0];
2107 	for(i=0;i<3;i++) axis2[i] =  v[i][1];
2108 	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];
2109 	/*
2110 	for(i=0;i<3;i++) axis3[i] =  v[i][2];
2111 	*/
2112 
2113 	for(i=0;i<3;i++) g_free(v[i]);
2114 	g_free(v);
2115 	printf("I= %f %f %f\n",I[0],I[1],I[2]);
2116 	return nFrag;
2117 }
2118 /********************************************************************************/
rotate_slected_atoms_minimize_rmsd()2119 static void rotate_slected_atoms_minimize_rmsd()
2120 {
2121 	gint i,j;
2122 
2123 	gint nA = 0;
2124 	const gint N = 8;
2125         gdouble d[8];
2126         gdouble w[8][3] = {
2127                 {1,1,1},
2128                 {-1,1,1},
2129                 {1,-1,1},
2130                 {1,1,-1},
2131                 {-1,-1,1},
2132                 {-1,1,-1},
2133                 {1,-1,-1},
2134                 {-1,-1,-1}
2135         };
2136         gdouble x, y, z;
2137 	gint* numA = NULL;
2138 	gint* numB = NULL;
2139 	gint iA, iB;
2140 
2141 	if(Natoms<1) return;
2142 
2143 	j = 0;
2144 	for(i = 0;i<Natoms;i++)
2145 		if(if_selected(i)) nA++;
2146 
2147 	if(nA != Natoms - nA || nA == 0) return;
2148 	numA = g_malloc(nA*sizeof(gint));
2149 	numB = g_malloc(nA*sizeof(gint));
2150         for (i=0;i<nA;i++) numA[i] = -1;
2151         for (i=0;i<nA;i++) numB[i] = -1;
2152 
2153 	iA = iB = 0;
2154 	for(i = 0;i<Natoms;i++)
2155 		if(if_selected(i)) numA[iA++] = i;
2156 		else numB[iB++] = i;
2157 
2158 	for(i = 0;i<nA;i++)
2159 	if(strcmp(geometry[numA[i]].Prop.symbol, geometry[numB[i]].Prop.symbol))
2160 	{
2161 		g_free(numA);
2162 		g_free(numB);
2163 		return;
2164 	}
2165 
2166         for (j=0;j<N;j++) d[j] = 0;
2167         for (i=0;i<nA;i++)
2168         {
2169                 for (j=0;j<N;j++)
2170                 {
2171                 x = geometry[numA[i]].X - w[j][0]*geometry[numB[i]].X;
2172                 y = geometry[numA[i]].Y - w[j][1]*geometry[numB[i]].Y;
2173                 z = geometry[numA[i]].Z - w[j][2]*geometry[numB[i]].Z;
2174                 d[j] += x*x + y*y + z*z;
2175                 }
2176         }
2177         double dmin = d[0];
2178 	int jmin = 0;
2179         for (j=1;j<N;j++) if(dmin>d[j]) {dmin=d[j]; jmin = j;}
2180         for (i=0;i<nA;i++)
2181 	{
2182                 geometry[numB[i]].X *=  w[jmin][0];
2183                 geometry[numB[i]].Y *=  w[jmin][1];
2184                 geometry[numB[i]].Z *=  w[jmin][2];
2185 
2186                 geometry0[numB[i]].X *=  w[jmin][0];
2187                 geometry0[numB[i]].Y *=  w[jmin][1];
2188                 geometry0[numB[i]].Z *=  w[jmin][2];
2189 	}
2190 
2191 
2192 	RebuildGeom = TRUE;
2193 }
2194 /********************************************************************************/
2195 /* type = 0 all atoms, type = 1 selected atoms, type = 2 not selected atoms */
set_xyz_to_standard_orientation(gint type)2196 static void set_xyz_to_standard_orientation(gint type)
2197 {
2198 	gint i,j;
2199 
2200 	gdouble* X;
2201 	gdouble* Y;
2202 	gdouble* Z;
2203 	gchar** symbols;
2204 
2205 	if(Natoms<1) return;
2206 
2207 	X = g_malloc(Natoms*sizeof(gdouble));
2208 	Y = g_malloc(Natoms*sizeof(gdouble));
2209 	Z = g_malloc(Natoms*sizeof(gdouble));
2210 	symbols = g_malloc(Natoms*sizeof(gchar*));
2211 	for(i = 0;i<Natoms;i++) symbols[i] = NULL;
2212 
2213 	j = 0;
2214 	for(i = 0;i<Natoms;i++)
2215 	{
2216 		if(type == 0 || (type==1 && if_selected(i))  || (type==2 && !if_selected(i)))
2217 		{
2218 			X[j] = geometry[i].X;
2219 			Y[j] = geometry[i].Y;
2220 			Z[j] = geometry[i].Z;
2221 			symbols[j] = g_strdup(geometry[i].Prop.symbol);
2222 			j++;
2223 		}
2224 	}
2225 
2226 	buildStandardOrientationDlg(j, symbols, X, Y, Z);
2227 
2228 	j = 0;
2229 	for(i = 0;i<Natoms;i++)
2230 	{
2231 		if(type == 0 || (type==1 && if_selected(i))  || (type==2 && !if_selected(i)))
2232 		{
2233 			geometry0[i].X = X[j];
2234 			geometry0[i].Y = Y[j];
2235 			geometry0[i].Z = Z[j];
2236 
2237 			geometry[i].X = X[j];
2238 			geometry[i].Y = Y[j];
2239 			geometry[i].Z = Z[j];
2240 			j++;
2241 		}
2242 	}
2243 
2244 	if(symbols) for(i = 0;i<Natoms;i++) if(symbols[i]) g_free(symbols[i]);
2245 	if(symbols) g_free(symbols);
2246 
2247 	if(X) g_free(X);
2248 	if(Y) g_free(Y);
2249 	if(Z) g_free(Z);
2250 
2251 	RebuildGeom = TRUE;
2252 }
2253 /********************************************************************************/
set_xyz_to_standard_orientation_all()2254 void set_xyz_to_standard_orientation_all()
2255 {
2256 	set_xyz_to_standard_orientation(0);
2257 	create_GeomXYZ_from_draw_grometry();
2258 	init_quat(Quat);
2259 	RebuildGeom = TRUE;
2260 	drawGeom();
2261 }
2262 /********************************************************************************/
set_xyz_to_standard_orientation_selected_atoms()2263 void set_xyz_to_standard_orientation_selected_atoms()
2264 {
2265 	set_xyz_to_standard_orientation(1);
2266 	create_GeomXYZ_from_draw_grometry();
2267 	init_quat(Quat);
2268 	RebuildGeom = TRUE;
2269 	drawGeom();
2270 }
2271 /********************************************************************************/
set_xyz_to_standard_orientation_not_selected_atoms()2272 void set_xyz_to_standard_orientation_not_selected_atoms()
2273 {
2274 	set_xyz_to_standard_orientation(2);
2275 	create_GeomXYZ_from_draw_grometry();
2276 	init_quat(Quat);
2277 	RebuildGeom = TRUE;
2278 	drawGeom();
2279 }
2280 /********************************************************************************/
set_xyz_to_standard_orientation_selected_and_not_selected_atoms()2281 void set_xyz_to_standard_orientation_selected_and_not_selected_atoms()
2282 {
2283 	set_xyz_to_standard_orientation(1);
2284 	set_xyz_to_standard_orientation(2);
2285 	rotate_slected_atoms_minimize_rmsd();
2286 	create_GeomXYZ_from_draw_grometry();
2287 	init_quat(Quat);
2288 	RebuildGeom = TRUE;
2289 	drawGeom();
2290 }
2291 /********************************************************************************/
set_xyz_to_principal_axes_of_selected_atoms(gpointer data,guint Operation,GtkWidget * wid)2292 void set_xyz_to_principal_axes_of_selected_atoms(gpointer data, guint Operation,GtkWidget* wid)
2293 {
2294 	gdouble axis1[3] = {1,0,0};
2295 	gdouble axis2[3] = {0,1,0};
2296 	gdouble axis3[3] = {0,0,1};
2297 	gdouble C[3] = {0,0,0};
2298 	int nFrag = compute_fragment_principal_axes(axis1,axis2,axis3,C,TRUE);
2299 	if(nFrag <2 ) return;
2300 	set_origin_to_point(C);
2301 	if(Operation == 0) set_geom_to_axes(axis1, axis2, axis3);
2302 	else set_geom_to_axes(axis3, axis2, axis1);
2303 	create_GeomXYZ_from_draw_grometry();
2304 	init_quat(Quat);
2305 	drawGeom();
2306 }
2307 /********************************************************************************/
create_tolerance_window(GtkWidget * w,gpointer data)2308 void create_tolerance_window(GtkWidget*w, gpointer data)
2309 {
2310 	createToleranceWindow(GeomDlg, NULL);
2311 }
2312 /********************************************************************************/
get_abelian_orientation_with_reduction(GtkWidget * w,gpointer data)2313 void get_abelian_orientation_with_reduction(GtkWidget*w, gpointer data)
2314 {
2315 	gchar** symbols = NULL;
2316 	gdouble* X = NULL;
2317 	gdouble* Y = NULL;
2318 	gdouble* Z = NULL;
2319 	gint i;
2320 	gint numberOfAtoms = Natoms;
2321 	gchar pointGroupSymbol[BSIZE];
2322 	gchar abelianPointGroupSymbol[BSIZE];
2323 
2324 	if(Natoms<1)
2325 	{
2326 		 Message(_("Sorry, the number of atoms is not positive"),_("Error"),TRUE);
2327 		return;
2328 	}
2329 	symbols = (gchar**)g_malloc(sizeof(gchar*)*(Natoms));
2330 	if(symbols == NULL) return;
2331 
2332 	X = (gdouble*)g_malloc(sizeof(gdouble)*(Natoms));
2333 	if(X == NULL) return;
2334 	Y = (gdouble*)g_malloc(sizeof(gdouble)*(Natoms));
2335 	if(Y == NULL) return;
2336 	Z = (gdouble*)g_malloc(sizeof(gdouble)*(Natoms));
2337 	if(Z == NULL) return;
2338 
2339 	for (i=0;i<(gint)Natoms;i++)
2340 	{
2341 		symbols[i] = g_strdup(geometry0[i].Prop.symbol);
2342 		X[i] = geometry0[i].X*BOHR_TO_ANG;
2343 		Y[i] = geometry0[i].Y*BOHR_TO_ANG;
2344 		Z[i] = geometry0[i].Z*BOHR_TO_ANG;
2345 	}
2346 	createGeometryAbelianGroupWindow(numberOfAtoms, symbols, X, Y, Z, pointGroupSymbol, abelianPointGroupSymbol);
2347 
2348 	for (i=0;i<(gint)Natoms;i++)
2349 		g_free( symbols[i]);
2350 	g_free( symbols);
2351 	g_free(X);
2352 	g_free(Y);
2353 	g_free(Z);
2354 	return;
2355 }
2356 /********************************************************************************/
get_standard_orientation_with_reduction(GtkWidget * w,gpointer data)2357 void get_standard_orientation_with_reduction(GtkWidget*w, gpointer data)
2358 {
2359 	gchar** symbols = NULL;
2360 	gdouble* X = NULL;
2361 	gdouble* Y = NULL;
2362 	gdouble* Z = NULL;
2363 	gint i;
2364 	gint numberOfAtoms = Natoms;
2365 	gchar groupeSymbol[BSIZE];
2366 
2367 	if(Natoms<1)
2368 	{
2369 		 Message(_("Sorry, the number of atoms is not positive"),_("Error"),TRUE);
2370 		return;
2371 	}
2372 	symbols = (gchar**)g_malloc(sizeof(gchar*)*(Natoms));
2373 	if(symbols == NULL) return;
2374 
2375 	X = (gdouble*)g_malloc(sizeof(gdouble)*(Natoms));
2376 	if(X == NULL) return;
2377 	Y = (gdouble*)g_malloc(sizeof(gdouble)*(Natoms));
2378 	if(Y == NULL) return;
2379 	Z = (gdouble*)g_malloc(sizeof(gdouble)*(Natoms));
2380 	if(Z == NULL) return;
2381 
2382 	for (i=0;i<(gint)Natoms;i++)
2383 	{
2384 		symbols[i] = g_strdup(geometry0[i].Prop.symbol);
2385 		X[i] = geometry0[i].X*BOHR_TO_ANG;
2386 		Y[i] = geometry0[i].Y*BOHR_TO_ANG;
2387 		Z[i] = geometry0[i].Z*BOHR_TO_ANG;
2388 	}
2389 	createGeometrySymmetryWindow(numberOfAtoms,symbols,X, Y, Z, groupeSymbol);
2390 
2391 	for (i=0;i<(gint)Natoms;i++)
2392 		g_free( symbols[i]);
2393 	g_free( symbols);
2394 	g_free(X);
2395 	g_free(Y);
2396 	g_free(Z);
2397 	return;
2398 }
2399 /********************************************************************************/
get_standard_orientation_with_symmetrization(GtkWidget * w,gpointer data)2400 void get_standard_orientation_with_symmetrization(GtkWidget*w, gpointer data)
2401 {
2402 	gchar** symbols = NULL;
2403 	gdouble* X = NULL;
2404 	gdouble* Y = NULL;
2405 	gdouble* Z = NULL;
2406 	gint i;
2407 	gint numberOfAtoms = Natoms;
2408 	gchar groupeSymbol[BSIZE];
2409 
2410 	if(Natoms<1)
2411 	{
2412 		 Message(_("Sorry, the number of atoms is not positive"),_("Error"),TRUE);
2413 		return;
2414 	}
2415 	symbols = (gchar**)g_malloc(sizeof(gchar*)*(Natoms));
2416 	if(symbols == NULL) return;
2417 
2418 	X = (gdouble*)g_malloc(sizeof(gdouble)*(Natoms));
2419 	if(X == NULL) return;
2420 	Y = (gdouble*)g_malloc(sizeof(gdouble)*(Natoms));
2421 	if(Y == NULL) return;
2422 	Z = (gdouble*)g_malloc(sizeof(gdouble)*(Natoms));
2423 	if(Z == NULL) return;
2424 
2425 	for (i=0;i<(gint)Natoms;i++)
2426 	{
2427 		symbols[i] = g_strdup(geometry0[i].Prop.symbol);
2428 		X[i] = geometry0[i].X*BOHR_TO_ANG;
2429 		Y[i] = geometry0[i].Y*BOHR_TO_ANG;
2430 		Z[i] = geometry0[i].Z*BOHR_TO_ANG;
2431 	}
2432 	createGeometrySymmetrizationWindow(numberOfAtoms,symbols,X, Y, Z, groupeSymbol);
2433 
2434 // reset geometry0
2435 	for(i = 0;i<numberOfAtoms;i++)
2436 	{
2437 		g_free(geometry0[i].Prop.symbol);
2438 		geometry0[i].Prop = prop_atom_get(symbols[i]);
2439 		geometry0[i].mmType = g_strdup(symbols[i]);
2440 		geometry0[i].pdbType = g_strdup(symbols[i]);
2441 		geometry0[i].Residue = g_strdup(symbols[i]);
2442 		geometry0[i].Charge = 0.0;
2443 		geometry0[i].X = X[i]/BOHR_TO_ANG;
2444 		geometry0[i].Y = Y[i]/BOHR_TO_ANG;
2445 		geometry0[i].Z = Z[i]/BOHR_TO_ANG;
2446 
2447 		g_free(geometry[i].Prop.symbol);
2448 		geometry[i].Prop = prop_atom_get(symbols[i]);
2449 		geometry[i].mmType = g_strdup(symbols[i]);
2450 		geometry[i].pdbType = g_strdup(symbols[i]);
2451 		geometry[i].Residue = g_strdup(symbols[i]);
2452 		geometry[i].Charge = 0.0;
2453 		geometry[i].X = geometry0[i].X;
2454 		geometry[i].Y = geometry0[i].Y;
2455 		geometry[i].Z = geometry0[i].Z;
2456 	}
2457 	resetConnections();
2458 	create_GeomXYZ_from_draw_grometry();
2459 
2460 	for (i=0;i<(gint)Natoms;i++)
2461 		g_free( symbols[i]);
2462 	g_free( symbols);
2463 	g_free(X);
2464 	g_free(Y);
2465 	g_free(Z);
2466 	return;
2467 }
2468 /********************************************************************************/
set_key_press(GtkWidget * wid,GdkEventKey * event,gpointer data)2469 static gint set_key_press(GtkWidget* wid, GdkEventKey *event, gpointer data)
2470 {
2471 	if((event->keyval == GDK_Shift_L || event->keyval == GDK_Shift_R) )
2472 		ShiftKeyPressed = TRUE;
2473 	else if((event->keyval == GDK_Control_L || event->keyval == GDK_Control_R) )
2474 	{
2475 		ControlKeyPressed = TRUE;
2476 	}
2477 	else if((event->keyval == GDK_Alt_L || event->keyval == GDK_Alt_R) )
2478 	{
2479 		ControlKeyPressed = TRUE;
2480 	}
2481 	else if((event->keyval == GDK_F || event->keyval == GDK_f) )
2482 	{
2483 		FKeyPressed = TRUE;
2484 	}
2485 	else if((event->keyval == GDK_G || event->keyval == GDK_g) )
2486 	{
2487 		GKeyPressed = TRUE;
2488 	}
2489 	else if((event->keyval == GDK_A || event->keyval == GDK_a)  && ControlKeyPressed)
2490 	{
2491 		SelectAllAtoms();
2492 	}
2493 	else if((event->keyval == GDK_u || event->keyval == GDK_U))
2494 	{
2495         	switch(OperationType)
2496         	{
2497 			case MOVEFRAG :
2498 			case DELETEOBJECTS :
2499 			case MEASURE     :
2500 			case EDITOBJECTS :
2501 			case ADDFRAGMENT :
2502 			case ROTLOCFRAG :
2503 			case ROTZLOCFRAG :
2504 				get_geometry_from_fifo( event->keyval == GDK_U);
2505 				drawGeom();
2506 				break;
2507 			default:break;
2508 		}
2509 	}
2510 	else if((event->keyval == GDK_z || event->keyval == GDK_y) && ControlKeyPressed)
2511 	{
2512         	switch(OperationType)
2513         	{
2514 			case MOVEFRAG :
2515 			case DELETEOBJECTS :
2516 			case MEASURE     :
2517 			case EDITOBJECTS :
2518 			case ADDFRAGMENT :
2519 			case ROTLOCFRAG :
2520 			case ROTZLOCFRAG :
2521 				get_geometry_from_fifo(event->keyval == GDK_y);
2522 				drawGeom();
2523 				break;
2524 			default:break;
2525 		}
2526 	}
2527 	GTK_WIDGET_GET_CLASS(wid)->key_press_event(wid, event);
2528 	return TRUE;
2529 
2530 }
2531 /********************************************************************************/
set_key_release(GtkWidget * wid,GdkEventKey * event,gpointer data)2532 static gint set_key_release(GtkWidget* wid, GdkEventKey *event, gpointer data)
2533 {
2534 	if((event->keyval == GDK_Shift_L || event->keyval == GDK_Shift_R) )
2535 		ShiftKeyPressed = FALSE;
2536 	else if((event->keyval == GDK_Control_L || event->keyval == GDK_Control_R) )
2537 		ControlKeyPressed = FALSE;
2538 	else if((event->keyval == GDK_Alt_L || event->keyval == GDK_Alt_R) )
2539 		ControlKeyPressed = FALSE;
2540 	else if((event->keyval == GDK_F || event->keyval == GDK_f) )
2541 		FKeyPressed = FALSE;
2542 	else if((event->keyval == GDK_G || event->keyval == GDK_g) )
2543 		GKeyPressed = FALSE;
2544 	return TRUE;
2545 }
2546 /********************************************************************************/
setMMTypesChargesFromPDBTpl(guint Operation)2547 void setMMTypesChargesFromPDBTpl(guint Operation)
2548 {
2549 	gint i;
2550 	gchar* mmType = NULL;
2551 	gdouble charge = 0.0;
2552 	for(i=0;i<(gint)Natoms;i++)
2553 	{
2554 		if(Operation!=3)
2555 		{
2556 			mmType = getMMTypeFromPDBTpl(geometry[i].Residue,geometry[i].pdbType,&charge);
2557 			if(!strcmp(mmType,"UNK"))
2558 			{
2559 				g_free(mmType);
2560 				continue;
2561 			}
2562 		}
2563 		switch(Operation)
2564 		{
2565 			case 0: geometry[i].Charge = charge;
2566 				geometry0[i].Charge = charge;
2567 				break;
2568 			case 1: g_free(geometry[i].mmType);
2569 				g_free(geometry0[i].mmType);
2570 				geometry[i].mmType = g_strdup(mmType);
2571 				geometry0[i].mmType = g_strdup(mmType);
2572 				break;
2573 			case 2: g_free(geometry[i].mmType);
2574 				g_free(geometry0[i].mmType);
2575 				geometry[i].mmType = g_strdup(mmType);
2576 				geometry0[i].mmType = g_strdup(mmType);
2577 				geometry[i].Charge = charge;
2578 				geometry0[i].Charge = charge;
2579 				break;
2580 			case 3:geometry[i].Charge = charge;
2581 			       geometry0[i].Charge = charge;
2582 			       break;
2583 			default: break;
2584 		}
2585 		if(Operation!=3) g_free(mmType);
2586 	}
2587 }
2588 /********************************************************************************/
setMMTypesCharges(gpointer data,guint Operation,GtkWidget * wid)2589 void setMMTypesCharges(gpointer data, guint Operation,GtkWidget* wid)
2590 {
2591 	if(Operation==4)
2592 	{
2593 		gint i;
2594 		calculTypesAmber(geometry, (gint)Natoms);
2595 		for(i=0;i<(gint)Natoms;i++)
2596 		{
2597 			geometry0[i].mmType = g_strdup(geometry[i].mmType);
2598 			geometry0[i].pdbType = g_strdup(geometry[i].pdbType);
2599 		}
2600 	}
2601 	else setMMTypesChargesFromPDBTpl(Operation);
2602 	create_GeomXYZ_from_draw_grometry();
2603 	drawGeom();
2604 }
2605 /*****************************************************************************/
Free_One_Geom(GeomDef * geom,gint N)2606 GeomDef* Free_One_Geom(GeomDef* geom,gint N)
2607 {
2608 	gint i;
2609 	if(!geom)  return NULL;
2610 	for (i=0;i<N;i++)
2611 	{
2612 		g_free(geom[i].Prop.name);
2613 		g_free(geom[i].Prop.symbol);
2614 		g_free(geom[i].mmType);
2615 		g_free(geom[i].pdbType);
2616 		g_free(geom[i].Residue);
2617 		if(geom[i].typeConnections) g_free(geom[i].typeConnections);
2618 	}
2619 	g_free(geom);
2620 	return NULL;
2621 }
2622 /*****************************************************************************/
free_text_to_draw()2623 void free_text_to_draw()
2624 {
2625 	if(strToDraw)
2626 		g_free(strToDraw);
2627 	strToDraw = NULL;
2628 }
2629 /*****************************************************************************/
set_text_to_draw(gchar * str)2630 void set_text_to_draw(gchar* str)
2631 {
2632 	free_text_to_draw();
2633 
2634 	strToDraw = g_strdup(str);
2635 }
2636 /********************************************************************************/
set_statubar_operation_str(gchar * str)2637 void set_statubar_operation_str(gchar* str)
2638 {
2639 	if(str && GeomDrawingArea)
2640 	{
2641 		gtk_statusbar_pop(GTK_STATUSBAR(StatusOperation),idStatusOperation);
2642 		gtk_statusbar_push(GTK_STATUSBAR(StatusOperation),idStatusOperation,str);
2643 	}
2644 }
2645 /*****************************************************************************/
draw_text(gchar * str)2646 void draw_text(gchar* str)
2647 {
2648 	GdkColormap *colormap;
2649 	GdkColor color;
2650  	PangoFontDescription *font_desc = pango_font_description_from_string (FontsStyleLabel.fontname);
2651 
2652 	gint x0  = GeomDrawingArea->allocation.width/20;
2653 	gint y0  = GeomDrawingArea->allocation.height-GeomDrawingArea->allocation.height/10;
2654 
2655 	color.red = FontsStyleLabel.TextColor.red;
2656 	color.green = FontsStyleLabel.TextColor.green;
2657 	color.blue = FontsStyleLabel.TextColor.blue;
2658 
2659    	colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
2660         gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE);
2661 	gdk_gc_set_foreground(gc,&color);
2662 	gabedit_cairo_string(cr, GeomDrawingArea, font_desc, gc, x0, y0, str, FALSE,TRUE);
2663 	if(crExport)
2664 	gabedit_cairo_string(crExport, GeomDrawingArea, font_desc, gc, x0, y0, str, FALSE,TRUE);
2665 
2666 	if(font_desc) pango_font_description_free (font_desc);
2667 
2668 }
2669 /*****************************************************************************/
select_atoms_by_groupe()2670 gboolean select_atoms_by_groupe()
2671 {
2672 	gint i;
2673 	gdouble x1=0;
2674 	gdouble y1=0;
2675 	gdouble xi;
2676 	gdouble yi;
2677 	gdouble d = 0;
2678 	gint j;
2679 	gint k;
2680 	gboolean OK = FALSE;
2681 
2682 	x1 = BeginX;
2683 	y1 = BeginY;
2684 
2685 	for(i=0;i<(gint)Natoms;i++)
2686 	{
2687 		xi = geometry[i].Xi;
2688 		yi = geometry[i].Yi;
2689 		d = (xi-x1)*(xi-x1) + (yi-y1)*(yi-y1);
2690 		d = sqrt(d);
2691 		if(d<=geometry[i].Rayon)
2692 		{
2693 			if(NumFatoms == NULL) NumFatoms = g_malloc((NFatoms+1)*sizeof(gint));
2694 			else NumFatoms = g_realloc(NumFatoms, (NFatoms+1)*sizeof(gint));
2695 			NumFatoms[NFatoms] = geometry[i].N;
2696 			NFatoms+=1;
2697 
2698 			for(j=0;j<(gint)Natoms;j++)
2699 			{
2700 				if(get_connection_type(i,j)>0)
2701 				{
2702 
2703 					gint nGroupAtoms=0;
2704 					gint * listGroupAtoms = getListGroupe(&nGroupAtoms, geometry0, Natoms, i, j,-1,-1);
2705 					if(NumFatoms == NULL) NumFatoms = g_malloc((NFatoms+nGroupAtoms+1)*sizeof(gint));
2706 					else NumFatoms = g_realloc(NumFatoms, (NFatoms+nGroupAtoms+1)*sizeof(gint));
2707 
2708 					NumFatoms[NFatoms] = geometry[j].N;
2709 					for(k=NFatoms+1;k<NFatoms+nGroupAtoms+1;k++)
2710 						NumFatoms[k] = geometry[listGroupAtoms[k-NFatoms-1]].N;
2711 					NFatoms+=nGroupAtoms+1;
2712 					if(listGroupAtoms) g_free(listGroupAtoms);
2713 					OK = TRUE;
2714 				}
2715 			}
2716 			break;
2717 
2718 		}
2719 	}
2720 	drawGeom();
2721 	return OK;
2722 }
2723 /*****************************************************************************/
select_atoms_by_residues()2724 gboolean select_atoms_by_residues()
2725 {
2726 	gint i;
2727 	gdouble x1=0;
2728 	gdouble y1=0;
2729 	gdouble xi;
2730 	gdouble yi;
2731 	gdouble d = 0;
2732 	gint j;
2733 	gint k;
2734 	gboolean del = FALSE;
2735 	gint selectedj;
2736 	gboolean OK = FALSE;
2737 
2738 
2739 	x1 = BeginX;
2740 	y1 = BeginY;
2741 
2742 	for(i=0;i<(gint)Natoms;i++)
2743 	{
2744 		xi = geometry[i].Xi;
2745 		yi = geometry[i].Yi;
2746 		d = (xi-x1)*(xi-x1) + (yi-y1)*(yi-y1);
2747 		d = sqrt(d);
2748 		if(d<=geometry[i].Rayon)
2749 		{
2750 			OK = TRUE;
2751 			del = if_selected(i);
2752 			for(j=0;j<(gint)Natoms;j++)
2753 			{
2754 				if(geometry[i].ResidueNumber == geometry[j].ResidueNumber)
2755 				{
2756 					selectedj = index_selected(j);
2757 					if(selectedj<0 && !del)
2758 					{
2759 						if(NumFatoms == NULL)
2760 							NumFatoms = g_malloc((NFatoms+1)*sizeof(gint));
2761 						else
2762 							NumFatoms = g_realloc(NumFatoms,
2763 									(NFatoms+1)*sizeof(gint));
2764 						NumFatoms[NFatoms] = geometry[j].N;
2765 						NFatoms++;
2766 					}
2767 					if(selectedj>=0 && del)
2768 					{
2769 						if((NFatoms-1)>0)
2770 						{
2771 							for(k=selectedj;k<(gint)(NFatoms-1);k++)
2772 								NumFatoms[k] = NumFatoms[k+1];
2773 
2774 							NumFatoms = g_realloc(NumFatoms,
2775 									(NFatoms-1)*sizeof(gint));
2776 							NFatoms--;
2777 						}
2778 						else
2779 						{
2780 							g_free(NumFatoms);
2781 							NumFatoms = NULL;
2782 							NFatoms = 0;
2783 						}
2784 					}
2785 
2786 				}
2787 			}
2788 			break;
2789 
2790 		}
2791 	}
2792 	drawGeom();
2793 	return OK;
2794 }
2795 /*****************************************************************************/
select_atoms_by_rectangle(gdouble x,gdouble y)2796 void select_atoms_by_rectangle(gdouble x,gdouble y)
2797 {
2798 	gint i;
2799 	gdouble x1=0;
2800 	gdouble y1=0;
2801 	gdouble x2=0;
2802 	gdouble y2=0;
2803 	gdouble xi;
2804 	gdouble yi;
2805 
2806 	if(x>BeginX)
2807 	{
2808 		x1 = BeginX;
2809 		x2 = x;
2810 	}
2811 	else
2812 	{
2813 		x1 = x;
2814 		x2 = BeginX;
2815 	}
2816 	if(y>BeginY)
2817 	{
2818 		y1 = BeginY;
2819 		y2 = y;
2820 	}
2821 	else
2822 	{
2823 		y1 = y;
2824 		y2 = BeginY;
2825 	}
2826 	if(!ShiftKeyPressed)
2827 	{
2828 		if(!NumFatoms)
2829 			g_free(NumFatoms);
2830 		NumFatoms = NULL;
2831 
2832 		NFatoms = 0;
2833 	}
2834 	for(i=0;i<(gint)Natoms;i++)
2835 	{
2836 		if(!geometry[i].show) continue;
2837 		xi = geometry[i].Xi;
2838 		yi = geometry[i].Yi;
2839 		if(xi>=x1 && xi<=x2 && yi>=y1 && yi<=y2 && !if_selected(i))
2840 		{
2841 			if(NumFatoms == NULL)
2842 				NumFatoms = g_malloc((NFatoms+1)*sizeof(gint));
2843 			else
2844 				NumFatoms = g_realloc(NumFatoms,(NFatoms+1)*sizeof(gint));
2845 			NumFatoms[NFatoms] = geometry[i].N;
2846 			NFatoms++;
2847 
2848 		}
2849 	}
2850 }
2851 /********************************************************************************/
draw_selection_rectangle(gdouble x,gdouble y)2852 void draw_selection_rectangle(gdouble x,gdouble y)
2853 {
2854 	gdouble xi=0;
2855 	gdouble yi=0;
2856 	gdouble xf=0;
2857 	gdouble yf=0;
2858         GdkColor color;
2859 	GdkColormap *colormap;
2860 
2861    	colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
2862 	color.red = 65535;
2863 	color.green = 65535;
2864 	color.blue = 65535;
2865 
2866 	drawGeom();
2867         gdk_colormap_alloc_color(colormap,&color,FALSE,TRUE);
2868     	gdk_gc_set_foreground(gc,&color);
2869 	if(x>BeginX)
2870 	{
2871 		xi = BeginX;
2872 		xf = x-BeginX;
2873 	}
2874 	else
2875 	{
2876 		xi = x;
2877 		xf = BeginX-x;
2878 	}
2879 	if(y>BeginY)
2880 	{
2881 		yi = BeginY;
2882 		yf = y-BeginY;
2883 	}
2884 	else
2885 	{
2886 		yi = y;
2887 		yf = BeginY-y;
2888 	}
2889 	gdk_gc_set_line_attributes(gc,1,GDK_LINE_DOUBLE_DASH,GDK_CAP_NOT_LAST,GDK_JOIN_MITER);
2890 #if !defined(G_OS_WIN32)
2891   	gdk_draw_rectangle (GeomDrawingArea->window,gc,FALSE,xi, yi, xf, yf);
2892 #else
2893   	gdk_draw_rectangle (GeomDrawingArea->window,GeomDrawingArea->style->white_gc,FALSE,xi, yi, xf, yf);
2894 #endif
2895 }
2896 /********************************************************************************/
draw_selection_circle(gdouble x,gdouble y)2897 void draw_selection_circle(gdouble x,gdouble y)
2898 {
2899 	gdouble xi=0;
2900 	gdouble yi=0;
2901 	gdouble xf=0;
2902 	gdouble yf=0;
2903         GdkColor color;
2904 	GdkColormap *colormap;
2905 
2906    	colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
2907 	color.red = 65535;
2908 	color.green = 65535;
2909 	color.blue = 65535;
2910 
2911 	drawGeom();
2912         gdk_colormap_alloc_color(colormap,&color,FALSE,TRUE);
2913     	gdk_gc_set_foreground(gc,&color);
2914 /*	GDK_LINE_ON_OFF_DASH, GDK_LINE_DOUBLE_DASH*/
2915 	if(x>BeginX)
2916 	{
2917 		xi = BeginX;
2918 		xf = x-BeginX;
2919 	}
2920 	else
2921 	{
2922 		xi = x;
2923 		xf = BeginX-x;
2924 	}
2925 	if(y>BeginY)
2926 	{
2927 		yi = BeginY;
2928 		yf = y-BeginY;
2929 	}
2930 	else
2931 	{
2932 		yi = y;
2933 		yf = BeginY-y;
2934 	}
2935 	gdk_gc_set_line_attributes(gc,1,GDK_LINE_DOUBLE_DASH,GDK_CAP_NOT_LAST,GDK_JOIN_MITER);
2936 	gdk_draw_arc(GeomDrawingArea->window,gc,FALSE,xi,yi,xf,yf,0,380*64);
2937 }
2938 /********************************************************************************/
delete_molecule()2939 static void delete_molecule()
2940 {
2941 	if(Natoms<1) return;
2942 
2943 	add_geometry_to_fifo();
2944 	geometry0 =Free_One_Geom(geometry0,Natoms);
2945 	geometry =Free_One_Geom(geometry,Natoms);
2946 	Natoms = 0;
2947 
2948 	if(NumFatoms) g_free(NumFatoms);
2949   	NumFatoms = NULL;
2950   	NFatoms = 0;
2951 
2952 	create_GeomXYZ_from_draw_grometry();
2953 
2954 	Ddef = FALSE;
2955 	drawGeom();
2956 	set_statubar_pop_sel_atom();
2957 	free_text_to_draw();
2958 	change_of_center(NULL,NULL);
2959 }
2960 /********************************************************************************/
copySelectedAtoms()2961 void copySelectedAtoms()
2962 {
2963 	Fragment F;
2964 	gint i;
2965 	gint k;
2966 
2967 	if(Frag.NAtoms) FreeFragment(&Frag);
2968 	Frag.NAtoms = 0;
2969 	Frag.Atoms = NULL;
2970 	if(NFatoms<1) return;
2971 	F.NAtoms = NFatoms;
2972 	F.Atoms = g_malloc(F.NAtoms*sizeof(Atom));
2973 
2974 	for (k=0;k<(gint)NFatoms;k++)
2975 	{
2976 		for (i=0;i<(gint)Natoms;i++)
2977 		{
2978 			if(NumFatoms[k]==geometry[i].N)
2979 			{
2980 				F.Atoms[k].Symb=g_strdup(geometry[i].Prop.symbol);
2981 				F.Atoms[k].mmType=g_strdup(geometry[i].mmType);
2982 				F.Atoms[k].pdbType=g_strdup(geometry[i].pdbType);
2983 				F.Atoms[k].Residue = g_strdup(geometry[i].Residue);
2984 				F.Atoms[k].Coord[0]=geometry[i].X;
2985 				F.Atoms[k].Coord[1]=geometry[i].Y;
2986 				F.Atoms[k].Coord[2]=geometry[i].Z;
2987 				F.Atoms[k].Charge=geometry[i].Charge;
2988 				break;
2989 			}
2990 		}
2991 		if(i==Natoms) break;
2992 	}
2993 	if(k!=NFatoms)
2994 	{
2995 		if(F.Atoms) g_free(F.Atoms);
2996 		return;
2997 	}
2998 
2999 	F.atomToDelete = -1;
3000 	F.atomToBondTo = -1;
3001 	F.angleAtom    = -1;
3002 
3003 	CenterFrag(&F);
3004 
3005 	Frag = F;
3006 	SetOperation (NULL,ADDFRAGMENT);
3007 }
3008 /********************************************************************************/
freeList(gchar ** strs,gint nlist)3009 static gchar** freeList(gchar** strs, gint nlist)
3010 {
3011 	gint i;
3012 
3013 	for(i=0;i<nlist;i++)
3014 		if(strs[i])
3015 			g_free(strs[i]);
3016 
3017 	g_free(strs);
3018 
3019 	return NULL;
3020 }
3021 /********************************************************************************/
setMMTypeOfselectedAtoms(GtkWidget * button,GtkWidget * entry)3022 static void setMMTypeOfselectedAtoms(GtkWidget* button, GtkWidget* entry)
3023 {
3024 	gint i;
3025 	gint k = 0;
3026 	G_CONST_RETURN gchar *tName;
3027 
3028 
3029 	if(Natoms<1) return;
3030 	tName = gtk_entry_get_text(GTK_ENTRY(entry));
3031 	if(strlen(tName)<1) return;
3032 	if(NFatoms<1) return;
3033 	if(!NumFatoms) return;
3034 
3035 	for (k=0;k<(gint)NFatoms;k++)
3036 	for (i=0;i<(gint)Natoms;i++)
3037 	{
3038 		if(geometry[i].N== NumFatoms[k])
3039 		{
3040 			if(geometry[i].mmType) g_free(geometry[i].mmType);
3041 			geometry[i].mmType = g_strdup(tName);
3042 			if(geometry0[i].mmType) g_free(geometry0[i].mmType);
3043 			geometry0[i].mmType = g_strdup(tName);
3044 		}
3045 	}
3046 	create_GeomXYZ_from_draw_grometry();
3047 	if(!strcmp(tName,"N3")) reset_all_connections();
3048 	drawGeom();
3049 }
3050 /********************************************************************************/
setMMTypeOfselectedAtomsDlg()3051 void setMMTypeOfselectedAtomsDlg()
3052 {
3053 	GtkWidget *winDlg;
3054 	GtkWidget *button;
3055 	GtkWidget *hbox;
3056 	GtkWidget *entry;
3057 	GtkWidget *frame;
3058 	GtkWidget *vboxframe;
3059 	gint n=0;
3060 	gchar** t = NULL;
3061 	gchar tmp[100] = "UNK";
3062 	gint i;
3063 	gint k;
3064 
3065 	if(Natoms<1) return;
3066 	if(NFatoms<1) return;
3067 	if(!NumFatoms) return;
3068 
3069 	k=0;
3070 	for (i=0;i<(gint)Natoms;i++)
3071 	{
3072 		if(geometry[i].N == NumFatoms[k])
3073 		{
3074 			sprintf(tmp,"%s",geometry[i].mmType);
3075 			break;
3076 		}
3077 	}
3078 
3079 	winDlg = gtk_dialog_new();
3080 	gtk_window_set_title(GTK_WINDOW(winDlg),_("Set MM Type of selected atoms"));
3081 	gtk_window_set_position(GTK_WINDOW(winDlg),GTK_WIN_POS_CENTER);
3082 	gtk_window_set_transient_for(GTK_WINDOW(winDlg),GTK_WINDOW(GeomDlg));
3083 
3084 	add_child(GeomDlg,winDlg,gtk_widget_destroy,_(" Set Sel. Type."));
3085 	g_signal_connect(G_OBJECT(winDlg),"delete_event",(GCallback)delete_child,NULL);
3086 
3087 	frame = gtk_frame_new (NULL);
3088 	gtk_frame_set_shadow_type( GTK_FRAME(frame),GTK_SHADOW_ETCHED_OUT);
3089 
3090 	gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
3091 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->vbox), frame,TRUE,TRUE,0);
3092 
3093 	gtk_widget_show (frame);
3094 
3095 	vboxframe = create_vbox(frame);
3096 	hbox=create_hbox_false(vboxframe);
3097 	n=0;
3098 	t = getListGeomMMTypes(&n);
3099 	entry = create_label_combo(hbox,_(" Type Name : "),t,n, TRUE,-1,-1);
3100 	if(strcmp(tmp,"UNK")) gtk_entry_set_text(GTK_ENTRY(entry),tmp);
3101 	gtk_editable_set_editable((GtkEditable*) entry,TRUE);
3102 	if(t) freeList(t,n);
3103 
3104 	gtk_widget_realize(winDlg);
3105 
3106 	button = create_button(winDlg,_("Cancel"));
3107 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->action_area), button,TRUE,TRUE,0);
3108 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)delete_child,GTK_OBJECT(winDlg));
3109 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
3110 
3111 	button = create_button(winDlg,_("OK"));
3112 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->action_area), button,TRUE,TRUE,0);
3113 	g_signal_connect(G_OBJECT(button), "clicked",(GCallback)setMMTypeOfselectedAtoms,entry);
3114 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)delete_child,GTK_OBJECT(winDlg));
3115 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
3116 	gtk_widget_grab_default(button);
3117 
3118 
3119 	gtk_widget_show_all(winDlg);
3120 }
3121 /********************************************************************************/
setPDBTypeOfselectedAtoms(GtkWidget * button,GtkWidget * entry)3122 static void setPDBTypeOfselectedAtoms(GtkWidget* button, GtkWidget* entry)
3123 {
3124 	gint i;
3125 	gint k = 0;
3126 	G_CONST_RETURN gchar *tName;
3127 
3128 
3129 	if(Natoms<1) return;
3130 	tName = gtk_entry_get_text(GTK_ENTRY(entry));
3131 	if(strlen(tName)<1) return;
3132 	if(NFatoms<1) return;
3133 	if(!NumFatoms) return;
3134 
3135 	for (k=0;k<(gint)NFatoms;k++)
3136 	for (i=0;i<(gint)Natoms;i++)
3137 	{
3138 		if(geometry[i].N== NumFatoms[k])
3139 		{
3140 			if(geometry[i].pdbType) g_free(geometry[i].pdbType);
3141 			geometry[i].pdbType = g_strdup(tName);
3142 			if(geometry0[i].pdbType) g_free(geometry0[i].pdbType);
3143 			geometry0[i].pdbType = g_strdup(tName);
3144 		}
3145 	}
3146 	create_GeomXYZ_from_draw_grometry();
3147 	drawGeom();
3148 }
3149 /********************************************************************************/
setPDBTypeOfselectedAtomsDlg()3150 void setPDBTypeOfselectedAtomsDlg()
3151 {
3152 	GtkWidget *winDlg;
3153 	GtkWidget *button;
3154 	GtkWidget *hbox;
3155 	GtkWidget *entry;
3156 	GtkWidget *frame;
3157 	GtkWidget *vboxframe;
3158 	gint n=0;
3159 	gchar** t = NULL;
3160 	gchar tmp[100] = "UNK";
3161 	gint i;
3162 	gint k;
3163 
3164 	if(Natoms<1) return;
3165 	if(NFatoms<1) return;
3166 	if(!NumFatoms) return;
3167 
3168 	k=0;
3169 	for (i=0;i<(gint)Natoms;i++)
3170 	{
3171 		if(geometry[i].N == NumFatoms[k])
3172 		{
3173 			sprintf(tmp,"%s",geometry[i].pdbType);
3174 			break;
3175 		}
3176 	}
3177 
3178 	winDlg = gtk_dialog_new();
3179 	gtk_window_set_title(GTK_WINDOW(winDlg),_("Set PDB Type of selected atoms"));
3180 	gtk_window_set_position(GTK_WINDOW(winDlg),GTK_WIN_POS_CENTER);
3181 	gtk_window_set_transient_for(GTK_WINDOW(winDlg),GTK_WINDOW(GeomDlg));
3182 
3183 	add_child(GeomDlg,winDlg,gtk_widget_destroy,_(" Set Sel. Type."));
3184 	g_signal_connect(G_OBJECT(winDlg),"delete_event",(GCallback)delete_child,NULL);
3185 
3186 	frame = gtk_frame_new (NULL);
3187 	gtk_frame_set_shadow_type( GTK_FRAME(frame),GTK_SHADOW_ETCHED_OUT);
3188 
3189 	gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
3190 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->vbox), frame,TRUE,TRUE,0);
3191 
3192 	gtk_widget_show (frame);
3193 
3194 	vboxframe = create_vbox(frame);
3195 	hbox=create_hbox_false(vboxframe);
3196 	n=0;
3197 	t = getListPDBTypesFromGeom(&n);
3198 	entry = create_label_combo(hbox,_(" Type Name : "),t,n, TRUE,-1,-1);
3199 	if(strcmp(tmp,"UNK")) gtk_entry_set_text(GTK_ENTRY(entry),tmp);
3200 	gtk_editable_set_editable((GtkEditable*) entry,TRUE);
3201 	if(t) freeList(t,n);
3202 
3203 	gtk_widget_realize(winDlg);
3204 
3205 	button = create_button(winDlg,_("Cancel"));
3206 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->action_area), button,TRUE,TRUE,0);
3207 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)delete_child,GTK_OBJECT(winDlg));
3208 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
3209 
3210 	button = create_button(winDlg,_("OK"));
3211 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->action_area), button,TRUE,TRUE,0);
3212 	g_signal_connect(G_OBJECT(button), "clicked",(GCallback)setPDBTypeOfselectedAtoms,entry);
3213 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)delete_child,GTK_OBJECT(winDlg));
3214 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
3215 	gtk_widget_grab_default(button);
3216 
3217 
3218 	gtk_widget_show_all(winDlg);
3219 }
3220 /********************************************************************************/
setResidueNameOfselectedAtoms(GtkWidget * button,GtkWidget * entry)3221 static void setResidueNameOfselectedAtoms(GtkWidget* button, GtkWidget* entry)
3222 {
3223 	gint i;
3224 	gint k = 0;
3225 	G_CONST_RETURN gchar *tName;
3226 
3227 
3228 	if(Natoms<1) return;
3229 	tName = gtk_entry_get_text(GTK_ENTRY(entry));
3230 	if(strlen(tName)<1) return;
3231 	if(NFatoms<1) return;
3232 	if(!NumFatoms) return;
3233 
3234 	for (k=0;k<(gint)NFatoms;k++)
3235 	for (i=0;i<(gint)Natoms;i++)
3236 	{
3237 		if(geometry[i].N== NumFatoms[k])
3238 		{
3239 			if(geometry[i].Residue) g_free(geometry[i].Residue);
3240 			geometry[i].Residue = g_strdup(tName);
3241 			if(geometry0[i].Residue) g_free(geometry0[i].Residue);
3242 			geometry0[i].Residue = g_strdup(tName);
3243 		}
3244 	}
3245 	create_GeomXYZ_from_draw_grometry();
3246 	drawGeom();
3247 }
3248 /********************************************************************************/
getResidueNameOfselectedAtoms()3249 static gchar* getResidueNameOfselectedAtoms()
3250 {
3251 	gint i;
3252 	gint k = 0;
3253 
3254 	if(Natoms<1) return g_strdup("DUM");
3255 	if(NFatoms<1) return  g_strdup("DUM");
3256 	if(!NumFatoms) return  g_strdup("DUM");
3257 
3258 	for (k=0;k<(gint)NFatoms;k++)
3259 	for (i=0;i<(gint)Natoms;i++)
3260 	{
3261 		if(geometry[i].N== NumFatoms[k])
3262 		{
3263 			 g_strdup(geometry[i].Residue);
3264 		}
3265 	}
3266 	return  g_strdup("DUM");
3267 }
3268 /********************************************************************************/
setResidueNameOfselectedAtomsDlg()3269 void setResidueNameOfselectedAtomsDlg()
3270 {
3271 	GtkWidget *winDlg;
3272 	GtkWidget *button;
3273 	GtkWidget *hbox;
3274 	GtkWidget *entry;
3275 	GtkWidget *frame;
3276 	GtkWidget *vboxframe;
3277 	gint n=0;
3278 	gchar** t = NULL;
3279 	gchar tmp[100] = "UNK";
3280 	gint i;
3281 	gint k;
3282 
3283 	if(Natoms<1) return;
3284 	if(NFatoms<1) return;
3285 	if(!NumFatoms) return;
3286 
3287 	k=0;
3288 	for (i=0;i<(gint)Natoms;i++)
3289 	{
3290 		if(geometry[i].N == NumFatoms[k])
3291 		{
3292 			sprintf(tmp,"%s",geometry[i].pdbType);
3293 			break;
3294 		}
3295 	}
3296 
3297 	winDlg = gtk_dialog_new();
3298 	gtk_window_set_title(GTK_WINDOW(winDlg),_("Set Residue name of selected atoms"));
3299 	gtk_window_set_position(GTK_WINDOW(winDlg),GTK_WIN_POS_CENTER);
3300 	gtk_window_set_transient_for(GTK_WINDOW(winDlg),GTK_WINDOW(GeomDlg));
3301 
3302 	add_child(GeomDlg,winDlg,gtk_widget_destroy,_(" Set Sel. Type."));
3303 	g_signal_connect(G_OBJECT(winDlg),"delete_event",(GCallback)delete_child,NULL);
3304 
3305 	frame = gtk_frame_new (NULL);
3306 	gtk_frame_set_shadow_type( GTK_FRAME(frame),GTK_SHADOW_ETCHED_OUT);
3307 
3308 	gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
3309 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->vbox), frame,TRUE,TRUE,0);
3310 
3311 	gtk_widget_show (frame);
3312 
3313 	vboxframe = create_vbox(frame);
3314 	hbox=create_hbox_false(vboxframe);
3315 	n=1;
3316 	t = g_malloc(sizeof(gchar*)*2);
3317 	t[0]  = NULL;
3318 	t[1]  = NULL;
3319 	t[0] = getResidueNameOfselectedAtoms();
3320 
3321 	entry = create_label_combo(hbox,_(" Residue Name : "),t,n, TRUE,-1,-1);
3322 	g_free(t[0]);
3323 	g_free(t);
3324 	if(strcmp(tmp,"UNK")) gtk_entry_set_text(GTK_ENTRY(entry),tmp);
3325 	gtk_editable_set_editable((GtkEditable*) entry,TRUE);
3326 
3327 	gtk_widget_realize(winDlg);
3328 
3329 	button = create_button(winDlg,_("Cancel"));
3330 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->action_area), button,TRUE,TRUE,0);
3331 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)delete_child,GTK_OBJECT(winDlg));
3332 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
3333 
3334 	button = create_button(winDlg,_("OK"));
3335 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->action_area), button,TRUE,TRUE,0);
3336 	g_signal_connect(G_OBJECT(button), "clicked",(GCallback)setResidueNameOfselectedAtoms,entry);
3337 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)delete_child,GTK_OBJECT(winDlg));
3338 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
3339 	gtk_widget_grab_default(button);
3340 
3341 
3342 	gtk_widget_show_all(winDlg);
3343 }
3344 /********************************************************************************/
getListCharges(gint * nlist)3345 gchar** getListCharges(gint* nlist)
3346 {
3347 
3348 	gchar** t = NULL;
3349 
3350 	gint i;
3351 	gint j;
3352 
3353 	*nlist = 0;
3354 	if(Natoms<1) return NULL;
3355 
3356 	t = g_malloc(Natoms*sizeof(gchar*));
3357 	*nlist = 1;
3358 	t[*nlist-1] =  g_strdup_printf("%f",geometry0[0].Charge);
3359 
3360 
3361 	for(i=1;i<Natoms;i++)
3362 	{
3363 		gboolean inList = FALSE;
3364 		for(j=0;j<*nlist;j++)
3365 		{
3366 			if(geometry0[i].Charge==atof(t[j]))
3367 			{
3368 				inList = TRUE;
3369 				break;
3370 			}
3371 		}
3372 		if(!inList)
3373 		{
3374 			(*nlist)++;
3375 			t[*nlist-1] =  g_strdup_printf("%f",geometry0[i].Charge);
3376 		}
3377 	}
3378 	t = g_realloc(t,*nlist*sizeof(gchar*));
3379 
3380 	return t;
3381 }
3382 /********************************************************************************/
setChargeOfselectedAtoms(GtkWidget * button,GtkWidget * entry)3383 static void setChargeOfselectedAtoms(GtkWidget* button, GtkWidget* entry)
3384 {
3385 	gint i;
3386 	gint k = 0;
3387 	G_CONST_RETURN gchar *tValue;
3388 
3389 
3390 	if(Natoms<1) return;
3391 	tValue = gtk_entry_get_text(GTK_ENTRY(entry));
3392 	if(strlen(tValue)<1) return;
3393 	if(NFatoms<1) return;
3394 	if(!NumFatoms) return;
3395 
3396 	for (k=0;k<(gint)NFatoms;k++)
3397 	for (i=0;i<(gint)Natoms;i++)
3398 	{
3399 		if(geometry[i].N== NumFatoms[k])
3400 		{
3401 			geometry[i].Charge = atof(tValue);
3402 			geometry0[i].Charge = atof(tValue);
3403 		}
3404 	}
3405 	create_GeomXYZ_from_draw_grometry();
3406 
3407 	drawGeom();
3408 }
3409 /********************************************************************************/
setChargeOfselectedAtomsDlg()3410 void setChargeOfselectedAtomsDlg()
3411 {
3412 	GtkWidget *winDlg;
3413 	GtkWidget *button;
3414 	GtkWidget *hbox;
3415 	GtkWidget *entry;
3416 	GtkWidget *frame;
3417 	GtkWidget *vboxframe;
3418 	gint n=0;
3419 	gchar** t = NULL;
3420 	gchar tmp[100] = "UNK";
3421 	gint i;
3422 	gint k;
3423 
3424 	if(Natoms<1) return;
3425 	if(NFatoms<1) return;
3426 	if(!NumFatoms) return;
3427 
3428 	k=0;
3429 	for (i=0;i<(gint)Natoms;i++)
3430 	{
3431 		if(geometry[i].N == NumFatoms[k])
3432 		{
3433 			sprintf(tmp,"%f",geometry[i].Charge);
3434 			break;
3435 		}
3436 	}
3437 
3438 	winDlg = gtk_dialog_new();
3439 	gtk_window_set_title(GTK_WINDOW(winDlg),_("Set Charge of selected atoms"));
3440 	gtk_window_set_position(GTK_WINDOW(winDlg),GTK_WIN_POS_CENTER);
3441 	gtk_window_set_transient_for(GTK_WINDOW(winDlg),GTK_WINDOW(GeomDlg));
3442 
3443 	add_child(GeomDlg,winDlg,gtk_widget_destroy,_(" Set Sel. Charge."));
3444 	g_signal_connect(G_OBJECT(winDlg),"delete_event",(GCallback)delete_child,NULL);
3445 
3446 	frame = gtk_frame_new (NULL);
3447 	gtk_frame_set_shadow_type( GTK_FRAME(frame),GTK_SHADOW_ETCHED_OUT);
3448 
3449 	gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
3450 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->vbox), frame,TRUE,TRUE,0);
3451 
3452 	gtk_widget_show (frame);
3453 
3454 	vboxframe = create_vbox(frame);
3455 	hbox=create_hbox_false(vboxframe);
3456 	n=0;
3457 	t = getListCharges(&n);
3458 	entry = create_label_combo(hbox, _(" Charge : "),t,n, TRUE,-1,-1);
3459 	if(strcmp(tmp,"UNK")) gtk_entry_set_text(GTK_ENTRY(entry),tmp);
3460 	gtk_editable_set_editable((GtkEditable*) entry,TRUE);
3461 	if(t) freeList(t,n);
3462 
3463 	gtk_widget_realize(winDlg);
3464 
3465 	button = create_button(winDlg,_("Cancel"));
3466 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->action_area), button,TRUE,TRUE,0);
3467 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)delete_child,GTK_OBJECT(winDlg));
3468 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
3469 
3470 	button = create_button(winDlg,_("OK"));
3471 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->action_area), button,TRUE,TRUE,0);
3472 	g_signal_connect(G_OBJECT(button), "clicked",(GCallback)setChargeOfselectedAtoms,entry);
3473 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)delete_child,GTK_OBJECT(winDlg));
3474 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
3475 	gtk_widget_grab_default(button);
3476 
3477 
3478 	gtk_widget_show_all(winDlg);
3479 }
3480 /********************************************************************************/
scaleChargesOfSelectedAtoms(GtkWidget * button,GtkWidget * entry)3481 static void scaleChargesOfSelectedAtoms(GtkWidget* button, GtkWidget* entry)
3482 {
3483 	gint i;
3484 	gint k;
3485 	G_CONST_RETURN gchar *strEntry;
3486 	gdouble factor = 1.0;
3487 
3488 
3489 	if(Natoms<1) return;
3490 	if(NFatoms<1) return;
3491 	if(!NumFatoms) return;
3492 	strEntry = gtk_entry_get_text(GTK_ENTRY(entry));
3493 	if(strlen(strEntry)<1) return;
3494 	factor = atof(strEntry);
3495 
3496 	for (k=0;k<(gint)NFatoms;k++)
3497 	for (i=0;i<(gint)Natoms;i++)
3498 	{
3499 		if(geometry[i].N== NumFatoms[k])
3500 		{
3501 			geometry[i].Charge *= factor;
3502 			geometry0[i].Charge *= factor;
3503 		}
3504 	}
3505 
3506 	drawGeom();
3507 }
3508 /********************************************************************************/
scaleChargesOfSelectedAtomsDlg()3509 void scaleChargesOfSelectedAtomsDlg()
3510 {
3511 	GtkWidget *winDlg;
3512 	GtkWidget *button;
3513 	GtkWidget *hbox;
3514 	GtkWidget *label;
3515 	GtkWidget *entry;
3516 	GtkWidget *frame;
3517 	GtkWidget *vboxframe;
3518 
3519 	winDlg = gtk_dialog_new();
3520 	gtk_window_set_title(GTK_WINDOW(winDlg),_("Scale charges of selected atoms"));
3521 	gtk_window_set_position(GTK_WINDOW(winDlg),GTK_WIN_POS_CENTER);
3522 	gtk_window_set_transient_for(GTK_WINDOW(winDlg),GTK_WINDOW(GeomDlg));
3523 
3524 	add_child(GeomDlg,winDlg,gtk_widget_destroy,_(" Scal. Char. "));
3525 	g_signal_connect(G_OBJECT(winDlg),"delete_event",(GCallback)delete_child,NULL);
3526 
3527 	frame = gtk_frame_new (NULL);
3528 	gtk_frame_set_shadow_type( GTK_FRAME(frame),GTK_SHADOW_ETCHED_OUT);
3529 
3530 	gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
3531 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->vbox), frame,TRUE,TRUE,0);
3532 
3533 	gtk_widget_show (frame);
3534 
3535 	vboxframe = create_vbox(frame);
3536 	hbox=create_hbox_false(vboxframe);
3537 	label = gtk_label_new(_(" Factor : "));
3538 	gtk_box_pack_start( GTK_BOX(hbox), label,TRUE,TRUE,0);
3539 	entry = gtk_entry_new();
3540 	gtk_entry_set_text(GTK_ENTRY(entry),"1.0");
3541 	gtk_box_pack_start( GTK_BOX(hbox), entry,TRUE,TRUE,0);
3542 
3543 	gtk_widget_realize(winDlg);
3544 
3545 	button = create_button(winDlg,_("Cancel"));
3546 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->action_area), button,TRUE,TRUE,0);
3547 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)delete_child,GTK_OBJECT(winDlg));
3548 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
3549 
3550 	button = create_button(winDlg,_("OK"));
3551 	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(winDlg)->action_area), button,TRUE,TRUE,0);
3552 	g_signal_connect(G_OBJECT(button), "clicked",(GCallback)scaleChargesOfSelectedAtoms,entry);
3553 	g_signal_connect_swapped(G_OBJECT(button), "clicked",(GCallback)delete_child,GTK_OBJECT(winDlg));
3554 	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
3555 	gtk_widget_grab_default(button);
3556 
3557 
3558 	gtk_widget_show_all(winDlg);
3559 }
3560 /*****************************************************************************/
set_vect_ij(gint i,gint j,gdouble V[])3561 static void set_vect_ij(gint i, gint j, gdouble V[])
3562 {
3563 	V[0] = geometry0[j].X-geometry0[i].X;
3564 	V[1] = geometry0[j].Y-geometry0[i].Y;
3565 	V[2] = geometry0[j].Z-geometry0[i].Z;
3566 }
3567 /*****************************************************************************/
add_hydrogen_atoms(gint addToI,gint nH,gchar * HType)3568 static void add_hydrogen_atoms(gint addToI, gint nH, gchar* HType)
3569 {
3570 	static SAtomsProp propH = {0};
3571 	static gint begin = 0;
3572 	gint i;
3573 	gint k;
3574 	gdouble dist = 1.0;
3575 	gint geom = 0; /* 0=3D, 1=planar, 2=linear */
3576 	gdouble angle = 109.5*PI/180.0;
3577 	gint nV;
3578 	gint nC;
3579 	gint* listOfConnectedAtoms = NULL;
3580 
3581 	if(begin==0)
3582 	{
3583 		begin++;
3584 		propH = prop_atom_get("H");
3585 	}
3586 	dist = (geometry[addToI].Prop.covalentRadii+propH.covalentRadii)*0.9;
3587 	if(nH==1 && strcmp(geometry0[addToI].Prop.symbol,"N"))
3588 	{
3589 		angle = 180.0*PI/180.0;
3590 		geom = 2;
3591 	}
3592 	if(nH==2 && !strcmp(geometry0[addToI].Prop.symbol,"N"))
3593 	{
3594 		angle = 120.0*PI/180.0;
3595 		geom = 1;
3596 	}
3597 	nV =geometry[addToI].Prop.maximumBondValence;
3598 	if(nV<1) return;
3599 	listOfConnectedAtoms = g_malloc(nV*sizeof(gint));
3600 
3601 	if(Natoms>0)
3602 	{
3603 		geometry0 = g_realloc(geometry0,(Natoms+nH)*sizeof(GeomDef));
3604 		geometry = g_realloc(geometry,(Natoms+nH)*sizeof(GeomDef));
3605 	}
3606 	else
3607 	{
3608 		geometry0 = g_malloc(nH*sizeof(GeomDef));
3609 		geometry = g_malloc(nH*sizeof(GeomDef));
3610 	}
3611 
3612 
3613 	nC = 0;
3614 	for(i=0;i<(gint)Natoms;i++)
3615 	{
3616 		gint ni = geometry[i].N-1;
3617 		if(geometry[addToI].typeConnections[ni]>0)
3618 		{
3619 			listOfConnectedAtoms[nC] = i;
3620 			nC++;
3621 		}
3622 	}
3623 
3624 	for(i=0;i<nH;i++)
3625 	{
3626 		gdouble v1[3];
3627 		gdouble v2[3];
3628 		gdouble v3[3];
3629 		gdouble v4[3];
3630 		gdouble v5[3];
3631 		for(k=0;k<3;k++)
3632 			v1[k] = rand()/(gdouble)RAND_MAX-0.5;
3633 		v3d_normal(v1);
3634 
3635 		switch (nC)
3636 		{
3637 			case 1:
3638 				{
3639 					set_vect_ij(addToI, listOfConnectedAtoms[0], v2);
3640 					v3d_normal(v2);
3641 					v3d_cross(v1,v2,v3);
3642 					v3d_normal(v3);
3643 					v3d_scale(v2,cos(angle));
3644 					v3d_scale(v3,sin(angle));
3645 					v3d_add(v2,v3,v1);
3646 					break;
3647 				}
3648 			case 2:
3649 				{
3650 					set_vect_ij(addToI, listOfConnectedAtoms[0], v2);
3651 					v3d_normal(v2);
3652 					set_vect_ij(addToI, listOfConnectedAtoms[1], v3);
3653 					v3d_normal(v3);
3654 					if(geom==0 || nH>1)
3655 					{
3656 						v3d_add(v2,v3,v4);
3657 						if(v3d_length(v4)>1e-2) v3d_normal(v4);
3658 						v3d_scale(v4,-1.0);
3659 						v3d_cross(v2,v3,v5);
3660 						if(v3d_length(v5)<1e-2)
3661 							for(k=0;k<3;k++) v5[k] = rand()/(gdouble)RAND_MAX-0.5;
3662 						v3d_normal(v5);
3663 						v3d_scale(v4,0.5);
3664 						v3d_scale(v5,0.5);
3665 						v3d_add(v4,v5,v1);
3666 						v3d_normal(v1);
3667 					}
3668 					else
3669 					{
3670 						v3d_add(v2,v3,v1);
3671 						v3d_normal(v1);
3672 						v3d_scale(v1,-1.0);
3673 					}
3674 					break;
3675 				}
3676 			default:
3677 				if(nC>=3)
3678 				{
3679 					set_vect_ij(addToI, listOfConnectedAtoms[nC-3], v2);
3680 					v3d_normal(v2);
3681 					set_vect_ij(addToI, listOfConnectedAtoms[nC-2], v3);
3682 					v3d_normal(v3);
3683 					set_vect_ij(addToI, listOfConnectedAtoms[nC-1], v4);
3684 					v3d_normal(v4);
3685 					v3d_add(v2,v3,v5);
3686 					v3d_add(v5,v4,v1);
3687 					if(v3d_length(v1)<2e-1) v3d_cross(v2,v3,v1);
3688 					v3d_normal(v1);
3689 					v3d_scale(v1,-1.0);
3690 					break;
3691 				}
3692 
3693 		}
3694 		geometry[Natoms].X= geometry0[addToI].X + dist*v1[0];
3695 		geometry[Natoms].Y= geometry0[addToI].Y + dist*v1[1];
3696 		geometry[Natoms].Z= geometry0[addToI].Z + dist*v1[2];
3697 		geometry[Natoms].Prop = prop_atom_get("H");
3698 		geometry[Natoms].pdbType = g_strdup(HType);
3699 		if(Natoms==0)
3700 		{
3701 			geometry[Natoms].Residue = g_strdup("H");
3702 			geometry[Natoms].ResidueNumber = 0;
3703 		}
3704 		else
3705 		{
3706 			geometry[Natoms].Residue = g_strdup(geometry[addToI].Residue);
3707 			geometry[Natoms].ResidueNumber = geometry[addToI].ResidueNumber;
3708 		}
3709 		{
3710 			gdouble charge;
3711 			gchar* mmType = getMMTypeFromPDBTpl(geometry[Natoms].Residue,geometry[Natoms].pdbType,&charge);
3712 			if(!strcmp(mmType,"UNK"))
3713 			{
3714 				geometry[Natoms].mmType = g_strdup(HType);
3715 				g_free(mmType);
3716 			}
3717 			else geometry[Natoms].mmType = mmType;
3718 		}
3719 		geometry[Natoms].Layer = geometry[addToI].Layer;
3720 		geometry[Natoms].N = Natoms+1;
3721 		geometry[Natoms].typeConnections = NULL;
3722 		geometry[Natoms].Charge = 0.0;
3723 		geometry[Natoms].Variable = TRUE;
3724 		geometry[Natoms].show = ShowHydrogenAtoms;
3725 
3726 		geometry0[Natoms].X = geometry[Natoms].X;
3727 		geometry0[Natoms].Y = geometry[Natoms].Y;
3728 		geometry0[Natoms].Z = geometry[Natoms].Z;
3729 		geometry0[Natoms].Prop = prop_atom_get("H");
3730 		geometry0[Natoms].mmType = g_strdup(geometry[Natoms].mmType);
3731 		geometry0[Natoms].pdbType = g_strdup(geometry[Natoms].pdbType);
3732 		geometry0[Natoms].Layer = geometry[Natoms].Layer;
3733 		geometry0[Natoms].Residue = g_strdup(geometry[Natoms].Residue);
3734 		geometry0[Natoms].ResidueNumber = geometry[Natoms].ResidueNumber;
3735 		geometry0[Natoms].Charge = 0.0;
3736 		geometry0[Natoms].Variable = TRUE;
3737 		geometry0[Natoms].N = geometry[Natoms].N;
3738 		geometry0[Natoms].show = geometry[Natoms].show;
3739 		geometry0[Natoms].typeConnections = NULL;
3740 
3741 		Natoms++;
3742 		nC++;
3743 		listOfConnectedAtoms = g_realloc(listOfConnectedAtoms, nC*sizeof(gint));
3744 		listOfConnectedAtoms[nC-1] = Natoms-1;
3745 	}
3746 	{
3747 		gint i,j;
3748 		for(i=0;i<(gint)Natoms-nH;i++)
3749 		{
3750 			geometry[i].typeConnections = g_realloc(geometry[i].typeConnections,Natoms*sizeof(gint));
3751 			for(j=Natoms-nH;j<(gint)Natoms;j++) geometry[i].typeConnections[j] = 0;
3752 			geometry0[i].typeConnections = g_realloc(geometry0[i].typeConnections,Natoms*sizeof(gint));
3753 			for(j=Natoms-nH;j<(gint)Natoms;j++) geometry0[i].typeConnections[j] = 0;
3754 		}
3755 		for(i=(gint)Natoms-nH;i<(gint)Natoms;i++)
3756 		{
3757 			geometry[i].typeConnections = g_malloc(Natoms*sizeof(gint));
3758 			for(j=0;j<(gint)Natoms;j++) geometry[i].typeConnections[j] = 0;
3759 			geometry0[i].typeConnections = g_malloc(Natoms*sizeof(gint));
3760 			for(j=0;j<(gint)Natoms;j++) geometry0[i].typeConnections[j] = 0;
3761 		}
3762 		for(i=(gint)Natoms-nH;i<(gint)Natoms;i++)
3763 		{
3764 			geometry[addToI].typeConnections[geometry[i].N-1] = 1;
3765 			geometry0[addToI].typeConnections[geometry0[i].N-1] = 1;
3766 			geometry[i].typeConnections[geometry[addToI].N-1] = 1;
3767 			geometry0[i].typeConnections[geometry0[addToI].N-1] = 1;
3768 		}
3769 		/* adjust_multiple_bonds_with_one_atom(addToI);*/
3770 	}
3771 	if(listOfConnectedAtoms) g_free(listOfConnectedAtoms);
3772 }
3773 /*****************************************************************************/
add_hydrogen_atom(gint addToI)3774 static gboolean add_hydrogen_atom(gint addToI)
3775 {
3776 	gint nMultiple = 0;
3777 	gint nAll = 0;
3778 	gchar HType[100] = "H";
3779 	gint j;
3780 	gint nV = 0;
3781 	gint nH = 0;
3782 
3783 
3784 	if(Natoms<1 ) return FALSE;
3785 	if(addToI>Natoms-1) return FALSE;
3786 
3787 	nV =geometry[addToI].Prop.maximumBondValence;
3788 	if(nV<1) return FALSE;
3789 
3790 	for(j=0;j<(gint)Natoms;j++)
3791 	{
3792 		gint nj = geometry[j].N-1;
3793 		if(geometry[addToI].typeConnections[nj]>1) nMultiple++;
3794 		nAll += geometry[addToI].typeConnections[nj];
3795 	}
3796 
3797 	nH = nV - nAll;
3798 	if(nH<1)
3799 	{
3800 		return FALSE;
3801 	}
3802 	if(nAll>=geometry[addToI].Prop.maximumBondValence && nMultiple==0)
3803 	{
3804 		return FALSE;
3805 	}
3806 
3807 
3808 	if(!strcmp(geometry[addToI].pdbType,"CA")) sprintf(HType,"HA");
3809 	else if(!strcmp(geometry[addToI].pdbType,"OH")) sprintf(HType,"HO");
3810 	else if(strstr(geometry[addToI].pdbType,"OE")) sprintf(HType,"HO");
3811 	else if(strstr(geometry[addToI].pdbType,"OD")) sprintf(HType,"HO");
3812 	else if(!strcmp(geometry[addToI].pdbType,"OG1")) sprintf(HType,"HG1");
3813 	else if(!strcmp(geometry[addToI].pdbType,"CT")) sprintf(HType,"HT");
3814 	else if(!strcmp(geometry[addToI].pdbType,"CB")) sprintf(HType,"HB1");
3815 	else if(!strcmp(geometry[addToI].pdbType,"SG")) sprintf(HType,"HG");
3816 	else if(!strcmp(geometry[addToI].pdbType,"CD1")) sprintf(HType,"HD11");
3817 	else if(!strcmp(geometry[addToI].pdbType,"CD2")) sprintf(HType,"HD22");
3818 	else if(strstr(geometry[addToI].pdbType,"CD")) sprintf(HType,"HD1");
3819 	else if(!strcmp(geometry[addToI].pdbType,"CG1")) sprintf(HType,"HG11");
3820 	else if(!strcmp(geometry[addToI].pdbType,"CG2")) sprintf(HType,"HG22");
3821 	else if(strstr(geometry[addToI].pdbType,"CG")) sprintf(HType,"HG1");
3822 	else if(!strcmp(geometry[addToI].pdbType,"CE1")) sprintf(HType,"HE1");
3823 	else if(!strcmp(geometry[addToI].pdbType,"CE2")) sprintf(HType,"HE2");
3824 	else if(strstr(geometry[addToI].pdbType,"CE")) sprintf(HType,"HE2");
3825 	else if(strstr(geometry[addToI].pdbType,"NZ")) sprintf(HType,"HZ2");
3826 	else if(strstr(geometry[addToI].pdbType,"NZ")) sprintf(HType,"HZ2");
3827 	else if(!strcmp(geometry[addToI].pdbType,"CZ1")) sprintf(HType,"HZ1");
3828 	else if(!strcmp(geometry[addToI].pdbType,"CZ2")) sprintf(HType,"HZ2");
3829 	else if(!strcmp(geometry[addToI].pdbType,"CZ3")) sprintf(HType,"HZ3");
3830 	else if(strstr(geometry[addToI].pdbType,"CZ")) sprintf(HType,"HZ");
3831 	else if(!strcmp(geometry[addToI].pdbType,"NE")) sprintf(HType,"HE");
3832 	else if(!strcmp(geometry[addToI].pdbType,"N")) sprintf(HType,"H");
3833 	else if(!strcmp(geometry[addToI].pdbType,"NE1")) sprintf(HType,"HE1");
3834 	else if(!strcmp(geometry[addToI].pdbType,"NH1")) sprintf(HType,"HH11");
3835 	else if(!strcmp(geometry[addToI].pdbType,"NH2")) sprintf(HType,"HH21");
3836 	else if(!strcmp(geometry[addToI].pdbType,"CH1")) sprintf(HType,"HH1");
3837 	else if(!strcmp(geometry[addToI].pdbType,"CH2")) sprintf(HType,"HH2");
3838 	else if(!strcmp(geometry[addToI].pdbType,"CH3")) sprintf(HType,"H2");
3839 	else
3840 	{
3841 		sprintf(HType,"%s1",geometry[addToI].pdbType);
3842 		if(strlen(HType)>0) HType[0] = 'H';
3843 	}
3844 	add_hydrogen_atoms(addToI, nH, HType);
3845 
3846 	reset_charges_multiplicities();
3847 	return TRUE;
3848 }
3849 /*****************************************************************************/
add_max_hydrogen_atom(gint addToI)3850 static gboolean add_max_hydrogen_atom(gint addToI)
3851 {
3852 	gint nAll = 0;
3853 	gchar HType[100] = "H";
3854 	gint j;
3855 	gint nV = 0;
3856 	gint nH = 0;
3857 
3858 
3859 	if(Natoms<1 ) return FALSE;
3860 	if(addToI>Natoms-1) return FALSE;
3861 
3862 	nV =geometry[addToI].Prop.maximumBondValence;
3863 	if(nV<1) return FALSE;
3864 
3865 	for(j=0;j<(gint)Natoms;j++)
3866 	{
3867 		gint nj = geometry[j].N-1;
3868 		if(geometry[addToI].typeConnections[nj]>0)
3869 		nAll += 1;
3870 	}
3871 	/*
3872 	printf("Type = %s res = %s\n", geometry[addToI].mmType, geometry[addToI].Residue);
3873 	*/
3874 
3875 	nH = nV - nAll;
3876 	if(nH<1)
3877 	{
3878 		return FALSE;
3879 	}
3880 
3881 	if(!strcmp(geometry[addToI].pdbType,"CA")) sprintf(HType,"HA");
3882 	else if(!strcmp(geometry[addToI].pdbType,"OH")) sprintf(HType,"HO");
3883 	else if(strstr(geometry[addToI].pdbType,"OE")) sprintf(HType,"HO");
3884 	else if(strstr(geometry[addToI].pdbType,"OD")) sprintf(HType,"HO");
3885 	else if(!strcmp(geometry[addToI].pdbType,"OG1")) sprintf(HType,"HG1");
3886 	else if(!strcmp(geometry[addToI].pdbType,"CT")) sprintf(HType,"HT");
3887 	else if(!strcmp(geometry[addToI].pdbType,"CB")) sprintf(HType,"HB1");
3888 	else if(!strcmp(geometry[addToI].pdbType,"SG")) sprintf(HType,"HG");
3889 	else if(!strcmp(geometry[addToI].pdbType,"CD1")) sprintf(HType,"HD11");
3890 	else if(!strcmp(geometry[addToI].pdbType,"CD2")) sprintf(HType,"HD22");
3891 	else if(strstr(geometry[addToI].pdbType,"CD")) sprintf(HType,"HD1");
3892 	else if(!strcmp(geometry[addToI].pdbType,"CG1")) sprintf(HType,"HG11");
3893 	else if(!strcmp(geometry[addToI].pdbType,"CG2")) sprintf(HType,"HG22");
3894 	else if(strstr(geometry[addToI].pdbType,"CG")) sprintf(HType,"HG1");
3895 	else if(!strcmp(geometry[addToI].pdbType,"CE1")) sprintf(HType,"HE1");
3896 	else if(!strcmp(geometry[addToI].pdbType,"CE2")) sprintf(HType,"HE2");
3897 	else if(strstr(geometry[addToI].pdbType,"CE")) sprintf(HType,"HE2");
3898 	else if(strstr(geometry[addToI].pdbType,"NZ")) sprintf(HType,"HZ2");
3899 	else if(strstr(geometry[addToI].pdbType,"NZ")) sprintf(HType,"HZ2");
3900 	else if(!strcmp(geometry[addToI].pdbType,"CZ1")) sprintf(HType,"HZ1");
3901 	else if(!strcmp(geometry[addToI].pdbType,"CZ2")) sprintf(HType,"HZ2");
3902 	else if(!strcmp(geometry[addToI].pdbType,"CZ3")) sprintf(HType,"HZ3");
3903 	else if(strstr(geometry[addToI].pdbType,"CZ")) sprintf(HType,"HZ");
3904 	else if(!strcmp(geometry[addToI].pdbType,"NE")) sprintf(HType,"HE");
3905 	else if(!strcmp(geometry[addToI].pdbType,"N")) sprintf(HType,"H");
3906 	else if(!strcmp(geometry[addToI].pdbType,"NE1")) sprintf(HType,"HE1");
3907 	else if(!strcmp(geometry[addToI].pdbType,"NH1")) sprintf(HType,"HH11");
3908 	else if(!strcmp(geometry[addToI].pdbType,"NH2")) sprintf(HType,"HH21");
3909 	else if(!strcmp(geometry[addToI].pdbType,"CH1")) sprintf(HType,"HH1");
3910 	else if(!strcmp(geometry[addToI].pdbType,"CH2")) sprintf(HType,"HH2");
3911 	else if(!strcmp(geometry[addToI].pdbType,"CH3")) sprintf(HType,"H2");
3912 	else
3913 	{
3914 		sprintf(HType,"%s1",geometry[addToI].pdbType);
3915 		if(strlen(HType)>0) HType[0] = 'H';
3916 	}
3917 	add_hydrogen_atoms(addToI, nH, HType);
3918 
3919 	setMultipleBonds();
3920 	reset_charges_multiplicities();
3921 	return TRUE;
3922 }
3923 /*****************************************************************************/
add_one_hydrogen_atom(gint addToI)3924 static gboolean add_one_hydrogen_atom(gint addToI)
3925 {
3926 	gint nMultiple = 0;
3927 	gint nAll = 0;
3928 	gchar HType[100] = "H";
3929 	gint j;
3930 	gint nV = 0;
3931 	gint nH = 0;
3932 	gint nC = 0;
3933 
3934 
3935 	if(Natoms<1 ) return FALSE;
3936 	if(addToI>Natoms-1) return FALSE;
3937 
3938 	nV =geometry[addToI].Prop.maximumBondValence;
3939 	if(nV<1) return FALSE;
3940 
3941 	for(j=0;j<(gint)Natoms;j++)
3942 	{
3943 		gint nj = geometry[j].N-1;
3944 		if(geometry[addToI].typeConnections[nj]>0) nC++;
3945 		if(geometry[addToI].typeConnections[nj]>1) nMultiple++;
3946 		nAll += geometry[addToI].typeConnections[nj];
3947 	}
3948 
3949 	nH = nV - nC;
3950 	if(nH<1)
3951 	{
3952 		return FALSE;
3953 	}
3954 	else nH = 1;
3955 	if(nAll>=geometry[addToI].Prop.maximumBondValence && nMultiple==0)
3956 	{
3957 		return FALSE;
3958 	}
3959 
3960 
3961 	if(!strcmp(geometry[addToI].pdbType,"CA")) sprintf(HType,"HA");
3962 	else if(!strcmp(geometry[addToI].pdbType,"OH")) sprintf(HType,"HO");
3963 	else if(strstr(geometry[addToI].pdbType,"OE")) sprintf(HType,"HO");
3964 	else if(strstr(geometry[addToI].pdbType,"OD")) sprintf(HType,"HO");
3965 	else if(!strcmp(geometry[addToI].pdbType,"OG1")) sprintf(HType,"HG1");
3966 	else if(!strcmp(geometry[addToI].pdbType,"CT")) sprintf(HType,"HT");
3967 	else if(!strcmp(geometry[addToI].pdbType,"CB")) sprintf(HType,"HB1");
3968 	else if(!strcmp(geometry[addToI].pdbType,"SG")) sprintf(HType,"HG");
3969 	else if(!strcmp(geometry[addToI].pdbType,"CD1")) sprintf(HType,"HD11");
3970 	else if(!strcmp(geometry[addToI].pdbType,"CD2")) sprintf(HType,"HD22");
3971 	else if(strstr(geometry[addToI].pdbType,"CD")) sprintf(HType,"HD1");
3972 	else if(!strcmp(geometry[addToI].pdbType,"CG1")) sprintf(HType,"HG11");
3973 	else if(!strcmp(geometry[addToI].pdbType,"CG2")) sprintf(HType,"HG22");
3974 	else if(strstr(geometry[addToI].pdbType,"CG")) sprintf(HType,"HG1");
3975 	else if(!strcmp(geometry[addToI].pdbType,"CE1")) sprintf(HType,"HE1");
3976 	else if(!strcmp(geometry[addToI].pdbType,"CE2")) sprintf(HType,"HE2");
3977 	else if(strstr(geometry[addToI].pdbType,"CE")) sprintf(HType,"HE2");
3978 	else if(strstr(geometry[addToI].pdbType,"NZ")) sprintf(HType,"HZ2");
3979 	else if(strstr(geometry[addToI].pdbType,"NZ")) sprintf(HType,"HZ2");
3980 	else if(!strcmp(geometry[addToI].pdbType,"CZ1")) sprintf(HType,"HZ1");
3981 	else if(!strcmp(geometry[addToI].pdbType,"CZ2")) sprintf(HType,"HZ2");
3982 	else if(!strcmp(geometry[addToI].pdbType,"CZ3")) sprintf(HType,"HZ3");
3983 	else if(strstr(geometry[addToI].pdbType,"CZ")) sprintf(HType,"HZ");
3984 	else if(!strcmp(geometry[addToI].pdbType,"NE")) sprintf(HType,"HE");
3985 	else if(!strcmp(geometry[addToI].pdbType,"N")) sprintf(HType,"H");
3986 	else if(!strcmp(geometry[addToI].pdbType,"NE1")) sprintf(HType,"HE1");
3987 	else if(!strcmp(geometry[addToI].pdbType,"NH1")) sprintf(HType,"HH11");
3988 	else if(!strcmp(geometry[addToI].pdbType,"NH2")) sprintf(HType,"HH21");
3989 	else if(!strcmp(geometry[addToI].pdbType,"CH1")) sprintf(HType,"HH1");
3990 	else if(!strcmp(geometry[addToI].pdbType,"CH2")) sprintf(HType,"HH2");
3991 	else if(!strcmp(geometry[addToI].pdbType,"CH3")) sprintf(HType,"H2");
3992 	else
3993 	{
3994 		sprintf(HType,"%s1",geometry[addToI].pdbType);
3995 		if(strlen(HType)>0) HType[0] = 'H';
3996 	}
3997 	add_hydrogen_atoms(addToI, nH, HType);
3998 
3999 	return TRUE;
4000 }
4001 /********************************************************************************/
addMaxHydrogens()4002 void addMaxHydrogens()
4003 {
4004 	gint i;
4005 	gint k = 0;
4006 
4007 
4008 	if(Natoms<1) return;
4009 	if(!NumFatoms) SelectAllAtoms();
4010 	if(NFatoms<1) return;
4011 	if(!NumFatoms) return;
4012 
4013 	for (k=0;k<(gint)NFatoms;k++)
4014 	for (i=0;i<(gint)Natoms;i++)
4015 	{
4016 		if(geometry[i].N== NumFatoms[k])
4017 		{
4018 			add_max_hydrogen_atom(i);
4019 			break;
4020 		}
4021 	}
4022 	reset_multiple_bonds();
4023 	create_GeomXYZ_from_draw_grometry();
4024 	reset_charges_multiplicities();
4025 	drawGeom();
4026 }
4027 /********************************************************************************/
addHydrogens()4028 void addHydrogens()
4029 {
4030 	gint i;
4031 	gint k = 0;
4032 
4033 
4034 	if(Natoms<1) return;
4035 	if(!NumFatoms) SelectAllAtoms();
4036 	if(NFatoms<1) return;
4037 	if(!NumFatoms) return;
4038 
4039 	for (k=0;k<(gint)NFatoms;k++)
4040 	for (i=0;i<(gint)Natoms;i++)
4041 	{
4042 		if(geometry[i].N== NumFatoms[k])
4043 		{
4044 			add_hydrogen_atom(i);
4045 			break;
4046 		}
4047 	}
4048 	create_GeomXYZ_from_draw_grometry();
4049 	reset_charges_multiplicities();
4050 	drawGeom();
4051 }
4052 /********************************************************************************/
addOneHydrogen()4053 void addOneHydrogen()
4054 {
4055 	gint i;
4056 	gint k = 0;
4057 
4058 
4059 	if(Natoms<1) return;
4060 	if(!NumFatoms) SelectAllAtoms();
4061 	if(NFatoms<1) return;
4062 	if(!NumFatoms) return;
4063 
4064 	for (k=0;k<(gint)NFatoms;k++)
4065 	for (i=0;i<(gint)Natoms;i++)
4066 	{
4067 		if(geometry[i].N== NumFatoms[k])
4068 		{
4069 			add_one_hydrogen_atom(i);
4070 			break;
4071 		}
4072 	}
4073 	create_GeomXYZ_from_draw_grometry();
4074 	reset_charges_multiplicities();
4075 	drawGeom();
4076 }
4077 /*******************************************************************/
adjust_hydrogens_connected_to_atom(gint ia)4078 void adjust_hydrogens_connected_to_atom(gint ia)
4079 {
4080 	if(Natoms<1) return;
4081 	if(ia<0 || ia>Natoms-1) return;
4082 	{
4083 		gint nj = 0;
4084 		gint j;
4085 		gint nBondsA = 0;
4086 
4087 		for(j=0;j<(gint)Natoms;j++)
4088 		{
4089 			nj = geometry[j].N-1;
4090 			if(geometry[ia].typeConnections && geometry[ia].typeConnections[nj]>0)
4091 				nBondsA += geometry[ia].typeConnections[nj];
4092 		}
4093 		if( nBondsA==geometry[ia].Prop.maximumBondValence ) return;
4094 		if(nBondsA<geometry[ia].Prop.maximumBondValence)
4095 		{
4096 			gint nHA = geometry[ia].Prop.maximumBondValence-nBondsA;
4097 			for(j=0;j<nHA;j++) add_hydrogen_atom(ia);
4098 			copy_connections(geometry0, geometry, Natoms);
4099 		}
4100 		if(nBondsA>geometry[ia].Prop.maximumBondValence)
4101 		{
4102 			gint nHA = nBondsA-geometry[ia].Prop.maximumBondValence;
4103 			deleteHydrogensConnectedTo(ia, nHA);
4104 		}
4105 		reset_charges_multiplicities();
4106 	}
4107 }
4108 /*******************************************************************/
adjust_hydrogens_connected_to_atoms(gint ia,gint ib)4109 void adjust_hydrogens_connected_to_atoms(gint ia, gint ib)
4110 {
4111 	if(Natoms<2) return;
4112 	if(ia<0 || ib<0 || ia>Natoms-1 || ib>Natoms-1) return;
4113 	if(!geometry[ia].typeConnections) return;
4114 	if(!geometry[ib].typeConnections) return;
4115 	{
4116 		gint nj = 0;
4117 		gint j;
4118 		gint nBondsA = 0;
4119 		gint nBondsB = 0;
4120 
4121 		for(j=0;j<(gint)Natoms;j++)
4122 		{
4123 			nj = geometry[j].N-1;
4124 		 	if(geometry[ia].typeConnections[nj]>0)
4125 				nBondsA += geometry[ia].typeConnections[nj];
4126 		 	if(geometry[ib].typeConnections[nj]>0)
4127 				nBondsB += geometry[ib].typeConnections[nj];
4128 		}
4129 		if(
4130 			nBondsA==geometry[ia].Prop.maximumBondValence &&
4131 			nBondsB==geometry[ib].Prop.maximumBondValence
4132 		) return;
4133 		if(nBondsA<geometry[ia].Prop.maximumBondValence)
4134 		{
4135 			gint nHA = geometry[ia].Prop.maximumBondValence-nBondsA;
4136 			for(j=0;j<nHA;j++) add_hydrogen_atom(ia);
4137 			copy_connections(geometry0, geometry, Natoms);
4138 		}
4139 		if(nBondsB<geometry[ib].Prop.maximumBondValence)
4140 		{
4141 			gint nHB = geometry[ib].Prop.maximumBondValence-nBondsB;
4142 			for(j=0;j<nHB;j++) add_hydrogen_atom(ib);
4143 			copy_connections(geometry0, geometry, Natoms);
4144 		}
4145 		if(nBondsA>geometry[ia].Prop.maximumBondValence && nBondsB<=geometry[ib].Prop.maximumBondValence)
4146 		{
4147 			gint nHA = nBondsA-geometry[ia].Prop.maximumBondValence;
4148 			deleteHydrogensConnectedTo(ia, nHA);
4149 		}
4150 		if(nBondsB>geometry[ib].Prop.maximumBondValence && nBondsA<=geometry[ia].Prop.maximumBondValence)
4151 		{
4152 			gint nHB = nBondsA-geometry[ib].Prop.maximumBondValence;
4153 			deleteHydrogensConnectedTo(ib, nHB);
4154 		}
4155 		if(nBondsA>geometry[ia].Prop.maximumBondValence && nBondsB>geometry[ib].Prop.maximumBondValence)
4156 		{
4157 			gint nHA = nBondsA-geometry[ia].Prop.maximumBondValence;
4158 			gint nHB = nBondsB-geometry[ib].Prop.maximumBondValence;
4159 			gint* numHA = NULL;
4160 			gint* numHB = NULL;
4161 			gint kA = 0;
4162 			gint kB = 0;
4163 			gint k;
4164 			gint i;
4165 			GeomDef tmp;
4166 			gint* oldN = NULL;
4167 
4168 			if(nHA>0) numHA = g_malloc(nHA*sizeof(gint));
4169 			if(nHB>0) numHB = g_malloc(nHB*sizeof(gint));
4170 			for(j=0;j<nHA;j++) numHA[j] = -1;
4171 			for(j=0;j<nHB;j++) numHB[j] = -1;
4172 
4173 			buildRotation();
4174 
4175 			kA = 0;
4176 			for(j=0;j<(gint)Natoms;j++)
4177 			{
4178 				if(j==ia) continue;
4179 				nj = geometry[j].N-1;
4180 				if(geometry[ia].typeConnections[nj] &&
4181 				!strcmp(geometry[j].Prop.symbol,"H"))
4182 				{
4183 					numHA[kA++] = geometry[j].N;
4184 					if(kA>=nHA) break;
4185 				}
4186 			}
4187 			kB = 0;
4188 			for(j=0;j<(gint)Natoms;j++)
4189 			{
4190 				if(j==ib) continue;
4191 				nj = geometry[j].N-1;
4192 				if(geometry[ib].typeConnections[nj] &&
4193 				!strcmp(geometry[j].Prop.symbol,"H"))
4194 				{
4195 					numHB[kB++] = geometry[j].N;
4196 					if(kB>=nHB) break;
4197 				}
4198 			}
4199 			copy_connections(geometry0, geometry, Natoms);
4200 			for (i=0;i<(gint)Natoms-1;i++)
4201 			{
4202 				gboolean toDelete = FALSE;
4203 				for(k=0;k<kA;k++) if(geometry[i].N==numHA[k]) {toDelete = TRUE; break;}
4204 				if(!toDelete) for(k=0;k<kB;k++) if(geometry[i].N==numHB[k]) {toDelete = TRUE; break;}
4205 				if(!toDelete) continue;
4206 				for(j=i+1;j<(gint)Natoms;j++)
4207 				{
4208 					gboolean toDelete = FALSE;
4209 					for(k=0;k<kA;k++) if(geometry[j].N==numHA[k]) {toDelete = TRUE; break;}
4210 					if(!toDelete) for(k=0;k<kB;k++) if(geometry[j].N==numHB[k]) {toDelete = TRUE; break;}
4211 					if(toDelete) continue;
4212 					tmp = geometry0[i];
4213 					geometry0[i] = geometry0[j];
4214 					geometry0[j] = tmp ;
4215 					tmp = geometry[i];
4216 					geometry[i] = geometry[j];
4217 					geometry[j] = tmp ;
4218 					break;
4219 				}
4220 			}
4221 			j = 0;
4222 			for (i=0;i<(gint)Natoms;i++)
4223 			{
4224 				gboolean toDelete = FALSE;
4225 				for(k=0;k<kA;k++) if(geometry[i].N==numHA[k]) {toDelete = TRUE; break;}
4226 				if(!toDelete) for(k=0;k<kB;k++) if(geometry[i].N==numHB[k]) {toDelete = TRUE; break;}
4227 				if(!toDelete) continue;
4228 				if(geometry0[i].typeConnections) g_free(geometry0[i].typeConnections);
4229 				if(geometry[i].typeConnections) g_free(geometry[i].typeConnections);
4230 				geometry0[i].typeConnections=NULL;
4231 				geometry[i].typeConnections=NULL;
4232 				j++;
4233 			}
4234 			if(numHA) g_free(numHA);
4235 			if(numHB) g_free(numHB);
4236 
4237 			oldN = g_malloc(Natoms*sizeof(gint));
4238 			for (i=0;i<(gint)Natoms;i++) oldN[i] = geometry0[i].N-1;
4239 			Natoms-=kA+kB;
4240 
4241 			for(j=0;j<(gint)NFatoms;j++)
4242 			{
4243 				for (i=0;i<(gint)Natoms;i++)
4244 					if(NumFatoms[j] ==(gint) geometry[i].N) { NumFatoms[j] = i+1; break;}
4245 				if(i==(gint)Natoms)  NumFatoms[j] =-1;
4246 			}
4247 			for(j=0;j<(gint)NFatoms;j++)
4248 				if( NumFatoms[j]<0)
4249 				{
4250 					for (i=j;i<(gint)NFatoms-1;i++)
4251 				 		NumFatoms[i]= NumFatoms[i+1];
4252 					NFatoms--;
4253 					j--;
4254 				}
4255 			for (i=0;i<(gint)Natoms;i++)
4256 			{
4257 				geometry0[i].N = i+1;
4258 				geometry[i].N = i+1;
4259 			}
4260 			/* in geometry0 : old connections , in geometry new connection */
4261 			for (i=0;i<(gint)Natoms;i++)
4262 			{
4263 				if(geometry[i].typeConnections)
4264 				{
4265 					for(j=0;j<(gint)Natoms;j++)
4266 					{
4267 						geometry[i].typeConnections[j] = geometry0[i].typeConnections[oldN[j]];
4268 					}
4269 				}
4270 			}
4271 			if(oldN) g_free(oldN);
4272 			copy_connections(geometry0, geometry, Natoms);
4273 			if(Natoms>0)
4274 			{
4275 				geometry0 = g_realloc(geometry0,Natoms*sizeof(GeomDef));
4276 				geometry = g_realloc(geometry,Natoms*sizeof(GeomDef));
4277 			}
4278 			else
4279 			{
4280 				if(geometry0) g_free(geometry0); geometry0 = NULL;
4281 				if(geometry) g_free(geometry);
4282 				geometry = NULL;
4283 				Natoms = 0;
4284 			}
4285 			Ddef = FALSE;
4286 			reset_charges_multiplicities();
4287 		}
4288 	}
4289 }
4290 /*****************************************************************************/
add_hydrogen_atoms_tpl(gint addToI,gint nA)4291 static void add_hydrogen_atoms_tpl(gint addToI, gint nA)
4292 {
4293 	static SAtomsProp propH = {0};
4294 	static gint begin = 0;
4295 	gint i;
4296 	gint k;
4297 	gdouble dist = 1.0;
4298 	gint geom = 0; /* 0=3D, 1=planar, 2=linear */
4299 	gdouble angle = 109.5*PI/180.0;
4300 	gint nV;
4301 	gint nC;
4302 	gint* listOfConnectedAtoms = NULL;
4303 	gint nH;
4304 	gchar* hAtoms[10];
4305 	gint nAll;
4306 	gint nOldH = 0;
4307 
4308 	nV =geometry[addToI].Prop.maximumBondValence;
4309 	if(nV<1) return;
4310 	nAll = 0;
4311 	nOldH = 0;
4312 	for(i=0;i<(gint)nA;i++)
4313 	{
4314 		gint ni = geometry[i].N-1;
4315 		if(geometry[addToI].typeConnections[ni]>0)
4316 		{
4317 			nAll += 1;
4318 		}
4319 	}
4320 	if(!strcmp(geometry[addToI].Prop.symbol,"N")) nV++;
4321 
4322 	for(i=0;i<10;i++)
4323 		hAtoms[i] = g_malloc(sizeof(gchar)*100);
4324 	nH = getHydrogensFromPDBTpl(geometry[addToI].Residue,geometry[addToI].pdbType, hAtoms);
4325 	nH -= nOldH;
4326 
4327 	if(nH<1)
4328 	{
4329 		for(i=0;i<10;i++)
4330 			g_free(hAtoms[i]);
4331 		return;
4332 	}
4333 
4334 	if(begin==0)
4335 	{
4336 		begin++;
4337 		propH = prop_atom_get("H");
4338 	}
4339 	dist = (geometry[addToI].Prop.covalentRadii+propH.covalentRadii)*0.9;
4340 	listOfConnectedAtoms = g_malloc(nV*sizeof(gint));
4341 
4342 	if(Natoms>0)
4343 	{
4344 		geometry0 = g_realloc(geometry0,(Natoms+nH)*sizeof(GeomDef));
4345 		geometry = g_realloc(geometry,(Natoms+nH)*sizeof(GeomDef));
4346 	}
4347 	else
4348 	{
4349 		geometry0 = g_malloc(nH*sizeof(GeomDef));
4350 		geometry = g_malloc(nH*sizeof(GeomDef));
4351 	}
4352 
4353 
4354 	nC = 0;
4355 	for(i=0;i<(gint)nA;i++)
4356 	{
4357 		gint ni = geometry[i].N-1;
4358 		if(geometry[addToI].typeConnections[ni]>0)
4359 		{
4360 			listOfConnectedAtoms[nC] = i;
4361 			nC++;
4362 		}
4363 	}
4364 
4365 	for(i=0;i<nH;i++)
4366 	{
4367 		gdouble v1[3];
4368 		gdouble v2[3];
4369 		gdouble v3[3];
4370 		gdouble v4[3];
4371 		gdouble v5[3];
4372 		for(k=0;k<3;k++)
4373 			v1[k] = rand()/(gdouble)RAND_MAX-0.5;
4374 		v3d_normal(v1);
4375 
4376 		switch (nC)
4377 		{
4378 			case 1:
4379 				{
4380 					set_vect_ij(addToI, listOfConnectedAtoms[0], v2);
4381 					v3d_normal(v2);
4382 					v3d_cross(v1,v2,v3);
4383 					v3d_normal(v3);
4384 					v3d_scale(v2,cos(angle));
4385 					v3d_scale(v3,sin(angle));
4386 					v3d_add(v2,v3,v1);
4387 					break;
4388 				}
4389 			case 2:
4390 				{
4391 					set_vect_ij(addToI, listOfConnectedAtoms[0], v2);
4392 					v3d_normal(v2);
4393 					set_vect_ij(addToI, listOfConnectedAtoms[1], v3);
4394 					v3d_normal(v3);
4395 					if(geom==0)
4396 					{
4397 						v3d_add(v2,v3,v4);
4398 						v3d_normal(v4);
4399 						v3d_scale(v4,-1.0);
4400 						v3d_cross(v2,v3,v5);
4401 						v3d_normal(v5);
4402 						v3d_scale(v4,0.5);
4403 						v3d_scale(v5,0.5);
4404 						v3d_add(v4,v5,v1);
4405 						v3d_normal(v1);
4406 					}
4407 					else
4408 					{
4409 						v3d_add(v2,v3,v1);
4410 						v3d_normal(v1);
4411 						v3d_scale(v1,-1.0);
4412 					}
4413 					break;
4414 				}
4415 			default:
4416 				if(nC>=3)
4417 				{
4418 					set_vect_ij(addToI, listOfConnectedAtoms[nC-3], v2);
4419 					v3d_normal(v2);
4420 					set_vect_ij(addToI, listOfConnectedAtoms[nC-2], v3);
4421 					v3d_normal(v3);
4422 					set_vect_ij(addToI, listOfConnectedAtoms[nC-1], v4);
4423 					v3d_normal(v4);
4424 					v3d_add(v2,v3,v5);
4425 					v3d_add(v5,v4,v1);
4426 					v3d_normal(v1);
4427 					v3d_scale(v1,-1.0);
4428 					break;
4429 				}
4430 
4431 		}
4432 		geometry[Natoms].X= geometry0[addToI].X + dist*v1[0];
4433 		geometry[Natoms].Y= geometry0[addToI].Y + dist*v1[1];
4434 		geometry[Natoms].Z= geometry0[addToI].Z + dist*v1[2];
4435 		geometry[Natoms].Prop = prop_atom_get("H");
4436 		geometry[Natoms].mmType = g_strdup(hAtoms[i]);
4437 		geometry[Natoms].pdbType = g_strdup(hAtoms[i]);
4438 		geometry[Natoms].Layer = geometry[addToI].Layer;
4439 		geometry[Natoms].N = Natoms+1;
4440 		geometry[Natoms].typeConnections = NULL;
4441 		if(Natoms==0)
4442 		{
4443 			geometry[Natoms].Residue = g_strdup("H");
4444 			geometry[Natoms].ResidueNumber = 0;
4445 		}
4446 		else
4447 		{
4448 			geometry[Natoms].Residue = g_strdup(geometry[addToI].Residue);
4449 			geometry[Natoms].ResidueNumber = geometry[addToI].ResidueNumber;
4450 		}
4451 		geometry[Natoms].Charge = 0.0;
4452 		geometry[Natoms].Variable = TRUE;
4453 		geometry[Natoms].show = ShowHydrogenAtoms;
4454 
4455 		geometry0[Natoms].X = geometry[Natoms].X;
4456 		geometry0[Natoms].Y = geometry[Natoms].Y;
4457 		geometry0[Natoms].Z = geometry[Natoms].Z;
4458 		geometry0[Natoms].Prop = prop_atom_get("H");
4459 		geometry0[Natoms].mmType = g_strdup(geometry[Natoms].mmType);
4460 		geometry0[Natoms].pdbType = g_strdup(geometry[Natoms].pdbType);
4461 		geometry0[Natoms].Layer = geometry[Natoms].Layer;
4462 		geometry0[Natoms].Residue = g_strdup(geometry[Natoms].Residue);
4463 		geometry0[Natoms].ResidueNumber = geometry[Natoms].ResidueNumber;
4464 		geometry0[Natoms].Charge = 0.0;
4465 		geometry0[Natoms].Variable = TRUE;
4466 		geometry0[Natoms].N = geometry[Natoms].N;
4467 		geometry0[Natoms].show = geometry[Natoms].show;
4468 		geometry0[Natoms].typeConnections = NULL;
4469 
4470 		Natoms++;
4471 
4472 		nC++;
4473 		listOfConnectedAtoms = g_realloc(listOfConnectedAtoms, nC*sizeof(gint));
4474 		listOfConnectedAtoms[nC-1] = Natoms-1;
4475 	}
4476 	{
4477 		gint i,j;
4478 		for(i=0;i<(gint)Natoms-nH;i++)
4479 		{
4480 			geometry[i].typeConnections = g_realloc(geometry[i].typeConnections,Natoms*sizeof(gint));
4481 			for(j=Natoms-nH;j<(gint)Natoms;j++) geometry[i].typeConnections[j] = 0;
4482 			geometry0[i].typeConnections = g_realloc(geometry0[i].typeConnections,Natoms*sizeof(gint));
4483 			for(j=Natoms-nH;j<(gint)Natoms;j++) geometry0[i].typeConnections[j] = 0;
4484 		}
4485 		for(i=(gint)Natoms-nH;i<(gint)Natoms;i++)
4486 		{
4487 			geometry[i].typeConnections = g_malloc(Natoms*sizeof(gint));
4488 			for(j=0;j<(gint)Natoms;j++) geometry[i].typeConnections[j] = 0;
4489 			geometry0[i].typeConnections = g_malloc(Natoms*sizeof(gint));
4490 			for(j=0;j<(gint)Natoms;j++) geometry0[i].typeConnections[j] = 0;
4491 		}
4492 		for(i=(gint)Natoms-nH;i<(gint)Natoms;i++)
4493 		{
4494 			geometry[addToI].typeConnections[geometry[i].N-1] = 1;
4495 			geometry0[addToI].typeConnections[geometry0[i].N-1] = 1;
4496 			geometry[i].typeConnections[geometry[addToI].N-1] = 1;
4497 			geometry0[i].typeConnections[geometry0[addToI].N-1] = 1;
4498 		}
4499 		adjust_multiple_bonds_with_one_atom(addToI);
4500 	}
4501 	if(listOfConnectedAtoms) g_free(listOfConnectedAtoms);
4502 	for(i=0;i<10;i++)
4503 		g_free(hAtoms[i]);
4504 }
4505 /********************************************************************************/
addHydrogensTpl()4506 void addHydrogensTpl()
4507 {
4508 	gint i;
4509 	gint k = 0;
4510 	gint nA = Natoms;
4511 
4512 
4513 	if(Natoms<1) return;
4514 	if(!NumFatoms) SelectAllAtoms();
4515 	if(NFatoms<1) return;
4516 	if(!NumFatoms) return;
4517 
4518 	for (k=0;k<(gint)NFatoms;k++)
4519 	for (i=0;i<(gint)nA;i++)
4520 	{
4521 		if(geometry[i].N== NumFatoms[k])
4522 		{
4523 			add_hydrogen_atoms_tpl(i,nA);
4524 			break;
4525 		}
4526 	}
4527 	setMMTypesChargesFromPDBTpl(2);
4528 	create_GeomXYZ_from_draw_grometry();
4529 	reset_charges_multiplicities();
4530 	drawGeom();
4531 }
4532 /********************************************************************************/
DeleteMolecule()4533 void DeleteMolecule()
4534 {
4535 	gchar *t =N_("Do you want to really destroy this molecule?");
4536 	if(Natoms>0)
4537 		Continue_YesNo(delete_molecule, NULL,t);
4538 	else
4539 		Message(_("No molecule to delete\n"),_("Warning"),TRUE);
4540 }
4541 /********************************************************************************/
SetOriginAtCenter(gpointer data,guint Operation,GtkWidget * wid)4542 void SetOriginAtCenter(gpointer data, guint Operation,GtkWidget* wid)
4543 {
4544 	gdouble C[3];
4545 	gint i;
4546 
4547 	if(Natoms<1)
4548 		return;
4549 
4550 	for(i=0;i<3;i++)
4551 		C[i] = 0.0;
4552 
4553 	for(i=0;i<(gint)Natoms;i++)
4554 	{
4555 		C[0] += geometry0[i].X;
4556 		C[1] += geometry0[i].Y;
4557 		C[2] += geometry0[i].Z;
4558 	}
4559 	for(i=0;i<3;i++)
4560 		C[i] /= Natoms;
4561 
4562 	for(i=0;i<(gint)Natoms;i++)
4563 	{
4564 		 geometry0[i].X -= C[0];
4565 		 geometry0[i].Y -= C[1];
4566 		 geometry0[i].Z -= C[2];
4567 	}
4568 
4569 	Ddef = FALSE;
4570 	TransX = 0;
4571 	TransY = 0;
4572 	//reset_origine_molecule_drawgeom();
4573 	for (i=0;i<3;i++) Orig[i] += C[i];
4574 	drawGeom();
4575 	set_statubar_pop_sel_atom();
4576 	return;
4577 }
4578 /********************************************************************************/
TraitementGeom(gpointer data,guint Operation,GtkWidget * wid)4579 void TraitementGeom(gpointer data, guint Operation,GtkWidget* wid)
4580 {
4581   switch((GabEditGeomOperation)Operation)
4582   {
4583 	case SAVEJPEG:
4584  		file_chooser_save(save_geometry_jpeg_file,_("Save image in jpeg file format"),GABEDIT_TYPEFILE_JPEG,GABEDIT_TYPEWIN_GEOM);
4585 		break;
4586 	case SAVEPPM:
4587  		file_chooser_save(save_geometry_ppm_file,_("Save image in ppm file format"),GABEDIT_TYPEFILE_PPM,GABEDIT_TYPEWIN_GEOM);
4588 		break;
4589 	case SAVEBMP:
4590  		file_chooser_save(save_geometry_bmp_file,_("Save image in bmp file format"),GABEDIT_TYPEFILE_BMP,GABEDIT_TYPEWIN_GEOM);
4591 		break;
4592 	case SAVEPS:
4593  		file_chooser_save(save_geometry_ps_file,_("Save image in ps file format"),GABEDIT_TYPEFILE_PS,GABEDIT_TYPEWIN_GEOM);
4594 		break;
4595 	default:
4596 		printf("Operation = %d\n",Operation);
4597   }
4598 }
4599 /********************************************************************************/
get_drawing_pixmap()4600 GdkPixmap *get_drawing_pixmap()
4601 {
4602   return pixmap;
4603 }
4604 /********************************************************************************/
get_drawing_cairo()4605 cairo_t *get_drawing_cairo()
4606 {
4607   return cr;
4608 }
4609 /********************************************************************************/
get_drawing_colormap()4610 GdkColormap* get_drawing_colormap()
4611 {
4612   GdkColormap *colormap = gdk_drawable_get_colormap(GeomDrawingArea->window);
4613 
4614   return colormap;
4615 }
4616 /********************************************************************************/
read_geometries_convergence(gpointer data,guint Operation,GtkWidget * wid)4617 void read_geometries_convergence(gpointer data, guint Operation,GtkWidget* wid)
4618 {
4619 	switch(Operation)
4620 	{
4621 		case FGEOMCONVDALTON:
4622  			  	  file_chooser_open(read_geometries_conv_dalton,_("Load Geom. Conv. From Dalton Output file"),
4623 				  GABEDIT_TYPEFILE_DALTON,GABEDIT_TYPEWIN_GEOM);
4624 				  break;
4625 		case FGEOMCONVGAMESS:
4626  			  	  file_chooser_open(read_geometries_conv_dalton,_("Load Geom. Conv. From Gamess Output file"),
4627 				  GABEDIT_TYPEFILE_GAMESS,GABEDIT_TYPEWIN_GEOM);
4628 				  break;
4629 		case FGEOMCONVGAUSS:
4630  			  	  file_chooser_open(read_geometries_conv_gaussian,_("Load Geom. Conv. From Gaussian Output file"),
4631 				  GABEDIT_TYPEFILE_GAUSSIAN,GABEDIT_TYPEWIN_GEOM);
4632 				  break;
4633 		case FGEOMCONVMOLPRO:
4634  			  	  file_chooser_open(read_geometries_conv_molpro,_("Load Geom. Conv. From Molpro log file"),
4635 				  GABEDIT_TYPEFILE_MOLPRO_LOG,GABEDIT_TYPEWIN_GEOM);
4636 				  break;
4637 		case FGEOMCONVMOLDEN:
4638  			  	  file_chooser_open(read_geometries_conv_molden,_("Load Geom. Conv. From Molden file"),
4639 				  GABEDIT_TYPEFILE_MOLDEN,GABEDIT_TYPEWIN_GEOM);
4640 				  break;
4641 		case FGEOMCONVGABEDIT:
4642  			  	  file_chooser_open(read_geometries_conv_gabedit,_("Load Geom. Conv. From Gabedit file"),
4643 				  GABEDIT_TYPEFILE_GABEDIT,GABEDIT_TYPEWIN_GEOM);
4644 				  break;
4645 		case FGEOMCONVMPQC:
4646  			  	  file_chooser_open(read_geometries_conv_mpqc,_("Load Geom. Conv. From MPQC output file"),
4647 				  GABEDIT_TYPEFILE_MPQC,GABEDIT_TYPEWIN_GEOM);
4648 				  break;
4649 		case FGEOMCONVXYZ:
4650  			  	  file_chooser_open(read_geometries_conv_xyz,_("Load Geom. Conv. From XYZ"),
4651 				  GABEDIT_TYPEFILE_XYZ,GABEDIT_TYPEWIN_GEOM);
4652 				  break;
4653 		default : break;
4654 	}
4655 }
4656 /********************************************************************************/
save_geometry(gpointer data,guint Operation,GtkWidget * wid)4657 void save_geometry(gpointer data, guint Operation,GtkWidget* wid)
4658 {
4659 	if(Natoms<1)
4660 	{
4661 		Message(_("Sorry,No molecule to save\n"),_("Warning"),TRUE);
4662 		return;
4663 	}
4664 	switch(Operation)
4665 	{
4666 		case FXYZ 	: create_GeomXYZ_from_draw_grometry();
4667  			  	  file_chooser_save(save_geometry_xyz_file,_("Save geometry in xyz file"),
4668 				  GABEDIT_TYPEFILE_XYZ,GABEDIT_TYPEWIN_GEOM);
4669 				  break;
4670 		case FMOL2 	: create_GeomXYZ_from_draw_grometry();
4671  			  	  file_chooser_save(save_geometry_mol2_file,_("Save geometry in mol2 file"),
4672 				  GABEDIT_TYPEFILE_MOL2,GABEDIT_TYPEWIN_GEOM);
4673 				  break;
4674 		case FTINKER 	: create_GeomXYZ_from_draw_grometry();
4675  			  	  file_chooser_save(save_geometry_tinker_file,_("Save geometry in tinker file"),
4676 				  GABEDIT_TYPEFILE_TINKER,GABEDIT_TYPEWIN_GEOM);
4677 				  break;
4678 		case FPDB 	: create_GeomXYZ_from_draw_grometry();
4679  			  	  file_chooser_save(save_geometry_pdb_file,_("Save geometry in pdb file"),
4680 				  GABEDIT_TYPEFILE_PDB,GABEDIT_TYPEWIN_GEOM);
4681 				  break;
4682 		case FHIN 	: create_GeomXYZ_from_draw_grometry();
4683  			  	  file_chooser_save(save_geometry_hin_file,_("Save geometry in hyperchem file"),
4684 				  GABEDIT_TYPEFILE_HIN,GABEDIT_TYPEWIN_GEOM);
4685 				  break;
4686 		case FGABEDIT 	: create_GeomXYZ_from_draw_grometry();
4687  			  	  file_chooser_save(save_geometry_gabedit_file,_("Save geometry in gabedit file"),
4688 				  GABEDIT_TYPEFILE_GABEDIT,GABEDIT_TYPEWIN_GEOM);
4689 				  break;
4690 		case FMZMAT 	: create_GeomXYZ_from_draw_grometry();
4691 				  if(!xyz_to_zmat())
4692 				  {
4693 					Message(_("Sorry\nConversion is not possible from XYZ to Zmat"),_("Error"),TRUE);
4694 					return;
4695 				  }
4696  			  	  file_chooser_save(save_geometry_mzmatrix_file,_("Save geometry in mopac z-matrix file"),
4697 				  GABEDIT_TYPEFILE_MZMAT,GABEDIT_TYPEWIN_GEOM);
4698 				  create_GeomXYZ_from_draw_grometry();
4699 				  MethodeGeom = GEOM_IS_XYZ;
4700 				  break;
4701 		case FGZMAT 	: create_GeomXYZ_from_draw_grometry();
4702 				  if(!xyz_to_zmat())
4703 				  {
4704 					Message(_("Sorry\nConversion is not possible from XYZ to Zmat"),_("Error"),TRUE);
4705 					return;
4706 				  }
4707  			  	  file_chooser_save(save_geometry_gzmatrix_file,_("Save geometry in gaussian z-matrix file"),
4708 				  GABEDIT_TYPEFILE_GZMAT,GABEDIT_TYPEWIN_GEOM);
4709 				  create_GeomXYZ_from_draw_grometry();
4710 				  MethodeGeom = GEOM_IS_XYZ;
4711 				  break;
4712 		default : break;
4713 	}
4714 }
4715 /********************************************************************************/
read_geometry(gpointer data,guint Operation,GtkWidget * wid)4716 void read_geometry(gpointer data, guint Operation,GtkWidget* wid)
4717 {
4718 	switch(Operation)
4719 	{
4720 		case FXYZ 	:  MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_XYZ);break;
4721 		case FGZMAT 	:  MethodeGeom = GEOM_IS_ZMAT;selc_ZMatrix_file();break;
4722 		case FMZMAT 	:  MethodeGeom = GEOM_IS_ZMAT;selc_ZMatrix_mopac_file();break;
4723 		case FMOL2 	:  MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_MOL2);break;
4724 		case FTINKER 	: MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_TINKER);break;
4725 		case FPDB 	: MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_PDB);break;
4726 		case FHIN 	: MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_HIN);break;
4727 
4728 		case FDALTONIN : break;
4729 		case FDALTONFIRST: MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_DALTONFIRST);break;
4730 		case FDALTONLAST : MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_DALTONLAST);break;
4731 
4732 		case FGAUSSIN : selc_all_input_file(_("Read Geometry from a Gaussian input file"));break;
4733 		case FGAUSSOUTFIRST: MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_GAUSSOUTFIRST);break;
4734 		case FGAUSSOUTLAST : MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_GAUSSOUTLAST);break;
4735 
4736 		case FMOLCASIN : selc_all_input_file(_("Read Geometry from a Molcas input file"));break;
4737 		case FMOLCASOUTFIRST: MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_MOLCASOUTFIRST);break;
4738 		case FMOLCASOUTLAST : MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_MOLCASOUTLAST);break;
4739 
4740 		case FMOLPROIN : selc_all_input_file(_("Read Geometry from a Molpro input file"));break;
4741 		case FMOLPROOUTFIRST: MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_MOLPROOUTFIRST);break;
4742 		case FMOLPROOUTLAST : MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_MOLPROOUTLAST);break;
4743 
4744 		case FMPQCIN : selc_all_input_file(_("Read Geometry from a MPQC input file"));break;
4745 		case FMPQCOUTFIRST: MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_MPQCOUTFIRST);break;
4746 		case FMPQCOUTLAST : MethodeGeom = GEOM_IS_XYZ;selc_XYZ_file(GABEDIT_TYPEFILEGEOM_MPQCOUTLAST);break;
4747 	}
4748 }
4749 /********************************************************************************/
label_option()4750 guint label_option()
4751 {
4752 	return LabelOption;
4753 }
4754 /********************************************************************************/
dipole_draw_mode()4755 gboolean dipole_draw_mode()
4756 {
4757 	return DrawDipole;
4758 }
4759 /********************************************************************************/
distances_draw_mode()4760 gboolean distances_draw_mode()
4761 {
4762 	return DrawDistance;
4763 }
4764 /********************************************************************************/
dipole_mode()4765 gboolean dipole_mode()
4766 {
4767 	return ShowDipole;
4768 }
4769 /********************************************************************************/
stick_mode()4770 gboolean stick_mode()
4771 {
4772 	if(TypeGeom== GABEDIT_TYPEGEOM_STICK) return TRUE;
4773 	return FALSE;
4774 }
4775 /********************************************************************************/
space_fill_mode()4776 gboolean space_fill_mode()
4777 {
4778 	if( TypeGeom == GABEDIT_TYPEGEOM_SPACE ) return TRUE;
4779 	return FALSE;
4780 }
4781 /********************************************************************************/
pers_mode()4782 gboolean pers_mode()
4783 {
4784 	return PersMode;
4785 }
4786 /********************************************************************************/
shad_mode()4787 gboolean shad_mode()
4788 {
4789 	return ShadMode;
4790 }
4791 /********************************************************************************/
light_mode()4792 gboolean light_mode()
4793 {
4794 	return LightMode;
4795 }
4796 /********************************************************************************/
ortep_mode()4797 gboolean ortep_mode()
4798 {
4799 	return OrtepMode;
4800 }
4801 /********************************************************************************/
cartoon_mode()4802 gboolean cartoon_mode()
4803 {
4804 	return CartoonMode;
4805 }
4806 /********************************************************************************/
get_frag_angle()4807 gdouble get_frag_angle()
4808 {
4809 	return fragAngle;
4810 }
4811 /********************************************************************************/
set_frag_angle(gdouble a)4812 void set_frag_angle(gdouble a)
4813 {
4814 	fragAngle = a;
4815 }
4816 /********************************************************************************/
set_HBonds_dialog_geom(GtkWidget * win,guint data)4817 void set_HBonds_dialog_geom(GtkWidget *win, guint data)
4818 {
4819 	set_HBonds_dialog (GeomDlg);
4820 }
4821 /********************************************************************************/
set_povray_options_geom(GtkWidget * win,guint data)4822 void set_povray_options_geom(GtkWidget *win, guint data)
4823 {
4824 	 createPovrayOptionsWindow(GeomDlg);
4825 }
4826 /********************************************************************************/
HideShowMeasure(gboolean hiding)4827 void HideShowMeasure(gboolean hiding)
4828 {
4829 	if(hiding)
4830 	{
4831   		gtk_widget_hide(vboxhandle);
4832   		gtk_widget_hide(GeomDrawingArea);
4833   		gtk_widget_show(GeomDrawingArea);
4834     		while( gtk_events_pending() ) gtk_main_iteration();
4835 	}
4836 	else gtk_widget_show(vboxhandle);
4837 
4838    	MeasureIsHide=hiding;
4839 }
4840 /********************************************************************************/
AdjustHydrogensYesNo(gboolean adjust)4841 void AdjustHydrogensYesNo(gboolean adjust)
4842 {
4843 	AdjustHydrogenAtoms = adjust;
4844 }
4845 /********************************************************************************/
getAdjustHydrogensYesNo()4846 gboolean getAdjustHydrogensYesNo()
4847 {
4848 	return AdjustHydrogenAtoms;
4849 }
4850 /********************************************************************************/
RebuildConnectionsDuringEditionYesNo(gboolean rebuild)4851 void RebuildConnectionsDuringEditionYesNo(gboolean rebuild)
4852 {
4853 	RebuildConnectionsDuringEdition = rebuild;
4854 }
4855 /********************************************************************************/
getRebuildConnectionsDuringEditionYesNo()4856 gboolean getRebuildConnectionsDuringEditionYesNo()
4857 {
4858 	return RebuildConnectionsDuringEdition;
4859 }
4860 /********************************************************************************/
ScaleByMouse(gpointer data)4861 static gint ScaleByMouse(gpointer data)
4862 {
4863 	GdkEventButton *bevent=(GdkEventButton *)data;
4864 
4865         switch(OperationType)
4866         {
4867 	case SCALEGEOM :
4868 			factor +=((bevent->y - BeginY) / GeomDrawingArea->allocation.height) * 5;
4869 			if(factor<0.1) factor = 0.1;
4870 			if(factor>10) factor = 10;
4871 			drawGeom();
4872 		break;
4873 	case SCALESTICK :
4874 			factorstick +=((bevent->y - BeginY) / GeomDrawingArea->allocation.height) * 5;
4875 			if(factorstick <0.1) factorstick  = 0.1;
4876 			if(factorstick >10) factorstick = 10;
4877 			drawGeom();
4878 
4879 		break;
4880 	case SCALEBALL :
4881 			factorball +=((bevent->y - BeginY) / GeomDrawingArea->allocation.height) * 5;
4882 			if(factorball <0.1) factorball  = 0.1;
4883 			if(factorball >10) factorball = 10;
4884 			drawGeom();
4885 		break;
4886 	case SCALEDIPOLE :
4887 			factordipole +=((bevent->y - BeginY) / GeomDrawingArea->allocation.height) * 5;
4888 			if(factordipole <0.1) factordipole  = 0.1;
4889 			if(factordipole >100) factordipole = 100;
4890 			redefine_dipole();
4891 			drawGeom();
4892 		break;
4893 	default : break;
4894 
4895         }
4896 	BeginX = bevent->x;
4897 	BeginY = bevent->y;
4898 
4899 
4900  	return TRUE;
4901 }
4902 /********************************************************************************/
TranslationByMouse(GtkWidget * widget,GdkEventMotion * event)4903 static gint TranslationByMouse(GtkWidget *widget, GdkEventMotion *event)
4904 {
4905 	int x, y;
4906 	GdkRectangle area;
4907 	GdkModifierType state;
4908 
4909 	if (event->is_hint)
4910 	{
4911 #if !defined(G_OS_WIN32)
4912 		gdk_window_get_pointer(event->window, &x, &y, &state);
4913 #else
4914 		x = event->x;
4915 		y = event->y;
4916 		state = event->state;
4917 #endif
4918 	}
4919 	else
4920 	{
4921 		x = event->x;
4922 		y = event->y;
4923 		state = event->state;
4924 	}
4925 
4926 	area.x = 0;
4927 	area.y = 0;
4928 	area.width  = widget->allocation.width;
4929 	area.height = widget->allocation.height;
4930 
4931     TransX =(gint)(TransX+(x - BeginX));
4932     TransY =(gint)(TransY+(y - BeginY));
4933 	drawGeom();
4934 
4935 	BeginX = x;
4936 	BeginY = y;
4937  return TRUE;
4938 }
4939 /********************************************************************************/
RotationByMouse(GtkWidget * widget,GdkEventMotion * event)4940 static gint RotationByMouse(GtkWidget *widget, GdkEventMotion *event)
4941 {
4942 	int x, y;
4943 	GdkRectangle area;
4944 	GdkModifierType state;
4945 	gdouble spin_quat[4];
4946 
4947 	if (event->is_hint)
4948 	{
4949 #if !defined(G_OS_WIN32)
4950 		gdk_window_get_pointer(event->window, &x, &y, &state);
4951 #else
4952 		x = event->x;
4953 		y = event->y;
4954 		state = event->state;
4955 #endif
4956 	}
4957 	else
4958 	{
4959 		x = event->x;
4960 		y = event->y;
4961 		state = event->state;
4962 	}
4963 
4964 	area.x = 0;
4965 	area.y = 0;
4966 	area.width  = widget->allocation.width;
4967 	area.height = widget->allocation.height;
4968 
4969 
4970 	trackball(spin_quat,
4971 		(2.0*BeginX  - area.width) / area.width,
4972 		(area.height - 2.0*BeginY) / area.height,
4973 		(2.0*x       - area.width) / area.width,
4974 		(area.height - 2.0*y     ) / area.height);
4975 	add_quats(spin_quat, Quat, Quat);
4976 	drawGeom();
4977 
4978 	BeginX = x;
4979 	BeginY = y;
4980  return TRUE;
4981 }
4982 /********************************************************************************/
RotationZByMouse(GtkWidget * widget,GdkEventMotion * event)4983 static gint RotationZByMouse(GtkWidget *widget, GdkEventMotion *event)
4984 {
4985 	int x, y;
4986 	GdkModifierType state;
4987 	gdouble spin_quat[4] = {0,0,0,0};
4988 	gdouble phi = 1.0/180*PI;
4989 	gdouble width;
4990 	gdouble height;
4991 	gint Xi;
4992 	gint Yi;
4993 
4994 	if (event->is_hint)
4995 	{
4996 #if !defined(G_OS_WIN32)
4997 		gdk_window_get_pointer(event->window, &x, &y, &state);
4998 #else
4999 		x = event->x;
5000 		y = event->y;
5001 		state = event->state;
5002 #endif
5003 	}
5004 	else
5005 	{
5006 		x = event->x;
5007 		y = event->y;
5008 		state = event->state;
5009 	}
5010 
5011 	width  = widget->allocation.width;
5012 	height = widget->allocation.height;
5013 
5014 	Xi = width/2 + TransX;
5015 	Yi = height/2 + TransY;
5016 
5017 
5018 	if(abs(BeginX-x)>abs(BeginY-y))
5019 	 {
5020 		  gdouble sign  = 1.0;
5021 		  if(BeginY> Yi && BeginX<x) sign = -1;
5022 		  if(BeginY< Yi && BeginX>x) sign = -1;
5023 		  phi = sign* fabs(BeginX-x)/width*PI;
5024 	  }
5025 	  else
5026 	  {
5027 		  gdouble sign = 1.0;
5028 		  if(BeginX> Xi && BeginY>y) sign = -1;
5029 		  if(BeginX< Xi && BeginY<y) sign = -1;
5030 		  phi = sign* fabs(BeginY-y)/height*PI;
5031 	  }
5032 	spin_quat[2] = 1.0;
5033 
5034 	spin_quat[2]= sin(phi/2);
5035 	spin_quat[3] = cos(phi/2);
5036 
5037 	add_quats(spin_quat, Quat, Quat);
5038 	drawGeom();
5039 
5040 	BeginX = x;
5041 	BeginY = y;
5042 	return TRUE;
5043 }
5044 /********************************************************************************/
rotation_fragment_quat(gdouble m[4][4],gdouble C[])5045 static void rotation_fragment_quat(gdouble m[4][4],gdouble C[])
5046 {
5047 	gdouble A[3];
5048 	gdouble B[3];
5049 	guint i,j,k;
5050 	gdouble M[4][4];
5051 	gdouble O[3];
5052 
5053 	build_rotmatrix(M,Quat);
5054 	for (i=0;i<Natoms;i++)
5055 	{
5056 		A[0] = geometry[i].X;
5057 		A[1] = geometry[i].Y;
5058 		A[2] = geometry[i].Z;
5059 		for(j=0;j<3;j++)
5060 		{
5061 			B[j] = 0.0;
5062 			for(k=0;k<3;k++)
5063 				B[j] += M[k][j]*A[k];
5064 		}
5065 		geometry[i].X=B[0];
5066 		geometry[i].Y=B[1];
5067 		geometry[i].Z=B[2];
5068 	}
5069 	for(i=0;i<3;i++) O[i] = Orig[i];
5070 	for(j=0;j<3;j++)
5071 	{
5072 		B[j] = 0.0;
5073 		for(k=0;k<3;k++)
5074 			B[j] += M[k][j]*O[k];
5075 	}
5076 	for(i=0;i<3;i++) Orig[i] = B[i];
5077 
5078 	for (i=0;i<Natoms;i++)
5079 	{
5080 		if(if_selected(i))
5081 		{
5082 			A[0] = geometry[i].X-C[0];
5083 			A[1] = geometry[i].Y-C[1];
5084 			A[2] = geometry[i].Z-C[2];
5085 			for(j=0;j<3;j++)
5086 			{
5087 				B[j] = 0.0;
5088 				for(k=0;k<3;k++)
5089 					B[j] += m[k][j]*A[k];
5090 			}
5091 			geometry[i].X=C[0]+B[0];
5092 			geometry[i].Y=C[1]+B[1];
5093 			geometry[i].Z=C[2]+B[2];
5094 		}
5095 
5096 	}
5097 	Ddef = FALSE;
5098 	for (i=0;i<Natoms;i++)
5099 	{
5100 		geometry0[i].X=geometry[i].X;
5101 		geometry0[i].Y=geometry[i].Y;
5102 		geometry0[i].Z=geometry[i].Z;
5103 	}
5104 	init_quat(Quat);
5105 
5106 
5107 	sort_with_zaxis();
5108 	define_coefs_pers();
5109 }
5110 /********************************************************************************/
local_zrotate_fragment(GtkWidget * widget,GdkEventMotion * event)5111 static gint local_zrotate_fragment(GtkWidget *widget, GdkEventMotion *event)
5112 {
5113 	int x, y;
5114 	GdkModifierType state;
5115 	gdouble spin_quat[4] = {0,0,0,0};
5116 	gdouble m[4][4];
5117 	gdouble C[3]={0,0,0};/* Center of Fragment */
5118 	gint i;
5119 	gint j;
5120 	gint k;
5121 	gushort Xmax;
5122 	gushort Ymax;
5123 	gushort Rmax;
5124 	gdouble Cmax;
5125 	gint Xi;
5126 	gint Yi;
5127 	gdouble width;
5128 	gdouble height;
5129 	gdouble phi = 1.0/180*PI;
5130 
5131 	if(Natoms>0)
5132 	{
5133 		if(PersMode)
5134 			Cmax  = coordmaxmin.Cmax*camera.f/(camera.position);
5135 		else
5136 			Cmax = coordmaxmin.Cmax;
5137 	}
5138 	else
5139 		return FALSE;
5140 
5141 	Xmax=GeomDrawingArea->allocation.width;
5142 	Ymax=GeomDrawingArea->allocation.height;
5143 	Rmax = Xmax;
5144 	if(Rmax<Ymax)
5145 		Rmax = Ymax;
5146 
5147 
5148 
5149 	j=0;
5150 	for (i=0;i<(gint)Natoms;i++)
5151 	{
5152 		if(if_selected(i))
5153 		{
5154 			j++;
5155 			C[0] += geometry[i].X;
5156 			C[1] += geometry[i].Y;
5157 			C[2] += geometry[i].Z;
5158 		}
5159 	}
5160 	if(j<1)
5161 		return FALSE;
5162 	for(k=0;k<3;k++)
5163 		C[k] /= (gdouble)j;
5164 
5165 	Xi = (gint)(C[0]/Cmax*factor*Rmax/2)+Xmax/2;
5166 	Yi = (gint)(C[1]/Cmax*factor*Rmax/2)+Ymax/2;
5167 
5168 	Xi = Xi + TransX;
5169 	Yi = Yi + TransY;
5170 
5171 	if (event->is_hint)
5172 	{
5173 #if !defined(G_OS_WIN32)
5174 		gdk_window_get_pointer(event->window, &x, &y, &state);
5175 #else
5176 		x = event->x;
5177 		y = event->y;
5178 		state = event->state;
5179 #endif
5180 	}
5181 	else
5182 	{
5183 		x = event->x;
5184 		y = event->y;
5185 		state = event->state;
5186 	}
5187 
5188 	width  = widget->allocation.width;
5189 	height = widget->allocation.height;
5190 
5191 	if(abs(BeginX-x)>abs(BeginY-y))
5192 	 {
5193 		  gdouble sign  = 1.0;
5194 		  if(BeginY> Yi && BeginX<x) sign = -1;
5195 		  if(BeginY< Yi && BeginX>x) sign = -1;
5196 		  phi = sign* fabs(BeginX-x)/width*PI;
5197 	  }
5198 	  else
5199 	  {
5200 		  gdouble sign = 1.0;
5201 		  if(BeginX> Xi && BeginY>y) sign = -1;
5202 		  if(BeginX< Xi && BeginY<y) sign = -1;
5203 		  phi = sign* fabs(BeginY-y)/height*PI;
5204 	  }
5205 	spin_quat[2] = 1.0;
5206 
5207 	spin_quat[2]= sin(phi/2);
5208 	spin_quat[3] = cos(phi/2);
5209 
5210 	add_quats(spin_quat, QuatFrag, QuatFrag);
5211 	build_rotmatrix(m,QuatFrag);
5212 	rotation_fragment_quat(m,C);
5213 
5214 	if(RebuildConnectionsDuringEdition)
5215 		reset_connections_between_selected_and_notselected_atoms();
5216 	/* reset_all_connections();*/
5217 	drawGeom();
5218 
5219 	init_quat(QuatFrag);
5220 	BeginX = x;
5221 	BeginY = y;
5222  return TRUE;
5223 }
5224 /********************************************************************************/
local_rotate_fragment(GtkWidget * widget,GdkEventMotion * event)5225 static gint local_rotate_fragment(GtkWidget *widget, GdkEventMotion *event)
5226 {
5227 	int x, y;
5228 	GdkModifierType state;
5229 	gdouble spin_quat[4];
5230 	gdouble m[4][4];
5231 	gdouble C[3]={0,0,0};/* Center of Fragment */
5232 	gint i;
5233 	gint j;
5234 	gint k;
5235 	gushort Xmax;
5236 	gushort Ymax;
5237 	gushort Rmax;
5238 	gdouble Cmax;
5239 	gint Xi;
5240 	gint Yi;
5241 	gdouble width;
5242 	gdouble height;
5243 
5244 	if(Natoms>0)
5245 	{
5246 		if(PersMode)
5247 			Cmax  = coordmaxmin.Cmax*camera.f/(camera.position);
5248 		else
5249 			Cmax = coordmaxmin.Cmax;
5250 	}
5251 	else
5252 		return FALSE;
5253 
5254 	Xmax=GeomDrawingArea->allocation.width;
5255 	Ymax=GeomDrawingArea->allocation.height;
5256 	Rmax = Xmax;
5257 	if(Rmax<Ymax)
5258 		Rmax = Ymax;
5259 
5260 
5261 
5262 	j=0;
5263 	for (i=0;i<(gint)Natoms;i++)
5264 	{
5265 		if(if_selected(i))
5266 		{
5267 			j++;
5268 			C[0] += geometry[i].X;
5269 			C[1] += geometry[i].Y;
5270 			C[2] += geometry[i].Z;
5271 		}
5272 	}
5273 	if(j<1)
5274 		return FALSE;
5275 	for(k=0;k<3;k++)
5276 		C[k] /= (gdouble)j;
5277 
5278 	Xi = (gint)(C[0]/Cmax*factor*Rmax/2)+Xmax/2;
5279 	Yi = (gint)(C[1]/Cmax*factor*Rmax/2)+Ymax/2;
5280 
5281 	Xi = Xi + TransX;
5282 	Yi = Yi + TransY;
5283 
5284 	if (event->is_hint)
5285 	{
5286 #if !defined(G_OS_WIN32)
5287 		gdk_window_get_pointer(event->window, &x, &y, &state);
5288 #else
5289 		x = event->x;
5290 		y = event->y;
5291 		state = event->state;
5292 #endif
5293 	}
5294 	else
5295 	{
5296 		x = event->x;
5297 		y = event->y;
5298 		state = event->state;
5299 	}
5300 
5301 	width  = widget->allocation.width;
5302 	height = widget->allocation.height;
5303 
5304 
5305 	trackball(spin_quat,
5306 		(2.0*(width/2+BeginX-Xi)  - (width)) / (width),
5307 		((height) - 2.0*(height/2+BeginY-Yi)) / (height),
5308 		(2.0*(width/2+x-Xi)       - (width)) / (width),
5309 		((height) - 2.0*(height/2+y-Yi)     ) / (height));
5310 
5311 	add_quats(spin_quat, QuatFrag, QuatFrag);
5312 	build_rotmatrix(m,QuatFrag);
5313 	rotation_fragment_quat(m,C);
5314 
5315 	if(RebuildConnectionsDuringEdition)
5316 		reset_connections_between_selected_and_notselected_atoms();
5317 	/* reset_all_connections();*/
5318 	drawGeom();
5319 
5320 	init_quat(QuatFrag);
5321 	BeginX = x;
5322 	BeginY = y;
5323  return TRUE;
5324 }
5325 /********************************************************************************/
set_statubar_pop_sel_atom()5326 void set_statubar_pop_sel_atom()
5327 {
5328 	gchar* temp = NULL;
5329 	if(NumSelectedAtom >=0 && OperationType == DELETEFRAG)
5330 	{
5331 		temp = g_strdup_printf(_("%s[%d] ; Coord (Ang) : %f %f %f ; Move your mouse to cancel the operation "),
5332 			geometry0[NumSelectedAtom].Prop.symbol,NumSelectedAtom+1,
5333 			geometry0[NumSelectedAtom].X*BOHR_TO_ANG,
5334 			geometry0[NumSelectedAtom].Y*BOHR_TO_ANG,
5335 			geometry0[NumSelectedAtom].Z*BOHR_TO_ANG);
5336 	}
5337 	if(OperationType == CUTBOND || OperationType == CHANGEBOND)
5338 	{
5339 		temp = g_strdup_printf(_("Move your mouse to cancel the operation "));
5340 	}
5341 	if(temp)
5342 	{
5343 		gtk_statusbar_pop(GTK_STATUSBAR(StatusOperation),idStatusOperation);
5344 		gtk_statusbar_push(GTK_STATUSBAR(StatusOperation),idStatusOperation,temp);
5345 		g_free(temp);
5346 	}
5347 }
5348 /********************************************************************************/
move_one_atom(GdkEventMotion * event)5349 static gint move_one_atom(GdkEventMotion *event)
5350 {
5351 	int x, y;
5352 	GdkModifierType state;
5353 	gdouble X;
5354 	gdouble Y;
5355 	gdouble Z;
5356 	gdouble Cmax;
5357 	gushort Xmax;
5358 	gushort Ymax;
5359 	gushort Rmax;
5360 
5361 	if(NumSelectedAtom<0) return -1;
5362 	Xmax=GeomDrawingArea->allocation.width;
5363 	Ymax=GeomDrawingArea->allocation.height;
5364 	Rmax = Xmax;
5365 	if(Rmax<Ymax) Rmax = Ymax;
5366 
5367 	if (event->is_hint)
5368 	{
5369 #if !defined(G_OS_WIN32)
5370 		gdk_window_get_pointer(event->window, &x, &y, &state);
5371 #else
5372 		x = event->x;
5373 		y = event->y;
5374 		state = event->state;
5375 #endif
5376 	}
5377 	else
5378 	{
5379 		x = event->x;
5380 		y = event->y;
5381 		state = event->state;
5382 	}
5383 
5384 
5385 	if(PersMode) Cmax  = coordmaxmin.Cmax*camera.f/(camera.position);
5386 	else Cmax = coordmaxmin.Cmax;
5387 
5388 	X = (gdouble)(x-Xmax/2-TransX)*2.0*Cmax/(factor*Rmax);
5389 	Y = -(gdouble)(y-Ymax/2-TransY)*2.0*Cmax/(factor*Rmax);
5390 	Z = geometry[NumSelectedAtom].Z;
5391 
5392 	if(PersMode)
5393 	{
5394 		X = X/camera.f*(-Z+camera.position);
5395 		Y = Y/camera.f*(-Z+camera.position);
5396 	}
5397 	{
5398 		gdouble m[4][4];
5399 		gdouble **m0 = g_malloc(3*sizeof(gdouble*));
5400 		gdouble** minv;
5401 		gint i,j;
5402 
5403 		gdouble A[3];
5404 		gdouble B[3];
5405 		guint k;
5406 
5407 		for(i=0;i<3;i++)
5408 			m0[i] = g_malloc(3*sizeof(gdouble));
5409 
5410 		build_rotmatrix(m,Quat);
5411 
5412 		for(i=0;i<3;i++)
5413 		for(j=0;j<3;j++)
5414 			m0[i][j] = m[i][j];
5415 
5416 		minv = Inverse(m0,3,1e-7);
5417 
5418 		A[0] = X;
5419 		A[1] = Y;
5420 		A[2] = Z;
5421 		for(j=0;j<3;j++)
5422 		{
5423 			B[j] = 0.0;
5424 			for(k=0;k<3;k++)
5425 				B[j] += minv[k][j]*A[k];
5426 		}
5427 		X=B[0];
5428 		Y=B[1];
5429 		Z=B[2];
5430 		i = NumSelectedAtom;
5431 		geometry0[i].X=B[0];
5432 		geometry0[i].Y=B[1];
5433 		geometry0[i].Z=B[2];
5434 
5435 		for(i=0;i<3;i++)
5436 			if(minv[i])
5437 				g_free(minv[i]);
5438 		if(minv)
5439 			g_free(minv);
5440 
5441 		for(i=0;i<3;i++)
5442 			if(m0[i])
5443 				g_free(m0[i]);
5444 		if(m0)
5445 			g_free(m0);
5446 	}
5447 	Ddef = FALSE;
5448 	buildRotation();
5449 
5450 	drawGeom();
5451 	set_statubar_pop_sel_atom();
5452 	return TRUE;
5453 }
5454 
5455 /***********************************************************************************/
move_all_selected_atoms(GtkWidget * widget,GdkEventMotion * event)5456 static gint move_all_selected_atoms(GtkWidget *widget, GdkEventMotion *event)
5457 {
5458 	int x, y;
5459 	GdkModifierType state;
5460 	gdouble X;
5461 	gdouble Y;
5462 	gdouble Z;
5463 	gdouble Cmax;
5464 	gushort Xmax;
5465 	gushort Ymax;
5466 	gushort Rmax;
5467 
5468 	if(NumSelectedAtom<0) return -1;
5469 	Xmax=GeomDrawingArea->allocation.width;
5470 	Ymax=GeomDrawingArea->allocation.height;
5471 	Rmax = Xmax;
5472 	if(Rmax<Ymax) Rmax = Ymax;
5473 
5474 
5475 	if (event->is_hint)
5476 	{
5477 #if !defined(G_OS_WIN32)
5478 		gdk_window_get_pointer(event->window, &x, &y, &state);
5479 #else
5480 		x = event->x;
5481 		y = event->y;
5482 		state = event->state;
5483 #endif
5484 	}
5485 	else
5486 	{
5487 		x = event->x;
5488 		y = event->y;
5489 		state = event->state;
5490 	}
5491 
5492 	if(PersMode)
5493 		Cmax  = coordmaxmin.Cmax*camera.f/(camera.position);
5494 	else
5495 		Cmax = coordmaxmin.Cmax;
5496 
5497 	X = (gdouble)(x-Xmax/2-TransX)*2.0*Cmax/(factor*Rmax);
5498 	Y = -(gdouble)(y-Ymax/2-TransY)*2.0*Cmax/(factor*Rmax);
5499 	Z = geometry[NumSelectedAtom].Z;
5500 
5501 	if(PersMode)
5502 	{
5503 		X = X/camera.f*(-Z+camera.position);
5504 		Y = Y/camera.f*(-Z+camera.position);
5505 	}
5506 	{
5507 		gdouble m[4][4];
5508 		gdouble **m0 = g_malloc(3*sizeof(gdouble*));
5509 		gdouble** minv;
5510 		gint i,j;
5511 
5512 		gdouble A[3];
5513 		gdouble B[3];
5514 		guint k;
5515 
5516 		for(i=0;i<3;i++)
5517 			m0[i] = g_malloc(3*sizeof(gdouble));
5518 
5519 		build_rotmatrix(m,Quat);
5520 
5521 		for(i=0;i<3;i++)
5522 		for(j=0;j<3;j++)
5523 			m0[i][j] = m[i][j];
5524 
5525 		minv = Inverse(m0,3,1e-7);
5526 
5527 		A[0] = X;
5528 		A[1] = Y;
5529 		A[2] = Z;
5530 		for(j=0;j<3;j++)
5531 		{
5532 			B[j] = 0.0;
5533 			for(k=0;k<3;k++)
5534 				B[j] += minv[k][j]*A[k];
5535 		}
5536 		X=B[0];
5537 		Y=B[1];
5538 		Z=B[2];
5539 		i = NumSelectedAtom;
5540 		B[0] -=geometry0[i].X;
5541 		B[1] -=geometry0[i].Y;
5542 		B[2] -=geometry0[i].Z;
5543 
5544 		for(i=0;i<(gint)Natoms;i++)
5545 		for(j=0;j<(gint)NFatoms;j++)
5546 			if(NumFatoms[j]==(gint)geometry0[i].N)
5547 			{
5548 				geometry0[i].X += B[0];
5549 				geometry0[i].Y += B[1];
5550 				geometry0[i].Z += B[2];
5551 			}
5552 
5553 
5554 		for(i=0;i<3;i++)
5555 			if(minv[i])
5556 				g_free(minv[i]);
5557 		if(minv)
5558 			g_free(minv);
5559 
5560 		for(i=0;i<3;i++)
5561 			if(m0[i])
5562 				g_free(m0[i]);
5563 		if(m0)
5564 			g_free(m0);
5565 	}
5566 	Ddef = FALSE;
5567 	if(RebuildConnectionsDuringEdition)
5568 		reset_connections_between_selected_and_notselected_atoms();
5569 	drawGeom();
5570 	set_statubar_pop_sel_atom();
5571 	return TRUE;
5572 }
5573 /********************************************************************************/
MoveAtomByMouse(GtkWidget * widget,GdkEventMotion * event)5574 static gint MoveAtomByMouse(GtkWidget *widget, GdkEventMotion *event)
5575 {
5576 	gboolean MoveAll = FALSE;
5577 	gint i;
5578 	gint j;
5579 
5580 	if(NumSelectedAtom<0) return FALSE;
5581 	for(i=0;i<(gint)Natoms;i++)
5582 		if((gint)i==NumSelectedAtom)
5583 		{
5584 			for(j = 0;j<(gint)NFatoms;j++)
5585 				if(NumFatoms[j] == (gint)geometry[i].N)
5586 					MoveAll = TRUE;
5587 			break;
5588 		}
5589 	if(!MoveAll)
5590 	{
5591 		move_one_atom(event);
5592 		if(RebuildConnectionsDuringEdition)
5593 			reset_connection_with_one_atom(NumSelectedAtom);
5594 		return TRUE;
5595 	}
5596 	move_all_selected_atoms(widget, event);
5597 	return TRUE;
5598 }
5599 /*****************************************************************************/
set_proche_atom(GdkEventButton * bevent)5600 gint set_proche_atom(GdkEventButton *bevent)
5601 {
5602 	gdouble xi,yi,xii,yii;
5603 	gint i;
5604 	gdouble mindist = -1;
5605 	gdouble d1 ;
5606 
5607 	xi = bevent->x;
5608 	yi = bevent->y;
5609 
5610 	NumProcheAtom = -1;
5611 	for(i=Natoms-1;i>=0;i--)
5612 	{
5613 		xii = xi-geometry[i].Xi;
5614 		yii = yi-geometry[i].Yi;
5615 		d1 = xii*xii+yii*yii;
5616 			if(mindist<0)
5617 			{
5618 				mindist = fabs(d1);
5619 				NumProcheAtom = i;
5620 			}
5621 			if(mindist>fabs(d1))
5622 			{
5623 				mindist = fabs(d1);
5624 				NumProcheAtom = i;
5625 			}
5626 	}
5627 	return NumProcheAtom;
5628 }
5629 /*****************************************************************************/
set_selected_atoms(GdkEventButton * bevent)5630 gint set_selected_atoms(GdkEventButton *bevent)
5631 {
5632 	gdouble xi,yi,xii,yii;
5633 	gint i;
5634 	gdouble mindist = -1;
5635 	gdouble d2 ;
5636 	gdouble d1 ;
5637 	gint ns = -1;
5638 
5639 	xi = bevent->x;
5640 	yi = bevent->y;
5641 
5642 	for(i=Natoms-1;i>=0;i--)
5643 	{
5644 		gdouble rayon = 2*get_rayon(i);
5645 		xii = xi-geometry[i].Xi;
5646 		yii = yi-geometry[i].Yi;
5647 		d1 = xii*xii+yii*yii;
5648 		d2 = d1-rayon*rayon;
5649 		if(d2<0)
5650 		{
5651 			if(mindist<0)
5652 			{
5653 				mindist = fabs(d1);
5654 				ns = i;
5655 			}
5656 			if(mindist>fabs(d1))
5657 			{
5658 				mindist = fabs(d1);
5659 				ns = i;
5660 			}
5661 		}
5662 	}
5663 	if(ns != -1)
5664 	{
5665 		gboolean Ok = FALSE;
5666 		for(i=0;i<4;i++)
5667 			if(NumSelAtoms[i] ==(gint) geometry[ns].N)
5668 			{
5669 				NumSelAtoms[i] = -1;
5670 				Ok = TRUE;
5671 				break;
5672 			}
5673 		if(!Ok)
5674 		for(i=0;i<4;i++)
5675 			if(NumSelAtoms[i] == -1 || NumSelAtoms[i] >(gint)Natoms)
5676 			{
5677 				NumSelAtoms[i] = geometry[ns].N;
5678 				Ok = TRUE;
5679 				break;
5680 			}
5681 
5682 		if(!Ok)
5683 		{
5684 			for(i=0;i<3;i++)
5685 				NumSelAtoms[i] = NumSelAtoms[i+1];
5686 			NumSelAtoms[3] = geometry[ns].N;
5687 		}
5688 	}
5689 	for(i=0;i<3;i++)
5690 		if(NumSelAtoms[i] == -1)
5691 		{
5692 			NumSelAtoms[i] = NumSelAtoms[i+1];
5693 			NumSelAtoms[i+1] = -1;
5694 		}
5695 	drawGeom();
5696 	change_of_center(NULL,NULL);
5697 	set_statubar_pop_sel_atom();
5698 	return ns;
5699 }
5700 /*****************************************************************************/
unselected_atom(GdkEventButton * bevent)5701 gint unselected_atom(GdkEventButton *bevent)
5702 {
5703 	gdouble xi,yi,xii,yii;
5704 
5705 	xi = bevent->x;
5706 	yi = bevent->y;
5707 
5708 	xii = xi-BeginX;
5709 	yii = yi-BeginY;
5710 	if(xii*xii+yii*yii > 8)
5711 	{
5712 		NumSelectedAtom = -1;
5713 		drawGeom();
5714 		SetOperation (NULL,OperationType);
5715 	}
5716 	return NumSelectedAtom;
5717 }
5718 /*****************************************************************************/
unselected_bond(GdkEventButton * bevent)5719 gint unselected_bond(GdkEventButton *bevent)
5720 {
5721 	gdouble xi,yi,xii,yii;
5722 
5723 	xi = bevent->x;
5724 	yi = bevent->y;
5725 
5726 	xii = xi-BeginX;
5727 	yii = yi-BeginY;
5728 	if(xii*xii+yii*yii > 8)
5729 	{
5730 		NumBatoms[0] = NumBatoms[1] = -1;
5731 		NBatoms = 0;
5732 		drawGeom();
5733 		SetOperation (NULL,OperationType);
5734 	}
5735 	return 0;
5736 }
5737 /*****************************************************************************/
set_selected_second_atom_bond(GdkEventButton * bevent)5738 gint set_selected_second_atom_bond(GdkEventButton *bevent)
5739 {
5740 	gdouble xi,yi,xa,ya;
5741 	gint i;
5742 	gdouble da ;
5743 	gint nb=0;
5744 
5745 	xi = bevent->x;
5746 	yi = bevent->y;
5747 
5748 
5749 	for(i=Natoms-1;i>=0;i--)
5750 	{
5751 		gdouble rayon = 2*get_rayon(i);
5752 		xa = xi-geometry[i].Xi;
5753 		ya = yi-geometry[i].Yi;
5754 		da = xa*xa+ya*ya;
5755 		if(geometry[i].N==geometry[NumSelectedAtom].N) continue;
5756 		if(da<rayon*rayon)
5757 		{
5758 			nb = (gint) geometry[i].N;
5759 			break;
5760 		}
5761 	}
5762 	if(nb>0)
5763 	{
5764 		NBatoms = 2;
5765 		NumBatoms[1] = nb;
5766 	}
5767 	else
5768 	{
5769 		NBatoms = 1;
5770 	}
5771 	drawGeom();
5772 	change_of_center(NULL,NULL);
5773 	set_statubar_pop_sel_atom();
5774 	return NBatoms;
5775 }
5776 /*****************************************************************************/
set_selected_atom(GdkEventButton * bevent)5777 gint set_selected_atom(GdkEventButton *bevent)
5778 {
5779 	gdouble xi,yi,xii,yii;
5780 	gint i;
5781 	gdouble mindist = -1;
5782 	gdouble d2 ;
5783 	gdouble d1 ;
5784 
5785 	xi = bevent->x;
5786 	yi = bevent->y;
5787 
5788 	NumSelectedAtom = -1;
5789 	for(i=Natoms-1;i>=0;i--)
5790 	{
5791 		gdouble rayon;
5792 		if(!geometry[i].show) continue;
5793 		rayon = 2*get_rayon(i);
5794 		xii = xi-geometry[i].Xi;
5795 		yii = yi-geometry[i].Yi;
5796 		d1 = xii*xii+yii*yii;
5797 		d2 = d1-rayon*rayon;
5798 		if(d2<0)
5799 		{
5800 			if(mindist<0)
5801 			{
5802 				mindist = fabs(d1);
5803 				NumSelectedAtom = i;
5804 			}
5805 			if(mindist>fabs(d1))
5806 			{
5807 				mindist = fabs(d1);
5808 				NumSelectedAtom = i;
5809 			}
5810 		}
5811 	}
5812 	for(i=0;i<3;i++)
5813 		QuatAtom[i] = 0;
5814 	QuatAtom[3] = 1;
5815 	if(NumSelectedAtom>=0)
5816 	{
5817 	CSselectedAtom[0] = geometry0[NumSelectedAtom].X;
5818 	CSselectedAtom[1] = geometry0[NumSelectedAtom].Y;
5819 	CSselectedAtom[2] = geometry0[NumSelectedAtom].Z;
5820 	}
5821 	drawGeom();
5822 	set_statubar_pop_sel_atom();
5823 	return NumSelectedAtom;
5824 }
5825 /*****************************************************************************/
set_selected_bond(GdkEventButton * bevent)5826 gint set_selected_bond(GdkEventButton *bevent)
5827 {
5828 	gdouble xi,yi,xa,ya,xb,yb;
5829 	gint i,j;
5830 	gdouble da ;
5831 	gdouble db ;
5832 	gint na = -1;
5833 	gint nb = -1;
5834 
5835 	xi = bevent->x;
5836 	yi = bevent->y;
5837 
5838 	NumBatoms[0] = NumBatoms[1] = -1;
5839 	NBatoms = 0;
5840 
5841 	for(i=Natoms-1;i>=0;i--)
5842 	{
5843 		gdouble rayoni;
5844 		xa = xi-geometry[i].Xi;
5845 		ya = yi-geometry[i].Yi;
5846 		da = xa*xa+ya*ya;
5847 		rayoni = get_rayon(i)/2;
5848 		rayoni = rayoni*rayoni;
5849 		for(j=Natoms-1;j>=0;j--)
5850 		{
5851 			gdouble rayonj;
5852 			gdouble minrayon;
5853 			if(i==j)  continue;
5854 			gint nj = geometry[j].N-1;
5855 			if(geometry[i].typeConnections[nj]<1)  continue;
5856 			xb = xi-geometry[j].Xi;
5857 			yb = yi-geometry[j].Yi;
5858 			db = xb*xb+yb*yb;
5859 			rayonj = get_rayon(j)/2;
5860 			rayonj = rayonj*rayonj;
5861 			minrayon = rayoni;
5862 			if(minrayon>rayonj) minrayon = rayonj;
5863 
5864 			if( da<minrayon || db<minrayon)
5865 			{
5866 				na = i;
5867 				nb = j;
5868 				break;
5869 			}
5870 
5871 			if( fabs((xa*xb+ya*yb)/sqrt(da*db)+1.0)<0.1)
5872 			{
5873 				na = i;
5874 				nb = j;
5875 				break;
5876 			}
5877 
5878 		}
5879 		if(na>-1 && nb>-1) break;
5880 	}
5881 	if(na != -1 && nb != -1)
5882 	{
5883 		NBatoms = 2;
5884 		NumBatoms[0] = (gint) geometry[na].N;
5885 		NumBatoms[1] = (gint) geometry[nb].N;
5886 	}
5887 	drawGeom();
5888 	change_of_center(NULL,NULL);
5889 	set_statubar_pop_sel_atom();
5890 	return NBatoms;
5891 }
5892 /*****************************************************************************/
set_selected_atom_bond(GdkEventButton * bevent)5893 gint set_selected_atom_bond(GdkEventButton *bevent)
5894 {
5895 	gdouble xi,yi,xa,ya;
5896 	gint i;
5897 	gdouble da ;
5898 
5899 	xi = bevent->x;
5900 	yi = bevent->y;
5901 
5902 	NumBatoms[0] = NumBatoms[1] = -1;
5903 	NBatoms = 0;
5904 
5905 	for(i=Natoms-1;i>=0;i--)
5906 	{
5907 		gdouble rayon = 2*get_rayon(i);
5908 		xa = xi-geometry[i].Xi;
5909 		ya = yi-geometry[i].Yi;
5910 		da = xa*xa+ya*ya;
5911 		if(da<rayon*rayon)
5912 		{
5913 			NBatoms = 1;
5914 			NumBatoms[0] = (gint) geometry[i].N;
5915 			break;
5916 		}
5917 	}
5918 	drawGeom();
5919 	change_of_center(NULL,NULL);
5920 	set_statubar_pop_sel_atom();
5921 	return NBatoms;
5922 }
5923 /*****************************************************************************/
get_atom_to_select(GdkEventButton * bevent)5924 gint get_atom_to_select(GdkEventButton *bevent)
5925 {
5926 	gdouble xi,yi,xii,yii;
5927 	gint i;
5928 	gdouble d2 ;
5929 	gdouble d1 ;
5930 
5931 	xi = bevent->x;
5932 	yi = bevent->y;
5933 
5934 	for(i=Natoms-1;i>=0;i--)
5935 	{
5936 		gdouble rayon;
5937 		if(!geometry[i].show) continue;
5938 		if(i==NumSelectedAtom) continue;
5939 		xii = xi-geometry[i].Xi;
5940 		yii = yi-geometry[i].Yi;
5941 		d1 = xii*xii+yii*yii;
5942 		rayon = 2*get_rayon(i);
5943 		d2 = d1-rayon*rayon;
5944 		if(d2<0) return i;
5945 	}
5946 	return -1;
5947 }
5948 /*****************************************************************************/
set_selected_atom_or_bond_to_delete(GdkEventButton * bevent)5949 gint set_selected_atom_or_bond_to_delete(GdkEventButton *bevent)
5950 {
5951 	NumSelectedAtom = -1;
5952 	if(get_atom_to_select(bevent)>=0)
5953 	{
5954 		OperationType = DELETEFRAG;
5955 		return set_selected_atom(bevent);
5956 	}
5957 	OperationType = CUTBOND;
5958 	return set_selected_bond(bevent);
5959 }
5960 /*****************************************************************************/
add_begin_atoms_bond(GdkEventButton * bevent)5961 gint add_begin_atoms_bond(GdkEventButton *bevent)
5962 {
5963 	gint ni,nj,i,j;
5964 	if(NBatoms==1 && NumBatoms[0]>0)
5965 	{
5966 		insert_atom(bevent);
5967 		j = Natoms-1;
5968 		nj = geometry[j].N-1;
5969 		for(i=0;i<(gint)Natoms;i++)
5970 			if(geometry[i].N==NumBatoms[0])
5971 			{
5972 				ni = geometry[i].N-1;
5973 				geometry0[j].typeConnections[ni] = 1;
5974 				geometry0[i].typeConnections[nj] = 1;
5975 				geometry[j].typeConnections[ni] = 1;
5976 				geometry[i].typeConnections[nj] = 1;
5977 				break;
5978 			}
5979 		NumSelectedAtom = Natoms-1;
5980 		return 1;
5981 	}
5982 	insert_atom(bevent);
5983 	NumProcheAtom = Natoms-1;
5984 	insert_atom(bevent);
5985 	j = Natoms-1;
5986 	i = Natoms-2;
5987 	ni = geometry[i].N-1;
5988 	nj = geometry[j].N-1;
5989 	geometry0[j].typeConnections[ni] = 1;
5990 	geometry0[i].typeConnections[nj] = 1;
5991 	geometry[j].typeConnections[ni] = 1;
5992 	geometry[i].typeConnections[nj] = 1;
5993 	NumSelectedAtom = Natoms-1;
5994 	NumBatoms[0] = -(geometry0[i].N+Natoms);
5995 	return 2;
5996 }
5997 /*****************************************************************************/
set_selected_atom_or_bond_to_edit(GdkEventButton * bevent)5998 gint set_selected_atom_or_bond_to_edit(GdkEventButton *bevent)
5999 {
6000 	gint res = -1;
6001 	NumSelectedAtom = -1;
6002 	res = get_atom_to_select(bevent);
6003 	if(res==-1)
6004 	{
6005 		set_selected_bond(bevent);
6006 		if(NBatoms==2)
6007 		{
6008 			OperationType = CHANGEBOND;
6009 			return NBatoms;
6010 		}
6011 	}
6012 	set_selected_atom_bond(bevent);
6013 	OperationType = ADDATOMSBOND;
6014 	res = set_selected_atom(bevent);
6015 	set_proche_atom(bevent);
6016 	return res;
6017 }
6018 /*****************************************************************************/
atom_noni_connected_to(gint i,gint k)6019 static gint atom_noni_connected_to(gint i, gint k)
6020 {
6021 	gint j;
6022 	gint l;
6023 	if(Natoms<3) return -1;
6024 	if(geometry[i].typeConnections)
6025 	for(j=0;j<Natoms;j++)
6026 	{
6027 		gint nj = geometry[j].N-1;
6028 		if(j==i) continue;
6029 		if(geometry[j].typeConnections)
6030 		for(l=0;l<Natoms;l++)
6031 		{
6032 			gint nl = geometry[l].N-1;
6033 			if(k==geometry[l].N && ( geometry[l].typeConnections[nj]>0 || geometry[j].typeConnections[nl]>0)
6034 					&& geometry[l].Prop.symbol[0] !='H') return geometry[j].N;
6035 		}
6036 	}
6037 	for(j=0;j<Natoms;j++)
6038 	{
6039 		gint nj = geometry[j].N-1;
6040 		if(j==i) continue;
6041 		if(geometry[j].typeConnections)
6042 		for(l=0;l<Natoms;l++)
6043 			if(k==geometry[l].N && geometry[l].typeConnections && geometry[l].typeConnections[nj]>0) return geometry[j].N;
6044 	}
6045 	return -1;
6046 }
6047 /*****************************************************************************/
set_selected_atoms_for_insert_frag(GdkEventButton * bevent)6048 gint set_selected_atoms_for_insert_frag(GdkEventButton *bevent)
6049 {
6050 	gint nb = 0;
6051 	gint i;
6052 	gint j;
6053 
6054 	NumSelectedAtom = -1;
6055 	angleTo = -1;
6056 	atomToBondTo = -1;
6057 	NumSelectedAtom = -1;
6058 
6059 	i = get_atom_to_select(bevent);
6060 	if(i<0)  return i;
6061 	atomToDelete = geometry[i].N;
6062 
6063 	atomToBondTo = -1;
6064 	for (j=0;j<(gint)Natoms;j++)
6065 	if(geometry[j].typeConnections && geometry[j].typeConnections[atomToDelete-1]>0)
6066 	{
6067 		nb++;
6068 		atomToBondTo = geometry[j].N;
6069 		angleTo = atom_noni_connected_to( i, atomToBondTo);
6070 	}
6071 	if(nb != 1 || atomToBondTo==-1)
6072 	{
6073 		atomToDelete = -1;
6074 		atomToBondTo = -1;
6075 		angleTo = -1;
6076 	}
6077 	if(Frag.NAtoms>0 && Frag.atomToDelete != -1) drawGeom();
6078 	return atomToDelete;
6079 }
6080 /*****************************************************************************
6081 *  event_dispatcher
6082 ******************************************************************************/
button_press(GtkWidget * DrawingArea,GdkEvent * event,gpointer Menu)6083 gint button_press(GtkWidget *DrawingArea, GdkEvent *event, gpointer Menu)
6084 {
6085 	GdkEventButton *bevent;
6086 
6087 	switch (event->type)
6088 	{
6089 		case GDK_BUTTON_PRESS:
6090 		{
6091 			buttonpress = TRUE;
6092 			bevent = (GdkEventButton *) event;
6093 			if (bevent->button == 3) /* Right Button ==> Popup Menu */
6094 			{
6095 				buttonpress = FALSE;
6096 				popup_menu_geom( bevent->button, bevent->time);
6097 			}
6098 			else
6099 			if (bevent->button == 1 && ControlKeyPressed)
6100 			{
6101 
6102 				BeginX= bevent->x;
6103 				BeginY = bevent->y;
6104 				return TRUE;
6105 			}
6106 			else
6107 			if (bevent->button == 1)
6108 			{
6109 				/* beginning of drag, reset mouse position */
6110 				BeginX= bevent->x;
6111 				BeginY = bevent->y;
6112         			switch(OperationType)
6113         			{
6114 					case SELECTOBJECTS :
6115 						if(GKeyPressed && select_atoms_by_groupe())
6116 							SetOperation(NULL,SELECTRESIDUE);
6117 						else
6118 						if(!FKeyPressed && select_atoms_by_residues())
6119 							SetOperation(NULL,SELECTRESIDUE);
6120 						else
6121 							SetOperation(NULL,SELECTFRAG);
6122 						break;
6123 					case MOVEFRAG :
6124 						add_geometry_to_fifo();
6125 						set_selected_atom(bevent); break;
6126 					case DELETEOBJECTS :
6127 						add_geometry_to_fifo();
6128 						set_selected_atom_or_bond_to_delete(bevent);break;
6129 					case MEASURE     : set_selected_atoms(bevent);break;
6130 					case EDITOBJECTS :
6131 							  add_geometry_to_fifo();
6132 							  set_selected_atom_or_bond_to_edit(bevent);
6133 							  if(NBatoms<2) add_begin_atoms_bond(bevent);
6134 							  drawGeom();
6135 							  break;
6136 					case ADDFRAGMENT :
6137 							  add_geometry_to_fifo();
6138 							  set_selected_atoms_for_insert_frag(bevent);
6139 							  set_proche_atom(bevent);break;
6140 					case ROTLOCFRAG :
6141 							  add_geometry_to_fifo();
6142 							  init_quat(QuatFrag);
6143 							  ButtonPressed = TRUE;
6144 							  drawGeom();
6145 							  break;
6146 					case ROTZLOCFRAG :
6147 							  add_geometry_to_fifo();
6148 							  init_quat(QuatFrag);
6149 							  ButtonPressed = TRUE;
6150 							  drawGeom();
6151 							  break;
6152 					default:break;
6153 				}
6154 			return TRUE;
6155 			}
6156 			else
6157 			if (bevent->button == 2)
6158 			{
6159 				BeginX= bevent->x;
6160 				BeginY = bevent->y;
6161 				return TRUE;
6162 			}
6163 		}
6164 		default: break;
6165 	}
6166 	return FALSE;
6167 }
6168 /*************************/
unselect_all_atoms()6169 void unselect_all_atoms()
6170 {
6171 	NFatoms = 0;
6172 	if(NumFatoms)
6173 	       g_free(NumFatoms);
6174 	NumFatoms = NULL;
6175 }
6176 /*****************************************************************************
6177 *  event_release
6178 ******************************************************************************/
button_release(GtkWidget * DrawingArea,GdkEvent * event,gpointer Menu)6179 gint button_release(GtkWidget *DrawingArea, GdkEvent *event, gpointer Menu)
6180 {
6181 	GdkEventButton *bevent;
6182 	buttonpress = FALSE;
6183 	if(event->type == GDK_BUTTON_RELEASE)
6184 	{
6185 		bevent = (GdkEventButton *) event;
6186 		if (bevent->button == 3) return TRUE;
6187 		if (bevent->button == 2) { drawGeom(); return TRUE;}
6188 		if (bevent->button == 1 && ControlKeyPressed) return TRUE;
6189 	}
6190 	if(NumSelectedAtom !=-1)
6191 	{
6192 		switch(OperationType)
6193 		{
6194 		case MOVEFRAG :
6195 			create_GeomXYZ_from_draw_grometry();
6196 			NumSelectedAtom = -1;
6197 			if(GeomIsOpen)
6198 				unselect_all_atoms();
6199 
6200 			free_text_to_draw();
6201 			drawGeom();
6202 			SetOperation (NULL,MOVEFRAG);
6203 			change_of_center(NULL,NULL);
6204 			break;
6205 		case DELETEFRAG :
6206 			delete_selected_atoms();
6207 			create_GeomXYZ_from_draw_grometry();
6208 			NumSelectedAtom = -1;
6209 			free_text_to_draw();
6210 			drawGeom();
6211 			SetOperation (NULL,DELETEOBJECTS);
6212 			change_of_center(NULL,NULL);
6213 			break;
6214 		default:break;
6215 
6216 		}
6217 	}
6218 	switch(OperationType)
6219 	{
6220 	case SELECTRESIDUE : SetOperation(NULL,SELECTOBJECTS);  break;
6221 	case SELECTFRAG : SetOperation(NULL,SELECTOBJECTS);  break;
6222 	case ADDATOMSBOND :
6223 		if(NBatoms==2 && NumBatoms[0]>0 &&  NumBatoms[1]>0 && NumBatoms[0]!=NumBatoms[1])
6224 		{
6225 			delete_one_atom(NumSelectedAtom);
6226 			add_bond();
6227 		}
6228 		else if(NBatoms==2 && NumBatoms[0]<-Natoms &&  NumBatoms[1]>0)
6229 		{
6230 			NumBatoms[0] = -NumBatoms[0]-Natoms;
6231 			delete_one_atom(NumSelectedAtom);
6232 			if( NumBatoms[0] != NumBatoms[1]) add_bond();
6233 		}
6234 		else if(NumBatoms[0]>0)
6235 		{
6236 			gint res = get_atom_to_select((GdkEventButton *)event);
6237 			if(res != -1)
6238 			{
6239 				delete_one_atom(NumSelectedAtom);
6240 				replace_atom(get_indice(NumBatoms[0]));
6241 				if(AdjustHydrogenAtoms) adjust_hydrogens_connected_to_atom(get_indice(NumBatoms[0]));
6242 			}
6243 			else if(AdjustHydrogenAtoms)
6244 			{
6245 				adjust_hydrogens_connected_to_atoms(NumSelectedAtom,get_indice(NumBatoms[0]));
6246 			}
6247 		}
6248 		else if(NumBatoms[0]<-Natoms)
6249 		{
6250 			gint res = -1;
6251 			NumBatoms[0] = -NumBatoms[0]-Natoms;
6252 			res = get_atom_to_select((GdkEventButton *)event);
6253 			if(res != -1)
6254 			{
6255 				delete_one_atom(NumSelectedAtom);
6256 				if(AdjustHydrogenAtoms) adjust_hydrogens_connected_to_atom(get_indice(NumBatoms[0]));
6257 			}
6258 			else if(AdjustHydrogenAtoms)
6259 			{
6260 				adjust_hydrogens_connected_to_atoms(NumSelectedAtom,get_indice(NumBatoms[0]));
6261 			}
6262 		}
6263 		create_GeomXYZ_from_draw_grometry();
6264 		reset_charges_multiplicities();
6265 		SetOperation (NULL,EDITOBJECTS);
6266 		change_of_center(NULL,NULL);
6267 		NumProcheAtom = -1;
6268 		NumSelectedAtom = -1;
6269 		free_text_to_draw();
6270 		NBatoms = 0;
6271 		NumBatoms[0] = NumBatoms[1] = -1;
6272 		drawGeom();
6273 		break;
6274 	case ADDFRAGMENT :
6275 		insert_fragment(DrawingArea,event);
6276 		create_GeomXYZ_from_draw_grometry();
6277 		NumProcheAtom = -1;
6278 		atomToDelete = -1;
6279 		atomToBondTo = -1;
6280 		angleTo = -1;
6281 		free_text_to_draw();
6282 		drawGeom();
6283 		/*activate_rotation();*/
6284 		SetOperation (NULL,ADDFRAGMENT);
6285 		change_of_center(NULL,NULL);
6286 		break;
6287 	case ROTLOCFRAG :
6288 		ButtonPressed = FALSE;
6289 		create_GeomXYZ_from_draw_grometry();
6290 		drawGeom();
6291 		change_of_center(NULL,NULL);
6292 		break;
6293 	case ROTZLOCFRAG :
6294 		ButtonPressed = FALSE;
6295 		create_GeomXYZ_from_draw_grometry();
6296 		drawGeom();
6297 		change_of_center(NULL,NULL);
6298 		break;
6299 	case CUTBOND :
6300 		delete_selected_bond();
6301 		free_text_to_draw();
6302 		create_GeomXYZ_from_draw_grometry();
6303 		reset_charges_multiplicities();
6304 		drawGeom();
6305 		SetOperation (NULL,DELETEOBJECTS);
6306 		break;
6307 	case CHANGEBOND :
6308 		change_selected_bond();
6309 		free_text_to_draw();
6310 		create_GeomXYZ_from_draw_grometry();
6311 		reset_charges_multiplicities();
6312 		drawGeom();
6313 		SetOperation (NULL,EDITOBJECTS);
6314 		break;
6315 
6316 	default:
6317 		drawGeom();
6318 	}
6319 
6320 	return TRUE;
6321 
6322 }
6323 /*****************************************************************************
6324 *  event_dispatcher
6325 ******************************************************************************/
event_dispatcher(GtkWidget * DrawingArea,GdkEvent * event,gpointer Menu)6326 gint event_dispatcher(GtkWidget *DrawingArea, GdkEvent *event, gpointer Menu)
6327 {
6328 	return button_press(DrawingArea,event,Menu);
6329 
6330 }
6331 /********************************************************************************/
6332 /* Moption Notify */
6333 /********************************************************************************/
motion_notify(GtkWidget * widget,GdkEventMotion * event)6334 gint motion_notify(GtkWidget *widget, GdkEventMotion *event)
6335 {
6336 	GdkModifierType state;
6337 
6338 	if (event->is_hint)
6339 	{
6340 #if !defined(G_OS_WIN32)
6341 		int x, y;
6342 		gdk_window_get_pointer(event->window, &x, &y, &state);
6343 #else
6344 		state = event->state;
6345 #endif
6346 
6347 	}
6348 	else
6349 		state = event->state;
6350 	if (state & GDK_BUTTON1_MASK)
6351 	{
6352 		if(ControlKeyPressed)
6353 		{
6354 			RotationByMouse(widget,event);
6355 			return TRUE;
6356 		}
6357 	}
6358 	if (state & GDK_BUTTON1_MASK)
6359 	{
6360 		switch(OperationType)
6361 		{
6362 			case ROTATION 	: RotationByMouse(widget,event);break;
6363 			case ROTATIONZ 	: RotationZByMouse(widget,event);break;
6364 			case TRANSMOVIE : TranslationByMouse(widget,event);break;
6365 			case SCALEGEOM 	:
6366 			case SCALESTICK	:
6367 			case SCALEBALL 	:
6368 			case SCALEDIPOLE: ScaleByMouse((gpointer)event);break;
6369 			case SELECTFRAG :
6370 					  switch(SelectType)
6371 					  {
6372 						case CIRCLE :
6373 							draw_selection_circle(event->x,event->y);
6374 							break;
6375 						case RECTANGLE:
6376 							draw_selection_rectangle(event->x,event->y);
6377 							select_atoms_by_rectangle(event->x,event->y);
6378 							break;
6379 						default:break;
6380 					  }
6381 					  break;
6382 			case MOVEFRAG   :
6383 					  MoveAtomByMouse(widget,event);
6384 					  free_text_to_draw();
6385 					  change_of_center(NULL,NULL);
6386 					  break;
6387 			case ROTLOCFRAG :
6388 					local_rotate_fragment(widget,event);
6389 					free_text_to_draw();
6390 					change_of_center(NULL,NULL);
6391 					break;
6392 			case ROTZLOCFRAG :
6393 					local_zrotate_fragment(widget,event);
6394 					free_text_to_draw();
6395 					change_of_center(NULL,NULL);
6396 					break;
6397 			case DELETEFRAG :
6398 					  if(unselected_atom((GdkEventButton *)event)==-1)
6399 					  {
6400 					  	OperationType = DELETEOBJECTS;
6401 					  	unselected_atom((GdkEventButton *)event);
6402 					  }
6403 					  free_text_to_draw();
6404 					  change_of_center(NULL,NULL);
6405 					  break;
6406 			case CUTBOND :
6407 					  OperationType = DELETEOBJECTS;
6408 					  unselected_bond((GdkEventButton *)event);
6409 					  free_text_to_draw();
6410 					  drawGeom();
6411 					  break;
6412 			case CHANGEBOND : unselected_bond((GdkEventButton *)event);
6413 					  free_text_to_draw();
6414 					  break;
6415 			case ADDATOMSBOND :
6416 					  move_one_atom(event);
6417 					  set_selected_second_atom_bond((GdkEventButton *)event);
6418 					  free_text_to_draw();
6419 					  break;
6420 			case ADDFRAGMENT :
6421 					  if(atomToDelete>-1)
6422 					  {
6423 						gint j = get_atom_to_select((GdkEventButton *)event);
6424 						if(j>=0 && geometry[j].N != atomToDelete && geometry[j].N != atomToBondTo &&
6425 							fabs(atof(get_angle(atomToDelete,atomToBondTo,geometry[j].N))-180)>0.1)
6426 						{
6427 							angleTo = geometry[j].N;
6428 							drawGeom();
6429 						}
6430 					  }
6431             default : return FALSE;
6432 		}
6433 	}
6434 
6435 	if (state & GDK_BUTTON2_MASK)
6436 	{
6437 		RotationByMouse(widget,event);
6438 	}
6439 	return TRUE;
6440 }
6441 /********************************************************************************/
redraw()6442 static void redraw()
6443 {
6444   gdk_draw_drawable(GeomDrawingArea->window,
6445                   GeomDrawingArea->style->fg_gc[GTK_WIDGET_STATE (GeomDrawingArea)],
6446                   pixmap,
6447                   0,0,
6448                   0,0,
6449                   GeomDrawingArea->allocation.width,
6450                   GeomDrawingArea->allocation.height);
6451 }
6452 /********************************************************************************/
pixmap_init(GtkWidget * widget)6453 static void pixmap_init(GtkWidget *widget)
6454 {
6455   GdkColormap *colormap;
6456 
6457   if(!BackColor)
6458   gdk_draw_rectangle (pixmap,
6459                       widget->style->black_gc,
6460                       TRUE,
6461                       0, 0,
6462                       widget->allocation.width,
6463                       widget->allocation.height);
6464   else
6465   {
6466    	colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
6467         gdk_colormap_alloc_color(colormap,BackColor,FALSE,TRUE);
6468 	gdk_gc_set_foreground(gc,BackColor);
6469 
6470         gdk_draw_rectangle (pixmap,
6471                       gc,
6472                       TRUE,
6473                       0, 0,
6474                       widget->allocation.width,
6475                       widget->allocation.height);
6476   }
6477 }
6478 /*****************************************************************************/
configure_event(GtkWidget * widget,GdkEventConfigure * event)6479 static gint configure_event( GtkWidget *widget, GdkEventConfigure *event )
6480 {
6481 	if(!gc) gc = gdk_gc_new(GeomDrawingArea->window);
6482 	if (pixmap) g_object_unref(pixmap);
6483 	pixmap = gdk_pixmap_new(widget->window, widget->allocation.width, widget->allocation.height, -1);
6484 	cr = gdk_cairo_create (pixmap);
6485 	drawGeom();
6486 
6487 	return TRUE;
6488 }
6489 /********************************************************************************/
expose_event(GtkWidget * widget,GdkEventExpose * event)6490 static gint expose_event( GtkWidget *widget, GdkEventExpose *event )
6491 {
6492 	if(event->count >0) return FALSE;
6493 	gdk_draw_drawable(widget->window,
6494                   widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
6495                   pixmap,
6496                   event->area.x, event->area.y,
6497                   event->area.x, event->area.y,
6498                   event->area.width, event->area.height);
6499 
6500 	return FALSE;
6501 }
6502 /*****************************************************************************/
SetCosSin()6503 void SetCosSin()
6504 {
6505   int i;
6506 
6507   for ( i=0; i < 91; i++ ) {
6508         TSIN[i] = sin((PI*i)/180.0);
6509         TCOS[i] = cos((PI*i)/180.0);
6510   }
6511 }
6512 /*****************************************************************************/
RenderStick()6513 void RenderStick()
6514 {
6515 	TypeGeom = GABEDIT_TYPEGEOM_STICK;
6516 	drawGeom();
6517 }
6518 /*****************************************************************************/
RenderBallStick()6519 void RenderBallStick()
6520 {
6521 	TypeGeom =  GABEDIT_TYPEGEOM_BALLSTICK;
6522 	drawGeom();
6523 }
6524 /*****************************************************************************/
RenderSpaceFill()6525 void RenderSpaceFill()
6526 {
6527 	TypeGeom = GABEDIT_TYPEGEOM_SPACE;
6528 	drawGeom();
6529 }
6530 /*****************************************************************************/
ActivateButtonOperation(GtkWidget * widget,guint data)6531 void ActivateButtonOperation (GtkWidget *widget, guint data)
6532 {
6533 	SetOperation (widget,data);
6534 }
6535 /*****************************************************************************/
SetOperation(GtkWidget * widget,guint data)6536 void SetOperation (GtkWidget *widget, guint data)
6537 {
6538 	gchar* temp = NULL;
6539 	if(data == CENTER)
6540 	{
6541 			TransX = 0;
6542 			TransY = 0;
6543 			drawGeom();
6544 		return;
6545 	}
6546 
6547 	OperationType = data ;
6548 	if( OperationType != ADDFRAGMENT)
6549 		hide_fragments_selector();
6550 	switch(data)
6551 	{
6552 		case ROTATION	: temp = g_strdup(_(" Press the Left mouse button and move your mouse for a \"Rotate molecule\". "));break;
6553 		case ROTATIONZ	: temp = g_strdup(_(" Press the Left mouse button and move your mouse for a \"Rotate molecule about z axis\". "));break;
6554 		case TRANSMOVIE : temp = g_strdup(_(" Press the Left mouse button and move your mouse for a \"Translation\". "));break;
6555 		case SCALEGEOM	: temp = g_strdup(_(" Press the Left mouse button and move your mouse for a \"Zoom\". "));break;
6556 		case SCALESTICK : temp = g_strdup(_(" Press the Left mouse button and move your mouse for \"Scale Stick\". "));break;
6557 		case SCALEBALL  :  temp = g_strdup(_(" Press the Left mouse button and move your mouse for \"Scale Ball\". "));break;
6558 		case SCALEDIPOLE:  temp = g_strdup(_(" Press the Left mouse button and move your mouse for \"Scale Dipole\". "));break;
6559 		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;
6560 		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;
6561 		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;
6562 		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;
6563 		case ROTLOCFRAG :  temp = g_strdup(_(" Press the Left mouse button and move your mouse for \"Rotatation of selected atom(s)[Local Rotation]\". "));break;
6564 		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;
6565 		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;
6566 		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;
6567 		case ADDATOMSBOND :  temp = g_strdup(_(" Press and release the Left mouse button for \"Insert atom(s)/bond\".\"Pick an atom for replace it.\""));break;
6568 		case CHANGEBOND :  temp = g_strdup(_(" Press the Left mouse button(for pick a bond) and release for \"Change selected bond\". "));break;
6569 		case CUTBOND :  temp = g_strdup(_(" Press the Left mouse button(for pick a bond) and release for \"Delete selected bond\". "));break;
6570 		case MEASURE		:  temp = g_strdup(_(" Press and release the Left mouse button for \"Select your atoms\". "));
6571 							HideShowMeasure(FALSE);
6572 							change_of_center(NULL,NULL);
6573 							drawGeom();
6574 							break;
6575 		case ADDFRAGMENT :  temp = g_strdup(_(" Press and release the Left mouse button for \"Insert a Fragment\". "));break;
6576 	}
6577 	if(temp)
6578 	{
6579 		gtk_statusbar_pop(GTK_STATUSBAR(StatusOperation),idStatusOperation);
6580 		gtk_statusbar_push(GTK_STATUSBAR(StatusOperation),idStatusOperation,temp);
6581 		g_free(temp);
6582 	}
6583 	drawGeom();
6584 }
6585 /*****************************************************************************/
setPersonalFragment(Fragment F)6586 void setPersonalFragment(Fragment F)
6587 {
6588 	gint i;
6589 	Frag.NAtoms = F.NAtoms;
6590 	Frag.Atoms = g_malloc(Frag.NAtoms*sizeof(Atom));
6591 	for(i=0;i<F.NAtoms;i++)
6592 	{
6593 		Frag.Atoms[i].Residue = g_strdup(F.Atoms[i].Residue);
6594 		Frag.Atoms[i].Symb = g_strdup(F.Atoms[i].Symb);
6595 		Frag.Atoms[i].mmType = g_strdup(F.Atoms[i].mmType);
6596 		Frag.Atoms[i].pdbType = g_strdup(F.Atoms[i].pdbType);
6597 		Frag.Atoms[i].Coord[0] = F.Atoms[i].Coord[0];
6598 		Frag.Atoms[i].Coord[1] = F.Atoms[i].Coord[1];
6599 		Frag.Atoms[i].Coord[2] = F.Atoms[i].Coord[2];
6600 		Frag.Atoms[i].Charge = F.Atoms[i].Charge;
6601 	}
6602 	Frag.atomToDelete = F.atomToDelete;
6603 	Frag.atomToBondTo = F.atomToBondTo;
6604 	Frag.angleAtom    = F.angleAtom;
6605 
6606 	SetOperation (NULL,ADDFRAGMENT);
6607 }
6608 /*****************************************************************************/
AddFragment(GtkWidget * widget,guint data)6609 void AddFragment(GtkWidget *widget, guint data)
6610 {
6611 	FreeFragment(&Frag);
6612 	Frag = GetFragment(FragItems[data].Name);
6613 	SetOperation (NULL,ADDFRAGMENT);
6614 }
6615 /*****************************************************************************/
add_a_fragment(GtkWidget * button,gchar * fragName)6616 void add_a_fragment(GtkWidget* button, gchar* fragName)
6617 {
6618 	GtkWidget* drawingArea = NULL;
6619 	gchar* slash = NULL;
6620 	if(!fragName) return;
6621 	FreeFragment(&Frag);
6622 	slash = strstr(fragName,"/");
6623 	if(slash && strlen(fragName)>strlen(slash))
6624 	{
6625 		Frag = GetFragment(slash+1);
6626 		if(Frag.NAtoms>1 && strstr(fragName,"Fullerenes"))
6627 		{
6628 			AddHToAtomPDB(&Frag,"C");
6629 		}
6630 		if(Frag.NAtoms<1)
6631 		{
6632 			gint OC1 = -1;
6633 			gint C = -1;
6634 			gint N = -1;
6635 			gint i ;
6636 
6637 			Frag = GetFragmentPPD(slash+1);
6638 			for(i=0;i<Frag.NAtoms;i++)
6639 			{
6640 				if(!strcmp(Frag.Atoms[i].pdbType,"OC1")) OC1 =  i;
6641 				if(!strcmp(Frag.Atoms[i].pdbType,"C")) C =  i;
6642 				if(!strcmp(Frag.Atoms[i].pdbType,"N")) N =  i;
6643 			}
6644 			/* printf("%s\n",Frag.Atoms[0].Residue);*/
6645 			if(Frag.NAtoms>1)
6646 			{
6647 				if(C != -1 && N == -1) AddHToAtomPDB(&Frag,"C");
6648 				else if(C == -1 && N != -1) AddHToAtomPDB(&Frag,"N");
6649 				else if(strlen(Frag.Atoms[0].Residue)<4) AddHToAtomPDB(&Frag,"C");
6650 				else if(strlen(Frag.Atoms[0].Residue)==4)
6651 				{
6652 					if( toupper(Frag.Atoms[0].Residue[0])=='C' || toupper(Frag.Atoms[0].Residue[0])=='O' ) AddHToAtomPDB(&Frag,"N");
6653 					else AddHToAtomPDB(&Frag,"C");
6654 				}
6655 			}
6656 		}
6657 		if(Frag.NAtoms<1)
6658 			addPersonalFragment(fragName, 0, NULL);
6659 	}
6660 	else
6661 		Frag = GetFragment(fragName);
6662 
6663 	drawingArea = g_object_get_data(G_OBJECT(button), "DrawingArea");
6664 	if(drawingArea) add_frag_to_preview_geom(drawingArea, &Frag);
6665 }
6666 /*****************************************************************************/
addAFragment(gchar * fragName)6667 void addAFragment(gchar* fragName)
6668 {
6669 	FreeFragment(&Frag);
6670 	if(fragName) Frag = GetFragment(fragName);
6671 	else return;
6672 	SetOperation (NULL,ADDFRAGMENT);
6673 }
6674 /*****************************************************************************/
initLabelOptions(guint data)6675 void initLabelOptions (guint data)
6676 {
6677 	LabelOption = data ;
6678 }
6679 /*****************************************************************************/
SetLabelOptions(GtkWidget * widget,guint data)6680 void SetLabelOptions (GtkWidget *widget, guint data)
6681 {
6682 	if(LabelOption != data)
6683 	{
6684 		LabelOption = data ;
6685 		drawGeom();
6686 	}
6687 }
6688 /*****************************************************************************/
SetLabelDistances(GtkWidget * win,gboolean YesNo)6689 void SetLabelDistances(GtkWidget *win,gboolean YesNo)
6690 {
6691 	DrawDistance = !DrawDistance;
6692 	drawGeom();
6693 }
6694 /*****************************************************************************/
SetLabelDipole(GtkWidget * win,gboolean YesNo)6695 void SetLabelDipole(GtkWidget *win,gboolean YesNo)
6696 {
6697 	DrawDipole = !DrawDipole;
6698 	drawGeom();
6699 }
6700 /*****************************************************************************/
RenderShad(GtkWidget * win,gboolean YesNo)6701 void RenderShad(GtkWidget *win,gboolean YesNo)
6702 {
6703 	ShadMode = !ShadMode;
6704 	drawGeom();
6705 }
6706 /*****************************************************************************/
RenderPers(GtkWidget * win,gboolean YesNo)6707 void RenderPers(GtkWidget *win,gboolean YesNo)
6708 {
6709 	PersMode = !PersMode;
6710 	if(PersMode)
6711 		define_coefs_pers();
6712 	drawGeom();
6713 }
6714 /*****************************************************************************/
RenderLight(GtkWidget * win,gboolean YesNo)6715 void RenderLight(GtkWidget *win,gboolean YesNo)
6716 {
6717 	LightMode = !LightMode;
6718 	drawGeom();
6719 }
6720 /*****************************************************************************/
RenderOrtep(GtkWidget * win,gboolean YesNo)6721 void RenderOrtep(GtkWidget *win,gboolean YesNo)
6722 {
6723 	OrtepMode = !OrtepMode;
6724 	drawGeom();
6725 }
6726 /*****************************************************************************/
RenderCartoon(GtkWidget * win,gboolean YesNo)6727 void RenderCartoon(GtkWidget *win,gboolean YesNo)
6728 {
6729 	CartoonMode = !CartoonMode;
6730 	drawGeom();
6731 }
6732 /*****************************************************************************/
RenderHBonds(GtkWidget * win,gboolean YesNo)6733 void RenderHBonds(GtkWidget *win,gboolean YesNo)
6734 {
6735 	ShowHBonds = !ShowHBonds;
6736 	if(ShowHBonds) set_Hconnections();
6737 	drawGeom();
6738 }
6739 /*****************************************************************************/
RenderHAtoms(GtkWidget * win,gboolean YesNo)6740 void RenderHAtoms(GtkWidget *win,gboolean YesNo)
6741 {
6742 	gint i;
6743 	for (i=0;i<(gint)Natoms;i++)
6744 	{
6745 		if(!strcmp(geometry0[i].Prop.symbol,"H"))
6746 		{
6747 			geometry[i].show = YesNo;
6748 			geometry0[i].show = YesNo;
6749 		}
6750 	}
6751 	drawGeom();
6752 	ShowHydrogenAtoms = YesNo;
6753 }
6754 /*****************************************************************************/
RenderDipole(GtkWidget * win,gboolean YesNo)6755 void RenderDipole(GtkWidget *win,gboolean YesNo)
6756 {
6757 	ShowDipole = !ShowDipole;
6758 	drawGeom();
6759 }
6760 /*****************************************************************************/
set_dipole_from_charges()6761 void set_dipole_from_charges()
6762 {
6763 	gint i;
6764 	gint j;
6765 
6766 	create_GeomXYZ_from_draw_grometry();
6767 	NumSelectedAtom = -1;
6768 	unselect_all_atoms();
6769 	Dipole.def = TRUE;
6770 	for(i=0;i<3;i++)
6771 		Dipole.value[i] = 0.0;
6772 	for(j=0;j<(gint)Natoms;j++)
6773 	{
6774 		Dipole.value[0] += geometry0[j].X*geometry0[j].Charge;
6775 		Dipole.value[1] += geometry0[j].Y*geometry0[j].Charge;
6776 		Dipole.value[2] += geometry0[j].Z*geometry0[j].Charge;
6777 
6778 	}
6779 	define_geometry();
6780 	drawGeom();
6781 }
6782 /*****************************************************************************/
get_sum_charges()6783 gdouble get_sum_charges()
6784 {
6785 	gdouble c = 0;
6786 	gint j;
6787 
6788 	for(j=0;j<(gint)Natoms;j++)
6789 		c += geometry0[j].Charge;
6790 	return c;
6791 }
6792 /*****************************************************************************/
compute_total_charge()6793 void compute_total_charge()
6794 {
6795 	gdouble c = 0;
6796 	gdouble cNeg = 0;
6797 	gdouble cPos = 0;
6798 	gint j;
6799     	GtkWidget* m;
6800 	gchar tmp[BSIZE];
6801 
6802 	for(j=0;j<(gint)Natoms;j++)
6803 	{
6804 		if(geometry0[j].Charge>0) cPos += geometry0[j].Charge;
6805 		if(geometry0[j].Charge<0) cNeg += geometry0[j].Charge;
6806 		c += geometry0[j].Charge;
6807 
6808 	}
6809 	if(cNeg !=0 && cPos != 0)
6810 	sprintf(tmp,
6811 			_(
6812 			"Total Charge = %f\n"
6813 			"Sum of positive charges = %f\n"
6814 			"Sum of negative charges = %f\n"
6815 			"positive/negative       = %f\n"
6816 			"negative/positive       = %f\n"
6817 			)
6818 			,
6819 			c, cPos, cNeg, cPos/cNeg, cNeg/cPos);
6820 	else
6821 	sprintf(tmp,
6822 			_(
6823 			"Total Charge = %f\n"
6824 			"Sum of positive charges = %f\n"
6825 			"Sum of negative charges = %f\n"
6826 			)
6827 			,
6828 			c, cPos, cNeg);
6829 	m = Message(tmp,_("Info"),TRUE);
6830 	gtk_window_set_modal (GTK_WINDOW (m), TRUE);
6831 }
6832 /*****************************************************************************/
compute_charge_of_selected_atoms()6833 void compute_charge_of_selected_atoms()
6834 {
6835 	gdouble c = 0;
6836 	gdouble cNeg = 0;
6837 	gdouble cPos = 0;
6838 	gint j;
6839     	GtkWidget* m;
6840 	gchar tmp[BSIZE];
6841 
6842 	for(j=0;j<(gint)Natoms;j++)
6843 	{
6844 		if(!if_selected(j)) continue;
6845 
6846 		if(geometry0[j].Charge>0) cPos += geometry0[j].Charge;
6847 		if(geometry0[j].Charge<0) cNeg += geometry0[j].Charge;
6848 		c += geometry0[j].Charge;
6849 
6850 	}
6851 	if(cNeg !=0 && cPos != 0)
6852 	sprintf(tmp,
6853 			_(
6854 			"Total Charge = %f\n"
6855 			"Sum of positive charges = %f\n"
6856 			"Sum of negative charges = %f\n"
6857 			"positive/negative       = %f\n"
6858 			"negative/positive       = %f\n"
6859 			)
6860 			,
6861 			c, cPos, cNeg, cPos/cNeg, cNeg/cPos);
6862 	else
6863 	sprintf(tmp,
6864 			_(
6865 			"Total Charge = %f\n"
6866 			"Sum of positive charges = %f\n"
6867 			"Sum of negative charges = %f\n"
6868 			)
6869 			,
6870 			c, cPos, cNeg);
6871 	m = Message(tmp,_("Info"),TRUE);
6872 	gtk_window_set_modal (GTK_WINDOW (m), TRUE);
6873 }
6874 /********************************************************************************/
create_text_win(gchar * title)6875 static GtkWidget* create_text_win(gchar* title)
6876 {
6877 	GtkWidget *Win;
6878 	GtkWidget *frame;
6879 	GtkWidget *vboxall;
6880 	GtkWidget *vboxwin;
6881 	GtkWidget *text;
6882 
6883 	/* Principal Window */
6884 	Win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
6885 	gtk_window_set_title(GTK_WINDOW(Win),title);
6886 	gtk_window_set_position(GTK_WINDOW(Win),GTK_WIN_POS_CENTER);
6887 	gtk_window_set_transient_for(GTK_WINDOW(Win),GTK_WINDOW(Fenetre));
6888 	gtk_window_set_modal (GTK_WINDOW (Win), TRUE);
6889 
6890 	gtk_widget_realize(Win);
6891 	g_signal_connect(G_OBJECT(Win),"delete_event",(GCallback)gtk_widget_destroy,NULL);
6892 
6893 	gtk_container_set_border_width (GTK_CONTAINER (Win), 5);
6894 	vboxall = create_vbox(Win);
6895 	vboxwin = vboxall;
6896 
6897 	frame = gtk_frame_new (NULL);
6898 	gtk_container_set_border_width (GTK_CONTAINER (frame), 5);
6899 	gtk_frame_set_shadow_type( GTK_FRAME(frame),GTK_SHADOW_ETCHED_OUT);
6900 	gtk_container_add(GTK_CONTAINER(vboxall),frame);
6901 	gtk_widget_show (frame);
6902 	text = create_text(Win,frame,TRUE);
6903 	set_font (text,FontsStyleResult.fontname);
6904 	set_base_style(text,FontsStyleResult.BaseColor.red ,FontsStyleResult.BaseColor.green ,FontsStyleResult.BaseColor.blue);
6905 	set_text_style(text,FontsStyleResult.TextColor.red ,FontsStyleResult.TextColor.green ,FontsStyleResult.TextColor.blue);
6906 	g_object_set_data(G_OBJECT (Win), "Text", text);
6907 	return Win;
6908 }
6909 /*****************************************************************************/
compute_charge_by_residue()6910 void compute_charge_by_residue()
6911 {
6912 	gint i;
6913 	gint j;
6914 	gint k;
6915 	gdouble* charges = NULL;
6916 	gint nr = 0;
6917 	GtkWidget *win;
6918 	GtkWidget *text;
6919 	gchar tmp[BSIZE];
6920 	gint* nums = NULL;
6921 
6922 	if(Natoms<1) return;
6923 
6924 	for(j=0;j<(gint)Natoms;j++)
6925 	{
6926 		if( nr<geometry0[j].ResidueNumber+1) nr = geometry0[j].ResidueNumber+1;
6927 	}
6928 	if(nr<1) return;
6929 
6930 	charges = g_malloc(nr*sizeof(gdouble));
6931 	nums = g_malloc(nr*sizeof(gint));
6932 
6933 	for(k=0;k<nr;k++) charges[k] = 0;
6934 	for(k=0;k<nr;k++) nums[k] = 0;
6935 
6936 
6937 	for(j=0;j<(gint)Natoms;j++)
6938 	{
6939 		k =  geometry0[j].ResidueNumber;
6940 		charges[k] += geometry0[j].Charge;
6941 		nums[k] = j;
6942 	}
6943 	for(i=0;i<nr-1;i++)
6944 	{
6945 		k = i;
6946 		for(j=i+1;j<nr;j++)
6947 			if(geometry0[nums[k]].ResidueNumber>geometry0[nums[j]].ResidueNumber) k = j;
6948 		if(i!=k)
6949 		{
6950 			gdouble x;
6951 			gint ix;
6952 			x = charges[k];
6953 			charges[k] = charges[i];
6954 			charges[i] = x;
6955 			ix = nums[k];
6956 			nums[k] = nums[i];
6957 			nums[i] = ix;
6958 
6959 		}
6960 	}
6961 	win = create_text_win(_("Charge by residues"));
6962     	gtk_widget_set_size_request(GTK_WIDGET(win),(gint)(ScreenHeight*0.5),(gint)(ScreenHeight*0.5));
6963 	text = g_object_get_data(G_OBJECT (win), "Text");
6964 	if(text)
6965 	for(k=0;k<nr;k++)
6966 	{
6967 		j = nums[k]+1;
6968 		sprintf(tmp,_("%s[%d] Charge = %f\n"),
6969 				geometry0[j-1].Residue,geometry0[j-1].ResidueNumber+1,charges[k]);
6970 		gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL,tmp,-1);
6971 	}
6972 	if(nums)g_free(nums);
6973 	if(charges)g_free(charges);
6974 	gtk_widget_show_all(win);
6975 }
6976 /*****************************************************************************/
compute_dipole_from_charges()6977 void compute_dipole_from_charges()
6978 {
6979 	gint j;
6980 	gdouble D[3] = {0,0,0};
6981     	GtkWidget* m;
6982 	gchar tmp[100];
6983 	gdouble tot = 0;
6984 
6985 	for(j=0;j<(gint)Natoms;j++)
6986 	{
6987 		D[0] += geometry0[j].X*geometry0[j].Charge;
6988 		D[1] += geometry0[j].Y*geometry0[j].Charge;
6989 		D[2] += geometry0[j].Z*geometry0[j].Charge;
6990 	}
6991 	for(j=0;j<3;j++)
6992 		D[j] *= AUTODEB;
6993 
6994 	for(j=0;j<3;j++)
6995 		tot += D[j]*D[j];
6996 	tot = sqrt(tot);
6997 
6998 	sprintf(tmp,_("Dipole (Debye) : X= %f Y= %f Z= %f  Tot=%f\n"),D[0] ,  D[1], D[2],tot);
6999 	m = Message(tmp,_("Info"),TRUE);
7000 	gtk_window_set_modal (GTK_WINDOW (m), TRUE);
7001 }
7002 /*****************************************************************************/
get_distance(gint i,gint j)7003 gchar *get_distance(gint i,gint j)
7004 {
7005         Point A;
7006         Point B;
7007         guint k;
7008         guint Ni=-1;
7009         guint Nj=-1;
7010         gchar *serr;
7011 
7012        for (k=0;k<Natoms;k++)
7013 	  if(geometry[k].N== (guint)i)
7014 		Ni = k;
7015        for (k=0;k<Natoms;k++)
7016 	  if(geometry[k].N== (guint)j)
7017 		Nj = k;
7018 
7019         if(Ni==-1 || Nj == -1)
7020         {
7021            serr=g_strdup("ERROR");
7022            return serr;
7023         }
7024 
7025 	A.C[0]=geometry[Ni].X;
7026 	A.C[1]=geometry[Ni].Y;
7027 	A.C[2]=geometry[Ni].Z;
7028 
7029 	B.C[0]=geometry[Nj].X;
7030 	B.C[1]=geometry[Nj].Y;
7031 	B.C[2]=geometry[Nj].Z;
7032 
7033         return get_distance_points(A,B,FALSE);
7034 }
7035 /*****************************************************************************/
get_angle(gint i,gint j,gint l)7036 gchar *get_angle(gint i,gint j,gint l)
7037 {
7038         Point A;
7039         Point B;
7040         guint k;
7041         guint Ni=0;
7042         guint Nj=0;
7043         guint Nl=0;
7044 
7045        for (k=0;k<Natoms;k++)
7046 	  if(geometry[k].N== (guint)i)
7047 		Ni = k;
7048        for (k=0;k<Natoms;k++)
7049 	  if(geometry[k].N== (guint)j)
7050 		Nj = k;
7051        for (k=0;k<Natoms;k++)
7052 	  if(geometry[k].N== (guint)l)
7053 		Nl = k;
7054 
7055 
7056 	A.C[0]=geometry[Ni].X-geometry[Nj].X;
7057 	A.C[1]=geometry[Ni].Y-geometry[Nj].Y;
7058 	A.C[2]=geometry[Ni].Z-geometry[Nj].Z;
7059 
7060 	B.C[0]=geometry[Nl].X-geometry[Nj].X;
7061 	B.C[1]=geometry[Nl].Y-geometry[Nj].Y;
7062 	B.C[2]=geometry[Nl].Z-geometry[Nj].Z;
7063 
7064         return get_angle_vectors(A,B);
7065 }
7066 /*****************************************************************************/
get_dihedral(gint i,gint j,gint l,gint m)7067 gchar *get_dihedral(gint i,gint j,gint l,gint m)
7068 {
7069         Point A;
7070         Point B;
7071         Point V1;
7072         Point V2;
7073         Point W1;
7074         guint k;
7075         guint Ni=0;
7076         guint Nj=0;
7077         guint Nl=0;
7078         guint Nm=0;
7079 	gdouble angle;
7080 	gdouble dihsgn;
7081 
7082        for (k=0;k<Natoms;k++)
7083 	  if(geometry[k].N== (guint)i)
7084 		Ni = k;
7085        for (k=0;k<Natoms;k++)
7086 	  if(geometry[k].N==(guint)j)
7087 		Nj = k;
7088        for (k=0;k<Natoms;k++)
7089 	  if(geometry[k].N== (guint)l)
7090 		Nl = k;
7091        for (k=0;k<Natoms;k++)
7092 	  if(geometry[k].N== (guint)m)
7093 		Nm = k;
7094 
7095 
7096 	V1.C[0]=geometry[Ni].X-geometry[Nj].X;
7097 	V1.C[1]=geometry[Ni].Y-geometry[Nj].Y;
7098 	V1.C[2]=geometry[Ni].Z-geometry[Nj].Z;
7099 
7100 	V2.C[0]=geometry[Nl].X-geometry[Nj].X;
7101 	V2.C[1]=geometry[Nl].Y-geometry[Nj].Y;
7102 	V2.C[2]=geometry[Nl].Z-geometry[Nj].Z;
7103 
7104         A = get_produit_vectoriel(V1,V2);
7105 
7106 	V1.C[0]=geometry[Nm].X-geometry[Nl].X;
7107 	V1.C[1]=geometry[Nm].Y-geometry[Nl].Y;
7108 	V1.C[2]=geometry[Nm].Z-geometry[Nl].Z;
7109 
7110 	V2.C[0]=geometry[Nj].X-geometry[Nl].X;
7111 	V2.C[1]=geometry[Nj].Y-geometry[Nl].Y;
7112 	V2.C[2]=geometry[Nj].Z-geometry[Nl].Z;
7113 
7114         B = get_produit_vectoriel(V2,V1);
7115 
7116         angle = atof(get_angle_vectors(A,B));
7117 
7118         W1 = get_produit_vectoriel(A,B);
7119         if (get_module(W1)<1e-5 )
7120               dihsgn = 1.0e0;
7121         else
7122 	{
7123         dihsgn = get_scalaire(W1,V2);
7124         if (dihsgn>0)
7125             dihsgn = -1.0e0;
7126         else
7127            dihsgn = 1.0e0;
7128 	}
7129           angle *=dihsgn;
7130 	return g_strdup_printf("%f",angle);
7131 }
7132 /*****************************************************************************/
define_coord_maxmin()7133 void define_coord_maxmin()
7134 {
7135 	guint i;
7136         gdouble XmaxMmin;
7137         gdouble YmaxMmin;
7138         if(Natoms==0)
7139         	return;
7140 	coordmaxmin.Xmax =geometry[0].X;
7141 	coordmaxmin.Ymax =geometry[0].Y;
7142 	coordmaxmin.Zmax =geometry[0].Z;
7143 
7144 	coordmaxmin.Xmin =geometry[0].X;
7145 	coordmaxmin.Ymin =geometry[0].Y;
7146 	coordmaxmin.Zmin =geometry[0].Z;
7147 
7148 	for (i = 1;i<Natoms;i++)
7149 	{
7150 	if (geometry[i].X>coordmaxmin.Xmax)
7151 			   coordmaxmin.Xmax =geometry[i].X;
7152 	if (geometry[i].X<coordmaxmin.Xmin)
7153 			   coordmaxmin.Xmin =geometry[i].X;
7154 
7155 	if (geometry[i].Y>coordmaxmin.Ymax)
7156 			   coordmaxmin.Ymax =geometry[i].Y;
7157 	if (geometry[i].Y<coordmaxmin.Ymin)
7158 			   coordmaxmin.Ymin =geometry[i].Y;
7159 
7160     if (geometry[i].Z>coordmaxmin.Zmax)
7161 			   coordmaxmin.Zmax =geometry[i].Z;
7162 	if (geometry[i].Z<coordmaxmin.Zmin)
7163 			   coordmaxmin.Zmin =geometry[i].Z;
7164 
7165 	}
7166 	XmaxMmin = coordmaxmin.Xmax-coordmaxmin.Xmin;
7167         if(fabs(XmaxMmin)<1.e-4 ) XmaxMmin = 1.0;
7168 	YmaxMmin = coordmaxmin.Ymax-coordmaxmin.Ymin;
7169         if(fabs(YmaxMmin)<1.e-4 ) YmaxMmin = 1.0;
7170         coordmaxmin.Cmax = XmaxMmin;
7171 	if(coordmaxmin.Cmax<YmaxMmin)
7172         	coordmaxmin.Cmax = YmaxMmin;
7173 
7174 }
7175 /*****************************************************************************/
geometry_in_au()7176 void geometry_in_au()
7177 {
7178         guint i;
7179         for(i=0;i<Natoms;i++)
7180 	{
7181            geometry[i].X *=ANG_TO_BOHR ;
7182            geometry[i].Y *=ANG_TO_BOHR ;
7183            geometry[i].Z *=ANG_TO_BOHR ;
7184         }
7185 }
7186 /*****************************************************************************/
set_layer(gchar * layer,GabEditLayerType * l)7187 static void set_layer(gchar* layer, GabEditLayerType* l)
7188 {
7189 	if(strstr(layer,"Low")) *l = LOW_LAYER;
7190 	else if(strstr(layer,"Medium")) *l= MEDIUM_LAYER;
7191 	else *l = HIGH_LAYER;
7192 }
7193 /*****************************************************************************/
set_constant_variable(gint i,gboolean xyz)7194 static void set_constant_variable(gint i, gboolean xyz)
7195 {
7196 	if(xyz)
7197 	{
7198         	if(!test(GeomXYZ[i].X) || !test(GeomXYZ[i].Y) || !test(GeomXYZ[i].Z))
7199 			geometry[i].Variable = TRUE;
7200 		else
7201 			geometry[i].Variable = FALSE;
7202 	}
7203 	else
7204 	{
7205 		if( i<1)
7206 		{
7207 			geometry[i].Variable = FALSE;
7208 			return;
7209 		}
7210 		if(i>0 && !test(Geom[i].R))
7211 		{
7212 			geometry[i].Variable = TRUE;
7213 			return;
7214 		}
7215 		if(i>1 && !test(Geom[i].Angle))
7216 		{
7217 			geometry[i].Variable = TRUE;
7218 			return;
7219 		}
7220 		if(i>2 && !test(Geom[i].Dihedral))
7221 		{
7222 			geometry[i].Variable = TRUE;
7223 			return;
7224 		}
7225 		geometry[i].Variable = FALSE;
7226 	}
7227 }
7228 /*****************************************************************************/
set_layer_of_selected_atoms(GabEditLayerType l)7229 void set_layer_of_selected_atoms(GabEditLayerType l)
7230 {
7231 	gint i;
7232 	for (i=0;i<(gint)Natoms;i++)
7233 	{
7234 		if(if_selected(i))
7235 		{
7236 			geometry[i].Layer = l;
7237 			geometry0[i].Layer = l;
7238 		}
7239 	}
7240 	create_GeomXYZ_from_draw_grometry();
7241 	drawGeom();
7242 }
7243 /*****************************************************************************/
define_geometry_from_xyz()7244 void define_geometry_from_xyz()
7245 {
7246         guint i;
7247 
7248         for(i=0;i<Natoms;i++)
7249 	{
7250          if(!test(GeomXYZ[i].X))
7251                  geometry[i].X = get_value_variableXYZ(GeomXYZ[i].X);
7252           else
7253 		geometry[i].X = atof(GeomXYZ[i].X);
7254          if(!test(GeomXYZ[i].Y))
7255                  geometry[i].Y = get_value_variableXYZ(GeomXYZ[i].Y);
7256           else
7257 		geometry[i].Y = atof(GeomXYZ[i].Y);
7258          if(!test(GeomXYZ[i].Z))
7259                  geometry[i].Z = get_value_variableXYZ(GeomXYZ[i].Z);
7260           else
7261 		geometry[i].Z = atof(GeomXYZ[i].Z);
7262 	geometry[i].Prop = prop_atom_get(GeomXYZ[i].Symb);
7263 	geometry[i].mmType = g_strdup(GeomXYZ[i].mmType);
7264 	geometry[i].pdbType = g_strdup(GeomXYZ[i].pdbType);
7265 	geometry[i].Residue = g_strdup(GeomXYZ[i].Residue);
7266 	geometry[i].ResidueNumber = GeomXYZ[i].ResidueNumber;
7267 	geometry[i].show = TRUE;
7268 	geometry[i].Charge = atof(GeomXYZ[i].Charge);
7269 	set_layer(GeomXYZ[i].Layer, &geometry[i].Layer);
7270 	set_constant_variable(i, TRUE);
7271 	geometry[i].N = i+1;
7272 	geometry[i].typeConnections = NULL;
7273 	}
7274 	for(i=0;i<Natoms;i++)
7275 	{
7276 		gint j;
7277 		geometry[i].typeConnections = g_malloc(Natoms*sizeof(gint));
7278 		for(j=0;j<(gint)Natoms;j++) geometry[i].typeConnections[j] = 0;
7279 		if(GeomXYZ[i].typeConnections)
7280 		{
7281 			for(j=0;j<Natoms;j++)
7282 			geometry[i].typeConnections[j] = GeomXYZ[i].typeConnections[j];
7283 		}
7284 	}
7285 }
7286 /*****************************************************************************/
define_geometry_from_zmat()7287 gboolean define_geometry_from_zmat()
7288 {
7289   gdouble cosph,sinph,costh,sinth,coskh,sinkh;
7290   gdouble cosa,sina,cosd,sind;
7291   gdouble dist,angle,dihed;
7292   gdouble xpd,ypd,zpd,xqd,yqd,zqd;
7293   gdouble xa,ya,za,xb,yb,zb;
7294   gdouble rbc,xyb,yza,temp;
7295   gdouble xpa,ypa,zqa;
7296   gdouble xd,yd,zd;
7297   gboolean flag;
7298   gint i, na, nb, nc;
7299 
7300   if (Natoms == 0)
7301     return( FALSE );
7302   /* Atom #1 */
7303   geometry[0].X = 0.0;
7304   geometry[0].Y = 0.0;
7305   geometry[0].Z = 0.0;
7306   geometry[0].N = 1;
7307   geometry[0].typeConnections = NULL;
7308 
7309   if (Natoms == 1)
7310   {
7311     geometry[0].Prop = prop_atom_get(Geom[0].Symb);
7312     geometry[0].mmType   = g_strdup(Geom[0].mmType);
7313     geometry[0].pdbType   = g_strdup(Geom[0].pdbType);
7314     geometry[0].Residue   = g_strdup(Geom[0].Residue);
7315     geometry[0].ResidueNumber   = Geom[0].ResidueNumber;
7316     geometry[0].show   = TRUE;
7317     geometry[0].Charge = atof(Geom[0].Charge);
7318     set_layer(Geom[0].Layer, &geometry[0].Layer);
7319     set_constant_variable(0, FALSE);
7320     return( TRUE );
7321   }
7322 
7323   /* Atom #2 */
7324   if(!test(Geom[1].R))
7325     geometry[1].X = get_value_variableZmat(Geom[1].R);
7326   else
7327     geometry[1].X = atof(Geom[1].R);
7328   geometry[1].Y = 0.0;
7329   geometry[1].Z = 0.0;
7330   geometry[1].N = 2;
7331   geometry[1].typeConnections = NULL;
7332 
7333   if( Natoms == 2 )
7334   {
7335     geometry[0].Prop = prop_atom_get(Geom[0].Symb);
7336     geometry[1].Prop = prop_atom_get(Geom[1].Symb);
7337     geometry[0].mmType = g_strdup(Geom[0].mmType);
7338     geometry[1].mmType = g_strdup(Geom[1].mmType);
7339     geometry[0].pdbType = g_strdup(Geom[0].pdbType);
7340     geometry[1].pdbType = g_strdup(Geom[1].pdbType);
7341     geometry[0].Residue = g_strdup(Geom[0].Residue);
7342     geometry[1].Residue = g_strdup(Geom[1].Residue);
7343     geometry[0].ResidueNumber   = Geom[0].ResidueNumber;
7344     geometry[1].ResidueNumber   = Geom[1].ResidueNumber;
7345     geometry[0].show   = TRUE;
7346     geometry[1].show   = TRUE;
7347     geometry[0].Charge = atof(Geom[0].Charge);
7348     geometry[1].Charge = atof(Geom[1].Charge);
7349     set_layer(Geom[0].Layer, &geometry[0].Layer);
7350     set_layer(Geom[1].Layer, &geometry[1].Layer);
7351     set_constant_variable(0, FALSE);
7352     set_constant_variable(1, FALSE);
7353     return( TRUE );
7354   }
7355 
7356   /* Atom #3 */
7357   if(!test(Geom[2].R))
7358     dist = get_value_variableZmat(Geom[2].R);
7359   else
7360     dist = atof(Geom[2].R);
7361 
7362   if(!test(Geom[2].Angle))
7363     angle = get_value_variableZmat(Geom[2].Angle);
7364   else
7365     angle = atof(Geom[2].Angle);
7366 
7367     angle *=  DEG_TO_RAD;
7368 
7369   cosa = cos(angle);
7370   sina = sin(angle);
7371 
7372   if( atoi (Geom[2].NAngle) == 2 )
7373   	geometry[2].X =  geometry[0].X + cosa*dist;
7374   else
7375   	geometry[2].X =  geometry[1].X - cosa*dist;
7376 
7377   geometry[2].Y =  sina*dist;
7378   geometry[2].Z = 0.0;
7379   geometry[2].N = 3;
7380   geometry[2].typeConnections = NULL;
7381 
7382   for (i = 3; i <(gint)Natoms; i++)
7383   {
7384   if(!test(Geom[i].R))
7385     dist = get_value_variableZmat(Geom[i].R);
7386   else
7387     dist = atof(Geom[i].R);
7388 
7389   if(!test(Geom[i].Angle))
7390     angle = get_value_variableZmat(Geom[i].Angle);
7391   else
7392     angle = atof(Geom[i].Angle) ;
7393 
7394   if(!test(Geom[i].Dihedral))
7395     dihed = get_value_variableZmat(Geom[i].Dihedral);
7396   else
7397     dihed = atof(Geom[i].Dihedral) ;
7398 
7399     angle *= DEG_TO_RAD;
7400     dihed *= DEG_TO_RAD;
7401 
7402     na = atoi(Geom[i].NR)-1;
7403     nb = atoi(Geom[i].NAngle)-1;
7404     nc = atoi(Geom[i].NDihedral)-1;
7405 
7406     xb = geometry[nb].X - geometry[na].X;
7407     yb = geometry[nb].Y - geometry[na].Y;
7408     zb = geometry[nb].Z - geometry[na].Z;
7409 
7410     rbc = xb*xb + yb*yb + zb*zb;
7411     if( rbc < 0.0001 )
7412       return( FALSE );
7413     rbc = 1.0/sqrt(rbc);
7414 
7415     cosa = cos(angle);
7416     sina = sin(angle);
7417 
7418 
7419     if( fabs(cosa) >= 0.999999 )
7420     {
7421       /* Colinear */
7422       temp = dist*rbc*cosa;
7423       geometry[i].X  = geometry[na].X + temp*xb;
7424       geometry[i].Y  = geometry[na].Y + temp*yb;
7425       geometry[i].Z  = geometry[na].Z + temp*zb;
7426       geometry[i].N = i+1;
7427       geometry[i].typeConnections = NULL;
7428     }
7429     else
7430     {
7431       xa = geometry[nc].X - geometry[na].X;
7432       ya = geometry[nc].Y - geometry[na].Y;
7433       za = geometry[nc].Z - geometry[na].Z;
7434 
7435       sind = -sin(dihed);
7436       cosd = cos(dihed);
7437 
7438       xd = dist*cosa;
7439       yd = dist*sina*cosd;
7440       zd = dist*sina*sind;
7441 
7442       xyb = sqrt(xb*xb + yb*yb);
7443       if( xyb < 0.1 )
7444       {
7445 	/* Rotate about y-axis! */
7446 	temp = za; za = -xa; xa = temp;
7447 	temp = zb; zb = -xb; xb = temp;
7448 	xyb = sqrt(xb*xb + yb*yb);
7449 	flag = TRUE;
7450       }
7451       else
7452 	flag = FALSE;
7453 
7454       costh = xb/xyb;
7455       sinth = yb/xyb;
7456       xpa = costh*xa + sinth*ya;
7457       ypa = costh*ya - sinth*xa;
7458 
7459       sinph = zb*rbc;
7460       cosph = sqrt(1.0 - sinph*sinph);
7461       zqa = cosph*za  - sinph*xpa;
7462 
7463       yza = sqrt(ypa*ypa + zqa*zqa);
7464 
7465       if( yza > 1.0E-10 )
7466       {
7467 	coskh = ypa/yza;
7468 	sinkh = zqa/yza;
7469 
7470 	ypd = coskh*yd - sinkh*zd;
7471 	zpd = coskh*zd + sinkh*yd;
7472       }
7473       else
7474       {
7475 	/* coskh = 1.0; */
7476 	/* sinkh = 0.0; */
7477 	ypd = yd;
7478 	zpd = zd;
7479       }
7480 
7481       xpd = cosph*xd  - sinph*zpd;
7482       zqd = cosph*zpd + sinph*xd;
7483       xqd = costh*xpd - sinth*ypd;
7484       yqd = costh*ypd + sinth*xpd;
7485 
7486       if( flag )
7487       {
7488 	/* Rotate about y-axis! */
7489 	geometry[i].X = geometry[na].X - zqd;
7490 	geometry[i].Y = geometry[na].Y + yqd;
7491 	geometry[i].Z = geometry[na].Z + xqd;
7492         geometry[i].N = i+1;
7493         geometry[i].typeConnections = NULL;
7494       }
7495       else
7496       {
7497 	geometry[i].X = geometry[na].X + xqd;
7498 	geometry[i].Y = geometry[na].Y + yqd;
7499 	geometry[i].Z = geometry[na].Z + zqd;
7500         geometry[i].N = i+1;
7501         geometry[i].typeConnections = NULL;
7502       }
7503     }
7504   }
7505   for(i=0;i<(gint)Natoms;i++)
7506   {
7507 	geometry[i].Prop = prop_atom_get(Geom[i].Symb);
7508     	geometry[i].mmType = g_strdup(Geom[i].mmType);
7509     	geometry[i].pdbType = g_strdup(Geom[i].pdbType);
7510     	geometry[i].Residue = g_strdup(Geom[i].Residue);
7511     	geometry[i].ResidueNumber = Geom[i].ResidueNumber;
7512     	geometry[i].Charge = atof(Geom[i].Charge);
7513     	geometry[i].show   = TRUE;
7514     	set_layer(Geom[i].Layer, &geometry[i].Layer);
7515     	set_constant_variable(i, FALSE);
7516   }
7517   return( TRUE );
7518 }
7519 /*****************************************************************************/
set_optimal_geom_view()7520 void set_optimal_geom_view()
7521 {
7522 	gushort Xmax;
7523 	gushort Ymax;
7524 	gushort Rmax;
7525 	gint Xi;
7526 	gint Yi;
7527 	guint i;
7528 	gdouble X;
7529 	gdouble Y;
7530 	gdouble Cmax;
7531 	gint X1,X2;
7532 	gint Y1,Y2;
7533 
7534 	Xmax=GeomDrawingArea->allocation.width;
7535 	Ymax=GeomDrawingArea->allocation.height;
7536 	X1 = Xmax;
7537 	X2 = Xmax;
7538 	Y1 = Ymax;
7539 	Y2 = Ymax;
7540 
7541 	Rmax = Xmax;
7542 	if(Rmax<Ymax) Rmax = Ymax;
7543 
7544 	sort_with_zaxis();
7545 	define_coefs_pers();
7546 	define_coord_maxmin();
7547 
7548 	for (i = 0;i<Natoms;i++)
7549 	{
7550 		if(PersMode)
7551 		{
7552 			X = geometry[i].X*camera.f/(-geometry[i].Z+camera.position);
7553 			Y = geometry[i].Y*camera.f/(-geometry[i].Z+camera.position);
7554 			Cmax  = coordmaxmin.Cmax*camera.f/(camera.position);
7555 		}
7556 		else
7557 		{
7558 			X = geometry[i].X;
7559 			Y = geometry[i].Y;
7560 			Cmax = coordmaxmin.Cmax;
7561 		}
7562 		Xi = (gint)(X/Cmax*factor*Rmax/2)+Xmax/2+TransX;
7563 		Yi = (gint)(-Y/Cmax*factor*Rmax/2)+Ymax/2+TransY;
7564 		if(i==0)
7565 		{
7566 			X1 = Xi; X2 =Xi; Y1 = Yi; Y2 = Yi;
7567 		}
7568 		else
7569 		{
7570 			if(X1>Xi) X1 = Xi;
7571 			if(X2<Xi) X2 = Xi;
7572 			if(Y1>Yi) Y1 = Yi;
7573 			if(Y2<Yi) Y2 = Yi;
7574 		}
7575 	}
7576 	if((X2-X1)>(gint)Xmax)
7577 		factor *= fabs((gdouble)(Xmax-20)/(X2-X1));
7578 
7579 	if((Y2-Y1)>(gint)Ymax)
7580 		factor *= fabs((gdouble)(Ymax-20)/(Y2-Y1));
7581 }
7582 /********************************************************************************/
define_good_factor()7583 void define_good_factor()
7584 {
7585 	set_optimal_geom_view();
7586 }
7587 /********************************************************************************/
7588 /*
7589 static void define_good_trans()
7590 {
7591 	gdouble C[3]={0,0,0};
7592 	gint i;
7593 	gint k;
7594 	gushort Xmax;
7595 	gushort Ymax;
7596 	gushort Rmax;
7597 	gdouble Cmax;
7598 
7599 	printf("Begin define_good_trans\n");
7600 	if(!GeomDrawingArea) return;
7601 	if(Natoms>0)
7602 	{
7603 		if(PersMode) Cmax  = coordmaxmin.Cmax*camera.f/(camera.position);
7604 		else Cmax = coordmaxmin.Cmax;
7605 	}
7606 	else return;
7607 
7608 	Xmax=GeomDrawingArea->allocation.width;
7609 	Ymax=GeomDrawingArea->allocation.height;
7610 	Rmax = Xmax;
7611 	if(Rmax<Ymax) Rmax = Ymax;
7612 
7613 	for (i=0;i<(gint)Natoms;i++)
7614 	{
7615 		C[0] += geometry[i].X;
7616 		C[1] += geometry[i].Y;
7617 		C[2] += geometry[i].Z;
7618 	}
7619 	for(k=0;k<3;k++) C[k] /= (gdouble)Natoms;
7620 	TransX = (gint)(-C[0]/Cmax*factor*Rmax/2);
7621 	TransY = (gint)(C[1]/Cmax*factor*Rmax/2);
7622 }
7623 */
7624 /*****************************************************************************/
define_coord_ecran()7625 void define_coord_ecran()
7626 {
7627 	gushort Xmax;
7628 	gushort Ymax;
7629 	gushort Rmax;
7630 	gint Xi;
7631 	gint Yi;
7632 	guint i;
7633 	gdouble X;
7634 	gdouble Y;
7635 	gdouble Cmax;
7636 
7637 	Xmax=GeomDrawingArea->allocation.width;
7638 	Ymax=GeomDrawingArea->allocation.height;
7639 	Rmax = Xmax;
7640 	if(Rmax<Ymax)
7641 		Rmax = Ymax;
7642 
7643 	for (i = 0;i<Natoms;i++)
7644 	{
7645 	if(PersMode)
7646 	{
7647 	X = geometry[i].X*camera.f/(-geometry[i].Z+camera.position);
7648 	Y = geometry[i].Y*camera.f/(-geometry[i].Z+camera.position);
7649 	Cmax  = coordmaxmin.Cmax*camera.f/(camera.position);
7650 	}
7651 	else
7652 	{
7653 	X = geometry[i].X;
7654 	Y = geometry[i].Y;
7655 	Cmax = coordmaxmin.Cmax;
7656 	}
7657 	Xi = (gint)(X/Cmax*factor*Rmax/2)+Xmax/2;
7658 	Yi = (gint)(-Y/Cmax*factor*Rmax/2)+Ymax/2;
7659 
7660 	geometry[i].Xi = Xi + TransX;
7661 	geometry[i].Yi = Yi + TransY;
7662 	geometry[i].Rayon = (gushort)(geometry[i].Prop.radii/coordmaxmin.Cmax*factor*Rmax/2);
7663 	}
7664 	CenterCoor[0]=0.0;
7665 	CenterCoor[1]=0.0;
7666 	for (i = 0;i<Natoms;i++)
7667 	{
7668 	CenterCoor[0] +=geometry[i].Xi;
7669 	CenterCoor[1] +=geometry[i].Yi;
7670 	}
7671 
7672 	CenterCoor[0] /=Natoms;
7673 	CenterCoor[1] /=Natoms;
7674 	if(Ddef)
7675 	{
7676 		for(i=0;i<NDIVDIPOLE;i++)
7677 		{
7678 			if(PersMode)
7679 			{
7680 			X = dipole[i][0]*camera.f/(-dipole[i][2]+camera.position);
7681 			Y = dipole[i][1]*camera.f/(-dipole[i][2]+camera.position);
7682 			Cmax  = coordmaxmin.Cmax*camera.f/(camera.position);
7683 			}
7684 			else
7685 			{
7686 			X = dipole[i][0];
7687 			Y = dipole[i][1];
7688 			Cmax = coordmaxmin.Cmax;
7689 			}
7690 			DXi[i] = (gint)(X/Cmax*factor*Rmax/2)+Xmax/2 + TransX;
7691 			DYi[i] = (gint)(-Y/Cmax*factor*Rmax/2)+Ymax/2 + TransY;
7692 		}
7693 	}
7694 }
7695 /*****************************************************************************/
sort_with_zaxis()7696 void sort_with_zaxis()
7697 {
7698 	guint i;
7699 	guint j;
7700 	guint k;
7701 	GeomDef tmpgeom;
7702 	gdouble Z = 0;
7703 
7704 	for (i = 0;i<Natoms-1;i++)
7705 	{
7706         	Z = geometry[i].Z;
7707 		k=i;
7708 		for (j = i+1;j<Natoms;j++)
7709 			if(Z>geometry[j].Z)
7710 			{
7711 				k=j;
7712         			Z =geometry[k].Z;
7713 			}
7714 		if(k!=i)
7715 		{
7716         		tmpgeom = geometry[i];
7717         		geometry[i] = geometry[k];
7718         		geometry[k] = tmpgeom;
7719 
7720 
7721 			tmpgeom = geometry0[i];
7722         		geometry0[i] = geometry0[k];
7723         		geometry0[k] = tmpgeom;
7724 
7725 			if(NumSelectedAtom == (gint)i)
7726 				NumSelectedAtom = (gint)k;
7727 			else
7728 			if(NumSelectedAtom == (gint)k)
7729 				NumSelectedAtom = (gint)i;
7730 
7731 		}
7732 	}
7733 	calcul_ndipole();
7734 }
7735 /*****************************************************************************/
define_coefs_pers()7736 void define_coefs_pers()
7737 {
7738 	guint i;
7739         if(fabs(coordmaxmin.Zmax-coordmaxmin.Zmin)<1.e-6)
7740 	{
7741 		camera.position = 10;
7742 		camera.f = 5;
7743         	for(i=0;i<Natoms;i++)
7744 			geometry[i].Coefpers = 1.0;
7745 	}
7746         else
7747 	{
7748 		gdouble posx = 4*fabs(coordmaxmin.Xmax-coordmaxmin.Xmin);
7749 		gdouble posy = 4*fabs(coordmaxmin.Ymax-coordmaxmin.Ymin);
7750 		gdouble posz = 4*fabs(coordmaxmin.Zmax-coordmaxmin.Zmin);
7751 		gdouble pos = posx;
7752 
7753 		if(pos<posy) pos = posy;
7754 		if(pos<posz) pos = posz;
7755 
7756 		camera.position = pos;
7757 
7758 		camera.f = camera.position/2;
7759         	for(i=0;i<Natoms;i++)
7760 			geometry[i].Coefpers = 1.5*camera.f/(-geometry[i].Z+camera.position);
7761 	}
7762 }
7763 /*****************************************************************************/
set_color_shad(GdkColor * color,guint i)7764 void set_color_shad(GdkColor *color,guint i)
7765 {
7766  gdouble Coef=1.0;
7767  if(fabs(coordmaxmin.Zmax-coordmaxmin.Zmin)>1.e-6)
7768  {
7769  	Coef = fabs(0.99-0.2*(coordmaxmin.Zmax-geometry[i].Z)/(coordmaxmin.Zmax-coordmaxmin.Zmin));
7770         if(Coef<1.0)
7771 	{
7772 	color->red =  (gushort)(color->red*Coef) ;
7773  	color->green =  (gushort)(color->green*Coef) ;
7774  	color->blue =  (gushort)(color->blue*Coef) ;
7775 	}
7776  }
7777 }
7778 /*****************************************************************************/
rotationGen(gdouble alpha,gdouble Axe[],gdouble A[],gdouble B[])7779 void rotationGen(gdouble alpha,gdouble Axe[],gdouble A[],gdouble B[])
7780 {
7781 /* Axe est un tableau de 2 elements qui definit l'axe de rotation qui se trouve dans le paln xOy*/
7782 /* theta angle entre l'axe de rotation et l'axe x. l'axe de rotation se trouve dans le plan xoy */
7783 /* alpha angle rotation autour de l'axe de rotation defini par theta */
7784 	gdouble cosa = cos(alpha/180*PI);
7785 	gdouble sina = sin(alpha/180*PI);
7786         gdouble cost=Axe[0]/sqrt(Axe[0]*Axe[0] + Axe[1]*Axe[1] );
7787         gdouble sint=Axe[1]/sqrt(Axe[0]*Axe[0] + Axe[1]*Axe[1] );
7788 
7789 	B[0] = A[0]*cost*cost + A[1]*sint*cost + A[0]*sint*sint*cosa - A[1]*cost*cosa*sint+A[2]*sint*sina;
7790 	B[1] = A[0]*cost*sint + A[1]*sint*sint - A[0]*sint*cost*cosa + A[1]*cost*cosa*cost-A[2]*cost*sina;
7791 	B[2] = -A[0]*sint*sina + A[1]*cost*sina + A[2]*cosa;
7792 }
7793 /*****************************************************************************/
replace_atom(gint i)7794 static gint replace_atom(gint i)
7795 {
7796 	g_free(geometry[i].Prop.symbol);
7797 	geometry[i].Prop = prop_atom_get(AtomToInsert);
7798 	g_free(geometry0[i].Prop.symbol);
7799 	geometry0[i].Prop = prop_atom_get(AtomToInsert);
7800 
7801 	g_free(geometry[i].mmType);
7802 	geometry[i].mmType = g_strdup(AtomToInsert);
7803 	g_free(geometry0[i].mmType);
7804 	geometry0[i].mmType = g_strdup(AtomToInsert);
7805 
7806 	g_free(geometry[i].pdbType);
7807 	geometry[i].pdbType = g_strdup(AtomToInsert);
7808 	g_free(geometry0[i].pdbType);
7809 	geometry0[i].pdbType = g_strdup(AtomToInsert);
7810 	return 1;
7811 }
7812 /*****************************************************************************/
insert_atom(GdkEventButton * bevent)7813 static gint insert_atom(GdkEventButton *bevent)
7814 {
7815 	int x, y;
7816 	gdouble X;
7817 	gdouble Y;
7818 	gdouble Z;
7819 	gdouble Cmax;
7820 	gushort Xmax;
7821 	gushort Ymax;
7822 	gushort Rmax;
7823 
7824 	if(Natoms>0 && NumProcheAtom<0) return -1;
7825 	if(Natoms>0)
7826 	{
7827 		geometry0 = g_realloc(geometry0,(Natoms+1)*sizeof(GeomDef));
7828 		geometry = g_realloc(geometry,(Natoms+1)*sizeof(GeomDef));
7829 	}
7830 	else
7831 	{
7832 		geometry0 = g_malloc(sizeof(GeomDef));
7833 		geometry = g_malloc(sizeof(GeomDef));
7834 	}
7835 
7836 	Ddef = FALSE;
7837 
7838 	Xmax=GeomDrawingArea->allocation.width;
7839 	Ymax=GeomDrawingArea->allocation.height;
7840 	Rmax = Xmax;
7841 	if(Rmax<Ymax)
7842 		Rmax = Ymax;
7843 
7844 
7845 	x = bevent->x;
7846 	y = bevent->y;
7847 
7848 	if(Natoms>0)
7849 	{
7850 		if(PersMode)
7851 			Cmax  = coordmaxmin.Cmax*camera.f/(camera.position);
7852 		else
7853 			Cmax = coordmaxmin.Cmax;
7854 	}
7855 	else
7856 	{
7857 		geometry[Natoms].Prop = prop_atom_get(AtomToInsert);
7858 		Cmax = 4*geometry[Natoms].Prop.covalentRadii;
7859 		coordmaxmin.Cmax = Cmax;
7860 	}
7861 
7862 	X = (gdouble)(x-Xmax/2-TransX)*2.0*Cmax/(factor*Rmax);
7863 	Y = -(gdouble)(y-Ymax/2-TransY)*2.0*Cmax/(factor*Rmax);
7864 	if(Natoms>0)
7865 		Z = geometry[NumProcheAtom].Z;
7866 	else
7867 		Z = 0.0;
7868 
7869 	if(PersMode)
7870 	{
7871 		X = X/camera.f*(-Z+camera.position);
7872 		Y = Y/camera.f*(-Z+camera.position);
7873 	}
7874 	{
7875 		gdouble m[4][4];
7876 		gdouble **m0 = g_malloc(3*sizeof(gdouble*));
7877 		gdouble** minv;
7878 		gint i,j;
7879 
7880 		gdouble A[3];
7881 		gdouble B[3];
7882 		guint k;
7883 
7884 		for(i=0;i<3;i++)
7885 			m0[i] = g_malloc(3*sizeof(gdouble));
7886 
7887 		build_rotmatrix(m,Quat);
7888 
7889 		for(i=0;i<3;i++)
7890 		for(j=0;j<3;j++)
7891 			m0[i][j] = m[i][j];
7892 
7893 		minv = Inverse(m0,3,1e-7);
7894 		if(minv)
7895 		{
7896 			A[0] = X;
7897 			A[1] = Y;
7898 			A[2] = Z;
7899 			for(j=0;j<3;j++)
7900 			{
7901 				B[j] = 0.0;
7902 				for(k=0;k<3;k++)
7903 				B[j] += minv[k][j]*A[k];
7904 			}
7905 			geometry[Natoms].X=B[0];
7906 			geometry[Natoms].Y=B[1];
7907 			geometry[Natoms].Z=B[2];
7908 			geometry[Natoms].Prop = prop_atom_get(AtomToInsert);
7909 			geometry[Natoms].mmType = g_strdup(AtomToInsert);
7910 			geometry[Natoms].pdbType = g_strdup(AtomToInsert);
7911 			geometry[Natoms].Layer = HIGH_LAYER;
7912 			geometry[Natoms].show = TRUE;
7913 			geometry[Natoms].N = Natoms+1;
7914         		geometry[Natoms].typeConnections = NULL;
7915 			if(Natoms==0)
7916 			{
7917 				geometry[Natoms].Residue = g_strdup(AtomToInsert);
7918 				geometry[Natoms].ResidueNumber = 0;
7919 			}
7920 			else
7921 			{
7922 				gint k;
7923 				gint proche = 0;
7924 				gdouble d;
7925 				gdouble d1;
7926 				d = get_real_distance2(geometry,0,Natoms);
7927 				for(k=1;k<(gint)Natoms;k++)
7928 				{
7929 
7930 					d1 = get_real_distance2(geometry,k,Natoms);
7931 					if(d1<d)
7932 					{
7933 						proche = k;
7934 						d = d1;
7935 					}
7936 				}
7937 				geometry[Natoms].Residue = g_strdup(geometry[proche].Residue);
7938 				geometry[Natoms].ResidueNumber = geometry[proche].ResidueNumber;
7939 			}
7940 
7941 			geometry[Natoms].Charge = 0.0;
7942 
7943 			geometry0[Natoms].Prop = prop_atom_get(AtomToInsert);
7944 			geometry0[Natoms].mmType = g_strdup(AtomToInsert);
7945 			geometry0[Natoms].pdbType = g_strdup(AtomToInsert);
7946 			geometry0[Natoms].Layer = HIGH_LAYER;
7947 			geometry0[Natoms].Variable = TRUE;
7948 			geometry0[Natoms].Residue = g_strdup(geometry[Natoms].Residue);
7949 			geometry0[Natoms].ResidueNumber = geometry[Natoms].ResidueNumber;
7950 			geometry0[Natoms].show = geometry[Natoms].show;
7951 			geometry0[Natoms].X = geometry[Natoms].X;
7952 			geometry0[Natoms].Y = geometry[Natoms].Y;
7953 			geometry0[Natoms].Z = geometry[Natoms].Z;
7954 			geometry0[Natoms].Charge = 0.0;
7955 			geometry0[Natoms].N = Natoms+1;
7956         		geometry0[Natoms].typeConnections = NULL;
7957 
7958 			for(i=0;i<3;i++)
7959 				if(minv[i])
7960 				g_free(minv[i]);
7961 			g_free(minv);
7962 			Natoms++;
7963 		}
7964 		if(m0)
7965 		{
7966 			for(i=0;i<3;i++)
7967 				if(m0[i])
7968 					g_free(m0[i]);
7969 				g_free(m0);
7970 		}
7971 	}
7972 	Ddef = FALSE;
7973 	{
7974 		gint i;
7975 		gint j;
7976 		for(i=0;i<(gint)Natoms-1;i++)
7977 		{
7978 			geometry[i].typeConnections = g_realloc(geometry[i].typeConnections,Natoms*sizeof(gint));
7979 			geometry[i].typeConnections[Natoms-1] = 0;
7980 			geometry0[i].typeConnections = g_realloc(geometry0[i].typeConnections,Natoms*sizeof(gint));
7981 		}
7982 		i = Natoms-1;
7983 		geometry[i].typeConnections = g_malloc(Natoms*sizeof(gint));
7984 		for(j=0;j<(gint)Natoms;j++) geometry[i].typeConnections[j] = 0;
7985 		geometry0[i].typeConnections = g_malloc(Natoms*sizeof(gint));
7986 		for(j=0;j<(gint)Natoms;j++) geometry0[i].typeConnections[j] = 0;
7987 	}
7988 	reset_charges_multiplicities();
7989 	return TRUE;
7990 }
7991 /*****************************************************************************/
select_fragment(gint NDelAtom)7992 static void select_fragment(gint NDelAtom)
7993 {
7994 	gint i;
7995 
7996 	if(!NumFatoms)
7997 		g_free(NumFatoms);
7998 	NumFatoms = NULL;
7999 
8000 	NFatoms = Frag.NAtoms-NDelAtom;
8001 	if(NFatoms<1)
8002 		return;
8003 	NumFatoms = g_malloc(NFatoms*sizeof(gint));
8004 	for(i=0;i<(gint)NFatoms;i++)
8005 	{
8006 			NumFatoms[i] = geometry[i+Natoms-NFatoms].N;
8007 	}
8008 }
8009 /*****************************************************************************/
get_number_new_residue()8010 static gint get_number_new_residue()
8011 {
8012 	gint numMax =-1;
8013 	gint i;
8014 	if(Natoms<1 || !geometry0)
8015 		return numMax + 1;
8016 	for(i=0;i<(gint)Natoms;i++)
8017 		if(numMax<geometry0[i].ResidueNumber)
8018 			numMax = geometry0[i].ResidueNumber;
8019 	return numMax +1;
8020 }
8021 /*****************************************************************************/
insert_fragment_without_delete_an_atom(GtkWidget * widget,GdkEvent * event)8022 static gint insert_fragment_without_delete_an_atom(GtkWidget *widget,GdkEvent *event)
8023 {
8024 	int x, y;
8025 	GdkEventButton *bevent=(GdkEventButton *)event;
8026 	gdouble X;
8027 	gdouble Y;
8028 	gdouble Z;
8029 	gdouble Cmax;
8030 	gushort Xmax;
8031 	gushort Ymax;
8032 	gushort Rmax;
8033 	gint i;
8034 	gint iBegin;
8035 	gint j;
8036 
8037 	if(Natoms>0 && NumProcheAtom<0)
8038 	{
8039 		FreeFragment(&Frag);
8040 		return 0;
8041 	}
8042 	if(Frag.NAtoms<=0)
8043 	{
8044 		FreeFragment(&Frag);
8045 		return 0;
8046 	}
8047 
8048 	if(Natoms>0)
8049 	{
8050 		geometry0 = g_realloc(geometry0,(Natoms+Frag.NAtoms)*sizeof(GeomDef));
8051 		geometry  = g_realloc(geometry,(Natoms+Frag.NAtoms)*sizeof(GeomDef));
8052 	}
8053 	else
8054 	{
8055 		geometry0 = g_malloc(Frag.NAtoms*sizeof(GeomDef));
8056 		geometry  = g_malloc(Frag.NAtoms*sizeof(GeomDef));
8057 	}
8058 
8059 	Ddef = FALSE;
8060 
8061 	Xmax=GeomDrawingArea->allocation.width;
8062 	Ymax=GeomDrawingArea->allocation.height;
8063 	Rmax = Xmax;
8064 	if(Rmax<Ymax)
8065 		Rmax = Ymax;
8066 
8067 
8068 	x = bevent->x;
8069 	y = bevent->y;
8070 
8071 	if(Natoms>0)
8072 	{
8073 		if(PersMode) Cmax  = coordmaxmin.Cmax*camera.f/(camera.position);
8074 		else Cmax = coordmaxmin.Cmax;
8075 	}
8076 	else
8077 	{
8078 		Natoms = 0;
8079 		for(i=0;i<Frag.NAtoms;i++)
8080 			geometry[Natoms+i].Prop = prop_atom_get(Frag.Atoms[i].Symb);
8081 		Cmax = 4*geometry[Natoms].Prop.covalentRadii;
8082 		for(i=1;i<Frag.NAtoms;i++)
8083 			if(Cmax<geometry[Natoms+i].Prop.covalentRadii)
8084 			       Cmax = geometry[Natoms+i].Prop.covalentRadii;
8085 		coordmaxmin.Cmax = Cmax;
8086 	}
8087 
8088 	X = (gdouble)(x-Xmax/2-TransX)*2.0*Cmax/(factor*Rmax);
8089 	Y = -(gdouble)(y-Ymax/2-TransY)*2.0*Cmax/(factor*Rmax);
8090 	if(Natoms>0) Z = geometry[NumProcheAtom].Z;
8091 	else Z = 0.0;
8092 
8093 	if(PersMode)
8094 	{
8095 		X = X/camera.f*(-Z+camera.position);
8096 		Y = Y/camera.f*(-Z+camera.position);
8097 	}
8098 	{
8099 		gdouble m[4][4];
8100 		gdouble **m0 = g_malloc(3*sizeof(gdouble*));
8101 		gdouble** minv;
8102 		gint i,j;
8103 
8104 		gdouble A[3];
8105 		gdouble B[3];
8106 		guint k;
8107 
8108 		for(i=0;i<3;i++)
8109 			m0[i] = g_malloc(3*sizeof(gdouble));
8110 
8111 		build_rotmatrix(m,Quat);
8112 
8113 		for(i=0;i<3;i++)
8114 		for(j=0;j<3;j++)
8115 			m0[i][j] = m[i][j];
8116 
8117 		minv = Inverse(m0,3,1e-7);
8118 		if(minv)
8119 		{
8120 			A[0] = X;
8121 			A[1] = Y;
8122 			A[2] = Z;
8123 			for(j=0;j<3;j++)
8124 			{
8125 				B[j] = 0.0;
8126 				for(k=0;k<3;k++)
8127 				B[j] += minv[k][j]*A[k];
8128 			}
8129 			j = -1;
8130 
8131 			for(i=0;i<Frag.NAtoms;i++)
8132 			{
8133 				j++;
8134 				geometry0[Natoms+j].X=B[0]+Frag.Atoms[i].Coord[0];
8135 				geometry0[Natoms+j].Y=B[1]+Frag.Atoms[i].Coord[1];
8136 				geometry0[Natoms+j].Z=B[2]+Frag.Atoms[i].Coord[2];
8137 				geometry0[Natoms+j].Prop = prop_atom_get(Frag.Atoms[i].Symb);
8138 				geometry0[Natoms+j].mmType =g_strdup(Frag.Atoms[i].mmType);
8139 				geometry0[Natoms+j].pdbType =g_strdup(Frag.Atoms[i].pdbType);
8140 				geometry0[Natoms+j].Layer = HIGH_LAYER;
8141 				geometry0[Natoms+j].Variable = TRUE;
8142 				geometry0[Natoms+j].Residue =g_strdup(Frag.Atoms[i].Residue);
8143 				geometry0[Natoms+j].ResidueNumber= get_number_new_residue();
8144 				geometry0[Natoms+j].show= TRUE;
8145 				geometry0[Natoms+j].Charge = Frag.Atoms[i].Charge;
8146 				geometry0[Natoms+j].N = Natoms+j+1;
8147         			geometry0[Natoms+j].typeConnections = NULL;
8148 
8149 				geometry[Natoms+j].Prop = prop_atom_get(Frag.Atoms[i].Symb);
8150 				geometry[Natoms+j].mmType =g_strdup(Frag.Atoms[i].mmType);
8151 				geometry[Natoms+j].pdbType =g_strdup(Frag.Atoms[i].pdbType);
8152 				geometry[Natoms+j].Layer = HIGH_LAYER;
8153 				geometry[Natoms+j].Residue =g_strdup(Frag.Atoms[i].Residue);
8154 				geometry[Natoms+j].ResidueNumber=geometry0[Natoms+j].ResidueNumber;
8155 				geometry[Natoms+j].show=geometry0[Natoms+j].show;
8156 				geometry[Natoms+j].Charge = Frag.Atoms[i].Charge;
8157 				geometry[Natoms+j].N = Natoms+j+1;
8158         			geometry[Natoms+j].typeConnections = NULL;
8159 
8160 				geometry[Natoms+j].X= geometry0[Natoms+j].X;
8161 				geometry[Natoms+j].Y= geometry0[Natoms+j].Y;
8162 				geometry[Natoms+j].Z= geometry0[Natoms+j].Z;
8163 			}
8164 
8165 			for(i=0;i<3;i++)
8166 				if(minv[i]) g_free(minv[i]);
8167 			g_free(minv);
8168 
8169 			Natoms+=Frag.NAtoms;
8170 		}
8171 		if(m0)
8172 		{
8173 			for(i=0;i<3;i++)
8174 				if(m0[i])
8175 					g_free(m0[i]);
8176 				g_free(m0);
8177 		}
8178 	}
8179 	Ddef = FALSE;
8180 	iBegin = Natoms-Frag.NAtoms;
8181 	for(i=0;i<iBegin;i++)
8182 	{
8183 		if(!geometry[i].typeConnections) continue;
8184 		geometry[i].typeConnections = g_realloc(geometry[i].typeConnections,Natoms*sizeof(gint));
8185 		for(j=iBegin;j<Natoms;j++) geometry[i].typeConnections[j] = 0;
8186 
8187 		if(!geometry0[i].typeConnections) continue;
8188 		geometry0[i].typeConnections = g_realloc(geometry0[i].typeConnections,Natoms*sizeof(gint));
8189 		for(j=iBegin;j<Natoms;j++) geometry0[i].typeConnections[j] = 0;
8190 	}
8191 	for(i=iBegin;i<Natoms;i++)
8192 	{
8193 		geometry[i].typeConnections = g_malloc(Natoms*sizeof(gint));
8194 		for(j=0;j<Natoms;j++) geometry[i].typeConnections[j] = 0;
8195 
8196 		geometry0[i].typeConnections = g_malloc(Natoms*sizeof(gint));
8197 		for(j=0;j<Natoms;j++) geometry0[i].typeConnections[j] = 0;
8198 	}
8199 	for(i=iBegin;i<Natoms;i++)
8200 	{
8201 		for(j=i+1;j<Natoms;j++)
8202 		{
8203 			if(draw_lines_yes_no(i,j)) geometry[i].typeConnections[j]= 1;
8204 			geometry[j].typeConnections[i] = geometry[i].typeConnections[j];
8205 		}
8206 	}
8207 	reset_multiple_bonds();
8208 	define_good_factor();
8209 	reset_charges_multiplicities();
8210 	/* SetOriginAtCenter(NULL,0,NULL);*/
8211 	set_statubar_pop_sel_atom();
8212 	return 1;
8213 }
8214 /*****************************************************************************/
insert_fragment_connected_to_an_atom(gint toD,gint toB,gint toA)8215 static gint insert_fragment_connected_to_an_atom(gint toD, gint toB, gint toA)
8216 {
8217 	gint i;
8218 	gint toBond=-1;
8219 	gint toAngle=-1;
8220 	gint* atomlist = NULL;
8221 	gint toDel = -1;
8222 	gdouble B[3];
8223 	gint j;
8224 	gint iBegin;
8225 	gdouble bondLength;
8226 
8227 	if(toD <0 || toB <0 || Frag.atomToDelete<0 || Frag.atomToBondTo<0) return 0;
8228 	if(toD >= Natoms || toB>= Natoms || Frag.atomToDelete>= Frag.NAtoms || Frag.atomToBondTo>= Frag.NAtoms) return 0;
8229 
8230 	if(Natoms>0)
8231 	{
8232 		geometry0 = g_realloc(geometry0,(Natoms+Frag.NAtoms)*sizeof(GeomDef));
8233 		geometry  = g_realloc(geometry,(Natoms+Frag.NAtoms)*sizeof(GeomDef));
8234 	}
8235 	else
8236 	{
8237 		geometry0 = g_malloc(Frag.NAtoms*sizeof(GeomDef));
8238 		geometry  = g_malloc(Frag.NAtoms*sizeof(GeomDef));
8239 	}
8240 
8241 	Ddef = FALSE;
8242 
8243 	atomlist = g_malloc((Frag.NAtoms)*sizeof(gint));
8244 	B[0] = geometry0[toB].X - Frag.Atoms[Frag.atomToDelete].Coord[0];
8245 	B[1] = geometry0[toB].Y - Frag.Atoms[Frag.atomToDelete].Coord[1];
8246 	B[2] = geometry0[toB].Z - Frag.Atoms[Frag.atomToDelete].Coord[2];
8247 
8248 	j = -1;
8249 	toBond = -1;
8250 	toAngle = -1;
8251 	toDel = -1;
8252 	for(i=0;i<Frag.NAtoms;i++)
8253 	{
8254 		j++;
8255 		geometry0[Natoms+j].X=B[0]+Frag.Atoms[i].Coord[0];
8256 		geometry0[Natoms+j].Y=B[1]+Frag.Atoms[i].Coord[1];
8257 		geometry0[Natoms+j].Z=B[2]+Frag.Atoms[i].Coord[2];
8258 
8259 		if(i==Frag.atomToDelete) toDel = Natoms+j;
8260 		if(i==Frag.atomToBondTo) toBond = Natoms+j;
8261 		if(i==Frag.angleAtom) toAngle = Natoms+j;
8262 		atomlist[j] = Natoms+j;
8263 
8264 		geometry0[Natoms+j].Prop = prop_atom_get(Frag.Atoms[i].Symb);
8265 		geometry0[Natoms+j].mmType =g_strdup(Frag.Atoms[i].mmType);
8266 		geometry0[Natoms+j].pdbType =g_strdup(Frag.Atoms[i].pdbType);
8267 		geometry0[Natoms+j].Layer = HIGH_LAYER;
8268 		geometry0[Natoms+j].Variable = TRUE;
8269 		geometry0[Natoms+j].Residue =g_strdup(Frag.Atoms[i].Residue);
8270 		geometry0[Natoms+j].ResidueNumber= get_number_new_residue();
8271 		geometry0[Natoms+j].show= TRUE;
8272 		geometry0[Natoms+j].Charge = Frag.Atoms[i].Charge;
8273 		geometry0[Natoms+j].N = Natoms+j+1;
8274         	geometry0[Natoms+j].typeConnections = NULL;
8275 
8276 		geometry[Natoms+j].Prop = prop_atom_get(Frag.Atoms[i].Symb);
8277 		geometry[Natoms+j].mmType =g_strdup(Frag.Atoms[i].mmType);
8278 		geometry[Natoms+j].pdbType =g_strdup(Frag.Atoms[i].pdbType);
8279 		geometry[Natoms+j].Layer = HIGH_LAYER;
8280 		geometry[Natoms+j].Residue =g_strdup(Frag.Atoms[i].Residue);
8281 		geometry[Natoms+j].ResidueNumber=geometry0[Natoms+j].ResidueNumber;
8282 		geometry[Natoms+j].show=geometry0[Natoms+j].show;
8283 		geometry[Natoms+j].Charge = Frag.Atoms[i].Charge;
8284 		geometry[Natoms+j].N = Natoms+j+1;
8285         	geometry[Natoms+j].typeConnections = NULL;
8286 
8287 		geometry[Natoms+j].X= geometry0[Natoms+j].X;
8288 		geometry[Natoms+j].Y= geometry0[Natoms+j].Y;
8289 		geometry[Natoms+j].Z= geometry0[Natoms+j].Z;
8290 	}
8291 
8292 	Natoms +=Frag.NAtoms;
8293 	/* Set Distance toB-toD to radius toB + radius Frag.atomToBondTo */
8294 	bondLength = geometry[toB].Prop.covalentRadii + geometry[toBond].Prop.covalentRadii;
8295 	bondLength /= (ANG_TO_BOHR);
8296 	bondLength *= 0.85;
8297 	SetBondDistance(geometry,toB, toBond, bondLength,atomlist, Frag.NAtoms);
8298 
8299 
8300 	SetAngle(Natoms,geometry0,toD, toB, toBond,0.0,atomlist, Frag.NAtoms);
8301 
8302 	if(toA>-1 && toAngle>-1)
8303 	{
8304 		SetTorsion(Natoms,geometry0, toA,toB, toBond, toAngle, fragAngle,atomlist, Frag.NAtoms);
8305 	}
8306 
8307 	if(!atomlist) g_free(atomlist);
8308 
8309 	iBegin = Natoms-Frag.NAtoms;
8310 	for(i=0;i<iBegin;i++)
8311 	{
8312 		if(!geometry[i].typeConnections) continue;
8313 		geometry[i].typeConnections = g_realloc(geometry[i].typeConnections,Natoms*sizeof(gint));
8314 		for(j=iBegin;j<Natoms;j++) geometry[i].typeConnections[j] = 0;
8315 
8316 		if(!geometry0[i].typeConnections) continue;
8317 		geometry0[i].typeConnections = g_realloc(geometry0[i].typeConnections,Natoms*sizeof(gint));
8318 		for(j=iBegin;j<Natoms;j++) geometry0[i].typeConnections[j] = 0;
8319 	}
8320 	for(i=iBegin;i<Natoms;i++)
8321 	{
8322 		geometry[i].typeConnections = g_malloc(Natoms*sizeof(gint));
8323 		for(j=0;j<Natoms;j++) geometry[i].typeConnections[j] = 0;
8324 
8325 		geometry0[i].typeConnections = g_malloc(Natoms*sizeof(gint));
8326 		for(j=0;j<Natoms;j++) geometry0[i].typeConnections[j] = 0;
8327 	}
8328 	for(i=iBegin;i<Natoms;i++)
8329 	{
8330 		for(j=i+1;j<Natoms;j++)
8331 		{
8332 			if(draw_lines_yes_no(i,j)) geometry[i].typeConnections[j]= 1;
8333 			geometry[j].typeConnections[i] = geometry[i].typeConnections[j];
8334 		}
8335 	}
8336 	geometry[toB].typeConnections[toBond] =1;
8337 	geometry[toBond].typeConnections[geometry[toB].N-1]=1;
8338 
8339 	if(!NumFatoms) g_free(NumFatoms);
8340 	NumFatoms = NULL;
8341 
8342 	NFatoms = 2;
8343 	NumFatoms = g_malloc(2*sizeof(gint));
8344 	NumFatoms[0] = geometry[toD].N;
8345 	NumFatoms[1] = geometry[toDel].N;
8346 	delete_all_selected_atoms();
8347 	copy_connections(geometry0, geometry, Natoms);
8348 	select_fragment(2);
8349 
8350 	Ddef = FALSE;
8351 	define_good_factor();
8352 	reset_multiple_bonds();
8353 	reset_charges_multiplicities();
8354 
8355 	/* SetOriginAtCenter(NULL,0,NULL);*/
8356 	set_statubar_pop_sel_atom();
8357 	return 1;
8358 }
8359 /*****************************************************************************/
insert_fragment(GtkWidget * widget,GdkEvent * event)8360 static gint insert_fragment(GtkWidget *widget,GdkEvent *event)
8361 {
8362 	if(Natoms>0 && NumProcheAtom<0)
8363 	{
8364 		FreeFragment(&Frag);
8365 		return 0;
8366 	}
8367 	if(Frag.NAtoms<=0)
8368 	{
8369 		FreeFragment(&Frag);
8370 		return 0;
8371 	}
8372 	if(atomToDelete>=0)
8373 	{
8374 		return insert_fragment_connected_to_an_atom(
8375 				get_indice(atomToDelete),
8376 				get_indice(atomToBondTo),get_indice(angleTo));
8377 	}
8378 	else if(Frag.NAtoms>0 && Frag.atomToDelete<0)
8379 		return insert_fragment_without_delete_an_atom(widget,event);
8380 	else if(Natoms==0)
8381 		return insert_fragment_without_delete_an_atom(widget,event);
8382 	return 0;
8383 }
8384 /*****************************************************************************/
delete_one_atom(gint NumDel)8385 void delete_one_atom(gint NumDel)
8386 {
8387 
8388 	gint i;
8389 	gint j;
8390 	gint* oldN = NULL;
8391 
8392 	if(Natoms<1) return;
8393 	copy_connections(geometry0, geometry, Natoms);
8394 	i = NumDel;
8395 	if(geometry0[i].typeConnections) g_free(geometry0[i].typeConnections);
8396 	if(geometry[i].typeConnections) g_free(geometry[i].typeConnections);
8397 
8398 
8399 	for (i=NumDel;i<(gint)Natoms-1;i++)
8400 	{
8401 		geometry0[i]=geometry0[i+1];
8402 		geometry[i]=geometry[i+1];
8403 	}
8404 	oldN = g_malloc(Natoms*sizeof(gint));
8405 	for (i=0;i<(gint)Natoms;i++) oldN[i] = geometry0[i].N-1;
8406 	Natoms--;
8407 	for(j=0;j<(gint)NFatoms;j++)
8408 	{
8409 		for (i=0;i<(gint)Natoms;i++)
8410 			if(NumFatoms[j] ==(gint) geometry[i].N) { NumFatoms[j] = i+1; break;}
8411 		if(i==Natoms)  NumFatoms[j] =-1;
8412 	}
8413 	for(j=0;j<(gint)NFatoms;j++)
8414 		if( NumFatoms[j]<0)
8415 		{
8416 			for (i=j;i<(gint)NFatoms-1;i++)
8417 				 NumFatoms[i]= NumFatoms[i+1];
8418 			NFatoms--;
8419 			j--;
8420 		}
8421 
8422 	for(j=0;j<2;j++)
8423 		for (i=0;i<(gint)Natoms;i++)
8424 			if(NumBatoms[j]==(gint) geometry[i].N) {NumBatoms[j] = i+1; break;}
8425 	for (i=0;i<(gint)Natoms;i++)
8426 	{
8427 		geometry0[i].N = i+1;
8428 		geometry[i].N = i+1;
8429 	}
8430 	/* in geometry0 : old connections , in geometry new connection */
8431 	for (i=0;i<(gint)Natoms;i++)
8432 	{
8433 		if(geometry[i].typeConnections)
8434 		{
8435 			for(j=0;j<(gint)Natoms;j++)
8436 			{
8437 				geometry[i].typeConnections[j] = geometry0[i].typeConnections[oldN[j]];
8438 			}
8439 		}
8440 	}
8441 	if(oldN) g_free(oldN);
8442 	copy_connections(geometry0, geometry, Natoms);
8443 	if(Natoms>0)
8444 	{
8445 		geometry0 = g_realloc(geometry0,Natoms*sizeof(GeomDef));
8446 		geometry = g_realloc(geometry,Natoms*sizeof(GeomDef));
8447 	}
8448 	else
8449 	{
8450 		if(geometry0) g_free(geometry0); geometry0 = NULL;
8451 		if(geometry) g_free(geometry);
8452 		geometry = NULL;
8453 		Natoms = 0;
8454 	}
8455 	Ddef = FALSE;
8456 	reset_charges_multiplicities();
8457 }
8458 /********************************************************************************/
deleteHydrogensConnectedTo(gint n,gint nH)8459 void deleteHydrogensConnectedTo(gint n, gint nH)
8460 {
8461 	gint i;
8462 	gint k = 0;
8463 	gint ni;
8464 
8465 	if(Natoms<1) return;
8466 
8467 	add_geometry_to_fifo();
8468 	for (i=0;i<(gint)Natoms;i++)
8469 	{
8470 		ni = geometry[i].N-1;
8471 		if(geometry[n].typeConnections[ni] &&
8472 		!strcmp(geometry[i].Prop.symbol,"H"))
8473 		{
8474 			delete_one_atom(i);
8475 			k++;
8476 			if(k>=nH) break;
8477 		}
8478 	}
8479 }
8480 /*****************************************************************************/
index_selected(gint Num)8481 gint index_selected(gint Num)
8482 {
8483 	gint j;
8484 	if(NFatoms<1 || !NumFatoms )
8485 		return -1;
8486 
8487 	for(j=0;j<(gint)NFatoms;j++)
8488 		if(NumFatoms[j] == (gint)geometry[Num].N)
8489 			return j;
8490 	return -1;
8491 }
8492 /*****************************************************************************/
if_selected(gint Num)8493 gboolean if_selected(gint Num)
8494 {
8495 	gint j;
8496 	if(NFatoms<1 || !NumFatoms )
8497 		return FALSE;
8498 
8499 	for(j=0;j<(gint)NFatoms;j++)
8500 		if(NumFatoms[j] == (gint)geometry[Num].N)
8501 			return TRUE;
8502 	return FALSE;
8503 }
8504 /*****************************************************************************/
delete_all_selected_atoms()8505 void delete_all_selected_atoms()
8506 {
8507 
8508 	gint i;
8509 	gint j;
8510 	GeomDef tmp;
8511 	gint* oldN = NULL;
8512 
8513 	if(Natoms<1) return;
8514 
8515 	copy_connections(geometry0, geometry, Natoms);
8516 
8517 	for (i=0;i<(gint)Natoms-1;i++)
8518 	{
8519 		if(!if_selected(i)) continue;
8520 
8521 		for(j=i+1;j<(gint)Natoms;j++)
8522 			if(!if_selected(j))
8523 			{
8524 				tmp = geometry0[i];
8525 				geometry0[i] = geometry0[j];
8526 				geometry0[j] = tmp ;
8527 				tmp = geometry[i];
8528 				geometry[i] = geometry[j];
8529 				geometry[j] = tmp ;
8530 				break;
8531 			}
8532 	}
8533 	oldN = g_malloc(Natoms*sizeof(gint));
8534 	for (i=0;i<(gint)Natoms;i++) oldN[i] = geometry0[i].N-1;
8535 
8536 	if(NFatoms>Natoms)
8537 	{
8538 		printf("internal error\n");
8539 		Natoms = 0;
8540 	}
8541 	else
8542 	{
8543 		for (i=(gint)Natoms-NFatoms;i<(gint)Natoms;i++)
8544 		{
8545 			if(geometry0[i].typeConnections) g_free(geometry0[i].typeConnections);
8546 			if(geometry[i].typeConnections) g_free(geometry[i].typeConnections);
8547 		}
8548 		Natoms-=NFatoms;
8549 	}
8550 	for(j=0;j<(gint)NBatoms;j++)
8551 		for (i=0;i<(gint)Natoms;i++)
8552 			if(NumBatoms[j] ==(gint) geometry[i].N) NumBatoms[j] = i+1;
8553 
8554 	for (i=0;i<(gint)Natoms;i++)
8555 	{
8556 		geometry0[i].N = i+1;
8557 		geometry[i].N = i+1;
8558 	}
8559 	/* in geometry0 : old connections , in geometry new connection */
8560 	for (i=0;i<(gint)Natoms;i++)
8561 	{
8562 		if(geometry[i].typeConnections)
8563 		{
8564 			for(j=0;j<(gint)Natoms;j++)
8565 			{
8566 				geometry[i].typeConnections[j] = geometry0[i].typeConnections[oldN[j]];
8567 			}
8568 		}
8569 	}
8570 	if(oldN) g_free(oldN);
8571 	copy_connections(geometry0, geometry, Natoms);
8572 
8573 	if(Natoms>0)
8574 	{
8575 		geometry0 = g_realloc(geometry0,Natoms*sizeof(GeomDef));
8576 		geometry = g_realloc(geometry,Natoms*sizeof(GeomDef));
8577 	}
8578 	else
8579 	{
8580 		if(geometry0)
8581 			g_free(geometry0);
8582 		geometry0 = NULL;
8583 		if(geometry)
8584 			g_free(geometry);
8585 		geometry = NULL;
8586 		Natoms = 0;
8587 	}
8588 	NFatoms = 0;
8589 	if(NumFatoms)
8590 		g_free(NumFatoms);
8591 	NumFatoms = NULL;
8592 	Ddef = FALSE;
8593 	reset_charges_multiplicities();
8594 }
8595 /********************************************************************************/
rotate_frag_for_set_its_principal_axes_to_xyz(gboolean sel)8596 static void rotate_frag_for_set_its_principal_axes_to_xyz(gboolean sel)
8597 {
8598 	gdouble **m0 = NULL;
8599 	gdouble** minv;
8600 	gint i,j;
8601 	guint n;
8602 
8603 	gdouble A[3];
8604 	gdouble B[3];
8605 	guint k;
8606 	gdouble* X;
8607 	gdouble* Y;
8608 	gdouble* Z;
8609 	gdouble axis1[3] = {1,0,0};
8610 	gdouble axis2[3] = {0,1,0};
8611 	gdouble axis3[3] = {0,0,1};
8612 	gdouble C[3] = {0,0,0};
8613 	gint nFrag = 0;
8614 
8615 	if(Natoms<1) return;
8616 	nFrag = compute_fragment_principal_axes(axis1,axis2,axis3,C,sel);
8617 	if(nFrag <2 ) return;
8618 	printf("nFrag = %d\n",nFrag);
8619 
8620 	m0 = g_malloc(3*sizeof(gdouble*));
8621 	X = g_malloc(Natoms*sizeof(gdouble));
8622 	Y = g_malloc(Natoms*sizeof(gdouble));
8623 	Z = g_malloc(Natoms*sizeof(gdouble));
8624 
8625 	for(i=0;i<3;i++) m0[i] = g_malloc(3*sizeof(gdouble));
8626 
8627 
8628 	m0[0][0] = axis1[0];
8629 	m0[0][1] = axis1[1];
8630 	m0[0][2] = axis1[2];
8631 
8632 	m0[1][0] = axis2[0];
8633 	m0[1][1] = axis2[1];
8634 	m0[1][2] = axis2[2];
8635 
8636 	m0[2][0] = axis3[0];
8637 	m0[2][1] = axis3[1];
8638 	m0[2][2] = axis3[2];
8639 
8640 	minv = Inverse(m0,3,1e-7);
8641 
8642 	for(n = 0;n<Natoms;n++)
8643 	{
8644 		if(if_selected(n)!=sel) continue;
8645 		A[0] = geometry[n].X-C[0];
8646 		A[1] = geometry[n].Y-C[1];
8647 		A[2] = geometry[n].Z-C[2];
8648 
8649 		for(j=0;j<3;j++)
8650 		{
8651 			B[j] = 0.0;
8652 			for(k=0;k<3;k++)
8653 				B[j] += minv[k][j]*A[k];
8654 		}
8655 
8656 		X[n] = B[0]+C[0];
8657 		Y[n] = B[1]+C[1];
8658 		Z[n] = B[2]+C[2];
8659 	}
8660 	for(n = 0;n<Natoms;n++)
8661 	{
8662 		if(if_selected(n)!=sel)
8663 		{
8664 			geometry0[n].X = geometry[n].X;
8665 			geometry0[n].Y = geometry[n].Y;
8666 			geometry0[n].Z = geometry[n].Z;
8667 		}
8668 		else
8669 		{
8670 			geometry0[n].X = X[n];
8671 			geometry0[n].Y = Y[n];
8672 			geometry0[n].Z = Z[n];
8673 
8674 			geometry[n].X = X[n];
8675 			geometry[n].Y = Y[n];
8676 			geometry[n].Z = Z[n];
8677 		}
8678 	}
8679 
8680 	if(minv!=m0)
8681 	{
8682 	for(i=0;i<3;i++) if(minv[i]) g_free(minv[i]);
8683 	if(minv) g_free(minv);
8684 	}
8685 
8686 	for(i=0;i<3;i++) if(m0[i]) g_free(m0[i]);
8687 	if(m0) g_free(m0);
8688 
8689 	if(X) g_free(X);
8690 	if(Y) g_free(Y);
8691 	if(Z) g_free(Z);
8692 }
8693 /*****************************************************************************/
alignPrincipalAxesOfSelectedAtomsToXYZ()8694 void alignPrincipalAxesOfSelectedAtomsToXYZ()
8695 {
8696 	add_geometry_to_fifo();
8697 	rotate_frag_for_set_its_principal_axes_to_xyz(TRUE);
8698 	create_GeomXYZ_from_draw_grometry();
8699 	init_quat(Quat);
8700 	drawGeom();
8701 	activate_edit_objects();
8702 }
8703 /*****************************************************************************/
alignSelectedAndNotSelectedAtoms()8704 void alignSelectedAndNotSelectedAtoms()
8705 {
8706 	add_geometry_to_fifo();
8707 	move_the_center_of_selected_or_not_selected_atoms_to_origin(TRUE);
8708 	move_the_center_of_selected_or_not_selected_atoms_to_origin(FALSE);
8709 	create_GeomXYZ_from_draw_grometry();
8710 	init_quat(Quat);
8711 	drawGeom();
8712 	activate_edit_objects();
8713 }
8714 /*****************************************************************************/
deleteSelectedAtoms()8715 void deleteSelectedAtoms()
8716 {
8717 	add_geometry_to_fifo();
8718 	delete_all_selected_atoms();
8719 	create_GeomXYZ_from_draw_grometry();
8720 	drawGeom();
8721 	activate_edit_objects();
8722 }
8723 /*****************************************************************************/
moveCenterOfSelectedAtomsToOrigin()8724 void moveCenterOfSelectedAtomsToOrigin()
8725 {
8726 	add_geometry_to_fifo();
8727 	move_the_center_of_selected_or_not_selected_atoms_to_origin(TRUE);
8728 	create_GeomXYZ_from_draw_grometry();
8729 	drawGeom();
8730 	activate_edit_objects();
8731 }
8732 /*****************************************************************************/
delete_hydrogen_atoms()8733 void delete_hydrogen_atoms()
8734 {
8735 
8736 	gint i;
8737 	gint j;
8738 	GeomDef tmp;
8739 	gint nA = 0;
8740 	gint* oldN = NULL;
8741 
8742 	add_geometry_to_fifo();
8743 
8744 	for (i=0;i<(gint)Natoms-1;i++)
8745 	{
8746 		if(strcmp(geometry[i].Prop.symbol,"H")) continue;
8747 
8748 		for(j=i+1;j<(gint)Natoms;j++)
8749 			if(strcmp(geometry[j].Prop.symbol,"H"))
8750 			{
8751 				tmp = geometry0[i];
8752 				geometry0[i] = geometry0[j];
8753 				geometry0[j] = tmp ;
8754 				tmp = geometry[i];
8755 				geometry[i] = geometry[j];
8756 				geometry[j] = tmp ;
8757 				break;
8758 			}
8759 	}
8760 	nA = 0;
8761 	for (i=0;i<(gint)Natoms;i++)
8762 		if(strcmp(geometry[i].Prop.symbol,"H")) nA++;
8763 
8764 
8765 	if(Natoms>0) oldN = g_malloc(Natoms*sizeof(gint));
8766 	for (i=0;i<(gint)Natoms;i++) oldN[i] = geometry0[i].N-1;
8767 	Natoms = nA;
8768 
8769 	for(j=0;j<(gint)NFatoms;j++)
8770 	{
8771 		for (i=0;i<(gint)Natoms;i++)
8772 			if(NumFatoms[j] ==(gint) geometry[i].N) { NumFatoms[j] = i+1; break;}
8773 		if(i==(gint)Natoms)  NumFatoms[j] =-1;
8774 	}
8775 	for(j=0;j<(gint)NFatoms;j++)
8776 		if( NumFatoms[j]<0)
8777 		{
8778 			for (i=j;i<(gint)NFatoms-1;i++)
8779 		 		NumFatoms[i]= NumFatoms[i+1];
8780 			NFatoms--;
8781 			j--;
8782 		}
8783 	for (i=0;i<(gint)Natoms;i++)
8784 	{
8785 		geometry0[i].N = i+1;
8786 		geometry[i].N = i+1;
8787 	}
8788 	/* in geometry0 : old connections , in geometry new connection */
8789 	for (i=0;i<(gint)Natoms;i++)
8790 	{
8791 		if(geometry[i].typeConnections)
8792 		{
8793 			for(j=0;j<(gint)Natoms;j++)
8794 			{
8795 				geometry[i].typeConnections[j] = geometry0[i].typeConnections[oldN[j]];
8796 			}
8797 		}
8798 	}
8799 	if(oldN) g_free(oldN);
8800 	copy_connections(geometry0, geometry, Natoms);
8801 
8802 	if(Natoms>0)
8803 	{
8804 		geometry0 = g_realloc(geometry0,Natoms*sizeof(GeomDef));
8805 		geometry = g_realloc(geometry,Natoms*sizeof(GeomDef));
8806 	}
8807 	else
8808 	{
8809 		if(geometry0) g_free(geometry0);
8810 		geometry0 = NULL;
8811 		if(geometry) g_free(geometry);
8812 		geometry = NULL;
8813 		Natoms = 0;
8814 	}
8815 	Ddef = FALSE;
8816 	/* reset_all_connections();*/
8817 	reset_charges_multiplicities();
8818 	create_GeomXYZ_from_draw_grometry();
8819 	drawGeom();
8820 	activate_edit_objects();
8821 }
8822 /********************************************************************************/
deleteHydrogenAtoms()8823 void deleteHydrogenAtoms()
8824 {
8825 	gchar *t =N_("Do you want to really remove all hydrogen atoms?");
8826 	if(Natoms>0) Continue_YesNo(delete_hydrogen_atoms, NULL,t);
8827 	else Message(_("No hydrogen atoms to remove\n"),_("Warning"),TRUE);
8828 }
8829 /*****************************************************************************/
delete_selected_atoms()8830 void delete_selected_atoms()
8831 {
8832 
8833 	gint i;
8834 	gint j;
8835 	gboolean DelAll = FALSE;
8836 
8837 	if(NumSelectedAtom<0)
8838 		return;
8839 
8840 	add_geometry_to_fifo();
8841 	for(i=0;i<(gint)Natoms;i++)
8842 		if((gint)i==NumSelectedAtom)
8843 		{
8844 			for(j = 0;j<(gint)NFatoms;j++)
8845 				if(NumFatoms[j] == (gint)geometry[i].N)
8846 					DelAll = TRUE;
8847 			break;
8848 		}
8849 	if(DelAll==FALSE)
8850 	{
8851 		delete_one_atom(NumSelectedAtom);
8852 		return;
8853 	}
8854 	delete_all_selected_atoms();
8855 }
8856 /*****************************************************************************/
delete_selected_bond()8857 void delete_selected_bond()
8858 {
8859 
8860 	if(NBatoms!=2) return;
8861 	if(NBatoms>Natoms)
8862 	{
8863 		printf("internal error\n");
8864 		Natoms = 0;
8865 	}
8866 	if(NumBatoms[0]>0 && NumBatoms[1]>0)
8867 	{
8868 		gint na = NumBatoms[0]-1;
8869 		gint nb = NumBatoms[1]-1;
8870 		gint ia = -1;
8871 		gint ib = -1;
8872 		gint i;
8873 		for(i=0;i<(gint)Natoms;i++)
8874 		if(geometry[i].N-1==na) { ia = i; break; }
8875 		for(i=0;i<(gint)Natoms;i++)
8876 		if(geometry[i].N-1==nb) { ib = i; break; }
8877 
8878 		if(ia>=0 && ib>=0)
8879 		{
8880 			geometry[ia].typeConnections[nb] = 0;
8881 			geometry[ib].typeConnections[na] = 0;
8882 		}
8883 		if(ia>=0 && ib>=0 &&  AdjustHydrogenAtoms)
8884 			adjust_hydrogens_connected_to_atoms(ia,ib);
8885 	}
8886 	copy_connections(geometry0, geometry, Natoms);
8887 	NBatoms = 0;
8888 	NumBatoms[0] = NumBatoms[1] = -1;
8889 }
8890 /*****************************************************************************/
change_selected_bond()8891 void change_selected_bond()
8892 {
8893 
8894 	if(NBatoms!=2) return;
8895 	if(NBatoms>Natoms)
8896 	{
8897 		printf("internal error\n");
8898 		Natoms = 0;
8899 	}
8900 	if(NumBatoms[0]>0 && NumBatoms[1]>0)
8901 	{
8902 		gint na = NumBatoms[0]-1;
8903 		gint nb = NumBatoms[1]-1;
8904 		gint newC = 1;
8905 		gint i;
8906 		gint ni=-1;
8907 		gint nj=-1;
8908 		gint nBondsA = 0;
8909 		gint nBondsB = 0;
8910 
8911 		for(i=0;i<(gint)Natoms;i++) if(geometry[i].N-1==na) { ni = i; break; }
8912 		for(i=0;i<(gint)Natoms;i++) if(geometry[i].N-1==nb) { nj = i; break; }
8913 		if(ni>=0)
8914 		newC = geometry[ni].typeConnections[nb]+1;
8915 		if(newC>3) newC = 1;
8916 		if(newC==1)
8917 		{
8918 			if(ni>=0 && nj>=0)
8919 				geometry[ni].typeConnections[nb] = geometry[nj].typeConnections[na] = newC;
8920 		}
8921 		else
8922 		{
8923 
8924 			if(ni>=0 && nj>=0)
8925 			for(i=0;i<(gint)Natoms;i++)
8926 			{
8927 				gint nk = geometry[i].N-1;
8928 				if(i==ni) continue;
8929 				if(i==nj) continue;
8930 				if(geometry[ni].typeConnections[nk]==0) continue;
8931 				if(!strcmp(geometry[i].Prop.symbol, "H") && AdjustHydrogenAtoms)continue;
8932 				nBondsA+=geometry[ni].typeConnections[nk];
8933 			}
8934 			if(ni>=0 && nj>=0)
8935 			for(i=0;i<(gint)Natoms;i++)
8936 			{
8937 				gint nk = geometry[i].N-1;
8938 				if(i==ni) continue;
8939 				if(i==nj) continue;
8940 				if(geometry[nj].typeConnections[nk]==0) continue;
8941 				if(!strcmp(geometry[i].Prop.symbol, "H") && AdjustHydrogenAtoms )continue;
8942 				nBondsB+=geometry[nj].typeConnections[nk];
8943 			}
8944 			if(    !( ni>=0 && nj>=0 &&
8945 				((gint)geometry[ni].Prop.maximumBondValence-(nBondsA+newC))>=0 &&
8946 				((gint)geometry[nj].Prop.maximumBondValence-(nBondsB+newC))>=0
8947 				)
8948 			) newC = 1;
8949 			if(ni>=0 && nj>=0)
8950 				geometry[ni].typeConnections[nb] = geometry[nj].typeConnections[na] = newC;
8951 		}
8952 		if(ni>=0 && nj>=0 &&  AdjustHydrogenAtoms)
8953 			adjust_hydrogens_connected_to_atoms(ni,nj);
8954 	}
8955 	copy_connections(geometry0, geometry, Natoms);
8956 	NBatoms = 0;
8957 	NumBatoms[0] = NumBatoms[1] = -1;
8958 }
8959 /*****************************************************************************/
add_bond()8960 void add_bond()
8961 {
8962 	if(NBatoms==1)
8963 	{
8964 		NBatoms = 0;
8965 		NumBatoms[0] = NumBatoms[1] = -1;
8966 	}
8967 	if(NBatoms!=2) return;
8968 	if(NBatoms>Natoms)
8969 	{
8970 		printf("internal error\n");
8971 		Natoms = 0;
8972 	}
8973 	if(NumBatoms[0]>0 && NumBatoms[1]>0)
8974 	{
8975 		gint na = NumBatoms[0]-1;
8976 		gint nb = NumBatoms[1]-1;
8977 		gint newC = 1;
8978 		gint i;
8979 		gint ni=-1;
8980 		gint nj=-1;
8981 		gint nBondsA = 0;
8982 		gint nBondsB = 0;
8983 		{
8984 			for(i=0;i<(gint)Natoms;i++)
8985 			if(geometry[i].N-1==na)
8986 			{
8987 				ni = i;
8988 				break;
8989 			}
8990 			if(ni>=0)
8991 			for(i=0;i<(gint)Natoms;i++)
8992 			if(geometry[i].N-1==nb)
8993 			{
8994 				nj = i;
8995 				break;
8996 			}
8997 			if(ni>=0 && nj>=0)
8998 			for(i=0;i<(gint)Natoms;i++)
8999 			{
9000 				gint nk = geometry[i].N-1;
9001 				if(i==ni) continue;
9002 				if(i==nj) continue;
9003 				if(geometry[ni].typeConnections[nk]==0) continue;
9004 				if(!strcmp(geometry[i].Prop.symbol, "H") && AdjustHydrogenAtoms )continue;
9005 				nBondsA+=geometry[ni].typeConnections[nk];
9006 			}
9007 			if(ni>=0 && nj>=0)
9008 			for(i=0;i<(gint)Natoms;i++)
9009 			{
9010 				gint nk = geometry[i].N-1;
9011 				if(i==ni) continue;
9012 				if(i==nj) continue;
9013 				if(geometry[nj].typeConnections[nk]==0) continue;
9014 				if(!strcmp(geometry[i].Prop.symbol, "H"))continue;
9015 				nBondsB+=geometry[nj].typeConnections[nk];
9016 			}
9017 			if(    !( ni>=0 && nj>=0 &&
9018 				((gint)geometry[ni].Prop.maximumBondValence-(nBondsA+newC))>=0 &&
9019 				((gint)geometry[nj].Prop.maximumBondValence-(nBondsB+newC))>=0
9020 				)
9021 			) newC = 0;
9022 			if(ni>=0 && nj>=0)
9023 				geometry[ni].typeConnections[nb] = geometry[nj].typeConnections[na] = newC;
9024 		}
9025 		if(ni>=0 && nj>=0 &&  AdjustHydrogenAtoms)
9026 			adjust_hydrogens_connected_to_atoms(ni,nj);
9027 	}
9028 	copy_connections(geometry0, geometry, Natoms);
9029 	NBatoms = 0;
9030 	NumBatoms[0] = NumBatoms[1] = -1;
9031 }
9032 /*****************************************************************************/
rotation_geometry_quat(gdouble m[4][4])9033 void rotation_geometry_quat(gdouble m[4][4])
9034 {
9035 	gdouble A[3];
9036 	gdouble B[3];
9037 	guint i,j,k;
9038 
9039 	for (i=0;i<Natoms;i++)
9040 	{
9041 		A[0] = geometry0[i].X;
9042 		A[1] = geometry0[i].Y;
9043 		A[2] = geometry0[i].Z;
9044 		for(j=0;j<3;j++)
9045 		{
9046 			B[j] = 0.0;
9047 			for(k=0;k<3;k++)
9048 				B[j] += m[k][j]*A[k];
9049 		}
9050 		geometry[i].X=B[0];
9051 		geometry[i].Y=B[1];
9052 		geometry[i].Z=B[2];
9053 	}
9054 	if(Ddef)
9055 	{
9056 
9057 	for (i=0;i<NDIVDIPOLE;i++)
9058 	{
9059 	A[0] = dipole0[i][0];
9060 	A[1] = dipole0[i][1];
9061 	A[2] = dipole0[i][2];
9062 	for(j=0;j<3;j++)
9063 	{
9064 		B[j] = 0.0;
9065 		for(k=0;k<3;k++)
9066 			B[j] += m[k][j]*A[k];
9067 	}
9068 	dipole[i][0]=B[0];
9069 	dipole[i][1]=B[1];
9070 	dipole[i][2]=B[2];
9071 	}
9072 	}
9073 
9074 	sort_with_zaxis();
9075 	define_coefs_pers();
9076 }
9077 /*****************************************************************************/
rotation_atom_quat(gint i,gdouble m[4][4])9078 void rotation_atom_quat(gint i,gdouble m[4][4])
9079 {
9080 	gdouble A[3];
9081 	gdouble B[3];
9082 	guint j,k;
9083 
9084 	A[0] = CSselectedAtom[0] ;
9085 	A[1] = CSselectedAtom[1] ;
9086 	A[2] = CSselectedAtom[2] ;
9087 	for(j=0;j<3;j++)
9088 	{
9089 		B[j] = 0.0;
9090 		for(k=0;k<3;k++)
9091 			B[j] += m[k][j]*A[k];
9092 	}
9093 	geometry0[i].X=B[0];
9094 	geometry0[i].Y=B[1];
9095 	geometry0[i].Z=B[2];
9096 }
9097 /*****************************************************************************/
rotation(double a,double b,double angle,double * ap,double * bp)9098 void rotation(double a,double b,double angle,double *ap,double *bp)
9099 {
9100 	double cosangle = cos(angle/180*PI);
9101 	double sinangle = sin(angle/180*PI);
9102 
9103 	*ap = a*cosangle - b *sinangle;
9104 	*bp = b*cosangle + a *sinangle;
9105 }
9106 /*****************************************************************************/
set_to_yaxis()9107 void set_to_yaxis()
9108 {
9109 	double A;
9110 	double B;
9111 	double angle=90;
9112 	double Xmax,Xmin;
9113 	double Ymax,Ymin;
9114 	double Zmax,Zmin;
9115 	guint i;
9116 	guint axe;
9117 
9118 
9119         if(Natoms<1)
9120           return;
9121 
9122 	Xmax =geometry[0].X;
9123 	Ymax =geometry[0].Y;
9124 	Zmax =geometry[0].Z;
9125 
9126 	Xmin =geometry[0].X;
9127 	Ymin =geometry[0].Y;
9128 	Zmin =geometry[0].Z;
9129 
9130 	for (i = 1;i<Natoms;i++)
9131 	{
9132 	if (geometry[i].X>Xmax)
9133 			  Xmax =geometry[i].X;
9134 	if (geometry[i].X<Xmin)
9135 			  Xmin =geometry[i].X;
9136 
9137 	if (geometry[i].Y>Ymax)
9138 			   Ymax =geometry[i].Y;
9139 	if (geometry[i].Y<Ymin)
9140 			  Ymin =geometry[i].Y;
9141 
9142     	if (geometry[i].Z>Zmax)
9143 			Zmax =geometry[i].Z;
9144 	if (geometry[i].Z<Zmin)
9145 			Zmin =geometry[i].Z;
9146 
9147 	}
9148         axe=0;
9149         if(fabs(Ymax-Ymin)<=fabs(Xmax-Xmin))
9150         {
9151         	if(fabs(Zmax-Zmin)<fabs(Ymax-Ymin))
9152                     axe=2;
9153                  else
9154 		    axe=1;
9155          }
9156          else
9157         {
9158         	if(fabs(Zmax-Zmin)<fabs(Xmax-Xmin))
9159                     axe=2;
9160          }
9161 
9162 
9163 	if(axe==0)
9164 	{
9165 		for (i=0;i<Natoms;i++)
9166 		{
9167 			A = geometry[i].Z;
9168 			B = geometry[i].X;
9169 			rotation(A,B,angle,&geometry[i].Z,&geometry[i].X);
9170 		}
9171 		for (i=0;i<NDIVDIPOLE;i++)
9172 		{
9173 			A = dipole[i][2];
9174 			B = dipole[i][0];
9175 			rotation(A,B,angle,&dipole[i][2],&dipole[i][0]);
9176 		}
9177 	}
9178         else if(axe==1)
9179 	{
9180 		for (i=0;i<Natoms;i++)
9181 		{
9182 			A = geometry[i].Y;
9183 			B = geometry[i].Z;
9184 			rotation(A,B,angle,&geometry[i].Y,&geometry[i].Z);
9185 		}
9186 		for (i=0;i<NDIVDIPOLE;i++)
9187 		{
9188 			A = dipole[i][1];
9189 			B = dipole[i][2];
9190 			rotation(A,B,angle,&dipole[i][1],&dipole[i][2]);
9191 		}
9192 	}
9193 }
9194 /*****************************************************************************/
define_geometry()9195 void define_geometry()
9196 {
9197         guint i;
9198         guint j;
9199         gdouble X0[3];
9200 	gint nC = 0;
9201 
9202 	if(geometry != NULL)
9203 	{
9204                 for (i=0;i<Natoms;i++)
9205 			g_free(geometry[i].Prop.symbol);
9206 
9207 		g_free(geometry);
9208 		geometry = NULL;
9209 	}
9210         if(MethodeGeom == GEOM_IS_XYZ) Natoms = NcentersXYZ;
9211         else Natoms = NcentersZmat;
9212 
9213 	geometry =g_malloc(Natoms*sizeof(GeomDef));
9214 
9215         if((MethodeGeom == GEOM_IS_XYZ) && (GeomXYZ  != NULL) ) define_geometry_from_xyz();
9216         if((MethodeGeom == GEOM_IS_ZMAT) && (Geom  != NULL) )
9217 	{
9218 		if(!define_geometry_from_zmat()) Message(_("Error in  conversion\n Zmatix to xyz "),_("Warning"),TRUE);
9219 		for(i=0;i<Natoms;i++)
9220 		{
9221 			gint j;
9222 			geometry[i].typeConnections = g_malloc(Natoms*sizeof(gint));
9223 			for(j=0;j<(gint)Natoms;j++) geometry[i].typeConnections[j] = 0;
9224 		}
9225 	}
9226 
9227          if(Units == 1 ) geometry_in_au();
9228 /* Center of molecule */
9229         if(Natoms<1) return;
9230         for(i=0;i<3;i++) X0[i] = 0.0;
9231         for(i=0;i<Natoms;i++)
9232 	{
9233 	X0[0] +=geometry[i].X;
9234 	X0[1] +=geometry[i].Y;
9235 	X0[2] +=geometry[i].Z;
9236 	}
9237         for(i=0;i<3;i++)
9238 		X0[i] /= Natoms;
9239         for(i=0;i<Natoms;i++)
9240 	{
9241 	geometry[i].X -= X0[0];
9242 	geometry[i].Y -= X0[1];
9243 	geometry[i].Z -= X0[2];
9244 	}
9245 
9246 	Ddef = Dipole.def;
9247 	if(Ddef)
9248 	{
9249 		gdouble step[3] ={Dipole.value[0]/(NDIVDIPOLE-1),Dipole.value[1]/(NDIVDIPOLE-1),Dipole.value[2]/(NDIVDIPOLE-1)};
9250 		dipole[0][0] = -X0[0];
9251 		dipole[0][1] = -X0[1];
9252 		dipole[0][2] = -X0[2];
9253 		for(i=1;i<NDIVDIPOLE;i++)
9254 			for(j=0;j<3;j++)
9255 				dipole[i][j] = dipole[0][j]+step[j]*i;
9256 	}
9257         for(i=0;i<3;i++) Orig[i] = X0[i];
9258 
9259 	set_to_yaxis();
9260 
9261 	if(geometry0) g_free(geometry0);
9262 	geometry0 = NULL;
9263 
9264 	geometry0 =g_malloc(Natoms*sizeof(GeomDef));
9265 	for(i=0;i<Natoms;i++)
9266 	{
9267 	geometry0[i].X = geometry[i].X;
9268 	geometry0[i].Y = geometry[i].Y;
9269 	geometry0[i].Z = geometry[i].Z;
9270 	geometry0[i].N = geometry[i].N;
9271         geometry0[i].typeConnections = NULL;
9272 	geometry0[i].Prop = prop_atom_get(geometry[i].Prop.symbol);
9273 	geometry0[i].mmType = g_strdup(geometry[i].mmType);
9274 	geometry0[i].pdbType = g_strdup(geometry[i].pdbType);
9275 	geometry0[i].Layer = geometry[i].Layer;
9276 	geometry0[i].Variable = geometry[i].Variable;
9277 	geometry0[i].Residue = g_strdup(geometry[i].Residue);
9278 	geometry0[i].ResidueNumber = geometry[i].ResidueNumber;
9279 	geometry0[i].show = geometry[i].show;
9280 	geometry0[i].Charge = geometry[i].Charge;
9281 	geometry0[i].typeConnections = NULL;
9282 	}
9283 	if(Ddef)
9284 	{
9285 	for(i=0;i<NDIVDIPOLE;i++)
9286 		for(j=0;j<3;j++)
9287 		{
9288 			dipole0[i][j] = dipole[0][j] + (dipole[i][j]-dipole[0][j])*factordipole;
9289 			dipole00[i][j] = dipole0[i][j];
9290 		}
9291 	}
9292 
9293 	nC = 0;
9294 	for(i=0;i<Natoms;i++)
9295 	{
9296 		geometry0[i].typeConnections = g_malloc(Natoms*sizeof(gint));
9297 		for(j=0;j<(gint)Natoms;j++) geometry0[i].typeConnections[j] = 0;
9298 	}
9299 	copy_connections(geometry0,geometry,Natoms);
9300 	nC = 0;
9301 	for(i=0;i<Natoms;i++)
9302 		for(j=0;j<(gint)Natoms;j++) nC+= geometry[i].typeConnections[j];
9303 	if(nC==0) reset_all_connections();
9304 	sort_with_zaxis();
9305 	define_coord_maxmin();
9306 	define_coefs_pers();
9307 	free_text_to_draw();
9308 	/* define_good_trans();*/
9309 
9310 	/* reset_charges_multiplicities();*/
9311 	reset_spin_of_electrons();
9312 
9313 }
9314 /*****************************************************************************/
get_num_min_rayonIJ(guint i,guint j)9315 guint get_num_min_rayonIJ(guint i,guint j)
9316 {
9317 	gint rmin;
9318 	guint kmin;
9319 
9320 	rmin = geometry[i].Rayon;
9321         kmin = i;
9322 	if(rmin > geometry[j].Rayon)
9323 		{
9324 			rmin = geometry[j].Rayon;
9325 			kmin =j;
9326 		}
9327 	return kmin;
9328 
9329 }
9330 /*****************************************************************************/
draw_triangle(gint x1,gint y1,gint x2,gint y2,gint x3,gint y3,GdkColor colori)9331 void draw_triangle(gint x1,gint y1,gint x2,gint y2,gint x3,gint y3, GdkColor colori)
9332 {
9333 	GdkColormap *colormap;
9334 
9335    	colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
9336         gdk_colormap_alloc_color(colormap,&colori,FALSE,TRUE);
9337 	gdk_gc_set_foreground(gc,&colori);
9338 	gdk_gc_set_line_attributes(gc,1,GDK_LINE_SOLID,GDK_CAP_NOT_LAST,GDK_JOIN_MITER);
9339 	gabedit_cairo_triangle(cr, GeomDrawingArea, gc, x1, y1, x2, y2,  x3, y3);
9340 	if(crExport)
9341 	gabedit_cairo_triangle(crExport, GeomDrawingArea, gc, x1, y1, x2, y2,  x3, y3);
9342 }
9343 /*****************************************************************************/
get_color_string(guint i)9344 GdkColor get_color_string(guint i)
9345 {
9346  GdkColor color;
9347  color.pixel = 0;
9348  if (ShadMode)
9349  {
9350   color.red   =(gushort)(65535-geometry[i].Prop.color.red*geometry[i].Coefpers);
9351   color.green =(gushort)(65535-geometry[i].Prop.color.green*geometry[i].Coefpers);
9352   color.blue  =(gushort)(65535-geometry[i].Prop.color.blue*geometry[i].Coefpers);
9353  }
9354  else
9355  {
9356   color.red   =FontsStyleLabel.TextColor.red;
9357   color.green =FontsStyleLabel.TextColor.green;
9358   color.blue  =FontsStyleLabel.TextColor.blue;
9359  }
9360  return color;
9361 }
9362 /*****************************************************************************/
draw_distance(gint i,gint j,gint x0,gint y0)9363 void draw_distance(gint i,gint j,gint x0,gint y0)
9364 {
9365 	GdkColormap *colormap;
9366         GdkColor color;
9367  	PangoFontDescription *font_desc = pango_font_description_from_string (FontsStyleLabel.fontname);
9368 
9369         Point A;
9370         Point B;
9371 
9372 	A.C[0]=geometry[i].X;
9373 	A.C[1]=geometry[i].Y;
9374 	A.C[2]=geometry[i].Z;
9375 
9376 	B.C[0]=geometry[j].X;
9377 	B.C[1]=geometry[j].Y;
9378 	B.C[2]=geometry[j].Z;
9379 
9380         color = get_color_string(i);
9381 
9382    	colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
9383         gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE);
9384 
9385 	gdk_gc_set_foreground(gc,&color);
9386 	gabedit_cairo_string(cr, GeomDrawingArea, font_desc, gc, x0,y0,get_distance_points(A,B,TRUE),TRUE,TRUE);
9387 	if(crExport)
9388 	gabedit_cairo_string(crExport, GeomDrawingArea, font_desc, gc, x0,y0,get_distance_points(A,B,TRUE),TRUE,TRUE);
9389 
9390 	if(font_desc) pango_font_description_free (font_desc);
9391 
9392 }
9393 /*****************************************************************************/
draw_line(gdouble x1,gdouble y1,gdouble x2,gdouble y2,GdkColor colori,gint epaisseuri,gboolean round)9394 void draw_line(gdouble x1,gdouble y1,gdouble x2,gdouble y2,GdkColor colori,gint epaisseuri, gboolean round)
9395 {
9396 	GdkColormap *colormap;
9397         gint epaisseur=epaisseuri;
9398 
9399    	colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
9400 
9401 	gdk_colormap_alloc_color(colormap,&colori,FALSE,TRUE);
9402 	gdk_gc_set_foreground(gc,&colori);
9403 	if(round)
9404 	gdk_gc_set_line_attributes(gc,epaisseur,GDK_LINE_SOLID,GDK_CAP_ROUND,GDK_JOIN_ROUND);
9405 	else
9406 	gdk_gc_set_line_attributes(gc,epaisseur,GDK_LINE_SOLID,GDK_CAP_NOT_LAST,GDK_JOIN_ROUND);
9407 	gabedit_cairo_line(cr, GeomDrawingArea, gc, x1,y1,x2,y2);
9408 	if(crExport) gabedit_cairo_line(crExport, GeomDrawingArea, gc, x1,y1,x2,y2);
9409 }
9410 /*****************************************************************************/
draw_line_hbond(gint x1,gint y1,gint x2,gint y2,GdkColor color,gint epaisseur)9411 static void draw_line_hbond(gint x1,gint y1,gint x2,gint y2,GdkColor color,gint epaisseur)
9412 {
9413 	GdkColormap *colormap;
9414 
9415    	colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
9416         gdk_colormap_alloc_color(colormap,&color,FALSE,TRUE);
9417 	gdk_gc_set_foreground(gc,&color);
9418 	gdk_gc_set_line_attributes(gc,epaisseur,GDK_LINE_ON_OFF_DASH,GDK_CAP_NOT_LAST,GDK_JOIN_MITER);
9419 
9420 	gabedit_cairo_line(cr, GeomDrawingArea, gc, x1,y1,x2,y2);
9421 	if(crExport) gabedit_cairo_line(crExport, GeomDrawingArea, gc, x1,y1,x2,y2);
9422 }
9423 /*****************************************************************************/
draw_line2_hbond(gint x1,gint y1,gint x2,gint y2,gint i,gint j,GdkColor color1,GdkColor color2,gint epaisseur)9424 static void draw_line2_hbond(gint x1,gint y1,gint x2,gint y2, gint i, gint j, GdkColor color1,GdkColor color2, gint epaisseur)
9425 {
9426 	gdouble x0;
9427 	gdouble y0;
9428 
9429         gdouble poid1;
9430         gdouble poid2;
9431         gdouble poid;
9432         gushort rayon;
9433         gdouble xp;
9434         gdouble yp;
9435         gdouble k;
9436 	gint nj = geometry[j].N-1;
9437 
9438 	GdkColor colorblack;
9439 
9440 	colorblack.red = 0;
9441 	colorblack.green = 0;
9442 	colorblack.blue = 0;
9443 	if(epaisseur<1) epaisseur = 1;
9444 
9445 	if((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)<epaisseur*epaisseur) return;
9446 
9447         if ( !stick_mode() && geometry[i].Layer != LOW_LAYER )
9448         {
9449                 rayon = get_rayon(i);
9450 
9451                  k= ((gdouble)rayon*(gdouble)rayon-(gdouble)epaisseur*(gdouble)epaisseur/4.0);
9452 		 if(geometry[i].typeConnections[nj]==2) k= ((gdouble)rayon*(gdouble)rayon-(gdouble)epaisseur*(gdouble)epaisseur*9.0/4);
9453 		 if(geometry[i].typeConnections[nj]==3) k= ((gdouble)rayon*(gdouble)rayon-(gdouble)epaisseur*(gdouble)epaisseur*25.0/4);
9454 
9455 		if(k>0 &&(( (gdouble)(x2-x1)*(gdouble)(x2-x1)+(gdouble)(y2-y1)*(gdouble)(y2-y1) )>2))
9456                 k = (sqrt(k))/(gdouble)(sqrt( (gdouble)(x2-x1)*(gdouble)(x2-x1)+(gdouble)(y2-y1)*(gdouble)(y2-y1) ) );
9457                 else
9458                  k=0.0;
9459 
9460                 xp = x1 + k *(x2-x1);
9461                 yp = y1 + k *(y2-y1);
9462 
9463 
9464         }
9465         else
9466         {
9467 	      xp = x1;
9468               yp = y1;
9469         }
9470 
9471         poid1 = geometry[i].Prop.covalentRadii+geometry[i].Prop.radii;
9472         poid2 = geometry[j].Prop.covalentRadii+geometry[j].Prop.radii;
9473         poid = poid1 + poid2 ;
9474 	x0=((x1*poid2+x2*poid1)/poid);
9475 	y0=((y1*poid2+y2*poid1)/poid);
9476 
9477 	if(color1.red==color2.red && color1.green==color2.green && color1.blue==color2.blue)
9478 	{
9479 		draw_line_hbond(xp,yp,x2,y2,color1,epaisseur);
9480 	}
9481 	else
9482 	{
9483 	draw_line_hbond(xp,yp,x0,y0,color1,epaisseur);
9484 	draw_line_hbond(x0,y0,x2,y2,color2,epaisseur);
9485 	}
9486 
9487 	if(DrawDistance) draw_distance(i,j,x0,y0);
9488 }
9489 /*****************************************************************************/
draw_anneau(gint xi,gint yi,gint rayoni,GdkColor colori)9490 void draw_anneau(gint xi,gint yi,gint rayoni,GdkColor colori)
9491 {
9492 	GdkColormap *colormap;
9493 
9494         colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
9495         gdk_colormap_alloc_color(colormap,&colori,FALSE,TRUE);
9496 	gdk_gc_set_foreground(gc,&colori);
9497 	gdk_gc_set_line_attributes(gc,4,GDK_LINE_SOLID,GDK_CAP_ROUND,GDK_JOIN_ROUND);
9498 	gdk_gc_set_fill(gc,GDK_STIPPLED);
9499 
9500 	gabedit_cairo_cercle(cr, GeomDrawingArea, gc, xi, yi,rayoni);
9501 	if(crExport) gabedit_cairo_cercle(crExport, GeomDrawingArea, gc, xi, yi,rayoni);
9502 	gdk_gc_set_fill(gc,GDK_SOLID);
9503 }
9504 /*****************************************************************************/
draw_lines_yes_no(guint i,guint j)9505 gboolean draw_lines_yes_no(guint i,guint j)
9506 {
9507   gdouble distance;
9508   gdouble rcut;
9509   gdouble x,y,z;
9510   x = geometry[i].X-geometry[j].X;
9511   y = geometry[i].Y-geometry[j].Y;
9512   z = geometry[i].Z-geometry[j].Z;
9513   distance = x*x+y*y+z*z;
9514   rcut = geometry[i].Prop.covalentRadii+geometry[j].Prop.covalentRadii;
9515   rcut = rcut* rcut;
9516 
9517   if(distance<rcut)
9518 	return TRUE;
9519   else
9520 	return FALSE;
9521 }
9522 /*****************************************************************************/
draw_symb(guint epaisseur,guint i)9523 void draw_symb(guint epaisseur,guint i)
9524 {
9525 	GdkColormap *colormap;
9526 	GdkColor color;
9527  	PangoFontDescription *font_desc = pango_font_description_from_string (FontsStyleLabel.fontname);
9528 	gchar* t= g_strdup_printf("%s", geometry[i].Prop.symbol);
9529 
9530 
9531 	color = get_color_string(i);
9532    	colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
9533         gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE);
9534 
9535 	gdk_gc_set_foreground(gc,&color);
9536         if(epaisseur == 0)epaisseur =1;
9537 	gdk_gc_set_line_attributes(gc,epaisseur,GDK_LINE_SOLID,GDK_CAP_ROUND,GDK_JOIN_ROUND);
9538 	gabedit_cairo_string(cr, GeomDrawingArea, font_desc, gc, geometry[i].Xi,geometry[i].Yi,t,TRUE,TRUE);
9539 	if(crExport)
9540 	gabedit_cairo_string(crExport, GeomDrawingArea, font_desc, gc, geometry[i].Xi,geometry[i].Yi,t,TRUE,TRUE);
9541 
9542 
9543 	if(font_desc) pango_font_description_free (font_desc);
9544 	g_free(t);
9545 
9546 }
9547 /*****************************************************************************/
draw_numb(guint epaisseur,guint i)9548 void draw_numb(guint epaisseur,guint i)
9549 {
9550 	GdkColormap *colormap;
9551         GdkColor color;
9552         gchar *temp;
9553  	PangoFontDescription *font_desc = pango_font_description_from_string (FontsStyleLabel.fontname);
9554         temp = g_strdup_printf("%d",geometry[i].N);
9555 
9556         color = get_color_string(i);
9557 
9558    	colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
9559         gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE);
9560 	gdk_gc_set_foreground(gc,&color);
9561         if(epaisseur == 0)epaisseur =1;
9562 	gdk_gc_set_line_attributes(gc,epaisseur,GDK_LINE_SOLID,GDK_CAP_ROUND,GDK_JOIN_ROUND);
9563 	gabedit_cairo_string(cr, GeomDrawingArea, font_desc, gc, geometry[i].Xi,geometry[i].Yi,temp,TRUE,TRUE);
9564 	if(crExport)
9565 	gabedit_cairo_string(crExport, GeomDrawingArea, font_desc, gc, geometry[i].Xi,geometry[i].Yi,temp,TRUE,TRUE);
9566 
9567 	if(font_desc) pango_font_description_free (font_desc);
9568 
9569         g_free(temp);
9570 }
9571 /*****************************************************************************/
draw_layer(guint epaisseur,guint i)9572 void draw_layer(guint epaisseur,guint i)
9573 {
9574 	GdkColormap *colormap;
9575 	GdkColor color;
9576  	PangoFontDescription *font_desc = pango_font_description_from_string (FontsStyleLabel.fontname);
9577 	gchar* t= NULL;
9578 
9579 	if(geometry[i].Layer==LOW_LAYER) t= g_strdup_printf("L");
9580 	else if(geometry[i].Layer==MEDIUM_LAYER) t= g_strdup_printf("M");
9581 	else t= g_strdup_printf(" ");
9582 
9583 	color = get_color_string(i);
9584    	colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
9585         gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE);
9586 
9587 	gdk_gc_set_foreground(gc,&color);
9588         if(epaisseur == 0)epaisseur =1;
9589 	gdk_gc_set_line_attributes(gc,epaisseur,GDK_LINE_SOLID,GDK_CAP_ROUND,GDK_JOIN_ROUND);
9590 	gabedit_cairo_string(cr, GeomDrawingArea, font_desc, gc, geometry[i].Xi,geometry[i].Yi,t,TRUE,TRUE);
9591 	if(crExport)
9592 	gabedit_cairo_string(crExport, GeomDrawingArea, font_desc, gc, geometry[i].Xi,geometry[i].Yi,t,TRUE,TRUE);
9593 
9594 	if(font_desc) pango_font_description_free (font_desc);
9595 	g_free(t);
9596 
9597 }
9598 /*****************************************************************************/
draw_mmtyp(guint epaisseur,guint i)9599 void draw_mmtyp(guint epaisseur,guint i)
9600 {
9601 	GdkColormap *colormap;
9602 	GdkColor color;
9603  	PangoFontDescription *font_desc = pango_font_description_from_string (FontsStyleLabel.fontname);
9604 	gchar* t= g_strdup_printf("%s", geometry[i].mmType);
9605 
9606 
9607 	color = get_color_string(i);
9608    	colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
9609         gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE);
9610 
9611 	gdk_gc_set_foreground(gc,&color);
9612         if(epaisseur == 0)epaisseur =1;
9613 	gdk_gc_set_line_attributes(gc,epaisseur,GDK_LINE_SOLID,GDK_CAP_ROUND,GDK_JOIN_ROUND);
9614 	gabedit_cairo_string(cr, GeomDrawingArea, font_desc, gc, geometry[i].Xi,geometry[i].Yi,t,TRUE,TRUE);
9615 	if(crExport)
9616 	gabedit_cairo_string(crExport, GeomDrawingArea, font_desc, gc, geometry[i].Xi,geometry[i].Yi,t,TRUE,TRUE);
9617 
9618 	if(font_desc) pango_font_description_free (font_desc);
9619 	g_free(t);
9620 
9621 }
9622 /*****************************************************************************/
draw_pdbtyp(guint epaisseur,guint i)9623 void draw_pdbtyp(guint epaisseur,guint i)
9624 {
9625 	GdkColormap *colormap;
9626 	GdkColor color;
9627  	PangoFontDescription *font_desc = pango_font_description_from_string (FontsStyleLabel.fontname);
9628 	gchar* t= g_strdup_printf("%s", geometry[i].pdbType);
9629 
9630 
9631 	color = get_color_string(i);
9632    	colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
9633         gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE);
9634 
9635 	gdk_gc_set_foreground(gc,&color);
9636         if(epaisseur == 0)epaisseur =1;
9637 	gdk_gc_set_line_attributes(gc,epaisseur,GDK_LINE_SOLID,GDK_CAP_ROUND,GDK_JOIN_ROUND);
9638 	gabedit_cairo_string(cr, GeomDrawingArea, font_desc, gc, geometry[i].Xi,geometry[i].Yi,t,TRUE,TRUE);
9639 	if(crExport)
9640 	gabedit_cairo_string(crExport, GeomDrawingArea, font_desc, gc, geometry[i].Xi,geometry[i].Yi,t,TRUE,TRUE);
9641 
9642 	if(font_desc) pango_font_description_free (font_desc);
9643 	g_free(t);
9644 
9645 }
9646 /*****************************************************************************/
draw_numb_symb(guint epaisseur,guint i)9647 void draw_numb_symb(guint epaisseur,guint i)
9648 {
9649 	GdkColormap *colormap;
9650         GdkColor color;
9651         gchar *temp;
9652  	PangoFontDescription *font_desc = pango_font_description_from_string (FontsStyleLabel.fontname);
9653         temp = g_strdup_printf("%s[%d]",geometry[i].Prop.symbol,geometry[i].N);
9654 
9655         color = get_color_string(i);
9656 
9657    	colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
9658         gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE);
9659 	gdk_gc_set_foreground(gc,&color);
9660         if(epaisseur == 0)epaisseur =1;
9661 	gdk_gc_set_line_attributes(gc,epaisseur,GDK_LINE_SOLID,GDK_CAP_ROUND,GDK_JOIN_ROUND);
9662 	gabedit_cairo_string(cr, GeomDrawingArea, font_desc, gc, geometry[i].Xi,geometry[i].Yi,temp,TRUE,TRUE);
9663 	if(crExport)
9664 	gabedit_cairo_string(crExport, GeomDrawingArea, font_desc, gc, geometry[i].Xi,geometry[i].Yi,temp,TRUE,TRUE);
9665 
9666 	if(font_desc) pango_font_description_free (font_desc);
9667         g_free(temp);
9668 }
9669 /*****************************************************************************/
draw_charge(guint epaisseur,guint i)9670 void draw_charge(guint epaisseur,guint i)
9671 {
9672 	GdkColormap *colormap;
9673         GdkColor color;
9674         gchar *temp;
9675  	PangoFontDescription *font_desc = pango_font_description_from_string (FontsStyleLabel.fontname);
9676         temp = g_strdup_printf("%0.3f",geometry[i].Charge);
9677 
9678         color = get_color_string(i);
9679    	colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
9680         gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE);
9681 	gdk_gc_set_foreground(gc,&color);
9682         if(epaisseur == 0)epaisseur =1;
9683 	gdk_gc_set_line_attributes(gc,epaisseur,GDK_LINE_SOLID,GDK_CAP_ROUND,GDK_JOIN_ROUND);
9684 	gabedit_cairo_string(cr, GeomDrawingArea, font_desc, gc, geometry[i].Xi,geometry[i].Yi,temp,TRUE,TRUE);
9685 	if(crExport)
9686 	gabedit_cairo_string(crExport, GeomDrawingArea, font_desc, gc, geometry[i].Xi,geometry[i].Yi,temp,TRUE,TRUE);
9687 
9688 	if(font_desc) pango_font_description_free (font_desc);
9689 
9690         g_free(temp);
9691 }
9692 /*****************************************************************************/
draw_symb_charge(guint epaisseur,guint i)9693 void draw_symb_charge(guint epaisseur,guint i)
9694 {
9695 	GdkColormap *colormap;
9696         GdkColor color;
9697         gchar *temp;
9698  	PangoFontDescription *font_desc = pango_font_description_from_string (FontsStyleLabel.fontname);
9699         temp = g_strdup_printf("%s[%0.3f]",geometry[i].Prop.symbol,geometry[i].Charge);
9700 
9701         color = get_color_string(i);
9702 
9703    	colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
9704         gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE);
9705 	gdk_gc_set_foreground(gc,&color);
9706         if(epaisseur == 0)epaisseur =1;
9707 	gdk_gc_set_line_attributes(gc,epaisseur,GDK_LINE_SOLID,GDK_CAP_ROUND,GDK_JOIN_ROUND);
9708 	gabedit_cairo_string(cr, GeomDrawingArea, font_desc, gc, geometry[i].Xi,geometry[i].Yi,temp,TRUE,TRUE);
9709 	if(crExport)
9710 	gabedit_cairo_string(crExport, GeomDrawingArea, font_desc, gc, geometry[i].Xi,geometry[i].Yi,temp,TRUE,TRUE);
9711 
9712 	if(font_desc) pango_font_description_free (font_desc);
9713 
9714         g_free(temp);
9715 }
9716 /*****************************************************************************/
draw_numb_charge(guint epaisseur,guint i)9717 void draw_numb_charge(guint epaisseur,guint i)
9718 {
9719 	GdkColormap *colormap;
9720         GdkColor color;
9721         gchar *temp;
9722  	PangoFontDescription *font_desc = pango_font_description_from_string (FontsStyleLabel.fontname);
9723         temp = g_strdup_printf("%d[%0.3f]",geometry[i].N,geometry[i].Charge);
9724 
9725         color = get_color_string(i);
9726 
9727    	colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
9728         gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE);
9729 	gdk_gc_set_foreground(gc,&color);
9730         if(epaisseur == 0)epaisseur =1;
9731 	gdk_gc_set_line_attributes(gc,epaisseur,GDK_LINE_SOLID,GDK_CAP_ROUND,GDK_JOIN_ROUND);
9732 	gabedit_cairo_string(cr, GeomDrawingArea, font_desc, gc, geometry[i].Xi,geometry[i].Yi,temp,TRUE,TRUE);
9733 	if(crExport)
9734 	gabedit_cairo_string(crExport, GeomDrawingArea, font_desc, gc, geometry[i].Xi,geometry[i].Yi,temp,TRUE,TRUE);
9735 
9736 	if(font_desc) pango_font_description_free (font_desc);
9737 
9738         g_free(temp);
9739 }
9740 /*****************************************************************************/
draw_residues(guint epaisseur,guint i)9741 void draw_residues(guint epaisseur,guint i)
9742 {
9743 	GdkColormap *colormap;
9744         GdkColor color;
9745         gchar *temp;
9746  	PangoFontDescription *font_desc = pango_font_description_from_string (FontsStyleLabel.fontname);
9747         temp = g_strdup_printf("%s[%d]",geometry[i].Residue,geometry[i].ResidueNumber+1);
9748 
9749         color = get_color_string(i);
9750 
9751    	colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
9752         gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE);
9753 	gdk_gc_set_foreground(gc,&color);
9754         if(epaisseur == 0)epaisseur =1;
9755 	gdk_gc_set_line_attributes(gc,epaisseur,GDK_LINE_SOLID,GDK_CAP_ROUND,GDK_JOIN_ROUND);
9756 	gabedit_cairo_string(cr, GeomDrawingArea, font_desc, gc, geometry[i].Xi,geometry[i].Yi,temp,TRUE,TRUE);
9757 	if(crExport)
9758 	gabedit_cairo_string(crExport, GeomDrawingArea, font_desc, gc, geometry[i].Xi,geometry[i].Yi,temp,TRUE,TRUE);
9759 
9760 	if(font_desc) pango_font_description_free (font_desc);
9761 
9762         g_free(temp);
9763 }
9764 /*****************************************************************************/
draw_coordinates(guint epaisseur,guint i)9765 void draw_coordinates(guint epaisseur,guint i)
9766 {
9767 	GdkColormap *colormap;
9768         GdkColor color;
9769         gchar *temp;
9770  	PangoFontDescription *font_desc = pango_font_description_from_string (FontsStyleLabel.fontname);
9771         temp = g_strdup_printf("%s[%0.3f,%0.3f,%0.3f] Ang",
9772 			geometry0[i].Prop.symbol,
9773 			geometry0[i].X*BOHR_TO_ANG,
9774 			geometry0[i].Y*BOHR_TO_ANG,
9775 			geometry0[i].Z*BOHR_TO_ANG);
9776 
9777         color = get_color_string(i);
9778 
9779    	colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
9780         gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE);
9781 	gdk_gc_set_foreground(gc,&color);
9782         if(epaisseur == 0)epaisseur =1;
9783 	gdk_gc_set_line_attributes(gc,epaisseur,GDK_LINE_SOLID,GDK_CAP_ROUND,GDK_JOIN_ROUND);
9784 	gabedit_cairo_string(cr, GeomDrawingArea, font_desc, gc, geometry[i].Xi,geometry[i].Yi,temp,TRUE,TRUE);
9785 	if(crExport)
9786 	gabedit_cairo_string(crExport, GeomDrawingArea, font_desc, gc, geometry[i].Xi,geometry[i].Yi,temp,TRUE,TRUE);
9787 
9788 	if(font_desc) pango_font_description_free (font_desc);
9789 
9790         g_free(temp);
9791 }
9792 /*****************************************************************************/
draw_label(guint epaisseur,guint i)9793 void draw_label(guint epaisseur,guint i)
9794 {
9795    switch(LabelOption)
9796    {
9797    case LABELSYMB: draw_symb(epaisseur,i);break;
9798    case LABELNUMB: draw_numb(epaisseur,i);break;
9799    case LABELMMTYP: draw_mmtyp(epaisseur,i);break;
9800    case LABELPDBTYP: draw_pdbtyp(epaisseur,i);break;
9801    case LABELLAYER: draw_layer(epaisseur,i);break;
9802    case LABELSYMBNUMB: draw_numb_symb(epaisseur,i);break;
9803    case LABELCHARGE: draw_charge(epaisseur,i);break;
9804    case LABELSYMBCHARGE: draw_symb_charge(epaisseur,i);break;
9805    case LABELNUMBCHARGE: draw_numb_charge(epaisseur,i);break;
9806    case LABELRESIDUES: draw_residues(epaisseur,i);break;
9807    case LABELCOORDINATES: draw_coordinates(epaisseur,i);break;
9808    }
9809 }
9810 /*****************************************************************************/
draw_line2(gint epaisseur,guint i,guint j,gint x1,gint y1,gint x2,gint y2,GdkColor color1,GdkColor color2,gboolean hideDistance)9811 void draw_line2(gint epaisseur,guint i,guint j,gint x1,gint y1,gint x2,gint y2,
9812 				GdkColor color1,GdkColor color2, gboolean hideDistance)
9813 {
9814 	gdouble x0;
9815 	gdouble y0;
9816 
9817         gdouble poid1;
9818         gdouble poid2;
9819         gdouble poid;
9820         gushort rayon;
9821         gdouble xp;
9822         gdouble yp;
9823         gdouble k;
9824 	gint nj = geometry[j].N-1;
9825 
9826 	GdkColor colorblack;
9827 
9828 	colorblack.red = 0;
9829 	colorblack.green = 0;
9830 	colorblack.blue = 0;
9831 
9832 	if((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)<epaisseur*epaisseur) return;
9833 
9834         if ( !stick_mode() && geometry[i].Layer != LOW_LAYER )
9835         {
9836                 rayon = get_rayon(i);
9837 
9838                  k= ((gdouble)rayon*(gdouble)rayon-(gdouble)epaisseur*(gdouble)epaisseur/4.0);
9839 		 if(geometry[i].typeConnections[nj]==2 && showMultipleBonds) k= ((gdouble)rayon*(gdouble)rayon-(gdouble)epaisseur*(gdouble)epaisseur*9.0/4);
9840 		 if(geometry[i].typeConnections[nj]==3 && showMultipleBonds) k= ((gdouble)rayon*(gdouble)rayon-(gdouble)epaisseur*(gdouble)epaisseur*25.0/4);
9841 
9842 		if(k>0 &&(( (gdouble)(x2-x1)*(gdouble)(x2-x1)+(gdouble)(y2-y1)*(gdouble)(y2-y1) )>2))
9843                 k = (sqrt(k))/(gdouble)(sqrt( (gdouble)(x2-x1)*(gdouble)(x2-x1)+(gdouble)(y2-y1)*(gdouble)(y2-y1) ) );
9844                 else
9845                  k=0.0;
9846 
9847                 xp = x1 + k *(x2-x1);
9848                 yp = y1 + k *(y2-y1);
9849 
9850 
9851         }
9852         else
9853         {
9854 	      xp = x1;
9855               yp = y1;
9856         }
9857 	gdk_gc_set_line_attributes(gc,epaisseur,GDK_LINE_SOLID,GDK_CAP_ROUND,GDK_JOIN_ROUND);
9858 	if(CartoonMode && !(buttonpress&&Natoms>MAT)) draw_line(xp,yp,x2,y2,colorblack,epaisseur+2,TRUE);
9859 
9860         poid1 = geometry[i].Prop.covalentRadii+geometry[i].Prop.radii;
9861         poid2 = geometry[j].Prop.covalentRadii+geometry[j].Prop.radii;
9862         poid = poid1 + poid2 ;
9863 	x0=((x1*poid2+x2*poid1)/poid);
9864 	y0=((y1*poid2+y2*poid1)/poid);
9865 
9866 	if(color1.red==color2.red && color1.green==color2.green && color1.blue==color2.blue)
9867 	{
9868 		if(LightMode)
9869 		{
9870         		if (!stick_mode())
9871 			{
9872 			color1.red = color1.green = color1.blue = 0;
9873 			draw_line(xp,yp,x2,y2,color1,epaisseur,TRUE);
9874 			}
9875 			else
9876 			{
9877 			GdkColormap *colormap;
9878    			colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
9879 			gdk_colormap_alloc_color(colormap,&color1,FALSE,TRUE);
9880 			gdk_gc_set_foreground(gc,&color1);
9881 			gdk_colormap_alloc_color(colormap,&color2,FALSE,TRUE);
9882 			if(!stick_mode())
9883 			gdk_gc_set_line_attributes(gc,epaisseur,GDK_LINE_SOLID,GDK_CAP_NOT_LAST,GDK_JOIN_ROUND);
9884 			else gdk_gc_set_line_attributes(gc,epaisseur,GDK_LINE_SOLID,GDK_CAP_ROUND,GDK_JOIN_ROUND);
9885 
9886 			gabedit_cairo_line_gradient(cr, GeomDrawingArea, gc, color1,  color2,  xp, yp, x2, y2);
9887 			if(crExport) gabedit_cairo_line_gradient(crExport, GeomDrawingArea, gc, color1,  color2,  xp, yp, x2, y2);
9888 			}
9889 		}
9890 		else
9891 		draw_line(xp,yp,x2,y2,color1,epaisseur,TRUE);
9892 	}
9893 	else
9894 	{
9895 		if(LightMode)
9896 		{
9897         		if (!stick_mode())
9898 			{
9899 			color1.red = color1.green = color1.blue = 0;
9900 			draw_line(xp,yp,x2,y2,color1,epaisseur,TRUE);
9901 			}
9902 			else
9903 			{
9904 			GdkColormap *colormap;
9905    			colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
9906 			gdk_colormap_alloc_color(colormap,&color1,FALSE,TRUE);
9907 			gdk_gc_set_foreground(gc,&color1);
9908 			gdk_colormap_alloc_color(colormap,&color2,FALSE,TRUE);
9909         		if (!stick_mode())
9910 			gdk_gc_set_line_attributes(gc,epaisseur,GDK_LINE_SOLID,GDK_CAP_NOT_LAST,GDK_JOIN_ROUND);
9911 			else
9912 			gdk_gc_set_line_attributes(gc,epaisseur,GDK_LINE_SOLID,GDK_CAP_ROUND,GDK_JOIN_ROUND);
9913 
9914 			gabedit_cairo_line_gradient(cr, GeomDrawingArea, gc, color1,  color2,  xp, yp, x2, y2);
9915 			if(crExport)
9916 			gabedit_cairo_line_gradient(crExport, GeomDrawingArea, gc, color1,  color2,  xp, yp, x2, y2);
9917 			}
9918 		}
9919 		else
9920 		{
9921 			draw_line(xp,yp,x0,y0,color1,epaisseur,TRUE);
9922 			draw_line(x0,y0,x2,y2,color2,epaisseur,TRUE);
9923 		}
9924 	}
9925 
9926 
9927 	if(DrawDistance && !hideDistance)
9928                  draw_distance(i,j,x0,y0);
9929 }
9930 /*****************************************************************************/
draw_cercle(gint xi,gint yi,gint rayoni,GdkColor colori,gboolean fill,gboolean cartoon,gboolean lighting)9931 void draw_cercle(gint xi,gint yi,gint rayoni,GdkColor colori, gboolean fill, gboolean cartoon, gboolean lighting)
9932 {
9933 	GdkColormap *colormap;
9934         gint x=xi,y=yi,rayon=rayoni;
9935         GdkColor colorblack;
9936 
9937         colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
9938 	if(cartoon)
9939 	{
9940        		colorblack.red = 0;
9941        		colorblack.green = 0;
9942        		colorblack.blue = 0;
9943 
9944 
9945         	gdk_colormap_alloc_color(colormap,&colorblack,FALSE,TRUE);
9946 		gdk_gc_set_line_attributes(gc,1,GDK_LINE_SOLID,GDK_CAP_ROUND,GDK_JOIN_ROUND);
9947 
9948 		rayon = rayoni+1;
9949 		gdk_gc_set_foreground(gc,&colorblack);
9950 		gdk_gc_set_fill(gc,GDK_STIPPLED);
9951 		gabedit_cairo_cercle(cr, GeomDrawingArea, gc, x, y,rayon);
9952 		if(crExport) gabedit_cairo_cercle(crExport, GeomDrawingArea, gc, x, y,rayon);
9953 		gdk_gc_set_fill(gc,GDK_SOLID);
9954 	}
9955 
9956 	if(fill)
9957 	{
9958 		rayon = rayoni;
9959         	gdk_colormap_alloc_color(colormap,&colori,FALSE,TRUE);
9960 		gdk_gc_set_foreground(gc,&colori);
9961 		gdk_gc_set_fill(gc,GDK_SOLID);
9962 
9963     		if (lighting)
9964 		{
9965 			gabedit_cairo_cercle_gradient(cr, GeomDrawingArea, gc, x, y,rayon);
9966 			if(crExport) gabedit_cairo_cercle_gradient(crExport, GeomDrawingArea, gc, x, y,rayon);
9967 		}
9968 		else
9969 		{
9970 			gabedit_cairo_cercle(cr, GeomDrawingArea, gc, x, y,rayon);
9971 			if(crExport) gabedit_cairo_cercle(crExport, GeomDrawingArea, gc, x, y,rayon);
9972 		}
9973 	}
9974 }
9975 /*****************************************************************************/
draw_arc(gint xi,gint yi,gint rayoni,gdouble angle1,gdouble angle2,gdouble scale1,gdouble scale2,GdkColor colori)9976 void draw_arc(gint xi,gint yi,gint rayoni,gdouble angle1, gdouble angle2, gdouble scale1, gdouble scale2, GdkColor colori)
9977 {
9978 	GdkColormap *colormap;
9979         gint x=xi,y=yi,rayon=rayoni;
9980         GdkColor colorblack;
9981 
9982         colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
9983 	if(CartoonMode)
9984 	{
9985 		gint lw = 2;
9986        		colorblack.red = 0;
9987        		colorblack.green = 0;
9988        		colorblack.blue = 0;
9989 
9990 
9991         	gdk_colormap_alloc_color(colormap,&colorblack,FALSE,TRUE);
9992 		gdk_gc_set_line_attributes(gc,lw,GDK_LINE_SOLID,GDK_CAP_ROUND,GDK_JOIN_ROUND);
9993 
9994 		/* rayon = rayoni+1;*/
9995 		rayon = rayoni;
9996 		gdk_gc_set_foreground(gc,&colorblack);
9997 		gabedit_cairo_arc(cr, GeomDrawingArea, gc, x, y,rayon, angle1, angle2, scale1, scale2);
9998 		if(crExport) gabedit_cairo_arc(crExport, GeomDrawingArea, gc, x, y,rayon, angle1, angle2,scale1, scale2);
9999 	}
10000 	/*
10001 
10002 	rayon = rayoni;
10003         gdk_colormap_alloc_color(colormap,&colori,FALSE,TRUE);
10004 	gdk_gc_set_foreground(gc,&colori);
10005 	gdk_gc_set_fill(gc,GDK_SOLID);
10006 
10007     	if (LightMode)
10008 	{
10009 		gabedit_cairo_arc(cr, GeomDrawingArea, gc, x, y,rayon,angle1, angle2, scale1, scale2);
10010 		if(crExport) gabedit_cairo_arc(crExport, GeomDrawingArea, gc, x, y,rayon,angle1, angle2, scale1, scale2);
10011 	}
10012 	else
10013 	{
10014 		gabedit_cairo_arc(cr, GeomDrawingArea, gc, x, y,rayon,angle1, angle2, scale1, scale2);
10015 		if(crExport) gabedit_cairo_arc(crExport, GeomDrawingArea, gc, x, y,rayon,angle1, angle2,scale1, scale2);
10016 	}
10017 	*/
10018 }
10019 /************************************************************************/
getOptimalCiCj(gint i,gint j,gdouble * Ci,gdouble * Cj,gdouble * C0)10020 void getOptimalCiCj(gint i, gint j, gdouble* Ci, gdouble* Cj, gdouble* C0)
10021 {
10022 	C0[0] = 0;
10023 	C0[1] = 0;
10024 	C0[2] = 0;
10025 
10026 	Ci[0] = geometry[i].X;
10027 	Ci[1] = geometry[i].Y;
10028 	Ci[2] = geometry[i].Z;
10029 
10030 	Cj[0] = geometry[j].X;
10031 	Cj[1] = geometry[j].Y;
10032 	Cj[2] = geometry[j].Z;
10033 
10034 /* serach a one none hydrogen atom connected to i or j atoms */
10035 	if(geometry[i].typeConnections)
10036 	{
10037 		gint l;
10038 		gint nl;
10039 		for(l=0, nl = geometry[l].N-1;l<Natoms;l++, nl = geometry[l].N-1)
10040 			if(l != j && l != i &&  geometry[i].typeConnections[nl]>0 && strcmp(geometry[l].Prop.symbol,"H"))
10041 			{
10042 				C0[0] = geometry[l].X;
10043 				C0[1] = geometry[l].Y;
10044 				C0[2] = geometry[l].Z;
10045 				/* printf("---%s\n",geometry[l].Prop.symbol);*/
10046 				return;
10047 			}
10048 	}
10049 	if(geometry[j].typeConnections)
10050 	{
10051 		gint l;
10052 		gint nl;
10053 		for(l=0, nl = geometry[l].N-1;l<Natoms;l++, nl = geometry[l].N-1)
10054 			if(l != j && l != i &&  geometry[j].typeConnections[nl]>0  && strcmp(geometry[l].Prop.symbol,"H"))
10055 			{
10056 				C0[0] = geometry[l].X;
10057 				C0[1] = geometry[l].Y;
10058 				C0[2] = geometry[l].Z;
10059 				/* printf("--%s\n",geometry[l].Prop.symbol);*/
10060 				return;
10061 			}
10062 	}
10063 	if(geometry[i].typeConnections)
10064 	{
10065 		gint l;
10066 		gint nl;
10067 		for(l=0, nl = geometry[l].N-1;l<Natoms;l++, nl = geometry[l].N-1)
10068 			if(l != j && l != i &&  geometry[i].typeConnections[nl]>0)
10069 			{
10070 				C0[0] = geometry[l].X;
10071 				C0[1] = geometry[l].Y;
10072 				C0[2] = geometry[l].Z;
10073 				/* printf("%s\n",geometry[l].Prop.symbol);*/
10074 				return;
10075 			}
10076 	}
10077 	if(geometry[j].typeConnections)
10078 	{
10079 		gint l;
10080 		gint nl;
10081 		for(l=0, nl = geometry[l].N-1;l<Natoms;l++, nl = geometry[l].N-1)
10082 			if(l != j && l != i &&  geometry[j].typeConnections[nl]>0)
10083 			{
10084 				C0[0] = geometry[l].X;
10085 				C0[1] = geometry[l].Y;
10086 				C0[2] = geometry[l].Z;
10087 				/* printf("%s\n",geometry[l].Prop.symbol);*/
10088 				return;
10089 			}
10090 	}
10091 }
10092 /*****************************************************************************/
draw_ball(gint xi,gint yi,gint rayoni,GdkColor colori)10093 void draw_ball(gint xi,gint yi,gint rayoni,GdkColor colori)
10094 {
10095 	if(!(buttonpress&&Natoms>MAT)) draw_cercle(xi,yi,rayoni,colori, TRUE, CartoonMode, LightMode);
10096 	else draw_cercle(xi,yi,rayoni,colori, TRUE, FALSE, LightMode);
10097 
10098 	if(OrtepMode && !(buttonpress&&Natoms>MAT))
10099 	{
10100     		draw_arc(xi,yi,rayoni,0, M_PI, 1.0, 0.5, colori);
10101     		draw_arc(xi,yi,rayoni,M_PI/2,3*M_PI/2,0.5,1.0, colori);
10102 	}
10103 }
10104 /*****************************************************************************/
drawGeom_byLayer()10105 void drawGeom_byLayer()
10106 {
10107 	guint i;
10108 	guint j;
10109 	guint k;
10110 	gint epaisseur;
10111         gushort rayon;
10112 	GdkColor color1;
10113 	GdkColor color2;
10114 	GdkColor colorRed;
10115 	GdkColor colorGreen;
10116 	GdkColor colorBlue;
10117 	GdkColor colorYellow;
10118 	GdkColor colorFrag;
10119 	gint ni;
10120 	gint nj;
10121 	gint epMin = -1;
10122 	gint epMinH = -1;
10123 	gint epMinM = -1;
10124 	gint epMinL = -1;
10125 
10126 	colorRed.red   = 40000;
10127 	colorRed.green = 0;
10128 	colorRed.blue  = 0;
10129 	colorRed.pixel  = 0;
10130 
10131 	colorGreen.red   = 0;
10132 	colorGreen.green = 40000;
10133 	colorGreen.blue  = 0;
10134 
10135 	colorBlue.red   = 0;
10136 	colorBlue.green = 0;
10137 	colorBlue.blue  = 40000;
10138 
10139 	colorYellow.red   = 40000;
10140 	colorYellow.green = 40000;
10141 	colorYellow.blue  = 0;
10142 
10143 	colorFrag = colorGreen;
10144 
10145 	if(Natoms<1) return;
10146 
10147 	for(i=0;i<Natoms;i++)
10148 	if((gint)i==NumSelectedAtom)
10149 	{
10150 		for(j = 0;j<NFatoms;j++)
10151 			if(NumFatoms[j] == (gint)geometry[i].N) colorFrag = colorRed;
10152 		break;
10153 	}
10154         if(ButtonPressed && OperationType==ROTLOCFRAG) colorFrag = colorRed;
10155         if(ButtonPressed && OperationType==ROTZLOCFRAG) colorFrag = colorRed;
10156 
10157 	define_coord_ecran();
10158 
10159 	for(i=0;i<Natoms;i++)
10160 	{
10161 		gint e = get_rayon(i);
10162 		if(geometry[i].Layer == LOW_LAYER)
10163 		{
10164 			if(epMinL<0) epMinL=e;
10165 			else if(e<epMinL) epMinL=e;
10166 		}
10167 		else
10168 		if(geometry[i].Layer == MEDIUM_LAYER)
10169 		{
10170 			if(epMinM<0) epMinM=e;
10171 			else if(e<epMinM) epMinM=e;
10172 		}
10173 		else
10174 		{
10175 			if(epMinH<0) epMinH=e;
10176 			else if(e<epMinH) epMinH=e;
10177 		}
10178 	}
10179 	if(epMinH>0) epMin = epMinH;
10180 	else if(epMinM>0) epMin = epMinM;
10181 	else if(epMinL>0) epMin = epMinL;
10182 	else epMin = 2;
10183 
10184 	epMin *= factorstick;
10185 	if(epMin<1) epMin = 1;
10186 
10187 	for(i=0;i<Natoms-1;i++)
10188 	{
10189 		ni = geometry[i].N-1;
10190 		if(!geometry[i].show)
10191 		{
10192 			if(ShowDipole) for(j = 0;j<NDIVDIPOLE;j++) if(Ndipole[j]==(gint)i) drawGeom_dipole(j);
10193 			continue;
10194 		}
10195                 rayon = get_rayon(i);
10196 		color1 = geometry[i].Prop.color;
10197     		if (ShadMode) set_color_shad(&color1,i);
10198 
10199 		if(geometry0[i].Layer != LOW_LAYER)
10200 		{
10201 			draw_ball(geometry[i].Xi,geometry[i].Yi,rayon,color1);
10202 		}
10203 		if((gint)i==NumSelectedAtom) draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorRed);
10204 		else
10205 		{
10206 			if(NSA[0]>-1 && (gint)geometry[i].N == NSA[0]) draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorRed);
10207 			if(NSA[1]>-1 && (gint)geometry[i].N == NSA[1]) draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorGreen);
10208 			if(NSA[2]>-1 && (gint)geometry[i].N == NSA[2]) draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorBlue);
10209 			if(NSA[3]>-1 && (gint)geometry[i].N == NSA[3]) draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorYellow);
10210 		}
10211 		if(OperationType == MEASURE)
10212 		for(j = 0;j<4;j++)
10213 		if(NumSelAtoms[j] == (gint)geometry[i].N) draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorGreen);
10214         	switch(OperationType)
10215 		{
10216 			case ADDFRAGMENT :
10217 				if(atomToDelete == (gint)geometry[i].N)
10218 	 				draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorRed);
10219 				if(atomToBondTo == (gint)geometry[i].N)
10220 	 				draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorGreen);
10221 				if(angleTo == (gint)geometry[i].N)
10222 	 				draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorBlue);
10223 			break;
10224 			case SELECTOBJECTS :
10225 			case SELECTFRAG :
10226 			case SELECTRESIDUE :
10227 			case DELETEOBJECTS :
10228 			case DELETEFRAG :
10229 			case ROTLOCFRAG :
10230 			case ROTZLOCFRAG :
10231 			case MOVEFRAG :
10232 			for(j = 0;j<NFatoms;j++)
10233 				if(NumFatoms[j] == (gint)geometry[i].N)
10234 	 				draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorFrag);
10235 			break;
10236 			case CUTBOND :
10237 			for(j = 0;j<NBatoms;j++)
10238 				if(NumBatoms[j] == (gint)geometry[i].N)
10239 	 				draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorRed);
10240 			break;
10241 			case CHANGEBOND :
10242 			case ADDATOMSBOND :
10243 			for(j = 0;j<NBatoms;j++)
10244 				if(NumBatoms[j] == (gint)geometry[i].N)
10245 	 				draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorFrag);
10246 			break;
10247 			default :break;
10248 		}
10249 
10250 		for(j=i+1, nj = geometry[j].N-1;j<Natoms;j++,nj = geometry[j].N-1)
10251                 if(geometry[i].typeConnections[nj]>0)
10252 		{
10253 			if(!geometry[j].show) continue;
10254 			gint split[2] = {0,0};
10255 			gdouble ab[] = {0,0};
10256 			k = i;
10257 			if(geometry0[i].Layer == geometry0[j].Layer ) k =get_num_min_rayonIJ(i,j);
10258 			else
10259 			{
10260 				if(geometry0[i].Layer == MEDIUM_LAYER) k = i;
10261 				if(geometry0[j].Layer == MEDIUM_LAYER) k = j;
10262 				if(geometry0[i].Layer == LOW_LAYER) k = i;
10263 				if(geometry0[j].Layer == LOW_LAYER) k = j;
10264 			}
10265 			/* epaisseur = get_rayon(k)*factorstick;*/
10266 			epaisseur = epMin;
10267 			if(geometry[i].Layer == LOW_LAYER || geometry[j].Layer == LOW_LAYER) epaisseur=(gint)(epaisseur/2.5);
10268 			else if(geometry[i].Layer == MEDIUM_LAYER || geometry[j].Layer == MEDIUM_LAYER) epaisseur=(gint)(epaisseur/1.2);
10269 
10270 			if(epaisseur<3) epaisseur = 3;
10271 
10272 			color2 = geometry[j].Prop.color;
10273     			if (ShadMode) set_color_shad(&color2,j);
10274 			if(geometry[i].typeConnections[nj]>1 && showMultipleBonds)
10275 			{
10276 				gdouble m = 0;
10277 				ab[0] = geometry[j].Yi-geometry[i].Yi;
10278 				ab[1] = -geometry[j].Xi+geometry[i].Xi;
10279 				m = sqrt(ab[0]*ab[0]+ab[1]*ab[1]);
10280 				if(m !=0)
10281 				{
10282 					ab[0] /= m;
10283 					ab[1] /= m;
10284 
10285 				}
10286 			}
10287 			if(geometry[i].typeConnections[nj]==3 && showMultipleBonds)
10288 			{
10289 				gint x1;
10290 				gint x2;
10291 				gint y1;
10292 				gint y2;
10293 
10294 				split[0] = (gint)(ab[0]*(epaisseur+10)/5);
10295 				split[1] = (gint)(ab[1]*(epaisseur+10)/5);
10296 
10297 				x1 = geometry[i].Xi-2*split[0];
10298 				x2 = geometry[j].Xi-2*split[0];
10299 				y1 = geometry[i].Yi-2*split[1];
10300 				y2 = geometry[j].Yi-2*split[1];
10301 				draw_line2(epaisseur/5,i,j,x1,y1, x2, y2, color1,color2,TRUE);
10302 
10303 				x1 = geometry[i].Xi;
10304 				x2 = geometry[j].Xi;
10305 				y1 = geometry[i].Yi;
10306 				y2 = geometry[j].Yi;
10307 				draw_line2(epaisseur/5,i,j,x1,y1, x2, y2, color1,color2,TRUE);
10308 
10309 				x1 = geometry[i].Xi+2*split[0];
10310 				x2 = geometry[j].Xi+2*split[0];
10311 				y1 = geometry[i].Yi+2*split[1];
10312 				y2 = geometry[j].Yi+2*split[1];
10313 				draw_line2(epaisseur/5,i,j,x1,y1, x2, y2, color1,color2,FALSE);
10314 
10315 			}
10316 			else if(geometry[i].typeConnections[nj]==2 && showMultipleBonds)
10317 			{
10318 				gint x1;
10319 				gint x2;
10320 				gint y1;
10321 				gint y2;
10322 
10323 				split[0] = (gint)(ab[0]*(epaisseur+3)/3);
10324 				split[1] = (gint)(ab[1]*(epaisseur+3)/3);
10325 
10326 				x1 = geometry[i].Xi-split[0];
10327 				x2 = geometry[j].Xi-split[0];
10328 				y1 = geometry[i].Yi-split[1];
10329 				y2 = geometry[j].Yi-split[1];
10330 				draw_line2(epaisseur/3,i,j,x1,y1, x2, y2, color1,color2,TRUE);
10331 
10332 				x1 = geometry[i].Xi+split[0];
10333 				x2 = geometry[j].Xi+split[0];
10334 				y1 = geometry[i].Yi+split[1];
10335 				y2 = geometry[j].Yi+split[1];
10336 				draw_line2(epaisseur/3,i,j,x1,y1, x2, y2, color1,color2,FALSE);
10337 			}
10338 			else
10339 			draw_line2(epaisseur,i,j,geometry[i].Xi,geometry[i].Yi,
10340 						geometry[j].Xi,geometry[j].Yi,
10341 						color1,color2,FALSE);
10342         		if((OperationType==CUTBOND || OperationType==CHANGEBOND)
10343 			&& NBatoms==2 && NumBatoms[0]>0 && NumBatoms[1]>0)
10344 			{
10345 				gint na = NumBatoms[0];
10346 				gint nb = NumBatoms[1];
10347 				if(
10348 			    		(na == (gint)geometry[i].N && geometry[i].show &&
10349 			    		nb == (gint)geometry[j].N && geometry[j].show)
10350 					||
10351 			    		(nb == (gint)geometry[i].N && geometry[i].show &&
10352 			    		na == (gint)geometry[j].N && geometry[j].show)
10353 					)
10354 				{
10355 					if(OperationType==CUTBOND)
10356 					draw_line2(epaisseur,i,j,geometry[i].Xi,geometry[i].Yi,
10357 						geometry[j].Xi,geometry[j].Yi,
10358 						colorRed,colorRed,FALSE);
10359 					else
10360 					draw_line2(epaisseur,i,j,geometry[i].Xi,geometry[i].Yi,
10361 						geometry[j].Xi,geometry[j].Yi,
10362 						colorFrag,colorFrag,FALSE);
10363 				}
10364 			}
10365 		}
10366 		else
10367 		{
10368 			k =get_num_min_rayonIJ(i,j);
10369 			epaisseur = get_rayon(k);
10370         		if(OperationType==ADDATOMSBOND
10371 			&& NFatoms==2 && NumFatoms[0]>0 && NumFatoms[1]>0)
10372 			{
10373 				gint na = NumFatoms[0];
10374 				gint nb = NumFatoms[1];
10375 			if(
10376 			    (na == (gint)geometry[i].N && geometry[i].show &&
10377 			    nb == (gint)geometry[j].N && geometry[j].show)
10378 					||
10379 			    (nb == (gint)geometry[i].N && geometry[i].show &&
10380 			    na == (gint)geometry[j].N && geometry[j].show)
10381 					)
10382 			draw_line2(epaisseur,i,j,geometry[i].Xi,geometry[i].Yi,
10383 						geometry[j].Xi,geometry[j].Yi,
10384 						colorFrag,colorFrag,FALSE);
10385 			}
10386 			if(geometry[i].show && geometry[j].show && ShowHBonds && geometry[i].typeConnections[nj]==-1)
10387 			{
10388 				epaisseur = 6;
10389                 		epaisseur*=factorstick;
10390 				color1 = geometry[i].Prop.color;
10391 				color2 = geometry[j].Prop.color;
10392 				draw_line2_hbond(geometry[i].Xi,geometry[i].Yi, geometry[j].Xi,geometry[j].Yi, i,  j,  color1, color2,  epaisseur);
10393 			}
10394 		}
10395     		if (LabelOption != 0) draw_label(5,i);
10396 		if(ShowDipole) for(j = 0;j<NDIVDIPOLE;j++) if(Ndipole[j]==(gint)i) drawGeom_dipole(j);
10397 	}
10398         i=Natoms-1;
10399         rayon = get_rayon(i);
10400 	color1 = geometry[i].Prop.color;
10401     	if (ShadMode) set_color_shad(&color1,i);
10402 
10403 	if(geometry[i].Layer != LOW_LAYER && geometry[i].show)
10404 	{
10405 		draw_ball(geometry[i].Xi,geometry[i].Yi,rayon,color1);
10406 	}
10407 	if((gint)i==NumSelectedAtom && geometry[i].show) draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorRed);
10408 	else
10409 	{
10410 		if(NSA[0]>-1 && (gint)geometry[i].N == NSA[0] && geometry[i].show) draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorRed);
10411 		if(NSA[1]>-1 && (gint)geometry[i].N == NSA[1] && geometry[i].show) draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorGreen);
10412 		if(NSA[2]>-1 && (gint)geometry[i].N == NSA[2] && geometry[i].show) draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorBlue);
10413 		if(NSA[3]>-1 && (gint)geometry[i].N == NSA[2] && geometry[i].show) draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorYellow);
10414 	}
10415 	if(OperationType == MEASURE && geometry[i].show)
10416 	for(j = 0;j<4;j++)
10417 		if(NumSelAtoms[j] == (gint)geometry[i].N )
10418  			draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorGreen);
10419         switch(OperationType)
10420 	{
10421 		case ADDFRAGMENT :
10422 			if(atomToDelete == (gint)geometry[i].N)
10423 	 			draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorRed);
10424 			if(atomToBondTo == (gint)geometry[i].N)
10425 	 			draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorGreen);
10426 			if(angleTo == (gint)geometry[i].N)
10427 	 			draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorBlue);
10428 		break;
10429 		case SELECTOBJECTS :
10430 		case SELECTFRAG :
10431 		case SELECTRESIDUE :
10432 		case DELETEFRAG :
10433 		case DELETEOBJECTS :
10434 		case ROTLOCFRAG :
10435 		case ROTZLOCFRAG :
10436 		case MOVEFRAG :
10437 		for(j = 0;j<NFatoms;j++)
10438 		if(NumFatoms[j] == (gint)geometry[i].N && geometry[i].show)
10439  			draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorFrag);
10440 		break;
10441 		case CUTBOND :
10442 		for(j = 0;j<NBatoms;j++)
10443 		if(NumBatoms[j] == (gint)geometry[i].N && geometry[i].show)
10444  			draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorRed);
10445 		break;
10446 		case CHANGEBOND :
10447 		case ADDATOMSBOND :
10448 		for(j = 0;j<NBatoms;j++)
10449 		if(NumBatoms[j] == (gint)geometry[i].N && geometry[i].show)
10450  			draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorFrag);
10451 		break;
10452 		default :break;
10453 	}
10454 
10455 	if(ShowDipole) for(j = 0;j<NDIVDIPOLE;j++) if(Ndipole[j]==(gint)i) drawGeom_dipole(j);
10456     	if (LabelOption != 0 && geometry[i].show) draw_label(5,i);
10457 
10458 
10459 }
10460 /*****************************************************************************/
redefine_dipole()10461 void redefine_dipole()
10462 {
10463         guint i;
10464         guint j;
10465 
10466 	if(!Ddef)
10467 		return;
10468 	{
10469 		for(i=0;i<NDIVDIPOLE;i++)
10470 			for(j=0;j<3;j++)
10471 				dipole0[i][j] = dipole00[0][j] + (dipole00[i][j]-dipole00[0][j])*factordipole;
10472 	}
10473 }
10474 /*****************************************************************************/
drawGeom_stick()10475 void drawGeom_stick()
10476 {
10477 	guint i;
10478 	guint j;
10479 	guint k;
10480 	gint epaisseur;
10481 	GdkColor color1;
10482 	GdkColor color2;
10483 	GdkColor colorRed;
10484 	GdkColor colorGreen;
10485 	GdkColor colorBlue;
10486 	GdkColor colorYellow;
10487 	GdkColor colorFrag;
10488     	gushort rayon;
10489 	gboolean* FreeAtoms = g_malloc(Natoms*sizeof(gboolean));
10490 	gint ni, nj;
10491 
10492 	colorRed.red   = 40000;
10493 	colorRed.green = 0;
10494 	colorRed.blue  = 0;
10495 	colorRed.pixel  = 0;
10496 
10497 	colorGreen.red   = 0;
10498 	colorGreen.green = 40000;
10499 	colorGreen.blue  = 0;
10500 
10501 	colorBlue.red   = 0;
10502 	colorBlue.green = 0;
10503 	colorBlue.blue  = 40000;
10504 
10505 	colorYellow.red   = 40000;
10506 	colorYellow.green = 40000;
10507 	colorYellow.blue  = 0;
10508 
10509 	colorFrag = colorGreen;
10510 
10511 
10512 	for(i=0;i<Natoms;i++)
10513 	if((gint)i==NumSelectedAtom)
10514 	{
10515 		for(j = 0;j<NFatoms;j++)
10516 		if(NumFatoms[j] == (gint)geometry[i].N) colorFrag = colorRed;
10517 		break;
10518 	}
10519         if(ButtonPressed && OperationType==ROTLOCFRAG) colorFrag = colorRed;
10520         if(ButtonPressed && OperationType==ROTZLOCFRAG) colorFrag = colorRed;
10521 
10522 	for(i=0;i<Natoms;i++) FreeAtoms[i] = TRUE;
10523 
10524 	define_coord_ecran();
10525 
10526 	for(i=0;i<Natoms;i++)
10527         {
10528 		ni = geometry[i].N-1;
10529 		if(!geometry[i].show)
10530 		{
10531 			if(ShowDipole) for(j = 0;j<NDIVDIPOLE;j++) if(Ndipole[j]==(gint)i) drawGeom_dipole(j);
10532 			continue;
10533 		}
10534 		k = -1;
10535 		for(j=i+1, nj = geometry[j].N-1;j<Natoms;j++, nj = geometry[j].N-1)
10536                 if(geometry[i].typeConnections[nj]>0)
10537 		{
10538 			if(!geometry[j].show) continue;
10539 			gint split[2] = {0,0};
10540 			gdouble ab[] = {0,0};
10541 			if(geometry[i].typeConnections[nj]>1 && showMultipleBonds)
10542 			{
10543 				gdouble m = 0;
10544 				ab[0] = geometry[j].Yi-geometry[i].Yi;
10545 				ab[1] = -geometry[j].Xi+geometry[i].Xi;
10546 				m = sqrt(ab[0]*ab[0]+ab[1]*ab[1]);
10547 				if(m !=0)
10548 				{
10549 					ab[0] /= m;
10550 					ab[1] /= m;
10551 
10552 				}
10553 			}
10554 			FreeAtoms[j] = FALSE;
10555 			FreeAtoms[i] = FALSE;
10556 			k =get_num_min_rayonIJ(i,j);
10557 			epaisseur = (gint) (geometry[k].Rayon/2*factorstick);
10558 
10559 			epaisseur = get_epaisseur();
10560 
10561 
10562     			if (PersMode)
10563                		 	epaisseur =(gint)(geometry[k].Coefpers*epaisseur);
10564 			color1 = geometry[i].Prop.color;
10565 			color2 = geometry[j].Prop.color;
10566     			if (ShadMode)
10567 			{
10568 				set_color_shad(&color1,i);
10569 				set_color_shad(&color2,j);
10570 			}
10571 			draw_line2(epaisseur,i,j,geometry[i].Xi,geometry[i].Yi, geometry[j].Xi,geometry[j].Yi, color1,color2,FALSE);
10572 			if(geometry[i].typeConnections[nj]==2 && showMultipleBonds)
10573 			{
10574 				gint x1;
10575 				gint x2;
10576 				gint y1;
10577 				gint y2;
10578 				split[0] = (gint)(ab[0]*epaisseur*1.5);
10579 				split[1] = (gint)(ab[1]*epaisseur*1.5);
10580 
10581 				x1 = geometry[i].Xi-split[0]-split[1];
10582 				y1 = geometry[i].Yi-split[1]+split[0];
10583 				x2 = geometry[j].Xi-split[0]+split[1];
10584 				y2 = geometry[j].Yi-split[1]-split[0];
10585 				draw_line2(epaisseur/3,i,j,x1, y1, x2, y2, color1,color2,TRUE);
10586 			}
10587 			if(geometry[i].typeConnections[nj]==3 && showMultipleBonds)
10588 			{
10589 				gint x1;
10590 				gint x2;
10591 				gint y1;
10592 				gint y2;
10593 				split[0] = (gint)(ab[0]*epaisseur*1.5);
10594 				split[1] = (gint)(ab[1]*epaisseur*1.5);
10595 
10596 				x1 = geometry[i].Xi-split[0]-split[1];
10597 				y1 = geometry[i].Yi-split[1]+split[0];
10598 				x2 = geometry[j].Xi-split[0]+split[1];
10599 				y2 = geometry[j].Yi-split[1]-split[0];
10600 				draw_line2(epaisseur/2,i,j,x1, y1, x2, y2, color1,color2,TRUE);
10601 				x1 = geometry[i].Xi+split[0]-split[1];
10602 				y1 = geometry[i].Yi+split[1]+split[0];
10603 				x2 = geometry[j].Xi+split[0]+split[1];
10604 				y2 = geometry[j].Yi+split[1]-split[0];
10605 				draw_line2(epaisseur/2,i,j,x1, y1, x2, y2, color1,color2,TRUE);
10606 			}
10607         		if((OperationType==CUTBOND || OperationType==CHANGEBOND)
10608 			&& NBatoms==2 && NumBatoms[0]>0 && NumBatoms[1]>0)
10609 			{
10610 				gint na = NumBatoms[0];
10611 				gint nb = NumBatoms[1];
10612 				if(
10613 			    		(na == (gint)geometry[i].N && geometry[i].show &&
10614 			    		nb == (gint)geometry[j].N && geometry[j].show)
10615 					||
10616 			    		(nb == (gint)geometry[i].N && geometry[i].show &&
10617 			    		na == (gint)geometry[j].N && geometry[j].show)
10618 					)
10619 				{
10620 					if(OperationType==CUTBOND)
10621 					draw_line2(epaisseur,i,j,geometry[i].Xi,geometry[i].Yi,
10622 						geometry[j].Xi,geometry[j].Yi,
10623 						colorRed,colorRed,FALSE);
10624 					else
10625 					draw_line2(epaisseur,i,j,geometry[i].Xi,geometry[i].Yi,
10626 						geometry[j].Xi,geometry[j].Yi,
10627 						colorFrag,colorFrag,FALSE);
10628 				}
10629 			}
10630 		}
10631 		else
10632 		{
10633 			k =get_num_min_rayonIJ(i,j);
10634 			epaisseur = (gint) (geometry[k].Rayon/2*factorstick);
10635 			epaisseur = get_epaisseur();
10636     			if (PersMode) epaisseur =(gint)(geometry[k].Coefpers*epaisseur);
10637         		if(OperationType==ADDATOMSBOND && NFatoms==2 && NumFatoms[0]>0 && NumFatoms[1]>0)
10638 			{
10639 				gint na = NumFatoms[0];
10640 				gint nb = NumFatoms[1];
10641 			if(
10642 			    (na == (gint)geometry[i].N && geometry[i].show &&
10643 			    nb == (gint)geometry[j].N && geometry[j].show)
10644 					||
10645 			    (nb == (gint)geometry[i].N && geometry[i].show &&
10646 			    na == (gint)geometry[j].N && geometry[j].show)
10647 					)
10648 			draw_line2(epaisseur,i,j,geometry[i].Xi,geometry[i].Yi,
10649 						geometry[j].Xi,geometry[j].Yi,
10650 						colorFrag,colorFrag,FALSE);
10651 			}
10652 			if(geometry[i].show && geometry[j].show && ShowHBonds && geometry[i].typeConnections[nj]==-1)
10653 			{
10654 				epaisseur = 3;
10655                 		epaisseur*=factorstick;
10656 				color1 = geometry[i].Prop.color;
10657 				color2 = geometry[j].Prop.color;
10658 				draw_line2_hbond(geometry[i].Xi,geometry[i].Yi, geometry[j].Xi,geometry[j].Yi, i,  j,  color1, color2,  epaisseur);
10659 			}
10660 		}
10661 		if(FreeAtoms[i])
10662 		{
10663         		rayon =(gushort)(geometry[i].Rayon*factorball)/2;
10664     			if (PersMode) rayon =(gushort)(geometry[i].Coefpers*geometry[i].Rayon*factorball)/2;
10665 			color1 = geometry[i].Prop.color;
10666     			if (ShadMode) set_color_shad(&color1,i);
10667 			if(rayon<5) rayon = 5;
10668 			draw_ball(geometry[i].Xi,geometry[i].Yi,rayon,color1);
10669 		}
10670 		else
10671 		{
10672         		rayon =(gushort)(geometry[i].Rayon*factorstick)/3;
10673     			if (PersMode) rayon =(gushort)(geometry[i].Coefpers*geometry[i].Rayon*factorstick)/3;
10674 			if(rayon<5) rayon = 5;
10675 		}
10676 		if((gint)i==NumSelectedAtom) draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorRed);
10677 		else
10678 		{
10679 			if(NSA[0]>-1 && (gint)geometry[i].N == NSA[0]) draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorRed);
10680 			if(NSA[1]>-1 && (gint)geometry[i].N == NSA[1]) draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorGreen);
10681 			if(NSA[2]>-1 && (gint)geometry[i].N == NSA[2]) draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorBlue);
10682 			if(NSA[3]>-1 && (gint)geometry[i].N == NSA[3]) draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorYellow);
10683 		}
10684 		if(OperationType == MEASURE)
10685 		for(j = 0;j<4;j++)
10686 		if(NumSelAtoms[j] == (gint)geometry[i].N)
10687 	 		draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorGreen);
10688 
10689         	switch(OperationType)
10690 		{
10691 			case ADDFRAGMENT :
10692 				if(atomToDelete == (gint)geometry[i].N)
10693 	 				draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorRed);
10694 				if(atomToBondTo == (gint)geometry[i].N)
10695 	 				draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorGreen);
10696 				if(angleTo == (gint)geometry[i].N)
10697 	 				draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorBlue);
10698 			break;
10699 			case SELECTOBJECTS :
10700 			case SELECTFRAG :
10701 			case SELECTRESIDUE :
10702 			case DELETEFRAG :
10703 			case DELETEOBJECTS :
10704 			case ROTLOCFRAG :
10705 			case ROTZLOCFRAG :
10706 			case MOVEFRAG :
10707 			for(j = 0;j<NFatoms;j++)
10708 			if(NumFatoms[j] == (gint)geometry[i].N)
10709 	 			draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorFrag);
10710 			break;
10711 			case CUTBOND :
10712 			for(j = 0;j<NBatoms;j++)
10713 			if(NumBatoms[j] == (gint)geometry[i].N)
10714 	 			draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorRed);
10715 			break;
10716 			case CHANGEBOND :
10717 			case ADDATOMSBOND :
10718 			for(j = 0;j<NBatoms;j++)
10719 			if(NumBatoms[j] == (gint)geometry[i].N)
10720 	 			draw_anneau(geometry[i].Xi,geometry[i].Yi,rayon,colorFrag);
10721 			break;
10722 			default : break;
10723 		}
10724 
10725 
10726 
10727 		if(ShowDipole) for(j = 0;j<NDIVDIPOLE;j++) if(Ndipole[j]==(gint)i) drawGeom_dipole(j);
10728     		if (LabelOption != 0) draw_label(5,i);
10729         }
10730     	if (LabelOption != 0 && geometry[Natoms-1].show) draw_label(5,Natoms-1);
10731 	g_free(FreeAtoms);
10732 
10733 }
10734 /*****************************************************************************/
draw_dipole(gint x0,gint y0)10735 void draw_dipole(gint x0,gint y0)
10736 {
10737 	GdkColormap *colormap;
10738         GdkColor color;
10739 	gchar* t;
10740 	gdouble d = 0.0;
10741 	gint i;
10742  	PangoFontDescription *font_desc = pango_font_description_from_string (FontsStyleLabel.fontname);
10743 
10744 	for(i=0;i<3;i++)
10745 		d += Dipole.value[i]*Dipole.value[i];
10746 
10747 	t = g_strdup_printf("%0.3f D",sqrt(d)*AUTODEB);
10748 
10749         color = get_color_string(0);
10750 
10751    	colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
10752 
10753         gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE);
10754 	gdk_gc_set_foreground(gc,&color);
10755 	gabedit_cairo_string(cr, GeomDrawingArea, font_desc, gc, x0,y0,t,TRUE,TRUE);
10756 	if(crExport)
10757 	gabedit_cairo_string(crExport, GeomDrawingArea, font_desc, gc, x0,y0,t,TRUE,TRUE);
10758 
10759 	if(font_desc) pango_font_description_free (font_desc);
10760 
10761 }
10762 /*****************************************************************************/
calcul_ndipole()10763 void calcul_ndipole()
10764 {
10765 	gint i;
10766 	gint j;
10767 
10768 	for (j = 0;j<NDIVDIPOLE;j++)
10769 		Ndipole[j] = 0;
10770 
10771 	for (i = 1;i<(gint)Natoms;i++)
10772 	{
10773 		for (j = 0;j<NDIVDIPOLE;j++)
10774 			if(dipole[j][2]>geometry[i].Z)
10775 				Ndipole[j] = i;
10776 	}
10777 
10778 }
10779 /*****************************************************************************/
drawGeom_dipole(gint i)10780 void drawGeom_dipole(gint i)
10781 {
10782 	gint epaisseur;
10783 	GdkColor color;
10784 
10785     	if(!Ddef) return;
10786 
10787 	epaisseur = (gint) (10*factorstick);
10788         epaisseur = (gint) (epaisseur/2.0);
10789         epaisseur =(gint)(epaisseur*Dipole.radius/0.25);
10790 	if(i<NDIVDIPOLE-1)
10791 	{
10792 	color.red = Dipole.color[0];
10793 	color.green = Dipole.color[1];
10794 	color.blue = Dipole.color[2];
10795 	draw_line(DXi[i],DYi[i],DXi[i+1],DYi[i+1],color,epaisseur,TRUE);
10796 	if(DrawDipole && i==NDIVDIPOLE/2)
10797 	 	draw_dipole(DXi[i],DYi[i]);
10798 	}
10799 	else
10800 	{
10801 		color.red = Dipole.color[0]/1.1;
10802 		color.green = Dipole.color[1]/1.1;
10803 		color.blue = Dipole.color[2]/1.1;
10804  		draw_cercle(DXi[i],DYi[i],epaisseur,color,TRUE, FALSE,FALSE);
10805 	}
10806 }
10807 /*****************************************************************************/
buildRotation()10808 void buildRotation()
10809 {
10810 	gdouble m[4][4];
10811 	build_rotmatrix(m,Quat);
10812 	rotation_geometry_quat(m);
10813 }
10814 /*****************************************************************************/
drawGeom()10815 void drawGeom()
10816 {
10817 	if(!GeomDrawingArea) return;
10818      	pixmap_init(GeomDrawingArea);
10819 
10820 
10821      	if(Natoms<1)
10822 	{
10823 		redraw();
10824 		return;
10825 	}
10826 
10827 	if(strToDraw)
10828 		draw_text(strToDraw);
10829 
10830 	buildRotation();
10831 
10832 
10833        	if (!stick_mode())
10834 		drawGeom_byLayer();
10835 	else
10836    		drawGeom_stick();
10837 
10838 	redraw();
10839 }
10840 /*****************************************************************************/
rafresh_drawing()10841 void rafresh_drawing()
10842 {
10843 
10844 	guint i;
10845 	HideShowMeasure(MeasureIsHide);
10846 	i= gtk_notebook_get_current_page(GTK_NOTEBOOK(NoteBookDraw));
10847 	define_geometry();
10848 	gtk_notebook_remove_page((GtkNotebook *)NoteBookDraw,0);
10849 	vboxmeasure =AddNoteBookPage(NoteBookDraw,_("Measure"));
10850 	AddMeasure(GeomDlg,vboxmeasure);
10851 
10852 	gtk_widget_hide_all(NoteBookDraw);
10853 	gtk_widget_show_all(NoteBookDraw);
10854 	gtk_notebook_set_current_page((GtkNotebook*)NoteBookDraw,i);
10855 
10856 
10857 	drawGeom();
10858 	change_of_center(NULL,NULL);
10859 }
10860 /********************************************************************************/
copyCoordinates2to1(GeomDef * geom1,GeomDef * geom2)10861 static void copyCoordinates2to1(GeomDef *geom1, GeomDef *geom2)
10862 {
10863 	gint i;
10864 	if(!geom1) return;
10865 	if(!geom2) return;
10866 	for (i=0;i<Natoms;i++)
10867 	{
10868 		geom1[i].X = geom2[i].X;
10869 		geom1[i].Y = geom2[i].Y;
10870 		geom1[i].Z = geom2[i].Z;
10871 	}
10872 }
10873 /******************************************************************************/
rafresh_window_geom()10874 void rafresh_window_geom()
10875 {
10876          if(GeomDrawingArea != NULL)
10877          {
10878                 RebuildGeom = TRUE;
10879                 copyCoordinates2to1(geometry, geometry0);
10880                 redraw(GeomDrawingArea);
10881          }
10882 	drawGeom();
10883 
10884      /* rafresh_drawing();*/
10885 }
10886 /*****************************************************************************/
multi_geometry_by_factor(gdouble fa0)10887 void multi_geometry_by_factor(gdouble fa0)
10888 {
10889         guint i;
10890 
10891         for(i=0;i<Natoms;i++)
10892 	{
10893           geometry[i].X *= fa0;
10894           geometry[i].Y *= fa0;
10895           geometry[i].Z *= fa0;
10896 	}
10897 	define_coord_maxmin();
10898 }
10899 /*****************************************************************************/
multi_geometry_by_a0(GtkWidget * win,gpointer d)10900 void multi_geometry_by_a0(GtkWidget *win, gpointer d)
10901 {
10902 	multi_geometry_by_factor(BOHR_TO_ANG);
10903 	drawGeom();
10904 }
10905 /*****************************************************************************/
divide_geometry_by_a0(GtkWidget * win,gpointer d)10906 void divide_geometry_by_a0(GtkWidget *win, gpointer d)
10907 {
10908  multi_geometry_by_factor(1.0/BOHR_TO_ANG);
10909  drawGeom();
10910 }
10911 /*****************************************************************************/
factor_default(GtkWidget * win,gpointer d)10912 void factor_default(GtkWidget *win,gpointer d)
10913 {
10914 	factor =1.0;
10915 	drawGeom();
10916 }
10917 /*****************************************************************************/
factor_stick_default(GtkWidget * win,gpointer d)10918 void factor_stick_default(GtkWidget *win,gpointer d)
10919 {
10920 	factorstick =1.0;
10921 	drawGeom();
10922 }
10923 /*****************************************************************************/
factor_ball_default(GtkWidget * win,gpointer d)10924 void factor_ball_default(GtkWidget *win,gpointer d)
10925 {
10926 	factorball =1.0;
10927 	drawGeom();
10928 }
10929 /*****************************************************************************/
factor_dipole_default(GtkWidget * win,gpointer d)10930 void factor_dipole_default(GtkWidget *win,gpointer d)
10931 {
10932 	factordipole =1.0;
10933 	redefine_dipole();
10934 	drawGeom();
10935 }
10936 /*****************************************************************************/
factor_all_default(GtkWidget * win,gpointer d)10937 void factor_all_default(GtkWidget *win,gpointer d)
10938 {
10939 	factorball =1.0;
10940 	factorstick =1.0;
10941 	factor =1.0;
10942 	factordipole =1.0;
10943 	redefine_dipole();
10944 	SetOperation(NULL,     	CENTER);
10945 }
10946 /*****************************************************************************/
set_back_color_black()10947 void set_back_color_black()
10948 {
10949 
10950 	if(BackColor)
10951         {
10952 		gdk_color_free(BackColor);
10953 		BackColor=NULL;
10954         }
10955         gdk_draw_rectangle (pixmap,
10956                       GeomDrawingArea->style->black_gc,
10957                       TRUE,
10958                       0, 0,
10959                       GeomDrawingArea->allocation.width,
10960                       GeomDrawingArea->allocation.height);
10961         drawGeom();
10962 }
10963 /*****************************************************************************/
set_back_color(GtkColorSelection * Sel,gpointer * d)10964 void set_back_color(GtkColorSelection *Sel,gpointer *d)
10965 {
10966 	GdkColor color;
10967 	GdkColormap *colormap;
10968 
10969 	gtk_color_selection_get_current_color(Sel, &color);
10970 	colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
10971 
10972         BackColor = gdk_color_copy(&color);
10973         gdk_colormap_alloc_color(colormap,&color,FALSE,TRUE);
10974 
10975 	gdk_gc_set_foreground(gc,&color);
10976 
10977         gdk_draw_rectangle (pixmap,
10978                       gc,
10979                       TRUE,
10980                       0, 0,
10981                       GeomDrawingArea->allocation.width,
10982                       GeomDrawingArea->allocation.height);
10983         drawGeom();
10984 
10985 }
10986 /*****************************************************************************/
set_back_color_grey()10987 void set_back_color_grey()
10988 {
10989 	GdkColor color;
10990 	GdkColormap *colormap;
10991 
10992 	color.red = 80*257;
10993 	color.green = 80*257;
10994 	color.blue = 80*257;
10995 	colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
10996 
10997         BackColor = gdk_color_copy(&color);
10998         gdk_colormap_alloc_color(colormap,&color,FALSE,TRUE);
10999 
11000 	gdk_gc_set_foreground(gc,&color);
11001 
11002         gdk_draw_rectangle (pixmap,
11003                       gc,
11004                       TRUE,
11005                       0, 0,
11006                       GeomDrawingArea->allocation.width,
11007                       GeomDrawingArea->allocation.height);
11008         drawGeom();
11009 }
11010 /*****************************************************************************/
set_back_color_default()11011 void set_back_color_default()
11012 {
11013 	static gint first = 0;
11014 	GdkColor color;
11015 	GdkColormap *colormap;
11016 
11017 	if(!BackColor)
11018 	{
11019 		set_back_color_grey();
11020 		return;
11021 	}
11022 	color.red = BackColor->red;
11023 	color.green = BackColor->green;
11024 	color.blue = BackColor->blue;
11025 	colormap  = gdk_drawable_get_colormap(GeomDrawingArea->window);
11026 
11027 	if(first==0)
11028 	{
11029 		g_free(BackColor);
11030 		first = 1;
11031 	}
11032         BackColor = gdk_color_copy(&color);
11033         gdk_colormap_alloc_color(colormap,&color,FALSE,TRUE);
11034 
11035 	gdk_gc_set_foreground(gc,&color);
11036 
11037         gdk_draw_rectangle (pixmap,
11038                       gc,
11039                       TRUE,
11040                       0, 0,
11041                       GeomDrawingArea->allocation.width,
11042                       GeomDrawingArea->allocation.height);
11043         drawGeom();
11044 }
11045 /*****************************************************************************/
open_color_dlg(GtkWidget * win,gpointer * DrawingArea)11046 void open_color_dlg(GtkWidget *win,gpointer *DrawingArea)
11047 {
11048 
11049 	GtkColorSelectionDialog *ColorDlg;
11050 	ColorDlg =
11051 		(GtkColorSelectionDialog *)gtk_color_selection_dialog_new(
11052 		_("Set Background Color"));
11053 	gtk_window_set_modal (GTK_WINDOW (ColorDlg), TRUE);
11054 	gtk_window_set_transient_for(GTK_WINDOW(ColorDlg),GTK_WINDOW(Fenetre));
11055 
11056 	gtk_widget_hide(ColorDlg->help_button);
11057 
11058 	g_signal_connect_swapped(G_OBJECT(ColorDlg->ok_button),"clicked",
11059 		(GCallback)set_back_color,GTK_OBJECT(ColorDlg->colorsel));
11060 
11061 	g_signal_connect_swapped(G_OBJECT(ColorDlg->ok_button),"clicked",
11062 		(GCallback)gtk_widget_destroy,GTK_OBJECT(ColorDlg));
11063 
11064 	g_signal_connect_swapped(G_OBJECT(ColorDlg->cancel_button),"clicked",
11065 		(GCallback)gtk_widget_destroy,GTK_OBJECT(ColorDlg));
11066 
11067 	gtk_widget_show(GTK_WIDGET(ColorDlg));
11068 
11069 }
11070 /*****************************************************************************/
create_drawing_in_box(GtkWidget * box)11071 GtkWidget *create_drawing_in_box(GtkWidget *box)
11072 {
11073     GtkWidget *DrawingArea;
11074 
11075     DrawingArea = gtk_drawing_area_new();
11076     gtk_box_pack_start(GTK_BOX(box), DrawingArea,TRUE,TRUE,0);
11077     gtk_widget_set_size_request(GTK_WIDGET(DrawingArea),400,-1);
11078     gtk_widget_show(DrawingArea);
11079     return DrawingArea;
11080 
11081 }
11082 /*****************************************************************************/
create_drawing_in_table(GtkWidget * Table,gint i,gint j,gint k,gint l)11083 GtkWidget *create_drawing_in_table(GtkWidget *Table,gint i,gint j,gint k,gint l)
11084 {
11085     GtkWidget *DrawingArea;
11086 
11087     DrawingArea = gtk_drawing_area_new();
11088 
11089     gtk_table_attach(GTK_TABLE(Table), DrawingArea, i,j, k,l,
11090                    GTK_FILL | GTK_EXPAND, GTK_EXPAND | GTK_FILL, 0, 0);
11091     gtk_widget_set_size_request(GTK_WIDGET(DrawingArea),400,-1);
11092     gtk_widget_show(DrawingArea);
11093     return DrawingArea;
11094 
11095 }
11096 /*****************************************************************************/
create_frame_in_vbox(gchar * title,GtkWidget * win,GtkWidget * vbox,gboolean type)11097 GtkWidget *create_frame_in_vbox(gchar *title,GtkWidget *win,GtkWidget *vbox,gboolean type)
11098 {
11099   GtkWidget *frame;
11100   frame = gtk_frame_new (title);
11101   gtk_frame_set_shadow_type( GTK_FRAME(frame),GTK_SHADOW_ETCHED_OUT);
11102   g_object_ref (frame);
11103   g_object_set_data_full(G_OBJECT (win), "frame",
11104 	  frame,(GDestroyNotify) g_object_unref);
11105   gtk_container_set_border_width (GTK_CONTAINER (frame), 1);
11106   gtk_box_pack_start(GTK_BOX(vbox), frame,type,type,1);
11107   gtk_widget_show (frame);
11108   return frame;
11109 
11110 }
11111 /*****************************************************************************/
create_vbox_in_hbox(GtkWidget * win,GtkWidget * hbox,gboolean type)11112 GtkWidget *create_vbox_in_hbox(GtkWidget *win,GtkWidget *hbox,gboolean type)
11113 {
11114 	GtkWidget *vbox;
11115 	vbox = gtk_vbox_new (FALSE, 0);
11116 	g_object_ref (vbox);
11117 	g_object_set_data_full(G_OBJECT (win), "vbox", vbox,
11118                             (GDestroyNotify) g_object_unref);
11119 	gtk_widget_show (vbox);
11120 	gtk_box_pack_start (GTK_BOX (hbox), vbox, type, type, 1);
11121 
11122 	return vbox;
11123 }
11124 /*****************************************************************************/
create_hbox_in_vbox(GtkWidget * vbox)11125 GtkWidget *create_hbox_in_vbox(GtkWidget *vbox)
11126 {
11127 	GtkWidget *hbox;
11128 	hbox = gtk_hbox_new (FALSE, 0);
11129 	g_object_ref (hbox);
11130 	gtk_widget_show (hbox);
11131 	gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
11132 	return hbox;
11133 }
11134 /*****************************************************************************/
destroy_drawing_and_children(GtkWidget * win,gpointer data)11135 void destroy_drawing_and_children(GtkWidget *win,gpointer data)
11136 {
11137   destroy_children(GeomDlg);
11138 }
11139 /*****************************************************************************/
destroy_all_drawing(GtkWidget * win)11140 void destroy_all_drawing(GtkWidget *win)
11141 {
11142 
11143   stop_calcul(win, NULL);
11144   while( gtk_events_pending() ) gtk_main_iteration();
11145   geometry  = Free_One_Geom(geometry ,Natoms);
11146   geometry0 = Free_One_Geom(geometry0,Natoms);
11147 
11148   g_free(NumFatoms);
11149   NumFatoms = NULL;
11150   NFatoms = 0;
11151   Natoms = 0;
11152 
11153  gtk_widget_destroy(GeomDrawingArea);
11154  GeomDrawingArea = NULL;
11155  gtk_widget_destroy(GeomDlg);
11156 
11157  if (pixmap) g_object_unref(pixmap);
11158  pixmap = NULL;
11159 
11160  if (cr) cairo_destroy (cr);
11161  cr = NULL;
11162 
11163  if (gc) g_object_unref(gc);
11164  gc = NULL;
11165 
11166  Orig[0] = Orig[1] = Orig[2] = 0.0;
11167 }
11168 /*****************************************************************************/
AddNoteBookPage(GtkWidget * NoteBook,char * label)11169 GtkWidget *AddNoteBookPage(GtkWidget *NoteBook,char *label)
11170 {
11171   GtkWidget *vboxpage;
11172   GtkWidget *Frame;
11173 
11174 
11175   Frame = gtk_frame_new(NULL);
11176   gtk_container_set_border_width(GTK_CONTAINER(Frame), 2);
11177 
11178   gtk_notebook_append_page_menu(GTK_NOTEBOOK(NoteBook),
11179                                 Frame,
11180                                 NULL, NULL);
11181 
11182   g_object_set_data(G_OBJECT (Frame), "Frame", Frame);
11183 
11184   gtk_widget_show(Frame);
11185   vboxpage = create_vbox(Frame);
11186 
11187   return vboxpage;
11188 }
11189 /********************************************************************************/
set_sensitive_stop_button(gboolean sens)11190 void set_sensitive_stop_button(gboolean sens)
11191 {
11192 	if(GeomDrawingArea) gtk_widget_set_sensitive(StopButton, sens);
11193 }
11194 /********************************************************************************************/
stop_calcul(GtkWidget * wi,gpointer data)11195 static void stop_calcul(GtkWidget *wi, gpointer data)
11196 {
11197 	StopCalcul = TRUE;
11198 }
11199 /********************************************************************************/
add_stop_button(GtkWidget * Win,GtkWidget * box)11200 void add_stop_button(GtkWidget *Win, GtkWidget *box)
11201 {
11202   StopButton = gtk_button_new_with_label("Cancel");
11203   gtk_box_pack_start (GTK_BOX (box), StopButton, FALSE, TRUE, 0);
11204   gtk_widget_set_sensitive(StopButton, FALSE);
11205 
11206   g_signal_connect(G_OBJECT(StopButton), "clicked", G_CALLBACK (stop_calcul), NULL);
11207 }
11208 /********************************************************************************/
open_menu(GtkWidget * Win,GdkEvent * event,gpointer Menu)11209 static void open_menu(GtkWidget *Win,  GdkEvent *event, gpointer Menu)
11210 {
11211 	GdkEventButton *bevent;
11212 	bevent = (GdkEventButton *) event;
11213 	popup_menu_geom( bevent->button, bevent->time);
11214 }
11215 /********************************************************************************/
add_menu_button(GtkWidget * Win,GtkWidget * box)11216 static void add_menu_button(GtkWidget *Win, GtkWidget *box)
11217 {
11218 	GtkWidget* menuButton;
11219         menuButton = gtk_button_new_with_label("M");
11220   	gtk_box_pack_start (GTK_BOX (box), menuButton, FALSE, TRUE, 0);
11221 
11222 	g_signal_connect(G_OBJECT(menuButton), "button_press_event",G_CALLBACK(open_menu), NULL);
11223 	gtk_widget_show (menuButton);
11224 }
11225 /********************************************************************************/
create_window_drawing()11226 void create_window_drawing()
11227 {
11228 	GtkWidget *vboxframe;
11229 	GtkWidget *frame;
11230 	GtkWidget *hboxframe;
11231 	GtkWidget *vbox;
11232 	GtkWidget *hbox;
11233 	GtkWidget *hboxoperation;
11234 	GtkWidget *DrawingArea;
11235 	GtkWidget *vboxleft;
11236 	GtkWidget *vboxright;
11237 	GtkWidget *NoteBook;
11238 	GtkWidget *Table;
11239 	GtkWidget *handelbox;
11240 	GtkWidget *Status;
11241 	GtkWidget *VboxWin;
11242 	GtkWidget *hboxtoolbar;
11243   	GtkWidget* handlebox;
11244   	GtkWidget* table;
11245 
11246 	{
11247 		gint i;
11248 		factor=1.0;
11249 		/*
11250 		factorstick=1.0;
11251 		factorball=1.0;
11252 		*/
11253 		factordipole=1.0;
11254 		TransX=0;
11255 		TransY=0;
11256 		SetCosSin();
11257 		Ddef = FALSE;
11258 		AtomToInsert = g_strdup("C");
11259 		for(i=0;i<4;i++) NumSelAtoms[i] = -1;
11260 		TypeGeom =  GABEDIT_TYPEGEOM_STICK;
11261 		ShadMode = FALSE;
11262 		PersMode = FALSE;
11263 		LightMode = FALSE;
11264 		OrtepMode = FALSE;
11265 		CartoonMode = TRUE;
11266 		DrawDistance=FALSE;
11267 		DrawDipole = FALSE;
11268 		StopCalcul = FALSE;
11269 		ShowHBonds = FALSE;
11270 		Frag.NAtoms = 0;
11271 		Frag.Atoms = NULL;
11272 		FragItems = NULL;
11273 		NFrags = 0;
11274 		OperationType = ROTATION ;
11275 	}
11276 
11277 
11278 	geometry = NULL;
11279 	geometry0 = NULL;
11280 	Natoms = 0;
11281 
11282 	NumFatoms = NULL;
11283 	NFatoms = 0;
11284 
11285 	define_geometry();
11286 
11287 	if(Natoms == 0) OperationType = EDITOBJECTS;
11288 
11289 	GeomDlg = NULL ;
11290 	GeomDlg = gtk_window_new(GTK_WINDOW_TOPLEVEL);
11291 	VboxWin = gtk_vbox_new (TRUE, 0);
11292 	gtk_container_add(GTK_CONTAINER(GeomDlg),VboxWin);
11293 	gtk_widget_show(VboxWin);
11294 	gtk_window_set_title(GTK_WINDOW(GeomDlg),_("Gabedit : Draw Geometry "));
11295 	gtk_window_set_transient_for(GTK_WINDOW(GeomDlg),GTK_WINDOW(Fenetre));
11296 
11297 	gtk_window_move(GTK_WINDOW(GeomDlg),0,0);
11298 	init_child(GeomDlg,destroy_all_drawing,_(" Draw Geom. "));
11299 	g_signal_connect(G_OBJECT(GeomDlg),"delete_event",(GCallback)destroy_children,NULL);
11300 
11301 	frame = create_frame_in_vbox(NULL,GeomDlg,VboxWin,TRUE);
11302 	gtk_widget_show (frame);
11303 	vboxframe = create_vbox(frame);
11304 	gtk_widget_show (vboxframe);
11305 
11306 	hboxframe = gtk_hbox_new (FALSE, 0);
11307 	gtk_box_pack_start (GTK_BOX (vboxframe), hboxframe, TRUE, TRUE, 0);
11308 	gtk_widget_show (hboxframe);
11309 
11310 
11311 	/* DrawingArea */
11312 	vbox = create_vbox_in_hbox(frame,hboxframe,TRUE);
11313 	frame = create_frame_in_vbox(NULL,GeomDlg,vbox,TRUE);
11314 	hbox = create_hbox_in_vbox(vbox);
11315 	vbox = create_vbox(frame);
11316 	vboxleft= vbox;
11317 
11318 	vbox = create_vbox_in_hbox(frame,hboxframe,FALSE);
11319 	vboxhandle = vbox;
11320 
11321 	handelbox =gtk_handle_box_new ();
11322 	gtk_handle_box_set_shadow_type(GTK_HANDLE_BOX(handelbox),GTK_SHADOW_NONE);
11323 	gtk_handle_box_set_handle_position  (GTK_HANDLE_BOX(handelbox),GTK_POS_TOP);
11324 	gtk_container_add( GTK_CONTAINER (vbox), handelbox);
11325 	gtk_widget_show (handelbox);
11326 	vbox = gtk_vbox_new (FALSE, 0);
11327 	gtk_container_add( GTK_CONTAINER(handelbox), vbox);
11328 	gtk_widget_show (vbox);
11329 
11330 	vboxright= vbox;
11331 	vbox = vboxleft;
11332 
11333 	/* The Table */
11334 	Table = gtk_table_new(1, 2, FALSE);
11335 	gtk_container_add(GTK_CONTAINER(vbox), Table);
11336 	gtk_widget_show(Table);
11337 
11338 	DrawingArea = create_drawing_in_table(Table,1,2,0,1);
11339 	gtk_widget_set_size_request(GTK_WIDGET(DrawingArea ),(gint)(ScreenHeight*0.5),(gint)(ScreenHeight*0.5));
11340 
11341 	GeomDrawingArea = DrawingArea;
11342 	g_signal_connect(G_OBJECT(GeomDrawingArea),"configure_event", (GCallback)configure_event,NULL);
11343 
11344 	vbox = gtk_vbox_new (FALSE, 0);
11345 	gtk_table_attach(GTK_TABLE(Table), vbox, 0,1, 0,1, GTK_FILL , GTK_FILL, 0, 0);
11346 	gtk_widget_show(vbox);
11347 	add_menu_button(GeomDlg, vbox);
11348 	hboxtoolbar = gtk_hbox_new (FALSE, 0);
11349   	gtk_box_pack_start (GTK_BOX (vbox), hboxtoolbar, TRUE, TRUE, 0);
11350 	gtk_widget_show(hboxtoolbar);
11351 
11352 	gtk_widget_set_events (GeomDrawingArea, GDK_EXPOSURE_MASK
11353 					| GDK_LEAVE_NOTIFY_MASK
11354 					| GDK_CONTROL_MASK
11355 					| GDK_BUTTON_PRESS_MASK
11356 					| GDK_BUTTON_RELEASE_MASK
11357 					| GDK_POINTER_MOTION_MASK
11358 					| GDK_POINTER_MOTION_HINT_MASK);
11359 
11360 
11361 	gtk_widget_realize(GeomDlg);
11362 
11363 	NoteBook = gtk_notebook_new();
11364 	gtk_notebook_set_show_tabs(GTK_NOTEBOOK(NoteBook), FALSE);
11365 	gtk_notebook_set_show_border(GTK_NOTEBOOK(NoteBook), FALSE);
11366 
11367 	NoteBookDraw = NoteBook;
11368 	gtk_box_pack_start(GTK_BOX (vboxright), NoteBook,TRUE, TRUE, 0);
11369 
11370 	vboxmeasure =AddNoteBookPage(NoteBook,_("Measure"));
11371 
11372 
11373 	AddMeasure(GeomDlg,vboxmeasure);
11374 	gtk_widget_show(NoteBook);
11375 	gtk_widget_show_all(vboxmeasure);
11376 	change_of_center(NULL,NULL);
11377 	gtk_widget_show(vboxright);
11378 
11379 
11380   	handlebox = gtk_handle_box_new ();
11381   	gtk_handle_box_set_shadow_type(GTK_HANDLE_BOX(handlebox),GTK_SHADOW_NONE);
11382 	gtk_handle_box_set_handle_position  (GTK_HANDLE_BOX(handlebox),GTK_POS_LEFT);
11383   	gtk_widget_show (handlebox);
11384 	gtk_box_pack_start(GTK_BOX (hbox), handlebox,TRUE, TRUE, 0);
11385 
11386 	table = gtk_table_new(2,2,FALSE);
11387 	gtk_container_add (GTK_CONTAINER (handlebox), table);
11388 	gtk_widget_show(table);
11389 	/* Rotation Status */
11390 	Status = gtk_statusbar_new();
11391 	gtk_table_attach(GTK_TABLE(table),Status,0,1,0,1,
11392 					(GtkAttachOptions)(GTK_FILL | GTK_EXPAND),
11393 					(GtkAttachOptions)(GTK_FILL | GTK_EXPAND),
11394 					1,1);
11395 	idStatusRotation = gtk_statusbar_get_context_id(GTK_STATUSBAR(Status),_("Rotation"));
11396 	StatusRotation = Status;
11397 	gtk_statusbar_pop(GTK_STATUSBAR(StatusRotation),idStatusRotation);
11398 	gtk_statusbar_push(GTK_STATUSBAR(StatusRotation),idStatusRotation,
11399 		_(" Press the Middle mouse button and move your mouse for a \"Rotation\". "));
11400 
11401 
11402 	/* Mode Status */
11403 	Status = gtk_statusbar_new();
11404 	gtk_table_attach(GTK_TABLE(table),Status,1,2,0,1,
11405 					(GtkAttachOptions)(GTK_FILL | GTK_EXPAND),
11406 					(GtkAttachOptions)(GTK_FILL | GTK_EXPAND),
11407 					1,1);
11408 	idStatusPopup= gtk_statusbar_get_context_id(GTK_STATUSBAR(Status),"Ball&Stick");
11409 	StatusPopup = Status;
11410 	gtk_statusbar_pop(GTK_STATUSBAR(StatusPopup),idStatusPopup);
11411 	gtk_statusbar_push(GTK_STATUSBAR(StatusPopup),idStatusPopup,
11412 		_(" Press the Right mouse button for display the popup menu. "));
11413 
11414 	/* Operation Status */
11415 	Status = gtk_statusbar_new();
11416 	hboxoperation = gtk_hbox_new (FALSE, 0);
11417 	gtk_table_attach(GTK_TABLE(table), hboxoperation,0,2,1,2,
11418 					(GtkAttachOptions)(GTK_FILL | GTK_EXPAND),
11419 					(GtkAttachOptions)(GTK_FILL | GTK_EXPAND),
11420 					1,1);
11421 	gtk_box_pack_start (GTK_BOX(hboxoperation),Status, TRUE, TRUE, 1);
11422 
11423 	idStatusOperation = gtk_statusbar_get_context_id(GTK_STATUSBAR(Status),_("Rotation"));
11424 	StatusOperation = Status;
11425 	gtk_statusbar_pop(GTK_STATUSBAR(StatusOperation),idStatusOperation);
11426 	gtk_statusbar_push(GTK_STATUSBAR(StatusOperation),idStatusOperation,
11427 		_(" Press the Left mouse button and move your mouse for a \"Rotation\". "));
11428 
11429 	add_stop_button(GeomDlg, hboxoperation);
11430 	gtk_widget_show_all(hbox);
11431 	gtk_widget_show_all(hboxoperation);
11432 	gtk_widget_show_all(vbox);
11433 
11434 
11435 	gtk_widget_show(frame);
11436 
11437 	if(MeasureIsHide)
11438 	{
11439   		gtk_widget_hide(vboxhandle);
11440 	}
11441 	else
11442 		gtk_widget_show(vboxhandle);
11443 
11444 	gtk_window_set_default_size (GTK_WINDOW(GeomDlg), (gint)(ScreenHeight*0.85), (gint)(ScreenHeight*0.85));
11445 
11446 
11447 	g_object_set_data(G_OBJECT(GeomDlg), "StatusBox",handlebox);
11448 	create_toolbar_and_popup_menu_geom(hboxtoolbar);
11449 
11450 
11451 	/* Evenments */
11452 	g_signal_connect(G_OBJECT(GeomDrawingArea),"expose_event",(GCallback)expose_event,NULL);
11453 	g_signal_connect(G_OBJECT(GeomDrawingArea), "button_press_event",G_CALLBACK(event_dispatcher), NULL);
11454 	g_signal_connect(G_OBJECT(GeomDrawingArea), "motion_notify_event",G_CALLBACK(motion_notify), NULL);
11455 	g_signal_connect(G_OBJECT(GeomDrawingArea), "button_release_event",G_CALLBACK(button_release), NULL);
11456 	g_signal_connect(G_OBJECT (GeomDlg), "key_press_event", (GCallback) set_key_press, GeomDlg);
11457 	g_signal_connect(G_OBJECT (GeomDlg), "key_release_event", (GCallback) set_key_release, NULL);
11458 	gtk_widget_show(GeomDlg);
11459 
11460 	gtk_window_move(GTK_WINDOW(GeomDlg),0,0);
11461 
11462 
11463 	/* set_back_color_black();*/
11464 	/* set_back_color_grey();*/
11465 	set_back_color_default();
11466 	set_icone(GeomDlg);
11467 	if(Natoms == 0) SetOperation(NULL,EDITOBJECTS);
11468 	/*define_good_trans();*/
11469 	setSymmetryPrecision(GeomDlg,"1e-4");
11470 }
11471 /*****************************************************************************/
draw_geometry(GtkWidget * w,gpointer d)11472 void draw_geometry(GtkWidget *w,gpointer d)
11473 {
11474  if(GeomDrawingArea == NULL)
11475           create_window_drawing();
11476  else
11477  {
11478 	gtk_widget_hide(GeomDlg);
11479 	gtk_widget_show(GeomDlg);
11480   	rafresh_drawing();
11481  }
11482 }
11483 /*****************************************************************************/
export_geometry(gchar * fileName,gchar * fileType)11484 void export_geometry(gchar* fileName, gchar* fileType)
11485 {
11486 	if(!fileName) return;
11487 	if(!fileType) return;
11488 	if(!GeomDrawingArea) return;
11489 	if(!strcmp(fileType,"pdf"))
11490 	{
11491 
11492 		cairo_surface_t *surface;
11493 		surface = cairo_pdf_surface_create(fileName, GeomDrawingArea->allocation.width, GeomDrawingArea->allocation.height);
11494 		crExport = cairo_create(surface);
11495 		drawGeom();
11496 		cairo_show_page(crExport);
11497 		cairo_surface_destroy(surface);
11498 		cairo_destroy(crExport);
11499 		crExport = NULL;
11500 		return;
11501 	}
11502 	else
11503 	if(!strcmp(fileType,"ps"))
11504 	{
11505 
11506 		cairo_surface_t *surface;
11507 		surface = cairo_ps_surface_create(fileName, GeomDrawingArea->allocation.width, GeomDrawingArea->allocation.height);
11508 		crExport = cairo_create(surface);
11509 		drawGeom();
11510 		cairo_show_page(crExport);
11511 		cairo_surface_destroy(surface);
11512 		cairo_destroy(crExport);
11513 		crExport = NULL;
11514 		return;
11515 	}
11516 	else
11517 	if(!strcmp(fileType,"eps"))
11518 	{
11519 
11520 		cairo_surface_t *surface;
11521 		surface = cairo_ps_surface_create(fileName, GeomDrawingArea->allocation.width, GeomDrawingArea->allocation.height);
11522 		cairo_ps_surface_set_eps(surface, TRUE);
11523 		crExport = cairo_create(surface);
11524 		drawGeom();
11525 		cairo_show_page(crExport);
11526 		cairo_surface_destroy(surface);
11527 		cairo_destroy(crExport);
11528 		crExport = NULL;
11529 		return;
11530 	}
11531 	else
11532 	if(!strcmp(fileType,"svg"))
11533 	{
11534 
11535 		cairo_surface_t *surface;
11536 		surface = cairo_svg_surface_create(fileName, GeomDrawingArea->allocation.width, GeomDrawingArea->allocation.height);
11537 		crExport = cairo_create(surface);
11538 		drawGeom();
11539 		cairo_show_page(crExport);
11540 		cairo_surface_destroy(surface);
11541 		cairo_destroy(crExport);
11542 		crExport = NULL;
11543 		return;
11544 	}
11545 }
11546 /********************************************************************************/
setSymbolOfselectedAtoms(GtkWidget * button,gpointer data)11547 static void setSymbolOfselectedAtoms(GtkWidget *button,gpointer data)
11548 {
11549 	GtkWidget* winDlg  = (GtkWidget*) g_object_get_data(G_OBJECT (button), "WinDlg");
11550 	gchar* symbol = NULL;
11551 	if(data && (gchar*) data) symbol = (gchar*) data;
11552 	/* fprintf(stderr,"%s\n",symbol);*/
11553 	if(symbol && Natoms>0 && NFatoms>0 && NumFatoms)
11554 	{
11555 		gint k,i;
11556 		for (k=0;k<(gint)NFatoms;k++)
11557 		for (i=0;i<(gint)Natoms;i++)
11558 		{
11559 			if(geometry[i].N== NumFatoms[k])
11560 			{
11561 				if(geometry0[i].Prop.name) g_free(geometry0[i].Prop.name);
11562 				if(geometry0[i].Prop.symbol) g_free(geometry0[i].Prop.symbol);
11563 				geometry0[i].Prop = prop_atom_get(symbol);
11564 				if(geometry[i].Prop.name) g_free(geometry[i].Prop.name);
11565 				if(geometry[i].Prop.symbol) g_free(geometry[i].Prop.symbol);
11566 				geometry[i].Prop = prop_atom_get(symbol);
11567 			}
11568 		}
11569 		reset_all_connections();
11570         	reset_charges_multiplicities();
11571         	drawGeom();
11572         	set_optimal_geom_view();
11573         	create_GeomXYZ_from_draw_grometry();
11574 	}
11575 	gtk_widget_destroy(winDlg);
11576 }
11577 /********************************************************************************/
setSymbolOfselectedAtomsDlg()11578 void setSymbolOfselectedAtomsDlg()
11579 {
11580 	GtkWidget* Table;
11581 	GtkWidget* button;
11582 	GtkWidget* frame;
11583 	guint i;
11584 	guint j;
11585         GtkStyle *button_style;
11586         GtkStyle *style;
11587 
11588 	gchar*** Symb = get_periodic_table();
11589 	GtkWidget* winDlg = gtk_window_new(GTK_WINDOW_TOPLEVEL);
11590 	gtk_window_set_modal(GTK_WINDOW(winDlg),TRUE);
11591 	gtk_window_set_title(GTK_WINDOW(winDlg),_("Select your atom"));
11592 	gtk_window_set_default_size (GTK_WINDOW(winDlg),(gint)(ScreenWidth*0.5),(gint)(ScreenHeight*0.4));
11593 
11594 	frame = gtk_frame_new (NULL);
11595 	gtk_frame_set_shadow_type( GTK_FRAME(frame),GTK_SHADOW_ETCHED_OUT);
11596 	gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
11597 
11598 	gtk_container_add(GTK_CONTAINER(winDlg),frame);
11599 	gtk_widget_show (frame);
11600 
11601 	Table = gtk_table_new(PERIODIC_TABLE_N_ROWS-1,PERIODIC_TABLE_N_COLUMNS,TRUE);
11602 	gtk_container_add(GTK_CONTAINER(frame),Table);
11603 	 button_style = gtk_widget_get_style(winDlg);
11604 
11605 	for ( i = 0;i<PERIODIC_TABLE_N_ROWS-1;i++)
11606 	for ( j = 0;j<PERIODIC_TABLE_N_COLUMNS;j++)
11607 	{
11608 	  if(strcmp(Symb[j][i],"00"))
11609 	  {
11610 	  	button = gtk_button_new_with_label(Symb[j][i]);
11611           	style=set_button_style(button_style,button,Symb[j][i]);
11612 		g_object_set_data(G_OBJECT (button), "WinDlg",winDlg);
11613           	g_signal_connect(G_OBJECT(button), "clicked", (GCallback)setSymbolOfselectedAtoms,(gpointer )Symb[j][i]);
11614 	  	gtk_table_attach(GTK_TABLE(Table),button,j,j+1,i,i+1,
11615 		  (GtkAttachOptions)(GTK_FILL | GTK_EXPAND) ,
11616 		  (GtkAttachOptions)(GTK_FILL | GTK_EXPAND),
11617 		  1,1);
11618 	  }
11619 	}
11620 
11621 	gtk_widget_show_all(winDlg);
11622 }
11623 #endif /* DRAWGEOMGL */
11624