~ubuntu-branches/ubuntu/raring/gdis/raring-proposed

« back to all changes in this revision

Viewing changes to edit.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Leidert (dale)
  • Date: 2009-04-06 17:12:18 UTC
  • mfrom: (3.1.3 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090406171218-uizoe126jrq09ytt
Tags: 0.90-1
* New upstream release 0.90.
* Acknowledge NMU (closes: #492994). Thanks to Neil Williams.

* makefile.debian: Upstream doesn't provide a Makefile to edit - so created
  our own.
* debian/compat: Added and set to be 5.
* debian/control: Added Homepage, Vcs* and DM-Upload-Allowed fields.
  (Maintainer): Set to the debichem team with approval by Noèl.
  (Uploaders): Added myself.
  (Build-Depends): Increased debhelper version to 5. Removed glutg3-dev.
  Added dpatch.
  (Standards-Version): Bumped to 3.8.1.
  (Description): Removed homepage. Fixed a typo.
* debian/copyright: Updated, completed and adjusted.
* debian/dirs: Dropped useless file.
* debian/docs: Renamed to debian/gdis.docs.
* debian/menu: Renamed to debian/gdis.menu.
  (section): Fixed accordingly to policy.
* debian/gdis.1: Just some formatting changes.
* debian/gdis.desktop: Added file (with small fixes) provided by Phill Bull
  (LP: #111353).
* debian/gdis.install: Added.
* debian/rules: Cleaned. Installation is now done by dh_install. Make sure,
  the CVS directory is not copied. Added dh_desktop call.
* debian/source.lintian-overrides: makefile.debian is created for Debian but
  lives outside debian/.
* debian/watch: Added.
* debian/README.build: Dropped.
* debian/README.source: Added to be compliant to the policy v3.8.
* debian/patches/Debian_make.dpatch: Added.
  - gdis.h (ELEM_FILE): Moved fix for gdis.elemts path (#399132) to this
    patch.
* debian/patches/00list: Added.

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
#include "coords.h"
34
34
#include "edit.h"
35
35
#include "matrix.h"
 
36
#include "measure.h"
36
37
#include "opengl.h"
37
38
#include "render.h"
38
39
#include "select.h"
39
 
#include "shortcuts.h"
 
40
#include "gui_shorts.h"
40
41
#include "interface.h"
41
42
#include "zone.h"
 
43
#include "undo.h"
42
44
 
43
45
#define DEBUG 0
44
46
 
47
49
 
48
50
gint current_colour[3];
49
51
 
 
52
/**********************/
 
53
/* undelete primitive */
 
54
/**********************/
 
55
gint core_undelete(struct model_pak *model, GSList *list)
 
56
{
 
57
struct core_pak *core;
 
58
struct shel_pak *shell;
 
59
 
 
60
g_assert(model != NULL);
 
61
g_assert(list != NULL);
 
62
 
 
63
core = list->data;
 
64
 
 
65
core->status &= ~DELETED;
 
66
 
 
67
model->cores = g_slist_prepend(model->cores, core);
 
68
if (core->shell)
 
69
  {
 
70
  shell = core->shell;
 
71
 
 
72
  shell->status &= ~DELETED;
 
73
  model->shels = g_slist_prepend(model->shels, core->shell);
 
74
  }
 
75
 
 
76
/* FIXME - this doesnt work */
 
77
/*
 
78
connect_atom_compute(core, model);
 
79
*/
 
80
 
 
81
/* TODO - more fine grained molecule recalc (ie recalc of affected molecules only) */
 
82
connect_bonds(model);
 
83
connect_molecules(model);
 
84
 
 
85
return(TRUE);
 
86
}
 
87
 
 
88
/**********************************/
 
89
/* flag core and associated shell */
 
90
/**********************************/
 
91
void delete_core(struct core_pak *core)
 
92
{
 
93
core->status |= DELETED;
 
94
if (core->shell)
 
95
  (core->shell)->status |= DELETED;
 
96
}
 
97
 
 
98
/*********************************/
 
99
/* delete primitive for one core */
 
100
/*********************************/
 
101
void core_delete_single(struct core_pak *core, struct model_pak *model)
 
102
{
 
103
GSList *list;
 
104
 
 
105
/* flag the core as deleted */
 
106
delete_core(core);
 
107
 
 
108
/* remove core references */
 
109
connect_atom_clear(core, model);
 
110
 
 
111
/* register the undo */
 
112
/* TODO - when a model is deleted - flush related undo's to avoid mem leaks */
 
113
list = NULL;
 
114
list = g_slist_prepend(list, core);
 
115
undo_register(model, core_undelete, list);
 
116
 
 
117
/* remove from lists */
 
118
model->cores = g_slist_remove(model->cores, core);
 
119
if (core->shell)
 
120
  model->shels = g_slist_remove(model->shels, core->shell);
 
121
 
 
122
/* TODO - more fine grained molecule recalc (ie recalc of affected molecules only) */
 
123
connect_molecules(model);
 
124
}
 
125
 
 
126
/*********************************/
 
127
/* remove all cores from a model */
 
128
/*********************************/
 
129
/* NB: leave symmetry / pbc structure intact */
 
130
void core_delete_all(struct model_pak *model)
 
131
{
 
132
g_assert(model != NULL);
 
133
 
 
134
/* free core reference lists */
 
135
free_mol_list(model);
 
136
wipe_bonds(model);
 
137
g_slist_free(model->unique_atom_list);
 
138
model->unique_atom_list = NULL;
 
139
 
 
140
/* free cores */
 
141
free_slist(model->cores);
 
142
model->cores = NULL;
 
143
 
 
144
/* redo dependancies */
 
145
zone_init(model);
 
146
calc_emp(model);
 
147
gui_refresh(GUI_MODEL_PROPERTIES);
 
148
model->state = 0;
 
149
}
 
150
 
 
151
/*******************************************************/
 
152
/* permanently remove all deleted cores from all lists */
 
153
/*******************************************************/
 
154
#define DEBUG_DELETE_COMMIT 0
 
155
void delete_commit(struct model_pak *data)
 
156
{
 
157
gint flag1=FALSE, flag2=FALSE;
 
158
gpointer m;
 
159
GSList *list1, *list2;
 
160
struct core_pak *core;
 
161
struct shel_pak *shell;
 
162
struct bond_pak *bond;
 
163
 
 
164
g_assert(data != NULL);
 
165
 
 
166
/* delete flaged cores in list */
 
167
list1 = data->cores;
 
168
while (list1)
 
169
  {
 
170
  core = list1->data;
 
171
  list1 = g_slist_next(list1);
 
172
 
 
173
  if (core->status & DELETED)
 
174
    {
 
175
#if DEBUG_DELETE_COMMIT
 
176
printf("Deleting %s core [%p] ...\n", core->label, core);
 
177
#endif
 
178
    flag1 = TRUE;
 
179
 
 
180
/* flag assoc. shell */
 
181
    if (core->shell)
 
182
      {
 
183
      shell = core->shell;
 
184
      shell->status |= DELETED;
 
185
      }
 
186
 
 
187
/* update connectivity */
 
188
    connect_atom_clear(core, data);
 
189
    list2 = data->ubonds;
 
190
    while (list2)
 
191
      {
 
192
      bond = list2->data;
 
193
      list2 = g_slist_next(list2);
 
194
 
 
195
      if (bond->atom1 == core || bond->atom2 == core)
 
196
        {
 
197
        data->ubonds = g_slist_remove(data->ubonds, bond);
 
198
        g_free(bond);
 
199
        }
 
200
      }
 
201
 
 
202
/* update selection */
 
203
    data->selection = g_slist_remove(data->selection, core);
 
204
 
 
205
/* delete any labels that reference the deleted core */
 
206
    list2 = data->measure_list;
 
207
    while (list2)
 
208
      {
 
209
      m = list2->data;
 
210
      list2 = g_slist_next(list2);
 
211
      if (measure_has_core(core, m))
 
212
        measure_free(m, data);
 
213
      }
 
214
/* update main list */
 
215
    data->cores = g_slist_remove(data->cores, core);
 
216
    g_free(core);
 
217
    }
 
218
  }
 
219
 
 
220
/* delete flaged shells in list */
 
221
list1 = data->shels;
 
222
while (list1)
 
223
  {
 
224
  shell = list1->data;
 
225
  list1 = g_slist_next(list1);
 
226
 
 
227
  if (shell->status & DELETED)
 
228
    {
 
229
    flag2 = TRUE;
 
230
/* update main list */
 
231
    data->shels = g_slist_remove(data->shels, shell);
 
232
    g_free(shell);
 
233
    }
 
234
  }
 
235
 
 
236
/* refresh totals */
 
237
data->num_atoms = g_slist_length(data->cores);
 
238
data->num_shells = g_slist_length(data->shels);
 
239
 
 
240
/* refresh spatial partitioning */
 
241
/* it's probably best to refresh the partitioning here, rather than */
 
242
/* incrementally as it's speedups for large models we're targeting */
 
243
zone_init(data);
 
244
 
 
245
/* cope with deleted bonds - expensive, so only do if required */
 
246
if (flag1)
 
247
  {
 
248
  connect_bonds(data);
 
249
  connect_molecules(data);
 
250
  }
 
251
 
 
252
/* refresh net charge calc */
 
253
calc_emp(data);
 
254
 
 
255
/* refresh unique atom list */
 
256
g_slist_free(data->unique_atom_list);
 
257
data->unique_atom_list = find_unique(ELEMENT, data);
 
258
 
 
259
/* refresh widgets */
 
260
meas_graft_model(data);
 
261
gui_refresh(GUI_MODEL_PROPERTIES);
 
262
 
 
263
/* reset functions with static pointers to cores */
 
264
data->state = 0;
 
265
}
50
266
 
51
267
/*********************/
52
268
/* copy an atom core */
129
345
core->primary_core = NULL;
130
346
 
131
347
/* duplicate strings */
132
 
core->atom_label = g_strdup(orig->atom_label);
133
 
core->atom_type = g_strdup(orig->atom_type);
134
 
core->res_name = g_strdup(orig->res_name);
135
 
core->flags = g_strdup(orig->flags);
 
348
if (orig->atom_label)
 
349
  core->atom_label = g_strdup(orig->atom_label);
 
350
if (orig->atom_type)
 
351
  core->atom_type = g_strdup(orig->atom_type);
 
352
if (orig->res_name)
 
353
  core->res_name = g_strdup(orig->res_name);
 
354
if (orig->flags)
 
355
  core->flags = g_strdup(orig->flags);
136
356
 
137
357
core->vibx_list = NULL;
138
358
core->viby_list = NULL;
191
411
core->atom_code = code;
192
412
core->atom_type = NULL;
193
413
core->atom_label = NULL;
194
 
core->res_name = g_strdup("");
 
414
core->res_name = NULL;
195
415
core->res_no = 1;
196
416
core->chain = NULL;
197
417
core->atom_order = 0;
198
418
 
 
419
/* default values for NMR values */
 
420
core->atom_nmr_shift=0.0;
 
421
core->atom_nmr_aniso=0.0;
 
422
core->atom_nmr_asym=0.0;
 
423
core->atom_nmr_cq=0.0;
 
424
core->atom_nmr_efgasym=0.0;
 
425
 
199
426
/* element related initialization */
200
427
get_elem_data(code, &elem_data, model);
201
428
core->bond_cutoff = elem_data.cova;
385
612
void delete_duplicate_cores(struct model_pak *model)
386
613
{
387
614
gdouble vec[3];
388
 
GSList *list1, *list2;
 
615
GSList *list1, *list2, *za_list;
389
616
gpointer zone;
390
617
struct core_pak *core1, *core2;
391
618
struct shel_pak *s1, *s2;
409
636
/* enumerate cores in current locality */
410
637
  zone = zone_get(core1->x, model->zone_array);
411
638
 
412
 
 
413
639
#if DEBUG_REMOVE_DUPLICATES_MORE
414
640
printf(" + %s [%p] : [%p] :", core1->atom_label, core1, zone);
415
641
P3VEC(" ", core1->x);
420
646
  for (list2=zone_cores(zone) ; list2 ; list2=g_slist_next(list2))
421
647
*/
422
648
 
423
 
 
424
 
  for (list2=zone_area_cores(1, zone, model->zone_array) ; list2 ; list2=g_slist_next(list2))
425
 
 
 
649
  za_list = zone_area_cores(1, zone, model->zone_array);
 
650
  for (list2=za_list ; list2 ; list2=g_slist_next(list2))
426
651
    {
427
652
    core2 = list2->data;
428
653
    if (core2->status & DELETED)
444
669
    ARR3SET(vec, core1->x);
445
670
    ARR3SUB(vec, core2->x);
446
671
 
447
 
    fractional_minsq(vec, model->periodic);
 
672
    fractional_min(vec, model->periodic);
448
673
 
449
674
    if (VEC3MAGSQ(vec) < FRACTION_TOLERANCE)
450
675
      {
469
694
        }
470
695
      }
471
696
    }
 
697
  g_slist_free(za_list);
472
698
  }
473
699
 
474
700
/* commit before searching for duplicate shells, as a commit */
496
722
    ARR3SUB(vec, s2->x);
497
723
 
498
724
/* adjust for periodicity */
499
 
    fractional_minsq(vec, model->periodic);
 
725
    fractional_min(vec, model->periodic);
500
726
 
501
727
    if (VEC3MAGSQ(vec) < FRACTION_TOLERANCE)
502
728
      {
517
743
}
518
744
 
519
745
/********************************************************/
520
 
/* set vector to minimum fractional magnitute (squared) */
 
746
/* set vector to minimum fractional offset (-0.5 - 0.5) */
521
747
/********************************************************/
522
748
#define DEBUG_FRAC_MINSQ 0
523
 
void fractional_minsq(gdouble *x, gint dim)
 
749
void fractional_min(gdouble *x, gint dim)
524
750
{
525
751
gint i, j;
526
752
gdouble whole;
546
772
#endif
547
773
}
548
774
 
549
 
/*************************************/
550
 
/* clamp coords to fractional limits */
551
 
/*************************************/
 
775
/*************************************************/
 
776
/* clamp coords to fractional limits [0.0 - 1.0) */
 
777
/*************************************************/
552
778
#define DEBUG_CLAMP 0
553
779
void fractional_clamp(gdouble *vec, gint *mov, gint dim)
554
780
{
589
815
/********************************************/
590
816
/* confine a list of atoms to the unit cell */
591
817
/********************************************/
592
 
#define DEBUG_PBC_ATOMS 0
593
818
void coords_confine_cores(GSList *cores, struct model_pak *model)
594
819
{
595
 
gint xlat[3];
596
 
gdouble mov[3];
 
820
gint dummy[3];
 
821
gdouble x[3];
597
822
GSList *list;
598
823
struct core_pak *core;
599
824
struct shel_pak *shell;
607
832
for (list=cores ; list ; list=g_slist_next(list))
608
833
  {
609
834
  core = list->data;
610
 
  fractional_clamp(core->x, xlat, model->periodic);
 
835
  fractional_clamp(core->x, dummy, model->periodic);
611
836
 
612
837
/* move shell */
613
838
  if (core->shell)
614
839
    {
615
840
    shell = core->shell;
616
 
    ARR3SET(mov, xlat);
617
 
    ARR3ADD(shell->x, mov);
 
841
 
 
842
/* want core-shell distance to be smallest possible */
 
843
    ARR3SET(x, shell->x);
 
844
    ARR3SUB(x, core->x);
 
845
    fractional_min(x, model->periodic);
 
846
    ARR3SET(shell->x, core->x);
 
847
    ARR3ADD(shell->x, x);
618
848
    }
619
849
  }
620
850
}
738
968
return(0);
739
969
}
740
970
 
 
971
/*************************************************************/
 
972
/* region changing routine - for dealing with polar surfaces */
 
973
/*************************************************************/
 
974
/* can now go both ways via the direction flag (UP or DOWN) */
 
975
#define DEBUG_REGION_SWITCH_ATOM 0
 
976
gint region_move_atom(struct core_pak *core, gint direction,
 
977
                                    struct model_pak *data)
 
978
{
 
979
gint flag, primary, secondary, mov[2];
 
980
gdouble vec[3], tmp[3], d[3];
 
981
GSList *list;
 
982
struct core_pak *comp;
 
983
 
 
984
#if DEBUG_REGION_SWITCH_ATOM
 
985
printf("       model: %s\n", data->basename);
 
986
printf(" periodicity: %d\n", data->periodic);
 
987
printf("         hkl: %f %f %f\n", data->surface.miller[0],
 
988
          data->surface.miller[1], data->surface.miller[2]);
 
989
printf("        dhkl: %f\n", data->surface.dspacing);
 
990
printf("region sizes: %f %f\n", data->surface.region[0], data->surface.region[1]);
 
991
printf("      moving: ");
 
992
if (direction == UP)
 
993
  printf("UP\n");
 
994
else
 
995
  printf("DOWN\n");
 
996
#endif
 
997
 
 
998
/* checks */
 
999
g_return_val_if_fail(data != NULL, 1);
 
1000
g_return_val_if_fail(data->periodic == 2, 1);
 
1001
if (data->surface.region[0] < 1)
 
1002
  {
 
1003
  gui_text_show(ERROR, "region 1 is empty.\n");
 
1004
  return(1);
 
1005
  }
 
1006
 
 
1007
/* setup region switching labels */
 
1008
if (direction == UP)
 
1009
  {
 
1010
  primary = REGION1A;
 
1011
  secondary = REGION2A;
 
1012
  }
 
1013
else
 
1014
  {
 
1015
  primary = REGION2A;
 
1016
  secondary = REGION1A;
 
1017
  }
 
1018
 
 
1019
/* get fractional depth translation vector */
 
1020
ARR3SET(vec, data->surface.depth_vec);
 
1021
vecmat(data->ilatmat, vec);
 
1022
 
 
1023
/* calculate offset to region boundary */
 
1024
ARR3SET(tmp, vec);
 
1025
if (direction == DOWN)
 
1026
  {
 
1027
  VEC3MUL(tmp, data->surface.region[0]);
 
1028
  VEC3MUL(tmp, -1.0);
 
1029
  }
 
1030
else
 
1031
  {
 
1032
  if (data->surface.region[1] == 0)
 
1033
    {
 
1034
    VEC3MUL(tmp, data->surface.region[0]);
 
1035
    }
 
1036
  else
 
1037
    {
 
1038
    VEC3MUL(tmp, data->surface.region[1]);
 
1039
    }
 
1040
  }
 
1041
 
 
1042
/* if region 2 is empty, just move core to the bottom */
 
1043
if (data->surface.region[1] == 0.0)
 
1044
  {
 
1045
  ARR3ADD(core->x, tmp);
 
1046
  if (core->shell)
 
1047
    {
 
1048
    ARR3ADD((core->shell)->x, tmp);
 
1049
    }
 
1050
  atom_colour_scheme(data->colour_scheme, core, data);
 
1051
  return(0);
 
1052
  }
 
1053
 
 
1054
/* get coordinates of target atom */
 
1055
ARR3ADD(tmp, core->x);
 
1056
 
 
1057
#if DEBUG_REGION_SWITCH_ATOM
 
1058
P3VEC("    translation: ", vec);
 
1059
P3VEC("  target coords: ", tmp);
 
1060
#endif
 
1061
 
 
1062
/* find the target */
 
1063
flag=0;
 
1064
for (list=data->cores ; list ; list=g_slist_next(list))
 
1065
  {
 
1066
  comp = list->data;
 
1067
 
 
1068
/* only atoms of the same type need apply */
 
1069
  if (core->atom_code != comp->atom_code)
 
1070
    continue;
 
1071
 
 
1072
/* get difference vector */
 
1073
  ARR3SET(d, comp->x);
 
1074
  ARR3SUB(d, tmp);
 
1075
 
 
1076
/* pbc constraint */
 
1077
  while(d[0] < -FRACTION_TOLERANCE)
 
1078
    d[0] += 1.0;
 
1079
  while(d[0] > 0.5)
 
1080
    d[0] -= 1.0;
 
1081
  while(d[1] < -FRACTION_TOLERANCE)
 
1082
    d[1] += 1.0;
 
1083
  while(d[1] > 0.5)
 
1084
    d[1] -= 1.0;
 
1085
 
 
1086
/* test difference vector's magnitude */
 
1087
  if (VEC3MAGSQ(d) < FRACTION_TOLERANCE)
 
1088
    {
 
1089
/* change its labelling */
 
1090
#if DEBUG_REGION_SWITCH_ATOM
 
1091
printf("Matched core: %p\n", comp);
 
1092
#endif
 
1093
    comp->region = secondary;
 
1094
    if (comp->shell)
 
1095
      {
 
1096
      (comp->shell)->region = secondary;
 
1097
      }
 
1098
    atom_colour_scheme(data->colour_scheme, comp, data);
 
1099
    flag++;
 
1100
    break;
 
1101
    }
 
1102
  }
 
1103
 
 
1104
if (!flag)
 
1105
  {
 
1106
  gui_text_show(ERROR, "Failed to find a boundary image.\n");
 
1107
  return(1);
 
1108
  }
 
1109
 
 
1110
/* now move selected atom to bottom of region 2 */
 
1111
ARR3SET(tmp, vec);
 
1112
VEC3MUL(tmp, (data->surface.region[0] + data->surface.region[1]));
 
1113
if (direction == UP)
 
1114
  VEC3MUL(tmp, -1.0);
 
1115
ARR3SUB(core->x, tmp);
 
1116
core->region = primary;
 
1117
/* pbc constrain */
 
1118
fractional_clamp(core->x, mov, 2);
 
1119
 
 
1120
if (core->shell)
 
1121
  {
 
1122
  ARR3SUB((core->shell)->x, tmp);
 
1123
  ARR2ADD((core->shell)->x, mov);
 
1124
  (core->shell)->region = primary;
 
1125
  }
 
1126
 
 
1127
atom_colour_scheme(data->colour_scheme, core, data);
 
1128
 
 
1129
return(0);
 
1130
}
 
1131
 
 
1132
/*********************************************/
 
1133
/* find and record the maximum region number */
 
1134
/*********************************************/
 
1135
gint region_max(struct model_pak *mdata)
 
1136
{
 
1137
gint max;
 
1138
GSList *list;
 
1139
struct core_pak *core;
 
1140
 
 
1141
max = 0;
 
1142
for (list=mdata->cores ; list ; list=g_slist_next(list))
 
1143
  {
 
1144
  core = list->data;
 
1145
  if (core->region > max)
 
1146
    max = core->region;
 
1147
  }
 
1148
return(max);
 
1149
}
 
1150