Skip to content

Commit

Permalink
Merge branch 'master' into improve-lic-example
Browse files Browse the repository at this point in the history
  • Loading branch information
finetjul authored Jul 15, 2021
2 parents 39c6c5b + 7a96c80 commit c683cf5
Show file tree
Hide file tree
Showing 20 changed files with 236 additions and 195 deletions.
2 changes: 1 addition & 1 deletion Sources/Common/Core/ImageHelper/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ function imageToImageData(
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.scale(flipX ? -1 : 1, flipY ? -1 : 1);
ctx.rotate((rotate * Math.PI) / 180);
ctx.drawImage(image, -image.width / 2, -image.width / 2);
ctx.drawImage(image, -image.width / 2, -image.height / 2);

return canvasToImageData(canvas);
}
Expand Down
45 changes: 0 additions & 45 deletions Sources/IO/XML/XMLPolyDataReader/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import macro from 'vtk.js/Sources/macro';
import vtkDataArray from 'vtk.js/Sources/Common/Core/DataArray';
import vtkPolyData from 'vtk.js/Sources/Common/DataModel/PolyData';
import vtkXMLReader from 'vtk.js/Sources/IO/XML/XMLReader';

Expand Down Expand Up @@ -60,28 +59,6 @@ function handleCells(
return size;
}

// ----------------------------------------------------------------------------

function handleFieldDataArray(
dataArrayElem,
compressor,
byteOrder,
headerType,
binaryBuffer
) {
const size = Number(dataArrayElem.getAttribute('NumberOfTuples'));
return vtkDataArray.newInstance(
vtkXMLReader.processDataArray(
size,
dataArrayElem,
compressor,
byteOrder,
headerType,
binaryBuffer
)
);
}

// ----------------------------------------------------------------------------
// vtkXMLPolyDataReader methods
// ----------------------------------------------------------------------------
Expand All @@ -92,26 +69,9 @@ function vtkXMLPolyDataReader(publicAPI, model) {

publicAPI.parseXML = (rootElem, type, compressor, byteOrder, headerType) => {
const datasetElem = rootElem.getElementsByTagName(model.dataType)[0];
const fieldDataElem = datasetElem.getElementsByTagName('FieldData')[0];
const pieces = datasetElem.getElementsByTagName('Piece');
const nbPieces = pieces.length;

// field data
let fieldDataArrays = [];
if (fieldDataElem) {
fieldDataArrays = [
...fieldDataElem.getElementsByTagName('DataArray'),
].map((daElem) =>
handleFieldDataArray(
daElem,
compressor,
byteOrder,
headerType,
model.binaryBuffer
)
);
}

for (let outputIndex = 0; outputIndex < nbPieces; outputIndex++) {
// Create dataset
const polydata = vtkPolyData.newInstance();
Expand Down Expand Up @@ -162,11 +122,6 @@ function vtkXMLPolyDataReader(publicAPI, model) {
model.binaryBuffer
);

const fieldData = polydata.getFieldData();
for (let i = 0; i < fieldDataArrays.length; i++) {
fieldData.addArray(fieldDataArrays[i]);
}

// Add new output
model.output[outputIndex] = polydata;
}
Expand Down
43 changes: 43 additions & 0 deletions Sources/IO/XML/XMLReader/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,28 @@ function processFieldData(
}
}

// ----------------------------------------------------------------------------
function handleFieldDataArrays(
fieldDataElem,
compressor,
byteOrder,
headerType,
binaryBuffer
) {
return [...fieldDataElem.getElementsByTagName('DataArray')].map((daElem) =>
vtkDataArray.newInstance(
processDataArray(
Number(daElem.getAttribute('NumberOfTuples')),
daElem,
compressor,
byteOrder,
headerType,
binaryBuffer
)
)
);
}

// ----------------------------------------------------------------------------
// vtkXMLReader methods
// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -513,6 +535,27 @@ function vtkXMLReader(publicAPI, model) {
}

publicAPI.parseXML(rootElem, type, compressor, byteOrder, headerType);

const datasetElem = rootElem.getElementsByTagName(type)[0];
const fieldDataElem = datasetElem.getElementsByTagName('FieldData')[0];

if (fieldDataElem) {
const fieldDataArrays = handleFieldDataArrays(
fieldDataElem,
compressor,
byteOrder,
headerType,
model.binaryBuffer
);

for (let i = 0; i < model.output.length; i++) {
const fieldData = model.output[i].getFieldData();
for (let j = 0; j < fieldDataArrays.length; j++) {
fieldData.addArray(fieldDataArrays[j]);
}
}
}

