11
11
var tube2mesh = require ( 'gl-streamtube3d' ) ;
12
12
var createTubeMesh = tube2mesh . createTubeMesh ;
13
13
14
- var simpleMap = require ( '../../lib' ) . simpleMap ;
14
+ var Lib = require ( '../../lib' ) ;
15
15
var parseColorScale = require ( '../../lib/gl_format_color' ) . parseColorScale ;
16
16
var zip3 = require ( '../../lib/zip3' ) ;
17
17
@@ -47,33 +47,54 @@ proto.handlePick = function(selection) {
47
47
48
48
var axisName2scaleIndex = { xaxis : 0 , yaxis : 1 , zaxis : 2 } ;
49
49
50
+ function distinctVals ( col ) {
51
+ return Lib . distinctVals ( col ) . vals ;
52
+ }
53
+
54
+ function getBoundPads ( vec ) {
55
+ var len = vec . length ;
56
+ if ( len === 1 ) {
57
+ return [ 0.5 , 0.5 ] ;
58
+ } else {
59
+ return [ vec [ 1 ] - vec [ 0 ] , vec [ len - 1 ] - vec [ len - 2 ] ] ;
60
+ }
61
+ }
62
+
50
63
function convert ( scene , trace ) {
51
64
var sceneLayout = scene . fullSceneLayout ;
52
65
var dataScale = scene . dataScale ;
66
+ var len = trace . _len ;
53
67
var tubeOpts = { } ;
54
68
55
69
function toDataCoords ( arr , axisName ) {
56
70
var ax = sceneLayout [ axisName ] ;
57
71
var scale = dataScale [ axisName2scaleIndex [ axisName ] ] ;
58
- return simpleMap ( arr , function ( v ) { return ax . d2l ( v ) * scale ; } ) ;
72
+ return Lib . simpleMap ( arr , function ( v ) { return ax . d2l ( v ) * scale ; } ) ;
59
73
}
60
74
61
- tubeOpts . vectors = zip3 (
62
- toDataCoords ( trace . u , 'xaxis' ) ,
63
- toDataCoords ( trace . v , 'yaxis' ) ,
64
- toDataCoords ( trace . w , 'zaxis' )
65
- ) ;
75
+ var u = toDataCoords ( trace . u . slice ( 0 , len ) , 'xaxis' ) ;
76
+ var v = toDataCoords ( trace . v . slice ( 0 , len ) , 'yaxis' ) ;
77
+ var w = toDataCoords ( trace . w . slice ( 0 , len ) , 'zaxis' ) ;
66
78
67
- // TODO make this optional?
68
- // N.B. this is a "meshgrid" but shouldn't this be the position
69
- // of the vector field ???
70
- tubeOpts . meshgrid = [
71
- toDataCoords ( trace . x , 'xaxis' ) ,
72
- toDataCoords ( trace . y , 'yaxis' ) ,
73
- toDataCoords ( trace . z , 'zaxis' )
74
- ] ;
79
+ tubeOpts . vectors = zip3 ( u , v , w ) ;
80
+
81
+ var valsx = distinctVals ( trace . x . slice ( 0 , len ) ) ;
82
+ var valsy = distinctVals ( trace . y . slice ( 0 , len ) ) ;
83
+ var valsz = distinctVals ( trace . z . slice ( 0 , len ) ) ;
84
+
85
+ // Over-specified mesh case, this would error in tube2mesh
86
+ if ( valsx . length * valsy . length * valsz . length > len ) {
87
+ return { positions : [ ] , cells : [ ] } ;
88
+ }
89
+
90
+ var meshx = toDataCoords ( valsx , 'xaxis' ) ;
91
+ var meshy = toDataCoords ( valsy , 'yaxis' ) ;
92
+ var meshz = toDataCoords ( valsz , 'zaxis' ) ;
93
+
94
+ tubeOpts . meshgrid = [ meshx , meshy , meshz ] ;
75
95
76
96
// TODO make this optional?
97
+ // Default to in-between x/y/z mesh
77
98
tubeOpts . startingPositions = zip3 (
78
99
toDataCoords ( trace . startx , 'xaxis' ) ,
79
100
toDataCoords ( trace . starty , 'yaxis' ) ,
@@ -87,12 +108,19 @@ function convert(scene, trace) {
87
108
88
109
tubeOpts . tubeSize = trace . sizeref ;
89
110
111
+ // add some padding around the bounds
112
+ // to e.g. allow tubes starting from a slice of the x/y/z mesh
113
+ // to go beyond bounds a little bit w/o getting clipped
90
114
var xbnds = toDataCoords ( trace . _xbnds , 'xaxis' ) ;
91
115
var ybnds = toDataCoords ( trace . _ybnds , 'yaxis' ) ;
92
116
var zbnds = toDataCoords ( trace . _zbnds , 'zaxis' ) ;
117
+ var xpads = getBoundPads ( meshx ) ;
118
+ var ypads = getBoundPads ( meshy ) ;
119
+ var zpads = getBoundPads ( meshz ) ;
120
+
93
121
var bounds = [
94
- [ xbnds [ 0 ] , ybnds [ 0 ] , zbnds [ 0 ] ] ,
95
- [ xbnds [ 1 ] , ybnds [ 1 ] , zbnds [ 1 ] ]
122
+ [ xbnds [ 0 ] - xpads [ 0 ] , ybnds [ 0 ] - ypads [ 0 ] , zbnds [ 0 ] - zpads [ 0 ] ] ,
123
+ [ xbnds [ 1 ] + xpads [ 1 ] , ybnds [ 1 ] + ypads [ 1 ] , zbnds [ 1 ] + zpads [ 1 ] ]
96
124
] ;
97
125
98
126
var meshData = tube2mesh ( tubeOpts , bounds ) ;
@@ -103,14 +131,22 @@ function convert(scene, trace) {
103
131
meshData . vertexIntensityBounds = [ trace . cmin / trace . _normMax , trace . cmax / trace . _normMax ] ;
104
132
105
133
// pass gl-mesh3d lighting attributes
106
- meshData . lightPosition = [ trace . lightposition . x , trace . lightposition . y , trace . lightposition . z ] ;
134
+ var lp = trace . lightposition ;
135
+ meshData . lightPosition = [ lp . x , lp . y , lp . z ] ;
107
136
meshData . ambient = trace . lighting . ambient ;
108
137
meshData . diffuse = trace . lighting . diffuse ;
109
138
meshData . specular = trace . lighting . specular ;
110
139
meshData . roughness = trace . lighting . roughness ;
111
140
meshData . fresnel = trace . lighting . fresnel ;
112
141
meshData . opacity = trace . opacity ;
113
142
143
+ // TODO
144
+ // stash autorange pad value
145
+ // - include pad!
146
+ // - include tubeScale
147
+ // trace._pad = meshData.tubeScale * trace.sizeref;
148
+ // if(trace.sizemode === 'scaled') trace._pad *= trace._normMax;
149
+
114
150
return meshData ;
115
151
}
116
152
0 commit comments