2424 'event_return' , 'extrusion' , 'faces' , 'frame' , 'gcurve' , 'gdots' ,
2525 'ghbars' , 'gobj' , 'graph' , 'gvbars' , 'helix' , 'label' ,
2626 'local_light' , 'menu' , 'meta_canvas' , 'points' , 'pyramid' ,
27- 'quad' , 'radio' , 'ring' , 'simple_sphere' , 'sleep' , 'slider' , 'sphere' ,
27+ 'quad' , 'radio' , 'ring' , 'set_browser' , ' simple_sphere' , 'sleep' , 'slider' , 'sphere' ,
2828 'standardAttributes' , 'text' , 'textures' , 'triangle' , 'vertex' ,
29- 'wtext' , 'winput' , 'keysdown' ]
29+ 'wtext' , 'winput' ]
3030
3131__p = platform .python_version ()
3232_ispython3 = (__p [0 ] == '3' )
4040version = [__version__ , 'jupyter' ]
4141GSversion = [__gs_version__ , 'glowscript' ]
4242
43- keysdownlist = [] # list of keys currently pressed
44-
4543# To print immediately, do this:
4644# print(.....)
4745# sys.stdout.flush()
9795 'right' :'q' , 'top' :'r' , 'bottom' :'s' , '_cloneid' :'t' ,
9896 'logx' :'u' , 'logy' :'v' , 'dot' :'w' , 'dot_radius' :'x' ,
9997 'markers' :'y' , 'legend' :'z' , 'label' :'A' , 'delta' :'B' , 'marker_color' :'C' ,
100- 'size_units' :'D' , 'userpan' :'E' , 'scroll' : 'F' }
98+ 'size_units' :'D' , 'userpan' :'E' }
10199
102100# methods are X in {'m': '23X....'}
103101# pos is normally updated as an attribute, but for interval-based trails, it is updated (multiply) as a method
@@ -524,7 +522,7 @@ class standardAttributes(baseObj):
524522 ['visible' ],
525523 []],
526524 'compound' :[['pos' , 'color' , 'trail_color' ],
527- ['axis' , 'size' , 'up' , 'origin' ],
525+ ['axis' , 'size' , 'up' ],
528526 ['visible' , 'opacity' ,'shininess' , 'emissive' ,
529527 'make_trail' , 'trail_type' , 'interval' , 'texture' ,
530528 'retain' , 'trail_color' , 'trail_radius' , 'obj_idxs' , 'pickable' ],
@@ -700,7 +698,7 @@ def setup(self, args):
700698
701699
702700 # set canvas
703- if self .canvas is None : ## not specified in constructor
701+ if self .canvas == None : ## not specified in constructor
704702 self .canvas = canvas .get_selected ()
705703 #cmd["attrs"].append({"attr": 'canvas', "value": self.canvas.idx})
706704 cmd ['canvas' ] = self .canvas .idx
@@ -713,7 +711,7 @@ def setup(self, args):
713711 if _special_clone is not None : cmd ["_cloneid" ] = _special_clone
714712 self .appendcmd (cmd )
715713
716- # if ('frame' in args and args['frame'] is not None):
714+ # if ('frame' in args and args['frame'] != None):
717715 # frame.objects.append(self)
718716 # frame.update_obj_list()
719717
@@ -1001,9 +999,9 @@ def rotate(self, angle=None, axis=None, origin=None):
1001999 saveorigin = origin
10021000 if angle == 0 :
10031001 return
1004- if angle is None :
1002+ if angle == None :
10051003 raise TypeError ('You must specify an angle through which to rotate' )
1006- if axis is None :
1004+ if axis == None :
10071005 rotaxis = self .axis
10081006 else :
10091007 rotaxis = axis
@@ -1530,34 +1528,32 @@ def size(self,value): # compound axis and size don't interact
15301528 if not self ._constructing :
15311529 self .addattr ('size' )
15321530
1533- @property
1534- def origin (self ):
1535- return self ._origin
1536- @origin .setter
1537- def origin (self ,value ): # compound origin cannot be reset
1538- if not self ._constructing :
1539- raise AttributeError ('The compound "origin" attribute is read-only; change "pos" instead.' )
1540- self ._origin = value
1531+ def _world_zaxis (self ):
1532+ axis = self ._axis
1533+ up = norm (self ._up )
1534+ if abs (axis .dot (up )) / sqrt (axis .mag2 ) > 0.98 :
1535+ if abs (norm (axis ).dot (vector (- 1 ,0 ,0 ))) > 0.98 :
1536+ z_axis = axis .cross (vector (0 ,0 ,1 )).norm ()
1537+ else :
1538+ z_axis = axis .cross (vector (- 1 ,0 ,0 )).norm ()
1539+ else :
1540+ z_axis = axis .cross (up ).norm ()
1541+ return z_axis
15411542
15421543 def world_to_compound (self , v ):
1543- v = v - self ._pos
1544- x_axis = self ._axis .hat
1545- y_axis = self ._up .hat
1546- z_axis = x_axis .cross (y_axis )
1547- ox = self ._size0 .x / self ._size .x # _size0 is the original size
1548- oy = self ._size0 .y / self ._size .y
1549- oz = self ._size0 .z / self ._size .z
1550- return self ._origin + vector (v .dot (x_axis )* ox , v .dot (y_axis )* oy , v .dot (z_axis )* oz )
1544+ axis = self ._axis
1545+ z_axis = self ._world_zaxis ()
1546+ y_axis = z_axis .cross (axis ).norm ()
1547+ x_axis = axis .norm ()
1548+ v = v - self ._pos
1549+ return vector (v .dot (x_axis ), v .dot (y_axis ), v .dot (z_axis ))
15511550
15521551 def compound_to_world (self , v ):
1553- v = v - self ._origin
1554- x_axis = self ._axis .hat
1555- y_axis = self ._up .hat
1556- z_axis = x_axis .cross (y_axis )
1557- ox = self ._size .x / self ._size0 .x # _size0 is the original size
1558- oy = self ._size .y / self ._size0 .y
1559- oz = self ._size .z / self ._size0 .z
1560- return self ._pos + v .x * ox * x_axis + v .y * oy * y_axis + v .z * oz * z_axis
1552+ axis = self ._axis
1553+ z_axis = self ._world_zaxis ()
1554+ y_axis = z_axis .cross (axis ).norm ()
1555+ x_axis = axis .norm ()
1556+ return self ._pos + (v .x * x_axis ) + (v .y * y_axis ) + (v .z * z_axis )
15611557
15621558class vertex (standardAttributes ):
15631559 def __init__ (self , ** args ):
@@ -1965,7 +1961,7 @@ def __init__(self,*args1, **args):
19651961
19661962 super (curveMethods , self ).setup (args )
19671963
1968- if tpos is not None :
1964+ if tpos != None :
19691965 if len (args1 ) > 0 : raise AttributeError ('Malformed constructor' )
19701966 self .append (tpos )
19711967 if len (args1 ) > 0 :
@@ -1989,7 +1985,7 @@ def __init__(self,*args1, **args):
19891985
19901986 super (curveMethods , self ).setup (args )
19911987
1992- if tpos is not None :
1988+ if tpos != None :
19931989 if len (args1 ) > 0 : raise AttributeError ('Malformed constructor' )
19941990 self .append (tpos )
19951991 if len (args1 ) > 0 :
@@ -2282,7 +2278,6 @@ def __init__(self, **args):
22822278 self ._title = ""
22832279 self ._xtitle = ""
22842280 self ._ytitle = ""
2285- self ._scroll = False
22862281 argsToSend = []
22872282
22882283 ## override default vector attributes
@@ -2297,7 +2292,7 @@ def __init__(self, **args):
22972292
22982293 ## override default scalar attributes
22992294 scalarAttributes = ['width' , 'height' , 'title' , 'xtitle' , 'ytitle' ,'align' ,
2300- 'xmin' , 'xmax' , 'ymin' , 'ymax' , 'logx' , 'logy' , 'fast' , 'scroll' ]
2295+ 'xmin' , 'xmax' , 'ymin' , 'ymax' , 'logx' , 'logy' , 'fast' ]
23012296 for a in scalarAttributes :
23022297 if a in args :
23032298 argsToSend .append (a )
@@ -2310,12 +2305,6 @@ def __init__(self, **args):
23102305
23112306 cmd = {"cmd" : objName , "idx" : self .idx }
23122307
2313- if self ._scroll :
2314- if not ('xmin' in argsToSend and 'xmax' in argsToSend ):
2315- raise AttributeError ("For a scrolling graph, both xmin and xmax must be specified." )
2316- if self ._xmax <= self ._xmin :
2317- raise AttributeError ("For a scrolling graph, xmax must be greater than xmin." )
2318-
23192308 ## send only args specified in constructor
23202309 for a in argsToSend :
23212310 aval = getattr (self ,a )
@@ -2329,16 +2318,11 @@ def __init__(self, **args):
23292318 def fast (self ): return self ._fast
23302319 @fast .setter
23312320 def fast (self ,val ):
2321+ # if _isnotebook and not val:
2322+ # raise AttributeError('"fast = False" is currently not available in a Jupyter notebook.')
23322323 self ._fast = val
23332324 self .addattr ('fast' )
23342325
2335- @property
2336- def scroll (self ): return self ._scroll
2337- @scroll .setter
2338- def scroll (self ,val ):
2339- self ._scroll = val
2340- self .addattr ('scroll' )
2341-
23422326 @property
23432327 def width (self ): return self ._width
23442328 @width .setter
@@ -2830,7 +2814,7 @@ def __init__(self, **args):
28302814
28312815 for a in canvasNonVecAttrs :
28322816 if a in args :
2833- if args [a ] is not None :
2817+ if args [a ] != None :
28342818 setattr (self , '_' + a , args [a ])
28352819 cmd [a ]= args [a ]
28362820 del args [a ]
@@ -3115,13 +3099,11 @@ def objz(self, obj, operation):
31153099
31163100## key events conflict with notebook command mode; not permitted for now
31173101 def handle_event (self , evt ): ## events and scene info updates
3118- global keysdownlist
31193102 ev = evt ['event' ]
31203103 if ev == 'pick' :
31213104 self .mouse .setpick ( evt )
31223105 self ._waitfor = True # what pick is looking for
31233106 elif ev == '_compound' : # compound, text, extrusion
3124- print ('compound event return' )
31253107 obj = self ._compound
31263108 p = evt ['pos' ]
31273109 if obj ._objName == 'text' :
@@ -3133,7 +3115,7 @@ def handle_event(self, evt): ## events and scene info updates
31333115 # on_change functions that detect changes in e.g. obj.pos.y
31343116 obj ._pos .value = list_to_vec (p )
31353117 s = evt ['size' ]
3136- obj ._size .value = obj . _size0 = list_to_vec (s )
3118+ obj ._size .value = list_to_vec (s )
31373119 obj ._axis .value = obj ._size ._x * norm (obj ._axis )
31383120 obj ._up .value = list_to_vec (evt ['up' ])
31393121 self ._waitfor = True # what compound and text and extrusion are looking for in _wait()
@@ -3200,8 +3182,6 @@ def handle_event(self, evt): ## events and scene info updates
32003182 if 'autoscale' in evt and self .userzoom and not self ._set_autoscale :
32013183 self ._autoscale = evt ['autoscale' ]
32023184 self ._set_autoscale = False
3203- if 'keysdown' in evt : keysdownlist = evt ['keysdown' ]
3204-
32053185
32063186 def bind (self , eventtype , whattodo ):
32073187 evts = eventtype .split ()
@@ -3275,7 +3255,7 @@ def __init__(self, **args):
32753255 args ['_objName' ] = "local_light"
32763256 super (local_light , self ).setup (args )
32773257
3278- if (canvas .get_selected () is not None ):
3258+ if (canvas .get_selected () != None ):
32793259 canvas .get_selected ()._lights .append (self )
32803260
32813261class distant_light (standardAttributes ):
@@ -3285,7 +3265,7 @@ def __init__(self, **args):
32853265 self ._direction = vector (0 ,0 ,1 )
32863266 super (distant_light , self ).setup (args )
32873267
3288- if (canvas .get_selected () is not None ):
3268+ if (canvas .get_selected () != None ):
32893269 canvas .get_selected ()._lights .append (self )
32903270
32913271 @property
@@ -4112,9 +4092,11 @@ def print_to_string(*args): # treatment of <br> vs. \n not quite right here
41124092 s = s [:- 1 ]
41134093 return (s )
41144094
4115- def keysdown ():
4116- global keysdownlist
4117- keys = []
4118- for k in keysdownlist : # return a copy of keysdownlist
4119- keys .append (k )
4120- return keys
4095+ # global variable for type of web browser to display vpython
4096+ _browsertype = 'default'
4097+ def set_browser (type = 'default' ):
4098+ global _browsertype
4099+ if type == 'pyqt' :
4100+ _browsertype = 'pyqt'
4101+ else :
4102+ _browsertype = 'default'
0 commit comments