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: DrawMolItemMSMS.C,v $ 00013 * $Author: johns $ $Locker: $ $State: Exp $ 00014 * $Revision: 1.52 $ $Date: 2021年10月28日 21:12:15 $ 00015 * 00016 *************************************************************************** 00017 * DESCRIPTION: 00018 * Use a MSMSInterface object to get a surface triangulation information 00019 * There are several rendering options: 00020 * 1) probe radius 00021 * 2) surface density 00022 * 3) "All Atoms" -- should the surface be of the selection or the 00023 * contribution of this selection to the surface of all the atoms? 00024 * 0 == just the selection, 1 == contribution to the all atom surface 00025 * 00026 ***************************************************************************/ 00027 00028 00029 #include <stdio.h> 00030 #include <stdlib.h> 00031 #include "DrawMolecule.h" 00032 #include "DrawMolItem.h" 00033 #include "MSMSInterface.h" 00034 #include "Inform.h" 00035 #include "Scene.h" 00036 00037 void DrawMolItem::draw_msms(float *framepos, int draw_wireframe, int allatoms, float radius, float density) { 00038 int i; 00039 int msms_ok = 1; 00040 00041 // regenerate sphere coordinates if necessary 00042 if (needRegenerate & MOL_REGEN || 00043 needRegenerate & SEL_REGEN || 00044 needRegenerate & REP_REGEN) { 00045 00046 msms.clear(); 00047 // so I need to recalculate the MSMS surface 00048 float *xyzr = new float[4L*mol->nAtoms]; 00049 int *ids = new int[mol->nAtoms]; 00050 int *flgs = NULL; // note: this is NOT ALLOCATED 00051 const float *aradius = mol->radius(); 00052 00053 // Should I compute the surface of all the atoms? 00054 int count = 0; 00055 if (allatoms) { 00056 // no (surface of only the selected atoms) 00057 // get the data for the selected atoms 00058 float r; 00059 for (i=atomSel->firstsel; i <= atomSel->lastsel; i++) { 00060 if (atomSel->on[i]) { 00061 xyzr[4L*count+0] = framepos[3L*i+0]; 00062 xyzr[4L*count+1] = framepos[3L*i+1]; 00063 xyzr[4L*count+2] = framepos[3L*i+2]; 00064 00065 r = aradius[i]; 00066 if (r < 0.2f) 00067 r = 0.2f; // work around an MSMS bug 00068 00069 xyzr[4L*count+3] = r; 00070 ids[count] = i; 00071 count++; 00072 } 00073 } // for 00074 } else { 00075 // yes (contribution of selected atoms to the complete surface) 00076 flgs = atomSel->on; // no translation is needed 00077 float r; 00078 for (i=0; i < mol->nAtoms; i++) { 00079 xyzr[4L*count+0] = framepos[3L*i+0]; 00080 xyzr[4L*count+1] = framepos[3L*i+1]; 00081 xyzr[4L*count+2] = framepos[3L*i+2]; 00082 00083 r = aradius[i]; 00084 if (r < 0.2f) 00085 r = 0.2f; // work around an MSMS bug 00086 00087 xyzr[4L*count+3] = r; 00088 ids[count] = i; 00089 count++; 00090 } 00091 } 00092 00093 // compute the surface 00094 #if defined(_MSC_VER) 00095 msms_ok = (MSMSInterface::COMPUTED == 00096 msms.compute_from_file(radius, density, count, ids, xyzr, flgs)); 00097 #else 00098 if (getenv("VMDMSMSUSEFILE")) { 00099 msms_ok = (MSMSInterface::COMPUTED == 00100 msms.compute_from_file(radius, density, count, ids, xyzr, flgs)); 00101 } else { 00102 msms_ok = (MSMSInterface::COMPUTED == 00103 msms.compute_from_socket(radius, density, count, ids, xyzr, flgs)); 00104 } 00105 #endif 00106 00107 if (!msms_ok) 00108 msgInfo << "Could not compute MSMS surface" << sendmsg; 00109 00110 // do NOT delete flgs as it points to "atomsel->on" 00111 delete [] ids; 00112 delete [] xyzr; 00113 00114 msgInfo << "Done with MSMS surface." << sendmsg; 00115 } 00116 00117 if (msms_ok && msms.faces.num() > 0) { 00118 sprintf(commentBuffer,"Mol[%d] Rep[%d] MSMS", mol->id(), repNumber); 00119 cmdCommentX.putdata(commentBuffer, cmdList); 00120 00121 append(DMATERIALON); 00122 00123 float *v, *c, *n; 00124 int ii, ind, fnum, vnum, vsize; 00125 00126 vnum = msms.coords.num(); 00127 fnum = msms.faces.num(); 00128 vsize = vnum * 3; 00129 00130 v = new float[vsize]; 00131 n = new float[vsize]; 00132 c = new float[vsize]; 00133 00134 for (ii=0; ii<vnum; ii++) { 00135 ind = ii * 3; 00136 v[ind ] = msms.coords[ii].x[0]; // X 00137 v[ind + 1] = msms.coords[ii].x[1]; // Y 00138 v[ind + 2] = msms.coords[ii].x[2]; // Z 00139 } 00140 00141 for (ii=0; ii<vnum; ii++) { 00142 ind = ii * 3; 00143 n[ind ] = msms.norms[ii].x[0]; // X 00144 n[ind + 1] = msms.norms[ii].x[1]; // Y 00145 n[ind + 2] = msms.norms[ii].x[2]; // Z 00146 } 00147 00148 for (ii=0; ii<vnum; ii++) { 00149 ind = ii * 3; 00150 int col = atomColor->color[msms.atomids[ii]]; 00151 const float *fp = scene->color_value(col); 00152 c[ind ] = fp[0]; // Red 00153 c[ind + 1] = fp[1]; // Green 00154 c[ind + 2] = fp[2]; // Blue 00155 } 00156 00157 if (draw_wireframe) { 00158 int lsize = fnum * 6; 00159 int * l = new int[lsize]; 00160 00161 int facecount = 0; 00162 for (ii=0; ii<fnum; ii++) { 00163 // draw the face 00164 ind = facecount * 6; 00165 l[ind ] = msms.faces[ii].vertex[0]; 00166 l[ind + 1] = msms.faces[ii].vertex[1]; 00167 l[ind + 2] = msms.faces[ii].vertex[1]; 00168 l[ind + 3] = msms.faces[ii].vertex[2]; 00169 l[ind + 4] = msms.faces[ii].vertex[2]; 00170 l[ind + 5] = msms.faces[ii].vertex[0]; 00171 facecount++; 00172 } 00173 00174 // Create a wire mesh 00175 cmdLineType.putdata(SOLIDLINE, cmdList); // set line drawing parameters 00176 cmdLineWidth.putdata(1, cmdList); 00177 cmdWireMesh.putdata(v, n, c, vnum, l, fnum*3, cmdList); 00178 delete [] l; 00179 } else { 00180 int fsize = fnum * 3; 00181 int * f = new int[fsize]; 00182 00183 int facecount = 0; 00184 for (ii=0; ii<fnum; ii++) { 00185 // draw the face 00186 ind = facecount * 3; 00187 f[ind ] = msms.faces[ii].vertex[0]; 00188 f[ind + 1] = msms.faces[ii].vertex[1]; 00189 f[ind + 2] = msms.faces[ii].vertex[2]; 00190 00191 facecount++; 00192 } 00193 00194 // Check if we're actively animating this rep in colors or in 00195 // geometry, and only use ACTC if we're going to draw it more than once 00196 if (atomColor->method() == AtomColor::THROB) { 00197 // create a triangle mesh without ACTC stripification 00198 cmdTriMesh.putdata(v, n, c, vnum, f, fnum, 0, cmdList); 00199 } else { 00200 // create a triangle mesh, allowing ACTC to stripify it. 00201 cmdTriMesh.putdata(v, n, c, vnum, f, fnum, 1, cmdList); 00202 } 00203 00204 delete [] f; 00205 } 00206 00207 delete [] v; 00208 delete [] n; 00209 delete [] c; 00210 } 00211 } 00212 00213 00214