return true;
};

Expand Down
47 changes: 47 additions & 0 deletions Sources/Testing/testAlgorithm.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,50 @@ test('Macro methods algo tests', (t) => {

t.end();
});

test('Macro shouldUpdate returns true if output is deleted', (t) => {
const algo = {
publicAPI: {},
model: {},
};
const input1 = {
publicAPI: {},
model: {},
};

const input2 = {
publicAPI: {},
model: {},
};

macro.obj(algo.publicAPI, algo.model);
macro.algo(algo.publicAPI, algo.model, 1, 1);

macro.obj(input1.publicAPI, input1.model);
macro.obj(input2.publicAPI, input2.model);

// trivial producer
algo.publicAPI.requestData = (inData, outData) => {
outData[0] = inData[0];
};

algo.publicAPI.setInputData(input1.publicAPI, 0);
t.equal(
input1.publicAPI,
algo.publicAPI.getOutputData(),
'Trivial producer outputs first input data'
);

// delete output data
algo.publicAPI.getOutputData().delete();

// set new data
algo.publicAPI.setInputData(input2.publicAPI, 0);
t.equal(
input2.publicAPI,
algo.publicAPI.getOutputData(),
'Trivial producer outputs second input data'
);

t.end();
});
13 changes: 13 additions & 0 deletions Sources/Testing/testMacro.js
Original file line number Diff line number Diff line change
Expand Up @@ -428,3 +428,16 @@ test('Macro methods keystore tests', (t) => {

t.end();
});

test('Macro debounce can be cancelled', (t) => {
const func = () => {
t.fail('Should not call cancelled debounce function');
};

const debFunc = macro.debounce(func, 5);
debFunc();
debFunc.cancel();

// end the test after the debounce phase
setTimeout(() => t.end(), 10);
});
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,29 @@ function vtkResliceCursorContextRepresentation(publicAPI, model) {
const length = vtkMath.normalize(vector);
axis.line.source.setDirection(vector);
axis.line.source.setHeight(length);
axis.rotation1.source.setCenter(state.getRotationPoint1());
axis.rotation2.source.setCenter(state.getRotationPoint2());

// Rotation handles
const pixelWorldHeight = publicAPI.getPixelWorldHeightAtCoord(center);
const { rendererPixelDims } = model.displayScaleParams;
const minDim = Math.min(rendererPixelDims[0], rendererPixelDims[1]);
const ratio = 0.5;
const distance =
(window.devicePixelRatio * (pixelWorldHeight * ratio * minDim)) / 2;
const rotationHandlePosition = [];
vtkMath.multiplyAccumulate(
center,
vector,
distance,
rotationHandlePosition
);
axis.rotation1.source.setCenter(rotationHandlePosition);
vtkMath.multiplyAccumulate(
center,
vector,
-distance,
rotationHandlePosition
);
axis.rotation2.source.setCenter(rotationHandlePosition);
}

