OpenStructure
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
__init__.py
Go to the documentation of this file.
1 #------------------------------------------------------------------------------
2 # This file is part of the OpenStructure project <www.openstructure.org>
3 #
4 # Copyright (C) 2008-2011 by the OpenStructure authors
5 #
6 # This library is free software; you can redistribute it and/or modify it under
7 # the terms of the GNU Lesser General Public License as published by the Free
8 # Software Foundation; either version 3.0 of the License, or (at your option)
9 # any later version.
10 # This library is distributed in the hope that it will be useful, but WITHOUT
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 # details.
14 #
15 # You should have received a copy of the GNU Lesser General Public License
16 # along with this library; if not, write to the Free Software Foundation, Inc.,
17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 #------------------------------------------------------------------------------
19 from _ost_gfx import *
20 from py_gfx_obj import PyGfxObj
21 
22 WHITE=RGB(1.0,1.0,1.0)
23 BLACK=RGB(0.0,0.0,0.0)
24 GREY=RGB(0.5,0.5,0.5)
25 RED=RGB(1.0,0.0,0.0)
26 DARKRED=RGB(0.5,0.0,0.0)
27 LIGHTRED=RGB(1.0,0.5,0.5)
28 GREEN=RGB(0.0,1.0,0.0)
29 DARKGREEN=RGB(0.0,0.5,0.0)
30 LIGHTGREEN=RGB(0.5,1.0,0.5)
31 BLUE=RGB(0.0,0.0,1.0)
32 DARKBLUE=RGB(0.0,0.0,0.5)
33 LIGHTBLUE=RGB(0.5,0.5,1.0)
34 YELLOW=RGB(1.0,1.0,0.0)
35 DARKYELLOW=RGB(0.5,0.5,0.0)
36 LIGHTYELLOW=RGB(1.0,1.0,0.5)
37 CYAN=RGB(0.0,1.0,1.0)
38 DARKCYAN=RGB(0.0,0.5,0.5)
39 LIGHTCYAN=RGB(0.5,1.0,1.0)
40 MAGENTA=RGB(1.0,0.0,1.0)
41 DARKMAGENTA=RGB(0.5,0.0,0.5)
42 LIGHTMAGENTA=RGB(1.0,0.5,1.0)
43 PURPLE=MAGENTA
44 DARKPURPLE=DARKMAGENTA
45 LIGHTPURPLE=LIGHTMAGENTA
46 ORANGE=RGB(1.0,0.5,0.0)
47 DARKORANGE=RGB(0.5,0.25,0.0)
48 LIGHTORANGE=RGB(1.0,0.75,0.5)
49 
50 def Stereo(mode,flip=None,alg=None):
51  """
52  Stereo control
53 
54  :param mode: 0=off, 1=quad-buffered, 2=interlaced
55  :type mode: int
56  :param flip: invert order of left/right display
57  :type flip: bool
58  :param alg: stereo algorithm (0 or 1)
59  :type param: int
60  """
61  if(flip):
62  Scene().SetStereoFlip(flip)
63  if(alg):
64  Scene().SetStereoAlg(alg)
65 
66  Scene().SetStereoMode(mode)
67 
68 def FitToScreen(gfx_ent, width=None, height=None, margin=0.05):
69  """
70  Setup camera such that it is centered on the graphical entity and the entity
71  fits the entire viewport. The longest axes of the entity are aligned along
72  the x- and y- axes of the screen.
73 
74  :param gfx_ent: The graphical entity
75  :type gfx_ent: str or :class:`Entity`
76 
77 
78  """
79  from ost import geom
80  import math
81  def _XYZ(view, axes):
82  """
83  returns the vectors in x, y and z direction respectively. The smallest
84  vector is in z, then y, and the largest along x.
85  """
86  rows=[axes.GetRow(i) for i in range(3)]
87  lengths=[]
88  for axe in rows:
89  min_proj=geom.Dot(axe, view.atoms[0].pos)
90  max_proj=min_proj
91  for atom in view.atoms[1:]:
92  proj=geom.Dot(axe, atom.pos)
93  min_proj=min(proj, min_proj)
94  max_proj=max(proj, max_proj)
95  lengths.append(max_proj-min_proj)
96  def cmp_x(rhs, lhs):
97  return cmp(lhs[1], rhs[1])
98  sorted_axes=sorted(zip(rows, lengths), cmp_x)
99  return [r*l for r,l in sorted_axes]
100  scene=Scene()
101  if not isinstance(gfx_ent, Entity):
102  gfx_ent=scene[str(gfx_ent)]
103  width=width and width or scene.viewport.width
104  height=height and height or scene.viewport.height
105  atom_positions=geom.Vec3List([atom.pos for atom in gfx_ent.view.atoms])
106  axes=atom_positions.principal_axes
107  sorted_axes=_XYZ(gfx_ent.view, axes)
108  x_bigger_than_y=geom.Length(sorted_axes[0])>geom.Length(sorted_axes[1])
109  if x_bigger_than_y:
110  if width>height:
111  x_axes=geom.Normalize(sorted_axes[0])
112  y_axes=geom.Normalize(sorted_axes[1])
113  else:
114  x_axes=geom.Normalize(sorted_axes[1])
115  y_axes=geom.Normalize(sorted_axes[0])
116  else:
117  if width>height:
118  x_axes=geom.Normalize(sorted_axes[1])
119  y_axes=geom.Normalize(sorted_axes[0])
120  else:
121  x_axes=geom.Normalize(sorted_axes[0])
122  y_axes=geom.Normalize(sorted_axes[1])
123  z_axes=geom.Normalize(geom.Cross(x_axes, y_axes))
124  rotation=geom.Mat3(x_axes[0], x_axes[1], x_axes[2],
125  y_axes[0], y_axes[1], y_axes[2],
126  z_axes[0], z_axes[1], z_axes[2])
127  rtc=geom.Mat4(rotation)
128 
129  center=gfx_ent.center
130  aspect=float(width)/float(height)
131  factor_y=1.0/math.tan(math.radians(scene.fov))
132  factor_x=factor_y/aspect
133  z_off=geom.Length(sorted_axes[2])*0.5
134  rtc[0,3]=center[0]
135  rtc[1,3]=center[1]
136  rtc[2,3]=center[2]
137  rtc[3,0]=0
138  rtc[3,1]=0
139  rtc[3,2]=-(max(factor_x*(1+margin)*geom.Length(sorted_axes[0]),
140  factor_y*(1+margin)*geom.Length(sorted_axes[1]))+z_off)
141  scene.SetRTC(rtc)
142 
143 
145  def __init__(self, node_list, name):
146  self._node_list=node_list
147  self._name=name
148 
149  def __iter__(self):
150  for node in self._node_list:
151  yield getattr(node, self._name)
152 
153  def __call__(self, *args, **kwargs):
154  for node in self._node_list:
155  bound_method=getattr(node, self._name)
156  bound_method(*args, **kwargs)
157 
158 class GfxNodeListProxy(object):
159  def __init__(self, node_list):
160  self._nodes=node_list
161 
162  def __getattr__(self, name):
163  if name.startswith('_'):
164  return super(GfxNodeListProxy, self).__getattr__(name)
165  return GfxNodeListAttrProxy(self._nodes, name)
166 
167  def __setattr__(self, name, value):
168  if name.startswith('_'):
169  super(GfxNodeListProxy, self).__setattr__(name, value)
170  for node in self._nodes:
171  setattr(node, name, value)
172 
173 def _Match(scene, pattern="*"):
174  import os
175  import fnmatch
176  def _Recurse(path, node, pattern):
177  matches=[]
178  for child in node.children:
179  full_name=os.path.join(path, child.name)
180  if fnmatch.fnmatchcase(full_name, pattern):
181  matches.append(child)
182  matches.extend(_Recurse(full_name, child, pattern))
183  return matches
184  return GfxNodeListProxy(_Recurse("", Scene().root_node, pattern))
185 
186 SceneSingleton.Match=_Match
187 
188 def _to_vec3(p):
189  import ost.geom
190  if isinstance(p,ost.geom.Vec3):
191  return p
192  else:
193  try:
194  return ost.geom.Vec3(p[0],p[1],p[2])
195  except:
196  raise TypeError("expected either a sequence or a geom.Vec3 object")
197 
198 
199 def _primlist_add_point(self,pos,color=None):
200  pos=_to_vec3(pos)
201  if not color:
202  color=WHITE
203  self._add_point(pos,color)
204 
205 def _primlist_add_line(self,pos1,pos2,color1=None,color2=None,color=None):
206  pos1=_to_vec3(pos1)
207  pos2=_to_vec3(pos2)
208  if not color:
209  color=WHITE
210  if not color1:
211  color1=color
212  if not color2:
213  color2=color1
214  self._add_line(pos1,pos2,color1,color2)
215 
216 def _primlist_add_sphere(self,cen,radius=1.0,color=None):
217  pos=_to_vec3(cen)
218  if not color:
219  color=WHITE
220  self._add_sphere(pos,radius,color)
221 
222 def _primlist_add_cyl(self,pos1,pos2,radius1=None,radius2=None,radius=None,color1=None,color2=None,color=None,):
223  pos1=_to_vec3(pos1)
224  pos2=_to_vec3(pos2)
225  if radius is None:
226  radius=1.0
227  if radius1 is None:
228  radius1=radius
229  if radius2 is None:
230  radius2=radius1
231  if not color:
232  color=WHITE
233  if not color1:
234  color1=color
235  if not color2:
236  color2=color1
237  self._add_cyl(pos1,pos2,radius1,radius2,color1,color2)
238 
239 def _primlist_add_text(self,text,pos,color=None,point_size=None):
240  pos=_to_vec3(pos)
241  if not color:
242  color=WHITE
243  if not point_size:
244  point_size=1.0
245  self._add_text(text,pos,color,point_size)
246 
247 PrimList.AddPoint=_primlist_add_point
248 PrimList.AddLine=_primlist_add_line
249 PrimList.AddSphere=_primlist_add_sphere
250 PrimList.AddCyl=_primlist_add_cyl
251 PrimList.AddText=_primlist_add_text
252 
253 # entity reset
254 
255 def _entity_reset(self,*args,**kwargs):
256  import ost.mol as mol
257  eh=None
258  ev=None
259  qr=None
260  qf=None
261  for a in args:
262  if isinstance(a,mol.Query):
263  if qr:
264  raise TypeError("Reset: more than one query string given")
265  qr=a
266  elif isinstance(a,mol.EntityHandle):
267  if eh:
268  raise TypeError("Reset: more than one entity handle given")
269  eh=a
270  elif isinstance(a,mol.EntityView):
271  if ev:
272  raise TypeError("Reset: more than one entity view given")
273  ev=a
274  elif isinstance(a,str):
275  if qr:
276  raise TypeError("Reset: more than one query string given")
277  qr=mol.Query(a)
278  elif isinstance(a,int):
279  if qf:
280  raise TypeError("Reset: more than one QueryFlags given")
281  qf=a
282  else:
283  raise TypeError("Reset: unknown option of type '%s' given"%type(a))
284 
285  for key,val in kwargs.iteritems():
286  if key=="entity":
287  if not isinstance(val,mol.EntityHandle):
288  raise TypeError("Reset: expected mol.EntityHandle for 'entity' option")
289  if eh:
290  raise TypeError("Reset: more than one entity handle given")
291  eh=val
292  elif key=="view":
293  if not isinstance(val,mol.EntityView):
294  raise TypeError("Reset: expected mol.EntityView for 'view' option")
295  if ev:
296  raise TypeError("Reset: more than one entity view given")
297  ev=val
298  elif key=="query":
299  if isinstance(val,mol.Query):
300  pass
301  elif isinstance(val,str):
302  val=mol.Query(val)
303  else:
304  raise TypeError("Reset: expected mol.Query or string for 'query' option")
305  if qr:
306  raise TypeError("Reset: more than one query string given")
307  qr=val
308  elif key=="query_flags":
309  if not isinstance(val,int):
310  raise TypeError("Reset: expected integer for 'query_flags' option")
311  if qf:
312  raise TypeError("Reset: more than one query flags given")
313  qf=val
314  else:
315  raise TypeError("Reset: unknown key '%s'"%key)
316 
317  if eh and ev:
318  raise TypeError("Reset: entity and view are mutually exclusive options")
319 
320  if ev:
321  self._reset4(ev)
322  else:
323  if not eh:
324  eh = self.query_view.entity
325  if not qr:
326  qr = self.query_view.query
327  if not qf:
328  qf = self.query_view.GetFlags()
329  self._reset3(eh,qr,qf)
330 
331 Entity.Reset=_entity_reset
332 
333 def _scene_export(self,*args,**kwargs):
334  """
335  scene.Export(Exporter)
336  scene.Export("file.png")
337  scene.Export("file.png",(width,height),samples=0,transparency=False)
338  deprecated:
339  scene.Export("file.png",width,height,samples=0,transparency=False)
340  scene.Export("file.png",width,height,transparency)
341  """
342  scene=Scene()
343  tp=False
344  sa=0
345  if "tp" in kwargs:
346  tp=int(kwargs["tp"])
347  if "transparency" in kwargs:
348  tp=int(kwargs["transparency"])
349  if "samples" in kwargs:
350  sa=int(kwargs["samples"])
351 
352  if len(args)==1:
353  if isinstance(args[0],Exporter):
354  scene._export_via_exporter(args[0])
355  return
356  elif type(args[0])==type(""):
357  scene._export_screen(args[0],tp)
358  return
359  elif len(args)==2:
360  if type(args[0]==type("")):
361  # assume second argument is a dimension
362  width=int(args[1][0])
363  height=int(args[1][1])
364  scene._export_buffer(args[0],width,height,sa,tp)
365  return
366  elif len(args)==3:
367  if type(args[0]==type("")):
368  width=int(args[1])
369  height=int(args[2])
370  scene._export_buffer(args[0],width,height,sa,tp)
371  return
372  elif len(args)==4:
373  if type(args[0]==type("")):
374  width=int(args[1])
375  height=int(args[2])
376  tp=int(args[3])
377  scene._export_buffer(args[0],width,height,sa,tp)
378  return
379  # getting here indicates an error
380  raise RuntimeError("""invalid arguments to scene.Export; expected one of
381  Export(gfx.Exporter)
382  Export('file.png')
383  Export('file.png',(width,height),samples=0, transparency=False)
384  Export('file.png',width,height,samples=0, transparency=False) -> deprecated
385  Export('file.png',width,height,transparency) -> deprecated
386  """)
387 
388 SceneSingleton.Export=_scene_export
389 
390 import __main__ as main_mod
391 main_mod.scene=Scene()
392 main_mod.scene.Stereo=Stereo
393 
394 import ost as ost_mod
395 ost_mod.scene=Scene()
396 ost_mod.scene.Stereo=Stereo
397 
398 def GostExporter(file,scale=1.0,to_origin=True):
399  e=GostExporter_(file)
400  e.scale=scale
401  e.to_origin=to_origin
402  return e
403 
404 def ColladaExporter(file,scale=1.0,to_origin=True):
405  e=ColladaExporter_(file)
406  e.scale=scale
407  e.to_origin=to_origin
408  return e
409 
410 def _go_get_vis(go):
411  return go.IsVisible()
412 
413 def _go_set_vis(go,flag):
414  if flag:
415  go.Show()
416  else:
417  go.Hide()
418 
419 GfxObj.visible=property(_go_get_vis,_go_set_vis)
420 
421 
main class for organization and root for the graphical display
Definition: scene.hh:80
Protein or molecule.
Real Dot(const Vec4 &v1, const Vec4 &v2)
vector dot product
Definition: vecmat4_op.hh:76
def ColladaExporter
Definition: __init__.py:404
def Stereo
Definition: __init__.py:50
Color DLLEXPORT_OST_GFX RGB(float r, float g, float b)
RGB color spec from floats (0.0-1.0)
Selection Query.
Definition: query.hh:74
Vec3 Cross(const Vec3 &v1, const Vec3 &v2)
vector cross product
Definition: vecmat3_op.hh:85
def GostExporter
Definition: __init__.py:398
def FitToScreen
Definition: __init__.py:68
Vec4 Normalize(const Vec4 &v)
Definition: vecmat4_op.hh:81
definition of EntityView
Definition: entity_view.hh:86
Real Length(const Vec4 &v)
returns length of vector
Definition: vecmat4_op.hh:40