Skip to content

Commit

Permalink
Merge pull request #535 from saalfeldlab/fix/1.2.2
Browse files Browse the repository at this point in the history
Fix/1.2.2
  • Loading branch information
cmhulbert authored May 24, 2024
2 parents acfa903 + ccdb497 commit e8de59b
Show file tree
Hide file tree
Showing 13 changed files with 130 additions and 131 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,14 @@ public ViewerPanelFX(
startRenderAnimator();
setWidth(options.getWidth());
setHeight(options.getHeight());
this.widthProperty().addListener((obs, oldv, newv) -> this.renderUnit.setDimensions((long) getWidth(), (long) getHeight()));
this.heightProperty().addListener((obs, oldv, newv) -> this.renderUnit.setDimensions((long) getWidth(), (long) getHeight()));
widthProperty().subscribe(width -> renderUnit.setDimensions(width.longValue(), (long)getHeight()));
heightProperty().subscribe(height -> renderUnit.setDimensions((long)getWidth(), height.longValue()));

visibleProperty().subscribe(visible -> {
if (!visible)
renderUnit.stopRendering();
});


transformListeners.add(tf -> Paintera.whenPaintable(getDisplay()::drawOverlays));

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
package org.janelia.saalfeldlab.bdv.fx.viewer.project;

import bdv.viewer.render.VolatileProjector;
import io.github.oshai.kotlinlogging.KLogger;
import io.github.oshai.kotlinlogging.KotlinLogging;
import net.imglib2.FinalInterval;
import net.imglib2.IterableInterval;
import net.imglib2.RandomAccessible;
Expand All @@ -51,6 +53,7 @@
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

Expand All @@ -64,6 +67,8 @@
*/
public class VolatileHierarchyProjector<A extends Volatile<?>, B extends SetZero> implements VolatileProjector {

private static KLogger LOG = KotlinLogging.INSTANCE.logger(() -> null);

/**
* A converter from the source pixel type to the target pixel type.
*/
Expand Down Expand Up @@ -211,10 +216,12 @@ public void clearMask() {

try {
LoopBuilder.setImages(mask).multiThreaded(taskExecutor).forEachPixel(val -> val.set(Byte.MAX_VALUE));
} catch (RejectedExecutionException e) {
LOG.trace(e, () -> "Clear Mask Rejected");
} catch (RuntimeException e) {
if (!e.getMessage().contains("Interrupted")) {
throw e;
}
if (e.getMessage() != null && e.getMessage().contains("Interrupted"))
LOG.trace(e, () -> "Clear Mask Interrupted");
else throw e;
}
numInvalidLevels = sources.size();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ public int paint(
clearQueue = newFrameRequest;
if (clearQueue)
cacheControl.prepareNextFrame();
createProjector = newFrameRequest || resized || requestedScreenScaleIndex != currentScreenScaleIndex || !sameAsLastRenderedInterval;
createProjector = projector == null || newFrameRequest || resized || requestedScreenScaleIndex != currentScreenScaleIndex || !sameAsLastRenderedInterval;
newFrameRequest = false;

final List<SourceAndConverter<?>> sacs = List.copyOf(sources);
Expand Down Expand Up @@ -624,8 +624,10 @@ public void requestRepaint(final Interval interval, final int screenScaleIndex)
if (Intervals.isEmpty(interval))
return;

if (renderingMayBeCancelled && projector != null)
if (renderingMayBeCancelled && projector != null) {
projector.cancel();
projector = null;
}

int newRequestedScaleIdx;
if (screenScaleIndex > maxScreenScaleIndex) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ private Interval clampRepaintInterval(final Interval interval) {
protected synchronized void update() {

LOG.debug("Updating render unit");
if (renderer != null)
renderer.animation.stop();

renderTarget = new TransformAwareBufferedImageOverlayRendererFX();
renderTarget.setCanvasSize((int)dimensions[0], (int)dimensions[1]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ public Interval getMaskInterval() {
} else {
mask = viewerMask;
}
final var maskPos = mask.displayPointToInitialMaskPoint(viewerSeedX, viewerSeedY);
final var maskPos = mask.displayPointToMask(viewerSeedX, viewerSeedY, true);
final var filter = getBackgorundLabelMaskForAssignment(maskPos, mask, assignment, fill);
if (filter == null)
return null;
Expand Down Expand Up @@ -179,7 +179,7 @@ public UtilityTask<?> fillViewerAt(final double viewerSeedX, final double viewer
} else {
mask = viewerMask;
}
final var maskPos = mask.displayPointToInitialMaskPoint(viewerSeedX, viewerSeedY);
final var maskPos = mask.displayPointToMask(viewerSeedX, viewerSeedY, true);
final UtilityTask<?> floodFillTask = fillMaskAt(maskPos, mask, fill, filter);
if (this.viewerMask == null) {
floodFillTask.onCancelled(true, (state, task) -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ package org.janelia.saalfeldlab.paintera.control
import org.janelia.saalfeldlab.bdv.fx.viewer.ViewerPanelFX
import bdv.viewer.TransformListener
import io.github.oshai.kotlinlogging.KotlinLogging
import javafx.application.Platform
import javafx.beans.InvalidationListener
import javafx.beans.Observable
import javafx.beans.property.ObjectProperty
import javafx.beans.property.SimpleBooleanProperty
import javafx.beans.property.SimpleDoubleProperty
import javafx.beans.property.SimpleObjectProperty
import javafx.beans.value.ChangeListener
import javafx.collections.FXCollections
import javafx.collections.ObservableList
import javafx.concurrent.Task
import javafx.concurrent.Worker
import javafx.scene.paint.Color
Expand Down Expand Up @@ -40,6 +41,7 @@ import net.imglib2.util.*
import net.imglib2.view.ExtendedRealRandomAccessibleRealInterval
import net.imglib2.view.IntervalView
import net.imglib2.view.Views
import org.checkerframework.common.reflection.qual.Invoke
import org.janelia.saalfeldlab.fx.Tasks
import org.janelia.saalfeldlab.fx.extensions.*
import org.janelia.saalfeldlab.fx.util.InvokeOnJavaFXApplicationThread
Expand All @@ -62,6 +64,7 @@ import org.janelia.saalfeldlab.util.*
import org.janelia.saalfeldlab.net.imglib2.view.BundleView
import java.math.BigDecimal
import java.math.RoundingMode
import java.util.Collections
import java.util.concurrent.ExecutionException
import java.util.concurrent.atomic.AtomicBoolean
import java.util.function.Supplier
Expand All @@ -88,9 +91,6 @@ class ShapeInterpolationController<D : IntegerType<D>>(

private val slicesAndInterpolants = SlicesAndInterpolants()

val sliceDepthProperty = SimpleDoubleProperty(0.0)
private var sliceDepth: Double by sliceDepthProperty.nonnull()

val isBusyProperty = SimpleBooleanProperty(false, "Shape Interpolation Controller is Busy")
private var isBusy: Boolean by isBusyProperty.nonnull()

Expand All @@ -99,8 +99,11 @@ class ShapeInterpolationController<D : IntegerType<D>>(
val isControllerActive: Boolean
get() = controllerState != ControllerState.Off

private val sliceAtCurrentDepthBinding = sliceDepthProperty.createNonNullValueBinding(slicesAndInterpolants) { slicesAndInterpolants.getSliceAtDepth(it.toDouble()) }
private val sliceAtCurrentDepth by sliceAtCurrentDepthBinding.nullableVal()
internal val currentDepthProperty = SimpleDoubleProperty()
internal val currentDepth: Double by currentDepthProperty.nonnullVal()

internal val sliceAtCurrentDepthProperty = slicesAndInterpolants.createObservableBinding(currentDepthProperty) { it.getSliceAtDepth(currentDepth) }
private val sliceAtCurrentDepth by sliceAtCurrentDepthProperty.nullableVal()

val currentSliceMaskInterval get() = sliceAtCurrentDepth?.maskBoundingBox

Expand Down Expand Up @@ -133,9 +136,6 @@ class ShapeInterpolationController<D : IntegerType<D>>(
return viewerState.getBestMipMapLevel(screenScaleTransform, source)
}


internal val currentDepth: Double by LazyForeignValue(this::globalToViewerTransform) { depthAt(it) }

private var selector: Task<Unit>? = null
private var interpolator: Task<Unit>? = null
private val onTaskFinished = {
Expand All @@ -152,10 +152,7 @@ class ShapeInterpolationController<D : IntegerType<D>>(
private var globalCompositeFillAndInterpolationImgs: Pair<RealRandomAccessible<UnsignedLongType>, RealRandomAccessible<VolatileUnsignedLongType>>? = null

private val viewerTransformDepthUpdater = TransformListener<AffineTransform3D> {
updateDepth()
sliceAtCurrentDepth?.mask.let {
currentViewerMask = it
}
currentDepthProperty.set(depthAt(it))
}

internal fun depthAt(globalTransform: AffineTransform3D): Double {
Expand Down Expand Up @@ -240,19 +237,17 @@ class ShapeInterpolationController<D : IntegerType<D>>(
selectNewInterpolationId()
initialGlobalToViewerTransform = globalToViewerTransform
activeViewer!!.addTransformListener(viewerTransformDepthUpdater)
updateDepth()
controllerState = ControllerState.Select

sliceAtCurrentDepthBinding.addListener { _, old, new ->
sliceAtCurrentDepthProperty.addListener { _, old, new ->
old?.mask?.setMaskOnUpdate = false
new?.mask?.setMaskOnUpdate = false
new?.mask?.also {
currentViewerMask = it
it.setMaskOnUpdate = false
}
}
}

private fun updateDepth() {
sliceDepth = currentDepth
}

fun exitShapeInterpolation(completed: Boolean) {
if (!isControllerActive) {
LOG.debug { "Not in shape interpolation" }
Expand All @@ -274,7 +269,6 @@ class ShapeInterpolationController<D : IntegerType<D>>(
selectedIds.activateAlso(lastSelectedId)
controllerState = ControllerState.Off
slicesAndInterpolants.clear()
sliceDepth = 0.0
currentViewerMask = null
interpolator = null
globalCompositeFillAndInterpolationImgs = null
Expand Down Expand Up @@ -381,7 +375,6 @@ class ShapeInterpolationController<D : IntegerType<D>>(
paintera().manager().apply {
setTransform(globalTransform, Duration(300.0)) {
transform = globalTransform
updateDepth()
controllerState = ControllerState.Select
}
}
Expand Down Expand Up @@ -989,7 +982,7 @@ class ShapeInterpolationController<D : IntegerType<D>>(
}
}

private class SlicesAndInterpolants : ObservableList<SliceOrInterpolant> by FXCollections.synchronizedObservableList(FXCollections.observableArrayList()) {
private class SlicesAndInterpolants : MutableList<SliceOrInterpolant> by Collections.synchronizedList(mutableListOf()), Observable {
fun removeSlice(slice: SliceInfo): Boolean {
synchronized(this) {
for (idx in indices) {
Expand All @@ -998,6 +991,9 @@ class ShapeInterpolationController<D : IntegerType<D>>(
LOG.trace { "Removing Slice: $idx" }
removeAt(idx).getSlice()
removeIfInterpolant(idx - 1)

notifyListeners()

return true
}
}
Expand All @@ -1017,7 +1013,11 @@ class ShapeInterpolationController<D : IntegerType<D>>(
synchronized(this) {
return if (idx >= 0 && idx <= size - 1 && get(idx).isInterpolant) {
LOG.trace { "Removing Interpolant: $idx" }
removeAt(idx).getInterpolant()
val interp = removeAt(idx).getInterpolant()

notifyListeners()

interp
} else null
}

Expand All @@ -1043,6 +1043,10 @@ class ShapeInterpolationController<D : IntegerType<D>>(
}
LOG.trace { "Adding Slice: ${this.size}" }
add(sliceOrInterpolant)

InvokeOnJavaFXApplicationThread {
listeners.forEach { it.invalidated(this) }
}
}
}

Expand Down Expand Up @@ -1145,6 +1149,20 @@ class ShapeInterpolationController<D : IntegerType<D>>(
return false
}
}

private val listeners = mutableListOf<InvalidationListener>()

override fun addListener(p0: InvalidationListener) {
listeners += p0
}

override fun removeListener(p0: InvalidationListener) {
listeners -= p0
}

private fun notifyListeners() = Platform.runLater {
listeners.forEach { it.invalidated(this) }
}
}

var initialGlobalToViewerTransform: AffineTransform3D? = null
Expand Down
Loading

0 comments on commit e8de59b

Please sign in to comment.