Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
viewers.cc
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 noet:
3 //
4 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 
10 /// @file
11 /// @brief
12 /// @author
13 
14 // Unit headers
16 
20 
21 // Package headers
24 #include <core/id/AtomID.hh>
25 
26 #include <core/pose/Pose.hh>
28 
29 #if defined(WIN32) || defined(BOINC)
34 #include <basic/options/keys/edensity.OptionKeys.gen.hh>
36 #endif
37 
39 
40 
41 // Project headers
42 // AUTO-REMOVED #include <ObjexxFCL/string.functions.hh>
43 
44 #ifdef GL_GRAPHICS
48 #include <protocols/viewer/triangleIterator.hh> //should not be auto-removed!! needed for graphics!
49 #include <protocols/viewer/ConformationViewer.hh> //should not be auto-removed!! needed for graphics!
50 #include <protocols/viewer/ConformationViewer.fwd.hh> //should not be auto-removed!! needed for graphics!
51 #include <ObjexxFCL/string.functions.hh> //should not be auto-removed!! needed for graphics!
52 #include <core/chemical/ResidueTypeSet.hh> //should not be auto-removed!! needed for graphics!
53 #include <core/chemical/ChemicalManager.hh> //should not be auto-removed!! needed for graphics!
56 #include <basic/options/keys/edensity.OptionKeys.gen.hh>
57 #endif
58 
59 // Utility headers
60 #include <utility/vector1.hh>
61 
62 #include <numeric/NumericTraits.hh>
63 
64 // GLUT
65 #if defined GL_GRAPHICS || defined BOINC_GRAPHICS
66 
67 #ifdef MAC
68 #include <GLUT/glut.h>
69 #elif _WIN32
70 #include <glut/glut.h>
71 #else
72 #include "GL/glut.h"
73 #endif
74 
75 #endif
76 
77 using namespace core; /////////////////////////////////////////// DANGER
78 
79 namespace protocols {
80 namespace viewer {
81 
82 #ifdef GL_GRAPHICS
83 // prototypes
84 void check_for_new_conformation_viewers();
85 
86 // global data
87 typedef std::map< int, ConformationViewerOP > ConformationViewers;
88 ConformationViewers conformation_viewers;
89 utility::vector1< ConformationViewerOP > new_conformation_viewers;
90 
91 pthread_mutex_t new_conformation_viewers_mut = PTHREAD_MUTEX_INITIALIZER;
92 
93 pthread_mutex_t start_mut = PTHREAD_MUTEX_INITIALIZER;
94 
95 pthread_cond_t start_cond = PTHREAD_COND_INITIALIZER;
96 
97 #endif
98 
99 #if defined GL_GRAPHICS || defined BOINC_GRAPHICS
100 
101 namespace graphics {
102  int window_size = 30;
103  int specialKey = 0;
104  bool click;
105  bool clicked_button;
106  int click_x;
107  int click_y;
108 
109  // pointer to a graphics_state object for each ConformationViewer
110  std::map< int , GraphicsState* > gs_map_;
111 
112  // Vector bg_color( 1.0f, 1.0f, 1.0f ); // white
113  Vector bg_color( 0.0f, 0.0f, 0.0f ); // black
114 
115  // rhiju parameters for cartoons
116  const int NUM_SEGMENTS = 5;
117  const int NUM_SEGMENTS_COIL = 10;
118  const core::Real HELIX_HALF_WIDTH = 1.5;
119  const core::Real STRAND_HALF_WIDTH = 1.0;
120  const core::Real COILRADIUS = 0.2;
121  const core::Real HELIX_HERMITE_FACTOR = 4.7;
122  const core::Real STRAND_HERMITE_FACTOR = 4.7;
123  const core::Real COIL_HERMITE_FACTOR = 5.0;
124  const core::Real NA_HERMITE_FACTOR = 7.7;
125  const core::Real CHAINBREAK_CUTOFF2 = 4.5*4.5;
126  const core::Real CHAINBREAK_CUTOFF2_NA = 7.5*7.5;
127  const core::Real SHOWBONDCUTOFF2 = (5.0*5.0)/(NUM_SEGMENTS*NUM_SEGMENTS);
128  const core::Real SHOWBONDCUTOFF2_COIL = (5.0*5.0)/(NUM_SEGMENTS_COIL*NUM_SEGMENTS_COIL);
129  const core::Real SHOWBONDCUTOFF2_NA = (8.0*8.0)/(NUM_SEGMENTS*NUM_SEGMENTS);
130 
131  //lin parameters for spacefill
132  core::Real const ligand_sphere_opacity( 1.0 );
133  core::Real const protein_sphere_opacity( 1.0 );
134  core::Real const ligand_sphere_shininess( 1.0);
135  core::Real const protein_sphere_shininess( 1.0 );
136  //lin parameters for ball and stick
137  core::Real const protein_wireframeScale( 0.2 );
138  core::Real const protein_stickScale( 0.2 );
139  core::Real const protein_sphereScale( 0.2 );
140  int sphereDisplayList = 0;
141  core::Real const BOND_LENGTH_CUTOFF2 = 6.0*6.0;
142 }
143 
144 #endif
145 
146 #if defined GL_GRAPHICS
147 
148 
149 void processMouse(int button, int state, int x, int y) {
150  using namespace graphics;
151 
152  //std::cout << "processMouse: " << glutGetWindow() << ' ' << button << ' ' << state << ' ' << x << ' ' << y << ' ' <<
153  // " graphicsvars: " << click << ' ' << clicked_button << ' ' << click_x << ' ' << click_y << std::endl;
154 
155  specialKey = glutGetModifiers();
156 
157  click_x = x;
158  click_y = y;
159  if (state == GLUT_DOWN) {
160  clicked_button = button;
161  if (!click) {
162  click = true;
163  // std::cout << "click button: " << button << std::endl;
164  }
165  }
166  if (state == GLUT_UP) {
167  clicked_button = -1;
168  click = false;
169  }
170 }
171 
172 
173 // rhiju
174 // Jack/Phil's rotate with mouse routine. Now with more
175 // intuitive rotating.
176 void processMouseActiveMotion(int x, int y) {
177  using namespace graphics;
178 
179  //std::cout << "processMouseActiveMotion: " << glutGetWindow() << ' ' << x << ' ' << y << ' ' <<
180  // " graphicsvars: " << click << ' ' << clicked_button << ' ' << click_x << ' ' << click_y << std::endl;
181 
182  static int old_x;
183  static int old_y;
184  if (click) {
185  old_x = click_x;
186  old_y = click_y;
187  click = false;
188  }
189 
190  float delta_x = old_x - x;
191  float delta_y = old_y - y;
192 
193 
194  if (specialKey == GLUT_ACTIVE_SHIFT & clicked_button == 0) { // Zoom in/out
195  double s = exp( -1.0* (double) delta_y*0.01);
196  glScalef(s,s,s);
197  }
198  else if (specialKey == GLUT_ACTIVE_CTRL & clicked_button == 0) { // Recontour
199  GraphicsState* current_gs = gs_map_[ glutGetWindow() ];
200  if (!current_gs) {
201  std::cerr << "ignoring processKeyPress for window id " << glutGetWindow() << std::endl;
202  return;
203  }
204  current_gs->density_sigma += delta_y*0.02;
205  current_gs->density_redraw = true;
206  }
207  else if (specialKey == GLUT_ACTIVE_SHIFT & clicked_button > 0){ //Rotate around z-axis
208  // See below for explanation of premultiplication.
209  GLfloat currentrotation[16];
210  glGetFloatv(GL_MODELVIEW_MATRIX, currentrotation);
211  glLoadIdentity();
212  glRotatef(delta_x,0,0,1);
213  glMultMatrixf(currentrotation);
214  }
215  else if (clicked_button > 0){ //Pan
216  GLint viewport[4];
217  glGetIntegerv(GL_VIEWPORT,viewport);
218  //glTranslatef( -1.0*delta_x * (_right-_left)/(viewport[2]),
219  // -1.0*delta_y * (_bottom-_top)/(viewport[3]), 0);
220  //Scale factors map from screen coordinates to molecule coordinates.
221  glMatrixMode(GL_MODELVIEW);
222  double xscale = (graphics::window_size * 2.0)/(viewport[2]);
223  double yscale = (graphics::window_size * 2.0)/(viewport[3]);
224 
225  GLfloat currentrotation[16];
226  glGetFloatv(GL_MODELVIEW_MATRIX, currentrotation);
227  glLoadIdentity();
228  glTranslatef( -delta_x * xscale, delta_y * yscale, 0);
229  glMultMatrixf(currentrotation);
230  }
231  else { //Rotate the sucker.
232  //double axis_z = 0;
233  double axis_x = -delta_y;
234  double axis_y = -delta_x;
235  double userangle = sqrt(delta_x*delta_x + delta_y*delta_y);
236 
237  glMatrixMode(GL_MODELVIEW);
238  // Standard GLUT rotation is a postmultiplication - rotation around
239  // molecule's inertial frame -- and leads to
240  // non-intuitive behavior.
241  //glRotatef(userangle,axis_x,axis_y,0.0);
242 
243  //A premultiplication -- rotates around the axis the user actually sees.
244  // A little more complicated to code; unfortunately GLUT doesn't have a one-line
245  // function for it.
246  GLfloat currentrotation[16];
247  glGetFloatv(GL_MODELVIEW_MATRIX, currentrotation);
248  glLoadIdentity();
249  glRotatef(userangle,axis_x,axis_y,0.0);
250  glMultMatrixf(currentrotation);
251  }
252 
253  glutPostRedisplay();
254 
255  old_x = x;
256  old_y = y;
257 }
258 
259 
260 
261 void processKeyPress(unsigned char key, int /* x */, int /* y */) {
262  using namespace graphics;
263  using namespace protocols::viewer;
264 
265  GraphicsState* current_gs = gs_map_[ glutGetWindow() ];
266  if (!current_gs) {
267  std::cerr << "ignoring processKeyPress for window id " << glutGetWindow() << std::endl;
268  return;
269  }
270 
271  if (key == 67 || key == 99) { //'c' control color
272  current_gs->Color_mode = ColorMode ( current_gs->Color_mode + 1 );
273  if ( current_gs->Color_mode > RESIDUE_CPK_COLOR ) current_gs->Color_mode = RAINBOW_COLOR;
274  }
275  if (key == 66 || key == 98) { //'b' control backbone display
276  current_gs->BBdisplay_state = BBdisplayState ( current_gs->BBdisplay_state + 1 );
277  if ( current_gs->BBdisplay_state > SHOW_BACKBONE ) current_gs->BBdisplay_state = SHOW_NOBB;
278  }
279  if (key == 72 || key == 104) { //'H' or 'h': toggle hydrogens
280  current_gs->show_H_state = ShowHState ( current_gs->show_H_state + 1 );
281  if ( current_gs->show_H_state > SHOW_H ) current_gs->show_H_state = SHOW_NO_H;
282  }
283  if (key == 83 || key == 115) { //'s' control sidechain display
284  current_gs->SCdisplay_state = SCdisplayState ( current_gs->SCdisplay_state + 1 );
285  if ( current_gs->SCdisplay_state > SHOW_WIREFRAME ) current_gs->SCdisplay_state = SHOW_NOSC;
286  }
287 
288  glutPostRedisplay();
289 }
290 /**/
291 
292 
293 /////////////////////////////////////////////////////////////////////////
294 // GRAPHICS THREAD
295 //
296 // this is the displayFunc for the windows of ConformationViewer objects
297 void
298 conformation_viewer_display( void )
299 {
300  // which viewer?
301  int const window( glutGetWindow() );
302 
303  //std::cout << "conformation_viewer_display: " << window << std::endl;
304 
305  if ( conformation_viewers.count( window ) ) {
306  conformation_viewers.find( window )->second->display_func();
307  glutSwapBuffers();
308  //glFlush();
309  }
310 
311 }
312 
313 /////////////////////////////////////////////////////////////////////////
314 //
315 // GRAPHICS THREAD
316 void
317 idle_func( void )
318 {
319 
320  check_for_new_conformation_viewers();
321 
322  // pthread_mutex_lock( &conformation_viewers_mut );
323 
324  for ( ConformationViewers::const_iterator iter = conformation_viewers.begin(), iter_end = conformation_viewers.end();
325  iter != iter_end; ++iter ) {
326  iter->second->display_if_necessary();
327  }
328 
329  // pthread_mutex_unlock( &conformation_viewers_mut );
330 
331 }
332 
333 
334 
335 /////////////////////////////////////////////////////////////////////////
336 // GRAPHICS THREAD
337 //
338 
339 int
340 conformation_viewer_window_init( GraphicsState& gs, std::string const & window_name, int length, int width )
341 {
342  using namespace graphics;
343 
344  glutInitWindowSize (length, width);
345  glutInitWindowPosition (370, 10);
346 
347  int const window = glutCreateWindow ( window_name.c_str() );
348 
349  // register gs object in gs map
350  gs.BBdisplay_state = SHOW_BACKBONE;
351  gs.SCdisplay_state = SHOW_WIREFRAME;
352  gs.Color_mode = RAINBOW_COLOR;
353  gs.Trajectory_state = SHOW_ALL_TRIALS;
354  gs.show_H_state = SHOW_NO_H;
355 
356  graphics::gs_map_[window] = &gs;
357 
358  glutDisplayFunc( conformation_viewer_display );
359 
360  glClearColor( bg_color.x(), bg_color.y(), bg_color.z(), 1.0 );
361  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
362 
363  glMatrixMode(GL_PROJECTION);
364  glLoadIdentity();
365  using graphics::window_size;
366  glOrtho( -window_size, window_size, -window_size, window_size, -10*window_size, 10*window_size );
367  glEnable( GL_DEPTH_TEST );
368  glMatrixMode(GL_MODELVIEW);
369 
370  glEnable(GL_LINE_SMOOTH);
371  glEnable(GL_POINT_SMOOTH);
372  glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
373 
374  glEnable(GL_BLEND);
375  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
376  glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
377 
378  glutMouseFunc( processMouse );
379  //glutMouseWheelFunc( processMouseWheel );
380  glutMotionFunc( processMouseActiveMotion );
381  glutKeyboardFunc( processKeyPress );
382  //glutSpecialFunc(specialKeyPressFunc);
383 
384  runtime_assert( glutGetWindow() == window );
385  return window;
386 
387 } // conformation_viewer_window_init( ... )
388 
389 
390 int
391 conformation_viewer_window_init( GraphicsState& gs, std::string const & window_name )
392 {
393 
394  using namespace graphics;
395  glutInitWindowSize (900, 900);
396  int window = conformation_viewer_window_init( gs, window_name, 900, 900 );
397  return window;
398 }
399 
400 /////////////////////////////////////////////////////////////////////////
401 // GRAPHICS THREAD
402 //
403 void
404 check_for_new_conformation_viewers()
405 {
406  pthread_mutex_lock( &new_conformation_viewers_mut );
407  if ( !new_conformation_viewers.empty() ) {
408  for ( Size i=1; i<= new_conformation_viewers.size(); ++i ) {
409  ConformationViewerOP viewer( new_conformation_viewers[i] );
410  // create the new window
411 
412  int width = viewer->get_width();
413  int length = viewer->get_length();
414 
415  int const new_window( conformation_viewer_window_init( viewer->get_gs(), viewer->name(), length, width ) );
416  viewer->window( new_window );
417  conformation_viewers[ new_window ] = viewer;
418  }
419  new_conformation_viewers.clear();
420  }
421  pthread_mutex_unlock( &new_conformation_viewers_mut );
422 }
423 
424 
425 /////////////////////////////////////////////////////////////////////////
426 //
427 // WORKER THREAD (conformation owner)
428 
429 void
431  conformation::Conformation & conformation,
432  std::string const name_in, // = ""
433  int length,
434  int width,
435  bool debug_pause
436 )
437 {
438 
439  pthread_mutex_lock( &new_conformation_viewers_mut );
440 
441  // create a new viewer
442  std::string const window_name
443  ( name_in.empty() ? "conformation"+ObjexxFCL::string_of( conformation_viewers.size() + new_conformation_viewers.size() ) :
444  name_in );
445 
446  ConformationViewerOP viewer( new ConformationViewer( window_name, length, width, debug_pause ) );
447 
448  viewer->attach_to( conformation );
449 
450  new_conformation_viewers.push_back( viewer );
451 
452  pthread_mutex_unlock( &new_conformation_viewers_mut );
453 
454  // allow main to start if this is the 1st window
455  pthread_cond_broadcast( &start_cond );
456 
457 }
458 
459 
460 /////////////////////////////////////////////////////////////////////////
461 //
462 // WORKER THREAD (conformation owner)
463 //
464 void
466  moves::MonteCarlo & mc,
467  std::string const name_in, //= ""
468  int const length,
469  int const width,
470  bool debug_pause
471 )
472 {
473 
474  pthread_mutex_lock( &new_conformation_viewers_mut );
475 
476  // create a new viewer
477  std::string const tag
478  ( name_in.empty() ?
479  "MC"+ObjexxFCL::string_of( conformation_viewers.size() + new_conformation_viewers.size() ) :
480  name_in );
481 
483  viewer1( new ConformationViewer(tag+"_last_accepted", length, width, debug_pause) ),
484  viewer2( new ConformationViewer(tag+"_best_accepted", length, width, debug_pause) );
485 
486  std::cerr << "attaching viewers!!!!" << std::endl;
487  mc.attach_observer_to_last_accepted_conformation( *viewer1 );
488  mc.attach_observer_to_lowest_score_conformation ( *viewer2 );
489 
490  new_conformation_viewers.push_back( viewer1 );
491  new_conformation_viewers.push_back( viewer2 );
492 
493  pthread_mutex_unlock( &new_conformation_viewers_mut );
494 
495  // allow main to start if this is the 1st window
496  pthread_cond_broadcast( &start_cond );
497 }
498 
499 
500 ///
501 void
502 silly_window_display()
503 {
504 
505  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
506  glutWireTeapot(0.5);
507 
508  glFlush();
509  glutSwapBuffers();
510  glFlush();
511 
512 }
513 
514 
515 /// testing/hacking
516 void
517 silly_window_init() {
518 
519 
520  glutInitWindowSize (500, 500);
521  glutInitWindowPosition (100, 100);
522 
523  glutCreateWindow ( "silly_window" );
524 
525  glutDisplayFunc( silly_window_display );
526 
527  //glutKeyboardFunc(keyPressFunc);
528 
529  //glutSpecialFunc(specialKeyPressFunc);
530 
531  glClearColor (0.0, 0.0, 0.0, 0.0);
532 }
533 
534 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
535 int
536 viewer_main( VoidFunc worker_main )
537 {
538  // launch rosetta thread (worker)
539  pthread_t p;
540  pthread_create ( &p, NULL, worker_main, NULL );
541 
542  // start glut
543  int argc(1);
544  char * argv[] = {"test"};
545  glutInit( &argc, argv );
546 
547  glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
548 
549  //silly_window_init();
550 
551  // wait for a window to get created::
552  pthread_mutex_lock( &start_mut );
553  if ( new_conformation_viewers.empty() ) {
554  pthread_cond_wait( &start_cond, &start_mut );
555  }
556  pthread_mutex_unlock( &start_mut );
557 
558  check_for_new_conformation_viewers();
559 
560  glutIdleFunc( idle_func );
561 
562  glutMainLoop();
563  return 0;
564 
565 }
566 
567 #endif
568 
569 #if defined GL_GRAPHICS || defined BOINC_GRAPHICS
570 
571 
572 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
573 // helper function
574 void
575 glVertex3fxyz( Vector const & coord )
576 {
577  glVertex3f((float)coord.x(), (float)coord.y(), (float)coord.z() );
578 }
579 
580 void
581 set_bg_color( Vector new_bg_color ) {
582  runtime_assert( new_bg_color.x() >= 0 );
583  runtime_assert( new_bg_color.y() >= 0 );
584  runtime_assert( new_bg_color.z() >= 0 );
585  graphics::bg_color = new_bg_color;
586 }
587 
588 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
589 // helper function
590 void
591 glColor3fxyz( Vector const & coord )
592 {
593  glColor3f((float)coord.x(), (float)coord.y(), (float)coord.z() );
594 }
595 
596 ///
597 
598 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
599 Vector
600 atom_color_by_element( std::string const element )
601 {
602 
603  if ( element == "N" ) {
604  return Vector(0.0, 0.0, 1.0 ); // blue
605  } else if ( element == "O" ) {
606  return Vector(1.0, 0.0, 0.0 ); // red
607  } else if ( element == "S") {
608  return Vector(1.0, 1.0, 0.0 ); // yellow
609  } else if ( element == "P") {
610  return Vector(1.0, 0.5, 0.0 ); // orange
611  } else if ( element == "H") {
612  return Vector(1.0, 1.0, 1.0 ); // white
613  }
614 
615  return Vector(0.5, 0.5, 0.5 ); // gray (default)
616 
617 }
618 
619 inline float dgaussian( float x, float mean, float sd )
620 {
621  float sqrt_2pi = 2.50662721600161f;
622  float sd_sq = sd * sd;
623  float mean_diff_sq = (x - mean) * (x - mean);
624  return 1 / (sd * sqrt_2pi) * std::exp( -1 * mean_diff_sq / ( 2 * sd_sq ) );
625 }
626 
627 Vector
628 residue_color_by_group( core::conformation::Residue const & res, int total_residue )
629 {
630  float sd = 0.10;
631  float max = 0.8;
632  float min = 0.2;
633  float factor = (float) res.seqpos() / (float) total_residue;
634  // rescale factor according to min and max
635  factor = (max - min) * factor + min;
636 
637  float red = dgaussian( factor, 0.75, sd );
638  float green = dgaussian( factor, 0.50, sd );
639  float blue = dgaussian( factor, 0.25, sd );
640 
641  Vector color( red, green, blue );
642  return color;
643 }
644 
645 // from rosetta++ protein_graphics.cc
646 void rainbow_color( float frac , float & red, float & green, float & blue , bool mute_color ) {
647  float muting = .7;
648  float my_color = frac;
649  red = my_color;
650  blue = 1.0 - my_color ;
651  green = (my_color < .5) ? 2.0*my_color : 2.0-2.0*my_color;
652  if (mute_color) {
653  float saturation = sqrt(red*red + green*green + blue*blue);
654  red = muting*red/saturation;
655  green = muting*green/saturation;
656  blue = muting*blue/saturation;
657  }
658 }
659 // chu enable color by chain
660 void chain_color( int const chain, float & red, float & green, float & blue ) {
661  static int const num_color = 5;
662  int chain_local = chain%num_color;
663  switch ( chain_local ) {
664  case 1: // blue
665  red = 0.0;
666  green = 0.0;
667  blue = 1.0;
668  return;
669  case 2: // green
670  red = 0.0;
671  green = 1.0;
672  blue = 0.0;
673  return;
674  case 3: // yellow
675  red = 0.7;
676  green = 0.7;
677  blue = 0.0;
678  return;
679  case 4: // orange
680  red = 0.7;
681  green = 0.5;
682  blue = 0.0;
683  return;
684  case 0: // red
685  red = 1.0;
686  green = 0.0;
687  blue = 0.0;
688  return;
689  default:
690  red = 0.0;
691  green = 0.0;
692  blue = 1.0;
693  return;
694  }
695 }
696 
697 // from rosetta++ protein_graphics.cc
698 void get_residue_color( float i, float & red, float & green, float & blue, bool mute_color, int total_residue ) {
699  float i_local = i;
700  if (i > total_residue) i_local = total_residue;
701  rainbow_color ( float(i_local) / float(total_residue), red, green, blue, mute_color);
702 }
703 
704 // from rosetta++ protein_graphics.cc
705 std::map<std::string, Vector> get_sidechain_color_rhiju() {
706 
707  std::map<std::string, Vector> sidechain_color_rhiju;
708 
709  sidechain_color_rhiju[ "ALA" ] = Vector( 0.3, 0.3, 0.3); //gray
710  sidechain_color_rhiju[ "CYS" ] = Vector( 0.7, 0.7, 0.0); //yellow:
711  sidechain_color_rhiju[ "ASP" ] = Vector( 0.7, 0.0, 0.0); //red
712  sidechain_color_rhiju[ "GLU" ] = Vector( 0.7, 0.0, 0.0); //red
713  sidechain_color_rhiju[ "PHE" ] = Vector( 0.3, 0.3, 0.3);
714  sidechain_color_rhiju[ "GLY" ] = Vector( 0.7, 0.5, 0.0); //orange; this shouldn't happen from sidechain.
715  sidechain_color_rhiju[ "HIS" ] = Vector( 0.0, 0.0, 0.7); //blue
716  sidechain_color_rhiju[ "ILE" ] = Vector( 0.3, 0.3, 0.3);
717  sidechain_color_rhiju[ "LYS" ] = Vector( 0.0, 0.0, 0.7); //blue
718  sidechain_color_rhiju[ "LEU" ] = Vector( 0.3, 0.3, 0.3);
719  sidechain_color_rhiju[ "MET" ] = Vector( 0.3, 0.3, 0.3);
720  sidechain_color_rhiju[ "ASN" ] = Vector( 0.0, 0.5, 0.0); //green
721  sidechain_color_rhiju[ "PRO" ] = Vector( 0.3, 0.3, 0.3);
722  sidechain_color_rhiju[ "GLN" ] = Vector( 0.0, 0.5, 0.0); //green
723  sidechain_color_rhiju[ "ARG" ] = Vector( 0.0, 0.0, 0.7); //blue
724  sidechain_color_rhiju[ "SER" ] = Vector( 0.0, 0.5, 0.0); //green
725  sidechain_color_rhiju[ "THR" ] = Vector( 0.0, 0.5, 0.0); //green
726  sidechain_color_rhiju[ "VAL" ] = Vector( 0.3, 0.3, 0.3);
727  sidechain_color_rhiju[ "TRP" ] = Vector( 0.3, 0.3, 0.3);
728  sidechain_color_rhiju[ "TYR" ] = Vector( 0.0, 0.5, 0.0); //green
729  sidechain_color_rhiju[ "SEP" ] = Vector( 0.5, 0.5, 0.0); //orange
730  sidechain_color_rhiju[ "GUA" ] = Vector( 0.0, 0.0, 0.5); //blue
731  sidechain_color_rhiju[ "ADE" ] = Vector( 0.5, 0.5, 0.0); //yellow
732  sidechain_color_rhiju[ "CYT" ] = Vector( 0.0, 0.5, 0.0); //green
733  sidechain_color_rhiju[ "THY" ] = Vector( 0.5, 0.0, 0.0); //red
734  sidechain_color_rhiju[ "RGU" ] = Vector( 0.0, 0.0, 0.5); //blue
735  sidechain_color_rhiju[ "RAD" ] = Vector( 0.5, 0.5, 0.0); //yellow
736  sidechain_color_rhiju[ "RCY" ] = Vector( 0.0, 0.5, 0.0); //green
737  sidechain_color_rhiju[ "URA" ] = Vector( 0.5, 0.0, 0.0); //red
738  sidechain_color_rhiju[ " rG" ] = Vector( 0.0, 0.0, 0.5); //blue
739  sidechain_color_rhiju[ " rA" ] = Vector( 0.5, 0.5, 0.0); //yellow
740  sidechain_color_rhiju[ " rC" ] = Vector( 0.0, 0.5, 0.0); //green
741  sidechain_color_rhiju[ " rU" ] = Vector( 0.5, 0.0, 0.0); //red
742 
743  return sidechain_color_rhiju;
744 }
745 
746 ////////////////////////////////////////////////////////////////////
747 Vector get_atom_color(
748  GraphicsState & gs,
750  int const & r,
751  int const & i ) {
752 
753  float red,green,blue;
754  static std::map<std::string, Vector> sidechain_color_rhiju = get_sidechain_color_rhiju();
755 
756  switch ( gs.Color_mode ) {
757 
758  case CPK_COLOR:
759  return atom_color_by_element( residues[r]->atom_type(i).element());
760 
761  case RAINBOW_COLOR:
762  rainbow_color( float(r)/ float(residues.size()), red, green, blue, true /*mute_color*/);
763  return Vector(red, green, blue);
764 
765  case RESIDUE_COLOR:
766  if (sidechain_color_rhiju.find(residues[r]->name3()) != sidechain_color_rhiju.end() )
767  return sidechain_color_rhiju[residues[r]->name3()];
768  return Vector( 1.0, 0.5, 0.0); //orange
769 
770  case CHAIN_COLOR:
771  chain_color( residues[r]->chain(), red, green, blue );
772  return Vector(red, green, blue);
773 
774  case RAINBOW_CPK_COLOR:
775  if ( !residues[r]->atom_is_backbone(i) ) { //non carbon atoms
776  return atom_color_by_element( residues[r]->atom_type(i).element());
777  }
778  rainbow_color( float(r)/ float(residues.size()), red, green, blue, true /*mute_color*/);
779  return Vector(red, green, blue);
780 
781  case RESIDUE_CPK_COLOR:
782  if ( !residues[r]->atom_is_backbone(i) ) { //non carbon atoms
783  return atom_color_by_element( residues[r]->atom_type(i).element());
784  }
785  if (sidechain_color_rhiju.find(residues[r]->name3()) != sidechain_color_rhiju.end() )
786  return sidechain_color_rhiju[residues[r]->name3()];
787  return Vector( 1.0, 1.0, 1.0);
788 
789  case RHIJU_COLOR:
790  if ( residues[r]->is_virtual(i) ){
791  return Vector( 1.0, 1.0, 1.0 );
792  } else if ( residues[r]->atom_is_backbone(i) ) {
793  rainbow_color( float(r)/ float(residues.size()), red, green, blue, false /*mute_color*/);
794  return Vector(red, green, blue);
795  } else if ( sidechain_color_rhiju.find(residues[r]->name3()) != sidechain_color_rhiju.end() ) {
796  return sidechain_color_rhiju[ residues[r]->name3() ];
797  }
798  }
799  return Vector( 1.0, 1.0, 1.0);
800 }
801 
802 
803 ////////////////////////////////////////////////////////////////////////////////////////////////
804 void
805 display_residues_wireframe(
806  GraphicsState & gs,
808  Vector const & center )
809 {
810  using namespace conformation;
811  using namespace chemical;
812 
813  // could get these from some runtime-configurable options set
814  //Real const bond_width( 0.1 );
815 
816  // In case the view has been rotated... set z to be the axis pointing out of the screen
817  glMatrixMode(GL_MODELVIEW);
818  GLfloat currentrotation[16];
819  glGetFloatv(GL_MODELVIEW_MATRIX, currentrotation);
820  Vector const z( currentrotation[2], currentrotation[6], currentrotation[10] );
821 
822  Size const nres( residues.size() );
823 
824  for ( Size i=1; i<= nres; ++i ) {
825  conformation::Residue const & rsd( *(residues[i] ) );
826  Size const natoms( rsd.natoms() );
827 
828  // draw connection to previous residue
829  if ( i>1 && !rsd.is_lower_terminus() && rsd.is_polymer() ) {
830 
831  Residue const & prev_rsd( *(residues[i-1]));
832  int const atom1( prev_rsd.mainchain_atoms()[ prev_rsd.n_mainchain_atoms() ] );
833  int const atom2( rsd.mainchain_atoms()[ 1 ] );
834 
835  Vector const color1( get_atom_color( gs, residues, i-1, atom1 ) );
836  Vector const color2( get_atom_color( gs, residues, i , atom2 ) );
837 
838  Vector const xyz1( prev_rsd.xyz( atom1 ) - center );
839  Vector const xyz2( rsd.xyz( atom2 ) - center );
840 
841  Vector const bond( xyz2 - xyz1 );
842  if (bond.length_squared() <= graphics::BOND_LENGTH_CUTOFF2 ) {
843 
844  Vector width( cross( bond, z ) );
845  if ( width.length_squared() ) width.normalize();
846  width *= graphics::protein_wireframeScale;
847 
848  // also need to draw the elbow?
849  // if (bond.length_squared() < 9.0 ){
850  glColor3fxyz( color1 );
851  glBegin(GL_POLYGON);
852  glVertex3fxyz ( xyz1 + width );
853  glVertex3fxyz ( xyz1 - width );
854  glColor3fxyz( color2 );
855  glVertex3fxyz ( xyz2 - width );
856  glVertex3fxyz ( xyz2 + width );
857  glEnd();
858  }
859  }
860 
861  // draw the atom bonds
862  utility::vector1< Vector > prev1( natoms ), prev2( natoms );
863  utility::vector1< bool > prev_set( natoms, false );
864 
865  for ( Size m=1; m<= natoms; ++m ) {
866 
867  AtomIndices const & nbrs( rsd.bonded_neighbor(m) );
868 
869  for ( Size jj=1; jj<= nbrs.size(); ++jj ) {
870  Size const n( nbrs[jj] );
871  if ( n < m ) continue;
872  //if ( rsd.atom_type(m).is_hydrogen() && graphics::exclude_hydrogens ) continue;
873 
874  Vector const color1( get_atom_color( gs, residues, i, m ) );
875  Vector const color2( get_atom_color( gs, residues, i, n ) );
876 
877  Vector const xyz1( rsd.xyz(m) - center );
878  Vector const xyz2( rsd.xyz(n) - center );
879 
880  Vector const bond( xyz2 - xyz1 );
881 
882  // check for chainbreaks
883  //if (bond.length_squared() > graphics::BOND_LENGTH_CUTOFF2 ) break;
884 
885  Vector width( cross( bond, z ) );
886  if ( width.length_squared() ) width.normalize();
887  width *= graphics::protein_wireframeScale;
888 
889  if ( rsd.atom_type(m).is_hydrogen() || rsd.atom_type(n).is_hydrogen() || rsd.is_virtual(m) || rsd.is_virtual(n) ) width *= 0.5;
890 
891  glColor3fxyz( color1 );
892 
893  if ( prev_set[ m ] ) {
894  // draw the elbow
895  glBegin(GL_POLYGON);
896  glVertex3fxyz ( prev1[m] );
897  glVertex3fxyz ( xyz1 + width );
898  glVertex3fxyz ( xyz1 - width );
899  glVertex3fxyz ( prev2[m] );
900  glEnd();
901  } else {
902  prev_set[m] = true;
903  prev1[m] = xyz1 - width;
904  prev2[m] = xyz1 + width;
905  }
906 
907  glBegin(GL_POLYGON);
908  glVertex3fxyz ( xyz1 + width );
909  glVertex3fxyz ( xyz1 - width );
910  glColor3fxyz( color2 ); // change color
911  glVertex3fxyz ( xyz2 - width );
912  glVertex3fxyz ( xyz2 + width );
913  glEnd();
914 
915  if ( !prev_set[n] ) {
916  // for drawing the elbow at atomn
917  prev_set[n] = true;
918  prev1[n] = xyz2 + width;
919  prev2[n] = xyz2 - width;
920  } else {
921  // draw the elbow
922  glBegin(GL_POLYGON);
923  glVertex3fxyz ( prev1[n] );
924  glVertex3fxyz ( xyz2 - width );
925  glVertex3fxyz ( xyz2 + width );
926  glVertex3fxyz ( prev2[n] );
927  glEnd();
928  }
929  } // jj
930  } // i
931  } // nres
932 } // void display_residues_wireframe
933 
934 
935 
936 ////////////////////////////////////////////////////////////////////////////////////////////////
937 // Secondary structure display methods from Rhiju's code in rosetta++
938 // protein_graphics.cc
939 
940 
941 // placeholder function
942 //bool check_occupancy( int, const core::pose::Pose & ) { return true; }
943 
944 void get_direction( Vector & direction, const int & next_res, const int & prior_res,
946  direction = residues[ next_res ]->xyz( "CA" ) - residues[ prior_res ]->xyz( "CA" );
947  if (direction.length_squared() > 0.00001) direction.normalize();
948 }
949 
950 
951 void get_normal( Vector & normal, const int n, utility::vector1< core::conformation::ResidueCOP > const & residues ) {
952  normal = cross( (residues[ n ]->xyz( "CA" )-residues[ n-1 ]->xyz( "CA" )),
953  (residues[ n+1 ]->xyz( "CA" )-residues[ n ]->xyz( "CA" )) );
954  if (normal.length_squared() > 0.00001) normal.normalize();
955 }
956 
957 
958 void get_axis_and_tangent( Vector & axis, Vector & tangent,
959  const Vector & direction, const Vector & normal) {
960  //Magic linear combinations from Per Kraulis' molscript.
961  const core::Real HELIX_ALPHA = 0.5585;
962  axis = std::cos(HELIX_ALPHA) * normal + std::sin(HELIX_ALPHA) * direction;
963  const core::Real HELIX_BETA = -0.1920;
964  tangent = std::cos(HELIX_BETA) * direction + std::sin(HELIX_BETA) * normal;
965 }
966 
967 
968 Vector get_CA_segment( const Vector & prev_CA, const Vector & current_CA,
969  const Vector & prev_tangent, const Vector & tangent,
970  const float & p, const float & hermite_factor) {
971  //Hermitean interpolation.
972  const core::Real p2 = p*p;
973  const core::Real p3 = p*p*p;
974  const core::Real h1 = 2*p3 - 3*p2 + 1;
975  const core::Real h2 =-2*p3 + 3*p2;
976  const core::Real h3 = p3 - 2*p2 + p;
977  const core::Real h4 = p3 - p2;
978  return (h1*prev_CA + h2*current_CA + h3*hermite_factor*prev_tangent + h4*hermite_factor*tangent);
979 }
980 
981 
982 float get_half_width( const std::string & taper, const float & secstruct_half_width, const float & p ) {
983  const Real PI = numeric::NumericTraits<Real>::pi();
984 
985  core::Real half_width = secstruct_half_width;
986  if (taper == "start"){
987  half_width = graphics::COILRADIUS + (secstruct_half_width - graphics::COILRADIUS)*
988  0.5 * ( - cos( PI * p ) + 1.0 );
989  }
990  if (taper == "end"){
991  half_width = graphics::COILRADIUS + (secstruct_half_width - graphics::COILRADIUS)*
992  0.5 * ( cos( PI * p ) + 1.0 );
993  }
994  if (taper == "strand_ultimate"){
995  half_width = graphics::COILRADIUS + (2*secstruct_half_width - graphics::COILRADIUS) * (1 - p);
996  }
997  return half_width;
998 }
999 
1000 
1001 void set_initial_polygon_vertices(const Vector & vec1, const Vector & vec2, GraphicsState & gs) {
1002  gs.previous_vertex1 = vec1;
1003  gs.previous_vertex2 = vec2;
1004  gs.previous_width_vector = 0.0;
1005 }
1006 
1007 
1008 void draw_next_polygon( const Vector & vec1, const Vector & vec2,
1009  const float & red, const float & green, const float & blue, const int & aa,
1010  GraphicsState & gs,
1011  bool is_coil = false,
1012  bool darken_inside = false) {
1013  if (aa<1) return;
1014 
1015  //Give the cartoon some thickness?
1016  const bool show_thickness = true;
1017  Vector width_vector;
1018 
1019  core::Real showbondcutoff2 = (is_coil) ? graphics::SHOWBONDCUTOFF2_COIL : graphics::SHOWBONDCUTOFF2;
1020 
1021  const core::Real bond_length2 = ((vec1 + vec2)/2.0 - (gs.previous_vertex1 + gs.previous_vertex2)/2.0).length_squared();
1022  if (!show_thickness) {
1023  glColor3f(red,green,blue);
1024  glBegin(GL_POLYGON);
1025  glVertex3fxyz ( gs.previous_vertex1 );
1026  glVertex3fxyz ( gs.previous_vertex2 );
1027  glVertex3fxyz ( vec2 );
1028  glVertex3fxyz ( vec1 );
1029  glVertex3fxyz ( gs.previous_vertex1 );
1030  glEnd();
1031  } else {
1032  width_vector = cross( (vec1 + vec2) - (gs.previous_vertex1 + gs.previous_vertex2),
1033  (vec1 + gs.previous_vertex1) - (vec2 + gs.previous_vertex2) );
1034  if (width_vector.length_squared() > 0.000001) width_vector.normalize();
1035  const float cartoon_width = 0.3;
1036  width_vector *= -1.0f * cartoon_width;
1037 
1038  if (gs.previous_width_vector == 0.0) gs.previous_width_vector = width_vector;
1039 
1040  if (bond_length2 < showbondcutoff2 ) {
1041  //outside
1042  glColor3f(red,green,blue);
1043  glBegin(GL_POLYGON);
1044  glVertex3fxyz ( gs.previous_vertex1 + gs.previous_width_vector );
1045  glVertex3fxyz ( gs.previous_vertex2 + gs.previous_width_vector );
1046  glVertex3fxyz ( vec2 + width_vector );
1047  glVertex3fxyz ( vec1 + width_vector );
1048  glEnd();
1049 
1050  //inside
1051  if (darken_inside) glColor3f(0.5*red,0.5*green,0.5*blue);
1052  glBegin(GL_POLYGON);
1053  glVertex3fxyz ( gs.previous_vertex1 - gs.previous_width_vector );
1054  glVertex3fxyz ( gs.previous_vertex2 - gs.previous_width_vector );
1055  glVertex3fxyz ( vec2 - width_vector );
1056  glVertex3fxyz ( vec1 - width_vector );
1057  glEnd();
1058 
1059  //edges
1060  glColor3f(0.7*red,0.7*green,0.7*blue);
1061  glBegin(GL_POLYGON);
1062  glVertex3fxyz ( gs.previous_vertex1 + gs.previous_width_vector );
1063  glVertex3fxyz ( vec1 + width_vector );
1064  glVertex3fxyz ( vec1 - width_vector );
1065  glVertex3fxyz ( gs.previous_vertex1 - gs.previous_width_vector );
1066  glEnd();
1067  glBegin(GL_POLYGON);
1068  glVertex3fxyz ( gs.previous_vertex2 + gs.previous_width_vector );
1069  glVertex3fxyz ( vec2 + width_vector );
1070  glVertex3fxyz ( vec2 - width_vector );
1071  glVertex3fxyz ( gs.previous_vertex2 - gs.previous_width_vector );
1072  glEnd();
1073  }
1074 
1075  }
1076 
1077  gs.previous_vertex1 = vec1;
1078  gs.previous_vertex2 = vec2;
1079  gs.previous_width_vector = width_vector;
1080 }
1081 
1082 
1083 void draw_secstruct_chunk(
1084  const Vector & prev_CA,
1085  const Vector & current_CA,
1086  const Vector & prev_tangent,
1087  const Vector & tangent,
1088  const Vector & prev_axis,
1089  const Vector & axis,
1090  const int & n,
1091  const char & secstruct_res,
1092  const std::string & taper,
1093  GraphicsState & gs,
1095 {
1096  float hermite_factor;
1097  float red( 0.0 ), green( 0.0 ), blue( 0.0 );
1098  float secstruct_half_width;
1099  bool darken_inside;
1100  if (secstruct_res == 'H'){
1101  secstruct_half_width = graphics::HELIX_HALF_WIDTH;
1102  darken_inside = true;
1103  hermite_factor = graphics::HELIX_HERMITE_FACTOR;
1104  } else if ( secstruct_res == 'E' ){
1105  secstruct_half_width = graphics::STRAND_HALF_WIDTH;
1106  darken_inside = false;
1107  hermite_factor = graphics::STRAND_HERMITE_FACTOR;
1108  } else {
1109  runtime_assert( secstruct_res == 'N' );
1110  secstruct_half_width = graphics::STRAND_HALF_WIDTH;
1111  darken_inside = true;
1112  hermite_factor = graphics::NA_HERMITE_FACTOR;
1113  }
1114  Vector axis_segment, CA_segment;
1115  for (int s = 1; s <= graphics::NUM_SEGMENTS; s++ ){
1116  const core::Real p = s / static_cast<core::Real>(graphics::NUM_SEGMENTS);
1117  axis_segment = p*axis + (1-p)*prev_axis;
1118  CA_segment = get_CA_segment( prev_CA, current_CA, prev_tangent, tangent, p, hermite_factor);
1119  if (gs.Color_mode == CHAIN_COLOR ) {
1120  chain_color( residues[n]->chain(), red, green, blue );
1121  } else {
1122  get_residue_color( static_cast<float>(n - 1) + p, red, green, blue, false, residues.size());
1123  }
1124  const core::Real half_width = get_half_width( taper, secstruct_half_width, p );
1125  draw_next_polygon(CA_segment - half_width*axis_segment, CA_segment + half_width*axis_segment,
1126  red,green,blue, n, gs, false, darken_inside);
1127  }
1128 }
1129 
1130 
1131 void draw_helix(
1132  const int & start,
1133  const int & end,
1134  GraphicsState & gs,
1136 {
1137 
1138  const int total_residue = residues.size();
1139 
1140  //Starting point.
1141  int prior_res( start-1 );
1142  if (prior_res < 1) prior_res = 1;
1143  Vector direction, normal, tangent, axis, current_CA;
1144  Vector prev_CA, prev_tangent, prev_axis;
1145 
1146  //For the starting point, need to figure out axis from next residue...
1147  int next_res = start + 1;
1148  if (next_res > total_residue-1) next_res = total_residue-1;
1149  get_direction( direction, next_res+1, next_res-1, residues);
1150  get_normal( normal, next_res, residues );
1151  get_axis_and_tangent( axis, tangent, direction, normal );
1152 
1153  get_direction(direction, start+1, prior_res, residues);
1154  tangent = direction;
1155  current_CA = residues[ start ]->xyz( "CA" );
1156  if (start==1)
1157  set_initial_polygon_vertices( current_CA - graphics::HELIX_HALF_WIDTH*axis,
1158  current_CA + graphics::HELIX_HALF_WIDTH*axis, gs);
1159 
1160  //previous residue's helix geometry
1161  prev_CA = current_CA;
1162  prev_tangent = tangent;
1163  prev_axis = axis;
1164  std::string taper = "start";
1165 
1166  // Draw the body of the helix.
1167  for (int n = start+1; n<=end-1; n++){
1168  //new residue's helix geometry
1169  get_direction( direction, n+1, n-1, residues );
1170  get_normal( normal, n, residues );
1171  get_axis_and_tangent( axis, tangent, direction, normal);
1172  current_CA = residues[ n ]->xyz( "CA" );
1173  draw_secstruct_chunk( prev_CA, current_CA, prev_tangent, tangent, prev_axis, axis, n,
1174  'H', taper, gs, residues);
1175 
1176  //previous residue's helix geometry
1177  prev_CA = current_CA;
1178  prev_tangent = tangent;
1179  prev_axis = axis;
1180  taper = "none";
1181  }
1182 
1183  //last piece.
1184  // next_res = end + 1;
1185  // if (next_res > nres) next_res = nres;
1186  // get_direction( direction, next_res, end - 1, xyz_full);
1187  get_direction( direction, end, end - 1, residues);
1188  tangent = direction;
1189  current_CA = residues[ end ]->xyz( "CA" );
1190  taper = "end";
1191  draw_secstruct_chunk( prev_CA, current_CA, prev_tangent, tangent, prev_axis, axis, end,
1192  'H', taper, gs, residues);
1193 }
1194 
1195 
1196 void draw_strand(
1197  const int & start,
1198  const int & end,
1199  GraphicsState & gs,
1201 
1202  const int total_residue = residues.size();
1203 
1204  //Pre-smooth? priestle_smooth
1205  //core::pose::Pose smooth_pose( pose );
1206 
1207  //Starting point.
1208  int prior_res( start-1 );
1209  if (prior_res < 1) prior_res = 1;
1210  Vector direction, normal, tangent, axis, current_CA, prev_CA, prev_direction, prev_normal;
1211 
1212  //For the starting point, need to figure out axis from next residue...
1213  int next_res = start + 1;
1214  if (next_res > total_residue-1) next_res = total_residue-1;
1215  get_direction( direction, next_res+1, next_res-1, residues);
1216  get_normal( normal, next_res, residues );
1217 
1218  current_CA = residues[ start ]->xyz( "CA" );
1219  if (start==1)
1220  set_initial_polygon_vertices( current_CA - graphics::STRAND_HALF_WIDTH*normal,
1221  current_CA + graphics::STRAND_HALF_WIDTH*normal, gs);
1222 
1223  //previous residue's strand geometry
1224  prev_CA = current_CA;
1225  prev_normal = normal;
1226  prev_direction = direction;
1227  std::string taper = "start";
1228 
1229  // Draw the body of the strand.
1230  for (int n = start+1; n<=end-1; n++){
1231  //new residue's strand geometry
1232  get_direction( direction, n+1, n-1, residues);
1233  get_normal( normal, n, residues );
1234  if ( dot(normal, prev_normal) < 0.0 ) normal *= -1.0;
1235  current_CA = residues[ n ]->xyz( "CA" );
1236  draw_secstruct_chunk( prev_CA, current_CA, prev_direction, direction, prev_normal, normal, n,
1237  'E', taper, gs, residues);
1238 
1239  //previous residue's strand geometry
1240  prev_CA = current_CA;
1241  prev_normal = normal;
1242  prev_direction = direction;
1243  taper = "none";
1244  }
1245 
1246  //last piece.
1247  next_res = end + 1;
1248  if (next_res > total_residue) next_res = total_residue;
1249  get_direction( direction, next_res, end - 1, residues);
1250  tangent = direction;
1251  current_CA = residues[ end ]->xyz( "CA" );
1252  taper = "strand_ultimate";
1253  draw_secstruct_chunk( prev_CA, current_CA, prev_direction, direction, prev_normal, normal, end,
1254  'E', taper, gs, residues);
1255 }
1256 
1257 
1258 void draw_coil_chunk(
1259  const Vector & prev_CA,
1260  const Vector & current_CA,
1261  const Vector & prev_tangent,
1262  const Vector & tangent,
1263  const int & n,
1264  GraphicsState & gs,
1266  float red( 0.0 ), green( 0.0 ), blue( 0.0 );
1267 
1268  Vector axis_segment, CA_segment, prev_CA_segment, bond, prev_bond;
1269 
1270  GLfloat currentrotation[16];
1271  glGetFloatv(GL_MODELVIEW_MATRIX, currentrotation);
1272  Vector z(currentrotation[2],currentrotation[6],currentrotation[10]); // z pointing out of window in current view.
1273 
1274  prev_CA_segment = prev_CA;
1275  prev_bond = current_CA - prev_CA;
1276  for (int s = 1; s <= graphics::NUM_SEGMENTS_COIL; s++ ){
1277  const float p = s / static_cast<float>(graphics::NUM_SEGMENTS_COIL);
1278  CA_segment = get_CA_segment( prev_CA, current_CA, prev_tangent, tangent, p, graphics::COIL_HERMITE_FACTOR);
1279  if (gs.Color_mode == CHAIN_COLOR ) {
1280  chain_color( residues[n]->chain(), red, green, blue );
1281  } else {
1282  get_residue_color ( static_cast<float>(n) + p, red, green, blue, false, residues.size());
1283  }
1284  //Need to replace the following with a real cylinder.
1285  bond = CA_segment - prev_CA_segment;
1286  Vector width = cross( bond, z );
1287  if (width.length_squared() > 0.0001 ) width.normalize();
1288  width = (width - 0.5*z).normalized(); //nice shadow effect
1289  width *= graphics::COILRADIUS;
1290 
1291  draw_next_polygon( CA_segment + width, CA_segment - width, red, green, blue, n, gs, false );
1292 
1293  prev_CA_segment = CA_segment;
1294  prev_bond = bond;
1295  }
1296 }
1297 
1298 
1299 void draw_coil(
1300  const int & start,
1301  const int & end,
1302  GraphicsState & gs,
1304  const int total_residue = residues.size();
1305  // Draw the body of the coil.
1306 
1307  Vector prev_CA, prev_direction, direction, current_CA;
1308  prev_CA = residues[ start ]->xyz( "CA" );
1309  get_direction( prev_direction, start+1, start, residues );
1310  if (start==1)
1311  set_initial_polygon_vertices( prev_CA, prev_CA, gs );
1312  for (int n = start; n <= end-1; n++){
1313  if (n < end-1 && end < total_residue)
1314  get_direction( direction, n+2, n, residues);
1315  else
1316  get_direction( direction, n+1, n, residues);
1317  current_CA = residues[ n+1 ]->xyz( "CA" );
1318  draw_coil_chunk( prev_CA, current_CA, prev_direction, direction, n, gs, residues);
1319  //previous residue's coil geometry
1320  prev_CA = current_CA;
1321  prev_direction = direction;
1322  }
1323 }
1324 
1325 
1326 void draw_segment(
1327  const int & start_segment,
1328  const int & end_segment,
1329  const char & prev_secstruct,
1330  GraphicsState & gs,
1332  const int size_segment = end_segment - start_segment + 1;
1333  if (start_segment >= end_segment) return; //not drawable
1334  if (prev_secstruct=='H' && size_segment >= 4)
1335  draw_helix( start_segment, end_segment, gs, residues );
1336  else if (prev_secstruct=='E' && size_segment >= 2)
1337  draw_strand( start_segment, end_segment, gs, residues );
1338  else
1339  draw_coil( start_segment, end_segment, gs, residues );
1340 }
1341 
1342 
1343 bool check_chainbreak(const int & i, utility::vector1< core::conformation::ResidueCOP > const & residues) {
1344  if (i==1) return false;
1345 
1346  float chainbreak_cutoff2 = graphics::CHAINBREAK_CUTOFF2;
1347  Vector vec = residues[i]->xyz("CA");
1348  Vector vec_prev = residues[i-1]->xyz("CA");
1349  const float dist2 = (vec-vec_prev).length_squared();
1350  if ( dist2 > chainbreak_cutoff2) {
1351  return true;
1352  }
1353  return false;
1354 }
1355 
1356 
1357 
1358 void draw_secstruct(
1359  GraphicsState & gs,
1361  utility::vector1< char > const & ss,
1362  int const begin, int const end)
1363 {
1364 
1365  char prev_secstruct = ss[ begin ];
1366 
1367  int start_segment( begin );
1368  bool is_chainbreak = false;
1369 
1370  int protein_end = 0;
1371  for (int i = begin+1; i<= end; i++) {
1372  if ( ! (residues[i-1]->is_protein() && residues[i]->is_protein()) ) continue;
1373  char current_secstruct = ss[ i ];
1374  protein_end = i;
1375  //if (current_secstruct != prev_secstruct || !check_occupancy(i, pose) || check_chainbreak(i, pose)) {
1376  if (current_secstruct != prev_secstruct || check_chainbreak(i, residues)) {
1377  int const end_segment = i - 1;
1378  draw_segment( start_segment, end_segment, prev_secstruct, gs, residues );
1379  start_segment = i;
1380 
1381  // if (!check_occupancy(i, pose)) {
1382  // start_segment++;
1383  // } else
1384  if ( !check_chainbreak(i, residues)) {
1385  draw_segment( end_segment, end_segment+1, 'L', gs, residues ); // connector region
1386  }
1387  }
1388  prev_secstruct = current_secstruct;
1389  }
1390  //if (check_occupancy(end, pose))
1391  draw_segment( start_segment, protein_end, prev_secstruct, gs, residues );
1392 }
1393 
1394 
1395 
1396 void draw_Calpha_trace(
1397  GraphicsState & gs,
1399  const int & start, const int & end, float xwidth = 0.5)
1400 {
1401 
1402  GLfloat currentrotation[16];
1403  glGetFloatv(GL_MODELVIEW_MATRIX, currentrotation);
1404  Vector z(currentrotation[2],currentrotation[6],currentrotation[10]); // z pointing out of window in current view.
1405  const core::Real z_offset = .1;
1406  const Vector z_halo = z * z_offset;
1407 
1408  Vector prev1( 0.0 ), prev2( 0.0 );
1409  bool last_bonded = false;
1410  for ( int i = start; i<end ; i++ ) {
1411  if ( ! (residues[i]->is_protein() && residues[i+1]->is_protein()) ) continue;
1412  Vector ca_pos1, ca_pos2;
1413  Vector ca_pos1tmp = residues[i]->xyz("CA");
1414  Vector ca_pos2tmp = residues[i+1]->xyz("CA");
1415  ca_pos1 = ca_pos1tmp;
1416  ca_pos2 = ca_pos2tmp;
1417 
1418  Vector bond;
1419  bond = ca_pos2 - ca_pos1;
1420  Vector width( cross( bond, z ));
1421  if ( width.length_squared() > 0.0001 ) width.normalize();
1422  width = width * (core::Real)xwidth;
1423 
1424  float red, green, blue;
1425  if ( gs.Color_mode == CHAIN_COLOR ) {
1426  chain_color( residues[i]->chain(), red, green, blue );
1427  } else {
1428  get_residue_color( i, red, green, blue, false, residues.size() );
1429  }
1430  if ( i > 1 && last_bonded) {
1431  glColor3f(red, green, blue);
1432  glBegin(GL_POLYGON);
1433  glVertex3fxyz ( prev1 );
1434  glVertex3fxyz ( ca_pos1 + width );
1435  glVertex3fxyz ( ca_pos1 - width );
1436  glVertex3fxyz ( prev2 );
1437  glEnd();
1438 
1439  glColor3f(0,0,0);
1440  glBegin(GL_LINES);
1441  glVertex3fxyz ( prev1 );
1442  glVertex3fxyz ( ca_pos1 + width );
1443  glVertex3fxyz ( ca_pos1 - width );
1444  glVertex3fxyz ( prev2 );
1445  glEnd();
1446  }
1447  last_bonded = false;
1448  if (bond.length_squared() < 16) {
1449  last_bonded = true;
1450  glColor3f(red, green, blue);
1451  glBegin(GL_POLYGON);
1452  glVertex3fxyz ( ca_pos1 + width );
1453  glVertex3fxyz ( ca_pos2 + width );
1454  glVertex3fxyz ( ca_pos2 - width );
1455  glVertex3fxyz ( ca_pos1 - width );
1456  glEnd();
1457 
1458  glColor3f(0,0,0);
1459  glBegin(GL_LINES);
1460  glVertex3fxyz ( z_halo + ca_pos1 + width );
1461  glVertex3fxyz ( z_halo + ca_pos2 + width );
1462  glVertex3fxyz ( z_halo + ca_pos2 - width );
1463  glVertex3fxyz ( z_halo + ca_pos1 - width );
1464  glEnd();
1465  }
1466  prev1 = ca_pos2 + width;
1467  prev2 = ca_pos2 - width;
1468  }
1469 
1470 }
1471 
1472 
1473 
1474 void
1475 draw_sidechains( GraphicsState & gs, utility::vector1< core::conformation::ResidueCOP > const & residues, const int & start, const int & end ) {
1476 
1477  if (gs.SCdisplay_state == SHOW_NOSC) return;
1478 
1479  GLfloat currentrotation[16];
1480  glGetFloatv(GL_MODELVIEW_MATRIX, currentrotation);
1481  Vector z(currentrotation[2],currentrotation[6],currentrotation[10]); // z pointing out of window in current view.
1482 
1483  float xwidth = graphics::protein_stickScale;
1484  for ( int r = start; r<=end ; ++r ) {
1485 
1486  if (residues[r]->is_ligand() && gs.SCdisplay_state != SHOW_STICK
1487  && gs.SCdisplay_state != SHOW_WIREFRAME ) continue;
1488 
1489  if (!residues[r]->is_ligand() && gs.SCdisplay_state == SHOW_WIREFRAME)
1490  xwidth = graphics::protein_wireframeScale;
1491 
1492  if (residues[r]->residue_type_set().name() == chemical::CENTROID
1493  && residues[r]->aa() != core::chemical::aa_unk ) continue;
1494 
1495  Size const natoms( residues[r]->natoms() );
1496 
1497  // draw the atom bonds
1498  utility::vector1< Vector > prev1( natoms ), prev2( natoms );
1499  utility::vector1< bool > prev_set( natoms, false );
1500 
1501  for ( Size i=1; i<= natoms; ++i ) {
1502  core::chemical::AtomIndices const & nbrs( residues[r]->bonded_neighbor(i) );
1503 
1504  for ( Size jj=1; jj<= nbrs.size(); ++jj ) {
1505  Size const j( nbrs[jj] );
1506  if ( j < i ) continue;
1507  if ( residues[r]->is_virtual(j) ) continue; //no virtual atoms
1508  if ( residues[r]->atom_type(j).is_hydrogen() && gs.show_H_state == SHOW_NO_H ) continue;
1509  //if ( pose.residue(r).atom_is_backbone(j) && pose.residue(r).atom_name(j) != "CA" ) continue;
1510 
1511  Vector const color1 = get_atom_color( gs, residues, r, i );
1512  Vector const color2 = get_atom_color( gs, residues, r, j );
1513 
1514  Vector const xyz1( residues[r]->xyz(i));
1515  Vector const xyz2( residues[r]->xyz(j));
1516 
1517  Vector const bond( xyz2 - xyz1 );
1518 
1519  // check for chainbreaks
1520  if (bond.length_squared() > graphics::BOND_LENGTH_CUTOFF2 ) break;
1521 
1522  Vector width( cross( bond, z ) );
1523  if ( width.length_squared() ) width.normalize();
1524  width *= xwidth;
1525 
1526  if ( residues[r]->atom_type(j).is_hydrogen() ) width *= 0.5;
1527 
1528  glColor3fxyz( color1 );
1529 
1530  if ( prev_set[ i ] ) {
1531  // draw the elbow
1532  glBegin(GL_POLYGON);
1533  glVertex3fxyz ( prev1[i] );
1534  glVertex3fxyz ( xyz1 + width );
1535  glVertex3fxyz ( xyz1 - width );
1536  glVertex3fxyz ( prev2[i] );
1537  glEnd();
1538  } else {
1539  prev_set[i] = true;
1540  prev1[i] = xyz1 - width;
1541  prev2[i] = xyz1 + width;
1542  }
1543 
1544  glBegin(GL_POLYGON);
1545  glVertex3fxyz ( xyz1 + width );
1546  glVertex3fxyz ( xyz1 - width );
1547  glColor3fxyz( color2 ); // change color
1548  glVertex3fxyz ( xyz2 - width );
1549  glVertex3fxyz ( xyz2 + width );
1550  glEnd();
1551 
1552  if ( !prev_set[j] ) {
1553  // for drawing the elbow at atomj
1554  prev_set[j] = true;
1555  prev1[j] = xyz2 + width;
1556  prev2[j] = xyz2 - width;
1557  } else {
1558  // draw the elbow
1559  glBegin(GL_POLYGON);
1560  glVertex3fxyz ( prev1[j] );
1561  glVertex3fxyz ( xyz2 - width );
1562  glVertex3fxyz ( xyz2 + width );
1563  glVertex3fxyz ( prev2[j] );
1564  glEnd();
1565  }
1566  } // jj
1567  } // i
1568  } // nres
1569 } // void draw_sidechains
1570 
1571 
1572 void draw_backbone(
1573  GraphicsState & gs,
1575  utility::vector1< char > const & ss ) {
1576 
1577  switch( gs.BBdisplay_state ) {
1578  case SHOW_BACKBONE:
1579  draw_Calpha_trace( gs, residues, 1, residues.size() );
1580  return;
1581  case SHOW_CARTOON:
1582  draw_secstruct( gs, residues, ss, 1, residues.size() );
1583  return;
1584  case SHOW_NOBB:
1585  return;
1586  }
1587 }
1588 
1589 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1590 //chu copied from rosetta++ protein_graphics.cc
1591 void
1592 draw_sphere( GraphicsState & gs, utility::vector1< core::conformation::ResidueCOP > const & residues )
1593 {
1594  using namespace graphics;
1595  //lin currently only ligand
1596  //lin should be easy to extend to non ligand
1597  const int nres = residues.size();
1598  glPushAttrib(GL_ENABLE_BIT);
1599  glEnable(GL_LIGHTING);
1600 
1601  GLUquadricObj *sphereObj = gluNewQuadric();
1602  // Create a glu quadric object
1603  gluQuadricDrawStyle(sphereObj, GLU_FILL);
1604  gluQuadricNormals(sphereObj, GLU_SMOOTH);
1605 
1606  // ligand residue only
1607  for ( int i = 1; i <= nres; i++ ) {
1608  conformation::Residue const & rsd = *(residues[i]);
1609 
1610  if( rsd.aa() != chemical::aa_unk ) continue;
1611 
1612  float const sphere_opacity ( rsd.is_protein() ? protein_sphere_opacity : ligand_sphere_opacity );
1613  float const sphere_shininess ( rsd.is_protein() ? protein_sphere_shininess : ligand_sphere_shininess );
1614 
1615  // loop through each heavy atom
1616  int atom_begin = 1 ;
1617  int atom_end = rsd.natoms();
1618 
1619  for ( int j = atom_begin; j <= atom_end; ++j ) {
1620  conformation::Atom const & atom( rsd.atom(j) );
1621 
1622  if ( rsd.is_virtual(j) ) continue; //no virtual atoms
1623 
1624  Vector const xyz( rsd.xyz(j) );
1625 
1626  // Figure out the material based on the atom type.
1627  Vector const atom_color ( get_atom_color( gs, residues, i, j ) );
1628 
1629  //GLfloat mat_shininess[] = { sphere_shininess };
1630  GLfloat atom_material[4] = {
1631  atom_color[0],
1632  atom_color[1],
1633  atom_color[2],
1634  1.0,
1635  };
1636  GLfloat specular_material[4] = {
1637  atom_material[0] * sphere_opacity,
1638  atom_material[1] * sphere_opacity,
1639  atom_material[2] * sphere_opacity,
1640  sphere_opacity,
1641  };
1642 
1643  // Highlight the nonprotein
1644  if ( ! rsd.is_protein() ) {
1645  for (int color = 0 ; color < 3 ; color++) {
1646  atom_material[color] *= 1.5;
1647  if (atom_material[color] > 1.0)
1648  atom_material[color] = 1.0;
1649  }
1650  if (atom_material[3] < 0.1)
1651  atom_material[3] = 0.1;
1652  }
1653  if (atom_material[3] < 0.1) continue;
1654  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, atom_material);
1655  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, atom_material);
1656  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular_material);
1657  glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &sphere_shininess);
1658 
1659  glPushMatrix();
1660  glTranslatef(xyz(1), xyz(2), xyz(3));
1661 
1662  // draw a sphere using the sphere display list
1663  if ( graphics::sphereDisplayList == 0 ) {
1664  const int SPHERE_SLICES(16), SPHERE_STACKS(16);
1665  float sphereRadius(1.0);
1666  graphics::sphereDisplayList = glGenLists(1);
1667  runtime_assert(graphics::sphereDisplayList != 0);
1668 
1669  glNewList(graphics::sphereDisplayList, GL_COMPILE);
1670  gluSphere(sphereObj, sphereRadius, SPHERE_SLICES, SPHERE_STACKS);
1671  glEndList();
1672  }
1673  if( graphics::sphereDisplayList != 0) {
1674  float sphereRadius, sphereScale(1.0);
1675  const float scale_for_display_list(1.0);
1676  sphereScale = 1.0 * scale_for_display_list ;
1677  sphereRadius = sphereScale * rsd.atom_type_set()[ atom.type() ].lj_radius();
1678  glScalef(sphereRadius, sphereRadius, sphereRadius);
1679  }
1680  glCallList(graphics::sphereDisplayList);
1681 
1682  glPopMatrix();
1683  }
1684  }
1685  // clean up
1686  glPopAttrib();
1687  gluDeleteQuadric(sphereObj);
1688  glDisable(GL_LIGHTING);// Turn lighting off
1689 }
1690 
1691 //////////////////////////////////////////////////
1692 //////////////////////////////////////////////////
1693 //////
1694 ////// electron density display functions
1695 //////
1696 void render_density(
1697  GraphicsState &gs,
1698  utility::vector1< triangle > &triangles) {
1699  // "on demand"
1700  if (!gs.density_redraw) return;
1701 
1702  triangles.clear();
1703 
1705  const float thresh = edm.getMean() + gs.density_sigma*edm.getStdev();
1706  triangleIterator tri_it( edm.data(), thresh );
1707 
1708  numeric::xyzVector_float vertex[3], normal[3];
1709  numeric::xyzVector< core::Real> cart_vi[3], cart_ni[3];
1710  while (tri_it.hasNext()) {
1711  tri_it.next( vertex, normal );
1712  for (int j=0; j<3; ++j) {
1713  edm.idx2cart( vertex[j] , cart_vi[j] );
1714  edm.idxoffset2cart( normal[j] , cart_ni[j] );
1715  cart_ni[j].normalize();
1716 
1717  //vertices.push_back( cart_vi );
1718  //normals.push_back( cart_ni );
1719  }
1720  triangles.push_back( triangle( cart_vi, cart_ni ) );
1721  }
1722 }
1723 
1724 // for sorting
1725 bool operator < (const triangle& left, const triangle& right) {
1726  return (left.depth_ < right.depth_);
1727 }
1728 
1729 
1730 void
1731 display_density(
1732  GraphicsState & /*gs*/,
1733  utility::vector1< triangle > &triangles ) {
1734  using namespace conformation;
1735  using namespace chemical;
1736 
1737  if (triangles.size() == 0) return;
1738  //glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); // wireframe
1739 
1740  glMatrixMode(GL_MODELVIEW);
1741  GLfloat currentrotation[16];
1742  glGetFloatv(GL_MODELVIEW_MATRIX, currentrotation);
1743  numeric::xyzVector_float const z( currentrotation[2], currentrotation[6], currentrotation[10] );
1744 
1745  glPushAttrib(GL_ENABLE_BIT);
1746  glEnable(GL_BLEND); //activate blending mode
1747  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //define blending factors
1748  glEnable(GL_LIGHTING);
1749  glColorMaterial ( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ) ;
1750  glEnable ( GL_COLOR_MATERIAL ) ;
1751  glDisable( GL_DEPTH_TEST );
1752 
1753  // sort triangles back to front
1754  core::Size const ntris = triangles.size();
1755  for (core::Size i=1; i<=ntris; ++i) {
1756  triangles[i].update( z );
1757  }
1758 
1759  std::sort( triangles.begin(), triangles.end() );
1760 
1761  glBegin(GL_TRIANGLES);
1762  Vector const color( 0.8,0.8,0.8 );
1763  glColor4f( color[0], color[1], color[2], 0.3 );
1764 
1765  for ( Size i=1; i<=ntris; ++i ) {
1766  for (Size j=0; j<3; ++j) {
1767  glNormal3f ( triangles[i].normals_[j][0] , triangles[i].normals_[j][1] , triangles[i].normals_[j][2] );
1768  glVertex3f ( triangles[i].vertices_[j][0], triangles[i].vertices_[j][1], triangles[i].vertices_[j][2] );
1769  }
1770  }
1771  glEnd();
1772 
1773  glPopAttrib();
1774  glDisable(GL_LIGHTING);
1775 }
1776 
1777 void
1778 draw_conformation_and_density(
1780  utility::vector1< char > const & ss,
1781  utility::vector1< triangle > &triangles,
1782  GraphicsState & gs,
1783  Vector const & center )
1784 {
1785 
1786  using namespace graphics;
1787  const int total_residue = residues.size();
1788 
1789  // clear
1790  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
1791 
1792  //Set background color
1793  glClearColor( bg_color.x(), bg_color.y(), bg_color.z(), 1.0 );
1794 
1795  // In case the view has been rotated... set z to be the axis pointing out of the screen
1796  glMatrixMode(GL_MODELVIEW);
1797  GLfloat currentrotation[16];
1798  glGetFloatv(GL_MODELVIEW_MATRIX, currentrotation);
1799 
1800  Vector const x( currentrotation[0], currentrotation[4], currentrotation[ 8] );
1801  Vector const y( currentrotation[1], currentrotation[5], currentrotation[ 9] );
1802  Vector const z( currentrotation[2], currentrotation[6], currentrotation[10] );
1803  Vector light = z + y ;
1804  Vector light2 = z - y - x;
1805 
1806  GLfloat light_position[] = { light[0], light[1], light[2], 0.0 };
1807  GLfloat light2_position[] = { light2[0], light2[1], light2[2], 0.0 };
1808  //GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
1809  //GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
1810  //GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
1811  //GLfloat mat_emission[] = { 0.0, 0.0, 0.0, 1.0 };
1812  //GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
1813 
1814  glEnable(GL_LIGHT0);
1815  glEnable(GL_LIGHT1);
1816  glEnable(GL_DEPTH_TEST);
1817  glShadeModel(GL_SMOOTH);
1818 
1819  glLightfv(GL_LIGHT0, GL_POSITION, light_position);
1820  glLightfv(GL_LIGHT1, GL_POSITION, light2_position);
1821  //glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
1822  //glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
1823  //glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
1824  //glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, mat_emission );
1825  //glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular );
1826 
1827 
1828  if ( total_residue > 0 ) {
1829  glPushMatrix();
1830  glTranslatef(-center.x(), -center.y(), -center.z());
1831 
1832  draw_backbone( gs, residues, ss );
1833  draw_sidechains( gs, residues, 1, total_residue );
1834  draw_sphere( gs, residues );
1835 
1836  render_density( gs, triangles ); // renders "on-demand" depending on gs object
1837  display_density( gs, triangles );
1838  glPopMatrix();
1839  }
1840 
1841  //glDisable(GL_LIGHT0);// Turn lighting off
1842  //glDisable(GL_LIGHT1);// Turn lighting off
1843 }
1844 
1845 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1846 
1847 void draw_conformation( utility::vector1< conformation::ResidueCOP > const & residues,
1848  utility::vector1< char > const & ss,
1849  GraphicsState & gs,
1850  Vector const & center) {
1851 
1852  using namespace graphics;
1853  const int total_residue = residues.size();
1854 
1855 #ifndef BOINC_GRAPHICS
1856 
1857  // clear
1858  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
1859 
1860  //Set background color
1861  glClearColor( bg_color.x(), bg_color.y(), bg_color.z(), 1.0 );
1862 
1863 #endif
1864 
1865  GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
1866  glEnable(GL_LIGHT0);
1867  glEnable(GL_DEPTH_TEST);
1868  glShadeModel(GL_SMOOTH);
1869  glLightfv(GL_LIGHT0, GL_POSITION, light_position);
1870 
1871  glPushMatrix();
1872  glTranslatef(-center.x(), -center.y(), -center.z());
1873 
1874  utility::vector1< conformation::ResidueCOP > residues_protein, other_residues;
1875  for (Size n = 1; n <= residues.size(); n++ ){
1876  conformation::ResidueCOP rsd = residues[ n ];
1877  if ( rsd->is_protein() ) {
1878  residues_protein.push_back( rsd );
1879  } else {
1880  other_residues.push_back( rsd );
1881  }
1882  }
1883 
1884 
1885  if ( residues_protein.size() > 0 ){
1886  draw_backbone( gs, residues_protein, ss );
1887  draw_sidechains( gs, residues_protein, 1, residues_protein.size() );
1888  draw_sphere( gs, residues_protein );
1889  }
1890 
1891  if ( other_residues.size() > 0 ){
1892  ColorMode colormode_save = gs.Color_mode;
1893  gs.Color_mode = RHIJU_COLOR;
1894  display_residues_wireframe( gs, other_residues, Vector( 0.0, 0.0, 0.0) );
1895  gs.Color_mode = colormode_save;
1896  }
1897 
1898  glPopMatrix();
1899  glDisable(GL_LIGHT0);// Turn lighting off
1900 }
1901 
1902 
1903 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1904 
1905 void draw_pose(
1906  const core::pose::Pose & pose,
1907  GraphicsState & gs,
1908  const bool centered) {
1909  core::Size nres = pose.total_residue();
1910  utility::vector1< char > ss(nres);
1912 
1913  for (int i=1; i<=(int)pose.total_residue(); ++i) {
1914  ss[i] = pose.secstruct(i);
1915  residues[i] = pose.residue(i);
1916  }
1917 
1918  Vector center_of_mass( 0, 0, 0 );
1919  if(centered) {
1920  for ( int i = 1; i <= (int) pose.total_residue(); ++i ) {
1921  center_of_mass += residues[i]->nbr_atom_xyz();
1922  }
1923  center_of_mass /= pose.total_residue();
1924  }
1925 
1926  draw_conformation( residues, ss, gs, center_of_mass );
1927 }
1928 
1929 
1930 #endif
1931 
1932 /// @brief
1933 utility::vector1< SilentObserverOP > silent_observers; // quick hack to eliminate OPs being destroyed!
1934 void
1936  moves::MonteCarlo & mc,
1937  std::string const name_in,
1938  bool fullatom = false
1939 )
1940 {
1942  viewer1( new SilentObserver( name_in + "_last_accepted", fullatom ) ),
1943  viewer2( new SilentObserver( name_in + "_best_accepted", fullatom ) );
1944 
1945  std::cout << "attaching viewers!" << std::endl;
1947  mc.attach_observer_to_lowest_score_pose ( *viewer2 );
1948 
1949  silent_observers.push_back( viewer1 );
1950  silent_observers.push_back( viewer2 );
1951 }
1952 
1953 ///////////////////////////////////////
1954 void
1956 {
1957 
1958 #ifdef GL_GRAPHICS
1959  conformation_viewers.clear();
1960 #endif
1961 }
1962 
1963 
1964 } // viewer
1965 } // protocols