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