48
50
gint current_colour[3];
52
/**********************/
53
/* undelete primitive */
54
/**********************/
55
gint core_undelete(struct model_pak *model, GSList *list)
57
struct core_pak *core;
58
struct shel_pak *shell;
60
g_assert(model != NULL);
61
g_assert(list != NULL);
65
core->status &= ~DELETED;
67
model->cores = g_slist_prepend(model->cores, core);
72
shell->status &= ~DELETED;
73
model->shels = g_slist_prepend(model->shels, core->shell);
76
/* FIXME - this doesnt work */
78
connect_atom_compute(core, model);
81
/* TODO - more fine grained molecule recalc (ie recalc of affected molecules only) */
83
connect_molecules(model);
88
/**********************************/
89
/* flag core and associated shell */
90
/**********************************/
91
void delete_core(struct core_pak *core)
93
core->status |= DELETED;
95
(core->shell)->status |= DELETED;
98
/*********************************/
99
/* delete primitive for one core */
100
/*********************************/
101
void core_delete_single(struct core_pak *core, struct model_pak *model)
105
/* flag the core as deleted */
108
/* remove core references */
109
connect_atom_clear(core, model);
111
/* register the undo */
112
/* TODO - when a model is deleted - flush related undo's to avoid mem leaks */
114
list = g_slist_prepend(list, core);
115
undo_register(model, core_undelete, list);
117
/* remove from lists */
118
model->cores = g_slist_remove(model->cores, core);
120
model->shels = g_slist_remove(model->shels, core->shell);
122
/* TODO - more fine grained molecule recalc (ie recalc of affected molecules only) */
123
connect_molecules(model);
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)
132
g_assert(model != NULL);
134
/* free core reference lists */
135
free_mol_list(model);
137
g_slist_free(model->unique_atom_list);
138
model->unique_atom_list = NULL;
141
free_slist(model->cores);
144
/* redo dependancies */
147
gui_refresh(GUI_MODEL_PROPERTIES);
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)
157
gint flag1=FALSE, flag2=FALSE;
159
GSList *list1, *list2;
160
struct core_pak *core;
161
struct shel_pak *shell;
162
struct bond_pak *bond;
164
g_assert(data != NULL);
166
/* delete flaged cores in list */
171
list1 = g_slist_next(list1);
173
if (core->status & DELETED)
175
#if DEBUG_DELETE_COMMIT
176
printf("Deleting %s core [%p] ...\n", core->label, core);
180
/* flag assoc. shell */
184
shell->status |= DELETED;
187
/* update connectivity */
188
connect_atom_clear(core, data);
189
list2 = data->ubonds;
193
list2 = g_slist_next(list2);
195
if (bond->atom1 == core || bond->atom2 == core)
197
data->ubonds = g_slist_remove(data->ubonds, bond);
202
/* update selection */
203
data->selection = g_slist_remove(data->selection, core);
205
/* delete any labels that reference the deleted core */
206
list2 = data->measure_list;
210
list2 = g_slist_next(list2);
211
if (measure_has_core(core, m))
212
measure_free(m, data);
214
/* update main list */
215
data->cores = g_slist_remove(data->cores, core);
220
/* delete flaged shells in list */
225
list1 = g_slist_next(list1);
227
if (shell->status & DELETED)
230
/* update main list */
231
data->shels = g_slist_remove(data->shels, shell);
237
data->num_atoms = g_slist_length(data->cores);
238
data->num_shells = g_slist_length(data->shels);
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 */
245
/* cope with deleted bonds - expensive, so only do if required */
249
connect_molecules(data);
252
/* refresh net charge calc */
255
/* refresh unique atom list */
256
g_slist_free(data->unique_atom_list);
257
data->unique_atom_list = find_unique(ELEMENT, data);
259
/* refresh widgets */
260
meas_graft_model(data);
261
gui_refresh(GUI_MODEL_PROPERTIES);
263
/* reset functions with static pointers to cores */
51
267
/*********************/
52
268
/* copy an atom core */
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)
979
gint flag, primary, secondary, mov[2];
980
gdouble vec[3], tmp[3], d[3];
982
struct core_pak *comp;
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]);
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)
1003
gui_text_show(ERROR, "region 1 is empty.\n");
1007
/* setup region switching labels */
1008
if (direction == UP)
1011
secondary = REGION2A;
1016
secondary = REGION1A;
1019
/* get fractional depth translation vector */
1020
ARR3SET(vec, data->surface.depth_vec);
1021
vecmat(data->ilatmat, vec);
1023
/* calculate offset to region boundary */
1025
if (direction == DOWN)
1027
VEC3MUL(tmp, data->surface.region[0]);
1032
if (data->surface.region[1] == 0)
1034
VEC3MUL(tmp, data->surface.region[0]);
1038
VEC3MUL(tmp, data->surface.region[1]);
1042
/* if region 2 is empty, just move core to the bottom */
1043
if (data->surface.region[1] == 0.0)
1045
ARR3ADD(core->x, tmp);
1048
ARR3ADD((core->shell)->x, tmp);
1050
atom_colour_scheme(data->colour_scheme, core, data);
1054
/* get coordinates of target atom */
1055
ARR3ADD(tmp, core->x);
1057
#if DEBUG_REGION_SWITCH_ATOM
1058
P3VEC(" translation: ", vec);
1059
P3VEC(" target coords: ", tmp);
1062
/* find the target */
1064
for (list=data->cores ; list ; list=g_slist_next(list))
1068
/* only atoms of the same type need apply */
1069
if (core->atom_code != comp->atom_code)
1072
/* get difference vector */
1073
ARR3SET(d, comp->x);
1076
/* pbc constraint */
1077
while(d[0] < -FRACTION_TOLERANCE)
1081
while(d[1] < -FRACTION_TOLERANCE)
1086
/* test difference vector's magnitude */
1087
if (VEC3MAGSQ(d) < FRACTION_TOLERANCE)
1089
/* change its labelling */
1090
#if DEBUG_REGION_SWITCH_ATOM
1091
printf("Matched core: %p\n", comp);
1093
comp->region = secondary;
1096
(comp->shell)->region = secondary;
1098
atom_colour_scheme(data->colour_scheme, comp, data);
1106
gui_text_show(ERROR, "Failed to find a boundary image.\n");
1110
/* now move selected atom to bottom of region 2 */
1112
VEC3MUL(tmp, (data->surface.region[0] + data->surface.region[1]));
1113
if (direction == UP)
1115
ARR3SUB(core->x, tmp);
1116
core->region = primary;
1118
fractional_clamp(core->x, mov, 2);
1122
ARR3SUB((core->shell)->x, tmp);
1123
ARR2ADD((core->shell)->x, mov);
1124
(core->shell)->region = primary;
1127
atom_colour_scheme(data->colour_scheme, core, data);
1132
/*********************************************/
1133
/* find and record the maximum region number */
1134
/*********************************************/
1135
gint region_max(struct model_pak *mdata)
1139
struct core_pak *core;
1142
for (list=mdata->cores ; list ; list=g_slist_next(list))
1145
if (core->region > max)