From 66c913c88b2c8b1812c1ffdd28809d4e350bffbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20B=C3=BC=C3=9Femeyer?= Date: Fri, 9 Jul 2021 12:04:28 +0200 Subject: [PATCH 01/13] add load precomputeed mesh to context menu in view and skeleton only mode --- .../javascripts/oxalis/view/context_menu.js | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/frontend/javascripts/oxalis/view/context_menu.js b/frontend/javascripts/oxalis/view/context_menu.js index ef1c9a8a72c..502e62fdc5f 100644 --- a/frontend/javascripts/oxalis/view/context_menu.js +++ b/frontend/javascripts/oxalis/view/context_menu.js @@ -282,6 +282,17 @@ function NoNodeContextMenuOptions({ , ] : []; + + const loadMeshItem = ( + + Load Precomputed Mesh + + ); const nonSkeletonActions = volumeTracing != null ? [ @@ -296,16 +307,7 @@ function NoNodeContextMenuOptions({ Select Segment ({cellIdAtPosition}) ) : null, - - - Load Precomputed Mesh - , - + loadMeshItem, , ] - : []; + : [loadMeshItem]; const allActions = isSkeletonToolActive ? skeletonActions.concat(nonSkeletonActions) From 6cf8a2a177ffc2a47dcb65ff6aad420203ab9c1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20B=C3=BC=C3=9Femeyer?= Date: Fri, 9 Jul 2021 12:28:51 +0200 Subject: [PATCH 02/13] consistent context menu naming --- frontend/javascripts/oxalis/controller.js | 4 +- .../controller/viewmodes/plane_controller.js | 10 ++-- .../javascripts/oxalis/view/context_menu.js | 24 ++++----- .../view/layouting/tracing_layout_view.js | 50 +++++++++---------- 4 files changed, 44 insertions(+), 44 deletions(-) diff --git a/frontend/javascripts/oxalis/controller.js b/frontend/javascripts/oxalis/controller.js index 566ba835690..bfc453f4cba 100644 --- a/frontend/javascripts/oxalis/controller.js +++ b/frontend/javascripts/oxalis/controller.js @@ -50,7 +50,7 @@ type OwnProps = {| initialCommandType: TraceOrViewCommand, controllerStatus: ControllerStatus, setControllerStatus: ControllerStatus => void, - showNodeContextMenuAt: ShowContextMenuFunction, + showContextMenuAt: ShowContextMenuFunction, |}; type StateProps = {| viewMode: ViewMode, @@ -337,7 +337,7 @@ class Controller extends React.PureComponent { if (isArbitrary) { return ; } else if (isPlane) { - return ; + return ; } else { // At the moment, all possible view modes consist of the union of MODES_ARBITRARY and MODES_PLANE // In case we add new viewmodes, the following error will be thrown. diff --git a/frontend/javascripts/oxalis/controller/viewmodes/plane_controller.js b/frontend/javascripts/oxalis/controller/viewmodes/plane_controller.js index 75ca17007e8..4229d47f67d 100644 --- a/frontend/javascripts/oxalis/controller/viewmodes/plane_controller.js +++ b/frontend/javascripts/oxalis/controller/viewmodes/plane_controller.js @@ -73,7 +73,7 @@ function ensureNonConflictingHandlers(skeletonControls: Object, volumeControls: } } -type OwnProps = {| showNodeContextMenuAt: ShowContextMenuFunction |}; +type OwnProps = {| showContextMenuAt: ShowContextMenuFunction |}; type StateProps = {| tracing: Tracing, @@ -209,23 +209,23 @@ class PlaneController extends React.PureComponent { const moveControls = MoveTool.getMouseControls( planeId, this.planeView, - this.props.showNodeContextMenuAt, + this.props.showContextMenuAt, ); const skeletonControls = SkeletonTool.getMouseControls( this.planeView, - this.props.showNodeContextMenuAt, + this.props.showContextMenuAt, ); const drawControls = DrawTool.getPlaneMouseControls( planeId, this.planeView, - this.props.showNodeContextMenuAt, + this.props.showContextMenuAt, ); const eraseControls = EraseTool.getPlaneMouseControls( planeId, this.planeView, - this.props.showNodeContextMenuAt, + this.props.showContextMenuAt, ); const fillCellControls = FillCellTool.getPlaneMouseControls(planeId); const pickCellControls = PickCellTool.getPlaneMouseControls(planeId); diff --git a/frontend/javascripts/oxalis/view/context_menu.js b/frontend/javascripts/oxalis/view/context_menu.js index 502e62fdc5f..2e239288786 100644 --- a/frontend/javascripts/oxalis/view/context_menu.js +++ b/frontend/javascripts/oxalis/view/context_menu.js @@ -42,11 +42,11 @@ import { getRequestLogZoomStep } from "oxalis/model/accessors/flycam_accessor"; /* eslint-disable react/no-unused-prop-types */ // The newest eslint version thinks the props listed below aren't used. type OwnProps = {| - nodeContextMenuPosition: [number, number], + contextMenuPosition: [number, number], clickedNodeId: ?number, globalPosition: Vector3, viewport: OrthoView, - hideNodeContextMenu: () => void, + hideContextMenu: () => void, |}; type DispatchProps = {| @@ -141,7 +141,7 @@ function getMaybeHoveredCellMenuItem(globalPosition: Vector3) { function NodeContextMenuOptions({ skeletonTracing, clickedNodeId, - hideNodeContextMenu, + hideContextMenu, deleteEdge, mergeTrees, deleteNode, @@ -163,7 +163,7 @@ function NodeContextMenuOptions({ ); } return ( - + + {allActions} ); @@ -346,8 +346,8 @@ function ContextMenu(props: Props) { skeletonTracing, isSkeletonToolActive, clickedNodeId, - nodeContextMenuPosition, - hideNodeContextMenu, + contextMenuPosition, + hideContextMenu, datasetScale, globalPosition, } = props; @@ -431,15 +431,15 @@ function ContextMenu(props: Props) {
- + {clickedNodeId != null ? NodeContextMenuOptions({ ...props, clickedNodeId }) : NoNodeContextMenuOptions({ isSkeletonToolActive, cellIdAtPosition, ...props })} diff --git a/frontend/javascripts/oxalis/view/layouting/tracing_layout_view.js b/frontend/javascripts/oxalis/view/layouting/tracing_layout_view.js index 8089f0d51e4..668edb4df72 100644 --- a/frontend/javascripts/oxalis/view/layouting/tracing_layout_view.js +++ b/frontend/javascripts/oxalis/view/layouting/tracing_layout_view.js @@ -18,7 +18,7 @@ import type { OxalisState, AnnotationType, TraceOrViewCommand } from "oxalis/sto import { RenderToPortal } from "oxalis/view/layouting/portal_utils"; import { updateUserSettingAction } from "oxalis/model/actions/settings_actions"; import ActionBarView from "oxalis/view/action_bar_view"; -import NodeContextMenu from "oxalis/view/context_menu"; +import ContextMenu from "oxalis/view/context_menu"; import ButtonComponent from "oxalis/view/components/button_component"; import NmlUploadZoneContainer from "oxalis/view/nml_upload_zone_container"; import OxalisController from "oxalis/controller"; @@ -80,10 +80,10 @@ type State = { activeLayoutName: string, hasError: boolean, status: ControllerStatus, - nodeContextMenuPosition: ?[number, number], + contextMenuPosition: ?[number, number], clickedNodeId: ?number, - nodeContextMenuGlobalPosition: Vector3, - nodeContextMenuViewport: ?OrthoView, + contextMenuGlobalPosition: Vector3, + contextMenuViewport: ?OrthoView, model: Object, }; @@ -109,10 +109,10 @@ class TracingLayoutView extends React.PureComponent { activeLayoutName: lastActiveLayoutName, hasError: false, status: "loading", - nodeContextMenuPosition: null, + contextMenuPosition: null, clickedNodeId: null, - nodeContextMenuGlobalPosition: [0, 0, 0], - nodeContextMenuViewport: null, + contextMenuGlobalPosition: [0, 0, 0], + contextMenuViewport: null, model: layout, }; } @@ -157,7 +157,7 @@ class TracingLayoutView extends React.PureComponent { initializeInputCatcherSizes(); }; - showNodeContextMenuAt = ( + showContextMenuAt = ( xPos: number, yPos: number, nodeId: ?number, @@ -165,19 +165,19 @@ class TracingLayoutView extends React.PureComponent { viewport: OrthoView, ) => { this.setState({ - nodeContextMenuPosition: [xPos, yPos], + contextMenuPosition: [xPos, yPos], clickedNodeId: nodeId, - nodeContextMenuGlobalPosition: globalPosition, - nodeContextMenuViewport: viewport, + contextMenuGlobalPosition: globalPosition, + contextMenuViewport: viewport, }); }; - hideNodeContextMenu = () => { + hideContextMenu = () => { this.setState({ - nodeContextMenuPosition: null, + contextMenuPosition: null, clickedNodeId: null, - nodeContextMenuGlobalPosition: [0, 0, 0], - nodeContextMenuViewport: null, + contextMenuGlobalPosition: [0, 0, 0], + contextMenuViewport: null, }); }; @@ -237,9 +237,9 @@ class TracingLayoutView extends React.PureComponent { const { clickedNodeId, - nodeContextMenuPosition, - nodeContextMenuGlobalPosition, - nodeContextMenuViewport, + contextMenuPosition, + contextMenuGlobalPosition, + contextMenuViewport, status, activeLayoutName, } = this.state; @@ -265,13 +265,13 @@ class TracingLayoutView extends React.PureComponent { return ( - {nodeContextMenuPosition != null && nodeContextMenuViewport != null ? ( - ) : null} { initialCommandType={this.props.initialCommandType} controllerStatus={status} setControllerStatus={this.onStatusLoaded} - showNodeContextMenuAt={this.showNodeContextMenuAt} + showContextMenuAt={this.showContextMenuAt} /> From 3ed2180c81dfdc867f8594b46801cb14400f95c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20B=C3=BC=C3=9Femeyer?= Date: Fri, 9 Jul 2021 13:03:06 +0200 Subject: [PATCH 03/13] fix segment id icon in dark mode --- .../javascripts/oxalis/view/context_menu.js | 2 +- frontend/stylesheets/dark.less | 4 ++ .../stylesheets/trace_view/_tracing_view.less | 6 +- public/images/cell-bright.svg | 56 +++++++++++++++++ public/images/cell.svg | 62 ++++++++++++++++--- 5 files changed, 119 insertions(+), 11 deletions(-) create mode 100644 public/images/cell-bright.svg diff --git a/frontend/javascripts/oxalis/view/context_menu.js b/frontend/javascripts/oxalis/view/context_menu.js index 2e239288786..d1d8939ee1c 100644 --- a/frontend/javascripts/oxalis/view/context_menu.js +++ b/frontend/javascripts/oxalis/view/context_menu.js @@ -415,7 +415,7 @@ function ContextMenu(props: Props) { if (cellIdAtPosition > 0) { infoRows.push(
- Segment Icon +
Segment ID: {cellIdAtPosition} {copyIconWithTooltip(cellIdAtPosition, "Copy Segment ID")}
, ); diff --git a/frontend/stylesheets/dark.less b/frontend/stylesheets/dark.less index 9b83487155c..d1ff4a5c3fe 100644 --- a/frontend/stylesheets/dark.less +++ b/frontend/stylesheets/dark.less @@ -54,3 +54,7 @@ a:hover { .icon-sidebar-show-right-bright { background-image: url(/assets/images/icon-sidebar-show-right-dark.svg); } + +.cell-context-icon { + background-image: url("/assets/images/cell-bright.svg"); +} diff --git a/frontend/stylesheets/trace_view/_tracing_view.less b/frontend/stylesheets/trace_view/_tracing_view.less index ff3ac33600c..e06326d6aac 100644 --- a/frontend/stylesheets/trace_view/_tracing_view.less +++ b/frontend/stylesheets/trace_view/_tracing_view.less @@ -495,8 +495,12 @@ img.keyboard-mouse-icon:first-child { } .cell-context-icon { - margin-right: 12px; + margin-right: 8px; height: 12px; + width: 15px; + display: inline-block; + background-image: url("/assets/images/cell.svg"); + background-size: contain; } .resolution-status-bar-icon { diff --git a/public/images/cell-bright.svg b/public/images/cell-bright.svg new file mode 100644 index 00000000000..b76f6e79663 --- /dev/null +++ b/public/images/cell-bright.svg @@ -0,0 +1,56 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/public/images/cell.svg b/public/images/cell.svg index 4ab245b0571..9c2a0aa62ba 100644 --- a/public/images/cell.svg +++ b/public/images/cell.svg @@ -1,12 +1,56 @@ + + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="16" + height="15" + viewBox="0 0 16 16" + fill="none" + version="1.1" + id="svg4" + sodipodi:docname="cell.svg" + inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"> + + + + image/svg+xml + + + + + + + d="M14.5402 10.5083C12.1152 14.9889 8.06642 16.4429 6.16263 15.8874C4.25884 15.3319 2.37908 13.2516 3.19622 11.143C4.01337 9.03438 7.94247 9.03438 8.50271 6.74256C9.06295 4.45074 10.3156 -0.669029 13.282 0.0727835C16.2484 0.814596 16.9651 6.02769 14.5402 10.5083Z" + fill="#000000a6" + id="path2" + style="fill:#4d4d4d;fill-opacity:1" /> From 82c1d2c3370d87ab985d2f6fdc9af6c35885a646 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20B=C3=BC=C3=9Femeyer?= Date: Thu, 15 Jul 2021 11:14:39 +0200 Subject: [PATCH 04/13] fix linting --- .../javascripts/oxalis/view/right-border-tabs/meshes_view.js | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/javascripts/oxalis/view/right-border-tabs/meshes_view.js b/frontend/javascripts/oxalis/view/right-border-tabs/meshes_view.js index 657de25f87a..083b0ee983a 100644 --- a/frontend/javascripts/oxalis/view/right-border-tabs/meshes_view.js +++ b/frontend/javascripts/oxalis/view/right-border-tabs/meshes_view.js @@ -13,7 +13,6 @@ import { connect } from "react-redux"; import React from "react"; import _ from "lodash"; -import api from "oxalis/api/internal_api"; import Toast from "libs/toast"; import type { ExtractReturn } from "libs/type_helpers"; import type { RemoteMeshMetaData } from "types/api_flow_types"; From 4b783302bd8fd963d07a7c84994451c26bb877c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20B=C3=BC=C3=9Femeyer?= Date: Thu, 15 Jul 2021 16:00:08 +0200 Subject: [PATCH 05/13] fix export bounding box modal not rendering --- .../right-border-tabs/bounding_box_tab.js | 28 ++++++++----------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/frontend/javascripts/oxalis/view/right-border-tabs/bounding_box_tab.js b/frontend/javascripts/oxalis/view/right-border-tabs/bounding_box_tab.js index afb976b4585..8995f0a2c7d 100644 --- a/frontend/javascripts/oxalis/view/right-border-tabs/bounding_box_tab.js +++ b/frontend/javascripts/oxalis/view/right-border-tabs/bounding_box_tab.js @@ -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"; @@ -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 = { @@ -30,6 +29,7 @@ type BoundingBoxTabProps = { }; function BoundingBoxTab(props: BoundingBoxTabProps) { + const [selectedBoundingBoxForExport, setSelectedBoundingBoxForExport] = useState(null); const { tracing, dataset, onChangeBoundingBoxes } = props; const { userBoundingBoxes } = getSomeTracing(tracing); @@ -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 => ( - - )); - } - } - return (
{userBoundingBoxes.length > 0 ? ( @@ -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)} /> )) ) : ( @@ -120,6 +106,14 @@ function BoundingBoxTab(props: BoundingBoxTabProps) { />
+ {selectedBoundingBoxForExport != null ? ( + setSelectedBoundingBoxForExport(null)} + /> + ) : null}
); } From f7561dd4d5f93b8972f50af490672e30b6ee2282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20B=C3=BC=C3=9Femeyer?= Date: Thu, 15 Jul 2021 18:25:09 +0200 Subject: [PATCH 06/13] reduce far clipping plane for node selection to directly in front of the camera --- .../oxalis/controller/combinations/skeleton_handlers.js | 3 +-- frontend/javascripts/oxalis/view/rendering_utils.js | 8 +++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/frontend/javascripts/oxalis/controller/combinations/skeleton_handlers.js b/frontend/javascripts/oxalis/controller/combinations/skeleton_handlers.js index 9d6a9411aac..619ec518ae5 100644 --- a/frontend/javascripts/oxalis/controller/combinations/skeleton_handlers.js +++ b/frontend/javascripts/oxalis/controller/combinations/skeleton_handlers.js @@ -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; diff --git a/frontend/javascripts/oxalis/view/rendering_utils.js b/frontend/javascripts/oxalis/view/rendering_utils.js index 9b1ed80d229..56d07f97a5e 100644 --- a/frontend/javascripts/oxalis/view/rendering_utils.js +++ b/frontend/javascripts/oxalis/view/rendering_utils.js @@ -43,12 +43,18 @@ export function renderToTexture( plane: OrthoView | typeof ArbitraryViewport, scene?: typeof THREE.Scene, camera?: typeof THREE.Camera, + withFarClipping?: boolean, clearColor?: number, ): Uint8Array { const SceneController = getSceneController(); const { renderer, scene: defaultScene } = SceneController; scene = scene || defaultScene; camera = camera || scene.getObjectByName(plane); + if (withFarClipping) { + camera = camera.clone(); + camera.far = 1; + camera.updateProjectionMatrix(); + } clearColor = clearColor != null ? clearColor : 0x000000; renderer.autoClear = true; @@ -91,7 +97,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); From efba904de531ce10acef98aa6155b90cacb40d5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20B=C3=BC=C3=9Femeyer?= Date: Fri, 16 Jul 2021 10:59:42 +0200 Subject: [PATCH 07/13] add changelog entry --- CHANGELOG.unreleased.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 7bb0332853b..abc1c3607a5 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -46,10 +46,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). From fc53087fc9edc9f9afd9ae083ab8b00c2690dfe8 Mon Sep 17 00:00:00 2001 From: Philipp Otto Date: Tue, 20 Jul 2021 18:22:13 +0200 Subject: [PATCH 08/13] fix that actual clippingDistance setting could not be tweaked for plane mode --- .../left-border-tabs/layer_settings_tab.js | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/frontend/javascripts/oxalis/view/left-border-tabs/layer_settings_tab.js b/frontend/javascripts/oxalis/view/left-border-tabs/layer_settings_tab.js index cf8d0d41265..7b4ea40129b 100644 --- a/frontend/javascripts/oxalis/view/left-border-tabs/layer_settings_tab.js +++ b/frontend/javascripts/oxalis/view/left-border-tabs/layer_settings_tab.js @@ -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, @@ -101,6 +101,7 @@ type DatasetSettingsProps = {| onChangeEnableAutoBrush: (active: boolean) => void, isAutoBrushEnabled: boolean, controlMode: ControlMode, + isArbitraryMode: boolean, |}; function DownsampleVolumeModal({ visible, hideDownsampleVolumeModal, magsToDownsample }) { @@ -740,13 +741,24 @@ class DatasetSettings extends React.PureComponent { value={userConfiguration.particleSize} onChange={this.onChangeUser.particleSize} /> - + {this.props.isArbitraryMode ? ( + + ) : ( + + )} ({ task: state.task, controlMode: state.temporaryConfiguration.controlMode, isAutoBrushEnabled: state.temporaryConfiguration.isAutoBrushEnabled, + isArbitraryMode: Constants.MODES_ARBITRARY.includes(state.temporaryConfiguration.viewMode), }); const mapDispatchToProps = (dispatch: Dispatch<*>) => ({ From 1e62ff56f0ea2e48ee1f79347a3a2979c92afceb Mon Sep 17 00:00:00 2001 From: Philipp Otto Date: Tue, 20 Jul 2021 18:22:30 +0200 Subject: [PATCH 09/13] use actual far value when rendering to texture --- .../oxalis/controller/camera_controller.js | 5 +++++ .../javascripts/oxalis/view/rendering_utils.js | 16 ++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/frontend/javascripts/oxalis/controller/camera_controller.js b/frontend/javascripts/oxalis/controller/camera_controller.js index a67fce9b37d..337dc27194a 100644 --- a/frontend/javascripts/oxalis/controller/camera_controller.js +++ b/frontend/javascripts/oxalis/controller/camera_controller.js @@ -141,6 +141,11 @@ class CameraController extends React.PureComponent { 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 offsettng 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(); } diff --git a/frontend/javascripts/oxalis/view/rendering_utils.js b/frontend/javascripts/oxalis/view/rendering_utils.js index 56d07f97a5e..4a74ca42669 100644 --- a/frontend/javascripts/oxalis/view/rendering_utils.js +++ b/frontend/javascripts/oxalis/view/rendering_utils.js @@ -48,17 +48,27 @@ export function renderToTexture( ): Uint8Array { const SceneController = getSceneController(); const { renderer, scene: defaultScene } = SceneController; + const state = Store.getState(); scene = scene || defaultScene; camera = camera || scene.getObjectByName(plane); + + const previousFarValue = camera.far; + if (withFarClipping) { + const isArbitraryMode = constants.MODES_ARBITRARY.includes( + state.temporaryConfiguration.viewMode, + ); camera = camera.clone(); - camera.far = 1; + 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); @@ -77,6 +87,8 @@ export function renderToTexture( renderer.render(scene, camera); renderer.readRenderTargetPixels(renderTarget, 0, 0, width, height, buffer); renderer.setRenderTarget(null); + + camera.far = previousFarValue; return buffer; } From a6da9fec0db1eff07dac676930f2f1e38c1bfe32 Mon Sep 17 00:00:00 2001 From: Philipp Otto Date: Tue, 20 Jul 2021 18:23:50 +0200 Subject: [PATCH 10/13] rename destroy to handleClose --- .../oxalis/view/right-border-tabs/bounding_box_tab.js | 2 +- .../view/right-border-tabs/export_bounding_box_modal.js | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/frontend/javascripts/oxalis/view/right-border-tabs/bounding_box_tab.js b/frontend/javascripts/oxalis/view/right-border-tabs/bounding_box_tab.js index 8995f0a2c7d..7888066851c 100644 --- a/frontend/javascripts/oxalis/view/right-border-tabs/bounding_box_tab.js +++ b/frontend/javascripts/oxalis/view/right-border-tabs/bounding_box_tab.js @@ -111,7 +111,7 @@ function BoundingBoxTab(props: BoundingBoxTabProps) { dataset={dataset} tracing={tracing} boundingBox={selectedBoundingBoxForExport.boundingBox} - destroy={() => setSelectedBoundingBoxForExport(null)} + handleClose={() => setSelectedBoundingBoxForExport(null)} /> ) : null}
diff --git a/frontend/javascripts/oxalis/view/right-border-tabs/export_bounding_box_modal.js b/frontend/javascripts/oxalis/view/right-border-tabs/export_bounding_box_modal.js index 5a5fd67f85f..4bb937c30ea 100644 --- a/frontend/javascripts/oxalis/view/right-border-tabs/export_bounding_box_modal.js +++ b/frontend/javascripts/oxalis/view/right-border-tabs/export_bounding_box_modal.js @@ -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, @@ -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; @@ -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 || ""); From 91ce5a7b52455f099121378b1c0c4682a16cdd13 Mon Sep 17 00:00:00 2001 From: Philipp Otto Date: Tue, 20 Jul 2021 18:31:57 +0200 Subject: [PATCH 11/13] add disclaimer comment to withFarClipping --- frontend/javascripts/oxalis/view/rendering_utils.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frontend/javascripts/oxalis/view/rendering_utils.js b/frontend/javascripts/oxalis/view/rendering_utils.js index 4a74ca42669..ba5731d365e 100644 --- a/frontend/javascripts/oxalis/view/rendering_utils.js +++ b/frontend/javascripts/oxalis/view/rendering_utils.js @@ -43,6 +43,11 @@ 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 { From 129858ed4c092f9f4306f3baf316daa6a0abe249 Mon Sep 17 00:00:00 2001 From: Philipp Otto Date: Wed, 21 Jul 2021 14:33:16 +0200 Subject: [PATCH 12/13] fix node picking in 3D viewport --- frontend/javascripts/oxalis/view/rendering_utils.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontend/javascripts/oxalis/view/rendering_utils.js b/frontend/javascripts/oxalis/view/rendering_utils.js index ba5731d365e..d1171fac633 100644 --- a/frontend/javascripts/oxalis/view/rendering_utils.js +++ b/frontend/javascripts/oxalis/view/rendering_utils.js @@ -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"; @@ -59,7 +60,9 @@ export function renderToTexture( const previousFarValue = camera.far; - if (withFarClipping) { + // 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, ); From aca3e7c27867a3d2029bb0a22e312636f36031fe Mon Sep 17 00:00:00 2001 From: Philipp Otto Date: Wed, 21 Jul 2021 14:37:26 +0200 Subject: [PATCH 13/13] incorporate PR feedback --- frontend/javascripts/oxalis/controller/camera_controller.js | 2 +- .../oxalis/view/left-border-tabs/layer_settings_tab.js | 2 +- frontend/javascripts/oxalis/view/rendering_utils.js | 3 --- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/frontend/javascripts/oxalis/controller/camera_controller.js b/frontend/javascripts/oxalis/controller/camera_controller.js index 337dc27194a..5383f319bc7 100644 --- a/frontend/javascripts/oxalis/controller/camera_controller.js +++ b/frontend/javascripts/oxalis/controller/camera_controller.js @@ -142,7 +142,7 @@ class CameraController extends React.PureComponent { this.props.cameras[planeId].top = height / 2; // We only set the `near` value here. The effect of far=clippingDistance is - // achieved by offsettng the plane onto which is rendered by the amount + // 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. diff --git a/frontend/javascripts/oxalis/view/left-border-tabs/layer_settings_tab.js b/frontend/javascripts/oxalis/view/left-border-tabs/layer_settings_tab.js index 7b4ea40129b..b41271b2c3b 100644 --- a/frontend/javascripts/oxalis/view/left-border-tabs/layer_settings_tab.js +++ b/frontend/javascripts/oxalis/view/left-border-tabs/layer_settings_tab.js @@ -755,7 +755,7 @@ class DatasetSettings extends React.PureComponent { roundTo={3} min={userSettings.clippingDistance.minimum} max={userSettings.clippingDistance.maximum} - value={this.props.userConfiguration.clippingDistance} + value={userConfiguration.clippingDistance} onChange={this.onChangeUser.clippingDistance} /> )} diff --git a/frontend/javascripts/oxalis/view/rendering_utils.js b/frontend/javascripts/oxalis/view/rendering_utils.js index d1171fac633..19747390eb6 100644 --- a/frontend/javascripts/oxalis/view/rendering_utils.js +++ b/frontend/javascripts/oxalis/view/rendering_utils.js @@ -58,8 +58,6 @@ export function renderToTexture( scene = scene || defaultScene; camera = camera || scene.getObjectByName(plane); - const previousFarValue = camera.far; - // Don't respect withFarClipping for the TDViewport as we don't do any clipping for // nodes there. if (withFarClipping && plane !== OrthoViews.TDView) { @@ -96,7 +94,6 @@ export function renderToTexture( renderer.readRenderTargetPixels(renderTarget, 0, 0, width, height, buffer); renderer.setRenderTarget(null); - camera.far = previousFarValue; return buffer; }