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

Fix Bounding Box download modal and node selection #5624

Merged
merged 19 commits into from
Jul 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
66c913c
add load precomputeed mesh to context menu in view and skeleton only …
MichaelBuessemeyer Jul 9, 2021
6cf8a2a
consistent context menu naming
MichaelBuessemeyer Jul 9, 2021
3ed2180
fix segment id icon in dark mode
MichaelBuessemeyer Jul 9, 2021
817ec1b
Merge branch 'master' into panel-content-and-new-controls-followup
normanrz Jul 13, 2021
0465db3
Fix loading mesh at clicked context menu position && Merge branch 'ma…
MichaelBuessemeyer Jul 15, 2021
34ff977
Merge branch 'panel-content-and-new-controls-followup' of github.com:…
MichaelBuessemeyer Jul 15, 2021
82c1d2c
fix linting
MichaelBuessemeyer Jul 15, 2021
8885d65
Merge branch 'master' of github.com:scalableminds/webknossos into pan…
MichaelBuessemeyer Jul 15, 2021
4b78330
fix export bounding box modal not rendering
MichaelBuessemeyer Jul 15, 2021
f7561dd
reduce far clipping plane for node selection to directly in front of …
MichaelBuessemeyer Jul 15, 2021
efba904
add changelog entry
MichaelBuessemeyer Jul 16, 2021
fc53087
fix that actual clippingDistance setting could not be tweaked for pla…
philippotto Jul 20, 2021
1e62ff5
use actual far value when rendering to texture
philippotto Jul 20, 2021
a6da9fe
rename destroy to handleClose
philippotto Jul 20, 2021
91ce5a7
add disclaimer comment to withFarClipping
philippotto Jul 20, 2021
129858e
fix node picking in 3D viewport
philippotto Jul 21, 2021
aca3e7c
incorporate PR feedback
philippotto Jul 21, 2021
0fb8c1b
Merge branch 'master' of github.com:scalableminds/webknossos into pan…
philippotto Jul 21, 2021
f3df782
Merge branch 'master' into panel-content-and-new-controls-followup
philippotto Jul 21, 2021
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: 2 additions & 0 deletions CHANGELOG.unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,12 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released
- Fixed a bug where dataset uploads of zips with just one file inside failed. [#5534](https://github.com/scalableminds/webknossos/pull/5534)
- Fixed a benign error message when a dataset without a segmentation layer was opened in view mode or with a skeleton-only annotation. [#5583](https://github.com/scalableminds/webknossos/pull/5583)
- Fixed crashing tree tab which could happen when dragging a node and then switching directly to another tab (e.g., comments) and then back again. [#5573](https://github.com/scalableminds/webknossos/pull/5573)
- Fixed a bug that the selection of nodes in the skeleton tool was possible for nodes far behind the position and thus prevented creating new nodes. [#5624](https://github.com/scalableminds/webknossos/pull/5624)
- Fixed that the UI allowed mutating trees in the tree tab (dragging/creating/deleting trees and groups) in read-only tracings. [#5573](https://github.com/scalableminds/webknossos/pull/5573)
- Fixed "Create a new tree group for this file" setting in front-end import when a group id of 0 was used in the NML. [#5573](https://github.com/scalableminds/webknossos/pull/5573)
- Fixed a bug that caused a distortion when moving or zooming in the maximized 3d viewport. [#5550](https://github.com/scalableminds/webknossos/pull/5550)
- Fixed a bug that prevented focusing the login fields when being prompted to login after trying to view a dataset without being logged in.[#5521](https://github.com/scalableminds/webknossos/pull/5577)
- Fixed a bug that prevented the modal to export data of a bounding box to tiff files to open up. [#5624](https://github.com/scalableminds/webknossos/pull/5624)
- Fixed that the 3d view content disappeared permanently if the 3d view was resized to not be visible. [#5588](https://github.com/scalableminds/webknossos/pull/5588)
- The following changes belong to [#5384](https://github.com/scalableminds/webknossos/pull/5384):
- Removed "Highlight hovered cells" setting (highlight on hover will always be done).
Expand Down
5 changes: 5 additions & 0 deletions frontend/javascripts/oxalis/controller/camera_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,11 @@ class CameraController extends React.PureComponent<Props> {
this.props.cameras[planeId].bottom = -height / 2;
this.props.cameras[planeId].top = height / 2;

// We only set the `near` value here. The effect of far=clippingDistance is
// achieved by offsetting the plane onto which is rendered by the amount
// of clippingDistance. Theoretically, `far` could be set here too, however,
// this leads to imprecision related bugs which cause the planes to not render
// for certain clippingDistance values.
this.props.cameras[planeId].near = -clippingDistance;
this.props.cameras[planeId].updateProjectionMatrix();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,8 +291,7 @@ export function maybeGetNodeIdFromPosition(
let { width, height } = getInputCatcherRect(Store.getState(), plane);
width = Math.round(width);
height = Math.round(height);

const buffer = renderToTexture(plane, pickingScene, camera);
const buffer = renderToTexture(plane, pickingScene, camera, true);
// Beware of the fact that new browsers yield float numbers for the mouse position
// Subtract the CSS border as the renderer viewport is smaller than the inputcatcher
const borderWidth = OUTER_CSS_BORDER;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ import LinkButton from "components/link_button";
import Toast from "libs/toast";
import * as Utils from "libs/utils";
import api from "oxalis/api/internal_api";
import { type Vector3, type ControlMode, ControlModeEnum } from "oxalis/constants";
import Constants, { type Vector3, type ControlMode, ControlModeEnum } from "oxalis/constants";
import {
enforceSkeletonTracing,
getActiveNode,
Expand Down Expand Up @@ -101,6 +101,7 @@ type DatasetSettingsProps = {|
onChangeEnableAutoBrush: (active: boolean) => void,
isAutoBrushEnabled: boolean,
controlMode: ControlMode,
isArbitraryMode: boolean,
|};

function DownsampleVolumeModal({ visible, hideDownsampleVolumeModal, magsToDownsample }) {
Expand Down Expand Up @@ -740,13 +741,24 @@ class DatasetSettings extends React.PureComponent<DatasetSettingsProps, State> {
value={userConfiguration.particleSize}
onChange={this.onChangeUser.particleSize}
/>
<NumberSliderSetting
label={settings.clippingDistanceArbitrary}
min={userSettings.clippingDistanceArbitrary.minimum}
max={userSettings.clippingDistanceArbitrary.maximum}
value={userConfiguration.clippingDistanceArbitrary}
onChange={this.onChangeUser.clippingDistanceArbitrary}
/>
{this.props.isArbitraryMode ? (
<NumberSliderSetting
label={settings.clippingDistanceArbitrary}
min={userSettings.clippingDistanceArbitrary.minimum}
max={userSettings.clippingDistanceArbitrary.maximum}
value={userConfiguration.clippingDistanceArbitrary}
onChange={this.onChangeUser.clippingDistanceArbitrary}
/>
) : (
<LogSliderSetting
philippotto marked this conversation as resolved.
Show resolved Hide resolved
label={settings.clippingDistance}
roundTo={3}
min={userSettings.clippingDistance.minimum}
max={userSettings.clippingDistance.maximum}
value={userConfiguration.clippingDistance}
onChange={this.onChangeUser.clippingDistance}
/>
)}
<SwitchSetting
label={settings.overrideNodeRadius}
value={userConfiguration.overrideNodeRadius}
Expand Down Expand Up @@ -809,6 +821,7 @@ const mapStateToProps = (state: OxalisState) => ({
task: state.task,
controlMode: state.temporaryConfiguration.controlMode,
isAutoBrushEnabled: state.temporaryConfiguration.isAutoBrushEnabled,
isArbitraryMode: Constants.MODES_ARBITRARY.includes(state.temporaryConfiguration.viewMode),
});

const mapDispatchToProps = (dispatch: Dispatch<*>) => ({
Expand Down
27 changes: 25 additions & 2 deletions frontend/javascripts/oxalis/view/rendering_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import constants, {
ArbitraryViewport,
OrthoViewColors,
OrthoViewValues,
OrthoViews,
} from "oxalis/constants";
import { getInputCatcherRect } from "oxalis/model/accessors/view_mode_accessor";
import getSceneController from "oxalis/controller/scene_controller_provider";
Expand Down Expand Up @@ -43,16 +44,37 @@ export function renderToTexture(
plane: OrthoView | typeof ArbitraryViewport,
scene?: typeof THREE.Scene,
camera?: typeof THREE.Camera,
// When withFarClipping is true, the user-specified clipping distance is used.
// Note that the data planes might not be included in the rendered texture, since
// these are exactly offset by the clipping distance. Currently, `withFarClipping`
// is only used for node picking (which does not render the data planes), which is why
// this behavior is not problematic for us.
withFarClipping?: boolean,
clearColor?: number,
): Uint8Array {
const SceneController = getSceneController();
const { renderer, scene: defaultScene } = SceneController;
const state = Store.getState();
scene = scene || defaultScene;
camera = camera || scene.getObjectByName(plane);

// Don't respect withFarClipping for the TDViewport as we don't do any clipping for
// nodes there.
if (withFarClipping && plane !== OrthoViews.TDView) {
const isArbitraryMode = constants.MODES_ARBITRARY.includes(
state.temporaryConfiguration.viewMode,
);
camera = camera.clone();
camera.far = isArbitraryMode
? state.userConfiguration.clippingDistanceArbitrary
: state.userConfiguration.clippingDistance;

camera.updateProjectionMatrix();
}
clearColor = clearColor != null ? clearColor : 0x000000;

renderer.autoClear = true;
let { width, height } = getInputCatcherRect(Store.getState(), plane);
let { width, height } = getInputCatcherRect(state, plane);
width = Math.round(width);
height = Math.round(height);

Expand All @@ -71,6 +93,7 @@ export function renderToTexture(
renderer.render(scene, camera);
renderer.readRenderTargetPixels(renderTarget, 0, 0, width, height, buffer);
renderer.setRenderTarget(null);

return buffer;
}

Expand All @@ -91,7 +114,7 @@ export async function downloadScreenshot() {

// $FlowIssue[prop-missing] planeId cannot be arbitraryViewport in OrthoViewColors access
const clearColor = OrthoViewValues.includes(planeId) ? OrthoViewColors[planeId] : 0xffffff;
const buffer = renderToTexture(planeId, null, null, clearColor);
const buffer = renderToTexture(planeId, null, null, false, clearColor);

// eslint-disable-next-line no-await-in-loop
const blob = await convertBufferToImage(buffer, width, height);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Tooltip } from "antd";
import { PlusSquareOutlined } from "@ant-design/icons";
import type { Dispatch } from "redux";
import { connect } from "react-redux";
import React from "react";
import React, { useState } from "react";
import _ from "lodash";

import type { APIDataset } from "types/api_flow_types";
Expand All @@ -20,7 +20,6 @@ import { getDatasetExtentInVoxel } from "oxalis/model/accessors/dataset_accessor
import { setUserBoundingBoxesAction } from "oxalis/model/actions/annotation_actions";
import * as Utils from "libs/utils";

import renderIndependently from "libs/render_independently";
import ExportBoundingBoxModal from "oxalis/view/right-border-tabs/export_bounding_box_modal";

type BoundingBoxTabProps = {
Expand All @@ -30,6 +29,7 @@ type BoundingBoxTabProps = {
};

function BoundingBoxTab(props: BoundingBoxTabProps) {
const [selectedBoundingBoxForExport, setSelectedBoundingBoxForExport] = useState(null);
const { tracing, dataset, onChangeBoundingBoxes } = props;
const { userBoundingBoxes } = getSomeTracing(tracing);

Expand Down Expand Up @@ -76,20 +76,6 @@ function BoundingBoxTab(props: BoundingBoxTabProps) {
onChangeBoundingBoxes(updatedUserBoundingBoxes);
}

function handleExportUserBoundingBox(id: number) {
const selectedBoundingBox = userBoundingBoxes.find(boundingBox => boundingBox.id === id);
if (selectedBoundingBox) {
renderIndependently(destroy => (
<ExportBoundingBoxModal
dataset={dataset}
tracing={tracing}
boundingBox={selectedBoundingBox.boundingBox}
destroy={destroy}
/>
));
}
}

return (
<div className="padded-tab-content" style={{ minWidth: 300 }}>
{userBoundingBoxes.length > 0 ? (
Expand All @@ -103,7 +89,7 @@ function BoundingBoxTab(props: BoundingBoxTabProps) {
isVisible={bb.isVisible}
onChange={_.partial(handleChangeUserBoundingBox, bb.id)}
onDelete={_.partial(handleDeleteUserBoundingBox, bb.id)}
onExport={_.partial(handleExportUserBoundingBox, bb.id)}
onExport={_.partial(setSelectedBoundingBoxForExport, bb)}
/>
))
) : (
Expand All @@ -120,6 +106,14 @@ function BoundingBoxTab(props: BoundingBoxTabProps) {
/>
</Tooltip>
</div>
{selectedBoundingBoxForExport != null ? (
<ExportBoundingBoxModal
dataset={dataset}
tracing={tracing}
boundingBox={selectedBoundingBoxForExport.boundingBox}
handleClose={() => setSelectedBoundingBoxForExport(null)}
/>
) : null}
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import * as Utils from "libs/utils";
import { useSelector } from "react-redux";

type Props = {
destroy: () => void,
handleClose: () => void,
tracing: ?Tracing,
dataset: APIDataset,
boundingBox: BoundingBoxType,
Expand All @@ -32,7 +32,7 @@ type LayerInfos = {
isColorLayer: ?boolean,
};

const ExportBoundingBoxModal = ({ destroy, dataset, boundingBox, tracing }: Props) => {
const ExportBoundingBoxModal = ({ handleClose, dataset, boundingBox, tracing }: Props) => {
const [startedExports, setStartedExports] = useState([]);
const volumeTracing = tracing != null ? tracing.volume : null;
const annotationId = tracing != null ? tracing.annotationId : null;
Expand All @@ -50,10 +50,6 @@ const ExportBoundingBoxModal = ({ destroy, dataset, boundingBox, tracing }: Prop
);
const existsActivePersistentMapping = isMappingEnabled && !isMergerModeEnabled;

const handleClose = () => {
destroy();
};

const exportKey = (layerInfos: LayerInfos) =>
(layerInfos.layerName || "") + (layerInfos.tracingId || "");

Expand Down