@@ -52,7 +52,53 @@ proto.handlePick = function(selection) {
5252} ;
5353
5454function parseColorArray ( colors ) {
55- return colors . map ( str2RgbaArray ) ;
55+ var b = [ ] ;
56+ var len = colors . length ;
57+ for ( var i = 0 ; i < len ; i ++ ) {
58+ b [ i ] = str2RgbaArray ( colors [ i ] ) ;
59+ }
60+ return b ;
61+ }
62+
63+ // Unpack position data
64+ function toDataCoords ( axis , coord , scale , calendar ) {
65+ var b = [ ] ;
66+ var len = coord . length ;
67+ for ( var i = 0 ; i < len ; i ++ ) {
68+ b [ i ] = axis . d2l ( coord [ i ] , 0 , calendar ) * scale ;
69+ }
70+ return b ;
71+ }
72+
73+ // Round indices if passed as floats
74+ function toRoundIndex ( a ) {
75+ var b = [ ] ;
76+ var len = a . length ;
77+ for ( var i = 0 ; i < len ; i ++ ) {
78+ b [ i ] = Math . round ( a [ i ] ) ;
79+ }
80+ return b ;
81+ }
82+
83+ function delaunayCells ( delaunayaxis , positions ) {
84+ var d = [ 'x' , 'y' , 'z' ] . indexOf ( delaunayaxis ) ;
85+ var b = [ ] ;
86+ var len = positions . length ;
87+ for ( var i = 0 ; i < len ; i ++ ) {
88+ b [ i ] = [ positions [ i ] [ ( d + 1 ) % 3 ] , positions [ i ] [ ( d + 2 ) % 3 ] ] ;
89+ }
90+ return triangulate ( b ) ;
91+ }
92+
93+ // Validate indices
94+ function hasValidIndices ( list , numVertices ) {
95+ var len = list . length ;
96+ for ( var i = 0 ; i < len ; i ++ ) {
97+ if ( list [ i ] <= - 0.5 || list [ i ] >= numVertices - 0.5 ) { // Note: the indices would be rounded -0.49 is valid.
98+ return false ;
99+ }
100+ }
101+ return true ;
56102}
57103
58104proto . update = function ( data ) {
@@ -61,33 +107,37 @@ proto.update = function(data) {
61107
62108 this . data = data ;
63109
64- // Unpack position data
65- function toDataCoords ( axis , coord , scale , calendar ) {
66- return coord . map ( function ( x ) {
67- return axis . d2l ( x , 0 , calendar ) * scale ;
68- } ) ;
69- }
110+ var numVertices = data . x . length ;
70111
71112 var positions = zip3 (
72113 toDataCoords ( layout . xaxis , data . x , scene . dataScale [ 0 ] , data . xcalendar ) ,
73114 toDataCoords ( layout . yaxis , data . y , scene . dataScale [ 1 ] , data . ycalendar ) ,
74- toDataCoords ( layout . zaxis , data . z , scene . dataScale [ 2 ] , data . zcalendar ) ) ;
115+ toDataCoords ( layout . zaxis , data . z , scene . dataScale [ 2 ] , data . zcalendar )
116+ ) ;
75117
76118 var cells ;
77119 if ( data . i && data . j && data . k ) {
78- cells = zip3 ( data . i , data . j , data . k ) ;
79- }
80- else if ( data . alphahull === 0 ) {
120+
121+ if (
122+ data . i . length !== data . j . length ||
123+ data . j . length !== data . k . length ||
124+ ! hasValidIndices ( data . i , numVertices ) ||
125+ ! hasValidIndices ( data . j , numVertices ) ||
126+ ! hasValidIndices ( data . k , numVertices )
127+ ) {
128+ return ;
129+ }
130+ cells = zip3 (
131+ toRoundIndex ( data . i ) ,
132+ toRoundIndex ( data . j ) ,
133+ toRoundIndex ( data . k )
134+ ) ;
135+ } else if ( data . alphahull === 0 ) {
81136 cells = convexHull ( positions ) ;
82- }
83- else if ( data . alphahull > 0 ) {
137+ } else if ( data . alphahull > 0 ) {
84138 cells = alphaShape ( data . alphahull , positions ) ;
85- }
86- else {
87- var d = [ 'x' , 'y' , 'z' ] . indexOf ( data . delaunayaxis ) ;
88- cells = triangulate ( positions . map ( function ( c ) {
89- return [ c [ ( d + 1 ) % 3 ] , c [ ( d + 2 ) % 3 ] ] ;
90- } ) ) ;
139+ } else {
140+ cells = delaunayCells ( data . delaunayaxis , positions ) ;
91141 }
92142
93143 var config = {
@@ -113,16 +163,13 @@ proto.update = function(data) {
113163 config . vertexIntensity = data . intensity ;
114164 config . vertexIntensityBounds = [ data . cmin , data . cmax ] ;
115165 config . colormap = parseColorScale ( data . colorscale ) ;
116- }
117- else if ( data . vertexcolor ) {
166+ } else if ( data . vertexcolor ) {
118167 this . color = data . vertexcolor [ 0 ] ;
119168 config . vertexColors = parseColorArray ( data . vertexcolor ) ;
120- }
121- else if ( data . facecolor ) {
169+ } else if ( data . facecolor ) {
122170 this . color = data . facecolor [ 0 ] ;
123171 config . cellColors = parseColorArray ( data . facecolor ) ;
124- }
125- else {
172+ } else {
126173 this . color = data . color ;
127174 config . meshColor = str2RgbaArray ( data . color ) ;
128175 }
0 commit comments