00001 /*************************************************************************** 00002 *cr 00003 *cr (C) Copyright 1995-2019 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: Surf.C,v $ 00013 * $Author: johns $ $Locker: $ $State: Exp $ 00014 * $Revision: 1.51 $ $Date: 2019年01月17日 21:21:02 $ 00015 * 00016 *************************************************************************** 00017 * DESCRIPTION: 00018 * This file implements the VMD interface to the 'Surf' molecular surface 00019 * compuatation program. 00020 ***************************************************************************/ 00021 00022 #include <stdio.h> 00023 #include <stdlib.h> 00024 #include <string.h> 00025 #include <math.h> 00026 #include "Surf.h" 00027 #include "Inform.h" 00028 #include "utilities.h" // needed for vmd_getuid, vmd_delete_file, etc 00029 00030 // max length to allocate for filenames 00031 #define VMD_FILENAME_MAX 1024 00032 00033 Surf::Surf() {} 00034 00035 int Surf::compute(float probe_r, int num, float *r, 00036 float *x, float *y, float *z) { 00037 FILE *outfile; // atom coords and radii we send to Surf 00038 FILE *infile; // surface geometry we get back from Surf 00039 char *surfbin; // location of the Surf executable 00040 char *surfcmd; // Surf command string we actually execute 00041 static int surf_firsttime = 1; // flag used to print Surf citation 00042 00043 if ((surfbin = getenv("SURF_BIN")) == NULL) { 00044 msgErr << "No SURF binary found; set the SURF_BIN environment variable" 00045 << sendmsg; 00046 msgErr << "to the location of your SURF executable." << sendmsg; 00047 return 0; // failure 00048 } 00049 00050 // 00051 // construct the temp filenames we'll use for the coord/radii file 00052 // we send to Surf and the triangulated surface file we get back 00053 // 00054 char *dirname = vmd_tempfile(""); 00055 char *ofilename = new char[VMD_FILENAME_MAX]; 00056 char *ifilename = new char[VMD_FILENAME_MAX]; 00057 int rndnum = (vmd_random() % 999); 00058 sprintf(ofilename, "%svmdsurf.u%d.%d.in", dirname, vmd_getuid(), rndnum); 00059 sprintf(ifilename, "%svmdsurf.u%d.%d.in.tri", dirname, vmd_getuid(), rndnum); 00060 delete [] dirname; 00061 vmd_delete_file(ofilename); 00062 vmd_delete_file(ifilename); 00063 00064 // 00065 // write atom coordinates and radii to the file we send to Surf 00066 // 00067 if ((outfile=fopen(ofilename, "wt")) == NULL) { 00068 msgErr << "Failed to create Surf atom radii input file" << sendmsg; 00069 if (ofilename) delete [] ofilename; 00070 if (ifilename) delete [] ifilename; 00071 return 0; // failure 00072 } 00073 for (int i=0; i<num; i++) { 00074 fprintf(outfile, "%d %f %f %f %f\n", i, r[i], x[i], y[i], z[i]); 00075 } 00076 fclose(outfile); 00077 00078 // 00079 // call Surf to calculate the surface for the given atoms 00080 // 00081 if ((surfcmd = new char[strlen(ofilename) + strlen(surfbin) + 82])) { 00082 sprintf(surfcmd, "\"%s\" -W 1 -R %f %s", surfbin, probe_r, ofilename); 00083 vmd_system(surfcmd); 00084 delete [] surfcmd; 00085 00086 // print Surf citation the first time it is used in a VMD session 00087 if (surf_firsttime == 1) { 00088 surf_firsttime = 0; 00089 msgInfo << "This surface is made with SURF from UNC-Chapel Hill." 00090 << " The reference is:" << sendmsg; 00091 msgInfo << "A. Varshney, F. P. Brooks, W. V. Wright, " 00092 << "Linearly Scalable Computation" << sendmsg; 00093 msgInfo << "of Smooth Molecular Surfaces, " 00094 << "IEEE Comp. Graphics and Applications, " << sendmsg; 00095 msgInfo << "v. 14 (1994) pp. 19-25." << sendmsg; 00096 } 00097 } 00098 00099 // 00100 // read the triangulated surface data 00101 // 00102 if ((infile = fopen(ifilename, "r")) == NULL) { 00103 msgErr << "Cannot read SURF output file: " << ifilename << sendmsg; 00104 00105 // Return cleanly, deleting temp files and so on. 00106 vmd_delete_file(ofilename); 00107 vmd_delete_file(ifilename); 00108 if (ofilename) delete [] ofilename; 00109 if (ifilename) delete [] ifilename; 00110 return 0; // failed 00111 } 00112 00113 msgInfo << "Reading Surf geometry output file..." << sendmsg; 00114 numtriangles = 0; // no triangles read yet 00115 int vertnum = 0; // no vertices read yet 00116 int atmindex; // atom index this triangle goes with 00117 float vn[18]; // vertex and normal data 00118 00119 // read in Surf geometry one triangle at a time 00120 // Each triangle is 18 floats, 3 x (3 coord values, 3 normal values) 00121 while (fscanf(infile, 00122 "%d%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f", 00123 &atmindex, 00124 vn, vn+1, vn+2, vn+3, vn+4, vn+5, 00125 vn+6, vn+7, vn+8, vn+9,vn+10,vn+11, 00126 vn+12,vn+13,vn+14,vn+15,vn+16,vn+17) == 19) { 00127 if (!tri_degenerate(&vn[0], &vn[3], &vn[6])) { 00128 ind.append(atmindex); // add new atom index into triangle->atom map 00129 00130 f.append(vertnum); // add new vertex indices into facet list 00131 vertnum++; 00132 f.append(vertnum); // add new vertex indices into facet list 00133 vertnum++; 00134 f.append(vertnum); // add new vertex indices into facet list 00135 vertnum++; 00136 numtriangles++; // total number of triangles added so far. 00137 00138 // add new vertices and normals into vertex and normal lists 00139 v.append3x3(&vn[0], &vn[6], &vn[12]); // v0, v1, v2 00140 n.append3x3(&vn[3], &vn[9], &vn[15]); // n0, n1, n2 00141 } 00142 } 00143 fclose(infile); // file has been read in completely 00144 00145 // Return cleanly, deleting temp files and so on. 00146 vmd_delete_file(ofilename); 00147 vmd_delete_file(ifilename); 00148 if (ifilename) delete [] ifilename; 00149 if (ofilename) delete [] ofilename; 00150 00151 msgInfo << "Read Surf output file, processing geometry..." << sendmsg; 00152 00153 return 1; // success 00154 } 00155 00156 void Surf::clear() { 00157 numtriangles=0; 00158 v.clear(); 00159 n.clear(); 00160 f.clear(); 00161 ind.clear(); 00162 } 00163