Skip to content

Allow isosurfaces for hybrid tracings when setting flag #3998

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

Merged
merged 2 commits into from
Apr 9, 2019
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
2 changes: 1 addition & 1 deletion frontend/javascripts/admin/admin_rest_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -1130,7 +1130,7 @@ export function computeIsosurface(
return doWithToken(async token => {
const { buffer, headers } = await Request.sendJSONReceiveArraybufferWithHeaders(
`${datastoreUrl}/data/datasets/${datasetId.owningOrganization}/${datasetId.name}/layers/${
layer.name
layer.fallbackLayer != null ? layer.fallbackLayer : layer.name
}/isosurface?token=${token}`,
{
data: {
Expand Down
2 changes: 2 additions & 0 deletions frontend/javascripts/oxalis/model/data_layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class DataLayer {
activeMapping: ?string;
layerRenderingManager: LayerRenderingManager;
resolutions: Array<Vector3>;
fallbackLayer: ?string;

constructor(
layerInfo: DataLayerType,
Expand All @@ -36,6 +37,7 @@ class DataLayer {
) {
this.connectionInfo = connectionInfo;
this.name = layerInfo.name;
this.fallbackLayer = layerInfo.fallbackLayer != null ? layerInfo.fallbackLayer : null;
this.resolutions = layerInfo.resolutions;

const { dataset } = Store.getState();
Expand Down
32 changes: 24 additions & 8 deletions frontend/javascripts/oxalis/model/sagas/isosurface_saga.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,30 +90,42 @@ function getNeighborPosition(
// for datasets is limited in volume tracings etc.), we use another state
// variable for the "active cell" in view mode. The cell can be changed via
// shift+click (similar to the volume tracing mode).
let currentIsosurfaceCellId = 0;
let currentViewIsosurfaceCellId = 0;
// The calculation of an isosurface is spread across multiple requests.
// In order to avoid, that too many chunks are computed for one user interaction,
// we store the amount of requests in a batch per segment.
const batchCounterPerSegment: { [key: number]: number } = {};
const MAXIMUM_BATCH_SIZE = 30;

function* changeActiveIsosurfaceCell(action: ChangeActiveIsosurfaceCellAction): Saga<void> {
currentIsosurfaceCellId = action.cellId;
currentViewIsosurfaceCellId = action.cellId;

yield* call(ensureSuitableIsosurface, null, action.seedPosition);
}

// This function either returns the activeCellId of the current volume tracing
// or the view-only active cell id
function* getCurrentCellId(): Saga<number> {
const volumeTracing = yield* select(state => state.tracing.volume);
if (volumeTracing != null) {
return volumeTracing.activeCellId;
}

return currentViewIsosurfaceCellId;
}

function* ensureSuitableIsosurface(
maybeFlycamAction: ?FlycamAction,
seedPosition?: Vector3,
): Saga<void> {
const segmentId = currentIsosurfaceCellId;
const segmentId = yield* call(getCurrentCellId);
if (segmentId === 0) {
return;
}
const renderIsosurfaces = yield* select(state => state.datasetConfiguration.renderIsosurfaces);
const isControlModeSupported = yield* select(
state => state.temporaryConfiguration.controlMode === ControlModeEnum.VIEW,
state =>
state.temporaryConfiguration.controlMode === ControlModeEnum.VIEW || window.allowIsosurfaces,
);
if (!renderIsosurfaces || !isControlModeSupported) {
return;
Expand Down Expand Up @@ -214,8 +226,9 @@ function* maybeLoadIsosurface(
}

function* downloadActiveIsosurfaceCell(): Saga<void> {
const currentId = yield* call(getCurrentCellId);
const sceneController = getSceneController();
const geometry = sceneController.getIsosurfaceGeometry(currentIsosurfaceCellId);
const geometry = sceneController.getIsosurfaceGeometry(currentId);

const stl = exportToStl(geometry);

Expand All @@ -224,10 +237,10 @@ function* downloadActiveIsosurfaceCell(): Saga<void> {
isosurfaceMarker.forEach((marker, index) => {
stl.setUint8(index, marker);
});
stl.setUint32(cellIdIndex, currentIsosurfaceCellId, true);
stl.setUint32(cellIdIndex, currentId, true);

const blob = new Blob([stl]);
yield* call(saveAs, blob, `isosurface-${currentIsosurfaceCellId}.stl`);
yield* call(saveAs, blob, `isosurface-${currentId}.stl`);
}

function* importIsosurfaceFromStl(action: ImportIsosurfaceFromStlAction): Saga<void> {
Expand All @@ -242,7 +255,10 @@ function* importIsosurfaceFromStl(action: ImportIsosurfaceFromStlAction): Saga<v
export default function* isosurfaceSaga(): Saga<void> {
yield* take("WK_READY");
yield _takeEvery(FlycamActions, ensureSuitableIsosurface);
yield _takeEvery("CHANGE_ACTIVE_ISOSURFACE_CELL", changeActiveIsosurfaceCell);
yield _takeEvery(
["CHANGE_ACTIVE_ISOSURFACE_CELL", "SET_ACTIVE_CELL"],
changeActiveIsosurfaceCell,
);
yield _takeEvery("TRIGGER_ISOSURFACE_DOWNLOAD", downloadActiveIsosurfaceCell);
yield _takeEvery("IMPORT_ISOSURFACE_FROM_STL", importIsosurfaceFromStl);
}
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ class DatasetSettings extends React.PureComponent<DatasetSettingsProps> {
onChange={_.partial(this.props.onChange, "highlightHoveredCellId")}
/>

{this.props.controlMode === ControlModeEnum.VIEW ? (
{this.props.controlMode === ControlModeEnum.VIEW || window.allowIsosurfaces ? (
<SwitchSetting
label="Render Isosurfaces (Beta)"
value={this.props.datasetConfiguration.renderIsosurfaces}
Expand Down