Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Volume traces #2753

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
6a9c27b
initial scaffolding for volume trace
kig Jun 23, 2018
31fbc97
volume convert, pass gl to volume generator
kig Jun 23, 2018
d3fc93f
volume attributes tweaks, something renders
kig Jun 25, 2018
9e8378d
volume trace rendering sort of works, automatic default isoBounds
kig Jun 25, 2018
0691672
volume: add opacityscale param
kig Jun 25, 2018
a48ee0e
fix volume update, cooler example function
kig Jun 25, 2018
27e6334
Merge branch 'master' into volume-traces
etpinard Jul 11, 2018
e0d7fa1
add gl-volume3d (w/ updated deps) to package-lock
etpinard Jul 11, 2018
bbaaebb
use 'value' instead of 'u'
etpinard Jul 11, 2018
c392a7d
add gl-volume3d npm package
kig Aug 27, 2018
d7ae2fd
add volume to lib/index-gl3d.js
kig Aug 27, 2018
ce212cb
createvolumeTrace -> createVolumeTrace
kig Aug 27, 2018
6866c18
volume trace hover text scaffolding
kig Sep 10, 2018
379efe6
add roles to volume attributes
kig Sep 10, 2018
61b9f60
Merge branch 'master' into volume-traces
kig Sep 10, 2018
34a1aa7
volume lint fixes
kig Sep 13, 2018
4f11e35
volume: remove boundmin/max, use default opacity, describe opacitymap…
kig Sep 13, 2018
0b06423
fix lint issue
kig Sep 20, 2018
34b40f0
volume/convert.js: bring back trace.opacity
kig Sep 20, 2018
4c6f59c
volume: document vmin, vmax, cmin, cmax, rename value to values
kig Sep 28, 2018
d788250
volume plot tests, initial scaffold
kig Oct 3, 2018
7107b68
Merge branch 'master' into volume-traces
etpinard Oct 29, 2018
8f93b02
bump gl-volume3d to kig's latest
etpinard Oct 29, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 6 additions & 22 deletions src/traces/volume/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,12 @@ var attrs = {
valType: 'data_array',
role: 'info',
editType: 'calc',
description: 'Sets the opacity scale of the volume, which opacity to use for which intensity. Array of 256 values in 0..1 range.'
description: [
'Sets the opacity scale of the volume.',
'Defines which opacity to use for which intensity.',
'Multiplied with trace.opacity to obtain the final opacity.',
'Colorscale-like array of [[0, opacity0], [v1, opacity1], ..., [1, opacityN]].'
].join(' ')
},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this mapping over the same range as colorscale? If so, can we specify it similarly, as a piecewise-linear list of pairs [[0, opacity0], [v1, opacity1], ..., [1, opacityN]]?

Is this used along with trace.opacity? Like the two are multiplied together perhaps? However that works it should be in the description.


imin: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forget. Did we settle on imin / imax in the past? If not, I think I would prefer vmin and vmax to match the v in values.

We should also explain how this pair of attributes is related to cmin / cmax

    volumeOpts.isoBounds = [trace.cmin, trace.cmax];
    volumeOpts.intensityBounds = [
        trace.imin === undefined ? trace.cmin : trace.imin,
        trace.imax === undefined ? trace.cmax : trace.imax
    ];

in the attribute description.

Expand All @@ -69,27 +74,6 @@ var attrs = {
description: 'Sets the maximum intensity bound of the volume.'
},

opacity: {
valType: 'number',
role: 'info',
editType: 'calc',
description: 'Sets the opacity of the volume.'
},

boundmin: {
valType: 'data_array',
role: 'info',
editType: 'calc',
description: ''
},

boundmax: {
valType: 'data_array',
role: 'info',
editType: 'calc',
description: ''
},

text: {
valType: 'string',
role: 'info',
Expand Down
41 changes: 30 additions & 11 deletions src/traces/volume/convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
}

var opacityscale = []
for (var i=0; i<256; i++) {
opacityscale[i] = Math.pow(i/256, 1.2)
for (var i=0; i<16; i++) {
opacityscale[i] = [i/15, Math.pow(i/15, 1.2)]
}

Plotly.newPlot(gd, [{
Expand Down Expand Up @@ -101,6 +101,33 @@ proto.handlePick = function(selection) {
}
};

function parseOpacityScale(opacityScale) {
var alphaMapLength = 256;
var alphaMap = new Float32Array(alphaMapLength);
var alphaMapIndex = 0;
var previousEntry = [0, 1];
for(var i = 0; i < opacityScale.length; i++) {
var entry = opacityScale[i];
var startIndex = alphaMapIndex;
var startValue = previousEntry[1];
var endIndex = Math.max(0, Math.min(Math.floor(entry[0] * alphaMapLength), alphaMapLength-1));
var endValue = entry[1];
var indexDelta = endIndex - startIndex;
while(alphaMapIndex < endIndex) {
var t = (alphaMapIndex - startIndex) / indexDelta;
alphaMap[alphaMapIndex] = (1 - t) * startValue + t * endValue;
alphaMapIndex++;
}
alphaMap[alphaMapIndex] = endValue;
previousEntry = entry;
}
var lastAlpha = alphaMap[alphaMapIndex];
while(alphaMapIndex < alphaMapLength) {
alphaMap[alphaMapIndex++] = lastAlpha;
}
return alphaMap;
}

var axisName2scaleIndex = {xaxis: 0, yaxis: 1, zaxis: 2};

function getSequence(src) {
Expand Down Expand Up @@ -141,18 +168,12 @@ function convert(gl, scene, trace) {
toDataCoords(zs, 'zaxis')
];

// var bounds = [
// volumeOpts.boundmin || [xs[0], ys[0], zs[0]],
// volumeOpts.boundmax || [xs[xs.length - 1], ys[ys.length - 1], zs[zs.length - 1]]
// ];


volumeOpts.values = trace.value;

volumeOpts.colormap = parseColorScale(trace.colorscale);

if(trace.opacityscale) {
volumeOpts.alphamap = trace.opacityscale;
volumeOpts.alphamap = parseOpacityScale(trace.opacityscale);
}

volumeOpts.isoBounds = [trace.cmin, trace.cmax];
Expand All @@ -161,8 +182,6 @@ function convert(gl, scene, trace) {
trace.imax === undefined ? trace.cmax : trace.imax
];

volumeOpts.opacity = trace.opacity === undefined ? 1 : trace.opacity;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can still set this, if it'll get used downstream - which it looks like it will based on your amended description for opacityscale, thanks for fleshing that out!

My point was just that you don't need to handle the undefined case here, since the global trace.opacity attribute has a default of 1 you know at this point that you can only have a number between 0 and 1.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohh, right, thanks for catching this.


var bounds = [[0, 0, 0], volumeOpts.dimensions];

var volume = volumePlot(gl, volumeOpts, bounds);
Expand Down
4 changes: 0 additions & 4 deletions src/traces/volume/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,8 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout

coerce('imin');
coerce('imax');
coerce('opacity');
coerce('opacityscale');

coerce('boundmin');
coerce('boundmax');

coerce('lighting.ambient');
coerce('lighting.diffuse');
coerce('lighting.specular');
Expand Down