Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

DrawMolItemOrbital.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 1995-2011 The Board of Trustees of the           
00004  *cr                        University of Illinois                       
00005  *cr                         All Rights Reserved                        
00006  *cr                                                                   
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: DrawMolItemOrbital.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.46 $       $Date: 2011/03/14 04:35:38 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *   A continuation of rendering types from DrawMolItem
00019  *
00020  *   This file only contains representations for visualizing QM orbital data
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" // need volume data definitions
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" // timers
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   // only recalculate the orbital grid if necessary
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     // XXX this needs to be fixed so that things like the
00070     //     draw multiple frames feature will work correctly for Orbitals
00071     int frame = mol->frame(); // draw currently active 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     // Find the  timestep independent wavefunction ID tag
00081     // by comparing type, spin, and excitation with the
00082     // signatures of existing wavefunctions.
00083     int waveid = mol->qm_data->find_wavef_id_from_gui_specs(
00084                   wavefnctype, wavefncspin, wavefncexcitation);
00085 
00086     // Translate the wavefunction ID into the index the
00087     // wavefunction has in this timestep
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     // Get the orbital index for this timestep from the orbital ID.
00099     int orbindex = ts->qm_timestep->get_orbital_index_from_id(iwave, orbid);
00100 
00101     // Build an Orbital object and prepare to calculate a grid
00102     Orbital *orbital = mol->qm_data->create_orbital(iwave, orbindex, 
00103                                                     ts->pos, ts->qm_timestep);
00104 
00105     // Set the bounding box of the atom coordinates as the grid dimensions
00106     orbital->set_grid_to_bbox(ts->pos, 3.0, gridspacing);
00107 
00108     // XXX needs more testing, can get stuck for certain orbitals
00109 #if 0
00110     // XXX for GPU, we need to only optimize to a stepsize of 4 or more, as
00111     //     otherwise doing this actually slows us down rather than speeding up
00112     //     orbital.find_optimal_grid(0.01, 4, 8);
00113     // 
00114     // optimize: minstep 2, maxstep 8, threshold 0.01
00115     orbital->find_optimal_grid(0.01, 2, 8);
00116 #endif
00117 
00118     // Calculate the molecular orbital
00119     orbital->calculate_mo(mol, density);
00120 
00121     motime = wkf_timer_timenow(timer);
00122 
00123     // query orbital grid origin, dimensions, and axes 
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     // build a VolumetricData object for rendering
00131     char dataname[64];
00132     sprintf(dataname, "molecular orbital %i", orbid);
00133 
00134     // update attributes of cached orbital grid
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(); // calc gradients: smooth vertex normals
00151 
00152     gradtime = wkf_timer_timenow(timer);
00153   } // regen the orbital grid...
00154 
00155 
00156   // draw the newly created VolumetricData object 
00157   sprintf(commentBuffer, "MoleculeID: %d ReprID: %d Beginning Orbital",
00158           mol->id(), repNumber);
00159   cmdCommentX.putdata(commentBuffer, cmdList);
00160 
00161   if (drawbox > 0) {
00162     // don't texture the box if color by volume is active
00163     if (atomColor->method() == AtomColor::VOLUME) {
00164       append(DVOLTEXOFF);
00165     }
00166     // wireframe only?  or solid?
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         // shaded points isosurface looping over X-axis, 1 point per voxel
00181         draw_volume_isosurface_lit_points(orbvol, isovalue, stepsize, thickness);
00182         break;
00183 
00184       case 2:
00185         // points isosurface looping over X-axis, max of 1 point per voxel
00186         draw_volume_isosurface_points(orbvol, isovalue, stepsize, thickness);
00187         break;
00188 
00189       case 1:
00190         // lines implementation, max of 18 line per voxel (3-per triangle)
00191         draw_volume_isosurface_lines(orbvol, isovalue, stepsize, thickness);
00192         break;
00193 
00194       case 0:
00195       default:
00196         // trimesh polygonalized surface, max of 6 triangles per voxel
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 

Generated on Sat May 26 01:47:56 2012 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002