Skip to content

Commit

Permalink
Fix rendering missing data black and wrong segment id being displayed (
Browse files Browse the repository at this point in the history
…#5674)

* fix getting segment id of 0 if using fallback mag when renderMissingDataBlack is turned off

* enable rendering fallback mags with a difference higher than one

* remove unused method

* add changelog entry

* adjust comment
  • Loading branch information
MichaelBuessemeyer authored Aug 23, 2021
1 parent 6245be5 commit c92659a
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 48 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released
- Improved context menu for interactions with segmentation data which wasn't loaded completely, yet. [#5637](https://github.com/scalableminds/webknossos/pull/5637)
- Any feature connected to computational jobs like precomputing a meshfile is now disabled for non local hosted datasets. [#5663](https://github.com/scalableminds/webknossos/pull/5663)
- Clicking outside of the context menu closes it without performing any other action (e.g., previously, a node could be created when clicking outside of the context menu, when the skeleton tool was active). Also, a repeated rightclick doesn't open the context menu again. [#5658](https://github.com/scalableminds/webknossos/pull/5658)
- When the option "Rendering missing data black" is turned of, the fallback data is now shown up to a zoom difference of 3. Previously it was 1. [#5674](https://github.com/scalableminds/webknossos/pull/5674)

### Fixed
- Fix that active segment and node id were not shown in status bar when being in a non-hybrid annotation. [#5638](https://github.com/scalableminds/webknossos/pull/5638)
- Fix that "Compute Mesh File" button was enabled in scenarios where it should not be supported (e.g., when no segmentation layer exists). [#5648](https://github.com/scalableminds/webknossos/pull/5648)
- Fixed a bug where an authentication error was shown when viewing the meshes tab while not logged in. [#5647](https://github.com/scalableminds/webknossos/pull/5647)
- Fix that segment id 0 was always shown even when fallback data of the segmentation layer was visible and hovered with the mouse. [#5674](https://github.com/scalableminds/webknossos/pull/5674)
- Fixed that nodes could only be selected via the context menu when an annotation was opened in read-only mode. Shift-Click will now work, too (and if "Classic Controls" are disabled, a simple left click will work, too). [#5661](https://github.com/scalableminds/webknossos/pull/5661)
- Fixed that the copy buttons in the context menu did not work properly. [#5658](https://github.com/scalableminds/webknossos/pull/5658)
- Fixed that creating a new node in merger mode did always turn of the "Hide unmapped segments" setting. [#5668](https://github.com/scalableminds/webknossos/pull/5668)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -515,12 +515,14 @@ class DataCube {
// needs to be examined for rendering.

const bucket = this.getBucket(this.positionToZoomedAddress(voxel, zoomStep));
const { renderMissingDataBlack } = Store.getState().datasetConfiguration;

if (!(bucket instanceof DataBucket)) {
// This is a NullBucket (e.g., because it's out of the bounding box or in a not-existing
// magnification). This zoomstep is as good as all the other zoomsteps (as these will only
// hold null buckets, too).
return true;
// This is a NullBucket (e.g., because it's out of the bounding box or there exists no data for this zoomstep).
// If renderMissingDataBlack is turned on, this zoomstep is as good as all the other zoomsteps (as these will only
// hold null buckets, too). If this option is turned off, buckets of higher mags could be used for rendering,
// thus return false in this case.
return renderMissingDataBlack;
}

if (bucket.hasData() || bucket.isLoaded()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import type { ElementClass } from "types/api_flow_types";
export const channelCountForLookupBuffer = 2;

function getSomeValue<T>(set: Set<T>): T {
const value = set.values().next().value;
const { value } = set.values().next();

if (value == null) {
throw new Error("Cannot get value of set because it's empty.");
Expand Down Expand Up @@ -345,8 +345,8 @@ export default class TextureBucketManager {
address = reservedAddress;
}

const isBaseBucket = bucketZoomStep === currentZoomStep;
const isFirstFallback = bucketZoomStep - 1 === currentZoomStep;
const zoomStepDifference = bucketZoomStep - currentZoomStep;
const isBaseBucket = zoomStepDifference === 0;
if (isBaseBucket) {
if (address === -1) {
let fallbackBucket = bucket.getFallbackBucket();
Expand Down Expand Up @@ -379,27 +379,22 @@ export default class TextureBucketManager {
this.lookUpBuffer[posInBuffer] = address;
this.lookUpBuffer[posInBuffer + 1] = bucketZoomStep;
}
} else if (isFirstFallback) {
if (address !== -1) {
const baseBucketAddresses = this._getBaseBucketAddresses(bucket, 1);
for (const baseBucketAddress of baseBucketAddresses) {
const lookUpIdx = this._getBucketIndex(baseBucketAddress);
const posInBuffer = channelCountForLookupBuffer * lookUpIdx;
if (this.lookUpBuffer[posInBuffer] !== -2 || lookUpIdx === -1) {
// Either, another bucket was already placed here. Or, the lookUpIdx is
// invalid. Skip the entire loop
break;
}
this.lookUpBuffer[posInBuffer] = address;
this.lookUpBuffer[posInBuffer + 1] = bucketZoomStep;
} else if (address !== -1) {
const baseBucketAddresses = this._getBaseBucketAddresses(bucket, zoomStepDifference);
for (const baseBucketAddress of baseBucketAddresses) {
const lookUpIdx = this._getBucketIndex(baseBucketAddress);
const posInBuffer = channelCountForLookupBuffer * lookUpIdx;
if (this.lookUpBuffer[posInBuffer] !== -2 || lookUpIdx === -1) {
// Either, another bucket was already placed here. Or, the lookUpIdx is
// invalid. Skip the entire loop
break;
}
} else {
// Don't overwrite the default -2 within the look up buffer for fallback buckets,
// since the effort is not worth it (only has an impact on the fallback color within the shader)
this.lookUpBuffer[posInBuffer] = address;
this.lookUpBuffer[posInBuffer + 1] = bucketZoomStep;
}
} else {
// Don't handle buckets with zoomStepDiff > 1, because filling the corresponding
// positions in the lookup buffer would take 8**zoomStepDiff iterations PER bucket.
// Don't overwrite the default -2 within the look up buffer for fallback buckets,
// since the effort is not worth it (only has an impact on the fallback color within the shader)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,6 @@ export function getBaseBucketsForFallbackBucket(
resolutions,
betterZoomStep,
);
if (zoomStepDifference > 1) {
// Due to the exponential complexity of calculating the "better bucket addresses",
// we currently only support this function if zoomStepDifference === 1
return [betterBucketAddress];
}

// resolutionFactors is a [x, y, z] tuple with x, y, z being 1 or 2 each (because
// zoomStepDifference === 1). In the case of isotropic resolutions, it's simply [2, 2, 2]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -608,24 +608,6 @@ class DatasetSettings extends React.PureComponent<DatasetSettingsProps, State> {
Toast.success(`Successfully reloaded data of layer ${layerName}.`);
};

onChangeRenderMissingDataBlack = async (value: boolean): Promise<void> => {
Toast.info(
value
? messages["data.enabled_render_missing_data_black"]
: messages["data.disabled_render_missing_data_black"],
{ timeout: 8000 },
);
this.props.onChange("renderMissingDataBlack", value);
const { layers } = this.props.datasetConfiguration;
const reloadAllLayersPromises = Object.keys(layers).map(async layerName => {
await clearCache(this.props.dataset, layerName);
await api.data.reloadBuckets(layerName);
});
await Promise.all(reloadAllLayersPromises);
window.needsRerender = true;
Toast.success("Successfully reloaded data of all layers.");
};

getVolumeMagsToDownsample = (): Array<Vector3> => {
if (this.props.task != null) {
return [];
Expand Down

0 comments on commit c92659a

Please sign in to comment.