#------------------------------------------------------------------------------ # This file is part of the OpenStructure project <www.openstructure.org> # # Copyright (C) 2008-2010 by the OpenStructure authors # # This library is free software; you can redistribute it and/or modify it under # the terms of the GNU Lesser General Public License as published by the Free # Software Foundation; either version 3.0 of the License, or (at your option) # any later version. # This library is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with this library; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #------------------------------------------------------------------------------ from _gfx import * WHITE=Color(1.0,1.0,1.0) BLACK=Color(0.0,0.0,0.0) GREY=Color(0.5,0.5,0.5) RED=Color(1.0,0.0,0.0) DARKRED=Color(0.5,0.0,0.0) LIGHTRED=Color(1.0,0.5,0.5) GREEN=Color(0.0,1.0,0.0) DARKGREEN=Color(0.0,0.5,0.0) LIGHTGREEN=Color(0.5,1.0,0.5) BLUE=Color(0.0,0.0,1.0) DARKBLUE=Color(0.0,0.0,0.5) LIGHTBLUE=Color(0.5,0.5,1.0) YELLOW=Color(1.0,1.0,0.0) DARKYELLOW=Color(0.5,0.5,0.0) LIGHTYELLOW=Color(1.0,1.0,0.5) CYAN=Color(0.0,1.0,1.0) DARKCYAN=Color(0.0,0.5,0.5) LIGHTCYAN=Color(0.5,1.0,1.0) MAGENTA=Color(1.0,0.0,1.0) DARKMAGENTA=Color(0.5,0.0,0.5) LIGHTMAGENTA=Color(1.0,0.5,1.0) PURPLE=MAGENTA DARKPURPLE=DARKMAGENTA LIGHTPURPLE=LIGHTMAGENTA ORANGE=Color(1.0,0.5,0.0) DARKORANGE=Color(0.5,0.25,0.0) LIGHTORANGE=Color(1.0,0.75,0.5) def Stereo(mode,flip=None,alg=None): """ Stereo control :param mode: 0=off, 1=quad-buffered, 2=interlaced :type mode: int :param flip: invert order of left/right display :type flip: bool :param alg: stereo algorithm (0 or 1) :type param: int """ if(flip): _gfx.Scene().SetStereoFlip(flip) if(alg): _gfx.Scene().SetStereoAlg(alg) _gfx.Scene().SetStereoMode(mode) def FitToScreen(gfx_ent, width=None, height=None, margin=0.01): """ Setup camera such that it is centered on the graphical entity and the entity fits the entire viewport. The longest axes of the entity are aligned along the x- and y- axes of the screen. :param gfx_ent: The graphical entity :type gfx_ent: str or :class:`Entity` """ from ost import geom import math def _XYZ(view, axes): """ returns the vectors in x, y and z direction respectively. The smallest vector is in z, then y, and the largest along x. """ rows=[axes.GetRow(i) for i in range(3)] lengths=[] for axe in rows: min_proj=geom.Dot(axe, view.atoms[0].pos) max_proj=min_proj for atom in view.atoms[1:]: proj=geom.Dot(axe, atom.pos) min_proj=min(proj, min_proj) max_proj=max(proj, max_proj) lengths.append(max_proj-min_proj) def cmp_x(rhs, lhs): return cmp(lhs[1], rhs[1]) sorted_axes=sorted(zip(rows, lengths), cmp_x) return [r*l for r,l in sorted_axes] scene=Scene() if not isinstance(gfx_ent, Entity): gfx_ent=scene[str(gfx_ent)] width=width and width or scene.viewport.width height=height and height or scene.viewport.height atom_positions=geom.Vec3List([atom.pos for atom in gfx_ent.view.atoms]) axes=atom_positions.principal_axes sorted_axes=_XYZ(gfx_ent.view, axes) x_bigger_than_y=geom.Length(sorted_axes[0])>geom.Length(sorted_axes[1]) if x_bigger_than_y: if width>height: x_axes=geom.Normalize(sorted_axes[0]) y_axes=geom.Normalize(sorted_axes[1]) else: x_axes=geom.Normalize(sorted_axes[1]) y_axes=geom.Normalize(sorted_axes[0]) else: if width>height: x_axes=geom.Normalize(sorted_axes[1]) y_axes=geom.Normalize(sorted_axes[0]) else: x_axes=geom.Normalize(sorted_axes[0]) y_axes=geom.Normalize(sorted_axes[1]) z_axes=geom.Normalize(geom.Cross(x_axes, y_axes)) rotation=geom.Mat3(x_axes[0], x_axes[1], x_axes[2], y_axes[0], y_axes[1], y_axes[2], z_axes[0], z_axes[1], z_axes[2]) rtc=geom.Mat4(rotation) center=gfx_ent.center aspect=float(width)/float(height) factor_y=1.0/math.tan(math.radians(scene.fov)) factor_x=factor_y/aspect z_off=geom.Length(sorted_axes[2])*0.5 rtc[0,3]=center[0] rtc[1,3]=center[1] rtc[2,3]=center[2] rtc[3,0]=0 rtc[3,1]=0 rtc[3,2]=-(max(factor_x*(1+margin)*geom.Length(sorted_axes[0]), factor_y*(1+margin)*geom.Length(sorted_axes[1]))+z_off) scene.SetRTC(rtc) class GfxNodeListAttrProxy: def __init__(self, node_list, name): self._node_list=node_list self._name=name def __iter__(self): for node in self._node_list: yield getattr(node, self._name) def __call__(self, *args, **kwargs): for node in self._node_list: bound_method=getattr(node, self._name) bound_method(*args, **kwargs) class GfxNodeListProxy(object): def __init__(self, node_list): self._nodes=node_list def __getattr__(self, name): if name.startswith('_'): return super(GfxNodeListProxy, self).__getattr__(name) return GfxNodeListAttrProxy(self._nodes, name) def __setattr__(self, name, value): if name.startswith('_'): super(GfxNodeListProxy, self).__setattr__(name, value) for node in self._nodes: setattr(node, name, value) def _Match(scene, pattern="*"): import os import fnmatch def _Recurse(path, node, pattern): matches=[] for child in node.children: full_name=os.path.join(path, child.name) if fnmatch.fnmatchcase(full_name, pattern): matches.append(child) matches.extend(_Recurse(full_name, child, pattern)) return matches return GfxNodeListProxy(_Recurse("", Scene().root_node, pattern)) SceneSingleton.__getitem__=_Match