This is MolShape.m in view mode; [Download] [Up]
/* MolShape.m - Copyright 1993 Steve Ludtke */ /* This object does the actual molecule rendering (except for quick mode) */ /* ball and stick mode is still quite primitive */ /* I should probably change the flags from numbers to #defined strings ... */ #import "Mtypes.h" #import "MolShape.h" #import <ri/ri.h> #import <math.h> #define SC .05 #define SCP1 SC/1.732 #define SCP2 SC/.866 #define SCP3 SC/2.45 #define SCP4 SC/1.633-SCP3 @implementation MolShape:N3DShape - renderSelf:(RtToken)context { int i,j,n,ln; float x,y,z,r,d,lx,ly,lz; /* a big square for a white background */ static RtPoint bsquare[4]= {{-200.0,-200.0,-40.0},{200.0,-200.0,-40.0},{200.0,200.0,-40.0},{-200.0,200.0,-40.0}}; static RtPoint square[4]= {{0.0,0.0,0.0},{1.0,0.0,0.0},{1.0,1.0,0.0},{0.0,1.0,0.0}}; static RtColor bgCol = {1.0,1.0,1.0}; static RtColor stCol = {.4,.4,.4}; static RtColor bCol = { 0,0,0 }; static RtColor dCol = { .95,.95,.95 }; static RtColor cCol; static RtColor selCol = { 0.0,0.0,0.0 }; char *tmap = "/users/steve/grid.tex"; if (mode==4) return self; /* quick mode, do nothing */ if (mode==12) mode=11; /* quick mode, but we want to print, so render */ /* RiMakeTexture("/users/steve/grid.tiff","/users/steve/grid.tex", RI_PERIODIC,RI_PERIODIC,RiGaussianFilter,1,1,RI_NULL); */ RiDeclare("texname","uniform string"); RiColor(dCol); /* if (nmol!=0 && mol[0].numaa>2) { RiTransformBegin(); RiTranslate(10.2,4.3,0.0); RiScale(10.0,10.0,1.0); RiSurface("texmap",(RtToken)"texname",(RtPointer)&tmap,RI_NULL); RiPolygon(4,RI_P,(RtPointer)square,RI_NULL); RiSurface("constant",RI_NULL); RiColor(bCol); RiTranslate(mol[0].am[1].phi/(2.0*M_PI)+.5, mol[0].am[1].psi/(2.0*M_PI)+.5,0.0); RiSphere(.05,-.05,.05,360.0,RI_NULL); RiTransformEnd(); }*/ RiSurface("constant",RI_NULL); if (mode>=8) { RiColor(bgCol); RiPolygon(4,RI_P,(RtPointer)bsquare,RI_NULL); } RiRotate(chi,0,1.0,0); RiRotate(theta,1.0,0,0.0); RiRotate(phi,0,1.0,0); /* metal is ok too ... */ RiSurface("plastic",RI_NULL); RiColor(dCol); /* stick mode */ if ((flags&3)==0) { RiColor(stCol); for (i=0; i<nmol; i++) { if (mol[i].numlb==0) continue; /* RiPointsLines(mol[i].numlb,mol[i].nverts,mol[i].verts ,RI_P,mol[i].coord,RI_NULL); */ for (j=0; j<mol[i].numlb; j++) { if (j%20==0) { RiSynchronize( RI_FLUSH ); RiSynchronize( RI_WAIT ); } n=mol[i].lb[j].n1; ln=mol[i].lb[j].n2; x=mol[i].coord[n][0]; y=mol[i].coord[n][1]; z=mol[i].coord[n][2]; lx=mol[i].coord[ln][0]-x; ly=mol[i].coord[ln][1]-y; lz=mol[i].coord[ln][2]-z; r=sqrt(SQR(lx)+SQR(ly)+SQR(lz)); d=acos(sqrt(SQR(lx)+SQR(ly))/r); if (lz<0.0) d*=-1.0; d=90.0-d/DRC; RiTransformBegin(); RiTranslate(x,y,z); RiRotate(-d,ly,-lx,0.0); /* cylinder 1 */ if (mol[i].atom[n].sel) RiColor(selCol); /* selected black */ else if (flags&4) { d=mol[i].atom[n].charge; if (d<0.0) { cCol[2]=1.0; cCol[0]=cCol[1]=1.0+d; } if (d>=0.0) { cCol[0]=1.0; cCol[1]=cCol[2]=1.0-d; } RiColor(cCol); } else RiColor(elinfo[mol[i].atom[n].anum].color); RiCylinder(BSR,0.0,r/2.0,360.0,RI_NULL); /* cylinder 2 */ if (mol[i].atom[ln].sel) RiColor(selCol); /* selected black */ else if (flags&4) { d=mol[i].atom[ln].charge; if (d<0.0) { cCol[2]=1.0; cCol[0]=cCol[1]=1.0+d; } if (d>=0.0) { cCol[0]=1.0; cCol[1]=cCol[2]=1.0-d; } RiColor(cCol); } else RiColor(elinfo[mol[i].atom[ln].anum].color); RiCylinder(BSR,r/2.0,r,360.0,RI_NULL); RiTransformEnd(); } } } /* ball and stick mode */ else if ((flags&3)==1) { for (i=0; i<nmol; i++) { if ((mode&3)>=2) RiColor(dCol); else RiColor(dCol); ln=-1; /* no ellipticity info. Just spheres are faster */ if (mol[i].ell==NULL) { for (j=0; j<mol[i].numa; j++) { if (j%20==0) { RiSynchronize( RI_FLUSH ); RiSynchronize( RI_WAIT ); } x=mol[i].coord[j][0]; y=mol[i].coord[j][1]; z=mol[i].coord[j][2]; n=mol[i].atom[j].anum; r=elinfo[n].rad/BSS; if (flags&4) { d=mol[i].atom[j].charge; if (d<0.0) { cCol[2]=1.0; cCol[0]=cCol[1]=1.0+d; } if (d>=0.0) { cCol[0]=1.0; cCol[1]=cCol[2]=1.0-d; } RiColor(cCol); } else if (n!=ln) RiColor(elinfo[n].color); ln=n; if (mol[i].atom[j].sel) { RiColor(selCol); ln=-1; } RiTransformBegin(); RiTranslate(x,y,z); RiSphere(r,-r,r,360.0,RI_NULL); RiTransformEnd(); } RiColor(stCol); for (j=0; j<mol[i].numlb; j++) { if (j%20==0) { RiSynchronize( RI_FLUSH ); RiSynchronize( RI_WAIT ); } n=mol[i].lb[j].n1; ln=mol[i].lb[j].n2; x=mol[i].coord[n][0]; y=mol[i].coord[n][1]; z=mol[i].coord[n][2]; lx=mol[i].coord[ln][0]-x; ly=mol[i].coord[ln][1]-y; lz=mol[i].coord[ln][2]-z; r=sqrt(SQR(lx)+SQR(ly)+SQR(lz)); d=acos(sqrt(SQR(lx)+SQR(ly))/r); if (lz<0.0) d*=-1.0; d=90.0-d/DRC; RiTransformBegin(); RiTranslate(x,y,z); RiRotate(-d,ly,-lx,0.0); RiCylinder(BSR,0.0,r,360.0,RI_NULL); RiTransformEnd(); } } /* Draw ellipsoids instead of spheres (otherwise identical) */ else { for (j=0; j<mol[i].numa; j++) { if (j%20==0) { RiSynchronize( RI_FLUSH ); RiSynchronize( RI_WAIT ); } x=mol[i].coord[j][0]; y=mol[i].coord[j][1]; z=mol[i].coord[j][2]; n=mol[i].atom[j].anum; if (flags&4) { d=mol[i].atom[j].charge; if (d<0.0) { cCol[2]=1.0; cCol[0]=cCol[1]=1.0+d; } if (d>=0.0) { cCol[0]=1.0; cCol[1]=cCol[2]=1.0-d; } RiColor(cCol); } else if (n!=ln) RiColor(elinfo[n].color); ln=n; if (mol[i].atom[j].sel) { RiColor(selCol); ln=-1; } RiTransformBegin(); RiTranslate(x,y,z); RiRotate(mol[i].ell[j].dz,0.0,0.0,1.0); RiRotate(mol[i].ell[j].dx,1.0,0.0,0.0); RiRotate(mol[i].ell[j].dz2,0.0,0.0,1.0); RiScale(mol[i].ell[j].x/BSS,mol[i].ell[j].y/BSS, mol[i].ell[j].z/BSS); RiSphere(1.0,-1.0,1.0,360.0,RI_NULL); RiTransformEnd(); } RiColor(stCol); for (j=0; j<mol[i].numlb; j++) { if (j%20==0) { RiSynchronize( RI_FLUSH ); RiSynchronize( RI_WAIT ); } n=mol[i].lb[j].n1; ln=mol[i].lb[j].n2; x=mol[i].coord[n][0]; y=mol[i].coord[n][1]; z=mol[i].coord[n][2]; lx=mol[i].coord[ln][0]-x; ly=mol[i].coord[ln][1]-y; lz=mol[i].coord[ln][2]-z; r=sqrt(SQR(lx)+SQR(ly)+SQR(lz)); d=acos(sqrt(SQR(lx)+SQR(ly))/r); if (lz<0.0) d*=-1.0; d=90.0-d/DRC; RiTransformBegin(); RiTranslate(x,y,z); RiRotate(-d,ly,-lx,0.0); RiCylinder(BSR,0.0,r,360.0,RI_NULL); RiTransformEnd(); } } } } /* space filling mode */ else if ((flags&3)==2) { lx=ly=lz=0; for (i=0; i<nmol; i++) { if ((mode&3)>=2) RiColor(dCol); else RiColor(dCol); ln=-1; /* no ellipsoids */ if (mol[i].ell==NULL) { for (j=0; j<mol[i].numa; j++) { if (j%20==0) { RiSynchronize( RI_FLUSH ); RiSynchronize( RI_WAIT ); } x=mol[i].coord[j][0]; y=mol[i].coord[j][1]; z=mol[i].coord[j][2]; n=mol[i].atom[j].anum; r=elinfo[n].rad; if (flags&4) { d=mol[i].atom[j].charge; if (d<0.0) { cCol[2]=1.0; cCol[0]=cCol[1]=1.0+d; } if (d>=0.0) { cCol[0]=1.0; cCol[1]=cCol[2]=1.0-d; } RiColor(cCol); } else if (n!=ln) RiColor(elinfo[n].color); ln=n; if (mol[i].atom[j].sel) { RiColor(selCol); ln=-1; } RiTranslate(x-lx,y-ly,z-lz); RiSphere(r,-r,r,360.0,RI_NULL); if (r==0.0) printf("%d %d %f %f %f\n",j,n,x,y,z); lx=x; ly=y; lz=z; } } /* Ellipsoids */ else { for (j=0; j<mol[i].numa; j++) { if (j%20==0) { RiSynchronize( RI_FLUSH ); RiSynchronize( RI_WAIT ); } x=mol[i].coord[j][0]; y=mol[i].coord[j][1]; z=mol[i].coord[j][2]; n=mol[i].atom[j].anum; r=elinfo[n].rad; if (flags&4) { d=mol[i].atom[j].charge; if (d<0.0) { cCol[2]=1.0; cCol[0]=cCol[1]=1.0+d; } if (d>=0.0) { cCol[0]=1.0; cCol[1]=cCol[2]=1.0-d; } RiColor(cCol); } else if (n!=ln) RiColor(elinfo[n].color); ln=n; if (mol[i].atom[j].sel) { RiColor(selCol); ln=-1; } RiTransformBegin(); RiTranslate(x,y,z); RiRotate(mol[i].ell[j].dz,0.0,0.0,1.0); RiRotate(mol[i].ell[j].dx,1.0,0.0,0.0); RiRotate(mol[i].ell[j].dz2,0.0,0.0,1.0); RiScale(mol[i].ell[j].x,mol[i].ell[j].y,mol[i].ell[j].z); RiSphere(1.0,-1.0,1.0,360.0,RI_NULL); lx=x; ly=y; lz=z; RiTransformEnd(); } } } } return self; } -setData:(Molecule *)Mol :(int)Nmol :(struct ELINFO *)Elinfo :(int)Mode :(int)Flags { mol=Mol; nmol=Nmol; elinfo=Elinfo; mode=Mode; flags=Flags; return self; } -setAng:(float)Theta :(float)Chi :(float)Phi { theta=Theta/DRC; chi=Chi/DRC; phi=Phi/DRC; return self; } - setSurfaceType:(N3DSurfaceType)st andDescendants:(BOOL)flag { [super setSurfaceType:st andDescendants:flag]; return self; } -setBSSR:(float)bss :(float)bsr { BSS=bss; BSR=bsr; if (BSS<=0.0) BSS=1.0; if (BSR<=0.0) BSR=0.1; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.