home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 418_02 / rasmol2 / transfor.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-02  |  51.6 KB  |  1,913 lines

  1. /* transfor.c
  2.  * RasMol2 Molecular Graphics
  3.  * Roger Sayle, February 1994
  4.  * Version 2.3
  5.  */
  6. #include "rasmol.h"
  7.  
  8. #ifdef IBMPC
  9. #include <windows.h>
  10. #endif
  11. #include <stdio.h>
  12. #include <math.h>
  13.  
  14. #define TRANSFORM
  15. #include "transfor.h"
  16. #include "molecule.h"
  17. #include "command.h"
  18. #include "abstree.h"
  19. #include "render.h"
  20. #include "graphics.h"
  21.  
  22.  
  23. typedef struct {
  24.         short col;
  25.         short shade;
  26.                 unsigned char r;
  27.                 unsigned char g;
  28.                 unsigned char b;
  29.               } ShadeRef;
  30.  
  31.  
  32. static ShadeRef CPKShade[] = {
  33.      { 0, 0, 200, 200, 200 },       /*  0 Light Grey   */
  34.      { 0, 0, 143, 143, 255 },       /*  1 Sky Blue     */
  35.      { 0, 0, 240,   0,   0 },       /*  2 Red          */
  36.      { 0, 0, 255, 200,  50 },       /*  3 Yellow       */
  37.      { 0, 0, 255, 255, 255 },       /*  4 White        */
  38.      { 0, 0, 255, 192, 203 },       /*  5 Pink         */
  39.      { 0, 0, 218, 165,  32 },       /*  6 Golden Rod   */
  40.      { 0, 0,   0,   0, 255 },       /*  7 Blue         */
  41.      { 0, 0, 255, 165,   0 },       /*  8 Orange       */
  42.      { 0, 0, 128, 128, 144 },       /*  9 Dark Grey    */
  43.      { 0, 0, 165,  42,  42 },       /* 10 Brown        */
  44.      { 0, 0, 160,  32, 240 },       /* 11 Purple       */
  45.      { 0, 0, 255,  20, 147 },       /* 12 Deep Pink    */
  46.      { 0, 0,   0, 255,   0 },       /* 13 Green        */
  47.      { 0, 0, 178,  34,  34 },       /* 14 Fire Brick   */
  48.      { 0, 0,  34, 139,  34 } };     /* 15 Forest Green */
  49.  
  50.  
  51. static int CPKIndex[] = { 12, /*Unknown*/
  52.       9, /*Ag*/   9, /*Al*/   6, /*Au*/  13, /* B*/
  53.      10, /*Br*/   0, /* C*/   9, /*Ca*/  13, /*Cl*/
  54.       9, /*Cr*/  10, /*Cu*/   6, /* F*/   8, /*Fe*/
  55.       4, /* H*/   5, /*He*/  11, /* I*/  12, /* K*/
  56.      14, /*Li*/  15, /*Mg*/   9, /*Mn*/   1, /* N*/
  57.       7, /*Na*/  10, /*Ni*/   2, /* O*/   8, /* P*/
  58.       3, /* S*/   6, /*Si*/  10  /*Zn*/ };
  59.  
  60. static ShadeRef Shapely[] = {
  61.      { 0, 0, 140, 255, 140 },    /* ALA */
  62.      { 0, 0, 255, 255, 255 },    /* GLY */
  63.      { 0, 0,  69,  94,  69 },    /* LEU */
  64.      { 0, 0, 255, 112,  66 },    /* SER */
  65.      { 0, 0, 255, 140, 255 },    /* VAL */
  66.      { 0, 0, 184,  76,   0 },    /* THR */
  67.      { 0, 0,  71,  71, 184 },    /* LYS */
  68.      { 0, 0, 160,   0,  66 },    /* ASP */
  69.      { 0, 0,   0,  76,   0 },    /* ILE */
  70.      { 0, 0, 255, 124, 112 },    /* ASN */
  71.      { 0, 0, 102,   0,   0 },    /* GLU */
  72.      { 0, 0,  82,  82,  82 },    /* PRO */
  73.      { 0, 0,   0,   0, 124 },    /* ARG */
  74.      { 0, 0,  83,  76,  66 },    /* PHE */
  75.      { 0, 0, 255,  76,  76 },    /* GLN */
  76.      { 0, 0, 140, 112,  76 },    /* TYR */
  77.      { 0, 0, 112, 112, 255 },    /* HIS */
  78.      { 0, 0, 255, 255, 112 },    /* CYS */
  79.      { 0, 0, 184, 160,  66 },    /* MET */
  80.      { 0, 0,  79,  70,   0 },    /* TRP */
  81.  
  82.      { 0, 0, 255,   0, 255 },    /* ASX */
  83.      { 0, 0, 255,   0, 255 },    /* GLX */
  84.      { 0, 0, 255,   0, 255 },    /* PCA */
  85.      { 0, 0, 255,   0, 255 },    /* HYP */
  86.  
  87.      { 0, 0, 160, 160, 255 },    /*   A */
  88.      { 0, 0, 255, 140,  75 },    /*   C */
  89.      { 0, 0, 255, 112, 112 },    /*   G */
  90.      { 0, 0, 160, 255, 160 },    /*   T */
  91.  
  92.      { 0, 0, 184, 184, 184 },    /* 28 -> BackBone */
  93.      { 0, 0,  94,   0,  94 },    /* 29 -> Special  */
  94.      { 0, 0, 255,   0, 255 } };  /* 30 -> Default  */
  95.  
  96.      
  97. static ShadeRef AminoShade[] = {
  98.      { 0, 0, 230,  10,  10 },    /*  0  ASP, GLU      */
  99.      { 0, 0,  20,  90, 255 },    /*  1  LYS, ARG      */
  100.      { 0, 0, 130, 130, 210 },    /*  2  HIS           */
  101.      { 0, 0, 250, 150,   0 },    /*  3  SER, THR      */
  102.      { 0, 0,   0, 220, 220 },    /*  4  ASN, GLN      */
  103.      { 0, 0, 230, 230,   0 },    /*  5  CYS, MET      */
  104.      { 0, 0, 200, 200, 200 },    /*  6  ALA           */
  105.      { 0, 0, 235, 235, 235 },    /*  7  GLY           */
  106.      { 0, 0,  15, 130,  15 },    /*  8  LEU, VAL, ILE */
  107.      { 0, 0,  50,  50, 170 },    /*  9  PHE, TYR      */
  108.      { 0, 0, 180,  90, 180 },    /* 10  TRP           */
  109.      { 0, 0, 220, 150, 130 },    /* 11  PRO, PCA, HYP */
  110.      { 0, 0, 190, 160, 110 } };  /* 12  Others        */
  111.  
  112. static int AminoIndex[] = {
  113.       6, /*ALA*/   7, /*GLY*/   8, /*LEU*/   3,  /*SER*/
  114.       8, /*VAL*/   3, /*THR*/   1, /*LYS*/   0,  /*ASP*/
  115.       8, /*ILE*/   4, /*ASN*/   0, /*GLU*/  11,  /*PRO*/
  116.       1, /*ARG*/   9, /*PHE*/   4, /*GLN*/   9,  /*TYR*/
  117.       2, /*HIS*/   5, /*CYS*/   5, /*MET*/  10,  /*TRP*/
  118.       4, /*ASX*/   4, /*GLX*/  11, /*PCA*/  11   /*HYP*/
  119.                           };
  120.  
  121. static ShadeRef HBondShade[] = {
  122.      { 0, 0, 255, 255, 255 },    /* 0  Offset =  2   */
  123.      { 0, 0, 255,   0, 255 },    /* 1  Offset =  3   */
  124.      { 0, 0, 255,   0,   0 },    /* 2  Offset =  4   */
  125.      { 0, 0, 255, 165,   0 },    /* 3  Offset =  5   */
  126.      { 0, 0,   0, 255, 255 },    /* 4  Offset = -3   */
  127.      { 0, 0,   0, 255,   0 },    /* 5  Offset = -4   */
  128.      { 0, 0, 255, 255,   0 } };  /* 6  Others        */
  129.  
  130.  
  131. static ShadeRef StructShade[] = {
  132.      { 0, 0, 255, 255, 255 },    /* 0  Default     */
  133.      { 0, 0, 240,   0, 128 },    /* 1  Alpha Helix */
  134.      { 0, 0, 255, 255,   0 },    /* 2  Beta Sheet  */
  135.      { 0, 0,  96, 128, 255 } };  /* 3  Turn        */
  136.  
  137.  
  138. typedef struct { 
  139.                 Long refcount;
  140.                 unsigned char r;
  141.                 unsigned char g;
  142.                 unsigned char b;
  143.               } ShadeDesc;
  144.  
  145.  
  146. /* Macros for commonly used loops */
  147. #define ForEachAtom  for(chain=Database->clist;chain;chain=chain->cnext) \
  148.                      for(group=chain->glist;group;group=group->gnext)    \
  149.                      for(ptr=group->alist;ptr;ptr=ptr->anext)
  150. #define ForEachBond  for(bptr=Database->blist;bptr;bptr=bptr->bnext) 
  151. #define ForEachBack  for(chain=Database->clist;chain;chain=chain->cnext) \
  152.                      for(bptr=chain->blist;bptr;bptr=bptr->bnext)
  153.  
  154. #define MAXSHADE         32
  155. #define MatchChar(a,b)   (((a)=='#')||((a)==(b)))
  156. #define RootSix          2.44948974278
  157.  
  158.  
  159. static ShadeDesc Shade[MAXSHADE];
  160. static ShadeRef ScaleRef[MAXSHADE];
  161. static int MaskColour[MAXMASK];
  162. static int MaskShade[MAXMASK];
  163. static int ScaleCount;
  164. static int LastShade;
  165.  
  166. static Real LastRX,LastRY,LastRZ;
  167. static Long OrigCX,OrigCY,OrigCZ;
  168. static Real Zoom;
  169.  
  170.  
  171.  
  172. void DetermineClipping()
  173. {
  174.     register int temp;
  175.     register int max;
  176.  
  177.     max = 0;
  178.     if( DrawAtoms && (MaxAtomRadius>max) )  max = MaxAtomRadius;
  179.     if( DrawBonds && (MaxBondRadius>max) )  max = MaxBondRadius;
  180.        
  181.     temp = ImageRadius + max;
  182.     UseScreenClip = (XOffset<temp) || (XOffset+temp>=XRange) ||
  183.                     (YOffset<temp) || (YOffset+temp>=YRange);
  184. }
  185.  
  186.  
  187.  
  188. void SetRadiusValue( rad )
  189.     int rad;
  190. {
  191.     register int irad,change;
  192.     register Chain __far *chain;
  193.     register Group __far *group;
  194.     register Atom __far *ptr;
  195.  
  196.     if( !Database )
  197.         return;
  198.  
  199.     irad = (int)(Scale*rad);
  200.     MaxAtomRadius = 0;
  201.     DrawAtoms = False;
  202.     change = False;
  203.  
  204.     ForEachAtom
  205.         if( ptr->flag & SelectFlag )
  206.         {   if( irad>MaxAtomRadius )
  207.                 MaxAtomRadius = irad;
  208.             ptr->flag |= SphereFlag;
  209.             ptr->radius = rad;
  210.             ptr->irad = irad;
  211.             change = True;
  212.         } else if( ptr->flag & SphereFlag )
  213.         {   DrawAtoms = True;
  214.             if( ptr->irad>MaxAtomRadius )
  215.                 MaxAtomRadius = ptr->irad;
  216.         }
  217.  
  218.     if( change )
  219.     {   DrawAtoms = True;
  220.         DetermineClipping();
  221.         VoxelsClean = False;
  222.         BucketFlag = False;
  223.     }
  224. }
  225.  
  226. void SetRadiusTemperature()
  227. {
  228.     register int rad,irad,change;
  229.     register Chain __far *chain;
  230.     register Group __far *group;
  231.     register Atom __far *ptr;
  232.  
  233.     if( !Database )
  234.         return;
  235.  
  236.     MaxAtomRadius = 0;
  237.     DrawAtoms = False;
  238.     change = False;
  239.  
  240.     ForEachAtom
  241.         if( (ptr->flag&SelectFlag) && (ptr->temp>0) )
  242.         {   rad = (5*ptr->temp)>>1;
  243.             if( rad>500 ) rad = 500;
  244.  
  245.             irad = (int)(Scale*rad);
  246.             if( irad>MaxAtomRadius )
  247.                 MaxAtomRadius = irad;
  248.             ptr->flag |= SphereFlag;
  249.             ptr->radius = rad;
  250.             ptr->irad = irad;
  251.             change = True;
  252.         } else if( ptr->flag & SphereFlag )
  253.         {   DrawAtoms = True;
  254.             if( ptr->irad>MaxAtomRadius )
  255.                 MaxAtomRadius = ptr->irad;
  256.         }
  257.  
  258.     if( change )
  259.     {   DrawAtoms = True;
  260.         DetermineClipping();
  261.         VoxelsClean = False;
  262.         BucketFlag = False;
  263.     }
  264. }
  265.  
  266.  
  267. void SetVanWaalRadius()
  268. {
  269.     register int rad,change;
  270.     register Chain __far *chain;
  271.     register Group __far *group;
  272.     register Atom __far *ptr;
  273.  
  274.     if( !Database )
  275.         return;
  276.  
  277.     MaxAtomRadius = 0;
  278.     DrawAtoms = False;
  279.     change = False;
  280.  
  281.     ForEachAtom
  282.         if( ptr->flag&SelectFlag )
  283.         {   rad = VanWaalRadius[ GetElemIdent(ptr) ];
  284.             ptr->irad = (int)(Scale*rad);
  285.             ptr->radius = rad;
  286.             change = True;
  287.  
  288.             ptr->flag |=SphereFlag;
  289.             if( ptr->irad>MaxAtomRadius )
  290.                 MaxAtomRadius = ptr->irad;
  291.         } else if( ptr->flag&SphereFlag )
  292.         {   DrawAtoms = True;
  293.             if( ptr->irad>MaxAtomRadius )
  294.                 MaxAtomRadius = ptr->irad;
  295.         }
  296.  
  297.     if( change )
  298.     {   DrawAtoms = True;
  299.         DetermineClipping();
  300.         VoxelsClean = False;
  301.         BucketFlag = False;
  302.     }
  303. }
  304.  
  305.  
  306. void DisableSpacefill()
  307. {
  308.     register Chain __far *chain;
  309.     register Group __far *group;
  310.     register Atom __far *ptr;
  311.  
  312.     if( !Database || !DrawAtoms )
  313.         return;
  314.  
  315.     MaxAtomRadius = 0;
  316.     DrawAtoms = False;
  317.     
  318.     ForEachAtom
  319.         if( !(ptr->flag&SelectFlag) )
  320.         {   if( ptr->flag&SphereFlag )
  321.             {   if( ptr->irad>MaxAtomRadius )
  322.                     MaxAtomRadius = ptr->irad;
  323.                 DrawAtoms = True;
  324.             }
  325.         } else if( ptr->flag&SphereFlag )
  326.             ptr->flag &= ~SphereFlag;
  327.  
  328.     DetermineClipping();
  329.     VoxelsClean = False;
  330.     BucketFlag = False;
  331. }
  332.  
  333.  
  334.  
  335. void EnableWireFrame( depth, rad )
  336.     int depth, rad;
  337. {
  338.     register Bond __far *bptr;
  339.     register int flag, irad;
  340.  
  341.     if( !Database )
  342.         return;
  343.  
  344.     DrawBonds = False;
  345.     MaxBondRadius = 0;
  346.     irad = (int)(Scale*rad);
  347.  
  348.     ForEachBond
  349.     {   flag = ZoneBoth? bptr->dstatom->flag & bptr->srcatom->flag
  350.                        : bptr->dstatom->flag | bptr->srcatom->flag;
  351.  
  352.         if( flag&SelectFlag )
  353.         {   DrawBonds = True;
  354.             bptr->flag &= ~DrawBondFlag;
  355.             if( !depth )
  356.             {   if( irad>MaxBondRadius )
  357.                     MaxBondRadius = irad;
  358.                 bptr->flag |= CylinderFlag;
  359.                 bptr->radius = rad;
  360.                 bptr->irad = irad;
  361.             } else bptr->flag |= WireFlag;
  362.         } else if( bptr->flag&DrawBondFlag )
  363.         {    DrawBonds = True;
  364.              if( bptr->flag&CylinderFlag )
  365.                  if( bptr->irad>MaxBondRadius )
  366.                      MaxBondRadius = bptr->irad;
  367.         }
  368.     }
  369.     DetermineClipping();
  370. }
  371.  
  372.  
  373. void DisableWireFrame()
  374. {
  375.     register Bond __far *bptr;
  376.     register int flag;
  377.  
  378.     if( !Database || !DrawBonds )
  379.         return;
  380.  
  381.     DrawBonds = False;
  382.     MaxBondRadius = 0;
  383.  
  384.     ForEachBond
  385.     {   flag = ZoneBoth? bptr->dstatom->flag & bptr->srcatom->flag
  386.                        : bptr->dstatom->flag | bptr->srcatom->flag;
  387.  
  388.         if( flag&SelectFlag )
  389.         {   bptr->flag &= ~DrawBondFlag;
  390.         } else if( bptr->flag&DrawBondFlag )
  391.         {   DrawBonds = True;
  392.             if( bptr->flag&CylinderFlag )
  393.                 if( bptr->irad>MaxBondRadius )
  394.                     MaxBondRadius = bptr->irad;
  395.         }
  396.     }
  397.     DetermineClipping();
  398. }
  399.  
  400.  
  401. void EnableBackBone( depth, rad )
  402.     int depth, rad;
  403. {
  404.     register Chain __far *chain;
  405.     register Bond __far *bptr;
  406.     register int flag,irad;
  407.  
  408.     if( !Database )
  409.         return;
  410.  
  411.     irad = (int)(Scale*rad);
  412.  
  413.     ForEachBack
  414.     {   flag = ZoneBoth? bptr->dstatom->flag & bptr->srcatom->flag
  415.                        : bptr->dstatom->flag | bptr->srcatom->flag;
  416.  
  417.         if( flag&SelectFlag )
  418.         {   bptr->flag &= ~DrawBondFlag;
  419.             if( !depth )
  420.             {   bptr->flag |= CylinderFlag;
  421.                 bptr->radius = rad;
  422.                 bptr->irad = irad;
  423.             } else bptr->flag |= WireFlag;
  424.         } 
  425.     }
  426.     DetermineClipping();
  427. }
  428.  
  429.  
  430. void DisableBackBone()
  431. {
  432.     register Chain __far *chain;
  433.     register Bond __far *bptr;
  434.  
  435.     if( !Database )
  436.         return;
  437.  
  438.     if( ZoneBoth )
  439.     {   ForEachBack
  440.             if( (bptr->dstatom->flag&bptr->srcatom->flag) & SelectFlag )
  441.                 bptr->flag &= ~DrawBondFlag;
  442.     } else ForEachBack
  443.         if( (bptr->dstatom->flag|bptr->srcatom->flag) & SelectFlag )
  444.             bptr->flag &= ~DrawBondFlag;
  445.     DetermineClipping();
  446. }
  447.  
  448.  
  449. void SetHBondStatus( hbonds, enable, rad )
  450.     int hbonds, enable, rad;
  451. {
  452.     register HBond __far *list;
  453.     register HBond __far *ptr;
  454.     register Atom __far *src;
  455.     register Atom __far *dst;
  456.     register int flag, irad;
  457.  
  458.     if( !Database )
  459.         return;
  460.  
  461.     if( hbonds )
  462.     {   if( InfoHBondCount<0 )
  463.             CalcHydrogenBonds();
  464.         list = Database->hlist;
  465.     } else 
  466.     {   if( InfoSSBondCount<0 )
  467.             FindDisulphideBridges();
  468.         list = Database->slist;
  469.     }
  470.  
  471.     irad = (int)(Scale*rad);
  472.     for( ptr=list; ptr; ptr=ptr->hnext )
  473.     {    if( !hbonds && SSBondMode )
  474.          {   src = ptr->srcCA;
  475.              dst = ptr->dstCA;
  476.          } else
  477.          {   src = ptr->src;
  478.              dst = ptr->dst;
  479.          }
  480.  
  481.          flag = ZoneBoth? src->flag&dst->flag : src->flag|dst->flag;
  482.          if( flag & SelectFlag ) 
  483.          {   ptr->flag &= ~DrawBondFlag;
  484.              if( enable )
  485.              {   if( rad )
  486.                  {   ptr->flag |= CylinderFlag;
  487.                      ptr->radius = rad;
  488.                      ptr->irad = irad;
  489.                  } else ptr->flag |= WireFlag;
  490.              }
  491.          }
  492.     }
  493. }
  494.  
  495.  
  496. void SetRibbonStatus( enable, width )
  497.     int enable, width;
  498. {
  499.     register Chain __far *chain;
  500.     register Group __far *group;
  501.     register Atom __far *ptr;
  502.  
  503.     if( !Database )
  504.         return;
  505.  
  506.     /* Ribbons already disabled! */
  507.     if( !enable && !DrawRibbon )
  508.         return;
  509.  
  510.     if( InfoHelixCount<0 )
  511.         DetermineStructure();
  512.  
  513.     DrawRibbon = False;
  514.     for( chain=Database->clist; chain; chain=chain->cnext )
  515.         for( group=chain->glist; group; group=group->gnext )
  516.             if( enable )
  517.             {   if( group->flag & RibbonFlag )
  518.                     DrawRibbon = True;
  519.                 
  520.                 for( ptr=group->alist; ptr; ptr=ptr->anext )
  521.                     if( IsAlphaCarbon(ptr->refno) )
  522.                     {   if( ptr->flag&SelectFlag )
  523.                         {   group->flag |= RibbonFlag;
  524.                             if( !width )
  525.                             {   if( group->flag & (HelixFlag|SheetFlag) )
  526.                                 {      group->width = 380;
  527.                                 } else group->width = 100;
  528.                             } else group->width = width;
  529.                             DrawRibbon = True;
  530.                         }
  531.                         break;
  532.  
  533.                     } else if( IsSugarPhosphate(ptr->refno) )
  534.                     {   if( ptr->flag&SelectFlag )
  535.                         {   group->width = width? width : 720;
  536.                             group->flag |= RibbonFlag;
  537.                             DrawRibbon = True;
  538.                         }
  539.                         break;
  540.                     }
  541.  
  542.  
  543.             } else  /* Disable Ribbon */
  544.                 if( group->flag & RibbonFlag )
  545.                 {   for( ptr=group->alist; ptr; ptr=ptr->anext )
  546.                         if( IsAlphaCarbon(ptr->refno) ||
  547.                             IsSugarPhosphate(ptr->refno) )
  548.                         {   if( ptr->flag&SelectFlag )
  549.                                 group->flag &= ~RibbonFlag;
  550.                             break;
  551.                         }
  552.                     if( group->flag & RibbonFlag ) 
  553.                         DrawRibbon = True;
  554.                 }
  555. }
  556.  
  557.  
  558. void SelectZone( mask )
  559.     int mask;
  560. {
  561.     register Bond __far *bptr;
  562.     register Chain __far *chain;
  563.     register Group __far *group;
  564.     register Atom __far *ptr;
  565.  
  566.     if( !Database )
  567.         return;
  568.  
  569.     SelectCount = 0;
  570.     ForEachAtom
  571.         if( ptr->flag & mask )
  572.         {   ptr->flag |= SelectFlag;
  573.             SelectCount++;
  574.         } else ptr->flag &= ~SelectFlag;
  575.     DisplaySelectCount();
  576.  
  577.     if( ZoneBoth )
  578.     {   ForEachBond
  579.            if( (bptr->srcatom->flag&bptr->dstatom->flag) & SelectFlag )
  580.            {   bptr->flag |= SelectFlag;
  581.            } else bptr->flag &= ~SelectFlag;
  582.     } else
  583.         ForEachBond
  584.            if( (bptr->srcatom->flag|bptr->dstatom->flag) & SelectFlag )
  585.            {   bptr->flag |= SelectFlag;
  586.            } else bptr->flag &= ~SelectFlag;
  587.  
  588. }
  589.  
  590.  
  591. void RestrictZone( mask )
  592.     int mask;
  593. {
  594.     register Bond __far *bptr;
  595.     register Chain __far *chain;
  596.     register Group __far *group;
  597.     register Atom __far *ptr;
  598.     register int flag;
  599.  
  600.     if( !Database )
  601.         return;
  602.  
  603.     DrawAtoms = False;   MaxAtomRadius = 0;
  604.     DrawBonds = False;   MaxBondRadius = 0;
  605.     
  606.     SelectCount = 0;
  607.     ForEachAtom
  608.         if( ptr->flag & mask )
  609.         {   ptr->flag |= SelectFlag;
  610.             SelectCount++;
  611.  
  612.             if( ptr->flag & SphereFlag )
  613.             {   DrawAtoms = True;
  614.                 if( ptr->irad>MaxAtomRadius )
  615.                     MaxAtomRadius = ptr->irad;
  616.             }
  617.         } else ptr->flag &= ~(SelectFlag|SphereFlag);
  618.     DisplaySelectCount();
  619.     
  620.     ForEachBond
  621.     {   /* Ignore ZoneBoth setting! */
  622.         flag = bptr->dstatom->flag & bptr->srcatom->flag;
  623.         if( flag & SelectFlag )
  624.         {   bptr->flag |= SelectFlag;
  625.             if( bptr->flag&DrawBondFlag )
  626.             {   DrawBonds = True;
  627.                 if( bptr->flag & CylinderFlag )
  628.                     if( bptr->irad>MaxBondRadius )
  629.                         MaxBondRadius = bptr->irad;
  630.             } 
  631.         } else bptr->flag &= ~(SelectFlag|DrawBondFlag);
  632.     }
  633.  
  634.     DetermineClipping();
  635.     VoxelsClean = False;
  636.     BucketFlag = False;
  637. }
  638.  
  639.  
  640.  
  641. int DefineShade( r, g, b )
  642.     unsigned char r, g, b;
  643. {
  644.     register int d,dr,dg,db;
  645.     register int dist,best;
  646.     register int i;
  647.  
  648.     /* Already defined! */
  649.     for( i=0; i<LastShade; i++ )
  650.         if( Shade[i].refcount )
  651.             if( (Shade[i].r==r)&&(Shade[i].g==g)&&(Shade[i].b==b) )
  652.                 return(i);
  653.  
  654.     /* Allocate request */
  655.     for( i=0; i<LastShade; i++ )
  656.          if( !Shade[i].refcount )
  657.          {   Shade[i].r = r;
  658.              Shade[i].g = g;
  659.              Shade[i].b = b;
  660.              Shade[i].refcount = 0;
  661.              return(i);
  662.          }
  663.  
  664.     if( CommandActive )
  665.         WriteChar('\n');
  666.     WriteString("Warning: Unable to allocate shade!\n");
  667.     CommandActive = False;
  668.  
  669.     /* To avoid lint warning! */
  670.     best = dist = 0;
  671.  
  672.     /* Nearest match */
  673.     for( i=0; i<LastShade; i++ )
  674.     {   dr = Shade[i].r - r;
  675.         dg = Shade[i].g - g;
  676.         db = Shade[i].b - b;
  677.         d = dr*dr + dg*dg + db*db;
  678.         if( !i || (d<dist) )
  679.         {   dist = d;
  680.             best = i;
  681.         }
  682.     }
  683.     return( best );
  684. }
  685.  
  686.  
  687. void ScaleColourMap( count )
  688.     int count;
  689. {
  690.     register Real hue;
  691.     register int fract, sextant;
  692.     register int i, r, g, b;
  693.  
  694.     ScaleCount=0;
  695.     for( i=0; i<LastShade; i++ )
  696.         if( !Shade[i].refcount )
  697.             ScaleCount++;
  698.  
  699.     /* If there are no shades free! */
  700.     if( !ScaleCount ) ScaleCount = LastShade;
  701.  
  702.     if( count && (count<ScaleCount) )
  703.         ScaleCount = count;
  704.  
  705.     for( i=0; i<ScaleCount; i++ )
  706.     {   sextant = (int)(hue = (4.0*i)/(ScaleCount-1));
  707.         fract = (int)(255.0*(hue-sextant));
  708.  
  709.         switch( sextant )
  710.         {   case(0): r = 0;         g = fract;     b = 255;         break;
  711.             case(1): r = 0;         g = 255;       b = 255-fract;   break;
  712.             case(2): r = fract;     g = 255;       b = 0;           break;
  713.             case(3): r = 255;       g = 255-fract; b = 0;           break;
  714.             default: r = 255;       g = 0;         b = 0;
  715.         }
  716.         ScaleRef[i].r = r;
  717.         ScaleRef[i].g = g;
  718.         ScaleRef[i].b = b;
  719.         ScaleRef[i].shade = 0;
  720.         ScaleRef[i].col = 0;
  721.     }
  722. }
  723.  
  724.  
  725. static void SetLutEntry( i, r, g, b )
  726.     int i, r, g, b;
  727. {
  728.     ULut[i] = True;
  729.     RLut[i] = r;
  730.     GLut[i] = g;
  731.     BLut[i] = b;
  732.  
  733. #ifdef EIGHTBIT
  734.     Lut[i] = i;
  735. #else
  736.     Lut[i] = ( ((r<<8)|g)<<8 ) | b;
  737. #endif
  738. }
  739.  
  740.  
  741. static Real Power( x, y )
  742.     Real x; int y;
  743. {
  744.     register Real result;
  745.  
  746.     result = x;
  747.     while( y>1 )
  748.     {   if( y&1 ) { result *= x; y--; }
  749.         else { result *= result; y>>=1; }
  750.     }
  751.     return( result );
  752. }
  753.  
  754.  
  755. void DefineColourMap()
  756. {
  757.     register Real diffuse;
  758.     register Real temp, inten;
  759.     register int col, r, g, b;
  760.     register int i, j, k;
  761.  
  762. #ifdef EIGHTBIT
  763.     for( i=0; i<256; i++ )
  764.         ULut[i] = False;
  765. #endif
  766.  
  767. #ifdef IBMPC
  768.     SetLutEntry(0,BackR,BackG,BackB);
  769. #else
  770.     SetLutEntry(5,BackR,BackG,BackB);
  771. #endif
  772.  
  773.     diffuse = 1.0 - Ambient;
  774.     for( i=0; i<ColourDepth; i++ )
  775.     {   temp = (Real)i/ColourMask;
  776.         inten = diffuse*temp + Ambient;
  777.  
  778.         if( DisplayMode )
  779.         {   /* Unselected [0,96,255] */
  780.             /* Selected   [255,0,0]  */
  781.             r = b = (int)(255*inten);
  782.             g = (int)(96*inten);
  783.  
  784.             SetLutEntry( Shade2Colour(0)+i, 0, g, b );
  785.             SetLutEntry( Shade2Colour(1)+i, r, 0, 0 );
  786.  
  787.         } else 
  788.         {   if( FakeSpecular )
  789.             {   temp = Power(temp,SpecPower);
  790.                 inten *= 1.0 - temp;
  791.                 k = (int)(255*temp);
  792.             }
  793.  
  794.             for( j=0; j<LastShade; j++ )
  795.                 if( Shade[j].refcount )
  796.                 {   col = Shade2Colour(j);
  797.                     r = (int)(Shade[j].r*inten); 
  798.                     g = (int)(Shade[j].g*inten);
  799.                     b = (int)(Shade[j].b*inten);
  800.  
  801.                     if( FakeSpecular )
  802.                     {   r += k;
  803.                         g += k;
  804.                         b += k;
  805.                     }
  806.                     SetLutEntry( col+i, r, g, b );
  807.                 }
  808.         }
  809.     }
  810.  
  811.     if( Interactive )
  812.         AllocateColourMap();
  813. }
  814.  
  815.  
  816. void ResetColourMap()
  817. {
  818.     register int i;
  819.  
  820. #ifdef EIGHTBIT
  821.     for( i=0; i<256; i++ )
  822.         ULut[i] = False;
  823. #endif
  824.  
  825.     BackR = BackG = BackB = 0;
  826.  
  827.     for( i=0; i<LastShade; i++ )
  828.         Shade[i].refcount = 0;
  829.     ScaleCount = 0;
  830. }
  831.  
  832.  
  833. void ColourBondNone()
  834. {
  835.     register Bond __far *bptr;
  836.  
  837.     if( Database )
  838.         ForEachBond
  839.             if( (bptr->flag&SelectFlag) && bptr->col )
  840.             {   Shade[Colour2Shade(bptr->col)].refcount--;
  841.                 bptr->col = 0;
  842.             }
  843. }
  844.  
  845.  
  846. void ColourBondAttrib( r, g, b )
  847.     int r, g, b;
  848. {
  849.     register Bond __far *bptr;
  850.     register int shade,col;
  851.  
  852.     if( Database )
  853.     {   ForEachBond
  854.             if( (bptr->flag&SelectFlag) && bptr->col )
  855.                 Shade[Colour2Shade(bptr->col)].refcount--;
  856.  
  857.         shade = DefineShade((Byte)r,(Byte)g,(Byte)b);
  858.         col = Shade2Colour(shade);
  859.  
  860.         ForEachBond
  861.             if( bptr->flag&SelectFlag )
  862.             {   Shade[shade].refcount++;
  863.                 bptr->col = col;
  864.             }
  865.     }
  866. }
  867.  
  868.  
  869. void ColourBackNone()
  870. {
  871.     register Chain __far *chain;
  872.     register Bond __far *bptr;
  873.     register int flag;
  874.  
  875.     if( Database )
  876.         ForEachBack
  877.         {   flag = ZoneBoth? bptr->dstatom->flag & bptr->srcatom->flag
  878.                            : bptr->dstatom->flag | bptr->srcatom->flag;
  879.  
  880.             if( flag&SelectFlag )
  881.             {   bptr->flag |= SelectFlag;
  882.                 if( bptr->col )
  883.                 {   Shade[Colour2Shade(bptr->col)].refcount--;
  884.                     bptr->col = 0;
  885.                 }
  886.             } else bptr->flag &= ~SelectFlag;
  887.         }
  888. }
  889.  
  890.  
  891. void ColourBackAttrib( r, g, b )
  892.     int r, g, b;
  893. {
  894.     register int shade,col;
  895.     register Chain __far *chain;
  896.     register Bond __far *bptr;
  897.  
  898.     if( Database )
  899.     {   ColourBackNone();
  900.         shade = DefineShade((Byte)r,(Byte)g,(Byte)b);
  901.         col = Shade2Colour(shade);
  902.  
  903.         ForEachBack
  904.             if( bptr->flag&SelectFlag )
  905.             {   Shade[shade].refcount++;
  906.                 bptr->col = col;
  907.             }
  908.     }
  909. }
  910.  
  911.  
  912. void ColourHBondNone( hbonds )
  913.     int hbonds;
  914. {
  915.     register HBond __far *list;
  916.     register HBond __far *ptr;
  917.     register Atom __far *src;
  918.     register Atom __far *dst;
  919.  
  920.     if( !Database )
  921.         return;
  922.  
  923.     if( hbonds )
  924.     {   if( InfoHBondCount<0 )
  925.         {   CalcHydrogenBonds();
  926.             return;
  927.         } else list = Database->hlist;
  928.     } else
  929.         if( InfoSSBondCount<0 )
  930.         {   FindDisulphideBridges();
  931.             return;
  932.         } else list = Database->slist;
  933.  
  934.  
  935.     if( ZoneBoth )
  936.     {   for( ptr=list; ptr; ptr=ptr->hnext )
  937.         {   if( !hbonds && SSBondMode )
  938.             {   src = ptr->srcCA;
  939.                 dst = ptr->dstCA;
  940.             } else
  941.             {   src = ptr->src;
  942.                 dst = ptr->dst;
  943.             }
  944.  
  945.             if( (src->flag&dst->flag) & SelectFlag )
  946.             {   ptr->flag |= SelectFlag;
  947.                 if( ptr->col )
  948.                 {   Shade[Colour2Shade(ptr->col)].refcount--;
  949.                     ptr->col = 0;
  950.                 }
  951.             } else ptr->flag &= ~SelectFlag;
  952.         }
  953.     } else
  954.         for( ptr=list; ptr; ptr=ptr->hnext )
  955.         {   if( !hbonds && SSBondMode )
  956.             {   src = ptr->srcCA;
  957.                 dst = ptr->dstCA;
  958.             } else
  959.             {   src = ptr->src;
  960.                 dst = ptr->dst;
  961.             }
  962.  
  963.             if( (src->flag|dst->flag) & SelectFlag )
  964.             {   ptr->flag |= SelectFlag;
  965.                 if( ptr->col )
  966.                 {   Shade[Colour2Shade(ptr->col)].refcount--;
  967.                     ptr->col = 0;
  968.                 }
  969.             } else ptr->flag &= ~SelectFlag;
  970.         }
  971. }
  972.  
  973. void ColourHBondType()
  974. {
  975.     register HBond __far *ptr;
  976.     register ShadeRef *ref;
  977.     register int i;
  978.  
  979.     if( !Database ) return;
  980.     for( i=0; i<7; i++ )
  981.         HBondShade[i].col = 0;
  982.     ColourHBondNone( True );
  983.  
  984.     for( ptr=Database->hlist; ptr; ptr=ptr->hnext )
  985.         if( ptr->flag & SelectFlag )
  986.         {   switch( ptr->offset )
  987.             {   case(  2 ):  ref = HBondShade;     break;
  988.                 case(  3 ):  ref = HBondShade+1;   break;
  989.                 case(  4 ):  ref = HBondShade+2;   break;
  990.                 case(  5 ):  ref = HBondShade+3;   break;
  991.                 case( -3 ):  ref = HBondShade+4;   break;
  992.                 case( -4 ):  ref = HBondShade+5;   break;
  993.                 default:     ref = HBondShade+6;   break;
  994.             }
  995.  
  996.             if( !ref->col )
  997.             {   ref->shade = DefineShade( ref->r, ref->g, ref->b );
  998.                 ref->col = Shade2Colour(ref->shade);
  999.             }
  1000.             Shade[ref->shade].refcount++;
  1001.             ptr->col = (Byte)ref->col;
  1002.         }
  1003. }
  1004.  
  1005.  
  1006. void ColourHBondAttrib( hbonds, r, g, b )
  1007.     int r, g, b;
  1008. {
  1009.     register HBond __far *list;
  1010.     register HBond __far *ptr;
  1011.     register int col,shade;
  1012.  
  1013.     if( !Database )
  1014.         return;
  1015.  
  1016.     ColourHBondNone( hbonds );
  1017.     shade = DefineShade((Byte)r,(Byte)g,(Byte)b);
  1018.     col = Shade2Colour(shade);
  1019.  
  1020.     list = hbonds? Database->hlist : Database->slist;
  1021.     for( ptr=list; ptr; ptr=ptr->hnext )
  1022.         if( ptr->flag & SelectFlag )
  1023.         {   Shade[shade].refcount++;
  1024.             ptr->col = col;
  1025.         }
  1026. }
  1027.  
  1028.  
  1029. void ColourRibbonNone()
  1030. {
  1031.     register Chain __far *chain;
  1032.     register Group __far *group;
  1033.     register Atom __far *aptr;
  1034.  
  1035.     if( !Database )
  1036.         return;
  1037.  
  1038.     if( InfoHelixCount<0 )
  1039.     {   DetermineStructure();
  1040.         return;
  1041.     }
  1042.  
  1043.     for( chain=Database->clist; chain; chain=chain->cnext )
  1044.         for( group=chain->glist; group; group=group->gnext )
  1045.             if( group->col && (aptr=FindGroupAtom(group,1) ) 
  1046.                 && (aptr->flag&SelectFlag) )
  1047.             {   Shade[Colour2Shade(group->col)].refcount--;
  1048.                 group->col = 0;
  1049.             }
  1050. }
  1051.  
  1052.  
  1053. void ColourRibbonAttrib( r, g, b )
  1054.     int r, g, b;
  1055. {
  1056.     register int shade, col;
  1057.     register Chain __far *chain;
  1058.     register Group __far *group;
  1059.     register Atom __far *aptr;
  1060.  
  1061.     if( Database )
  1062.     {   ColourRibbonNone();
  1063.         shade = DefineShade((Byte)r,(Byte)g,(Byte)b);
  1064.         col = Shade2Colour(shade);
  1065.  
  1066.         for( chain=Database->clist; chain; chain=chain->cnext )
  1067.             for( group=chain->glist; group; group=group->gnext )
  1068.                 if( (aptr=FindGroupAtom(group,1)) 
  1069.                     && (aptr->flag&SelectFlag) )
  1070.                 {   Shade[shade].refcount++;
  1071.                     group->col = col;
  1072.                 }
  1073.     }
  1074. }
  1075.  
  1076.  
  1077. static void ResetColourAttrib()
  1078. {
  1079.     register Chain __far *chain;
  1080.     register Group __far *group;
  1081.     register Atom __far *ptr;
  1082.  
  1083.     ForEachAtom
  1084.         if( (ptr->flag&SelectFlag) && ptr->col )
  1085.             Shade[Colour2Shade(ptr->col)].refcount--;
  1086. }
  1087.  
  1088.  
  1089. void MonoColourAttrib( r, g, b )
  1090.     int r, g, b;
  1091. {
  1092.     register int shade,col;
  1093.     register Chain __far *chain;
  1094.     register Group __far *group;
  1095.     register Atom __far *ptr;
  1096.  
  1097.     if( Database )
  1098.     {   ResetColourAttrib();
  1099.         shade = DefineShade((Byte)r,(Byte)g,(Byte)b);
  1100.         col = Shade2Colour(shade);
  1101.  
  1102.         ForEachAtom
  1103.             if( ptr->flag&SelectFlag )
  1104.             {   Shade[shade].refcount++;
  1105.                 ptr->col = col;
  1106.             }
  1107.     }
  1108. }
  1109.  
  1110.  
  1111. void ScaleColourAttrib( attr )
  1112.     int attr;
  1113. {
  1114.     register ShadeRef *ref;
  1115.     register int count, attrno, factor;
  1116.     register Chain __far *chain;
  1117.     register Group __far *group;
  1118.     register Atom __far *ptr;
  1119.  
  1120.     if( !Database ) return;
  1121.  
  1122.     switch( attr )
  1123.     {   case(ChainAttr):   attrno = InfoChainCount;   
  1124.                            break;
  1125.  
  1126.         case(GroupAttr):   factor = MinMainRes;
  1127.                            attrno = MaxMainRes;
  1128.                            if( HetaGroups && HetaGroupCount )
  1129.                            {   if( MinHetaRes < factor )
  1130.                                    factor = MinHetaRes;
  1131.                                if( MaxHetaRes > attrno )
  1132.                                    attrno = MaxHetaRes;
  1133.                            } 
  1134.                            attrno -= factor;
  1135.                            break;
  1136.  
  1137.         case(TempAttr):    factor = MinMainTemp;
  1138.                            attrno = MaxMainTemp;
  1139.                            if( HetaGroups && HetaGroupCount )
  1140.                            {   if( MinHetaTemp < factor )
  1141.                                    factor = MinHetaTemp;
  1142.                                if( MaxHetaTemp > attrno )
  1143.                                    attrno = MaxHetaTemp;
  1144.                            }
  1145.                            attrno -= factor;
  1146.                            break;
  1147.  
  1148.         default:           return;
  1149.     }
  1150.  
  1151.     if( attrno<2 )
  1152.     {   if( CommandActive )
  1153.             WriteChar('\n');
  1154.         WriteString("Warning: Only a single attribute value!\n");
  1155.         CommandActive = False;
  1156.         return;
  1157.     }
  1158.  
  1159.     ResetColourAttrib();
  1160.     ScaleColourMap(attrno);
  1161.  
  1162.     switch( attr )
  1163.     {    case(ChainAttr):
  1164.                  count = 0;
  1165.                  for( chain=Database->clist; chain; chain=chain->cnext )
  1166.                  {   ref = &(ScaleRef[(count*ScaleCount)/attrno]);
  1167.                      if( !(ref->col && Shade[ref->shade].refcount) )
  1168.                      {   ref->shade = DefineShade(ref->r,ref->g,ref->b);
  1169.                          ref->col = Shade2Colour(ref->shade);
  1170.                      }
  1171.                      for( group=chain->glist; group; group=group->gnext )
  1172.                          for( ptr=group->alist; ptr; ptr=ptr->anext )
  1173.                              if( ptr->flag&SelectFlag )
  1174.                              {   Shade[ref->shade].refcount++;
  1175.                                  ptr->col = ref->col;
  1176.                              }
  1177.                      count++;
  1178.                  }
  1179.                  break;
  1180.  
  1181.  
  1182.          case(GroupAttr):
  1183.                  factor++;
  1184.                  for( chain=Database->clist; chain; chain=chain->cnext )
  1185.                      for( group=chain->glist; group; group=group->gnext )
  1186.                      {   count = group->serno-factor;
  1187.                          if( count<0 )
  1188.                          {   ref = ScaleRef;
  1189.                          } else if( count<attrno )
  1190.                          {   count = (ScaleCount*count)/attrno;
  1191.                              ref = ScaleRef + count;
  1192.                          } else ref = ScaleRef + (ScaleCount-1);
  1193.  
  1194.                          if( !(ref->col && Shade[ref->shade].refcount) )
  1195.                          {   ref->shade = DefineShade(ref->r,ref->g,ref->b);
  1196.                              ref->col = Shade2Colour(ref->shade);
  1197.                          }
  1198.  
  1199.                          for( ptr=group->alist; ptr; ptr=ptr->anext )
  1200.                              if( ptr->flag&SelectFlag )
  1201.                              {   Shade[ref->shade].refcount++;
  1202.                                  ptr->col = ref->col;
  1203.                              }
  1204.                      }
  1205.                  break;
  1206.  
  1207.  
  1208.          case(TempAttr):
  1209.                  factor++;
  1210.                  ForEachAtom
  1211.                      if( ptr->flag&SelectFlag )
  1212.                      {   count = ptr->temp-factor;
  1213.                          if( count<0 )
  1214.                          {   ref = ScaleRef;
  1215.                          } else if( count<attrno )
  1216.                          {   count = (ScaleCount*count)/attrno;
  1217.                              ref = ScaleRef + count;
  1218.                          } else ref = ScaleRef + (ScaleCount-1);
  1219.  
  1220.                          if( !ref->col )
  1221.                          {   ref->shade = DefineShade(ref->r,ref->g,ref->b);
  1222.                              ref->col = Shade2Colour(ref->shade);
  1223.                          }
  1224.                          Shade[ref->shade].refcount++;
  1225.                          ptr->col = ref->col;
  1226.                      }
  1227.                  break;
  1228.     }
  1229. }
  1230.  
  1231.  
  1232.  
  1233. static int MatchNumber( len, value, mask )
  1234.     int len, value;
  1235.     char *mask;
  1236. {
  1237.     register char digit, template;
  1238.     register int result;
  1239.     register int i;
  1240.  
  1241.     result = True;
  1242.     for( i=0; i<len; i++ )
  1243.     {   digit = (value%10) + '0';
  1244.         template = mask[len-i];
  1245.         if( template==' ' )
  1246.         {   if( value ) result = False;
  1247.         } else if( !MatchChar(template,digit) )
  1248.             result = False;
  1249.         value/=10;
  1250.     }
  1251.     return( result );
  1252. }
  1253.  
  1254.  
  1255. void UserMaskAttrib( fields )
  1256.     int fields;
  1257. {
  1258.     register MaskDesc *mptr;
  1259.     register char *temp, *name;
  1260.     register int shade, change;
  1261.     register int i, rad, match;
  1262.  
  1263.     register Chain __far *chain;
  1264.     register Group __far *group;
  1265.     register Atom __far *ptr;
  1266.  
  1267.  
  1268.     if( !Database ) return;
  1269.  
  1270.     if( !MaskCount )
  1271.     {   if( CommandActive )
  1272.             WriteChar('\n');
  1273.         WriteString("Warning: No user supplied colour records!\n");
  1274.         CommandActive = False;
  1275.         return;
  1276.     }
  1277.  
  1278.     change = False;
  1279.     ResetColourAttrib();
  1280.     if( fields&MaskColourFlag )
  1281.         for( i=0; i<MaskCount; i++ )
  1282.             MaskShade[i] = -1;
  1283.  
  1284.     if( fields&MaskRadiusFlag )
  1285.     {   MaxAtomRadius = 0;
  1286.         DrawAtoms = False;
  1287.     }
  1288.  
  1289.  
  1290.     ForEachAtom
  1291.     if( ptr->flag&SelectFlag )
  1292.     {   for( i=0; i<MaskCount; i++ )
  1293.         {   mptr = UserMask+i;
  1294.             temp = mptr->mask;
  1295.             match = True;
  1296.  
  1297.             if( !MatchChar(temp[13],chain->ident) ) match=False;
  1298.             if( !MatchChar(temp[9],ptr->altl) )     match=False;
  1299.  
  1300.             /* Atom Name */
  1301.             if( match )
  1302.             {   name = ElemDesc[ptr->refno];
  1303.                 if( !MatchChar(temp[5],name[0]) ) match=False;
  1304.                 if( !MatchChar(temp[6],name[1]) ) match=False;
  1305.             if( !MatchChar(temp[7],name[2]) ) match=False;
  1306.             if( !MatchChar(temp[8],name[3]) ) match=False;
  1307.             }
  1308.  
  1309.             /* Group Name */
  1310.             if( match )
  1311.             {   name = Residue[group->refno];
  1312.                 if( !MatchChar(temp[10],name[0]) ) match=False;
  1313.                 if( !MatchChar(temp[11],name[1]) ) match=False;
  1314.                 if( !MatchChar(temp[12],name[2]) ) match=False;
  1315.             }
  1316.  
  1317.  
  1318.             if( match && (mptr->flags&SerNoFlag) )
  1319.                 match = MatchNumber(4,ptr->serno,&temp[0]);
  1320.             if( match && (mptr->flags&ResNoFlag) )
  1321.                 match = MatchNumber(3,group->serno,&temp[14]);
  1322.             if( match ) break;
  1323.         }
  1324.  
  1325.         if( fields&MaskColourFlag )
  1326.         {   if( match )
  1327.             {   if( MaskShade[i] == -1 )
  1328.                 {   MaskShade[i] = DefineShade(mptr->r,mptr->g,mptr->b);
  1329.                     MaskColour[i] = Shade2Colour(MaskShade[i]);
  1330.                 }
  1331.                 Shade[MaskShade[i]].refcount++;
  1332.                 ptr->col = MaskColour[i];
  1333.             } else
  1334.             {   shade = DefineShade(255,255,255);
  1335.                 ptr->col = Shade2Colour(shade);
  1336.                 Shade[shade].refcount++;
  1337.             }
  1338.         }
  1339.  
  1340.         if( fields&MaskRadiusFlag )
  1341.         {   rad = match? mptr->radius : 375;
  1342.             ptr->irad = (int)(Scale*rad);
  1343.             ptr->flag |= SphereFlag;
  1344.             ptr->radius = rad;
  1345.  
  1346.             if( ptr->irad>MaxAtomRadius )
  1347.                 MaxAtomRadius = ptr->irad;
  1348.             change = True;
  1349.         }
  1350.     } else if( ptr->flag&SphereFlag )
  1351.     {   DrawAtoms = True;
  1352.         if( ptr->irad>MaxAtomRadius )
  1353.             MaxAtomRadius = ptr->irad;
  1354.     }
  1355.  
  1356.     if( change )
  1357.     {   DrawAtoms = True;
  1358.         DetermineClipping();
  1359.         VoxelsClean = False;
  1360.         BucketFlag = False;
  1361.     }
  1362. }
  1363.  
  1364.  
  1365. void CPKColourAttrib()
  1366. {
  1367.     register ShadeRef *ref;
  1368.     register Chain __far *chain;
  1369.     register Group __far *group;
  1370.     register Atom __far *ptr;
  1371.     register int i;
  1372.  
  1373.     if( !Database ) return;
  1374.     for( i=0; i<7; i++ )
  1375.         CPKShade[i].col = 0;
  1376.     ResetColourAttrib();
  1377.  
  1378.  
  1379.     ForEachAtom
  1380.         if( ptr->flag&SelectFlag )
  1381.         {   i = GetElemIdent( ptr );
  1382.             ref = CPKShade + CPKIndex[i];
  1383.  
  1384.             if( !ref->col )
  1385.             {   ref->shade = DefineShade( ref->r, ref->g, ref->b );
  1386.                 ref->col = Shade2Colour(ref->shade);
  1387.             }
  1388.             Shade[ref->shade].refcount++;
  1389.             ptr->col = ref->col;
  1390.         }
  1391. }
  1392.  
  1393.  
  1394. void AminoColourAttrib()
  1395. {
  1396.     register ShadeRef *ref;
  1397.     register Chain __far *chain;
  1398.     register Group __far *group;
  1399.     register Atom __far *ptr;
  1400.     register int i;
  1401.  
  1402.     if( !Database ) return;
  1403.     for( i=0; i<13; i++ )
  1404.         AminoShade[i].col = 0;
  1405.     ResetColourAttrib();
  1406.  
  1407.     ForEachAtom
  1408.         if( ptr->flag&SelectFlag )
  1409.         {   if( IsAmino(group->refno) )
  1410.             {   ref = AminoShade + AminoIndex[group->refno];
  1411.             } else ref = AminoShade+12;
  1412.  
  1413.             if( !ref->col )
  1414.             {   ref->shade = DefineShade( ref->r, ref->g, ref->b );
  1415.                 ref->col = Shade2Colour(ref->shade);
  1416.             }
  1417.             Shade[ref->shade].refcount++;
  1418.             ptr->col = ref->col;
  1419.         }
  1420. }
  1421.  
  1422.  
  1423. void ShapelyColourAttrib()
  1424. {
  1425.     register ShadeRef *ref;
  1426.     register Chain __far *chain;
  1427.     register Group __far *group;
  1428.     register Atom __far *ptr;
  1429.     register int i;
  1430.  
  1431.     if( !Database ) return;
  1432.     for( i=0; i<30; i++ )
  1433.         Shapely[i].col = 0;
  1434.     ResetColourAttrib();
  1435.  
  1436.     ForEachAtom
  1437.         if( ptr->flag&SelectFlag )
  1438.         {   if( IsAminoNucleo(group->refno) )
  1439.             {   ref = Shapely + group->refno;
  1440.             } else ref = Shapely+30;
  1441.  
  1442. /*  Original Colour Scheme
  1443.  *
  1444.  *  ref = &(Shapely[26]);
  1445.  *  if( IsNucleo(group->refno) )
  1446.  *  {   ref = Shapely + group->refno;
  1447.  *  } else if( IsShapelyBackbone(ptr->refno) )
  1448.  *  {   ref = &(Shapely[24]);
  1449.  *  } else if( IsShapelySpecial(ptr->refno) )
  1450.  *  {   ref = &(Shapely[25]);
  1451.  *  } else if( IsAmino(group->refno) )
  1452.  *      ref = Shapely + group->refno;
  1453.  */
  1454.  
  1455.             if( !ref->col )
  1456.             {   ref->shade = DefineShade( ref->r, ref->g, ref->b );
  1457.                 ref->col = Shade2Colour(ref->shade);
  1458.             }
  1459.             Shade[ref->shade].refcount++;
  1460.             ptr->col = ref->col;
  1461.         }
  1462. }
  1463.  
  1464.  
  1465. void StructColourAttrib()
  1466. {
  1467.     register ShadeRef *ref;
  1468.     register Chain __far *chain;
  1469.     register Group __far *group;
  1470.     register Atom __far *ptr;
  1471.     register int i;
  1472.  
  1473.     if( !Database )
  1474.         return;
  1475.  
  1476.     if( InfoHelixCount<0 )
  1477.         DetermineStructure();
  1478.  
  1479.     for( i=0; i<30; i++ )
  1480.         StructShade[i].col = 0;
  1481.     ResetColourAttrib();
  1482.  
  1483.     ForEachAtom
  1484.         if( ptr->flag&SelectFlag )
  1485.         {   if( group->flag & HelixFlag )
  1486.             {   ref = StructShade+1;
  1487.             } else if( group->flag & SheetFlag )
  1488.             {   ref = StructShade+2;
  1489.             } else if( group->flag & TurnFlag )
  1490.             {   ref = StructShade+3;
  1491.             } else ref = StructShade;
  1492.  
  1493.             if( !ref->col )
  1494.             {   ref->shade = DefineShade( ref->r, ref->g, ref->b );
  1495.                 ref->col = Shade2Colour(ref->shade);
  1496.             }
  1497.             Shade[ref->shade].refcount++;
  1498.             ptr->col = ref->col;
  1499.         }
  1500. }
  1501.  
  1502.  
  1503. void InitialTransform()
  1504. {
  1505.     register Card dist;
  1506.     register Long x, y, z;
  1507.     register Long dx, dy, dz;
  1508.     register Card ax, ay, az;
  1509.     register Chain __far *chain;
  1510.     register Group __far *group;
  1511.     register Atom __far *ptr;
  1512.  
  1513.  
  1514.     dx = MaxX-MinX;   OrigCX = (dx>>1)+MinX;
  1515.     dy = MaxY-MinY;   OrigCY = (dy>>1)+MinY;
  1516.     dz = MaxZ-MinZ;   OrigCZ = (dz>>1)+MinZ;
  1517.  
  1518.     MaxX -= OrigCX;   MinX -= OrigCX;
  1519.     MaxY -= OrigCY;   MinY -= OrigCY;
  1520.     MaxZ -= OrigCZ;   MinZ -= OrigCZ;
  1521.  
  1522.     WorldRadius = 0;
  1523.     SideLen = MaxFun(dx,dy);
  1524.     if( dz>SideLen ) SideLen = dz;
  1525.     SideLen += 1000;  Offset = SideLen>>1;
  1526.     XOffset = WRange;  YOffset = HRange;
  1527.  
  1528.     ForEachAtom
  1529.     {   x = ptr->xorg-OrigCX;   ptr->xorg = x;  ax = (Card)AbsFun(x);
  1530.         y = ptr->yorg-OrigCY;   ptr->yorg = y;  ay = (Card)AbsFun(y);
  1531.         z = ptr->zorg-OrigCZ;   ptr->zorg = z;  az = (Card)AbsFun(z);
  1532.         dist = ax*ax + ay*ay + az*az;
  1533.         if( dist>WorldRadius )
  1534.         WorldRadius = dist;
  1535.     }
  1536.  
  1537.     WorldRadius = (Card)sqrt((double)WorldRadius);
  1538.     WorldSize = WorldRadius<<1;
  1539.     DScale = 1.0/(WorldSize+1000);
  1540.  
  1541.     /* MaxZoom*DScale*Range*500 == 118 */
  1542.     MaxZoom = 0.236*(WorldSize+1000)/Range;
  1543.     ZoomRange = Range;
  1544.     MaxZoom -= 1.0;
  1545.  
  1546. }
  1547.  
  1548.  
  1549. void ReviseInvMatrix()
  1550. {
  1551.     InvX[0] = IScale*( DirX[0] = RotY[1]*RotZ[2]-RotY[2]*RotZ[1] );
  1552.     InvX[1] = IScale*( DirX[1] = RotX[2]*RotZ[1]-RotX[1]*RotZ[2] );
  1553.     InvX[2] = IScale*( DirX[2] = RotX[1]*RotY[2]-RotX[2]*RotY[1] );
  1554.  
  1555.     InvY[0] = IScale*( DirY[0] = RotY[2]*RotZ[0]-RotY[0]*RotZ[2] );
  1556.     InvY[1] = IScale*( DirY[1] = RotX[0]*RotZ[2]-RotX[2]*RotZ[0] );
  1557.     InvY[2] = IScale*( DirY[2] = RotX[2]*RotY[0]-RotX[0]*RotY[2] );
  1558.  
  1559.     InvZ[0] = IScale*( DirZ[0] = RotY[0]*RotZ[1]-RotY[1]*RotZ[0] );
  1560.     InvZ[1] = IScale*( DirZ[1] = RotX[1]*RotZ[0]-RotX[0]*RotZ[1] );
  1561.     InvZ[2] = IScale*( DirZ[2] = RotX[0]*RotY[1]-RotX[1]*RotY[0] );
  1562.  
  1563.     ShadowTransform();
  1564. }
  1565.  
  1566.  
  1567. void PrepareTransform()
  1568. {
  1569.     register Real theta, temp;
  1570.     register Real cost, sint;
  1571.     register Real x, y, z;
  1572.     register Real ncost;
  1573.  
  1574.     if( (ReDrawFlag&RFRotateX) && (DialValue[0]!=LastRX) )
  1575.     {   theta = PI*(DialValue[0]-LastRX);
  1576.         cost = cos(theta);  sint = sin(theta);
  1577.         LastRX = DialValue[0];
  1578.  
  1579.         y=RotY[0]; z=RotZ[0];
  1580.         RotY[0]=cost*y+sint*z; 
  1581.         RotZ[0]=cost*z-sint*y;
  1582.  
  1583.         y=RotY[1]; z=RotZ[1];
  1584.         RotY[1]=cost*y+sint*z;
  1585.         RotZ[1]=cost*z-sint*y;
  1586.  
  1587.         y=RotY[2]; z=RotZ[2];
  1588.         RotY[2]=cost*y+sint*z;
  1589.         RotZ[2]=cost*z-sint*y;
  1590.  
  1591.         if( UseShadow )
  1592.         {   y=DirX[1]; z=DirX[2];
  1593.             DirX[1]=cost*y+sint*z;
  1594.             DirX[2]=cost*z-sint*y;
  1595.  
  1596.             y=DirY[1]; z=DirY[2];
  1597.             DirY[1]=cost*y+sint*z;
  1598.             DirY[2]=cost*z-sint*y;
  1599.  
  1600.             y=DirZ[1]; z=DirZ[2];
  1601.             DirZ[1]=cost*y+sint*z;
  1602.             DirZ[2]=cost*z-sint*y;
  1603.         }
  1604.  
  1605.         if( CenX || CenY || CenZ )
  1606.         {   ncost = 1.0-cost;
  1607.             temp =  CenX*(ncost*RotY[0] + sint*RotZ[0]);
  1608.             temp += CenY*(ncost*RotY[1] + sint*RotZ[1]);
  1609.             temp += CenZ*(ncost*RotY[2] + sint*RotZ[2]);
  1610.             temp = DialValue[5] - (Scale*temp)/YRange;
  1611.  
  1612.             if( temp < -1.0 )
  1613.             {   DialValue[5] = -1.0;
  1614.             } else if( temp > 1.0 )
  1615.             {   DialValue[5] = 1.0;
  1616.             } else DialValue[5] = temp;
  1617.         }
  1618.     }
  1619.  
  1620.     if( (ReDrawFlag&RFRotateY) && (DialValue[1]!=LastRY) )
  1621.     {   theta = PI*(DialValue[1]-LastRY);
  1622.         cost = cos(theta);  sint = sin(theta);
  1623.         LastRY = DialValue[1];
  1624.  
  1625.         x=RotX[0]; z=RotZ[0];
  1626.         RotX[0]=cost*x+sint*z;
  1627.         RotZ[0]=cost*z-sint*x;
  1628.  
  1629.         x=RotX[1]; z=RotZ[1];
  1630.         RotX[1]=cost*x+sint*z;
  1631.         RotZ[1]=cost*z-sint*x;
  1632.  
  1633.         x=RotX[2]; z=RotZ[2];
  1634.         RotX[2]=cost*x+sint*z;
  1635.         RotZ[2]=cost*z-sint*x;
  1636.  
  1637.         if( UseShadow )
  1638.         {   x=DirX[0]; z=DirX[2];
  1639.             DirX[0]=cost*x+sint*z;
  1640.             DirX[2]=cost*z-sint*x;
  1641.  
  1642.             x=DirY[0]; z=DirY[2];
  1643.             DirY[0]=cost*x+sint*z;
  1644.             DirY[2]=cost*z-sint*x;
  1645.  
  1646.             x=DirZ[0]; z=DirZ[2];
  1647.             DirZ[0]=cost*x+sint*z;
  1648.             DirZ[2]=cost*z-sint*x;
  1649.         }
  1650.  
  1651.         if( CenX || CenY || CenZ )
  1652.         {   ncost = 1.0-cost;
  1653.             temp =  CenX*(ncost*RotX[0] + sint*RotZ[0]);
  1654.             temp += CenY*(ncost*RotX[1] + sint*RotZ[1]);
  1655.             temp += CenZ*(ncost*RotX[2] + sint*RotZ[2]);
  1656.             temp = DialValue[4] - (Scale*temp)/XRange;
  1657.  
  1658.             if( temp < -1.0 )
  1659.             {   DialValue[4] = -1.0;
  1660.             } else if( temp > 1.0 )
  1661.             {   DialValue[4] = 1.0;
  1662.             } else DialValue[4] = temp;
  1663.         }
  1664.     }
  1665.  
  1666.     if( (ReDrawFlag&RFRotateZ) && (DialValue[2]!=LastRZ) )
  1667.     {   theta = PI*(DialValue[2]-LastRZ);
  1668.         cost = cos(theta);  sint = sin(theta);
  1669.         LastRZ = DialValue[2];
  1670.  
  1671.         x=RotX[0]; y=RotY[0];
  1672.         RotX[0]=cost*x-sint*y;
  1673.         RotY[0]=cost*y+sint*x;
  1674.  
  1675.         x=RotX[1]; y=RotY[1];
  1676.         RotX[1]=cost*x-sint*y;
  1677.         RotY[1]=cost*y+sint*x;
  1678.  
  1679.         x=RotX[2]; y=RotY[2];
  1680.         RotX[2]=cost*x-sint*y;
  1681.         RotY[2]=cost*y+sint*x;
  1682.  
  1683.         if( UseShadow )
  1684.         {   x=DirX[0]; y=DirX[1];
  1685.             DirX[0]=cost*x-sint*y;
  1686.             DirX[1]=cost*y+sint*x;
  1687.  
  1688.             x=DirY[0]; y=DirY[1];
  1689.             DirY[0]=cost*x-sint*y;
  1690.             DirY[1]=cost*y+sint*x;
  1691.  
  1692.             x=DirZ[0]; y=DirZ[1];
  1693.             DirZ[0]=cost*x-sint*y;
  1694.             DirZ[1]=cost*y+sint*x;
  1695.         }
  1696.  
  1697.         if( CenX || CenY || CenZ )
  1698.         {   ncost = 1.0-cost;
  1699.             temp =  CenX*(ncost*RotX[0] - sint*RotY[0]);
  1700.             temp += CenY*(ncost*RotX[1] - sint*RotY[1]);
  1701.             temp += CenZ*(ncost*RotX[2] - sint*RotY[2]);
  1702.             temp = DialValue[4] - (Scale*temp)/XRange;
  1703.  
  1704.             if( temp < -1.0 )
  1705.             {   DialValue[4] = -1.0;
  1706.             } else if( temp > 1.0 )
  1707.             {   DialValue[4] = 1.0;
  1708.             } else DialValue[4] = temp;
  1709.  
  1710.             ncost = 1.0-cost;
  1711.             temp =  CenX*(ncost*RotY[0] + sint*RotX[0]);
  1712.             temp += CenY*(ncost*RotY[1] + sint*RotX[1]);
  1713.             temp += CenZ*(ncost*RotY[2] + sint*RotX[2]);
  1714.             temp = DialValue[5] - (Scale*temp)/YRange;
  1715.  
  1716.             if( temp < -1.0 )
  1717.             {   DialValue[5] = -1.0;
  1718.             } else if( temp > 1.0 )
  1719.             {   DialValue[5] = 1.0;
  1720.             } else DialValue[5] = temp;
  1721.         }
  1722.     }
  1723. }
  1724.  
  1725.  
  1726. void ApplyTransform()
  1727. {
  1728.     register int temp;
  1729.     register Real x, y, z;
  1730.     register int oldx,oldy;
  1731.     register Chain __far *chain;
  1732.     register Group __far *group;
  1733.     register HBond __far *hptr;
  1734.     register Bond __far *bptr;
  1735.     register Atom __far *ptr;
  1736.  
  1737.  
  1738.     if( ReDrawFlag & RFMagnify )
  1739.     {   if( DialValue[3] <= 0.0 )
  1740.         {   Zoom = DialValue[3]+1.0;
  1741.             if( Zoom<0.1 ) Zoom=0.1;
  1742.         } else Zoom = (DialValue[3]*MaxZoom) + 1.0;
  1743.  
  1744.         Scale = Zoom*DScale*Range;
  1745.         ImageSize = (int)(Scale*WorldSize);
  1746.         ImageRadius = ImageSize>>1;
  1747.         IScale = 1.0/Scale;
  1748.  
  1749.         MaxAtomRadius = 0;
  1750.         MaxBondRadius = 0;
  1751.     }
  1752.  
  1753.     if( ReDrawFlag & RFRotate )
  1754.     {   PrepareTransform();
  1755.         if( UseShadow )
  1756.             ShadowTransform();
  1757.     }
  1758.  
  1759.     if( ReDrawFlag & (RFRotate|RFMagnify) )
  1760.     {   MatX[0] = Scale*RotX[0]; 
  1761.         MatX[1] = Scale*RotX[1];
  1762.         MatX[2] = Scale*RotX[2];
  1763.  
  1764.         MatY[0] = Scale*RotY[0];
  1765.         MatY[1] = Scale*RotY[1];
  1766.         MatY[2] = Scale*RotY[2];
  1767.  
  1768.         MatZ[0] = Scale*RotZ[0];
  1769.         MatZ[1] = Scale*RotZ[1];
  1770.         MatZ[2] = Scale*RotZ[2];
  1771.  
  1772.         if( UseShadow )
  1773.         {   InvX[0] = IScale*DirX[0]; 
  1774.             InvX[1] = IScale*DirX[1];
  1775.             InvX[2] = IScale*DirX[2];
  1776.  
  1777.             InvY[0] = IScale*DirY[0];
  1778.             InvY[1] = IScale*DirY[1];
  1779.             InvY[2] = IScale*DirY[2];
  1780.  
  1781.             InvZ[0] = IScale*DirZ[0];
  1782.             InvZ[1] = IScale*DirZ[1];
  1783.             InvZ[2] = IScale*DirZ[2];
  1784.         }
  1785.     }
  1786.  
  1787.     oldx = XOffset;
  1788.     oldy = YOffset;
  1789.     XOffset = WRange + (int)(DialValue[4]*XRange);
  1790.     YOffset = HRange + (int)(DialValue[5]*YRange);
  1791.  
  1792.     /* Zoom dependent Translation! */
  1793.     /* XOffset = WRange + (int)(DialValue[4]*ImageSize); */
  1794.     /* YOffset = HRange + (int)(DialValue[5]*ImageSize); */
  1795.  
  1796.  
  1797.     switch( ReDrawFlag )
  1798.     {   case(RFTransX):
  1799.                 if( temp = XOffset-oldx ) 
  1800.                     ForEachAtom ptr->x += temp;
  1801.                 break;
  1802.  
  1803.         case(RFTransY):
  1804.                 if( temp = YOffset-oldy ) 
  1805.                     ForEachAtom ptr->y += temp;
  1806.                 break;
  1807.  
  1808.         case(RFRotateX):
  1809.             ForEachAtom
  1810.             {   x = ptr->xorg; y = ptr->yorg; z = ptr->zorg;
  1811.                 ptr->z = (int)(x*MatZ[0]+y*MatZ[1]+z*MatZ[2])+ImageRadius;
  1812.                 ptr->y = (int)(x*MatY[0]+y*MatY[1]+z*MatY[2])+YOffset;
  1813.             }
  1814.             break;
  1815.  
  1816.         case(RFRotateY):
  1817.             ForEachAtom
  1818.             {   x = ptr->xorg; y = ptr->yorg; z = ptr->zorg;
  1819.                 ptr->z = (int)(x*MatZ[0]+y*MatZ[1]+z*MatZ[2])+ImageRadius;
  1820.                 ptr->x = (int)(x*MatX[0]+y*MatX[1]+z*MatX[2])+XOffset;
  1821.             }
  1822.             break;
  1823.  
  1824.         case(RFRotateZ):
  1825.             ForEachAtom
  1826.             {   x = ptr->xorg; y = ptr->yorg; z = ptr->zorg;
  1827.                 ptr->x = (int)(x*MatX[0]+y*MatX[1]+z*MatX[2])+XOffset;
  1828.                 ptr->y = (int)(x*MatY[0]+y*MatY[1]+z*MatY[2])+YOffset;
  1829.             }
  1830.             break;
  1831.  
  1832.         default:
  1833.             if( DrawAtoms && (ReDrawFlag&RFMagnify) )
  1834.             {   ForEachAtom 
  1835.                 {   x = ptr->xorg; y = ptr->yorg; z = ptr->zorg;
  1836.                     ptr->z = (int)(x*MatZ[0]+y*MatZ[1]+z*MatZ[2])+ImageRadius;
  1837.                     ptr->x = (int)(x*MatX[0]+y*MatX[1]+z*MatX[2])+XOffset;
  1838.                     ptr->y = (int)(x*MatY[0]+y*MatY[1]+z*MatY[2])+YOffset;
  1839.                     if( ptr->flag&SphereFlag )
  1840.                     {   ptr->irad = (int)(Scale*ptr->radius);
  1841.                         if( ptr->irad>MaxAtomRadius )
  1842.                             MaxAtomRadius = ptr->irad;
  1843.                     }
  1844.                 }
  1845.             } else
  1846.                 ForEachAtom 
  1847.                 {   x = ptr->xorg; y = ptr->yorg; z = ptr->zorg;
  1848.                     ptr->z = (int)(x*MatZ[0]+y*MatZ[1]+z*MatZ[2])+ImageRadius;
  1849.                     ptr->x = (int)(x*MatX[0]+y*MatX[1]+z*MatX[2])+XOffset;
  1850.                     ptr->y = (int)(x*MatY[0]+y*MatY[1]+z*MatY[2])+YOffset;
  1851.                 }
  1852.  
  1853.             if( ReDrawFlag & RFMagnify )
  1854.             {   if( DrawBonds )
  1855.                     ForEachBond
  1856.                         if( bptr->flag&CylinderFlag )
  1857.                         {   bptr->irad = (int)(Scale*bptr->radius);
  1858.                             if( bptr->irad>MaxBondRadius )
  1859.                             MaxBondRadius = bptr->irad;
  1860.                         }
  1861.  
  1862.                 for( hptr=Database->hlist; hptr; hptr=hptr->hnext )
  1863.                     if( hptr->flag&CylinderFlag )
  1864.                         hptr->irad = (int)(Scale*hptr->radius);
  1865.  
  1866.                 for( hptr=Database->slist; hptr; hptr=hptr->hnext )
  1867.                     if( hptr->flag&CylinderFlag )
  1868.                         hptr->irad = (int)(Scale*hptr->radius);
  1869.  
  1870.                 ForEachBack
  1871.                     if( bptr->flag&CylinderFlag )
  1872.                         bptr->irad = (int)(Scale*bptr->radius);
  1873.             }
  1874.     }
  1875.  
  1876.     DetermineClipping();
  1877.     if( UseScreenClip || ReDrawFlag!=RFRotateY )
  1878.         BucketFlag = False;
  1879. }
  1880.  
  1881.  
  1882. void ResetTransform()
  1883. {
  1884.     RotX[0] = 1.0;  RotX[1] = 0.0;  RotX[2] = 0.0;
  1885.     RotY[0] = 0.0;  RotY[1] = 1.0;  RotY[2] = 0.0;
  1886.     RotZ[0] = 0.0;  RotZ[1] = 0.0;  RotZ[2] = 1.0;
  1887.  
  1888.     DirX[0] = 1.0;  DirX[1] = 0.0;  DirX[2] = 0.0;
  1889.     DirY[0] = 0.0;  DirY[1] = 1.0;  DirY[2] = 0.0;
  1890.     DirZ[0] = 0.0;  DirZ[1] = 0.0;  DirZ[2] = 1.0;
  1891.  
  1892.     LastRX = LastRY = LastRZ = 0.0;
  1893.     CenX = CenY = CenZ = 0;
  1894. }
  1895.  
  1896.  
  1897. void InitialiseTransform()
  1898. {
  1899.     ColourDepth = DefaultColDepth;
  1900.     ColourMask = ColourDepth-1;
  1901.     Ambient = DefaultAmbient;
  1902.  
  1903.     LastShade = Colour2Shade(LutSize);
  1904.  
  1905.     ResetColourMap();
  1906.     ResetTransform();
  1907.  
  1908.     ZoneBoth = False;
  1909.     HetaGroups = True;
  1910.     Hydrogens = True;
  1911. }
  1912.  
  1913.