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