/*************************************************************************** * RasMol 2.7.5 * * * * RasMol * * Molecular Graphics Visualisation Tool * * 13 June 2009 * * * * Based on RasMol 2.6 by Roger Sayle * * Biomolecular Structures Group, Glaxo Wellcome Research & Development, * * Stevenage, Hertfordshire, UK * * Version 2.6, August 1995, Version 2.6.4, December 1998 * * Copyright (C) Roger Sayle 1992-1999 * * * * and Based on Mods by * *Author Version, Date Copyright * *Arne Mueller RasMol 2.6x1 May 98 (C) Arne Mueller 1998 * *Gary Grossman and RasMol 2.5-ucb Nov 95 (C) UC Regents/ModularCHEM * *Marco Molinaro RasMol 2.6-ucb Nov 96 Consortium 1995, 1996 * * * *Philippe Valadon RasTop 1.3 Aug 00 (C) Philippe Valadon 2000 * * * *Herbert J. RasMol 2.7.0 Mar 99 (C) Herbert J. Bernstein * *Bernstein RasMol 2.7.1 Jun 99 1998-2008 * * RasMol 2.7.1.1 Jan 01 * * RasMol 2.7.2 Aug 00 * * RasMol 2.7.2.1 Apr 01 * * RasMol 2.7.2.1.1 Jan 04 * * RasMol 2.7.3 Feb 05 * * RasMol 2.7.3.1 Apr 06 * * RasMol 2.7.4 Nov 07 * * RasMol 2.7.4.1 Jan 08 * * RasMol 2.7.4.2 Mar 08 * * RasMol 2.7.5 May 09 * * * * RasMol 2.7.5 incorporates changes by T. Ikonen, G. McQuillan, N. Darakev* * and L. Andrews (via the neartree package). Work on RasMol 2.7.5 * * supported in part by grant 1R15GM078077-01 from the National Institute * * of General Medical Sciences (NIGMS), U.S. National Institutes of Health * * and by grant ER63601-1021466-0009501 from the Office of Biological & * * Environmental Research (BER), Office of Science, U. S. Department of * * Energy. RasMol 2.7.4 incorporated changes by G. Todorov, Nan Jia, * * N. Darakev, P. Kamburov, G. McQuillan, and J. Jemilawon. Work on RasMol * * 2.7.4 supported in part by grant 1R15GM078077-01 from the NIGMS/NIH and * * grant ER63601-1021466-0009501 from BER/DOE. RasMol 2.7.3 incorporates * * changes by Clarice Chigbo, Ricky Chachra, and Mamoru Yamanishi. Work * * on RasMol 2.7.3 supported in part by grants DBI-0203064, DBI-0315281 * * and EF-0312612 from the U.S. National Science Foundation and grant * * DE-FG02-03ER63601 from BER/DOE. The content is solely the responsibility* * of the authors and does not necessarily represent the official views of * * the funding organizations. * * * * The code for use of RasMol under GTK in RasMol 2.7.4.2 and 2.7.5 was * * written by Teemu Ikonen. * * * * and Incorporating Translations by * * Author Item Language * * Isabel Servan Martinez, * * Jose Miguel Fernandez Fernandez 2.6 Manual Spanish * * Jose Miguel Fernandez Fernandez 2.7.1 Manual Spanish * * Fernando Gabriel Ranea 2.7.1 menus and messages Spanish * * Jean-Pierre Demailly 2.7.1 menus and messages French * * Giuseppe Martini, Giovanni Paolella, 2.7.1 menus and messages * * A. Davassi, M. Masullo, C. Liotto 2.7.1 help file Italian * * G. Pozhvanov 2.7.3 menus and messages Russian * * G. Todorov 2.7.3 menus and messages Bulgarian* * Nan Jia, G. Todorov 2.7.3 menus and messages Chinese * * Mamoru Yamanishi, Katajima Hajime 2.7.3 menus and messages Japanese * * * * This Release by * * Herbert J. Bernstein, Bernstein + Sons, 5 Brewster Ln, Bellport, NY, USA* * yaya@bernstein-plus-sons.com * * Copyright(C) Herbert J. Bernstein 1998-2008 * * * * READ THE FILE NOTICE FOR RASMOL LICENSES * *Please read the file NOTICE for important notices which apply to this * *package and for license terms (GPL or RASLIC). * ***************************************************************************/ /* outfile.c $Log$ Revision 1.9 2008/03/22 18:42:53 yaya Post release cleanup and credit to Ikonen in file headers. -- HJB Revision 1.8 2008/03/17 03:01:31 yaya Update to agree with 2.7.4.2 release and T. Ikonen GTK mods -- HJB Revision 1.3 2008/03/17 01:32:41 yaya Add gtk mods by tpikonen, and intergate with 2.7.4.2 mods -- HJB Revision 1.7 2008/03/16 22:25:22 yaya Align comments with production version; Update rasmol_install and rasmol_run shell scripts for Japanese and Chinese; Align logic for positioning and sizing initial window with windows version -- HJB Revision 1.2 2008/01/28 03:29:37 yaya Update CVS to RasMol_2.7.4.1 -- HJB Revision 1.6 2008/01/05 20:56:29 yaya Update handling of stereo interaction with slab Enable save of CBF-style maps. -- HJB Revision 1.5 2007/12/14 02:04:50 yaya Correct Chinese data for missing line in langsel_utf.c Rewrite code for handling of slab mode in stereo -- HJB Revision 1.4 2007/11/19 03:28:39 yaya Update to credits for 2.7.4 in manual and headers Mask code added -- HJB Revision 1.3 2007/07/07 21:54:31 yaya Next round of preliminary updates for maps, allowing multiple maps, code to set the contour level and some fixes to the languages files -- HJB Revision 1.2 2007/07/02 12:44:39 yaya Partial preliminary map code -- HJB Revision 1.1.1.1 2007/03/01 01:16:33 todorovg Chinese working versio from rasmol_ru initial import Revision 1.5 2007/02/02 21:08:59 yaya Remove // comments for AIX build Fix signed length conflict Fix array bounds violation for molecule names in multiple.c -- HJB Revision 1.4 2006/12/03 02:53:10 yaya Clean up compilation warnings in outfile.c Mods for about screen under Linux -- HJB Revision 1.3 2006/11/01 03:23:50 yaya Update NSIS windows installer for more script types and to fix misplaced script instructions for data files; add document and script icons directly in raswin.exe; add credit line to G. A. Pozhvanov in comments for Russian translations. -- HJB Revision 1.2 2006/09/17 10:53:55 yaya Clean up headers and start on code for X11 -- HJB Revision 1.1.1.1 2006/09/16 18:45:53 yaya Start of RasMol Russian Translation Project based on translations by Gregory A. Pozhvanov of Saint Petersburg State University -- HJB Revision 1.1.1.1 2006/06/19 22:05:14 todorovg Initial Rasmol 2.7.3 Import Revision 1.1 2004/05/07 19:46:16 yaya Initial revision Revision 1.3 2004/02/15 00:24:00 yaya *** empty log message *** Revision 1.2 2003/12/13 19:26:11 yaya *** empty log message *** Revision 1.1 2003/12/12 21:10:38 yaya Initial revision Revision 1.1 2001/01/31 02:13:45 yaya Initial revision Revision 1.4 2000/08/26 18:12:36 yaya Updates to header comments in all files Revision 1.3 2000/08/26 03:14:01 yaya Mods for mac compilations Revision 1.2 2000/08/09 01:18:08 yaya Rough cut with ucb */ #include "rasmol.h" #ifdef IBMPC #include #endif #ifdef MSWIN #include #endif #ifdef APPLEMAC #include #include #ifdef __CONDITIONALMACROS__ #include #else #include #endif #endif #ifndef sun386 #include #endif #include #include #include #define OUTFILE #include "outfile.h" #include "molecule.h" #include "command.h" #include "cmndline.h" #include "abstree.h" #include "transfor.h" #include "render.h" #include "repres.h" #include "graphics.h" #include "pixutils.h" #include "script.h" #include "font.h" #include "maps.h" /* #define BIGGIF */ #define Round(x) ((int)(x)) #ifdef INVERT #define InvertY(y) (y) #else #define InvertY(y) (-(y)) #endif #ifdef EIGHTBIT #define RComp(x) (RLut[LutInv[x]]) #define GComp(x) (GLut[LutInv[x]]) #define BComp(x) (BLut[LutInv[x]]) #else #define RComp(x) (((x)>>16)&0xff) #define GComp(x) (((x)>>8)&0xff) #define BComp(x) ((x)&0xff) #endif /* Macros for commonly used loops */ #define ForEachAtom for(chain=Database->clist;chain;chain=chain->cnext) \ for(group=chain->glist;group;group=group->gnext) \ for(aptr=group->alist;aptr;aptr=aptr->anext) #define ForEachBond for(bptr=Database->blist;bptr;bptr=bptr->bnext) #define ForEachBack for(chain=Database->clist;chain;chain=chain->cnext) \ for(bptr=chain->blist;bptr;bptr=bptr->bnext) /* Sun rasterfile.h macro defns */ #define RAS_MAGIC 0x59a66a95 #define RAS_RLE 0x80 #define RT_STANDARD 1 #define RT_BYTE_ENCODED 2 #define RMT_NONE 0 #define RMT_EQUAL_RGB 1 /* Standard A4 size page: 8.267x11.811 inches */ /* U.S. Normal size page: 8.500x11.000 inches */ #define PAGEHIGH (11.811*72.0) #define PAGEWIDE (8.267*72.0) #define BORDER 0.90 /* Compression Ratio 0>8)&0xff, OutFile ); } #endif static void WriteMSBShort( int val ) { putc( (val>>8)&0xff, OutFile ); putc( val&0xff, OutFile ); } #ifdef EIGHTBIT static void WriteLSBLong( Card val ) { putc((int)(val&0xff),OutFile); putc((int)((val>>8) &0xff),OutFile); putc((int)((val>>16)&0xff),OutFile); putc((int)((val>>24)&0xff),OutFile); } #endif static void WriteMSBLong( Card val ) { putc((int)((val>>24)&0xff),OutFile); putc((int)((val>>16)&0xff),OutFile); putc((int)((val>>8) &0xff),OutFile); putc((int)(val&0xff),OutFile); } static void CalcInvColourMap( void ) { #ifdef EIGHTBIT register int i; for( i=0; i<256; i++ ) if( ULut[i] ) LutInv[Lut[i]] = i; #endif } #ifdef EIGHTBIT static int CompactColourMap( void ) { register Pixel __huge *ptr; register Long pos, count; register int i, cols; CalcInvColourMap(); for( i=0; i<256; i++ ) { Buffer[i] = 0; Node[i] = 5; } #ifdef MSWIN ptr = (Pixel __huge*)GlobalLock(FBufHandle); #else ptr = FBuffer; #endif cols = 0; count = (Long)XRange*YRange; for( pos=0; pos99 ) { putc((i/100)+'0',OutFile); i %= 100; putc((i/10) +'0',OutFile); i %= 10; } else if( i>9 ) { putc((i/10)+'0',OutFile); i %= 10; } putc(i+'0',OutFile); } int WritePPMFile( char *name, int raw ) { register Pixel __huge *ptr; register int i,col; register int x,y; #if defined(IBMPC) || defined(APPLEMAC) OutFile = fopen(name, (raw?"wb":"w") ); #else OutFile = fopen(name,"w"); #endif if( !OutFile ) { FatalOutputError(name); return( False ); } CalcInvColourMap(); fprintf(OutFile,"P%c %d %d 255\n",(raw?'6':'3'),XRange,YRange); #ifdef MSWIN FBuffer = (Pixel __huge*)GlobalLock(FBufHandle); #endif #ifndef INVERT ptr = FBuffer; #endif if( !raw ) { col = 0; for( y=YRange-1; y>=0; y-- ) { #ifdef INVERT ptr = FBuffer + (Long)y*XRange; #endif for( x=0; x=0; y-- ) { #ifdef INVERT ptr = FBuffer + (Long)y*XRange; #endif for( x=0; x max ) { #ifdef IBMPC Buffer[PacketLen++]=(Byte)(BitBuffer&0xff); #else Buffer[PacketLen++]=BitBuffer; #endif BitBuffer >>= 8; BitBufLen -= 8; if( PacketLen==255 ) { WriteByte(0xff); fwrite((char*)Buffer,1,255,OutFile); PacketLen = 0; } } } int WriteGIFFile( char *name ) { register int i,j,cols; register int pref,next,last; register int isize, ilast; register Pixel __huge *ptr; register short __far *prev; register int x,y,init; cols = CompactColourMap(); if( cols<2 ) return( False ); for( isize=2; isize<8; isize++ ) if( (1<= cols ) break; cols = 1<=0; y-- ) { #ifdef INVERT ptr = FBuffer + (Long)y*XRange; #endif for( x=0; x1)? 3 : 2; } else if( RLEOutput ) { if( RLELength>2 ) { WriteByte(RAS_RLE); WriteByte(RLELength-1); } else if( RLELength==2 ) WriteByte(RLEChar); WriteByte(RLEChar); } else RLEFileSize += MinFun(RLELength,3); } static void WriteRastRLECode( int val ) { if( RLEEncode ) { if( !RLELength ) { RLELength = 1; RLEChar = val; } else if( (RLEChar!=val) || (RLELength==256) ) { FlushRastRLE(); RLELength = 1; RLEChar = val; } else RLELength++; } else WriteByte(val); } static void WriteRastRLEPad( void ) { if( RLEEncode ) { if( !RLELength || (RLELength==256) ) { WriteRastRLECode(0x00); } else RLELength++; } else WriteByte(0x00); } static void WriteRastData( int output ) { register Pixel __huge *ptr; register int x,y,pad; #ifndef EIGHTBIT register int i; #endif #ifdef MSWIN FBuffer = (Pixel __huge*)GlobalLock(FBufHandle); #endif #ifndef INVERT ptr = FBuffer; #endif pad = XRange%2; RLEOutput = output; RLEFileSize = 0; RLELength = 0; for( y=YRange-1; y>=0; y-- ) { #ifdef INVERT ptr = FBuffer + (Long)y*XRange; #endif for( x=0; x>4] ); WriteByte( hex[val&0x0f] ); if( (LineLength+=2) > 72 ) { WriteByte('\n'); LineLength = 0; } } static void EncodeEPSFPixel( int val, int col ) { register int r, g, b; register int i; r = RComp(val); g = GComp(val); b = BComp(val); if( col ) { OutputEPSFByte( r ); OutputEPSFByte( g ); OutputEPSFByte( b ); } else { i = (20*r + 32*g + 12*b)>>6; OutputEPSFByte( i ); } } int WriteEPSFFile( char *name, int col, int compr ) { register int x, y, i, j; register int xsize, ysize; register int xpos, ypos; register int rotpage; register Pixel __huge *ptr; int RLEBuffer[128]; OutFile = fopen(name,"w"); if( !OutFile ) { FatalOutputError(name); return(False); } CalcInvColourMap(); if( XRange <= YRange ) { rotpage = False; xsize = XRange; ysize = YRange; } else { rotpage = True; xsize = YRange; ysize = XRange; } if( xsize > (int)(BORDER*PAGEWIDE) ) { ysize = (int)(ysize*(BORDER*PAGEWIDE)/xsize); xsize = (int)(BORDER*PAGEWIDE); } if( ysize > (int)(BORDER*PAGEHIGH) ) { xsize = (int)(xsize*(BORDER*PAGEHIGH)/ysize); ysize = (int)(BORDER*PAGEHIGH); } xpos = (int)(PAGEWIDE-xsize)/2; ypos = (int)(PAGEHIGH-ysize)/2; fputs("%!PS-Adobe-2.0 EPSF-2.0\n",OutFile); fprintf(OutFile,"%%Creator: RasMol Version %s\n",VERSION); fprintf(OutFile,"%%%%Title: %s\n",name); fprintf(OutFile,"%%%%BoundingBox: %d %d ",xpos,ypos); fprintf(OutFile,"%d %d\n",xpos+xsize,ypos+ysize); fputs("%%Pages: 1\n",OutFile); fputs("%%EndComments\n",OutFile); fputs("%%EndProlog\n",OutFile); fputs("%%Page: 1 1\n",OutFile); fputs("gsave\n",OutFile); fputs("10 dict begin\n",OutFile); fprintf(OutFile,"%d %d translate\n",xpos,ypos); fprintf(OutFile,"%d %d scale\n",xsize,ysize); if( rotpage ) { fputs("0.5 0.5 translate\n",OutFile); fputs("90 rotate\n",OutFile); fputs("-0.5 -0.5 translate\n",OutFile); } fputc('\n',OutFile); if( compr ) { fputs("/rlecount 0 def\n",OutFile); fputs("/rlebyte 1 string def\n",OutFile); fprintf(OutFile,"/pixbuf %d string def\n", col?3:1 ); fputs("/reppixel { pixbuf } def\n",OutFile); fputs("/getpixel { \n",OutFile); fputs(" currentfile pixbuf readhexstring pop\n",OutFile); fputs("} def\n\n",OutFile); if( col ) { fputs("/colorimage where {\n",OutFile); fputs(" pop\n",OutFile); fputs("} {\n",OutFile); fputs(" /bytebuf 1 string def\n",OutFile); fputs(" /colorimage { pop pop image } def\n",OutFile); fputs(" /reppixel { bytebuf } def\n",OutFile); fputs(" /getpixel {\n",OutFile); fputs(" currentfile pixbuf readhexstring pop pop\n",OutFile); fputs(" bytebuf 0\n",OutFile); fputs(" pixbuf 0 get 20 mul\n",OutFile); fputs(" pixbuf 1 get 32 mul\n",OutFile); fputs(" pixbuf 2 get 12 mul\n",OutFile); fputs(" add add -6 bitshift put bytebuf\n",OutFile); fputs(" } def\n",OutFile); fputs("} ifelse\n\n",OutFile); } fputs("/rledecode {\n",OutFile); fputs(" rlecount 0 eq {\n",OutFile); fputs(" currentfile rlebyte readhexstring pop\n",OutFile); fprintf(OutFile," 0 get dup %d gt {\n",EPSFCompRatio); fprintf(OutFile," /rlecount exch %d sub def\n",EPSFCompRatio); fputs(" /rleflag true def\n",OutFile); fputs(" } {\n",OutFile); fputs(" /rlecount exch def\n",OutFile); fputs(" /rleflag false def\n",OutFile); fputs(" } ifelse getpixel\n",OutFile); fputs(" } {\n",OutFile); fputs(" /rlecount rlecount 1 sub def\n",OutFile); fputs(" rleflag { reppixel } { getpixel } ifelse\n",OutFile); fputs(" } ifelse\n",OutFile); fputs("} def\n",OutFile); } else if( col ) { fprintf(OutFile,"/scanbuf %d string def\n",XRange*3); fputs("/colorimage where {\n",OutFile); fputs(" pop\n",OutFile); fputs("} {\n",OutFile); fputs(" /pixbuf 3 string def\n",OutFile); fputs(" /bytebuf 1 string def\n",OutFile); fputs(" /colorimage {\n",OutFile); fputs(" pop pop pop {\n",OutFile); fputs(" currentfile pixbuf readhexstring pop pop\n",OutFile); fputs(" bytebuf 0\n",OutFile); fputs(" pixbuf 0 get 20 mul\n",OutFile); fputs(" pixbuf 1 get 32 mul\n",OutFile); fputs(" pixbuf 2 get 12 mul\n",OutFile); fputs(" add add -6 bitshift put bytebuf\n",OutFile); fputs(" } image\n",OutFile); fputs(" } def\n",OutFile); fputs("} ifelse\n\n",OutFile); } else fprintf(OutFile,"/scanbuf %d string def\n\n",XRange); fprintf(OutFile,"%d %d %d\n",XRange,YRange,8); fprintf(OutFile,"[%d 0 0 -%d 0 %d]\n",XRange,YRange,YRange); if( !compr ) { fputs("{ currentfile scanbuf readhexstring pop }\n",OutFile); } else fputs("{ rledecode }\n",OutFile); if( col ) fputs("false 3 color",OutFile); fputs("image\n",OutFile); #ifdef MSWIN FBuffer = (Pixel __huge*)GlobalLock(FBufHandle); #endif #ifndef INVERT ptr = FBuffer; #endif RLELength = 0; LineLength = 0; for( y=YRange-1; y>=0; y-- ) { #ifdef INVERT ptr = FBuffer + (Long)y*XRange; #endif for( x=0; x1 ) { OutputEPSFByte(RLELength-2); for( j=0; j BMPCount+5 ) { FlushBMPPackets(); return; } /* Flush AbsMode buffer */ if( PacketLen+BMPTotal>255 ) FlushBMPBuffer(); /* Cannot leave RLEMode */ if( PacketLen+BMPTotal<3 ) return; /* Determine AbsMode cost */ if( PacketLen ) { cost = BMPTotal - (PacketLen%2); cost += (cost%2); } else cost = (BMPTotal%2)+BMPTotal+2; /* Put RLE Packets into AbsMode buffer */ if( cost <= (int)(BMPCount<<1) ) { for( i=0; i=0; y-- ) { #ifndef INVERT ptr = FBuffer + (Long)y*XRange; #endif for( x=0; x=0; y-- ) { #ifndef INVERT ptr = FBuffer + (Long)y*XRange; #endif for( x=0; xz; case(PSBond): bond = (Bond __far*)item; result = bond->srcatom->z; if( result < bond->dstatom->z ) result = bond->dstatom->z; return result; case(PSSSBond): case(PSHBond): hbond = (HBond __far*)item; if( (type==PSHBond)? HBondMode : SSBondMode ) { result = hbond->srcCA->z; if( result < hbond->dstCA->z ) result = hbond->dstCA->z; } else { result = hbond->src->z; if( result < hbond->dst->z ) result = hbond->dst->z; } return result; case(PSMonit): monit = (Monitor __far*)item; result = monit->src->z; if( result < monit->dst->z ) result = monit->dst->z; return result; } return 0; } static void DepthSort( PSItemPtr __far *data, char __far *type, int count ) { register char ttmp; register void __far *dtmp; register int i, j, k; register int depth; register int temp; for( i=1; ij; k-- ) { data[k] = data[k-1]; type[k] = type[k-1]; } data[j] = dtmp; type[j] = ttmp; } } } static int ClipVectSphere( RAtom __far *ptr ) { register int rad; rad = ptr->irad; if( ptr->x + rad < 0 ) return True; if( ptr->y + rad < 0 ) return True; if( ptr->x - rad >= XRange ) return True; if( ptr->y - rad >= YRange ) return True; return False; } static int ClipVectBond( RAtom __far *src, RAtom __far *dst ) { if( !src || !dst ) return True; if( (src->x<0) && (dst->x<0) ) return True; if( (src->y<0) && (dst->y<0) ) return True; if( (src->x>=XRange) && (dst->x>=XRange) ) return True; if( (src->y>=YRange) && (dst->y>=YRange) ) return True; return False; } static void WriteVectColour( int col ) { if( col != VectCol ) { fprintf(OutFile,"%g ",(Real)RLut[col]/255.0); fprintf(OutFile,"%g ",(Real)GLut[col]/255.0); fprintf(OutFile,"%g ",(Real)BLut[col]/255.0); fputs("setrgbcolor\n",OutFile); VectCol = col; } } #define MAXSECT 5 typedef struct { /* Ellipse */ Real ephi,epsi; Real etheta; Real ex,ey; Real erad; /* Sphere */ Real sphi,spsi; int sx,sy; Real srad; } SphereSect; static int VectClipContain( SphereSect *x, SphereSect *y ) { if( x->erad != 0.0 ) { if( y->erad != 0.0 ) /* Simple segment containment test! */ return( ((x->sphi+x->spsi)>=(y->sphi+y->spsi)) && ((x->sphi-x->spsi)<=(y->sphi-y->spsi)) ); } else if( y->erad == 0.0 ) return( x->srad >= y->srad ); return False; } static void WriteVectSphere( PSItemPtr __far *data, char __far *type, int index ) { register int ecount, count; register RAtom __far *atm; register RAtom __far *ptr; register Long dist2,dist3; register int dx, dy, dz; register int i,j,k; register Real b,d,f,g=0.0,x; register Real radf,radb; register Real phi1,phi2; register Real temp,psi; register Real theta; register SphereSect *sptr; SphereSect sect[MAXSECT]; ptr = (RAtom __far*)data[index]; radf = ((Real)ptr->radius)*Scale; count = 0; ecount = 0; sptr = sect; for( i=index-1; i>=0; i-- ) { if( type[i] != PSAtom ) continue; atm = (RAtom __far*)data[i]; /* Atom can't intersect visibly! */ if( atm->z + atm->irad < ptr->z ) continue; dx = atm->x - ptr->x; dy = atm->y - ptr->y; dz = atm->z - ptr->z; dist2 = (Long)dx*dx + (Long)dy*dy; dist3 = dist2 + dz*dz; radb = ((Real)atm->radius)*Scale; temp = radf + radb; /* Atoms don't intersect! */ if( dist3 > temp*temp ) continue; d = sqrt( (double)dist3 ); f = (temp*(radf-radb)+dist3)/(2.0*d); theta = -dz/d; if( f>0 ) { temp = radf*radf; /* Intersection not visible! */ if( theta*temp > temp-f*f ) continue; } else if( f < -radf ) return; x = sqrt( (radf-f)*(radf+f) ); if( dx || dy ) { g = sqrt( (double)dist2 ); psi = Rad2Deg*atan2(dy,dx); b = (f*(dz*dz))/(d*g); if( AbsFun(b)>x ) continue; phi1 = b + (f*g)/d; phi1 = Rad2Deg*acos(phi1/radf); if( phi1!=phi1 ) continue; phi2 = (d*b)/g; if( AbsFun(phi2) < x ) { phi2 = Rad2Deg*acos(phi2/x); if( phi2!=phi2 ) continue; if( phi2 > 90.0 ) phi2 = 180.0-phi1; } else phi2 = 90.0; sptr->erad = x; sptr->etheta = -theta; sptr->ephi = psi; sptr->epsi = phi2; temp = f/d; sptr->ex = ptr->x+temp*dx; sptr->ey = ptr->y+temp*dy; sptr->srad = radf; sptr->sphi = psi; sptr->spsi = phi1; sptr->sx = ptr->x; sptr->sy = ptr->y; } else { x = sqrt( (radf-g)*(radf+g) ); sptr->srad = x; sptr->erad = 0.0; sptr->sx = ptr->x; sptr->sy = ptr->y; sptr->sphi = 180; sptr->spsi = -180; } /* Optimize Segments */ j = 0; while( jerad != 0.0 ) ecount++; if( count==MAXSECT ) break; } } if( UseOutLine ) { temp = (ptr->z-ZOffset)/ImageSize + 1.0; if( temp != LineWidth ) { fprintf(OutFile,"%g setlinewidth\n",temp); LineWidth = temp; } } if( !VectSolid ) { fputs("[] 0 setdash\n",OutFile); VectSolid = True; } if( count ) { fputs("gsave\n",OutFile); fprintf(OutFile,"%%%% %d %d\n",count,ecount); sptr = sect; for( i=0; ierad != 0.0 ) { fprintf(OutFile,"%g %g %g %g %g %g ClipEllips\n", sptr->erad,sptr->epsi,sptr->etheta, sptr->ephi,sptr->ex,sptr->ey); } if( (i==count-1) || (sptr->erad==0.0) ) { fprintf(OutFile,"%g %g %g %d %d ClipSphere\n",sptr->srad, sptr->sphi+sptr->spsi,sptr->sphi-sptr->spsi, sptr->sx, sptr->sy ); } else fprintf(OutFile,"%g %g %g %d %d ClipBox\n", sptr->srad+sptr->srad+2, sptr->srad+1, sptr->ephi, sptr->sx, sptr->sy ); sptr++; } i = ptr->col + ColourMask; fprintf(OutFile,"%g ",(Real)RLut[i]/255.0); fprintf(OutFile,"%g ",(Real)GLut[i]/255.0); fprintf(OutFile,"%g ",(Real)BLut[i]/255.0); fprintf(OutFile,"%g Shade\n",radf); fputs("grestore\n\n",OutFile); } else { i = ptr->col + ColourMask; fprintf(OutFile,"%g ",(Real)RLut[i]/255.0); fprintf(OutFile,"%g ",(Real)GLut[i]/255.0); fprintf(OutFile,"%g ",(Real)BLut[i]/255.0); fprintf(OutFile,"%g %ld %ld ",radf,ptr->x,ptr->y); fputs("Sphere\n\n",OutFile); } } static void WriteVectWire( RAtom __far *src, RAtom __far *dst, int col, int dash ) { register RAtom __far *tmp; register Real radius=0.0; register Real temp; register Real dist; register Real midx, midy; register Real endx, endy; register int col1, col2; register int dx, dy, dz; register Long dist2; register int inten; if( src->z > dst->z ) { tmp = src; src = dst; dst = tmp; } if( !col ) { col1 = src->col; col2 = dst->col; } else col1 = col2 = col; if( UseBackFade ) { dz = (src->z+dst->z)>>1; inten = (ColourDepth*(dz+ImageRadius-ZOffset))/ImageSize; } else inten = ColourMask; dx = dst->x - src->x; dy = dst->y - src->y; dist2 = dx*dx + dy*dy; dist = sqrt( (double)dist2 ); if( dst->flag & SphereFlag ) { radius = ((Real)dst->radius)*Scale; if( dist <= radius ) return; /* Test for second half obscured! */ if( (col1!=col2) && (0.5*dist < radius) ) col2 = col1; } if( src->flag & SphereFlag ) { radius = ((Real)src->radius)*Scale; if( dist <= radius ) return; /* Test for first half obscured! */ if( (col1!=col2) && (0.5*dist < radius) ) col1 = col2; } WriteVectColour( col1+inten ); dz = (src->z+dst->z)>>1; temp = (double)(dz-ZOffset)/ImageSize + 1.0; if( temp != LineWidth ) { fprintf(OutFile,"%g setlinewidth\n",temp); LineWidth = temp; } if( dash ) { if( VectSolid ) { fputs("[3 3] 0 setdash\n",OutFile); VectSolid = False; } } else if( !VectSolid ) { fputs("[] 0 setdash\n",OutFile); VectSolid = True; } if( src->flag & SphereFlag ) { dz = dst->z - src->z; dist = sqrt( (double)(dist2 + dz*dz) ); endx = src->x + (radius*dx)/dist; endy = src->y + (radius*dy)/dist; fprintf(OutFile,"%g %g ",endx,endy); } else fprintf(OutFile,"%ld %ld ",src->x,src->y); if( col1 != col2 ) { midx = 0.5*(src->x + dst->x); midy = 0.5*(src->y + dst->y); fprintf(OutFile,"%g %g Wire\n",midx,midy); WriteVectColour( col2+inten ); fprintf(OutFile,"%g %g ",midx,midy); } fprintf(OutFile,"%ld %ld Wire\n",dst->x,dst->y); } static void WriteVectStick( RAtom __far *src, RAtom __far *dst, int col, int rad ) { register RAtom __far *tmp; register Real midx, midy; register Real relx, rely; register Real endx=0.0, endy=0.0; register Real radius, angle; register Real dist, dist3; register Real temp, ratio; register Long dist2; register int dx, dy, dz; register int col1, col2; register int i, inten; if( !rad ) { WriteVectWire(src,dst,col,False); return; } if( src->z > dst->z ) { tmp = src; src = dst; dst = tmp; } if( !col ) { col1 = src->col; col2 = dst->col; } else col1 = col2 = col; dx = dst->x - src->x; dy = dst->y - src->y; dz = dst->z - src->z; dist2 = dx*dx + dy*dy; dist3 = sqrt( (double)(dist2 + dz*dz) ); dist = sqrt( (double)dist2 ); if( dst->flag & SphereFlag ) { radius = ((Real)dst->radius)*Scale; if( dist <= radius ) return; /* Test for nearest half obscured! */ if( (col1!=col2) && (0.5*dist < radius) ) col2 = col1; } if( src->flag & SphereFlag ) { radius = ((Real)src->radius)*Scale; if( dist <= radius ) return; /* Test for furthest half obscured! */ if( (col1!=col2) && (0.5*dist < radius) ) col1 = col2; } if( !VectSolid ) { fputs("[] 0 setdash\n",OutFile); VectSolid = True; } temp = ((src->z-ZOffset)+(dst->z-ZOffset))/ImageSize + 1.0; if( temp != LineWidth ) { fprintf(OutFile,"%g setlinewidth\n",temp); LineWidth = temp; } radius = ((Real)rad)*Scale; angle = Rad2Deg*atan2((double)dy,(double)dx); inten = (int)((dist/dist3)*ColourMask); if( col1 != col2 ) { midx = 0.5*(src->x + dst->x); midy = 0.5*(src->y + dst->y); relx = (radius*dx)/dist; rely = (radius*dy)/dist; fprintf(OutFile,"%g %g moveto\n",midx+rely,midy-relx); fprintf(OutFile,"%g %g lineto\n",midx-rely,midy+relx); ratio = dz/dist3; if( (src->flag&SphereFlag) && (src->radius>rad) ) { temp = (Scale*(Real)(src->radius))/dist3; endx = src->x + temp*dx; endy = src->y + temp*dy; fprintf(OutFile,"%g %g %g ",radius,ratio,angle); fprintf(OutFile,"%g %g StickEnd\n",endx,endy); } else { fprintf(OutFile,"%ld %ld %g ",src->x,src->y,radius); fprintf(OutFile,"%g %g arc\n",angle+90,angle-90); } fputs("closepath ",OutFile); i = col1 + inten; fprintf(OutFile,"%g ",(Real)RLut[i]/255.0); fprintf(OutFile,"%g ",(Real)GLut[i]/255.0); fprintf(OutFile,"%g ",(Real)BLut[i]/255.0); fputs("setrgbcolor fill\n",OutFile); fprintf(OutFile,"%ld %ld %g ",dst->x,dst->y,radius); fprintf(OutFile,"%g %g arc\n",angle-90,angle+90); fprintf(OutFile,"%g %g %g ",radius,ratio,angle); fprintf(OutFile,"%g %g StickEnd\n",midx,midy); fputs("closepath ",OutFile); i = col2 + inten; fprintf(OutFile,"%g ",(Real)RLut[i]/255.0); fprintf(OutFile,"%g ",(Real)GLut[i]/255.0); fprintf(OutFile,"%g ",(Real)BLut[i]/255.0); fputs("setrgbcolor fill\n",OutFile); if( UseOutLine ) { fprintf(OutFile,"%ld %ld %g ",dst->x,dst->y,radius); fprintf(OutFile,"%g %g arc\n",angle-90,angle+90); if( (src->flag&SphereFlag) && (src->radius>rad) ) { fprintf(OutFile,"%g %g %g ",radius,ratio,angle); fprintf(OutFile,"%g %g StickEnd\n",endx,endy); } else { fprintf(OutFile,"%ld %ld %g ",src->x,src->y,radius); fprintf(OutFile,"%g %g arc\n",angle+90,angle-90); } fputs("closepath 0 setgray stroke\n",OutFile); } } else /* col1 == col2! */ { fprintf(OutFile,"%ld %ld %g ",dst->x,dst->y,radius); fprintf(OutFile,"%g %g arc\n",angle-90,angle+90); if( (src->flag&SphereFlag) && (src->radius>rad) ) { temp = (Scale*(Real)(src->radius))/dist3; endx = src->x + temp*dx; endy = src->y + temp*dy; ratio = dz/dist3; fprintf(OutFile,"%g %g %g ",radius,ratio,angle); fprintf(OutFile,"%g %g StickEnd\n",endx,endy); } else { fprintf(OutFile,"%ld %ld %g ",src->x,src->y,radius); fprintf(OutFile,"%g %g arc\n",angle+90,angle-90); } i = col1 + inten; fprintf(OutFile,"%g ",(Real)RLut[i]/255.0); fprintf(OutFile,"%g ",(Real)GLut[i]/255.0); fprintf(OutFile,"%g ",(Real)BLut[i]/255.0); fputs("Stick\n",OutFile); } VectCol = 0; } static void WriteVectDots( void ) { register DotStruct __far *ptr; register Real x,y,z; register Real xi,yi; register int inten; register int temp, tump; register int zi; register int i; register int xp; if( LineWidth != 1.0 ) { fputs("1 setlinewidth\n",OutFile); LineWidth = 1.0; } temp = SlabValue - ZOffset; tump = DepthValue - ZOffset; for( ptr=DotPtr; ptr; ptr=ptr->next ) for( i=0; icount; i++ ) { x = ptr->xpos[i]; y = ptr->ypos[i]; z = ptr->zpos[i]; xi = (x*MatX[0]+y*MatX[1]+z*MatX[2]) + XOffset; if( (xi<0.0) || ((int)rint(xi)>=View.xmax) ) continue; yi = (x*MatY[0]+y*MatY[1]+z*MatY[2]) + YOffset; if( (yi<0.0) || ((int)rint(yi)>=View.ymax) ) continue; zi = (int)(x*MatZ[0]+y*MatZ[1]+z*MatZ[2]); xp = rint(xi); if( UseSlabPlane && (zi>=View.slbuf[xp]) ) continue; if( UseDepthPlane && (zi<=View.dlbuf[xp]) ) continue; inten = (ColourDepth*(zi+ImageRadius))/ImageSize; WriteVectColour( ptr->col[i]+inten ); fprintf(OutFile,"%g %g Dot\n",xi,yi); } } static void WriteVectMapPoints( void ) { register Real x,y,z; register Real xi,yi; register int inten; register int temp, tump; register int zi; register int i; register int xp; if( LineWidth != 1.0 ) { fputs("1 setlinewidth\n",OutFile); LineWidth = 1.0; } temp = SlabValue - ZOffset; tump = DepthValue - ZOffset; if (MapInfoPtr) { int imap; MapPointVec __far* MapPointsPtr; for (imap = 0; imap < MapInfoPtr->size; imap++) { MapInfo mapinfo; vector_get_element((GenericVec __far *)MapInfoPtr,(void __far *)&mapinfo,imap); MapPointsPtr = mapinfo.MapPointsPtr; if (MapPointsPtr) { for (i= 0; i < MapPointsPtr->size; i++) { x = (MapPointsPtr->array[i]).xpos; y = (MapPointsPtr->array[i]).xpos; z = (MapPointsPtr->array[i]).xpos; xi = (x*MatX[0]+y*MatX[1]+z*MatX[2]) + XOffset; if( (xi<0.0) || ((int)rint(xi)>=View.xmax) ) continue; yi = (x*MatY[0]+y*MatY[1]+z*MatY[2]) + YOffset; if( (yi<0.0) || ((int)rint(yi)>=View.ymax) ) continue; zi = (int)(x*MatZ[0]+y*MatZ[1]+z*MatZ[2]); xp = rint(xi); if( UseSlabPlane && (zi>=View.slbuf[xp]) ) continue; if( UseDepthPlane && (zi<=View.dlbuf[xp]) ) continue; inten = (ColourDepth*(zi+ImageRadius))/ImageSize; WriteVectColour( (MapPointsPtr->array[i]).col+inten ); fprintf(OutFile,"%g %g Dot\n",xi,yi); } } } } } static void WriteVectMapBonds( void) { } static void WriteVectLabels( void ) { register Chain __far *chain; register Group __far *group; register RAtom __far *aptr; register Label *label; auto unsigned char buffer[80]; fputs("/Times-Roman",OutFile); /* Courier or Courier-Bold? */ fprintf(OutFile," findfont %d scalefont setfont\n",FontSize<<1); if( UseLabelCol ) { if( BackR || BackG || BackB ) { fprintf(OutFile,"%g %g %g setrgbcolor\n", LabR/250.0, LabG/250.0, LabB/250.0); } else fputs("0 setgray\n",OutFile); } else VectCol = 0; ForEachAtom if( aptr->label ) { if( !UseLabelCol && (aptr->col!=VectCol) ) WriteVectColour( aptr->col ); label = (Label*)aptr->label; FormatLabel(chain,group,aptr,label->label,buffer); fprintf(OutFile,"(%s) %ld %ld Label\n",buffer,aptr->x,aptr->y); } } static void WriteVectMonitors( void ) { register RAtom __far *s; register RAtom __far *d; register Monitor *ptr; register int x,y,col; register char *cptr; register int dist; char buffer[10]; buffer[9] = '\0'; buffer[6] = '.'; fputs("/Times-Roman",OutFile); /* Courier or Courier-Bold? */ fprintf(OutFile," findfont %d scalefont setfont\n",FontSize<<1); for( ptr=MonitList; ptr; ptr=ptr->next ) { s = ptr->src; d = ptr->dst; if( ZBValid( (s->x+d->x)/2,(s->z+d->z)/2 ) ) { x = (s->x+d->x)/2; y = (s->y+d->y)/2; if( !UseLabelCol ) { /* Use Source atom colour! */ if( ptr->col ) { col = ptr->col + (ColourMask>>1); } else col = s->col + (ColourMask>>1); } else col = LabelCol; WriteVectColour(col); dist = ptr->dist; buffer[8] = (dist%10)+'0'; dist /= 10; buffer[7] = (dist%10)+'0'; cptr = &buffer[5]; if( dist > 9 ) { do { dist /= 10; *cptr-- = (dist%10)+'0'; } while( dist > 9 ); cptr++; } else *cptr = '0'; fprintf(OutFile,"(%s) %d %d Label\n",cptr,x+4,y); } } } static Long CountPSItems( void ) { register Chain __far *chain; register Group __far *group; register HBond __far *hptr; register Bond __far *bptr; register RAtom __far *aptr; register Monitor *mptr; register Long result; result = 0; if( DrawAtoms || DrawStars) ForEachAtom if( aptr->flag&(SphereFlag|StarFlag) ) if( !UseClipping || !ClipVectSphere(aptr) ) result++; if( DrawBonds ) ForEachBond if( bptr->flag&DrawBondFlag && (!UseClipping || !ClipVectBond(bptr->srcatom,bptr->dstatom)) ) result++; if( DrawRibbon) for(chain=Database->clist;chain;chain=chain->cnext) if(chain->glist) result++; ForEachBack if( bptr->flag&DrawBondFlag && (!UseClipping || !ClipVectBond(bptr->srcatom,bptr->dstatom)) ) result++; for( hptr=Database->hlist; hptr; hptr=hptr->hnext ) if( hptr->flag&DrawBondFlag ) { if( HBondMode ) { if( !ClipVectBond(hptr->srcCA,hptr->dstCA) ) result++; } else if( !ClipVectBond(hptr->src,hptr->dst) ) result++; } for( hptr=Database->slist; hptr; hptr=hptr->hnext ) if( hptr->flag&DrawBondFlag ) { if( SSBondMode ) { if( !ClipVectBond(hptr->srcCA,hptr->dstCA) ) result++; } else if( !ClipVectBond(hptr->src,hptr->dst) ) result++; } for( mptr=MonitList; mptr; mptr=mptr->next ) if( !UseClipping || !ClipVectBond(mptr->src,mptr->dst) ) result++; return result; } static void FetchPSItems( PSItemPtr __far *data, char __far *type ) { register Chain __far *chain; register Group __far *group; register HBond __far *hptr; register Bond __far *bptr; register RAtom __far *aptr; register Monitor *mptr; register int i,flag; i = 0; if( DrawAtoms || DrawStars ) ForEachAtom if( aptr->flag&(SphereFlag | StarFlag) ) if( !UseClipping || !ClipVectSphere(aptr) ) { type[i] = PSAtom; data[i++] = aptr; } if( DrawBonds ) ForEachBond if( bptr->flag&DrawBondFlag && (!UseClipping || !ClipVectBond(bptr->srcatom,bptr->dstatom)) ) { type[i] = PSBond; data[i++] = bptr; } if( DrawRibbon ) { for( chain = Database->clist; chain; chain=chain->cnext) if( chain->glist ) { type[i]= PSRibbon; data[i++]= chain; } } ForEachBack if( bptr->flag&DrawBondFlag && (!UseClipping || !ClipVectBond(bptr->srcatom,bptr->dstatom)) ) { type[i] = PSBond; data[i++] = bptr; } for( hptr=Database->hlist; hptr; hptr=hptr->hnext ) if( hptr->flag&DrawBondFlag ) { if( HBondMode ) { flag = !ClipVectBond(hptr->srcCA,hptr->dstCA); } else flag = !ClipVectBond(hptr->src,hptr->dst); if( flag ) { type[i] = PSHBond; data[i++] = hptr; } } for( hptr=Database->slist; hptr; hptr=hptr->hnext ) if( hptr->flag&DrawBondFlag ) { if( SSBondMode ) { flag = !ClipVectBond(hptr->srcCA,hptr->dstCA); } else flag = !ClipVectBond(hptr->src,hptr->dst); if( flag ) { type[i] = PSSSBond; data[i++] = hptr; } } for( mptr=MonitList; mptr; mptr=mptr->next ) if( !UseClipping || !ClipVectBond(mptr->src,mptr->dst) ) { type[i] = PSMonit; data[i++] = mptr; } } int WriteVectPSFile( char *name ) { register Real ambi; register Real temp, inten; register int xsize, ysize; register int xpos, ypos; register Long count; register int i; PSItemPtr __far *data; char __far *type; count = CountPSItems(); if( !count ) return( True ); #ifdef IBMPC if( count > 16383 ) { InvalidateCmndLine(); WriteString("Output Error: Too many PostScript objects!\n"); return( False ); } #endif /* Allocate arrays for objects! */ data = (PSItemPtr __far*)_fmalloc((size_t)count*sizeof(PSItemPtr)); type = (char __far*)_fmalloc((size_t)count*sizeof(char)); if( !data || !type ) { InvalidateCmndLine(); WriteString("Output Error: Not enough memory to create PostScript!\n"); if( data ) _ffree( data ); if( type ) _ffree( type ); return( False ); } OutFile = fopen(name,"w"); if( !OutFile ) { FatalOutputError(name); return(False); } /* Determine the size of the image */ ysize = (int)(YRange*(BORDER*PAGEWIDE)/XRange); if( ysize > (int)(BORDER*PAGEHIGH) ) { xsize = (int)(XRange*(BORDER*PAGEHIGH)/YRange); ysize = (int)(BORDER*PAGEHIGH); } else xsize = (int)(BORDER*PAGEWIDE); xpos = (int)(PAGEWIDE-xsize)/2; ypos = (int)(PAGEHIGH-ysize)/2; fputs("%!PS-Adobe-2.0 EPSF-2.0\n",OutFile); fprintf(OutFile,"%%Creator: RasMol Version %s\n",VERSION); fprintf(OutFile,"%%%%Title: %s\n",name); fprintf(OutFile,"%%%%BoundingBox: %d %d ",xpos,ypos); fprintf(OutFile,"%d %d\n",xpos+xsize,ypos+ysize); fputs("%%Pages: 1\n",OutFile); fputs("%%EndComments\n",OutFile); fputs("%%EndProlog\n",OutFile); fputs("%%BeginSetup\n",OutFile); fputs("1 setlinecap 1 setlinejoin [] 0 setdash\n",OutFile); fputs("1 setlinewidth 0 setgray\n",OutFile); fputs("%%EndSetup\n",OutFile); fputs("%%Page: 1 1\n",OutFile); fputs("gsave\n",OutFile); fputs("14 dict begin\n\n",OutFile); fputs("/handleerror { showpage } def\n\n",OutFile); fputs("/Inten {\n dup 4 index mul exch\n",OutFile); fputs(" dup 4 index mul exch\n",OutFile); fputs(" 3 index mul setrgbcolor\n} def\n\n",OutFile); fputs("/Dot {\n moveto 0 0 rlineto stroke\n} def\n\n",OutFile); fputs("/Wire {\n moveto lineto stroke\n} def\n\n",OutFile); #ifdef INVERT fputs("/Label {\n moveto show\n} def\n\n",OutFile); #else fputs("/Label {\n moveto 1 -1 scale\n",OutFile); fputs(" show mtrx setmatrix\n} def\n\n",OutFile); #endif if( UseOutLine ) { fputs("/Stick {\n closepath gsave setrgbcolor fill\n",OutFile); fputs(" grestore 0 setgray stroke\n} def\n\n",OutFile); } else fputs("/Stick {\n closepath setrgbcolor fill\n} def\n\n",OutFile); fputs("/StickEnd {\n matrix currentmatrix 6 1 roll\n",OutFile); fputs(" translate rotate 1 scale\n",OutFile); fputs(" 0 0 3 2 roll 90 -90 arc\n setmatrix\n} def\n\n",OutFile); if( UseOutLine ) { fputs("/Shade {\n closepath gsave clip\n",OutFile); } else fputs("/Shade {\n closepath clip\n",OutFile); if( Ambient < 0.99 ) { ambi = 0.5*Ambient; fputs(" 45 rotate dup -0.81649658092 mul scale\n",OutFile); fprintf(OutFile," %g Inten fill\n",ambi); inten = (1.0-ambi)/31; for( i=0; i<31; i++ ) { temp = (Real)(i+1)/32; fprintf(OutFile," 0 %g ",(Real)i/32); fprintf(OutFile,"%g 0 360 arc ",sqrt(1.0-temp*temp)); fprintf(OutFile,"%g Inten fill\n",i*inten+ambi); } if( UseOutLine ) { fputs(" grestore 0 setgray stroke",OutFile); } else fputc(' ',OutFile); fputs(" pop pop pop\n} def\n\n",OutFile); } else /* Saturated Colours! */ { fputs(" pop setrgbcolor fill\n",OutFile); if( UseOutLine ) fputs(" grestore 0 setgray stroke\n",OutFile); fputs("} def\n\n",OutFile); } fputs("/ClipSphere {\n translate 0 0 5 2 roll arc\n} def\n\n",OutFile); fputs("/ClipBox {\n translate rotate\n dup lineto dup neg ",OutFile); fputs("dup\n 0 rlineto 0 exch rlineto 0 rlineto closepath\n",OutFile); fputs(" clip newpath mtrx setmatrix\n} def\n\n",OutFile); fputs("/ClipEllips {\n translate rotate 1 scale\n",OutFile); fputs(" 0 0 4 2 roll dup neg arc\n",OutFile); fputs(" reversepath mtrx setmatrix\n} def\n\n",OutFile); fputs("/Sphere {\n gsave\n",OutFile); fputs(" translate 0 0 2 index 0 360 arc\n",OutFile); if( UseOutLine ) { fputs(" gsave Shade grestore\n",OutFile); fputs(" 0 setgray stroke\n",OutFile); fputs(" grestore\n} def\n\n",OutFile); } else fputs(" Shade grestore\n} def\n\n",OutFile); #ifdef INVERT fprintf(OutFile,"%d %d translate\n",xpos,ypos); fprintf(OutFile,"%g ",(Real)xsize/XRange); fprintf(OutFile,"%g ",(Real)ysize/YRange); #else fprintf(OutFile,"%d %d translate\n",xpos,ypos+ysize); fprintf(OutFile,"%g ",(Real)xsize/XRange); fprintf(OutFile,"%g ",(Real)-ysize/YRange); #endif fputs("scale\n/mtrx matrix currentmatrix def\n\n",OutFile); fputs("newpath 0 0 moveto 0 ",OutFile); fprintf(OutFile,"%d rlineto %d 0 rlineto 0 %d",YRange,XRange,-YRange); fputs(" rlineto\nclosepath clip ",OutFile); if( BackR || BackG || BackB ) { fprintf(OutFile,"%g %g %g",BackR/255.0,BackG/255.0,BackB/255.0); fputs(" setrgbcolor fill\n\n",OutFile); } else fputs("newpath\n\n",OutFile); LineWidth = 1.0; VectSolid = True; VectCol = 0; FetchPSItems(data,type); if( count>1 ) DepthSort(data,type,(int)count); WritePSItems(data,type,(int)count); if( !VectSolid ) { fputs("[] 0 setdash\n",OutFile); VectSolid = True; } if( DotPtr ) WriteVectDots(); if( MapInfoPtr) WriteVectMapPoints(); if( DrawMonitDistance && MonitList ) WriteVectMonitors(); if( LabelList ) WriteVectLabels(); fputs("newpath 0 0 moveto 0 ",OutFile); fprintf(OutFile,"%d rlineto %d 0 rlineto 0 %d",YRange,XRange,-YRange); fputs(" rlineto\nclosepath 0 setgray 1 setlinewidth stroke\n",OutFile); fputs("end grestore\nshowpage\n",OutFile); fputs("%%Trailer\n",OutFile); fputs("%%EOF\n",OutFile); fclose( OutFile ); #ifdef APPLEMAC /* Avoid ANSI trigraph problems! */ SetFileInfo(name,'vgrd','TEXT',134); #endif _ffree( data ); _ffree( type ); return(True); } static void WritePSItems( PSItemPtr __far *data, char __far *type, int count ) { register Monitor __far *monit; register HBond __far *hbond; register Bond __far *bond; register RAtom __far *src; register RAtom __far *dst; register int i; for( i=0; isrcatom; dst = bond->dstatom; if( bond->flag & WireFlag ) { WriteVectWire(src,dst,bond->col,False); } else if( bond->flag & CylinderFlag ) { WriteVectStick(src,dst,bond->col,bond->radius); } else /* bond->flag & DashFlag */ WriteVectWire(src,dst,bond->col,True); break; case(PSSSBond): case(PSHBond): hbond = (HBond __far*)data[i]; if( (type[i]==PSHBond)? HBondMode : SSBondMode ) { src = hbond->srcCA; dst = hbond->dstCA; } else { src = hbond->src; dst = hbond->dst; } if( hbond->flag & WireFlag ) { WriteVectWire(src,dst,hbond->col,True); } else /* bond->flag & CylinderFlag */ WriteVectStick(src,dst,hbond->col, hbond->radius); break; case(PSMonit): monit = (Monitor __far*)data[i]; WriteVectWire(monit->src,monit->dst, monit->col,True); break; } } /****************************************************************************/ /* Writing a Raster3D file */ /****************************************************************************/ #define R3Dcoord(xorg,yorg,zorg,xtemp,ytemp,ztemp,xnew,ynew,znew) {\ xtemp= (Real)((xorg) - CenX) ; \ ytemp= (Real)((yorg) - CenY) ; \ ztemp= (Real)((zorg) - CenZ) ; \ xnew = ((xtemp)*MatX[0] + (ytemp)*MatX[1] + (ztemp)*MatX[2] + ((Real)(XOffset-XRange/2)))/(Real)(scale); \ ynew = InvertY((xtemp)*MatY[0] + (ytemp)*MatY[1] + (ztemp)*MatY[2] + ((Real)(YOffset-YRange/2)))/(Real)(scale); \ znew = ((xtemp)*MatZ[0] + (ytemp)*MatZ[1] + (ztemp)*MatZ[2] + ((Real)(ZOffset-ZRange/2)))/(Real)(scale); } #define R3DcoordC(xorgC,yorgC,zorgC,xnew,ynew,znew) {\ xnew = ((xorgC)*MatX[0] + (yorgC)*MatX[1] + (zorgC)*MatX[2] + ((Real)(XOffset-XRange/2)))/(Real)(scale); \ ynew = InvertY((xorgC)*MatY[0] + (yorgC)*MatY[1] + (zorgC)*MatY[2] + ((Real)(YOffset-YRange/2)))/(Real)(scale); \ znew = ((xorgC)*MatZ[0] + (yorgC)*MatZ[1] + (zorgC)*MatZ[2] + ((Real)(ZOffset-ZRange/2)))/(Real)(scale); } static void WriteR3DSphere( PSItemPtr __far *data, char __far *type, int index, int scale) { register RAtom __far *ptr; register Real x, y, z; /* coordinates after rotation and translation */ register Real x_sc, y_sc, z_sc; /* coordinates scaled from Rasmol to Raster3d */ register Real rad; register ShadeDesc *shade; ptr = (RAtom __far*)data[index]; R3Dcoord(ptr->xorg+ptr->fxorg,ptr->yorg+ptr->fyorg,ptr->zorg+ptr->fzorg,x_sc,y_sc,z_sc,x,y,z); rad = Scale*(Real)(ptr->radius)/scale; /*i = ptr->col + ColourMask;*/ shade = Shade + Colour2Shade(ptr->col); fprintf(OutFile,"2 \n"); fprintf(OutFile,"%.5f %.5f %.5f %.5f ", x, y, z, rad); fprintf(OutFile,"%g %g %g\n",(Real)(shade->r)/255.0, (Real)(shade->g)/255.0 ,(Real)(shade->b)/255.0); } static void R3DSphere( int x, int y, int z, int radius, int col, int scale) { register Real x1, y1, z1; /* coordinates after rotation and translation*/ register Real x_sc, y_sc, z_sc; /* coordinates scaled from Rasmol to Raster3d*/ register Real rad; register ShadeDesc *shade; R3Dcoord(x,y,z,x_sc,y_sc,z_sc,x1,y1,z1); rad = Scale*(Real)(radius)/scale; /*i = col + ColourMask;*/ shade = Shade + Colour2Shade(col); fprintf(OutFile,"2 \n"); fprintf(OutFile,"%.5f %.5f %.5f %.5f ", (double)x, (double)y, (double)z, rad); fprintf(OutFile,"%g %g %g\n", (double) (shade->r)/255.0, (double) (shade->g)/255.0, (double) (shade->b)/255.0); } static void R3DCylinder( int x1, int y1, int z1, int x2, int y2, int z2, int col, int scale ) { register Real src_x_sc, src_y_sc, src_z_sc; register Real dst_x_sc, dst_y_sc, dst_z_sc; register Real src_x, src_y, src_z; register Real dst_x, dst_y, dst_z, bond_rad; register ShadeDesc *shade; R3Dcoord(x1,y1,z1,src_x_sc,src_y_sc,src_z_sc,src_x,src_y,src_z); R3Dcoord(x2,y2,z2,dst_x_sc,dst_y_sc,dst_z_sc,dst_x,dst_y,dst_z); bond_rad = 0.01; /*i = col + ColourMask;*/ shade = Shade + Colour2Shade(col); fprintf(OutFile,"3 \n"); fprintf(OutFile,"%.5f %.5f %.5f %.5f %.5f %.5f %.5f 0.00 " ,src_x, src_y, src_z, bond_rad, dst_x, dst_y, dst_z); fprintf(OutFile,"%g %g %g\n",(Real)(shade->r)/255.0, (Real)(shade->g)/255.0, (Real)(shade->b)/255.0); } static void WriteR3DStick( RAtom __far *src, RAtom __far *dst, int col, int rad, int scale ) { register int col1, col2; register Real src_x_sc, src_y_sc, src_z_sc; register Real dst_x_sc, dst_y_sc, dst_z_sc; register Real src_x, src_y, src_z; register Real dst_x, dst_y, dst_z, bond_rad; register Real mid_x, mid_y, mid_z; register ShadeDesc *shade; R3Dcoord(src->xorg + src->fxorg,src->yorg + src->fyorg,src->zorg + src->fzorg,src_x_sc,src_y_sc,src_z_sc,src_x,src_y,src_z); R3Dcoord(dst->xorg + dst->fxorg,dst->yorg + dst->fyorg,dst->zorg + dst->fzorg,dst_x_sc,dst_y_sc,dst_z_sc,dst_x,dst_y,dst_z); bond_rad = Scale*(Real)(rad)/scale; if( !rad ) { WriteR3DStick(src,dst,col,10,scale); return; } if( !col ) { mid_x=(src_x+dst_x)/2; mid_y=(src_y+dst_y)/2; mid_z=(src_z+dst_z)/2; col1 = src->col; col2 = dst->col; /*i = col1 + ColourMask;*/ shade = Shade + Colour2Shade(col1); fprintf(OutFile,"3 \n"); fprintf(OutFile,"%.5f %.5f %.5f %.5f %.5f %.5f %.5f 0.00 " ,src_x,src_y,src_z,bond_rad,mid_x,mid_y,mid_z); fprintf(OutFile,"%g ",(Real)(shade->r)/255.0); fprintf(OutFile,"%g ",(Real)(shade->g)/255.0); fprintf(OutFile,"%g \n",(Real)(shade->b)/255.0); /* i = col2 + ColourMask; */ shade = Shade + Colour2Shade(col2); fprintf(OutFile,"3 \n"); fprintf(OutFile,"%.5f %.5f %.5f %.5f %.5f %.5f %.5f 0.00 " ,mid_x,mid_y,mid_z,bond_rad,dst_x,dst_y,dst_z); fprintf(OutFile,"%g ",(Real)(shade->r)/255.0); fprintf(OutFile,"%g ",(Real)(shade->g)/255.0); fprintf(OutFile,"%g \n",(Real)(shade->b)/255.0); } else { /* i = col + ColourMask; */ shade = Shade + Colour2Shade(col); fprintf(OutFile,"3 \n"); fprintf(OutFile,"%.5f %.5f %.5f %.5f %.5f %.5f %.5f 0.00 " ,src_x,src_y,src_z,bond_rad,dst_x,dst_y,dst_z); fprintf(OutFile,"%g ",(Real)(shade->r)/255.0); fprintf(OutFile,"%g ",(Real)(shade->g)/255.0); fprintf(OutFile,"%g \n",(Real)(shade->b)/255.0); } } static void WriteR3DMonitor( Monitor __far* monit, int rad, int scale ) { RAtom __far *src; RAtom __far *dst; register int col,col1, col2; register int num_of_dots,j; register Real length, dot_length; register Real src_x_sc, src_y_sc, src_z_sc; register Real dst_x_sc, dst_y_sc, dst_z_sc; register Real x_incr, y_incr, z_incr; register Real src_x, src_y, src_z; register Real dst_x, dst_y, dst_z, bond_rad; register Real mid_x, mid_y, mid_z; register Real tmp_x, tmp_y, tmp_z; register Real mid_xdist, mid_ydist, mid_zdist; register Real mid_x_sc, mid_y_sc, mid_z_sc; register Real distance; static unsigned char name[22]; int units=128; register ShadeDesc *shade; src = monit->src; dst = monit->dst; col = monit->col; distance =(Real)monit->dist/100; R3Dcoord(src->xorg + src->fxorg,src->yorg + src->fyorg,src->zorg + src->fzorg,src_x_sc,src_y_sc,src_z_sc,src_x,src_y,src_z); R3Dcoord(dst->xorg + dst->fxorg,dst->yorg + dst->fyorg,dst->zorg + dst->fzorg,dst_x_sc,dst_y_sc,dst_z_sc,dst_x,dst_y,dst_z); bond_rad = Scale*(Real)(rad)/scale; dot_length = 0.01; if(!rad ) { WriteR3DMonitor(monit,10,scale); return; } if(!col) { col1 = src->col; col2 = dst->col; } else col1=col2=col; length=sqrt((src_x-dst_x)*(src_x-dst_x) + (src_y-dst_y)*(src_y-dst_y)+ (src_z-dst_z)*(src_z-dst_z)); x_incr=dot_length*(dst_x-src_x)/length; y_incr=dot_length*(dst_y-src_y)/length; z_incr=dot_length*(dst_z-src_z)/length; mid_x=(src_x+dst_x)/2; mid_y=(src_y+dst_y)/2; mid_z=(src_z+dst_z)/2; tmp_x=mid_x+x_incr/2; tmp_y=mid_y+y_incr/2; tmp_z=mid_z+z_incr/2; num_of_dots=length/dot_length; for(j=0;jr)/255.0); fprintf(OutFile,"%g ",(Real)(shade->g)/255.0); fprintf(OutFile,"%g \n",(Real)(shade->b)/255.0); tmp_x=tmp_x+ 2*x_incr; tmp_y=tmp_y+ 2*y_incr; tmp_z=tmp_z+ 2*z_incr; } tmp_x=mid_x-x_incr/2; tmp_y=mid_y-y_incr/2; tmp_z=mid_z-z_incr/2; for(j=0;jr)/255.0); fprintf(OutFile,"%g ",(Real)(shade->g)/255.0); fprintf(OutFile,"%g \n",(Real)(shade->b)/255.0); tmp_x=tmp_x-2*x_incr; tmp_y=tmp_y-2*y_incr; tmp_z=tmp_z-2*z_incr; } if(DrawMonitDistance) { if(monit-> monmode == PickDist) units=127; else if(monit-> monmode == PickAngle) units=128; if(monit-> monmode == PickTorsn) units=128; sprintf((char *)name,"%.2f%c",distance,units); R3Dcoord((src->xorg + src->fxorg + dst->xorg + dst->fxorg)/2,(src->yorg + src->fyorg + dst->yorg + dst->fyorg)/2,(src->zorg + src->fzorg + dst->zorg + dst->fzorg)/2,mid_x_sc,mid_y_sc,mid_z_sc,mid_xdist,mid_ydist,mid_zdist); OutputR3DFontString(mid_xdist,mid_ydist,mid_zdist,name,col1,scale); } } static void WriteR3DLabels(int scale) { register Chain __far *chain; register Group __far *group; register RAtom __far *aptr; register Label *label; register Real lab_x, lab_y, lab_z; register Real x_sc, y_sc, z_sc; auto unsigned char buffer[80]; static unsigned char name[22]; /* if( UseLabelCol ) { if( BackR || BackG || BackB ) { fprintf(OutFile,"%g %g %g setrgbcolor\n", LabR/250.0, LabG/250.0, LabB/250.0); } else fputs("0 setgray\n",OutFile); } else VectCol = 0; */ ForEachAtom if( aptr->label ) { /* if( !UseLabelCol && (aptr->col!=VectCol) )*/ /* WriteVectColour( aptr->col );*/ label = (Label*)aptr->label; FormatLabel(chain,group,aptr,label->label,buffer); sprintf((char *)name,"%s",buffer); R3Dcoord(aptr->xorg + aptr->fxorg,aptr->yorg + aptr->fyorg,aptr->zorg + aptr->fzorg,x_sc,y_sc,z_sc,lab_x,lab_y,lab_z); OutputR3DFontString(lab_x, lab_y, lab_z,name,aptr->col,scale); } } static void OutputR3DCharacter( Real x, Real y, Real z, int glyph, int col,Real scale, Real r3d_font_scale) { register char *ptr; register Real sx,sy; register Real ex,ey; register Real out_x1, out_y1, out_z, out_x2, out_y2; register ShadeDesc *shade; ex = x; ey = y; /*i = col + ColourMask;*/ shade = Shade + Colour2Shade(col); ptr = VectFont[glyph]; while( *ptr ) { /* Uppercase test */ if( ptr[0] < 'a' ) { sx = x + r3d_font_scale*FontDimen[ptr[0]-'A']; sy = y + InvertY(r3d_font_scale*FontDimen[ptr[1]-'a']); ptr += 2; } else { sx = ex; sy = ey; } ex = x + r3d_font_scale*FontDimen[ptr[0]-'a']; ey = y + InvertY(r3d_font_scale*FontDimen[ptr[1]-'a']); out_x1 = sx; out_x2 = ex; out_y1 = InvertY(sy); out_y2 = InvertY(ey); out_z = 1.36; fprintf(OutFile,"3 \n"); if (FontStroke < 1 ) fprintf(OutFile,"%.5f %.5f %.5f 0.001 %.5f %.5f %.5f 0.00 " ,out_x1,out_y1,out_z,out_x2,out_y2,out_z); else fprintf(OutFile,"%.5f %.5f %.5f %.5f %.5f %.5f %.5f 0.00 " ,out_x1,out_y1,out_z,FontStroke*0.002,out_x2,out_y2,out_z); fprintf(OutFile,"%g ",(Real)(shade->r)/255.0); fprintf(OutFile,"%g ",(Real)(shade->g)/255.0); fprintf(OutFile,"%g \n",(Real)(shade->b)/255.0); ptr += 2; } } void OutputR3DFontString( Real x, Real y, Real z, unsigned char *label, int col, Real scale ) { register Real r3d_font_scale =0.0015; while( *label ) { OutputR3DCharacter(x,y,z,(*label-32),col,scale,r3d_font_scale); x += r3d_font_scale * FontWid[(*label-32)]+ r3d_font_scale * FontStroke; label++; } } /*==============================*/ /* Ribbon & Cartoon Functions */ /*==============================*/ /* SplineCount is either 1, 2, 3, 4, 5 or 9! */ void R3DStrandRibbon( Knot __far *src, Knot __far *dst, int col1, int col2, Real scale ) { register int hsx, hsy, hsz; register int hdx, hdy, hdz; register int qsx, qsy, qsz; register int qdx, qdy, qdz; register int col; register Real x1, y1, z1; register Real x2, y2, z2; register Real src_x, src_y, src_z; register Real dst_x, dst_y, dst_z; register Real bond_rad; register ShadeDesc *shade; bond_rad=0.003; if( SplineCount != 4 ) { if( SplineCount == 1 ) { R3Dcoord(src->px,src->py,src->pz,x1,y1,z1,src_x,src_y,src_z); R3Dcoord(dst->px,dst->py,dst->pz,x2,y2,z2,dst_x,dst_y,dst_z); /* i = col2 + ColourMask; */ shade = Shade + Colour2Shade(col2); fprintf(OutFile,"3 \n"); fprintf(OutFile,"%.5f %.5f %.5f %.5f %.5f %.5f %.5f 0.00 " , src_x, src_y, src_z, bond_rad, dst_x, dst_y, dst_z); fprintf(OutFile,"%g %g %g\n", (Real)(shade->r)/255.0, (Real)(shade->g)/255.0, (Real)(shade->b)/255.0); return; } else if( SplineCount != 2 ) { R3Dcoord(src->px,src->py,src->pz,x1,y1,z1,src_x,src_y,src_z); R3Dcoord(dst->px,dst->py,dst->pz,x2,y2,z2,dst_x,dst_y,dst_z); /* i = col1 + ColourMask; */ shade = Shade + Colour2Shade(col1); fprintf(OutFile,"3 \n"); fprintf(OutFile,"%.5f %.5f %.5f %.5f %.5f %.5f %.5f 0.00 " , src_x, src_y, src_z, bond_rad, dst_x, dst_y, dst_z); fprintf(OutFile,"%g %g %g\n", (Real)(shade->r)/255.0, (Real)(shade->g)/255.0, (Real)(shade->b)/255.0); } R3Dcoord(src->px + src->wx,src->py + src->wy,src->pz + src->wz,x1,y1,z1,src_x,src_y,src_z); R3Dcoord(dst->px + dst->wx,dst->py + dst->wy,dst->pz + dst->wz,x2,y2,z2,dst_x,dst_y,dst_z); /* i = col2 + ColourMask; */ shade = Shade + Colour2Shade(col2); fprintf(OutFile,"3 \n"); fprintf(OutFile,"%.5f %.5f %.5f %.5f %.5f %.5f %.5f 0.00 " , src_x, src_y, src_z, bond_rad, dst_x, dst_y, dst_z); fprintf(OutFile,"%g %g %g\n", (Real)(shade->r)/255.0, (Real)(shade->g)/255.0, (Real)(shade->b)/255.0); R3Dcoord(src->px - src->wx,src->py - src->wy,src->pz - src->wz,x1,y1,z1,src_x,src_y,src_z); R3Dcoord(dst->px - dst->wx,dst->py - dst->wy,dst->pz - dst->wz,x2,y2,z2,dst_x,dst_y,dst_z); /* i = col2 + ColourMask; */ shade = Shade + Colour2Shade(col2); fprintf(OutFile,"3 \n"); fprintf(OutFile,"%.5f %.5f %.5f %.5f %.5f %.5f %.5f 0.00 " , src_x, src_y, src_z, bond_rad, dst_x, dst_y, dst_z); fprintf(OutFile,"%g %g %g\n", (Real)(shade->r)/255.0, (Real)(shade->g)/255.0, (Real)(shade->b)/255.0); if( SplineCount<=3 ) return; hsx = src->wx/2; hsy = src->wy/2; hsz = src->wz/2; hdx = dst->wx/2; hdy = dst->wy/2; hdz = dst->wz/2; R3Dcoord(src->px + hsx,src->py + hsy,src->pz + hsz,x1,y1,z1,src_x,src_y,src_z); R3Dcoord(dst->px + hdx,dst->py + hdy,dst->pz + hdz,x2,y2,z2,dst_x,dst_y,dst_z); /* i = col1 + ColourMask; */ shade = Shade + Colour2Shade(col1); fprintf(OutFile,"3 \n"); fprintf(OutFile,"%.5f %.5f %.5f %.5f %.5f %.5f %.5f 0.00 " , src_x, src_y, src_z, bond_rad, dst_x, dst_y, dst_z); fprintf(OutFile,"%g %g %g\n", (Real)(shade->r)/255.0, (Real)(shade->g)/255.0, (Real)(shade->b)/255.0); R3Dcoord(src->px - hsx,src->py - hsy,src->pz - hsz,x1,y1,z1,src_x,src_y,src_z); R3Dcoord(dst->px - hdx,dst->py - hdy,dst->pz - hdz,x2,y2,z2,dst_x,dst_y,dst_z); /* i = col1 + ColourMask; */ shade = Shade + Colour2Shade(col1); fprintf(OutFile,"3 \n"); fprintf(OutFile,"%.5f %.5f %.5f %.5f %.5f %.5f %.5f 0.00 " , src_x, src_y, src_z, bond_rad, dst_x, dst_y, dst_z); fprintf(OutFile,"%g %g %g\n", (Real)(shade->r)/255.0, (Real)(shade->g)/255.0, (Real)(shade->b)/255.0); if( SplineCount==5 ) return; col = col1; } else /* SplineCount == 4 */ { hsx = src->wx/2; hsy = src->wy/2; hsz = src->wz/2; hdx = dst->wx/2; hdy = dst->wy/2; hdz = dst->wz/2; col = col2; } qsx = hsx/2; qsy = hsy/2; qsz = hsz/2; qdx = hdx/2; qdy = hdy/2; qdz = hdz/2; R3Dcoord(src->px + hsx + qsx,src->py + hsy + qsy,src->pz + hsz + qsy,x1,y1,z1,src_x,src_y,src_z); R3Dcoord(dst->px + hdx + qdx,dst->py + hdy + qdy,dst->pz + hdz + qdz,x2,y2,z2,dst_x,dst_y,dst_z); /* i = col + ColourMask; */ shade = Shade + Colour2Shade(col); fprintf(OutFile,"3 \n"); fprintf(OutFile,"%.5f %.5f %.5f %.5f %.5f %.5f %.5f 0.00 " , src_x, src_y, src_z, bond_rad, dst_x, dst_y, dst_z); fprintf(OutFile,"%g %g %g\n", (Real)(shade->r)/255.0, (Real)(shade->g)/255.0, (Real)(shade->b)/255.0); R3Dcoord(src->px + hsx - qsx,src->py + hsy - qsy,src->pz + hsz - qsy,x1,y1,z1,src_x,src_y,src_z); R3Dcoord(dst->px + hdx - qdx,dst->py + hdy - qdy,dst->pz + hdz - qdz,x2,y2,z2,dst_x,dst_y,dst_z); /* i = col1 + ColourMask; */ shade = Shade + Colour2Shade(col1); fprintf(OutFile,"3 \n"); fprintf(OutFile,"%.5f %.5f %.5f %.5f %.5f %.5f %.5f 0.00 " , src_x, src_y, src_z, bond_rad, dst_x, dst_y, dst_z); fprintf(OutFile,"%g %g %g\n", (Real)(shade->r)/255.0, (Real)(shade->g)/255.0, (Real)(shade->b)/255.0); R3Dcoord(src->px - hsx + qsx,src->py - hsy + qsy,src->pz - hsz + qsy,x1,y1,z1,src_x,src_y,src_z); R3Dcoord(dst->px - hdx + qdx,dst->py - hdy + qdy,dst->pz - hdz + qdz,x2,y2,z2,dst_x,dst_y,dst_z); /* i = col1 + ColourMask; */ shade = Shade + Colour2Shade(col1); fprintf(OutFile,"3 \n"); fprintf(OutFile,"%.5f %.5f %.5f %.5f %.5f %.5f %.5f 0.00 " , src_x, src_y, src_z, bond_rad, dst_x, dst_y, dst_z); fprintf(OutFile,"%g %g %g\n", (Real)(shade->r)/255.0, (Real)(shade->g)/255.0, (Real)(shade->b)/255.0); R3Dcoord(src->px - hsx - qsx,src->py - hsy - qsy,src->pz - hsz - qsy,x1,y1,z1,src_x,src_y,src_z); R3Dcoord(dst->px - hdx - qdx,dst->py - hdy - qdy,dst->pz - hdz - qdz,x2,y2,z2,dst_x,dst_y,dst_z); /* i = col + ColourMask; */ shade = Shade + Colour2Shade(col); fprintf(OutFile,"3 \n"); fprintf(OutFile,"%.5f %.5f %.5f %.5f %.5f %.5f %.5f 0.00 " , src_x, src_y, src_z, bond_rad, dst_x, dst_y, dst_z); fprintf(OutFile,"%g %g %g\n", (Real)(shade->r)/255.0, (Real)(shade->g)/255.0, (Real)(shade->b)/255.0); } /* void SolidRibbon2( Knot __far *src, Knot __far *dst, int col1, int col2 ) { register int dx,dy; register int col; static Poly p; p.count = 3; p.v[0].x = src->px+src->wx; p.v[0].y = src->py+src->wy; p.v[0].z = src->pz+src->wz; p.v[1].x = dst->px-dst->wx; p.v[1].y = dst->py-dst->wy; p.v[1].z = dst->pz-dst->wz; dx = p.v[1].x - p.v[0].x; dy = p.v[1].y - p.v[0].y; p.v[2].x = dst->px+dst->wx; p.v[2].y = dst->py+dst->wy; p.v[2].z = dst->pz+dst->wz; #ifdef INVERT col = ( dst->wx*dy > dst->wy*dx )? col2 : col1; #else col = ( dst->wx*dy < dst->wy*dx )? col2 : col1; #endif p.v[0].inten = src->vinten+col; p.v[1].inten = dst->vinten+col; p.v[2].inten = dst->vinten+col; ClipPolygon( &p ); p.v[2].x = src->px-src->wx; p.v[2].y = src->py-src->wy; p.v[2].z = src->pz-src->wz; #ifdef INVERT col = ( src->wx*dy > src->wy*dx )? col2 : col1; #else col = ( src->wx*dy < src->wy*dx )? col2 : col1; #endif p.v[0].inten = src->vinten+col; p.v[1].inten = dst->vinten+col; p.v[2].inten = src->vinten+col; ClipPolygon( &p ); } */ /*void normals(Real p1_x, Real p1_y, Real p1_z, Real p2_x, Real p2_y, Real p2_z, Real p3_x, Real p3_y, Real p3_z, Real $res_x, Real $res_y, Real $res_z) { vect1_x = p1_x - p2_x; vect1_y = p1_y - p2_y; vect1_z = p1_z - p2_z; vect2_x = p1_x - p3_x; vect2_y = p1_y - p3_y; vect2_z = p1_z - p3_z; nor1_x= vect1_y*vect2_z - vect1_z*vect2_y; nor1_y= vect1_z*vect2_x - vect1_x*vect2_z; nor1_z= vect1_x*vect2_y - vect1_y*vect2_x; if( (vect1_x*vect2_x + vect1_y*vect2_y + vect1_z*vect2_z) < 0 ) { nor1_x = - nor1_x; nor1_y = - nor1_y; nor1_z = - nor1_z; } }*/ #ifdef UNUSED void CalculateVInten( Knot *ptr ) { register Real inten; if( !ptr->vsize ) ptr->vsize = isqrt( (Long)ptr->vnx*ptr->vnx + (Long)ptr->vny*ptr->vny + (Long)ptr->vnz*ptr->vnz ) + 1; #ifdef ORIGINAL inten = LightDot(ptr->vnx,-InvertY(ptr->vny),ptr->vnz); inten /= ptr->vsize*LightLength; #else inten = (Real)ptr->vnz/ptr->vsize; #endif if( ptr->vnz < 0 ) inten = -inten; if( inten > 0.0 ) { ptr->vinten = (char)(ColourMask*inten); } else ptr->vinten = 0; } void CalculateHInten( Knot *ptr ) { register Real inten; /* The intensity of the sides of a protein cartoon * may be calculated using ptr->cx,cy,cz and this * should save interpolating ptr->hnx,hny,hnz! */ if( !ptr->hsize ) ptr->hsize = isqrt( (Long)ptr->hnx*ptr->hnx + (Long)ptr->hny*ptr->hny + (Long)ptr->hnz*ptr->hnz ) + 1; #ifdef ORIGINAL inten = LightDot(ptr->hnx,-InvertY(ptr->hny),ptr->hnz); inten /= ptr->hsize*LightLength; #else inten = (Real)ptr->hnz / ptr->hsize; #endif if( ptr->hnz < 0 ) inten = -inten; if( inten > 0.0 ) { ptr->hinten = (char)(ColourMask*inten); } else ptr->hinten = 0; } #endif void Cartoon_ribdata( Knot __far *src, Knot __far *dst, R3DRib __far** front, R3DRib __far** back, R3DRib __far** side1, R3DRib __far** side2, int col, Real scale) { Real x1, x2, x3, x4; Real y1, y2, y3, y4; Real z1, z2, z3, z4; /* top surface*/ x1= src->px + src->wx + src->dx; y1= src->py + src->wy + src->dy; z1= src->pz + src->wz + src->dz; x2= dst->px + dst->wx + dst->dx; y2= dst->py + dst->wy + dst->dy; z2= dst->pz + dst->wz + dst->dz; x3= dst->px - dst->wx + dst->dx; y3= dst->py - dst->wy + dst->dy; z3= dst->pz - dst->wz + dst->dz; x4= src->px - src->wx + src->dx; y4= src->py - src->wy + src->dy; z4= src->pz - src->wz + src->dz; *front = Add_ribdata(x1, y1, z1, x4, y4, z4, x2, y2, z2,*front, col, scale); *front = Add_ribdata(x4, y4, z4, x2, y2, z2, x3, y3, z3,*front, col, scale); /* bottom surface*/ x1= src->px + src->wx - src->dx; y1= src->py + src->wy - src->dy; z1= src->pz + src->wz - src->dz; x2= dst->px + dst->wx - dst->dx; y2= dst->py + dst->wy - dst->dy; z2= dst->pz + dst->wz - dst->dz; x3= dst->px - dst->wx - dst->dx; y3= dst->py - dst->wy - dst->dy; z3= dst->pz - dst->wz - dst->dz; x4= src->px - src->wx - src->dx; y4= src->py - src->wy - src->dy; z4= src->pz - src->wz - src->dz; *back = Add_ribdata(x1, y1, z1, x4, y4, z4, x2, y2, z2,*back, col, scale); *back = Add_ribdata(x4, y4, z4, x2, y2, z2, x3, y3, z3,*back, col, scale); /*side1*/ x1 = src->px + src->wx + src->dx; y1 = src->py + src->wy + src->dy; z1 = src->pz + src->wz + src->dz; x2 = dst->px + dst->wx + dst->dx; y2 = dst->py + dst->wy + dst->dy; z2 = dst->pz + dst->wz + dst->dz; x3 = dst->px + dst->wx - dst->dx; y3 = dst->py + dst->wy - dst->dy; z3 = dst->pz + dst->wz - dst->dz; x4 = src->px + src->wx - src->dx; y4 = src->py + src->wy - src->dy; z4 = src->pz + src->wz - src->dz; *side1 = Add_ribdata(x1, y1, z1, x4, y4, z4, x2, y2, z2,*side1, col, scale); *side1 = Add_ribdata(x4, y4, z4, x2, y2, z2, x3, y3, z3,*side1, col, scale); /*side2*/ x1 = src->px - src->wx + src->dx; y1 = src->py - src->wy + src->dy; z1 = src->pz - src->wz + src->dz; x2 = dst->px - dst->wx + dst->dx; y2 = dst->py - dst->wy + dst->dy; z2 = dst->pz - dst->wz + dst->dz; x3 = dst->px - dst->wx - dst->dx; y3 = dst->py - dst->wy - dst->dy; z3 = dst->pz - dst->wz - dst->dz; x4 = src->px - src->wx - src->dx; y4 = src->py - src->wy - src->dy; z4 = src->pz - src->wz - src->dz; *side2 = Add_ribdata(x1, y1, z1, x4, y4, z4, x2, y2, z2,*side2, col, scale); *side2 = Add_ribdata(x4, y4, z4, x2, y2, z2, x3, y3, z3,*side2, col, scale); } R3DRib __far * Poly_ribdata( Knot __far *src, Knot __far *dst, R3DRib __far* curdata, int col, Real scale) { Real x1, x2, x3, x4; Real y1, y2, y3, y4; Real z1, z2, z3, z4; x1= src->px + src->wx; y1= src->py + src->wy; z1= src->pz + src->wz; x2= dst->px + dst->wx; y2= dst->py + dst->wy; z2= dst->pz + dst->wz; x3= dst->px - dst->wx; y3= dst->py - dst->wy; z3= dst->pz - dst->wz; x4= src->px - src->wx; y4= src->py - src->wy; z4= src->pz - src->wz; curdata = Add_ribdata(x1, y1, z1, x4, y4, z4, x2, y2, z2, curdata, col, scale); curdata = Add_ribdata(x4, y4, z4, x2, y2, z2, x3, y3, z3, curdata, col, scale); return curdata; } R3DRib __far *Add_ribdata( Real in_x1, Real in_y1, Real in_z1, Real in_x2, Real in_y2, Real in_z2, Real in_x3, Real in_y3, Real in_z3, R3DRib __far* curdata,int col, Real scale) { Real n1_x, n1_y, n1_z; Real vect1_x, vect1_y, vect1_z; Real vect2_x, vect2_y, vect2_z; R3DRib __far *xtemp; xtemp = (R3DRib __far *)_fmalloc(sizeof(R3DRib)); R3DcoordC((Real)(in_x1),(Real)(in_y1),(Real)(in_z1),xtemp->x1,xtemp->y1,xtemp->z1); R3DcoordC((Real)(in_x2),(Real)(in_y2),(Real)(in_z2),xtemp->x2,xtemp->y2,xtemp->z2); R3DcoordC((Real)(in_x3),(Real)(in_y3),(Real)(in_z3),xtemp->x3,xtemp->y3,xtemp->z3); /* xtemp->x1= Scale*(Real)(in_x1)/scale; xtemp->y1= InvertY(Scale*(Real)(in_y1)/scale); xtemp->z1= Scale*(Real)(in_z1)/scale; xtemp->x2= Scale*(Real)(in_x2)/scale; xtemp->y2= InvertY(Scale*(Real)(in_y2)/scale); xtemp->z2= Scale*(Real)(in_z2)/scale; xtemp->x3= Scale*(Real)(in_x3)/scale; xtemp->y3= InvertY(Scale*(Real)(in_y3)/scale); xtemp->z3= Scale*(Real)(in_z3)/scale; */ vect1_x= xtemp->x3 - xtemp->x1; vect1_y= xtemp->y3 - xtemp->y1; vect1_z= xtemp->z3 - xtemp->z1; vect2_x= xtemp->x2 - xtemp->x1; vect2_y= xtemp->y2 - xtemp->y1; vect2_z= xtemp->z2 - xtemp->z1; n1_x= vect1_y*vect2_z - vect1_z*vect2_y; n1_y= vect1_z*vect2_x - vect1_x*vect2_z; n1_z= vect1_x*vect2_y - vect1_y*vect2_x; xtemp->norm1_x = xtemp->norm2_x = xtemp->norm3_x = n1_x; xtemp->norm1_y = xtemp->norm2_y = xtemp->norm3_y = n1_y; xtemp->norm1_z = xtemp->norm2_z = xtemp->norm3_z = n1_z; xtemp->col = col; xtemp->next = curdata; return xtemp; } void R3DSolidRib(R3DRib __far *ribdata) { Real x_av, y_av, z_av; R3DRib __far *beg_ribdata; register ShadeDesc *shade; beg_ribdata = ribdata; if (!ribdata) return; for(;ribdata->next;ribdata=ribdata->next) { if((ribdata->norm1_x*ribdata->next->norm1_x + ribdata->norm1_y*ribdata->next->norm1_y + ribdata->norm1_z*ribdata->next->norm1_z) < 0 ) { ribdata->next->norm1_x = ribdata->next->norm2_x = ribdata->next->norm3_x = - ribdata->next->norm1_x; ribdata->next->norm1_y = ribdata->next->norm2_y = ribdata->next->norm3_y = - ribdata->next->norm1_y; ribdata->next->norm1_z = ribdata->next->norm2_z = ribdata->next->norm3_z = - ribdata->next->norm1_z; } } ribdata= beg_ribdata; for(;ribdata->next->next;ribdata=ribdata->next) { x_av= (ribdata->norm1_x + ribdata->next->norm2_x + ribdata->next->next->norm3_x)/3; y_av= (ribdata->norm1_y + ribdata->next->norm2_y + ribdata->next->next->norm3_y)/3; z_av= (ribdata->norm1_z + ribdata->next->norm2_z + ribdata->next->next->norm3_z)/3; ribdata->norm1_x = ribdata->next->norm2_x = ribdata->next->next->norm3_x = x_av; ribdata->norm1_y = ribdata->next->norm2_y = ribdata->next->next->norm3_y = y_av; ribdata->norm1_z = ribdata->next->norm2_z = ribdata->next->next->norm3_z = z_av; } for( ;beg_ribdata; beg_ribdata = beg_ribdata->next) { fprintf(OutFile,"1\n"); fprintf(OutFile,"%.5f %.5f %.5f %.5f %.5f %.5f %.5f %.5f %.5f " ,beg_ribdata->x1, beg_ribdata->y1, beg_ribdata->z1 ,beg_ribdata->x2, beg_ribdata->y2, beg_ribdata->z2 ,beg_ribdata->x3, beg_ribdata->y3, beg_ribdata->z3); /* i = beg_ribdata->col + ColourMask; */ shade = Shade + Colour2Shade(beg_ribdata->col); fprintf(OutFile,"%g %g %g\n", (Real)(shade->r)/255.0, (Real)(shade->g)/255.0, (Real)(shade->b)/255.0); fprintf(OutFile,"7\n"); fprintf(OutFile,"%.5f %.5f %.5f %.5f %.5f %.5f %.5f %.5f %.5f\n " ,beg_ribdata->norm1_x, beg_ribdata->norm1_y, beg_ribdata->norm1_z ,beg_ribdata->norm2_x, beg_ribdata->norm2_y, beg_ribdata->norm2_z ,beg_ribdata->norm3_x, beg_ribdata->norm3_y, beg_ribdata->norm3_z); } } void WriteR3DRibbon( Chain __far *chain, Real scale ) { register Group __far *group; register RAtom __far *captr; register RAtom __far *o1ptr; register RAtom __far *o2ptr; register RAtom __far *next; register int prev, wide; register int col1,col2; register int bx,by,bz; register int dx,dy,dz; register int arrow; register int size; R3DRib __far *ribdata; R3DRib __far *front, *back, *side1, *side2; int cartoon_flag; static Knot mid1, mid2, mid3; static Knot knot1, knot2; cartoon_flag = 0; ribdata = front = back = side1 = side2 =NULL; prev = False; group = chain->glist; if( IsProtein(group->refno) ) captr = FindGroupAtom(group,1); else captr = FindGroupAtom(group,7); while( group->gnext ) { if( IsProtein(group->gnext->refno) ) { next = FindGroupAtom(group->gnext,1); o1ptr = FindGroupAtom(group,3); } else /* Nucleic Acid */ { next = FindGroupAtom(group->gnext,7); o1ptr = FindGroupAtom(group->gnext,10); } /* When not to have a control point! */ if( !next || !captr || !o1ptr || (next->flag&BreakFlag) || !((group->flag|group->gnext->flag)&DrawKnotFlag) ) { group = group->gnext; captr = next; prev = False; continue; } knot2.tx = next->xorg - captr->xorg + next->fxorg - captr->fxorg ; knot2.ty = next->yorg - captr->yorg + next->fyorg - captr->fyorg; knot2.tz = next->zorg - captr->zorg + next->fzorg - captr->fzorg; if( IsProtein(group->refno) ) { bx = o1ptr->xorg - captr->xorg + o1ptr->fxorg - captr->fxorg; by = o1ptr->yorg - captr->yorg + o1ptr->fyorg - captr->fyorg; bz = o1ptr->zorg - captr->zorg + o1ptr->fzorg - captr->fzorg; } else /* Nucleic Acid */ { o2ptr = FindGroupAtom(group,8); if( o2ptr && !FindGroupAtom(group,17) ) { /* Deoxyribonucleic Acid */ bx = (o1ptr->xorg + o2ptr->xorg)/2 - captr->xorg + (o1ptr->fxorg + o2ptr->fxorg)/2 - captr->fxorg; by = (o1ptr->yorg + o2ptr->yorg)/2 - captr->yorg + (o1ptr->fyorg + o2ptr->fyorg)/2 - captr->fyorg; bz = (o1ptr->zorg + o2ptr->zorg)/2 - captr->zorg + (o1ptr->fzorg + o2ptr->fzorg)/2 - captr->fzorg; } else { /* Ribonucleic Acid */ bx = o1ptr->xorg - captr->xorg + o1ptr->fxorg - captr->fxorg; by = o1ptr->yorg - captr->yorg + o1ptr->fyorg - captr->fyorg; bz = o1ptr->zorg - captr->zorg + o1ptr->fzorg - captr->fzorg; } } knot2.px = (captr->xorg + next->xorg)/2 + (captr->fxorg + next->fxorg)/2; knot2.py = (captr->yorg + next->yorg)/2 + (captr->fyorg + next->fyorg)/2; knot2.pz = (captr->zorg + next->zorg)/2 + (captr->fzorg + next->fzorg)/2; /* c := a x b */ knot2.vnx = knot2.ty*bz*Scale*Scale - knot2.tz*by*Scale*Scale; knot2.vny = knot2.tz*bx*Scale*Scale - knot2.tx*bz*Scale*Scale; knot2.vnz = knot2.tx*by*Scale*Scale - knot2.ty*bx*Scale*Scale; if( (group->struc&group->gnext->struc) & HelixFlag ) { /* Compensate for narrowing of helices! */ size = isqrt((Long)knot2.vnx*knot2.vnx + (Long)knot2.vny*knot2.vny + (Long)knot2.vnz*knot2.vnz); knot2.vsize = size; if( size ) { /* 1.00 Angstrom Displacement */ wide = 250; #ifdef INVERT knot2.px += (int)(((Long)wide*knot2.vnx)/size); knot2.py += (int)(((Long)wide*knot2.vny)/size); knot2.pz += (int)(((Long)wide*knot2.vnz)/size); #else knot2.px -= (int)(((Long)wide*knot2.vnx)/size); knot2.py -= (int)(((Long)wide*knot2.vny)/size); knot2.pz -= (int)(((Long)wide*knot2.vnz)/size); #endif } } else knot2.vsize = 0; if( !(group->flag&group->gnext->flag&TraceFlag) ) { /* d := c x a */ dx = (int)(((Long)knot2.vny*knot2.tz - (Long)knot2.vnz*knot2.ty)/96); dy = (int)(((Long)knot2.vnz*knot2.tx - (Long)knot2.vnx*knot2.tz)/96); dz = (int)(((Long)knot2.vnx*knot2.ty - (Long)knot2.vny*knot2.tx)/96); knot2.hsize = isqrt((Long)dx*dx + (Long)dy*dy + (Long)dz*dz); /* Handle Carbonyl Oxygen Flip */ if( prev && (((Long)knot1.hnx*dx + (Long)knot1.hny*dy + (Long)knot1.hnz*dz)<0) ) { knot2.hnx = -dx; knot2.vnx = -knot2.vnx; knot2.hny = -dy; knot2.vny = -knot2.vny; knot2.hnz = -dz; knot2.vnz = -knot2.vnz; } else { knot2.hnx = dx; knot2.hny = dy; knot2.hnz = dz; } arrow = False; if( group->flag&CartoonFlag ) { if( DrawBetaArrows && (group->struc&SheetFlag) && !(group->gnext->struc&SheetFlag) ) { wide = (3*group->width)>>1; arrow = True; } else wide = group->width; } else if( group->flag & WideKnotFlag ) { /* Average Ribbon Width */ if( group->gnext->flag & WideKnotFlag ) wide = (group->width+group->gnext->width)>>1; else if( group->gnext->flag & CartoonFlag ) wide = group->gnext->width; else wide = group->width; } else wide = group->gnext->width; if( knot2.hsize && !arrow ) { size = knot2.hsize; knot2.wx = (int)(((Long)wide*knot2.hnx)/size); knot2.wy = (int)(((Long)wide*knot2.hny)/size); knot2.wz = (int)(((Long)wide*knot2.hnz)/size); knot2.wide = (short)wide; } else { knot2.wide = 0; knot2.wx = 0; knot2.wy = 0; knot2.wz = 0; } if( group->flag & CartoonFlag ) if( prev && (knot1.wide!=wide) && knot1.hsize ) { size = knot1.hsize; knot1.wx = (int)(((Long)wide*knot1.hnx)/size); knot1.wy = (int)(((Long)wide*knot1.hny)/size); knot1.wz = (int)(((Long)wide*knot1.hnz)/size); } if( (group->flag|group->gnext->flag)&CartoonFlag ) { CalculateVInten( &knot2 ); CalculateHInten( &knot2 ); size = knot2.vsize; wide = (int)(CartoonHeight); knot2.dx = (int)(((Long)wide*knot2.vnx)/size); knot2.dy = (int)(((Long)wide*knot2.vny)/size); knot2.dz = (int)(((Long)wide*knot2.vnz)/size); } else if( (group->flag|group->gnext->flag)&RibbonFlag ) {} CalculateVInten( &knot2 ); } if( !(col1 = group->col1) ) col1 = captr->col; if( prev ) { /* Approximate spline segment with plane! */ /* Calculate Hermite Spline Points */ mid1.px = (int)(((Long)54*knot1.px + (Long)9*knot1.tx + (Long)10*knot2.px - (Long)3*knot2.tx)/64); mid1.py = (int)(((Long)54*knot1.py + (Long)9*knot1.ty + (Long)10*knot2.py - (Long)3*knot2.ty)/64); mid1.pz = (int)(((Long)54*knot1.pz + (Long)9*knot1.tz + (Long)10*knot2.pz - (Long)3*knot2.tz)/64); mid2.px = (int)(((Long)4*knot1.px + knot1.tx + (Long)4*knot2.px - knot2.tx)/8); mid2.py = (int)(((Long)4*knot1.py + knot1.ty + (Long)4*knot2.py - knot2.ty)/8); mid2.pz = (int)(((Long)4*knot1.pz + knot1.tz + (Long)4*knot2.pz - knot2.tz)/8); mid3.px = (int)(((Long)10*knot1.px + (Long)3*knot1.tx + (Long)54*knot2.px - (Long)9*knot2.tx)/64); mid3.py = (int)(((Long)10*knot1.py + (Long)3*knot1.ty + (Long)54*knot2.py - (Long)9*knot2.ty)/64); mid3.pz = (int)(((Long)10*knot1.pz + (Long)3*knot1.tz + (Long)54*knot2.pz - (Long)9*knot2.tz)/64); if( group->flag & TraceFlag ) { wide = (int)(group->width); R3DCylinder(knot1.px+CenX, knot1.py+CenY, knot1.pz+CenZ, mid1.px+CenX, mid1.py+CenY, mid1.pz+CenZ, col1, scale ); R3DCylinder(mid1.px+CenX, mid1.py, mid1.pz, mid2.px+CenX, mid2.py+CenY, mid2.pz+CenZ, col1, scale ); R3DCylinder(mid2.px+CenX, mid2.py, mid2.pz, mid3.px+CenX, mid3.py+CenY, mid3.pz+CenZ, col1, scale ); R3DCylinder(mid3.px+CenX, mid3.py, mid3.pz, knot2.px+CenX, knot2.py+CenY, knot2.pz+CenZ, col1, scale ); } else if( group->flag & DotsFlag ) { wide = (int)(group->width); R3DSphere(knot1.px+CenX, knot1.py+CenY, knot1.pz+CenZ, wide, col1,scale); R3DSphere(mid2.px+CenX, mid2.py+CenY, mid2.pz+CenZ, wide, col1,scale); } else { /* Calculate Hermite Spline Widths */ mid1.wx = (27*knot1.wx + 5*knot2.wx)/32; mid1.wy = (27*knot1.wy + 5*knot2.wy)/32; mid1.wz = (27*knot1.wz + 5*knot2.wz)/32; mid2.wx = (knot1.wx + knot2.wx)/2; mid2.wy = (knot1.wy + knot2.wy)/2; mid2.wz = (knot1.wz + knot2.wz)/2; mid3.wx = (5*knot1.wx + 27*knot2.wx)/32; mid3.wy = (5*knot1.wy + 27*knot2.wy)/32; mid3.wz = (5*knot1.wz + 27*knot2.wz)/32; /* Draw the Spline Segments */ if( group->flag & (StrandFlag|DashStrandFlag) ) { if( !(col2 = group->col2) ) col2 = captr->col; R3DStrandRibbon( &knot1, &mid1, col1, col2, scale ); R3DStrandRibbon( &mid1, &mid2, col1, col2, scale ); R3DStrandRibbon( &mid2, &mid3, col1, col2, scale ); R3DStrandRibbon( &mid3, &knot2, col1, col2, scale ); } else /* Ribbon or Cartoon! */ { mid1.vsize = 0; mid1.vnx = (int)(((Long)27*knot1.vnx + (Long) 5*knot2.vnx)/32); mid1.vny = (int)(((Long)27*knot1.vny + (Long) 5*knot2.vny)/32); mid1.vnz = (int)(((Long)27*knot1.vnz + (Long) 5*knot2.vnz)/32); CalculateVInten( &mid1 ); mid2.vsize = 0; mid2.vnx = (knot1.vnx + knot2.vnx)/2; mid2.vny = (knot1.vny + knot2.vny)/2; mid2.vnz = (knot1.vnz + knot2.vnz)/2; CalculateVInten( &mid2 ); mid3.vsize = 0; mid3.vnx = (int)(((Long) 5*knot1.vnx + (Long)27*knot2.vnx)/32); mid3.vny = (int)(((Long) 5*knot1.vny + (Long)27*knot2.vny)/32); mid3.vnz = (int)(((Long) 5*knot1.vnz + (Long)27*knot2.vnz)/32); CalculateVInten( &mid3 ); if( group->flag & RibbonFlag ) { if( group->struc & HelixFlag ) { if( !(col2 = group->col2) ) col2 = captr->col; } else col2 = col1; if( col1 != col2 ) { /* SolidRibbon2( &knot1, &mid1, col1, col2 ); SolidRibbon2( &mid1, &mid2, col1, col2 ); SolidRibbon2( &mid2, &mid3, col1, col2 ); SolidRibbon2( &mid3, &knot2, col1, col2 );*/ } else { ribdata = Poly_ribdata( &knot1, &mid1, ribdata, col1, scale ); ribdata = Poly_ribdata( &mid1, &mid2, ribdata, col1, scale ); ribdata = Poly_ribdata( &mid2, &mid3, ribdata, col1, scale ); ribdata = Poly_ribdata( &mid3, &knot2, ribdata, col1, scale ); } } else /* Cartoon! */ { /* Calculate Spline Heights */ wide = (int)(CartoonHeight); size = mid1.vsize; mid1.dx = (int)(((Long)wide*mid1.vnx)/size); mid1.dy = (int)(((Long)wide*mid1.vny)/size); mid1.dz = (int)(((Long)wide*mid1.vnz)/size); size = mid2.vsize; mid2.dx = (int)(((Long)wide*mid2.vnx)/size); mid2.dy = (int)(((Long)wide*mid2.vny)/size); mid2.dz = (int)(((Long)wide*mid2.vnz)/size); size = mid3.vsize; mid3.dx = (int)(((Long)wide*mid3.vnx)/size); mid3.dy = (int)(((Long)wide*mid3.vny)/size); mid3.dz = (int)(((Long)wide*mid3.vnz)/size); /* Calculate Surface Intensity */ mid1.hsize = 0; mid1.hnx = (int)(((Long)27*knot1.hnx + (Long) 5*knot2.hnx)/32); mid1.hny = (int)(((Long)27*knot1.hny + (Long) 5*knot2.hny)/32); mid1.hnz = (int)(((Long)27*knot1.hnz + (Long) 5*knot2.hnz)/32); CalculateHInten( &mid1 ); mid2.hsize = 0; mid2.hnx = (knot1.hnx + knot2.hnx)/2; mid2.hny = (knot1.hny + knot2.hny)/2; mid2.hnz = (knot1.hnz + knot2.hnz)/2; CalculateHInten( &mid2 ); mid3.hsize = 0; mid3.hnx = (int)(((Long) 5*knot1.hnx + (Long)27*knot2.hnx)/32); mid3.hny = (int)(((Long) 5*knot1.hny + (Long)27*knot2.hny)/32); mid3.hnz = (int)(((Long) 5*knot1.hnz + (Long)27*knot2.hnz)/32); CalculateHInten( &mid3 ); cartoon_flag = 1; Cartoon_ribdata( &knot1, &mid1, &front, &back, &side1, &side2, col1, scale ); Cartoon_ribdata( &mid1, &mid2, &front, &back, &side1, &side2, col1, scale ); Cartoon_ribdata( &mid2, &mid3, &front, &back, &side1, &side2, col1, scale ); Cartoon_ribdata( &mid3, &knot2, &front, &back, &side1, &side2, col1, scale ); } } } } else if( group == chain->glist ) { knot1 = knot2; knot1.px = captr->xorg + captr->fxorg- CenX; knot1.py = captr->yorg + captr->fyorg - CenY; knot1.pz = captr->zorg + captr->fzorg - CenZ; if( group->flag & RibbonFlag ) { ribdata=Poly_ribdata(&knot1, &knot2, ribdata, col1, scale); } else if( group->flag & RibbonFlag ) { Cartoon_ribdata( &knot1, &knot2, &front, &back, &side1, &side2, col1, scale ); } else if( group->flag & (StrandFlag|DashStrandFlag) ) { if( !(col2 = group->col2) ) col2 = captr->col; R3DStrandRibbon( &knot1, &knot2, col1, col2, scale); } else if( group->flag & TraceFlag ) { R3DCylinder(knot1.px+CenX, knot1.py+CenY, knot1.pz+CenZ, knot2.px+CenX, knot2.py+CenY, knot2.pz+CenZ, col1, scale); } else if( group->flag & DotsFlag ) { wide = (int)(group->width); R3DSphere(knot1.px+CenX,knot1.py+CenY,knot1.pz+CenZ,wide,col1,scale); } prev = True; } else prev = True; group = group->gnext; captr = next; knot1 = knot2; } if( prev ) { if( !(col1 = group->col1) ) col1 = captr->col; if( group->flag & CartoonFlag ) { /* Test for arrow head! */ if( DrawBetaArrows && (group->struc&SheetFlag) ) { wide = (3*group->width)>>1; knot2.px = captr->xorg + captr->fxorg + (knot2.tx/2) - CenX; knot2.py = captr->yorg + captr->fyorg + (knot2.ty/2) - CenY; knot2.pz = captr->zorg + captr->fyorg + (knot2.tz/2) - CenZ; arrow = True; } else { wide = group->width; knot2.px = captr->xorg + captr->fxorg - CenX; knot2.py = captr->yorg + captr->fyorg - CenY; knot2.pz = captr->zorg + captr->fzorg - CenZ; arrow = False; } if( (knot1.wide!=wide) && knot1.hsize ) { size = knot1.hsize; knot1.wx = (int)(((Long)wide*knot1.hnx)/size); knot1.wy = (int)(((Long)wide*knot1.hny)/size); knot1.wz = (int)(((Long)wide*knot1.hnz)/size); if( !arrow ) { knot2.wx = knot1.wx; knot2.wy = knot1.wy; knot2.wz = knot1.wz; } else { knot2.wx = 0; knot2.wy = 0; knot2.wz = 0; } } else if( arrow ) { knot2.wx = 0; knot2.wy = 0; knot2.wz = 0; } Cartoon_ribdata( &knot1, &knot2, &front, &back, &side1, &side2, col1, scale ); } else /* !Cartoon */ { knot2.px = captr->xorg + captr->fxorg - CenX; knot2.py = captr->yorg + captr->fyorg - CenY; knot2.pz = captr->zorg + captr->fzorg - CenZ; if( group->flag & RibbonFlag ) { ribdata= Poly_ribdata(&knot1, &knot2, ribdata, col1, scale); } else if( group->flag & (StrandFlag|DashStrandFlag) ) { if( !(col2 = group->col2) ) col2 = captr->col; R3DStrandRibbon(&knot1, &knot2, col1, col2, scale); } else if( group->flag & TraceFlag ) { R3DCylinder(knot1.px+CenX, knot1.py+CenY, knot1.pz+CenZ, knot2.px+CenX, knot2.py+CenY, knot2.pz+CenZ, col1, scale); } else if( group->flag & DotsFlag ) { wide = (int)(group->width); R3DSphere(knot1.px+CenX,knot1.py+CenY,knot1.pz+CenZ,wide,col1,scale); R3DSphere(knot2.px+CenX,knot2.py+CenX,knot2.pz+CenX,wide,col1,scale); } } } if( group->flag & RibbonFlag ) { R3DSolidRib(ribdata); } else if(cartoon_flag) { R3DSolidRib(front); R3DSolidRib(back); R3DSolidRib(side1); R3DSolidRib(side2); } } static void WriteR3DItems( PSItemPtr __far *data, char __far *type, int count,int scale ) { register Monitor __far *monit; register HBond __far *hbond; register Bond __far *bond; register RAtom __far *src; register RAtom __far *dst; register Chain __far *chain; register int i; for( i=0; isrcatom; dst = bond->dstatom; if( bond->flag & WireFlag ) WriteR3DStick(src,dst,bond->col,10,scale); else if( bond->flag & CylinderFlag ) WriteR3DStick(src,dst,bond->col,bond->radius,scale); else /* bond->flag & DashFlag */ WriteR3DStick(src,dst,bond->col,bond->radius,scale); break; case(PSSSBond): case(PSHBond): hbond = (HBond __far*)data[i]; if( (type[i]==PSHBond)? HBondMode : SSBondMode ) { src = hbond->srcCA; dst = hbond->dstCA; } else { src = hbond->src; dst = hbond->dst; } if( hbond->flag & WireFlag ) WriteR3DStick(src,dst,hbond->col,10,scale); else /* bond->flag & CylinderFlag */ WriteR3DStick(src,dst,hbond->col,hbond->radius,scale); break; case(PSMonit): monit = (Monitor __far*)data[i]; WriteR3DMonitor(monit,10,scale); break; case(PSRibbon): chain = (Chain __far*)data[i]; WriteR3DRibbon(chain, scale); break; } } int WriteR3DFile( char* name) { register int scale; register Long count; PSItemPtr __far *data; char __far *type; count = CountPSItems(); if( !count ) return( True ); #ifdef IBMPC if( count > 16383 ) { InvalidateCmndLine(); WriteString("Output Error: Too many objects!\n"); return( False ); } #endif scale = XRange; if (YRange > scale) scale= YRange; /* Allocate arrays for objects! */ data = (PSItemPtr __far*)_fmalloc((size_t)count*sizeof(PSItemPtr)); type = (char __far*)_fmalloc((size_t)count*sizeof(char)); if( !data || !type ) { InvalidateCmndLine(); WriteString("Output Error: Not enough memory to create raster3d!\n"); if( data ) _ffree( data ); if( type ) _ffree( type ); return( False ); } OutFile = fopen(name,"w"); if( !OutFile ) { FatalOutputError(name); return(False); } /* creating the R3D header */ fprintf(OutFile,"Raster3d file: %s Creator: RasMol Version %s\n",name,VERSION); fprintf(OutFile,"%d %d tiles in x,y\n",NTX, NTY); fprintf(OutFile,"%d %d pixels (x,y) per tile\n",NPX, NPY); fprintf(OutFile,"4 anti-aliasing level 4; 3X3->2X2\n"); fprintf(OutFile,"%.2f %.2f %.2f background color\n",BackR/255.0,BackG/255.0,BackB/255.0); fprintf(OutFile,"F shadows cast\n"); if (FakeSpecular) { fprintf(OutFile,"10 Phong power\n"); fprintf(OutFile,"0.10 secondary light contribution\n"); fprintf(OutFile,"0.05 ambient light contribution\n"); fprintf(OutFile,"0.50 specular reflection component\n"); } else { fprintf(OutFile,"25 Phong power\n"); fprintf(OutFile,"0.25 secondary light contribution\n"); fprintf(OutFile,"0.05 ambient light contribution\n"); fprintf(OutFile,"0.25 specular reflection component\n"); } fprintf(OutFile,"0.0 eye position\n"); fprintf(OutFile,"1 1 1 main light source position( from over right shoulder)\n"); fprintf(OutFile,"%f %f %f 0 view matrix for coordinate transformations\n", 1.0, 0.0, 0.0); fprintf(OutFile,"%f %f %f 0\n", 0.0, 1.0, 0.0); fprintf(OutFile,"%f %f %f 0\n", 0.0, 0.0, 1.0); fprintf(OutFile,"%f %f %f %f translation\n", 0.0, 0.0, 0.0, 1.0); fprintf(OutFile,"3\n*\n*\n*\n"); if (UseDepthPlane) { fprintf(OutFile,"16\nBACKCLIP %f\n", (Real)(DepthValue-ZRange/2+1)/(Real)scale); } if (UseSlabPlane) { fprintf(OutFile,"16\nFRONTCLIP %f\n", (Real)(SlabValue-ZRange/2-1)/(Real)scale); } FetchPSItems(data,type); if( count>1 ) DepthSort(data,type,(int)count); WriteR3DItems(data,type,(int)count,scale); /* if( !VectSolid ) { fputs("[] 0 setdash\n",OutFile); VectSolid = True; } if( DotPtr ) WriteVectDots(); if( DrawMonitDistance && MonitList ) WriteVectMonitors(); */ if( LabelList ) WriteR3DLabels(scale); fclose(OutFile); #ifdef APPLEMAC /* Avoid ANSI trigraph problems! */ SetFileInfo(name,'vgrd','TEXT',134); #endif _ffree( data ); _ffree( type ); return(True); } /*==================================*/ /* Macintosh PICT File Generation */ /*==================================*/ static void FlushPICTBuffer( void ) { if( PacketLen ) { if( RLEOutput ) { WriteByte(PacketLen-1); fwrite((char*)Buffer,1,PacketLen,OutFile); } else RLELineSize += PacketLen+1; PacketLen = 0; } } static void FlushPICTPacket( void ) { register int i; if( RLELength>2 ) { FlushPICTBuffer(); if( RLEOutput ) { WriteByte(257-RLELength); WriteByte(RLEChar); } else RLELineSize += 2; } else for( i=0; i=0; y-- ) { #ifdef INVERT ptr = FBuffer + (Long)y*XRange; #endif RLELineSize = 0; RLEOutput = False; PacketLen = 0; RLELength = 0; #ifdef EIGHTBIT tmp = ptr; for( x=0; x 250 ) { WriteMSBShort(RLELineSize); RLEFileSize += (RLELineSize+2); } else { WriteByte(RLELineSize); RLEFileSize += (RLELineSize+1); } #else WriteMSBShort(RLELineSize); RLEFileSize += (RLELineSize+2); #endif RLEOutput = True; PacketLen = 0; RLELength = 0; #ifdef EIGHTBIT for( x=0; x2 ) { FlushIRISBuffer(); if( RLEOutput ) { WriteByte(RLELength); WriteByte(RLEChar); } else RLELineSize += 2; } else for( i=0; i*max ) *max=i; WriteIRISCode(i); } FlushIRISPacket(); FlushIRISBuffer(); rowsize[y] = RLELineSize; rowstart[y] = RLEFileSize; RLEFileSize += RLELineSize; ptr = tmp; RLELineSize = 0; /* Green Component */ for( x=0; x*max ) *max=i; WriteIRISCode(i); } FlushIRISPacket(); FlushIRISBuffer(); i = y+YRange; rowsize[i] = RLELineSize; rowstart[i] = RLEFileSize; RLEFileSize += RLELineSize; ptr = tmp; RLELineSize = 0; /* Blue Component */ for( x=0; x*max ) *max=i; WriteIRISCode(i); } FlushIRISPacket(); FlushIRISBuffer(); i = y+(YRange<<1); rowsize[i] = RLELineSize; rowstart[i] = RLEFileSize; RLEFileSize += RLELineSize; } } static void WriteIRISHeader( Long __far *rowstart, short __far *rowsize, int min, int max ) { register int i,size; WriteMSBShort(474); /* imagic */ WriteMSBShort(257); /* type */ WriteMSBShort(3); /* dim */ WriteMSBShort(XRange); /* xsize */ WriteMSBShort(YRange); /* ysize */ WriteMSBShort(3); /* zsize */ WriteMSBLong(min); /* min */ WriteMSBLong(max); /* max */ WriteMSBLong(0); /* wastebytes */ /* name */ fputs("RasMol IRIS RGB format output",OutFile); for( i=0; i<51; i++ ) WriteByte(0x00); WriteMSBLong(0); /* colormap */ size = 3*YRange; for( i=0; i<404; i++ ) WriteByte(0x00); for( i=0; i