13
13
import sys
14
14
from . import __version__ , __gs_version__
15
15
from ._notebook_helpers import _isnotebook
16
- from ._vector_import_helper import (vector , mag , norm , cross , dot , adjust_up ,
16
+ from ._vector_import_helper import (vector , mag , norm , dot , adjust_up ,
17
17
adjust_axis , object_rotate )
18
18
19
19
# List of names that will be imported from this file with import *
97
97
'right' :'q' , 'top' :'r' , 'bottom' :'s' , '_cloneid' :'t' ,
98
98
'logx' :'u' , 'logy' :'v' , 'dot' :'w' , 'dot_radius' :'x' ,
99
99
'markers' :'y' , 'legend' :'z' , 'label' :'A' , 'delta' :'B' , 'marker_color' :'C' ,
100
- 'size_units' :'D' , 'userpan' :'E' , 'scroll' :'F' , 'choices' : 'G' , 'depth' : 'H' }
100
+ 'size_units' :'D' , 'userpan' :'E' , 'scroll' :'F' }
101
101
102
102
# methods are X in {'m': '23X....'}
103
103
# pos is normally updated as an attribute, but for interval-based trails, it is updated (multiply) as a method
113
113
'marker_color' ]
114
114
115
115
__textattrs = ['text' , 'align' , 'caption' , 'title' , 'xtitle' , 'ytitle' , 'selected' , 'label' , 'capture' ,
116
- 'append_to_caption' , 'append_to_title' , 'bind' , 'unbind' , 'pause' , 'GSprint' , 'choices' ]
116
+ 'append_to_caption' , 'append_to_title' , 'bind' , 'unbind' , 'pause' , 'GSprint' ]
117
117
118
118
def _encode_attr2 (sendval , val , ismethods ):
119
119
s = ''
@@ -129,10 +129,8 @@ def _encode_attr2(sendval, val, ismethods):
129
129
s += "{:.16G}," .format (p )
130
130
s = s [:- 1 ]
131
131
elif sendval == 'plot' or sendval == 'data' :
132
- if sendval == 'data' and len (val ) == 0 : s += "None, None,"
133
- else :
134
- for p in val :
135
- s += "{:.16G},{:.16G}," .format (p [0 ], p [1 ])
132
+ for p in val :
133
+ s += "{:.16G},{:.16G}," .format (p [0 ], p [1 ])
136
134
s = s [:- 1 ]
137
135
elif sendval in ['v0' , 'v1' , 'v2' , 'v3' ]: # val is the vertex object referenced by triangle or quad
138
136
s += str (val .idx )
@@ -330,10 +328,10 @@ def __del__(self):
330
328
# Now there is no threading in Jupyter VPython. Data is sent to the
331
329
# browser from the trigger() function, which is called by a
332
330
# canvas_update event sent to Python from the browser (glowcomm.js), currently
333
- # every 17 milliseconds. When trigger() is called, it immediately signals
334
- # the browser to set a timeout of 17 ms to send another signal to Python.
331
+ # every 33 milliseconds. When trigger() is called, it immediately signals
332
+ # the browser to set a timeout of 33 ms to send another signal to Python.
335
333
# Note that a typical VPython program starts out by creating objects (constructors) and
336
- # specifying their attributes. The 17 ms signal from the browser is adequate to ensure
334
+ # specifying their attributes. The 33 ms signal from the browser is adequate to ensure
337
335
# prompt data transmissions to the browser.
338
336
339
337
# The situation with non-notebook use is similar, but the http server is threaded,
@@ -402,10 +400,9 @@ def handle_close(self, data):
402
400
def _wait (cvs ): # wait for an event
403
401
cvs ._waitfor = None
404
402
if _isnotebook : baseObj .trigger () # in notebook environment must send methods immediately
405
- t = clock ()
406
403
while cvs ._waitfor is None :
407
- rate (100 )
408
- if _isnotebook : baseObj . trigger () # restart activity in glowcomm.html
404
+ rate (30 )
405
+ return cvs . _waitfor
409
406
410
407
class color (object ):
411
408
black = vector (0 ,0 ,0 )
@@ -587,7 +584,6 @@ def setup(self, args):
587
584
del args ['_objName' ]
588
585
589
586
# default values
590
- self ._sizing = True # axis/size connection is the default; False for sphere, ring, text, compound
591
587
self ._pos = vector (0 ,0 ,0 )
592
588
self ._axis = vector (1 ,0 ,0 )
593
589
self ._up = vector (0 ,1 ,0 )
@@ -764,52 +760,32 @@ def up(self,value):
764
760
def axis (self ):
765
761
return self ._axis
766
762
@axis .setter
767
- def axis (self ,value ): # sphere or ring or text or compound have no axis/size link
768
- currentaxis = self ._axis
769
- self ._axis = value
770
- if value .mag2 == 0 :
771
- if self ._save_oldaxis is None : self ._save_oldaxis = currentaxis
772
- else :
773
- if self ._save_oldaxis is not None :
774
- self ._save_oldaxis = adjust_up (self ._axis , value , self ._up , self ._save_oldaxis ) # this sets self._axis and self._up
763
+ def axis (self ,value ):
764
+ self ._save_oldaxis = adjust_up (self ._axis , value , self ._up , self ._save_oldaxis ) # this sets self._axis and self._up
775
765
if not self ._constructing :
776
766
self .addattr ('axis' )
777
- if self ._sizing :
778
- self ._size ._x = value .mag # changing axis length changes size.x
767
+ self ._size ._x = value .mag # changing axis length changes size.x
779
768
780
769
@property
781
770
def size (self ):
782
771
return self ._size
783
772
@size .setter
784
- def size (self ,value ): # sphere or ring or text or compound have no axis/size link
785
- currentaxis = self ._axis
786
- self ._size = value
787
- if value .x == 0 :
788
- if self ._save_oldaxis is not None :
789
- currentaxis = self ._save_oldaxis
790
- self ._save_oldaxis = None
791
- else :
792
- currentaxis = vector (1 ,0 ,0 )
773
+ def size (self ,value ):
774
+ self ._size .value = value
793
775
if not self ._constructing :
794
776
self .addattr ('size' )
795
- if self ._sizing :
796
- self ._axis = currentaxis .norm ()* value .x
777
+ a = self ._axis .norm () * value .x
778
+ if mag (self ._axis ) == 0 :
779
+ a = vector (value .x ,0 ,0 )
780
+ self ._axis .value = a # changing size changes length of axis
797
781
798
782
@property
799
783
def length (self ):
800
784
return self ._size .x
801
785
@length .setter
802
786
def length (self ,value ):
803
- if value == 0 :
804
- if self ._save_oldaxis is None : self ._save_oldaxis = vector (self ._axis .x , self ._axis .y , self ._axis .z )
805
- self ._axis = vector (0 ,0 ,0 )
806
- self ._size ._x = 0
807
- else :
808
- if self ._save_oldaxis is not None :
809
- self ._axis = self ._save_oldaxis
810
- self ._save_oldaxis = None
811
- if self ._size ._x == 0 : self .axis = vector (value , 0 , 0 )
812
- else : self .axis = value * self ._axis .norm () # this will set length
787
+ self ._axis = self ._axis .norm () * value
788
+ self ._size ._x = value
813
789
if not self ._constructing :
814
790
self .addattr ('axis' )
815
791
self .addattr ('size' )
@@ -1039,24 +1015,6 @@ def rotate(self, angle=None, axis=None, origin=None):
1039
1015
self ._pos .value = newpos
1040
1016
self .addattr ('pos' )
1041
1017
1042
- def bounding_box (self ):
1043
- centered = ['box' , 'compound' , 'ellipsoid' , 'sphere' , 'simple_sphere' , 'ring' ]
1044
- x = norm (self ._axis )
1045
- y = norm (self ._up )
1046
- z = norm (cross (x ,y ))
1047
- L = self ._size .x
1048
- H = self ._size .y
1049
- W = self ._size .z
1050
- p = vector (self ._pos ) # make a copy of pos, so changes to p won't affect the object
1051
- if self ._objName not in centered :
1052
- p = p + 0.5 * L * x # move to center
1053
- pts = []
1054
- for dx in [- L / 2 , L / 2 ]:
1055
- for dy in [- H / 2 , H / 2 ]:
1056
- for dz in [- W / 2 , W / 2 ]:
1057
- pts .append (p + dx * x + dy * y + dz * z )
1058
- return pts
1059
-
1060
1018
def _on_size_change (self ): # the vector class calls this when there's a change in x, y, or z
1061
1019
self ._axis .value = self ._axis .norm () * self ._size .x # update axis length when box.size.x is changed
1062
1020
self .addattr ('size' )
@@ -1145,7 +1103,6 @@ def __init__(self, **args):
1145
1103
args ['_default_size' ] = vector (2 ,2 ,2 )
1146
1104
args ['_objName' ] = "sphere"
1147
1105
super (sphere , self ).setup (args )
1148
- self ._sizing = False # no axis/size connection
1149
1106
1150
1107
@property
1151
1108
def radius (self ):
@@ -1236,7 +1193,6 @@ def __init__(self, **args):
1236
1193
args ['_default_size' ] = vector (0.2 ,2.2 ,2.2 )
1237
1194
args ['_objName' ] = "ring"
1238
1195
super (ring , self ).setup (args )
1239
- self ._sizing = False # no axis/size connection
1240
1196
1241
1197
@property
1242
1198
def thickness (self ):
@@ -1492,7 +1448,6 @@ def __init__(self, objList, **args):
1492
1448
self .compound_idx += 1
1493
1449
args ['_objName' ] = 'compound' + str (self .compound_idx )
1494
1450
super (compound , self ).setup (args )
1495
- self ._sizing = False # no axis/size connection
1496
1451
1497
1452
for obj in objList :
1498
1453
# GlowScript will make the objects invisible, so need not set obj.visible
@@ -1856,8 +1811,8 @@ def pop(self, *args):
1856
1811
return val
1857
1812
1858
1813
def point (self ,N ):
1859
- if N >= len (self ._pts ) or (N < 0 and - N >= len (self .pts )):
1860
- raise ValueError ('N = {} is outside the bounds 0-{} of the curve points' .format (N , len (self ._pos ) ))
1814
+ if N >= len (self ._pts ) or (N < 0 and - N > len (self ._pts )):
1815
+ raise ValueError ('N = {} is outside the bounds 0-{} of the curve points' .format (N , len (self ._pts ) - 1 ))
1861
1816
info = self ._pts [N ]
1862
1817
if 'color' not in info : info ['color' ] = self .color
1863
1818
if 'radius' not in info : info ['radius' ] = self .radius
@@ -2026,8 +1981,6 @@ def setup(self, args):
2026
1981
self ._legend = False
2027
1982
self ._interval = - 1
2028
1983
self ._graph = None
2029
- self ._visible = True
2030
- self ._data = []
2031
1984
objName = args ['_objName' ]
2032
1985
del args ['_objName' ]
2033
1986
self ._constructing = True ## calls are from constructor
@@ -2163,8 +2116,6 @@ def preresolve2(self, args):
2163
2116
raise AttributeError ("Cannot currently change color in a plot statement." )
2164
2117
if 'pos' in args :
2165
2118
return self .resolveargs (args ['pos' ])
2166
- elif 'data' in args :
2167
- return self .resolveargs (args ['data' ])
2168
2119
else :
2169
2120
raise AttributeError ("Must be plot(x,y) or plot(pos=[x,y]) or plot([x,y]) or plot([x,y], ...) or plot([ [x,y], ... ])" )
2170
2121
@@ -2173,18 +2124,8 @@ def plot(self, *args1, **args2):
2173
2124
p = self .preresolve1 (args1 )
2174
2125
else :
2175
2126
p = self .preresolve2 (args2 )
2176
- self ._data = self ._data + p
2177
2127
self .addmethod ('plot' , p )
2178
2128
2179
- @property
2180
- def visible (self ):
2181
- return self ._visible
2182
- @visible .setter
2183
- def visible (self ,value ):
2184
- self ._visible = value
2185
- if not self ._constructing :
2186
- self .addattr ('visible' )
2187
-
2188
2129
def delete (self ):
2189
2130
self .addmethod ('delete' , 'None' )
2190
2131
@@ -2881,8 +2822,7 @@ def __init__(self, **args):
2881
2822
baseObj ._canvas_constructing = False
2882
2823
2883
2824
def follow (self , obj ): ## should allow a function also
2884
- if obj is None : self .addmethod ('follow' , 'None' )
2885
- else : self .addmethod ('follow' , obj .idx )
2825
+ self .addmethod ('follow' , obj .idx )
2886
2826
2887
2827
def select (self ):
2888
2828
canvas .selected = self
@@ -3369,7 +3309,6 @@ class controls(baseObj):
3369
3309
def setup (self , args ):
3370
3310
super (controls , self ).__init__ () ## get idx, attrsupdt from baseObj
3371
3311
## default values of common attributes
3372
- self ._disabled = False
3373
3312
self ._constructing = True
3374
3313
argsToSend = []
3375
3314
objName = args ['_objName' ]
@@ -3604,8 +3543,7 @@ def choices(self):
3604
3543
return self ._choices
3605
3544
@choices .setter
3606
3545
def choices (self , value ):
3607
- self ._choices = value
3608
- self .addattr ('choices' )
3546
+ raise AttributeError ('choices cannot be modified after a menu is created' )
3609
3547
3610
3548
@property
3611
3549
def index (self ):
@@ -3889,7 +3827,6 @@ def end_face_color(self,value):
3889
3827
class text (standardAttributes ):
3890
3828
3891
3829
def __init__ (self , ** args ):
3892
- self ._sizing = False # no axis/size connection
3893
3830
args ['_default_size' ] = vector (1 ,1 ,1 ) # to keep standardAttributes happy
3894
3831
args ['_objName' ] = "text"
3895
3832
self ._height = 1 ## not derived from size
@@ -3944,10 +3881,10 @@ def axis(self):
3944
3881
return self ._axis
3945
3882
@axis .setter
3946
3883
def axis (self ,value ): # changing axis does not affect size
3947
- old = vector (self .axis )
3884
+ oldaxis = vector (self .axis )
3948
3885
u = self .up
3949
3886
self ._axis .value = value
3950
- self ._save_oldaxis = adjust_up (norm (old ), self ._axis , self ._up , self ._save_oldaxis )
3887
+ self ._save_oldaxis = adjust_up (norm (oldaxis ), self ._axis , self ._up , self ._save_oldaxis )
3951
3888
self .addattr ('axis' )
3952
3889
self .addattr ('up' )
3953
3890
@@ -3985,7 +3922,7 @@ def depth(self, val): # sign issue ??
3985
3922
if abs (val ) < 0.01 * self ._height :
3986
3923
if val < 0 : val = - 0.01 * self ._height
3987
3924
else : val = 0.01 * self ._height
3988
- self ._depth = val
3925
+ self ._depth = value
3989
3926
self .addattr ('depth' )
3990
3927
3991
3928
@property
0 commit comments