Skip to content
Snippets Groups Projects
Commit 93f64136 authored by Vojtech Moravec's avatar Vojtech Moravec
Browse files

Merge remote-tracking branch 'upstream/master' into fork_sync

parents 368cc7c0 c698350b
Branches
No related tags found
No related merge requests found
Showing
with 1995 additions and 589 deletions
# BigDataViewer N5 format
The BigDataViewer N5 back-end (`format="bdv.n5"`) requires a N5 dataset with a specific group hierarchy and attributes.
Multi-channel (-angle, -tile, -illumination) time-series as
multi-resolution 3D stacks are organized in the following N5 hierarchy:
```
\
├── setup0
│ ├── attributes.json {"downsamplingFactors":[[1,1,1],[2,2,2]],"dataType":"uint8"}
│ ├── timepoint0
│ │ ├── s0
│ │ │ ├── attributes.json {"dataType":"uint8","compression":{"type":"bzip2","blockSize":9},"blockSize":[16,16,16],"dimensions":[400,400,25]}
│ │ │ ┊
│ │ │
│ │ ├── s1
│ │ ┊
│ │
│ ├── timepoint1
│ ┊
├── setup1
```
Each 3D stack is stored as a dataset with path formatted as `/setup%d/timepoint%d/s%d`.
Here, `setup` number is flattened integer ID of channel, angle, tile, illumination, etc.,
`timepoint` is the integer ID of the time point, and `s` is the scale level of the multi-resolution pyramid.
## setup attributes
Each `setup` group has attributes
```
"downsamplingFactors" : [[1,1,1], [2,2,1], ...]
"dataType":"uint8"
```
that specify downsampling scheme and datatype, which are the same for all timepoints.
`downsamplingFactors` specifies power-of-two downscaling factors for each scale level (with respect to full resolution `s0`, which always has `[1,1,1]`).
`dataType` is one of {uint8, uint16, uint32, uint64, int8, int16, int32, int64, float32, float64}.
> TODO: Additional metadata (for example identifying `setup3` as channel 3, tile 124, etc.) could be replicated from the XML.
The idea would be that parts of a dataset can be used independent of BDV, without the XML.
We should agree on standard attributes for this.
## timepoint attributes
`timepoint` has no mandatory attributes.
For compatibility with Paintera, when exporting to N5 we put the `"multiScale" : true`, and `"resolution" : [x,y,z]` attributes.
## scale level attributes
`s0`, `s1`, etc. have the mandatory N5 dataset attributes.
For compatibility with Paintera, when exporting to N5 we put the `"downsamplingFactors": [x,y,z]` attribute.
> TODO: Additional metadata (for example scaled resolution and affine transform) could be replicated from the XML.
The idea would be that an individual stack can be used independent of BDV, without the XML.
We should agree on standard attributes for this.
Copyright (c) 2012 - 2016, Tobias Pietzsch, Stephan Saalfeld, Stephan Preibisch,
Jean-Yves Tinevez, HongKee Moon, Johannes Schindelin, Curtis Rueden, John Bogovic
Copyright (c) 2012 - 2020, BigDataViewer developers.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
......
......@@ -5,13 +5,13 @@
<parent>
<groupId>org.scijava</groupId>
<artifactId>pom-scijava</artifactId>
<version>27.0.1</version>
<version>29.2.1</version>
<relativePath />
</parent>
<groupId>sc.fiji</groupId>
<artifactId>bigdataviewer-core</artifactId>
<version>7.0.1-SNAPSHOT</version>
<version>10.0.3-SNAPSHOT</version>
<name>BigDataViewer Core</name>
<description>BigDataViewer core classes with minimal dependencies.</description>
......@@ -134,12 +134,9 @@
<package-name>bdv</package-name>
<license.licenseName>bsd_2</license.licenseName>
<license.copyrightOwners>BigDataViewer developers.</license.copyrightOwners>
<enforcer.skip>true</enforcer.skip>
<!-- NB: Deploy releases to the SciJava Maven repository. -->
<releaseProfiles>deploy-to-scijava</releaseProfiles>
<imglib2-cache.version>1.0.0-beta-12</imglib2-cache.version>
</properties>
<repositories>
......@@ -162,10 +159,6 @@
<groupId>net.imglib2</groupId>
<artifactId>imglib2-cache</artifactId>
</dependency>
<dependency>
<groupId>net.imglib2</groupId>
<artifactId>imglib2-ui</artifactId>
</dependency>
<dependency>
<groupId>net.imglib2</groupId>
<artifactId>imglib2-algorithm</artifactId>
......@@ -193,8 +186,20 @@
<dependency>
<groupId>org.scijava</groupId>
<artifactId>scijava-listeners</artifactId>
<version>1.0.0-beta-2</version>
</dependency>
<dependency>
<groupId>org.janelia.saalfeldlab</groupId>
<artifactId>n5-imglib2</artifactId>
</dependency>
<dependency>
<groupId>org.janelia.saalfeldlab</groupId>
<artifactId>n5</artifactId>
</dependency>
<dependency>
<groupId>com.miglayout</groupId>
<artifactId>miglayout-swing</artifactId>
</dependency>
<!-- test dependencies -->
<dependency>
<groupId>junit</groupId>
......
/*-
* #%L
* BigDataViewer core classes with minimal dependencies.
* %%
* Copyright (C) 2012 - 2020 BigDataViewer developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* #L%
*/
package bdv;
import bdv.img.cache.CacheArrayLoader;
......@@ -16,7 +44,7 @@ import net.imglib2.type.NativeType;
/**
* Abstract {@link ViewerSetupImgLoader} with a VolatileGlobalCellCache.
*
* @author Stephan Saalfeld &lt;saalfelds@janelia.hhmi.org&gt;
* @author Stephan Saalfeld
*/
abstract public class AbstractCachedViewerSetupImgLoader< T extends NativeType< T > , V extends Volatile< T > & NativeType< V >, A extends VolatileAccess >
extends AbstractViewerSetupImgLoader< T, V >
......
/*
* #%L
* BigDataViewer core classes with minimal dependencies
* BigDataViewer core classes with minimal dependencies.
* %%
* Copyright (C) 2012 - 2016 Tobias Pietzsch, Stephan Saalfeld, Stephan Preibisch,
* Jean-Yves Tinevez, HongKee Moon, Johannes Schindelin, Curtis Rueden, John Bogovic
* Copyright (C) 2012 - 2020 BigDataViewer developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
......
/*
* #%L
* BigDataViewer core classes with minimal dependencies
* BigDataViewer core classes with minimal dependencies.
* %%
* Copyright (C) 2012 - 2016 Tobias Pietzsch, Stephan Saalfeld, Stephan Preibisch,
* Jean-Yves Tinevez, HongKee Moon, Johannes Schindelin, Curtis Rueden, John Bogovic
* Copyright (C) 2012 - 2020 BigDataViewer developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
......
This diff is collapsed.
/*
* #%L
* BigDataViewer core classes with minimal dependencies
* BigDataViewer core classes with minimal dependencies.
* %%
* Copyright (C) 2012 - 2016 Tobias Pietzsch, Stephan Saalfeld, Stephan Preibisch,
* Jean-Yves Tinevez, HongKee Moon, Johannes Schindelin, Curtis Rueden, John Bogovic
* Copyright (C) 2012 - 2020 BigDataViewer developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
......@@ -57,6 +56,8 @@ public class BigDataViewerActions extends Actions
public static final String MANUAL_TRANSFORM = "toggle manual transformation";
public static final String SAVE_SETTINGS = "save settings";
public static final String LOAD_SETTINGS = "load settings";
public static final String EXPAND_CARDS = "expand and focus cards panel";
public static final String COLLAPSE_CARDS = "collapse cards panel";
public static final String RECORD_MOVIE = "record movie";
public static final String RECORD_MAX_PROJECTION_MOVIE = "record max projection movie";
public static final String SET_BOOKMARK = "set bookmark";
......@@ -72,6 +73,8 @@ public class BigDataViewerActions extends Actions
static final String[] RECORD_MOVIE_KEYS = new String[] { "F10" };
static final String[] SAVE_SETTINGS_KEYS = new String[] { "F11" };
static final String[] LOAD_SETTINGS_KEYS = new String[] { "F12" };
public static final String[] EXPAND_CARDS_KEYS = new String[] { "P" };
public static final String[] COLLAPSE_CARDS_KEYS = new String[] { "shift P", "shift ESCAPE" };
static final String[] GO_TO_BOOKMARK_KEYS = new String[] { "B" };
static final String[] GO_TO_BOOKMARK_ROTATION_KEYS = new String[] { "O" };
static final String[] SET_BOOKMARK_KEYS = new String[] { "shift B" };
......@@ -104,6 +107,8 @@ public class BigDataViewerActions extends Actions
actions.manualTransform( bdv.manualTransformationEditor );
actions.runnableAction( bdv::loadSettings, LOAD_SETTINGS, LOAD_SETTINGS_KEYS );
actions.runnableAction( bdv::saveSettings, SAVE_SETTINGS, SAVE_SETTINGS_KEYS );
actions.runnableAction( bdv::expandAndFocusCardPanel, EXPAND_CARDS, EXPAND_CARDS_KEYS );
actions.runnableAction( bdv::collapseCardPanel, COLLAPSE_CARDS, COLLAPSE_CARDS_KEYS );
actions.install( inputActionBindings, "bdv" );
}
......@@ -119,11 +124,13 @@ public class BigDataViewerActions extends Actions
new ToggleDialogAction( name, dialog ).put( getActionMap() );
}
@Deprecated
public void dialog( final BrightnessDialog brightnessDialog )
{
toggleDialogAction( brightnessDialog, BRIGHTNESS_SETTINGS, BRIGHTNESS_SETTINGS_KEYS );
}
@Deprecated
public void dialog( final VisibilityAndGroupingDialog visibilityAndGroupingDialog )
{
toggleDialogAction( visibilityAndGroupingDialog, VISIBILITY_AND_GROUPING, VISIBILITY_AND_GROUPING_KEYS );
......
/*
* #%L
* BigDataViewer core classes with minimal dependencies
* BigDataViewer core classes with minimal dependencies.
* %%
* Copyright (C) 2012 - 2016 Tobias Pietzsch, Stephan Saalfeld, Stephan Preibisch,
* Jean-Yves Tinevez, HongKee Moon, Johannes Schindelin, Curtis Rueden, John Bogovic
* Copyright (C) 2012 - 2020 BigDataViewer developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
......
/*
* #%L
* BigDataViewer core classes with minimal dependencies.
* %%
* Copyright (C) 2012 - 2020 BigDataViewer developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* #L%
*/
package bdv;
import org.scijava.ui.behaviour.util.Behaviours;
/**
* Change a transformation in response to user input (mouse events, key events, etc.)
*
* The {@link TransformEventHandler} receives notifications about changes of the
* canvas size (it may react for example by changing the scale of the
* transformation accordingly).
*
* @author Tobias Pietzsch
*/
public interface TransformEventHandler
{
/**
* Install transformation behaviours into the specified {@code behaviours} contrainer.
*/
void install( Behaviours behaviours );
/**
* This is called, when the screen size of the canvas (the component
* displaying the image and generating mouse events) changes. This can be
* used to determine screen coordinates to keep fixed while zooming or
* rotating with the keyboard, e.g., set these to
* <em>(width/2, height/2)</em>. It can also be used to update the current
* source-to-screen transform, e.g., to change the zoom along with the
* canvas size.
*
* @param width
* the new canvas width.
* @param height
* the new canvas height.
* @param updateTransform
* whether the current source-to-screen transform should be
* updated. This will be <code>false</code> for the initial
* update of a new {@link TransformEventHandler} and
* <code>true</code> on subsequent calls.
*/
void setCanvasSize( int width, int height, boolean updateTransform );
}
/*-
* #%L
* BigDataViewer core classes with minimal dependencies.
* %%
* Copyright (C) 2012 - 2020 BigDataViewer developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* #L%
*/
package bdv;
import net.imglib2.realtransform.AffineTransform3D;
import org.scijava.ui.behaviour.Behaviour;
import org.scijava.ui.behaviour.ClickBehaviour;
import org.scijava.ui.behaviour.DragBehaviour;
import org.scijava.ui.behaviour.ScrollBehaviour;
import org.scijava.ui.behaviour.util.Behaviours;
/**
* A {@link TransformEventHandler} that changes an {@link AffineTransform3D}
* through a set of {@link Behaviour}s.
*
* @author Tobias Pietzsch
*/
public class TransformEventHandler2D implements TransformEventHandler
{
// -- behaviour names --
public static final String DRAG_TRANSLATE = "2d drag translate";
public static final String DRAG_ROTATE = "2d drag rotate";
public static final String ZOOM_NORMAL = "2d scroll zoom";
public static final String SCROLL_TRANSLATE = "2d scroll translate";
public static final String SCROLL_ROTATE = "2d scroll rotate";
public static final String ROTATE_LEFT = "2d rotate left";
public static final String ROTATE_RIGHT = "2d rotate right";
public static final String KEY_ZOOM_IN = "2d zoom in";
public static final String KEY_ZOOM_OUT = "2d zoom out";
public static final String ZOOM_FAST = "2d scroll zoom fast";
public static final String SCROLL_TRANSLATE_FAST = "2d scroll translate fast";
public static final String SCROLL_ROTATE_FAST = "2d scroll rotate fast";
public static final String ROTATE_LEFT_FAST = "2d rotate left fast";
public static final String ROTATE_RIGHT_FAST = "2d rotate right fast";
public static final String KEY_ZOOM_IN_FAST = "2d zoom in fast";
public static final String KEY_ZOOM_OUT_FAST = "2d zoom out fast";
public static final String ZOOM_SLOW = "2d scroll zoom slow";
public static final String SCROLL_TRANSLATE_SLOW = "2d scroll translate slow";
public static final String SCROLL_ROTATE_SLOW = "2d scroll rotate slow";
public static final String ROTATE_LEFT_SLOW = "2d rotate left slow";
public static final String ROTATE_RIGHT_SLOW = "2d rotate right slow";
public static final String KEY_ZOOM_IN_SLOW = "2d zoom in slow";
public static final String KEY_ZOOM_OUT_SLOW = "2d zoom out slow";
// -- default shortcuts --
private static final String[] DRAG_TRANSLATE_KEYS = new String[] { "button2", "button3" };
private static final String[] DRAG_ROTATE_KEYS = new String[] { "button1" };
private static final String[] ZOOM_NORMAL_KEYS = new String[] { "scroll", "meta scroll", "ctrl shift scroll" };
private static final String[] SCROLL_TRANSLATE_KEYS = new String[] { "not mapped" };
private static final String[] SCROLL_ROTATE_KEYS = new String[] { "not mapped" };
private static final String[] ROTATE_LEFT_KEYS = new String[] { "LEFT" };
private static final String[] ROTATE_RIGHT_KEYS = new String[] { "RIGHT" };
private static final String[] KEY_ZOOM_IN_KEYS = new String[] { "UP" };
private static final String[] KEY_ZOOM_OUT_KEYS = new String[] { "DOWN" };
private static final String[] ZOOM_FAST_KEYS = new String[] { "shift scroll" };
private static final String[] SCROLL_TRANSLATE_FAST_KEYS = new String[] { "not mapped" };
private static final String[] SCROLL_ROTATE_FAST_KEYS = new String[] { "not mapped" };
private static final String[] ROTATE_LEFT_FAST_KEYS = new String[] { "shift LEFT" };
private static final String[] ROTATE_RIGHT_FAST_KEYS = new String[] { "shift RIGHT" };
private static final String[] KEY_ZOOM_IN_FAST_KEYS = new String[] { "shift UP" };
private static final String[] KEY_ZOOM_OUT_FAST_KEYS = new String[] { "shift DOWN" };
private static final String[] ZOOM_SLOW_KEYS = new String[] { "ctrl scroll" };
private static final String[] SCROLL_TRANSLATE_SLOW_KEYS = new String[] { "not mapped" };
private static final String[] SCROLL_ROTATE_SLOW_KEYS = new String[] { "not mapped" };
private static final String[] ROTATE_LEFT_SLOW_KEYS = new String[] { "ctrl LEFT" };
private static final String[] ROTATE_RIGHT_SLOW_KEYS = new String[] { "ctrl RIGHT" };
private static final String[] KEY_ZOOM_IN_SLOW_KEYS = new String[] { "ctrl UP" };
private static final String[] KEY_ZOOM_OUT_SLOW_KEYS = new String[] { "ctrl DOWN" };
// -- behaviours --
private final DragTranslate dragTranslate;
private final DragRotate dragRotate;
private final Zoom zoom;
private final Zoom zoomFast;
private final Zoom zoomSlow;
private final ScrollTranslate scrollTranslate;
private final ScrollTranslate scrollTranslateFast;
private final ScrollTranslate scrollTranslateSlow;
private final ScrollRotate scrollRotate;
private final ScrollRotate scrollRotateFast;
private final ScrollRotate scrollRotateSlow;
private final KeyRotate keyRotateLeft;
private final KeyRotate keyRotateLeftFast;
private final KeyRotate keyRotateLeftSlow;
private final KeyRotate keyRotateRight;
private final KeyRotate keyRotateRightFast;
private final KeyRotate keyRotateRightSlow;
private final KeyZoom keyZoomIn;
private final KeyZoom keyZoomInFast;
private final KeyZoom keyZoomInSlow;
private final KeyZoom keyZoomOut;
private final KeyZoom keyZoomOutFast;
private final KeyZoom keyZoomOutSlow;
private static final double[] speed = { 1.0, 10.0, 0.1 };
/**
* Copy of transform when mouse dragging started.
*/
private final AffineTransform3D affineDragStart = new AffineTransform3D();
/**
* Current transform during mouse dragging.
*/
private final AffineTransform3D affineDragCurrent = new AffineTransform3D();
/**
* Coordinates where mouse dragging started.
*/
private double oX, oY;
/**
* The screen size of the canvas (the component displaying the image and
* generating mouse events).
*/
private int canvasW = 1, canvasH = 1;
/**
* Screen coordinates to keep centered while zooming or rotating with the
* keyboard. These are set to <em>(canvasW/2, canvasH/2)</em>
*/
private int centerX = 0, centerY = 0;
private final TransformState transform;
public TransformEventHandler2D( final TransformState transform )
{
this.transform = transform;
dragTranslate = new DragTranslate();
dragRotate = new DragRotate();
scrollTranslate = new ScrollTranslate( speed[ 0 ] );
scrollTranslateFast = new ScrollTranslate( speed[ 1 ] );
scrollTranslateSlow = new ScrollTranslate( speed[ 2 ] );
zoom = new Zoom( speed[ 0 ] );
zoomFast = new Zoom( speed[ 1 ] );
zoomSlow = new Zoom( speed[ 2 ] );
scrollRotate = new ScrollRotate( 2 * speed[ 0 ] );
scrollRotateFast = new ScrollRotate( 2 * speed[ 1 ] );
scrollRotateSlow = new ScrollRotate( 2 * speed[ 2 ] );
keyRotateLeft = new KeyRotate( speed[ 0 ] );
keyRotateLeftFast = new KeyRotate( speed[ 1 ] );
keyRotateLeftSlow = new KeyRotate( speed[ 2 ] );
keyRotateRight = new KeyRotate( -speed[ 0 ] );
keyRotateRightFast = new KeyRotate( -speed[ 1 ] );
keyRotateRightSlow = new KeyRotate( -speed[ 2 ] );
keyZoomIn = new KeyZoom( speed[ 0 ] );
keyZoomInFast = new KeyZoom( speed[ 1 ] );
keyZoomInSlow = new KeyZoom( speed[ 2 ] );
keyZoomOut = new KeyZoom( -speed[ 0 ] );
keyZoomOutFast = new KeyZoom( -speed[ 1 ] );
keyZoomOutSlow = new KeyZoom( -speed[ 2 ] );
}
@Override
public void install( final Behaviours behaviours )
{
behaviours.behaviour( dragTranslate, DRAG_TRANSLATE, DRAG_TRANSLATE_KEYS );
behaviours.behaviour( dragRotate, DRAG_ROTATE, DRAG_ROTATE_KEYS );
behaviours.behaviour( scrollTranslate, SCROLL_TRANSLATE, SCROLL_TRANSLATE_KEYS );
behaviours.behaviour( scrollTranslateFast, SCROLL_TRANSLATE_FAST, SCROLL_TRANSLATE_FAST_KEYS );
behaviours.behaviour( scrollTranslateSlow, SCROLL_TRANSLATE_SLOW, SCROLL_TRANSLATE_SLOW_KEYS );
behaviours.behaviour( zoom, ZOOM_NORMAL, ZOOM_NORMAL_KEYS );
behaviours.behaviour( zoomFast, ZOOM_FAST, ZOOM_FAST_KEYS );
behaviours.behaviour( zoomSlow, ZOOM_SLOW, ZOOM_SLOW_KEYS );
behaviours.behaviour( scrollRotate, SCROLL_ROTATE, SCROLL_ROTATE_KEYS );
behaviours.behaviour( scrollRotateFast, SCROLL_ROTATE_FAST, SCROLL_ROTATE_FAST_KEYS );
behaviours.behaviour( scrollRotateSlow, SCROLL_ROTATE_SLOW, SCROLL_ROTATE_SLOW_KEYS );
behaviours.behaviour( keyRotateLeft, ROTATE_LEFT, ROTATE_LEFT_KEYS );
behaviours.behaviour( keyRotateLeftFast, ROTATE_LEFT_FAST, ROTATE_LEFT_FAST_KEYS );
behaviours.behaviour( keyRotateLeftSlow, ROTATE_LEFT_SLOW, ROTATE_LEFT_SLOW_KEYS );
behaviours.behaviour( keyRotateRight, ROTATE_RIGHT, ROTATE_RIGHT_KEYS );
behaviours.behaviour( keyRotateRightFast, ROTATE_RIGHT_FAST, ROTATE_RIGHT_FAST_KEYS );
behaviours.behaviour( keyRotateRightSlow, ROTATE_RIGHT_SLOW, ROTATE_RIGHT_SLOW_KEYS );
behaviours.behaviour( keyZoomIn, KEY_ZOOM_IN, KEY_ZOOM_IN_KEYS );
behaviours.behaviour( keyZoomInFast, KEY_ZOOM_IN_FAST, KEY_ZOOM_IN_FAST_KEYS );
behaviours.behaviour( keyZoomInSlow, KEY_ZOOM_IN_SLOW, KEY_ZOOM_IN_SLOW_KEYS );
behaviours.behaviour( keyZoomOut, KEY_ZOOM_OUT, KEY_ZOOM_OUT_KEYS );
behaviours.behaviour( keyZoomOutFast, KEY_ZOOM_OUT_FAST, KEY_ZOOM_OUT_FAST_KEYS );
behaviours.behaviour( keyZoomOutSlow, KEY_ZOOM_OUT_SLOW, KEY_ZOOM_OUT_SLOW_KEYS );
}
@Override
public void setCanvasSize( final int width, final int height, final boolean updateTransform )
{
if ( width == 0 || height == 0 ) {
// NB: We are probably in some intermediate layout scenario.
// Attempting to trigger a transform update with 0 size will result
// in the exception "Matrix is singular" from imglib2-realtrasform.
return;
}
if ( updateTransform )
{
final AffineTransform3D affine = transform.get();
affine.set( affine.get( 0, 3 ) - canvasW / 2, 0, 3 );
affine.set( affine.get( 1, 3 ) - canvasH / 2, 1, 3 );
affine.scale( ( double ) width / canvasW );
affine.set( affine.get( 0, 3 ) + width / 2, 0, 3 );
affine.set( affine.get( 1, 3 ) + height / 2, 1, 3 );
transform.set( affine );
}
canvasW = width;
canvasH = height;
centerX = width / 2;
centerY = height / 2;
}
/**
* One step of rotation (radian).
*/
final private static double step = Math.PI / 180;
private void scale( final double s, final double x, final double y )
{
final AffineTransform3D affine = transform.get();
// center shift
affine.set( affine.get( 0, 3 ) - x, 0, 3 );
affine.set( affine.get( 1, 3 ) - y, 1, 3 );
// scale
affine.scale( s );
// center un-shift
affine.set( affine.get( 0, 3 ) + x, 0, 3 );
affine.set( affine.get( 1, 3 ) + y, 1, 3 );
transform.set( affine );
}
/**
* Rotate by d radians around Z axis. Keep screen coordinates {@code (centerX, centerY)} fixed.
*/
private void rotate( final AffineTransform3D affine, final double d )
{
// center shift
affine.set( affine.get( 0, 3 ) - centerX, 0, 3 );
affine.set( affine.get( 1, 3 ) - centerY, 1, 3 );
// rotate
affine.rotate( 2, d );
// center un-shift
affine.set( affine.get( 0, 3 ) + centerX, 0, 3 );
affine.set( affine.get( 1, 3 ) + centerY, 1, 3 );
}
private class DragRotate implements DragBehaviour
{
@Override
public void init( final int x, final int y )
{
oX = x;
oY = y;
transform.get( affineDragStart );
}
@Override
public void drag( final int x, final int y )
{
final double dX = x - centerX;
final double dY = y - centerY;
final double odX = oX - centerX;
final double odY = oY - centerY;
final double theta = Math.atan2( dY, dX ) - Math.atan2( odY, odX );
affineDragCurrent.set( affineDragStart );
rotate( affineDragCurrent, theta );
transform.set( affineDragCurrent );
}
@Override
public void end( final int x, final int y )
{}
}
private class ScrollRotate implements ScrollBehaviour
{
private final double speed;
public ScrollRotate( final double speed )
{
this.speed = speed;
}
@Override
public void scroll( final double wheelRotation, final boolean isHorizontal, final int x, final int y )
{
final AffineTransform3D affine = transform.get();
final double theta = speed * wheelRotation * Math.PI / 180.0;
// center shift
affine.set( affine.get( 0, 3 ) - x, 0, 3 );
affine.set( affine.get( 1, 3 ) - y, 1, 3 );
affine.rotate( 2, theta );
// center un-shift
affine.set( affine.get( 0, 3 ) + x, 0, 3 );
affine.set( affine.get( 1, 3 ) + y, 1, 3 );
transform.set( affine );
}
}
private class DragTranslate implements DragBehaviour
{
@Override
public void init( final int x, final int y )
{
oX = x;
oY = y;
transform.get( affineDragStart );
}
@Override
public void drag( final int x, final int y )
{
final double dX = oX - x;
final double dY = oY - y;
affineDragCurrent.set( affineDragStart );
affineDragCurrent.set( affineDragCurrent.get( 0, 3 ) - dX, 0, 3 );
affineDragCurrent.set( affineDragCurrent.get( 1, 3 ) - dY, 1, 3 );
transform.set( affineDragCurrent );
}
@Override
public void end( final int x, final int y )
{}
}
private class ScrollTranslate implements ScrollBehaviour
{
private final double speed;
public ScrollTranslate( final double speed )
{
this.speed = speed;
}
@Override
public void scroll( final double wheelRotation, final boolean isHorizontal, final int x, final int y )
{
final AffineTransform3D affine = transform.get();
final double d = -wheelRotation * 10 * speed;
if ( isHorizontal )
affine.translate( d, 0, 0 );
else
affine.translate( 0, d, 0 );
transform.set( affine );
}
}
private class Zoom implements ScrollBehaviour
{
private final double speed;
public Zoom( final double speed )
{
this.speed = speed;
}
@Override
public void scroll( final double wheelRotation, final boolean isHorizontal, final int x, final int y )
{
final double s = speed * wheelRotation;
final double dScale = 1.0 + 0.05 * Math.abs( s );
if ( s > 0 )
scale( 1.0 / dScale, x, y );
else
scale( dScale, x, y );
}
}
private class KeyRotate implements ClickBehaviour
{
private final double speed;
public KeyRotate( final double speed )
{
this.speed = speed;
}
@Override
public void click( final int x, final int y )
{
final AffineTransform3D affine = transform.get();
rotate( affine, step * speed );
transform.set( affine );
}
}
private class KeyZoom implements ClickBehaviour
{
private final double dScale;
public KeyZoom( final double speed )
{
if ( speed > 0 )
dScale = 1.0 + 0.1 * speed;
else
dScale = 1.0 / ( 1.0 - 0.1 * speed );
}
@Override
public void click( final int x, final int y )
{
scale( dScale, centerX, centerY );
}
}
}
/*-
/*
* #%L
* BigDataViewer core classes with minimal dependencies
* BigDataViewer core classes with minimal dependencies.
* %%
* Copyright (C) 2012 - 2016 Tobias Pietzsch, Stephan Saalfeld, Stephan Preibisch,
* Jean-Yves Tinevez, HongKee Moon, Johannes Schindelin, Curtis Rueden, John Bogovic
* Copyright (C) 2012 - 2020 BigDataViewer developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
......@@ -29,11 +28,15 @@
*/
package bdv;
import org.scijava.ui.behaviour.util.TriggerBehaviourBindings;
import net.imglib2.ui.TransformEventHandler;
public interface BehaviourTransformEventHandler< A > extends TransformEventHandler< A >
/**
* Factory for {@code TransformEventHandler}.
*
* @author Tobias Pietzsch
*/
public interface TransformEventHandlerFactory
{
public void install( final TriggerBehaviourBindings bindings );
/**
* Create a new {@code TransformEventHandler}.
*/
TransformEventHandler create( TransformState transformState );
}
/*
/*-
* #%L
* BigDataViewer core classes with minimal dependencies
* BigDataViewer core classes with minimal dependencies.
* %%
* Copyright (C) 2012 - 2016 Tobias Pietzsch, Stephan Saalfeld, Stephan Preibisch,
* Jean-Yves Tinevez, HongKee Moon, Johannes Schindelin, Curtis Rueden, John Bogovic
* Copyright (C) 2012 - 2020 BigDataViewer developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
......@@ -27,28 +26,53 @@
* POSSIBILITY OF SUCH DAMAGE.
* #L%
*/
package bdv.viewer.render;
import java.awt.image.BufferedImage;
package bdv;
import java.util.function.Consumer;
import net.imglib2.realtransform.AffineTransform3D;
import net.imglib2.ui.RenderTarget;
import net.imglib2.ui.TransformListener;
public interface TransformAwareRenderTarget extends RenderTarget
public interface TransformState
{
/**
* Set the {@link BufferedImage} that is to be drawn on the canvas, and the
* transform with which this image was created.
* Get the current transform.
*
* @param img
* image to draw (may be null).
* @param transform
* is set to the current transform
*/
public BufferedImage setBufferedImageAndTransform( final BufferedImage img, final AffineTransform3D transform );
void get( AffineTransform3D transform );
public void addTransformListener( final TransformListener< AffineTransform3D > listener );
/**
* Get the current transform.
*
* @return a copy of the current transform
*/
default AffineTransform3D get()
{
final AffineTransform3D transform = new AffineTransform3D();
get( transform );
return transform;
}
/**
* Set the transform.
*/
void set( AffineTransform3D transform );
public void addTransformListener( final TransformListener< AffineTransform3D > listener, final int index );
static TransformState from( Consumer< AffineTransform3D > get, Consumer< AffineTransform3D > set )
{
return new TransformState()
{
@Override
public void get( final AffineTransform3D transform )
{
get.accept( transform );
}
public void removeTransformListener( final TransformListener< AffineTransform3D > listener );
@Override
public void set( final AffineTransform3D transform )
{
set.accept( transform );
}
};
}
}
/*
* #%L
* BigDataViewer core classes with minimal dependencies
* BigDataViewer core classes with minimal dependencies.
* %%
* Copyright (C) 2012 - 2016 Tobias Pietzsch, Stephan Saalfeld, Stephan Preibisch,
* Jean-Yves Tinevez, HongKee Moon, Johannes Schindelin, Curtis Rueden, John Bogovic
* Copyright (C) 2012 - 2020 BigDataViewer developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
......@@ -35,7 +34,7 @@ import mpicbg.spim.data.generic.sequence.BasicMultiResolutionImgLoader;
public interface ViewerImgLoader extends BasicMultiResolutionImgLoader
{
@Override
public ViewerSetupImgLoader< ?, ? > getSetupImgLoader( final int setupId );
ViewerSetupImgLoader< ?, ? > getSetupImgLoader( final int setupId );
public CacheControl getCacheControl();
CacheControl getCacheControl();
}
/*
* #%L
* BigDataViewer core classes with minimal dependencies
* BigDataViewer core classes with minimal dependencies.
* %%
* Copyright (C) 2012 - 2016 Tobias Pietzsch, Stephan Saalfeld, Stephan Preibisch,
* Jean-Yves Tinevez, HongKee Moon, Johannes Schindelin, Curtis Rueden, John Bogovic
* Copyright (C) 2012 - 2020 BigDataViewer developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
......@@ -36,7 +35,7 @@ import net.imglib2.Volatile;
public interface ViewerSetupImgLoader< T, V extends Volatile< T > > extends BasicMultiResolutionSetupImgLoader< T >
{
public RandomAccessibleInterval< V > getVolatileImage( final int timepointId, final int level, ImgLoaderHint... hints );
RandomAccessibleInterval< V > getVolatileImage( final int timepointId, final int level, ImgLoaderHint... hints );
public V getVolatileImageType();
V getVolatileImageType();
}
/*
* #%L
* BigDataViewer core classes with minimal dependencies
* BigDataViewer core classes with minimal dependencies.
* %%
* Copyright (C) 2012 - 2016 Tobias Pietzsch, Stephan Saalfeld, Stephan Preibisch,
* Jean-Yves Tinevez, HongKee Moon, Johannes Schindelin, Curtis Rueden, John Bogovic
* Copyright (C) 2012 - 2020 BigDataViewer developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
......
/*
* #%L
* BigDataViewer core classes with minimal dependencies
* BigDataViewer core classes with minimal dependencies.
* %%
* Copyright (C) 2012 - 2016 Tobias Pietzsch, Stephan Saalfeld, Stephan Preibisch,
* Jean-Yves Tinevez, HongKee Moon, Johannes Schindelin, Curtis Rueden, John Bogovic
* Copyright (C) 2012 - 2020 BigDataViewer developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
......@@ -40,7 +39,7 @@ import bdv.img.cache.VolatileGlobalCellCache;
* {@link VolatileGlobalCellCache}, these can be simply implemented to do
* nothing.
*
* @author Tobias Pietzsch &lt;tobias.pietzsch@gmail.com&gt;
* @author Tobias Pietzsch
*/
public interface CacheControl
{
......@@ -54,12 +53,12 @@ public interface CacheControl
* previously enqueued requests to be enqueued again for the new frame.
* </ul>
*/
public void prepareNextFrame();
void prepareNextFrame();
/**
* {@link CacheControl} that does nothing.
*/
public static class Dummy implements CacheControl
class Dummy implements CacheControl
{
@Override
public void prepareNextFrame()
......@@ -70,7 +69,7 @@ public interface CacheControl
* {@link CacheControl} backed by a set of {@link CacheControl}s.
* {@link #prepareNextFrame()} forwards to all of them.
*/
public static class CacheControls implements CacheControl
class CacheControls implements CacheControl
{
private final CopyOnWriteArrayList< CacheControl > cacheControls = new CopyOnWriteArrayList<>();
......@@ -94,6 +93,11 @@ public interface CacheControl
cacheControls.remove( cacheControl );
}
public synchronized void clear()
{
cacheControls.clear();
}
@Override
public void prepareNextFrame()
{
......
/*-
* #%L
* BigDataViewer core classes with minimal dependencies.
* %%
* Copyright (C) 2012 - 2020 BigDataViewer developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* #L%
*/
package bdv.export;
import java.util.Arrays;
import net.imglib2.RandomAccess;
import net.imglib2.loops.ClassCopyProvider;
import net.imglib2.type.numeric.RealType;
public interface CopyBlock< T extends RealType< T > >
{
void copyBlock( final RandomAccess< T > in, final RandomAccess< T > out, final int[] dimensions );
static < T extends RealType< T > > CopyBlock< T > create(
final int numDimensions,
final Class< ? > pixelTypeClass,
final Class< ? > inAccessClass )
{
return CopyBlockInstances.create( numDimensions, pixelTypeClass, inAccessClass );
}
}
class CopyBlockInstances
{
@SuppressWarnings( "rawtypes" )
private static ClassCopyProvider< CopyBlock > provider;
@SuppressWarnings( "unchecked" )
public static < T extends RealType< T > > CopyBlock< T > create(
final int numDimensions,
final Class< ? > pixelTypeClass,
final Class< ? > inAccessClass )
{
if ( provider == null )
{
synchronized ( CopyBlockInstances.class )
{
if ( provider == null )
provider = new ClassCopyProvider<>( Imp.class, CopyBlock.class, int.class );
}
}
Object key = Arrays.asList( numDimensions, pixelTypeClass, inAccessClass );
return provider.newInstanceForKey( key, numDimensions );
}
public static class Imp< T extends RealType< T > > implements CopyBlock< T >
{
private final int n;
public Imp( final int n )
{
if ( n < 1 || n > 3 )
throw new IllegalArgumentException();
this.n = n;
}
@Override
public void copyBlock(
final RandomAccess< T > in,
final RandomAccess< T > out,
final int[] dimensions )
{
if ( n == 3 )
copyBlock3D( out, dimensions[ 0 ], dimensions[ 1 ], dimensions[ 2 ], in );
else if ( n == 2 )
copyBlock2D( out, dimensions[ 0 ], dimensions[ 1 ], in );
else
copyBlock1D( out, dimensions[ 0 ], in );
}
private void copyBlock3D(
final RandomAccess< T > out,
final int sx, // size of output image
final int sy,
final int sz,
final RandomAccess< T > in )
{
for ( int z = 0; z < sz; ++z )
{
copyBlock2D( out, sx, sy, in );
out.fwd( 2 );
in.fwd( 2 );
}
out.move( -sz, 2 );
in.move( -sz, 2 );
}
private void copyBlock2D(
final RandomAccess< T > out,
final int sx, // size of output image
final int sy,
final RandomAccess< T > in )
{
for ( int y = 0; y < sy; ++y )
{
copyBlock1D( out, sx, in );
out.fwd( 1 );
in.fwd( 1 );
}
out.move( -sy, 1 );
in.move( -sy, 1 );
}
private void copyBlock1D(
final RandomAccess< T > out,
final int sx, // size of output image
final RandomAccess< T > in )
{
for ( int x = 0; x < sx; ++x )
{
out.get().set( in.get() );
out.fwd( 0 );
in.fwd( 0 );
}
out.move( -sx, 0 );
in.move( -sx, 0 );
}
}
}
/*
* #%L
* BigDataViewer core classes with minimal dependencies
* BigDataViewer core classes with minimal dependencies.
* %%
* Copyright (C) 2012 - 2016 Tobias Pietzsch, Stephan Saalfeld, Stephan Preibisch,
* Jean-Yves Tinevez, HongKee Moon, Johannes Schindelin, Curtis Rueden, John Bogovic
* Copyright (C) 2012 - 2020 BigDataViewer developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
......@@ -44,6 +43,9 @@ import net.imglib2.view.Views;
public class Downsample
{
/**
* TODO: Revise. This is probably not very efficient
*/
public static < T extends RealType< T > > void downsample( final RandomAccessible< T > input, final RandomAccessibleInterval< T > output, final int[] factor )
{
assert input.numDimensions() == output.numDimensions();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment