Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ConformationViewer.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 #ifdef GL_GRAPHICS //////////////////////////////////////////////////////////////////---------------------
15 
16 // Unit headers
18 
19 // Package headers
21 
28 
30 
31 #include <core/types.hh>
32 
33 // Project headers
34 #include <utility/pointer/access_ptr.hh>
35 #include <utility/vector1.hh>
36 
37 #include <basic/options/option.hh>
38 #include <basic/options/keys/edensity.OptionKeys.gen.hh>
39 // using -edensity::mapfile option to determine whether to try to display density contours or not
40 
41 // C++ Headers
42 
43 // GLUT
44 #ifdef MAC
45 #include <GLUT/glut.h>
46 #else
47 #include "GL/glut.h"
48 #endif
49 
50 #include <pthread.h>
51 
52 using namespace core; ////////////////////////////////// !!!!!!!!!!!!!!!!!!!!!!!!!! DANGER
53 
54 
55 
56 namespace protocols {
57 namespace viewer {
58 
59 
60 // signal that our window hasn't been created yet
61 int const BAD_WINDOW( -999 );
62 
63 /// @brief default constructor
64 ConformationViewer::ConformationViewer() :
65  Super(),
66  new_conformation_( true ),
67  use_debug_pause_( false ),
68  conf_( NULL )
69 {}
70 
71 // CALLED BY WORKER THREAD
72 ConformationViewer::ConformationViewer(std::string const & name_in ):
73  Super(),
74  name_( name_in ),
75  new_conformation_( true ),
76  my_window_( BAD_WINDOW ),
77  length_( 900 ),
78  width_( 900 ),
79  use_debug_pause_( false ),
80  conf_( NULL )
81 {
82  pthread_mutex_init( &residues_mut_, NULL );
83 }
84 
85 ConformationViewer::ConformationViewer(std::string const & name_in, int length, int width, bool debug_pause ):
86  Super(),
87  name_( name_in ),
88  new_conformation_( true ),
89  my_window_( BAD_WINDOW ),
90  length_( length ),
91  width_( width ),
92  use_debug_pause_( debug_pause ),
93  conf_( NULL )
94 {
95  pthread_mutex_init( &residues_mut_, NULL );
96 }
97 
98 /// @brief default destructor
99 ConformationViewer::~ConformationViewer()
100 {
101  detach_from();
102 }
103 
104 
105 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
106 // called by our window's glutDisplayFunc, conformation_viewer_display, when glut registers need for
107 // redrawing our window
108 //
109 // CALLED BY GRAPHICS THREAD
110 
111 void
112 ConformationViewer::display_func()
113 {
114 
115  if ( residues_.empty() ) return;
116 
117  // lock the residues vector
118  pthread_mutex_lock( &residues_mut_ );
119 
120  //display_residues( residues_, anchor_id_ ); // in viewer.cc
121  if ( basic::options::option[ basic::options::OptionKeys::edensity::mapfile ].user()) {
122 
124  runtime_assert ( edm.isMapLoaded() );
125  draw_conformation_and_density( residues_, secstruct_, triangles_ , current_gs_,
126  residues_[ anchor_id_.rsd() ]->xyz( anchor_id_.atomno() ));
127 
128  } else {
129  draw_conformation( residues_, secstruct_, current_gs_,
130  residues_[ anchor_id_.rsd() ]->xyz(anchor_id_.atomno() ) ); // in viewer.cc
131  }
132 
133  pthread_mutex_unlock( &residues_mut_ );
134 }
135 
136 /////////////////////////////////////////////////////////////////
137 
138 // called by glutIdleFunc -- GRAPHICS THREAD
139 void
140 ConformationViewer::display_if_necessary()
141 {
142 
143  if ( new_conformation_ && my_window_ != BAD_WINDOW ) {
144  //std::cout << "display_if_necessary new_conf=true" << std::endl;
145  new_conformation_ = false;
146  glutSetWindow( my_window_ );
147  glutPostRedisplay();
148 
149  }
150 
151 }
152 
153 /////////////////////////////////////////////////////////////////
154 /// @brief is currently observing a Conformation?
155 /// @return the Conformation, otherwise NULL
157 ConformationViewer::is_observing() const
158 {
159  return conf_;
160 }
161 
162 /////////////////////////////////////////////////////////////////
163 /// @brief attach to Conformation
164 void
165 ConformationViewer::attach_to(
167 )
168 {
169  detach_from();
170 
171  xyz_event_link_ = conf.attach_xyz_obs( &ConformationViewer::on_xyz_change, this );
172  connection_event_link_ = conf.attach_connection_obs( &ConformationViewer::on_connection_change, this );
173 
174  conf.debug_pause( use_debug_pause_ );
175 
176  conf_ = &conf; // keeping pointer only so debug_pause() can be cleared later
177 }
178 
179 /////////////////////////////////////////////////////////////////
180 /// @brief detach from Conformation
181 void
182 ConformationViewer::detach_from()
183 {
184  xyz_event_link_.invalidate();
185  connection_event_link_.invalidate();
186 
187  if ( conf_ ) {
188  conf_->debug_pause( false );
189  }
190 
191  conf_ = 0;
192 
193 // next line is commented out under the assumption that we may want
194 // to draw the last state of the Conformation even after detachment
195 // residues_.clear();
196 }
197 
198 /////////////////////////////////////////////////////////////////
199 /// @brief upon receiving a ConnectionEvent do...
200 void
201 ConformationViewer::on_connection_change(
203 )
204 {
206 
207  switch ( event.tag ) {
208  case ConnectionEvent::DISCONNECT:
209  detach_from();
210  break;
211  case ConnectionEvent::TRANSFER:
212  // connection is being transferred, so swap the Conformation pointer
213  attach_to( *event.conformation );
214  break;
215  default: // do nothing
216  break;
217  }
218 }
219 
220 /////////////////////////////////////////////////////////////////
221 /// @brief upon receiving a GeneralEvent update the residues and atom tree root
222 void
223 ConformationViewer::on_xyz_change(
225 )
226 {
227  pthread_mutex_lock( &residues_mut_ );
228 
229  // Grab the residues. This is a roundabout way of doing it, but
230  // at the moment it's the only const access to the residues and
231  // it doesn't trigger any residue updates inside the Conformation.
232  // The alternative is to change all viewer function calls to using
233  // CAPs instead, but for now we don't do that in case display of
234  // the residues persist after a Conformation is destroyed.
235  core::conformation::ResidueCAPs res_caps = event.conformation->const_residues();
236  residues_.resize( res_caps.size() );
237  secstruct_.resize( res_caps.size() );
238  for ( core::Size i = 1, ie = res_caps.size(); i <= ie; ++i ) {
239  residues_[ i ] = res_caps[ i ].get();
240  secstruct_[ i ] = event.conformation->secstruct( i );
241  }
242 
243  if ( event.conformation->atom_tree().root() ) {
244  anchor_id_ = event.conformation->atom_tree().root()->id();
245  }
246 
247  new_conformation_ = true;
248 
249  // always set the debug pause in case it gets reset elsewhere
250  event.conformation->debug_pause( use_debug_pause_ );
251 
252  pthread_mutex_unlock( &residues_mut_ );
253 }
254 
255 
256 } // namespace conformation
257 } // namespace core
258 
259 
260 #endif // ifdef GL_GRAPHICS