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

Update vtk.js pointFeature #953

Merged
merged 7 commits into from
Nov 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 4 additions & 1 deletion src/d3/pointFeature.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,10 @@ var d3_pointFeature = function (arg) {

inherit(d3_pointFeature, pointFeature);

var capabilities = {};
capabilities[pointFeature.capabilities.stroke] = true;

// Now register it
registerFeature('d3', 'point', d3_pointFeature);
registerFeature('d3', 'point', d3_pointFeature, capabilities);

module.exports = d3_pointFeature;
5 changes: 4 additions & 1 deletion src/gl/pointFeature.js
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,10 @@ var gl_pointFeature = function (arg) {

inherit(gl_pointFeature, pointFeature);

var capabilities = {};
capabilities[pointFeature.capabilities.stroke] = true;

// Now register it
registerFeature('vgl', 'point', gl_pointFeature);
registerFeature('vgl', 'point', gl_pointFeature, capabilities);

module.exports = gl_pointFeature;
4 changes: 3 additions & 1 deletion src/pointFeature.js
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,9 @@ pointFeature.create = function (layer, spec) {

pointFeature.capabilities = {
/* core feature name -- support in any manner */
feature: 'point'
feature: 'point',
/* support for stroke properties */
stroke: 'line.stroke'
};

inherit(pointFeature, feature);
Expand Down
41 changes: 41 additions & 0 deletions src/vtkjs/object.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* Vtk.js specific subclass of object which rerenders when the object is drawn.
*
* @class
* @alias geo.vtkjs.object
* @extends geo.sceneObject
* @param {object} arg Options for the object.
* @returns {geo.vtkjs.object}
*/
var vtkjs_object = function (arg) {
'use strict';

var object = require('../object');

// this is used to extend other geojs classes, so only generate
// a new object when that is not the case... like if this === window
if (!(this instanceof object)) {
return new vtkjs_object(arg);
}

var m_this = this,
s_draw = this.draw;

/**
* Redraw the object.
*
* @returns {this}
*/
this.draw = function () {
if (m_this.ready) {
m_this._update();
m_this.renderer()._render();
s_draw();
}
return m_this;
};

return this;
};

module.exports = vtkjs_object;
82 changes: 57 additions & 25 deletions src/vtkjs/pointFeature.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,23 @@ var vtkjs_pointFeature = function (arg) {
pointFeature.call(this, arg);

var transform = require('../transform');
var object = require('../object');
var object = require('./object');
var vtk = require('./vtkjsRenderer').vtkjs;
var vtkActor = vtk.Rendering.Core.vtkActor;
var vtkMapper = vtk.Rendering.Core.vtkGlyph3DMapper;
var vtkDataArray = vtk.Common.Core.vtkDataArray;
var vtkGlyph3DMapper = vtk.Rendering.Core.vtkGlyph3DMapper;
var vtkMapper = vtk.Rendering.Core.vtkMapper;
var vtkPointSet = vtk.Common.DataModel.vtkPointSet;
var vtkSphereSource = vtk.Filters.Sources.vtkSphereSource;

object.call(this);

/**
* @private
*/
var m_this = this,
m_actor,
m_pointSet,
m_source,
m_colorArray,
m_diamArray,
s_init = this._init,
s_exit = this._exit,
s_update = this._update;
Expand All @@ -48,7 +49,20 @@ var vtkjs_pointFeature = function (arg) {
m_source = vtkSphereSource.newInstance();
m_source.setThetaResolution(30);
m_source.setPhiResolution(30);
var mapper = vtkMapper.newInstance();
var mapper = vtkGlyph3DMapper.newInstance({
// Orientation
orient: false,

// Color and Opacity
colorByArrayName: 'color',
scalarMode: vtkMapper.ScalarMode.USE_POINT_FIELD_DATA,
colorMode: vtkMapper.ColorMode.DIRECT_SCALARS,

// Scaling
scaling: true,
scaleArray: 'diam',
scaleMode: vtkGlyph3DMapper.ScaleModes.SCALE_BY_MAGNITUDE
});
mapper.setInputData(m_pointSet, 0);
mapper.setInputConnection(m_source.getOutputPort(), 1);
m_actor = vtkActor.newInstance();
Expand All @@ -70,26 +84,40 @@ var vtkjs_pointFeature = function (arg) {
* Build this feature.
*/
this._build = function () {
var i, i3, posVal,
var i, i3, i4, posVal, clrVal,
nonzeroZ,
numPts = m_this.data().length,
position = new Array(numPts * 3),
data = m_this.data(),
posFunc = m_this.position(),
radFunc = m_this.style.get('radius'),
fillFunc = m_this.style.get('fill'),
colorFunc = m_this.style.get('fillColor'),
opacityFunc = m_this.style.get('fillOpacity');
opacityFunc = m_this.style.get('fillOpacity'),
unitsPerPixel = m_this.layer().map().unitsPerPixel(m_this.layer().map().zoom());

if (!m_diamArray || m_diamArray.length !== numPts) {
m_diamArray = new Float32Array(numPts);
}
if (!m_colorArray || m_colorArray.length !== numPts * 4) {
m_colorArray = new Uint8Array(numPts * 4);
}

/* It is more efficient to do a transform on a single array rather than on
* an array of arrays or an array of objects. */
for (i = i3 = 0; i < numPts; i += 1, i3 += 3) {
* an array of arrays or an array of objects. */
for (i = i3 = i4 = 0; i < numPts; i += 1, i3 += 3, i4 += 4) {
posVal = posFunc(data[i], i);
position[i3] = posVal.x;
position[i3 + 1] = posVal.y;
position[i3 + 2] = posVal.z || 0;
nonzeroZ = nonzeroZ || position[i3 + 2];
// TODO: fix the opacity per point.
m_actor.getProperty().setOpacity(opacityFunc(data[i], i));

m_diamArray[i] = radFunc(data[i], i) * unitsPerPixel * 2;
clrVal = colorFunc(data[i], i);
m_colorArray[i4] = clrVal.r * 255;
m_colorArray[i4 + 1] = clrVal.g * 255;
m_colorArray[i4 + 2] = clrVal.b * 255;
m_colorArray[i4 + 3] = fillFunc(data[i], i) ? opacityFunc(data[i], i) * 255 : 0;
}
position = transform.transformCoordinates(
m_this.gcs(), m_this.layer().map().gcs(),
Expand All @@ -104,15 +132,12 @@ var vtkjs_pointFeature = function (arg) {
}
}

// TODO: points can vary, this needs to be refactors to have a distinct
// size per point. What should be done with the strokeColor, strokeWidth,
// and strokeOpacity? Honor the fill/stroke options or document that we
// don't honot them. Handle the zero-data-itmes condition.
var rad = radFunc(data[0], 0), clr = colorFunc(data[0], 0);
rad *= m_this.layer().map().unitsPerPixel(m_this.layer().map().zoom());
m_pointSet.getPoints().setData(position, 3);
m_source.setRadius(rad);
m_actor.getProperty().setColor(clr.r, clr.g, clr.b);

// Attach fields
m_pointSet.getPointData().addArray(vtkDataArray.newInstance({name: 'color', values: m_colorArray, numberOfComponents: 4}));
m_pointSet.getPointData().addArray(vtkDataArray.newInstance({name: 'diam', values: m_diamArray}));

m_this.buildTime().modified();
};

Expand All @@ -127,10 +152,14 @@ var vtkjs_pointFeature = function (arg) {
m_this._build();
} else {
var data = m_this.data(),
radFunc = m_this.style.get('radius'),
rad = radFunc(data[0], 0);
rad *= m_this.layer().map().unitsPerPixel(m_this.layer().map().zoom());
m_source.setRadius(rad);
radFunc = m_this.style.get('radius');

const scalingFactor = m_this.layer().map().unitsPerPixel(m_this.layer().map().zoom());
const dataArray = m_pointSet.getPointData().getArray('diam');
const newScaleArray = dataArray.getData().map((v, i) => radFunc(data[i], i) * scalingFactor * 2);

dataArray.setData(newScaleArray);
m_pointSet.modified();
}

m_this.updateTime().modified();
Expand All @@ -150,7 +179,10 @@ var vtkjs_pointFeature = function (arg) {

inherit(vtkjs_pointFeature, pointFeature);

var capabilities = {};
capabilities[pointFeature.capabilities.stroke] = false;

// Now register it
registerFeature('vtkjs', 'point', vtkjs_pointFeature);
registerFeature('vtkjs', 'point', vtkjs_pointFeature, capabilities);

module.exports = vtkjs_pointFeature;
3 changes: 3 additions & 0 deletions tests/gl-cases/vtkjsPointFeature.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ describe('geo.vtkjs.pointFeature', function () {
}
}
}).data(testPoints);
sinon.spy(point, '_update');
point.draw();
expect(point._update.calledOnce).toBe(true);
point._update.restore();
expect($('#map div canvas').length).toBe(1);
});
waitForIt('points to be generated', function () {
Expand Down