00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 from _ost_gfx import *
00020 from py_gfx_obj import PyGfxObj
00021
00022 WHITE=RGB(1.0,1.0,1.0)
00023 BLACK=RGB(0.0,0.0,0.0)
00024 GREY=RGB(0.5,0.5,0.5)
00025 RED=RGB(1.0,0.0,0.0)
00026 DARKRED=RGB(0.5,0.0,0.0)
00027 LIGHTRED=RGB(1.0,0.5,0.5)
00028 GREEN=RGB(0.0,1.0,0.0)
00029 DARKGREEN=RGB(0.0,0.5,0.0)
00030 LIGHTGREEN=RGB(0.5,1.0,0.5)
00031 BLUE=RGB(0.0,0.0,1.0)
00032 DARKBLUE=RGB(0.0,0.0,0.5)
00033 LIGHTBLUE=RGB(0.5,0.5,1.0)
00034 YELLOW=RGB(1.0,1.0,0.0)
00035 DARKYELLOW=RGB(0.5,0.5,0.0)
00036 LIGHTYELLOW=RGB(1.0,1.0,0.5)
00037 CYAN=RGB(0.0,1.0,1.0)
00038 DARKCYAN=RGB(0.0,0.5,0.5)
00039 LIGHTCYAN=RGB(0.5,1.0,1.0)
00040 MAGENTA=RGB(1.0,0.0,1.0)
00041 DARKMAGENTA=RGB(0.5,0.0,0.5)
00042 LIGHTMAGENTA=RGB(1.0,0.5,1.0)
00043 PURPLE=MAGENTA
00044 DARKPURPLE=DARKMAGENTA
00045 LIGHTPURPLE=LIGHTMAGENTA
00046 ORANGE=RGB(1.0,0.5,0.0)
00047 DARKORANGE=RGB(0.5,0.25,0.0)
00048 LIGHTORANGE=RGB(1.0,0.75,0.5)
00049
00050 def Stereo(mode,flip=None,alg=None):
00051 """
00052 Stereo control
00053
00054 :param mode: 0=off, 1=quad-buffered, 2=interlaced
00055 :type mode: int
00056 :param flip: invert order of left/right display
00057 :type flip: bool
00058 :param alg: stereo algorithm (0 or 1)
00059 :type param: int
00060 """
00061 if(flip):
00062 Scene().SetStereoFlip(flip)
00063 if(alg):
00064 Scene().SetStereoAlg(alg)
00065
00066 Scene().SetStereoMode(mode)
00067
00068 def FitToScreen(gfx_ent, width=None, height=None, margin=0.05):
00069 """
00070 Setup camera such that it is centered on the graphical entity and the entity
00071 fits the entire viewport. The longest axes of the entity are aligned along
00072 the x- and y- axes of the screen.
00073
00074 :param gfx_ent: The graphical entity
00075 :type gfx_ent: str or :class:`Entity`
00076
00077
00078 """
00079 from ost import geom
00080 import math
00081 def _XYZ(view, axes):
00082 """
00083 returns the vectors in x, y and z direction respectively. The smallest
00084 vector is in z, then y, and the largest along x.
00085 """
00086 rows=[axes.GetRow(i) for i in range(3)]
00087 lengths=[]
00088 for axe in rows:
00089 min_proj=geom.Dot(axe, view.atoms[0].pos)
00090 max_proj=min_proj
00091 for atom in view.atoms[1:]:
00092 proj=geom.Dot(axe, atom.pos)
00093 min_proj=min(proj, min_proj)
00094 max_proj=max(proj, max_proj)
00095 lengths.append(max_proj-min_proj)
00096 def cmp_x(rhs, lhs):
00097 return cmp(lhs[1], rhs[1])
00098 sorted_axes=sorted(zip(rows, lengths), cmp_x)
00099 return [r*l for r,l in sorted_axes]
00100 scene=Scene()
00101 if not isinstance(gfx_ent, Entity):
00102 gfx_ent=scene[str(gfx_ent)]
00103 width=width and width or scene.viewport.width
00104 height=height and height or scene.viewport.height
00105 atom_positions=geom.Vec3List([atom.pos for atom in gfx_ent.view.atoms])
00106 axes=atom_positions.principal_axes
00107 sorted_axes=_XYZ(gfx_ent.view, axes)
00108 x_bigger_than_y=geom.Length(sorted_axes[0])>geom.Length(sorted_axes[1])
00109 if x_bigger_than_y:
00110 if width>height:
00111 x_axes=geom.Normalize(sorted_axes[0])
00112 y_axes=geom.Normalize(sorted_axes[1])
00113 else:
00114 x_axes=geom.Normalize(sorted_axes[1])
00115 y_axes=geom.Normalize(sorted_axes[0])
00116 else:
00117 if width>height:
00118 x_axes=geom.Normalize(sorted_axes[1])
00119 y_axes=geom.Normalize(sorted_axes[0])
00120 else:
00121 x_axes=geom.Normalize(sorted_axes[0])
00122 y_axes=geom.Normalize(sorted_axes[1])
00123 z_axes=geom.Normalize(geom.Cross(x_axes, y_axes))
00124 rotation=geom.Mat3(x_axes[0], x_axes[1], x_axes[2],
00125 y_axes[0], y_axes[1], y_axes[2],
00126 z_axes[0], z_axes[1], z_axes[2])
00127 rtc=geom.Mat4(rotation)
00128
00129 center=gfx_ent.center
00130 aspect=float(width)/float(height)
00131 factor_y=1.0/math.tan(math.radians(scene.fov))
00132 factor_x=factor_y/aspect
00133 z_off=geom.Length(sorted_axes[2])*0.5
00134 rtc[0,3]=center[0]
00135 rtc[1,3]=center[1]
00136 rtc[2,3]=center[2]
00137 rtc[3,0]=0
00138 rtc[3,1]=0
00139 rtc[3,2]=-(max(factor_x*(1+margin)*geom.Length(sorted_axes[0]),
00140 factor_y*(1+margin)*geom.Length(sorted_axes[1]))+z_off)
00141 scene.SetRTC(rtc)
00142
00143
00144 class GfxNodeListAttrProxy:
00145 def __init__(self, node_list, name):
00146 self._node_list=node_list
00147 self._name=name
00148
00149 def __iter__(self):
00150 for node in self._node_list:
00151 yield getattr(node, self._name)
00152
00153 def __call__(self, *args, **kwargs):
00154 for node in self._node_list:
00155 bound_method=getattr(node, self._name)
00156 bound_method(*args, **kwargs)
00157
00158 class GfxNodeListProxy(object):
00159 def __init__(self, node_list):
00160 self._nodes=node_list
00161
00162 def __getattr__(self, name):
00163 if name.startswith('_'):
00164 return super(GfxNodeListProxy, self).__getattr__(name)
00165 return GfxNodeListAttrProxy(self._nodes, name)
00166
00167 def __setattr__(self, name, value):
00168 if name.startswith('_'):
00169 super(GfxNodeListProxy, self).__setattr__(name, value)
00170 for node in self._nodes:
00171 setattr(node, name, value)
00172
00173 def _Match(scene, pattern="*"):
00174 import os
00175 import fnmatch
00176 def _Recurse(path, node, pattern):
00177 matches=[]
00178 for child in node.children:
00179 full_name=os.path.join(path, child.name)
00180 if fnmatch.fnmatchcase(full_name, pattern):
00181 matches.append(child)
00182 matches.extend(_Recurse(full_name, child, pattern))
00183 return matches
00184 return GfxNodeListProxy(_Recurse("", Scene().root_node, pattern))
00185
00186 SceneSingleton.Match=_Match
00187
00188 def _to_vec3(p):
00189 import ost.geom
00190 if isinstance(p,ost.geom.Vec3):
00191 return p
00192 else:
00193 try:
00194 return ost.geom.Vec3(p[0],p[1],p[2])
00195 except:
00196 raise TypeError("expected either a sequence or a geom.Vec3 object")
00197
00198
00199 def _primlist_add_point(self,pos,color=None):
00200 pos=_to_vec3(pos)
00201 if not color:
00202 color=WHITE
00203 self._add_point(pos,color)
00204
00205 def _primlist_add_line(self,pos1,pos2,color1=None,color2=None,color=None):
00206 pos1=_to_vec3(pos1)
00207 pos2=_to_vec3(pos2)
00208 if not color:
00209 color=WHITE
00210 if not color1:
00211 color1=color
00212 if not color2:
00213 color2=color1
00214 self._add_line(pos1,pos2,color1,color2)
00215
00216 def _primlist_add_sphere(self,cen,radius=1.0,color=None):
00217 pos=_to_vec3(cen)
00218 if not color:
00219 color=WHITE
00220 self._add_sphere(pos,radius,color)
00221
00222 def _primlist_add_cyl(self,pos1,pos2,radius1=None,radius2=None,radius=None,color1=None,color2=None,color=None,):
00223 pos1=_to_vec3(pos1)
00224 pos2=_to_vec3(pos2)
00225 if radius is None:
00226 radius=1.0
00227 if radius1 is None:
00228 radius1=radius
00229 if radius2 is None:
00230 radius2=radius1
00231 if not color:
00232 color=WHITE
00233 if not color1:
00234 color1=color
00235 if not color2:
00236 color2=color1
00237 self._add_cyl(pos1,pos2,radius1,radius2,color1,color2)
00238
00239 def _primlist_add_text(self,text,pos,color=None,point_size=None):
00240 pos=_to_vec3(pos)
00241 if not color:
00242 color=WHITE
00243 if not point_size:
00244 point_size=1.0
00245 self._add_text(text,pos,color,point_size)
00246
00247 PrimList.AddPoint=_primlist_add_point
00248 PrimList.AddLine=_primlist_add_line
00249 PrimList.AddSphere=_primlist_add_sphere
00250 PrimList.AddCyl=_primlist_add_cyl
00251 PrimList.AddText=_primlist_add_text
00252
00253
00254
00255 def _entity_reset(self,*args,**kwargs):
00256 import ost.mol as mol
00257 eh=None
00258 ev=None
00259 qr=None
00260 qf=None
00261 for a in args:
00262 if isinstance(a,mol.Query):
00263 if qr:
00264 raise TypeError("Reset: more than one query string given")
00265 qr=a
00266 elif isinstance(a,mol.EntityHandle):
00267 if eh:
00268 raise TypeError("Reset: more than one entity handle given")
00269 eh=a
00270 elif isinstance(a,mol.EntityView):
00271 if ev:
00272 raise TypeError("Reset: more than one entity view given")
00273 ev=a
00274 elif isinstance(a,str):
00275 if qr:
00276 raise TypeError("Reset: more than one query string given")
00277 qr=mol.Query(a)
00278 elif isinstance(a,int):
00279 if qf:
00280 raise TypeError("Reset: more than one QueryFlags given")
00281 qf=a
00282 else:
00283 raise TypeError("Reset: unknown option of type '%s' given"%type(a))
00284
00285 for key,val in kwargs.iteritems():
00286 if key=="entity":
00287 if not isinstance(val,mol.EntityHandle):
00288 raise TypeError("Reset: expected mol.EntityHandle for 'entity' option")
00289 if eh:
00290 raise TypeError("Reset: more than one entity handle given")
00291 eh=val
00292 elif key=="view":
00293 if not isinstance(val,mol.EntityView):
00294 raise TypeError("Reset: expected mol.EntityView for 'view' option")
00295 if ev:
00296 raise TypeError("Reset: more than one entity view given")
00297 ev=val
00298 elif key=="query":
00299 if isinstance(val,mol.Query):
00300 pass
00301 elif isinstance(val,str):
00302 val=mol.Query(val)
00303 else:
00304 raise TypeError("Reset: expected mol.Query or string for 'query' option")
00305 if qr:
00306 raise TypeError("Reset: more than one query string given")
00307 qr=val
00308 elif key=="query_flags":
00309 if not isinstance(val,int):
00310 raise TypeError("Reset: expected integer for 'query_flags' option")
00311 if qf:
00312 raise TypeError("Reset: more than one query flags given")
00313 qf=val
00314 else:
00315 raise TypeError("Reset: unknown key '%s'"%key)
00316
00317 if eh and ev:
00318 raise TypeError("Reset: entity and view are mutually exclusive options")
00319
00320 if ev:
00321 self._reset4(ev)
00322 else:
00323 if not eh:
00324 eh = self.query_view.entity
00325 if not qr:
00326 qr = self.query_view.query
00327 if not qf:
00328 qf = self.query_view.GetFlags()
00329 self._reset3(eh,qr,qf)
00330
00331 Entity.Reset=_entity_reset
00332
00333 def _scene_export(self,*args,**kwargs):
00334 """
00335 scene.Export(Exporter)
00336 scene.Export("file.png")
00337 scene.Export("file.png",(width,height),samples=0,transparency=False)
00338 deprecated:
00339 scene.Export("file.png",width,height,samples=0,transparency=False)
00340 scene.Export("file.png",width,height,transparency)
00341 """
00342 scene=Scene()
00343 tp=False
00344 sa=0
00345 if "tp" in kwargs:
00346 tp=int(kwargs["tp"])
00347 if "transparency" in kwargs:
00348 tp=int(kwargs["transparency"])
00349 if "samples" in kwargs:
00350 sa=int(kwargs["samples"])
00351
00352 if len(args)==1:
00353 if isinstance(args[0],Exporter):
00354 scene._export_via_exporter(args[0])
00355 return
00356 elif type(args[0])==type(""):
00357 scene._export_screen(args[0],tp)
00358 return
00359 elif len(args)==2:
00360 if type(args[0]==type("")):
00361
00362 width=int(args[1][0])
00363 height=int(args[1][1])
00364 scene._export_buffer(args[0],width,height,sa,tp)
00365 return
00366 elif len(args)==3:
00367 if type(args[0]==type("")):
00368 width=int(args[1])
00369 height=int(args[2])
00370 scene._export_buffer(args[0],width,height,sa,tp)
00371 return
00372 elif len(args)==4:
00373 if type(args[0]==type("")):
00374 width=int(args[1])
00375 height=int(args[2])
00376 tp=int(args[3])
00377 scene._export_buffer(args[0],width,height,sa,tp)
00378 return
00379
00380 raise RuntimeError("""invalid arguments to scene.Export; expected one of
00381 Export(gfx.Exporter)
00382 Export('file.png')
00383 Export('file.png',(width,height),samples=0, transparency=False)
00384 Export('file.png',width,height,samples=0, transparency=False) -> deprecated
00385 Export('file.png',width,height,transparency) -> deprecated
00386 """)
00387
00388 SceneSingleton.Export=_scene_export
00389
00390 import __main__ as main_mod
00391 main_mod.scene=Scene()
00392 main_mod.scene.Stereo=Stereo
00393
00394 import ost as ost_mod
00395 ost_mod.scene=Scene()
00396 ost_mod.scene.Stereo=Stereo
00397
00398 def GostExporter(file,scale=1.0,to_origin=True):
00399 e=GostExporter_(file)
00400 e.scale=scale
00401 e.to_origin=to_origin
00402 return e
00403
00404 def ColladaExporter(file,scale=1.0,to_origin=True):
00405 e=ColladaExporter_(file)
00406 e.scale=scale
00407 e.to_origin=to_origin
00408 return e
00409
00410 def _go_get_vis(go):
00411 return go.IsVisible()
00412
00413 def _go_set_vis(go,flag):
00414 if flag:
00415 go.Show()
00416 else:
00417 go.Hide()
00418
00419 GfxObj.visible=property(_go_get_vis,_go_set_vis)
00420
00421