00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <math.h>
00023 #include <stdlib.h>
00024 #include <stdio.h>
00025
00026 #include "DrawMolItem.h"
00027 #include "DrawMolecule.h"
00028 #include "BaseMolecule.h"
00029 #include "Inform.h"
00030 #include "Isosurface.h"
00031 #include "MoleculeList.h"
00032 #include "Scene.h"
00033 #include "Orbital.h"
00034 #include "QMData.h"
00035 #include "VolumetricData.h"
00036 #include "VMDApp.h"
00037 #include "utilities.h"
00038 #include "WKFUtils.h"
00039
00040 #define MYSGN(a) (((a) > 0) ? 1 : -1)
00041
00042 void DrawMolItem::draw_orbital(int density, int wavefnctype, int wavefncspin,
00043 int wavefncexcitation, int orbid,
00044 float isovalue,
00045 int drawbox, int style,
00046 float gridspacing, int stepsize, int thickness) {
00047 if (!mol->numframes() || gridspacing <= 0.0f)
00048 return;
00049
00050
00051 int regenorbital=0;
00052 if (density != orbgridisdensity ||
00053 wavefnctype != waveftype ||
00054 wavefncspin != wavefspin ||
00055 wavefncexcitation != wavefexcitation ||
00056 orbid != gridorbid ||
00057 gridspacing != orbgridspacing ||
00058 orbvol == NULL ||
00059 needRegenerate & MOL_REGEN ||
00060 needRegenerate & SEL_REGEN) {
00061 regenorbital=1;
00062 }
00063
00064 double motime=0, voltime=0, gradtime=0;
00065 wkf_timerhandle timer = wkf_timer_create();
00066 wkf_timer_start(timer);
00067
00068 if (regenorbital) {
00069
00070
00071 int frame = mol->frame();
00072 const Timestep *ts = mol->get_frame(frame);
00073
00074 if (!ts->qm_timestep || !mol->qm_data ||
00075 !mol->qm_data->num_basis || orbid < 1) {
00076 wkf_timer_destroy(timer);
00077 return;
00078 }
00079
00080
00081
00082
00083 int waveid = mol->qm_data->find_wavef_id_from_gui_specs(
00084 wavefnctype, wavefncspin, wavefncexcitation);
00085
00086
00087
00088 int iwave = ts->qm_timestep->get_wavef_index(waveid);
00089
00090 if (iwave<0 ||
00091 !ts->qm_timestep->get_wavecoeffs(iwave) ||
00092 !ts->qm_timestep->get_num_orbitals(iwave) ||
00093 orbid > ts->qm_timestep->get_num_orbitals(iwave)) {
00094 wkf_timer_destroy(timer);
00095 return;
00096 }
00097
00098
00099 int orbindex = ts->qm_timestep->get_orbital_index_from_id(iwave, orbid);
00100
00101
00102 Orbital *orbital = mol->qm_data->create_orbital(iwave, orbindex,
00103 ts->pos, ts->qm_timestep);
00104
00105
00106 orbital->set_grid_to_bbox(ts->pos, 3.0, gridspacing);
00107
00108
00109 #if 0
00110
00111
00112
00113
00114
00115 orbital->find_optimal_grid(0.01, 2, 8);
00116 #endif
00117
00118
00119 orbital->calculate_mo(mol, density);
00120
00121 motime = wkf_timer_timenow(timer);
00122
00123
00124 const int *numvoxels = orbital->get_numvoxels();
00125 const float *origin = orbital->get_origin();
00126
00127 float xaxis[3], yaxis[3], zaxis[3];
00128 orbital->get_grid_axes(xaxis, yaxis, zaxis);
00129
00130
00131 char dataname[64];
00132 sprintf(dataname, "molecular orbital %i", orbid);
00133
00134
00135 orbgridisdensity = density;
00136 waveftype = wavefnctype;
00137 wavefspin = wavefncspin;
00138 wavefexcitation = wavefncexcitation;
00139 gridorbid = orbid;
00140 orbgridspacing = gridspacing;
00141 delete orbvol;
00142 orbvol = new VolumetricData(dataname, origin,
00143 xaxis, yaxis, zaxis,
00144 numvoxels[0], numvoxels[1], numvoxels[2],
00145 orbital->get_grid_data());
00146 delete orbital;
00147
00148 voltime = wkf_timer_timenow(timer);
00149
00150 orbvol->compute_volume_gradient();
00151
00152 gradtime = wkf_timer_timenow(timer);
00153 }
00154
00155
00156
00157 sprintf(commentBuffer, "MoleculeID: %d ReprID: %d Beginning Orbital",
00158 mol->id(), repNumber);
00159 cmdCommentX.putdata(commentBuffer, cmdList);
00160
00161 if (drawbox > 0) {
00162
00163 if (atomColor->method() == AtomColor::VOLUME) {
00164 append(DVOLTEXOFF);
00165 }
00166
00167 if (style > 0 || drawbox == 2) {
00168 draw_volume_box_lines(orbvol);
00169 } else {
00170 draw_volume_box_solid(orbvol);
00171 }
00172 if (atomColor->method() == AtomColor::VOLUME) {
00173 append(DVOLTEXON);
00174 }
00175 }
00176
00177 if ((drawbox == 2) || (drawbox == 0)) {
00178 switch (style) {
00179 case 3:
00180
00181 draw_volume_isosurface_lit_points(orbvol, isovalue, stepsize, thickness);
00182 break;
00183
00184 case 2:
00185
00186 draw_volume_isosurface_points(orbvol, isovalue, stepsize, thickness);
00187 break;
00188
00189 case 1:
00190
00191 draw_volume_isosurface_lines(orbvol, isovalue, stepsize, thickness);
00192 break;
00193
00194 case 0:
00195 default:
00196
00197 draw_volume_isosurface_trimesh(orbvol, isovalue, stepsize);
00198 break;
00199 }
00200 }
00201
00202 #if 0
00203 if (regenorbital) {
00204 double surftime = wkf_timer_timenow(timer);
00205 char strmsg[1024];
00206 sprintf(strmsg, "Total MO rep time: %.3f [MO: %.3f vol: %.3f grad: %.3f surf: %.2f]",
00207 wkf_timer_time(timer), motime, voltime - motime, gradtime - motime, surftime - gradtime);
00208
00209 msgInfo << strmsg << sendmsg;
00210 }
00211 #endif
00212
00213 wkf_timer_destroy(timer);
00214 }
00215