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

Custom viewports #3070

Merged
merged 33 commits into from
Sep 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
34b7be9
Revert "Revert "Allow user-customizable viewport arrangements (#2570)""
philippotto Jun 4, 2018
e874ef8
Revert "Revert "fix node selection; 3d viewport rotation/zooming; fix…
philippotto Jun 4, 2018
d9b9502
make gl style static to avoid re-mountings
philippotto Jun 4, 2018
2872afd
workaround weird uglifyjs bug which remounts instead of rerenders som…
philippotto Jun 5, 2018
616c225
Merge branch 'master' of github.com:scalableminds/webknossos into cus…
philippotto Jul 2, 2018
9e47341
re-add snapshots
philippotto Jul 2, 2018
010e5b7
Merge branch 'master' of github.com:scalableminds/webknossos into cus…
philippotto Jul 13, 2018
86ededf
fix bug which caused hidden arbitrary view to be still rendered
philippotto Jul 13, 2018
4ff0621
pretty code
philippotto Jul 13, 2018
079393f
Merge branch 'master' of github.com:scalableminds/webknossos into cus…
philippotto Jul 18, 2018
895c673
tmp: work on different default-layout(s)
philippotto Jul 18, 2018
3814c87
Merge branch 'master' of github.com:scalableminds/webknossos into cus…
philippotto Aug 6, 2018
edcc5ee
Revert "tmp: work on different default-layout(s)"
philippotto Aug 6, 2018
53606d8
tmp: re-add k/l for custom viewports
philippotto Aug 7, 2018
133352e
pretty code
philippotto Aug 7, 2018
1c80101
fix wrong method call
philippotto Aug 8, 2018
b0716c8
update snapshots
philippotto Aug 8, 2018
5634a0b
update snapshots
philippotto Aug 8, 2018
855258d
Merge branch 'master' of github.com:scalableminds/webknossos into cus…
philippotto Aug 13, 2018
162b879
Merge branch 'master' of github.com:scalableminds/webknossos into cus…
philippotto Sep 3, 2018
8c2e45c
adapt custom viewports to newest master
philippotto Sep 3, 2018
700ced3
clean up custom viewports
philippotto Sep 3, 2018
0f425e3
re-introduce k/l scale value into store; improve UX of custom viewports
philippotto Sep 4, 2018
1a39c8e
fix linting
philippotto Sep 10, 2018
f8c138f
Merge remote-tracking branch 'origin/master' into custom-viewports
philippotto Sep 10, 2018
331b5de
Merge branch 'master' of github.com:scalableminds/webknossos into cus…
philippotto Sep 12, 2018
34ea584
fix multiple reset and show move-cursor when hovering over tab
philippotto Sep 12, 2018
47f085b
add default layoutScaleValue to backend
philippotto Sep 12, 2018
40f0835
fix syntax error
philippotto Sep 12, 2018
3c923be
Merge branch 'master' of github.com:scalableminds/webknossos into cus…
philippotto Sep 17, 2018
e773afc
update changelog
philippotto Sep 17, 2018
33e168b
Merge branch 'master' into custom-viewports
philippotto Sep 17, 2018
42e3304
pretty code
philippotto Sep 17, 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.md).
- Added URLs to the tabs in the dashboard. [#3183](https://github.com/scalableminds/webknossos/pull/3183)
- Improved security by enabling http security headers. [#3084](https://github.com/scalableminds/webknossos/pull/3084)
- Added the possibility to write markdown in the annotation description. [#3081](https://github.com/scalableminds/webknossos/pull/3081)
- Added customizable layouting to the tracing view. [#3070](https://github.com/scalableminds/webknossos/pull/3070)
- Added the brush size to the settings on the left in volume tracing. The size can now also be adjusted by using only the keyboard. [#3126](https://github.com/scalableminds/webknossos/pull/3126)
- Added a user documentation for webKnossos [#3011](https://github.com/scalableminds/webknossos/pull/3011)
- Tree groups can now be activated. This allows to rename a tree group analogous to renaming a tree. Also, toggling the visibility of a tree group can now be done by using the shortcuts "1" and "2". [#3066](https://github.com/scalableminds/webknossos/pull/3066)
Expand Down
2 changes: 1 addition & 1 deletion app/assets/javascripts/admin/help/keyboardshortcut_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const KeyboardShortcutView = () => {
},
{
keybinding: "K, L",
action: "Scale Up/down Viewport Size",
action: "Increase/Decrease Size of Layout",
},
{
keybinding: "B, J",
Expand Down
12 changes: 12 additions & 0 deletions app/assets/javascripts/libs/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,18 @@ export function sortArray8(arr: Array<number>): void {
swap(arr, 3, 4);
}

export function waitForSelector(selector: string): Promise<*> {
const tryToResolve = resolve => {
const el = document.querySelector(selector);
if (el) {
resolve(el);
} else {
window.requestAnimationFrame(() => tryToResolve(resolve));
}
};
return new Promise(tryToResolve);
}

export function convertDecToBase256(num: number): Vector4 {
const divMod = n => [Math.floor(n / 256), n % 256];
let tmp = num;
Expand Down
2 changes: 2 additions & 0 deletions app/assets/javascripts/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ In order to restore the current window, a reload is necessary.`,
"tracing.tree_viewer_no_cyclic_trees":
"Cyclic trees are not supported by the abstract tree viewer.",
"tracing.changed_move_value": "The move value was changed to: ",
"tracing.no_viewport_scaling_setting":
"Scaling the viewports via k/l is not supported anymore. Instead you can increase the viewport size by dragging the borders between the panes. You can also rearrange the panes by dragging the tabs.",
"tracing.natural_sorting": "Correctly sort numbers in text (word2 < word10). This may be slow!",
"tracing.cant_create_node_due_to_active_group":
"You cannot create nodes, since no tree is active.",
Expand Down
2 changes: 1 addition & 1 deletion app/assets/javascripts/oxalis/api/api_latest.js
Original file line number Diff line number Diff line change
Expand Up @@ -804,7 +804,7 @@ class UserApi {
- moveValue3d
- rotateValue
- crosshairSize
- scaleValue
- layoutScaleValue
- mouseRotateValue
- clippingDistance
- clippingDistanceArbitrary
Expand Down
2 changes: 1 addition & 1 deletion app/assets/javascripts/oxalis/api/api_v2.js
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,7 @@ class UserApi {
- moveValue3d
- rotateValue
- crosshairSize
- scaleValue
- layoutScaleValue
- mouseRotateValue
- clippingDistance
- clippingDistanceArbitrary
Expand Down
12 changes: 10 additions & 2 deletions app/assets/javascripts/oxalis/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ export type BoundingBoxType = {
min: Vector3,
max: Vector3,
};
export type Rect = {
top: number,
left: number,
width: number,
height: number,
};

export const AnnotationContentTypes = ["skeleton", "volume", "hybrid"];
export const Vector2Indicies = [0, 1];
Expand All @@ -31,8 +37,10 @@ export const OrthoViews = {
PLANE_XZ: "PLANE_XZ",
TDView: "TDView",
};
export const ArbitraryViewport = "arbitraryViewport";
export type OrthoViewType = $Keys<typeof OrthoViews>;
export type OrthoViewMapType<T> = { [key: OrthoViewType]: T };
export type ViewportType = OrthoViewType | typeof ArbitraryViewport;
export const OrthoViewValues: Array<OrthoViewType> = Object.keys(OrthoViews);
export const OrthoViewIndices = {
PLANE_XY: OrthoViewValues.indexOf("PLANE_XY"),
Expand Down Expand Up @@ -133,8 +141,8 @@ const Constants = {

FPS: 50,

MIN_SCALE: 0.5,
MAX_SCALE: 20,
MIN_LAYOUT_SCALE: 1,
MAX_LAYOUT_SCALE: 5,

MIN_BRUSH_SIZE: 5,
MAX_BRUSH_SIZE: 5000,
Expand Down
23 changes: 7 additions & 16 deletions app/assets/javascripts/oxalis/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,11 @@ class Controller extends React.PureComponent<Props, State> {
));
}

scaleTrianglesPlane(delta: number): void {
let scale = Store.getState().userConfiguration.scale + delta;
scale = Math.min(constants.MAX_SCALE, scale);
scale = Math.max(constants.MIN_SCALE, scale);

Store.dispatch(updateUserSettingAction("scale", scale));
setLayoutScale(multiplier: number): void {
let scale = Store.getState().userConfiguration.layoutScaleValue + 0.05 * multiplier;
scale = Math.min(constants.MAX_LAYOUT_SCALE, scale);
scale = Math.max(constants.MIN_LAYOUT_SCALE, scale);
Store.dispatch(updateUserSettingAction("layoutScaleValue", scale));
}

isWebGlSupported() {
Expand Down Expand Up @@ -276,16 +275,8 @@ class Controller extends React.PureComponent<Props, State> {
this.keyboardNoLoop = new InputKeyboardNoLoop(keyboardControls);

this.keyboard = new InputKeyboard({
// Scale planes
l: timeFactor => {
const scaleValue = Store.getState().userConfiguration.scaleValue;
this.scaleTrianglesPlane(-scaleValue * timeFactor);
},

k: timeFactor => {
const scaleValue = Store.getState().userConfiguration.scaleValue;
this.scaleTrianglesPlane(scaleValue * timeFactor);
},
l: () => this.setLayoutScale(-1),
k: () => this.setLayoutScale(1),
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
} from "oxalis/model/accessors/skeletontracing_accessor";
import type { Point2, Vector3, OrthoViewType, OrthoViewMapType } from "oxalis/constants";
import api from "oxalis/api/internal_api";
import { getInputCatcherRect } from "oxalis/model/accessors/view_mode_accessor";
import { V3 } from "libs/mjs";

const OrthoViewToNumber: OrthoViewMapType<number> = {
Expand Down Expand Up @@ -131,12 +132,16 @@ function onClick(
const pickingScene = new THREE.Scene();
pickingScene.add(pickingNode);

let { width, height } = getInputCatcherRect(plane);
width = Math.round(width);
height = Math.round(height);

const buffer = planeView.renderOrthoViewToTexture(plane, pickingScene);
// Beware of the fact that new browsers yield float numbers for the mouse position
const [x, y] = [Math.round(position.x), Math.round(position.y)];
// compute the index of the pixel under the cursor,
// while inverting along the y-axis, because OpenGL has its origin bottom-left :/
const index = (x + (planeView.curWidth - y) * planeView.curWidth) * 4;
const index = (x + (width - y) * height) * 4;
// the nodeId can be reconstructed by interpreting the RGB values of the pixel as a base-255 number
const nodeId = buffer.subarray(index, index + 3).reduce((a, b) => a * 255 + b, 0);
SceneController.skeleton.stopPicking();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import _ from "lodash";
import Store from "oxalis/store";
import * as Utils from "libs/utils";
import { OrthoViews, VolumeToolEnum, ContourModeEnum } from "oxalis/constants";
import { getViewportScale } from "oxalis/model/accessors/view_mode_accessor";
import { calculateGlobalPos } from "oxalis/controller/viewmodes/plane_controller";
import Model from "oxalis/model";
import { getPosition, getRequestLogZoomStep } from "oxalis/model/accessors/flycam_accessor";
Expand All @@ -33,7 +34,7 @@ import type { OrthoViewType, Point2 } from "oxalis/constants";
const simulateTracing = async (): Promise<void> => {
Store.dispatch(setToolAction(VolumeToolEnum.TRACE));

const controls = getPlaneMouseControls();
const controls = getPlaneMouseControls(OrthoViews.PLANE_XY);
let pos = (x, y) => ({ x, y });

controls.leftMouseDown(pos(100, 100), OrthoViews.PLANE_XY, ({}: any));
Expand All @@ -55,7 +56,7 @@ const simulateTracing = async (): Promise<void> => {
await simulateTracing();
};

export function getPlaneMouseControls(): * {
export function getPlaneMouseControls(planeId: OrthoViewType): * {
return {
leftDownMove: (delta: Point2, pos: Point2) => {
const { tracing } = Store.getState();
Expand All @@ -65,7 +66,7 @@ export function getPlaneMouseControls(): * {

if (tool === VolumeToolEnum.MOVE) {
const state = Store.getState();
const viewportScale = state.userConfiguration.scale;
const viewportScale = getViewportScale(planeId);
const { activeViewport } = state.viewModeData.plane;
const v = [(delta.x * -1) / viewportScale, (delta.y * -1) / viewportScale, 0];
Store.dispatch(movePlaneFlycamOrthoAction(v, activeViewport, true));
Expand Down
2 changes: 2 additions & 0 deletions app/assets/javascripts/oxalis/controller/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ function getRenderer() {
typeof document !== "undefined" && document.getElementById
? new THREE.WebGLRenderer({
canvas: document.getElementById("render-canvas"),
// This prevents flickering when rendering to a buffer instead of the canvas
preserveDrawingBuffer: true,
antialias: true,
})
: {};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import * as Utils from "libs/utils";
import Toast from "libs/toast";
import type { ModeType, Point2 } from "oxalis/constants";
import Store from "oxalis/store";
import { getViewportScale } from "oxalis/model/accessors/view_mode_accessor";
import Model from "oxalis/model";
import {
updateUserSettingAction,
Expand All @@ -32,7 +33,7 @@ import ArbitraryPlane from "oxalis/geometries/arbitrary_plane";
import Crosshair from "oxalis/geometries/crosshair";
import app from "app";
import ArbitraryView from "oxalis/view/arbitrary_view";
import constants from "oxalis/constants";
import constants, { ArbitraryViewport } from "oxalis/constants";
import type { Matrix4x4 } from "libs/mjs";
import {
yawFlycamAction,
Expand All @@ -52,7 +53,7 @@ import { listenToStoreProperty } from "oxalis/model/helpers/listener_helpers";
import SceneController from "oxalis/controller/scene_controller";
import api from "oxalis/api/internal_api";

const CANVAS_SELECTOR = "#render-canvas";
const arbitraryViewportSelector = "#inputcatcher_arbitraryViewport";

type Props = {
onRender: () => void,
Expand Down Expand Up @@ -92,33 +93,33 @@ class ArbitraryController extends React.PureComponent<Props> {
}

initMouse(): void {
this.input.mouse = new InputMouse(CANVAS_SELECTOR, {
leftDownMove: (delta: Point2) => {
if (this.props.viewMode === constants.MODE_ARBITRARY) {
Store.dispatch(
yawFlycamAction(delta.x * Store.getState().userConfiguration.mouseRotateValue, true),
);
Store.dispatch(
pitchFlycamAction(
delta.y * -1 * Store.getState().userConfiguration.mouseRotateValue,
true,
),
);
} else if (this.props.viewMode === constants.MODE_ARBITRARY_PLANE) {
const f =
Store.getState().flycam.zoomStep /
(this.arbitraryView.width / constants.VIEWPORT_WIDTH);
Store.dispatch(moveFlycamAction([delta.x * f, delta.y * f, 0]));
}
},
scroll: this.scroll,
pinch: (delta: number) => {
if (delta < 0) {
Store.dispatch(zoomOutAction());
} else {
Store.dispatch(zoomInAction());
}
},
Utils.waitForSelector(arbitraryViewportSelector).then(() => {
this.input.mouse = new InputMouse(arbitraryViewportSelector, {
leftDownMove: (delta: Point2) => {
if (this.props.viewMode === constants.MODE_ARBITRARY) {
Store.dispatch(
yawFlycamAction(delta.x * Store.getState().userConfiguration.mouseRotateValue, true),
);
Store.dispatch(
pitchFlycamAction(
delta.y * -1 * Store.getState().userConfiguration.mouseRotateValue,
true,
),
);
} else if (this.props.viewMode === constants.MODE_ARBITRARY_PLANE) {
const f = Store.getState().flycam.zoomStep / getViewportScale(ArbitraryViewport);
Store.dispatch(moveFlycamAction([delta.x * f, delta.y * f, 0]));
}
},
scroll: this.scroll,
pinch: (delta: number) => {
if (delta < 0) {
Store.dispatch(zoomOutAction());
} else {
Store.dispatch(zoomInAction());
}
},
});
});
}

Expand Down Expand Up @@ -290,7 +291,7 @@ class ArbitraryController extends React.PureComponent<Props> {
this.setClippingDistance(clippingDistanceArbitrary);
this.crosshair.setScale(crosshairSize);
this.crosshair.setVisibility(displayCrosshair);
this.arbitraryView.resize();
this.arbitraryView.resizeThrottled();
},
),
listenToStoreProperty(
Expand Down
Loading