/**
Expand Down Expand Up @@ -247,7 +268,6 @@ function vtkResliceCursorContextRepresentation(publicAPI, model) {
const axis2State = state[getAxis2]();

let activeLineState = null;
let activeRotationPointName = '';
let methodName = '';

switch (prop) {
Expand All @@ -261,22 +281,18 @@ function vtkResliceCursorContextRepresentation(publicAPI, model) {
break;
case model.pipelines.axes[0].rotation1.actor:
activeLineState = axis1State;
activeRotationPointName = 'RotationPoint1';
methodName = InteractionMethodsName.RotateLine;
break;
case model.pipelines.axes[0].rotation2.actor:
activeLineState = axis1State;
activeRotationPointName = 'RotationPoint2';
methodName = InteractionMethodsName.RotateLine;
break;
case model.pipelines.axes[1].rotation1.actor:
activeLineState = axis2State;
activeRotationPointName = 'RotationPoint1';
methodName = InteractionMethodsName.RotateLine;
break;
case model.pipelines.axes[1].rotation2.actor:
activeLineState = axis2State;
activeRotationPointName = 'RotationPoint2';
methodName = InteractionMethodsName.RotateLine;
break;
default:
Expand All @@ -285,7 +301,6 @@ function vtkResliceCursorContextRepresentation(publicAPI, model) {
}

state.setActiveLineState(activeLineState);
state.setActiveRotationPointName(activeRotationPointName);
state.setUpdateMethodName(methodName);

return state;
Expand All @@ -296,33 +311,39 @@ function vtkResliceCursorContextRepresentation(publicAPI, model) {
// Object factory
// ----------------------------------------------------------------------------

const DEFAULT_VALUES = {
axis1Name: '',
axis2Name: '',
coincidentTopologyParameters: {
Point: {
factor: -1.0,
offset: -1.0,
},
Line: {
factor: -1.5,
offset: -1.5,
function defaultValues(initialValues) {
return {
axis1Name: '',
axis2Name: '',
coincidentTopologyParameters: {
Point: {
factor: -1.0,
offset: -1.0,
},
Line: {
factor: -1.5,
offset: -1.5,
},
Polygon: {
factor: -2.0,
offset: -2.0,
},
},
Polygon: {
factor: -2.0,
offset: -2.0,
},
},
rotationEnabled: true,
scaleInPixels: true,
viewType: null,
};
rotationEnabled: true,
rotationHandlePosition: 0.5,
scaleInPixels: true,
viewType: null,
...initialValues,
};
}

// ----------------------------------------------------------------------------

export function extend(publicAPI, model, initialValues = {}) {
Object.assign(model, defaultValues(initialValues));
vtkWidgetRepresentation.extend(publicAPI, model, initialValues);
Object.assign(model, DEFAULT_VALUES, initialValues);

macro.setGet(publicAPI, model, ['rotationHandlePosition']);

// Object specific methods
vtkResliceCursorContextRepresentation(publicAPI, model);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import macro from 'vtk.js/Sources/macro';
import vtkActor from 'vtk.js/Sources/Rendering/Core/Actor';
import vtkHandleRepresentation from 'vtk.js/Sources/Widgets/Representations/HandleRepresentation';
import vtkContextRepresentation from 'vtk.js/Sources/Widgets/Representations/ContextRepresentation';
import vtkMapper from 'vtk.js/Sources/Rendering/Core/Mapper';
import vtkPolyData from 'vtk.js/Sources/Common/DataModel/PolyData';
import vtkSpline3D from 'vtk.js/Sources/Common/DataModel/Spline3D';
Expand Down Expand Up @@ -155,7 +155,7 @@ const DEFAULT_VALUES = {
export function extend(publicAPI, model, initialValues = {}) {
Object.assign(model, DEFAULT_VALUES, initialValues);

vtkHandleRepresentation.extend(publicAPI, model, initialValues);
vtkContextRepresentation.extend(publicAPI, model, initialValues);
macro.get(publicAPI, model, ['mapper']);
macro.setGet(publicAPI, model, [
'resolution',
Expand Down
2 changes: 0 additions & 2 deletions Sources/Widgets/Widgets3D/ResliceCursorWidget/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ These sub states contain :

- activeLineState: Used in the behavior.js file in order to get the attribute of the selected line

- activeRotationPointName: Used in the behavior.js file in order to get the selected rotation point

- image: vtkImage used to place the reslice cursor

- activeViewType: Used in the behavior.js file in order to get the current view
Expand Down
15 changes: 7 additions & 8 deletions Sources/Widgets/Widgets3D/ResliceCursorWidget/behavior.js
Original file line number Diff line number Diff line change
Expand Up @@ -316,20 +316,19 @@ export default function widgetBehavior(publicAPI, model) {
);

const center = model.widgetState.getCenter();
const previousWorldPosition = activeLine[
`get${model.widgetState.getActiveRotationPointName()}`
]();

const previousVectorToOrigin = [0, 0, 0];
vtkMath.subtract(previousWorldPosition, center, previousVectorToOrigin);
vtkMath.normalize(previousVectorToOrigin);
const previousLineDirection = vtkMath.subtract(
activeLine.getPoint1(),
activeLine.getPoint2(),
[]
);
vtkMath.normalize(previousLineDirection);

const currentVectorToOrigin = [0, 0, 0];
vtkMath.subtract(worldCoords, center, currentVectorToOrigin);
vtkMath.normalize(currentVectorToOrigin);

const radianAngle = vtkMath.signedAngleBetweenVectors(
previousVectorToOrigin,
previousLineDirection,
currentVectorToOrigin,
planeNormal
);
Expand Down
Loading

0 comments on commit c683cf5

Please sign in to comment.