@@ -56,11 +56,23 @@ class SurfaceGeometry(BufferGeometry):
56
56
z = List (CFloat , [0 ] * 100 )
57
57
width = CInt (10 )
58
58
height = CInt (10 )
59
- width_segments = CInt (10 )
60
- height_segments = CInt (10 )
61
-
62
- @observe ('z' , 'width' , 'height' , 'width_segments' , 'height_segments' )
63
- def _update_surface (self , change ):
59
+ width_segments = CInt (10 , read_only = True )
60
+ height_segments = CInt (10 , read_only = True )
61
+
62
+ def __init__ (self , ** kwargs ):
63
+ for key in ['width_segments' , 'height_segments' ]:
64
+ if key in kwargs :
65
+ self .set_trait (key , kwargs .pop (key ))
66
+ super (SurfaceGeometry , self ).__init__ (** kwargs )
67
+ self ._update_surface ()
68
+
69
+ @observe ('z' , 'width' , 'height' )
70
+ def _on_change (self , change ):
71
+ # Only trigger automatically after initial creation
72
+ if 'position' in self .attributes :
73
+ self ._update_surface ()
74
+
75
+ def _update_surface (self ):
64
76
nx = self .width_segments + 1
65
77
ny = self .height_segments + 1
66
78
x = np .linspace (- self .width / 2 , self .width / 2 , nx )
@@ -79,12 +91,21 @@ def _update_surface(self, change):
79
91
80
92
indices = np .array (tuple (grid_indices_gen (nx , ny )), dtype = np .uint16 ).ravel ()
81
93
82
- self .attributes = {
83
- 'position' : BufferAttribute (positions ),
84
- 'index' : BufferAttribute (indices ),
85
- 'normal' : BufferAttribute (normals ),
86
- 'uv' : BufferAttribute (uvs ),
87
- }
94
+ if 'position' not in self .attributes :
95
+ # Initial values:
96
+ self .attributes = {
97
+ 'position' : BufferAttribute (positions ),
98
+ 'index' : BufferAttribute (indices ),
99
+ 'normal' : BufferAttribute (normals ),
100
+ 'uv' : BufferAttribute (uvs ),
101
+ }
102
+ else :
103
+ # We're updating
104
+ with self .hold_trait_notifications ():
105
+ self .attributes ['position' ].array = positions
106
+ self .attributes ['index' ].array = indices
107
+ self .attributes ['normal' ].array = normals
108
+ self .attributes ['uv' ].array = uvs
88
109
89
110
90
111
def SurfaceGrid (geometry , material , ** kwargs ):
@@ -104,6 +125,16 @@ def SurfaceGrid(geometry, material, **kwargs):
104
125
g = Geometry (vertices = [vertices [y * nx + x , :].tolist () for x in range (nx )])
105
126
lines .append (Line (g , material ))
106
127
128
+ def _update_lines (change ):
129
+ vertices = geometry .attributes ['position' ].array
130
+ for x in range (nx ):
131
+ g = lines [x ].geometry
132
+ g .vertices = [vertices [y * nx + x , :].tolist () for y in range (ny )]
133
+ for y in range (ny ):
134
+ g = lines [nx + y ].geometry
135
+ g .vertices = [vertices [y * nx + x , :].tolist () for x in range (nx )]
136
+ geometry .attributes ['position' ].observe (_update_lines , names = ('array' ))
137
+
107
138
return Group (children = lines , ** kwargs )
108
139
109
140
0 commit comments