Skip to content

Commit 86593ce

Browse files
authored
Merge pull request #21 from UU-cellbiology/nextRelease
Next release
2 parents 2558e2c + 20e8486 commit 86593ce

5 files changed

Lines changed: 241 additions & 26 deletions

File tree

pom.xml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
<groupId>nl.uu.science.cellbiology</groupId>
1313
<artifactId>bigtrace</artifactId>
14-
<version>0.9.1-SNAPSHOT</version>
14+
<version>0.9.1</version>
1515

1616
<name>BigTrace</name>
1717
<description>Tracing of curvilinear structures in 3D</description>
@@ -83,7 +83,7 @@
8383
<license.copyrightOwners>Cell Biology, Neurobiology and Biophysics Department of Utrecht University.</license.copyrightOwners>
8484
<!-- NB: Deploy releases to the SciJava Maven repository. -->
8585
<!-- releaseProfiles>sign,deploy-to-scijava</releaseProfiles -->
86-
<bvv-playground.version>0.5.5</bvv-playground.version>
86+
<bvv-playground.version>0.5.6</bvv-playground.version>
8787
<bdv-loaders.version>0.10.0</bdv-loaders.version>
8888
</properties>
8989

@@ -151,10 +151,6 @@
151151
<groupId>net.imglib2</groupId>
152152
<artifactId>imglib2-realtransform</artifactId>
153153
</dependency>
154-
<dependency>
155-
<groupId>net.imglib2</groupId>
156-
<artifactId>imglib2-roi</artifactId>
157-
</dependency>
158154
<dependency>
159155
<groupId>net.imglib2</groupId>
160156
<artifactId>imglib2-ij</artifactId>
@@ -164,6 +160,13 @@
164160
<groupId>org.scijava</groupId>
165161
<artifactId>ui-behaviour</artifactId>
166162
</dependency>
163+
164+
<!-- N5 Utils -->
165+
<dependency>
166+
<groupId>org.janelia.saalfeldlab</groupId>
167+
<artifactId>n5-viewer_fiji</artifactId>
168+
</dependency>
169+
167170
<dependency>
168171
<groupId>org.jogamp.jogl</groupId>
169172
<artifactId>jogl-all</artifactId>

src/main/java/bigtrace/BigTrace.java

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,22 @@
11
package bigtrace;
22

33
import java.awt.Color;
4-
import java.awt.Cursor;
5-
import java.awt.Desktop;
6-
import java.awt.GridBagConstraints;
7-
import java.awt.GridBagLayout;
8-
import java.awt.Insets;
9-
import java.awt.event.MouseAdapter;
10-
import java.awt.event.MouseEvent;
4+
115
import java.awt.event.WindowAdapter;
126
import java.awt.event.WindowEvent;
137
import java.io.File;
14-
import java.io.IOException;
15-
import java.net.URI;
16-
import java.net.URISyntaxException;
178
import java.nio.file.Path;
189
import java.nio.file.Paths;
1910
import java.util.ArrayList;
2011
import java.util.List;
2112

2213
import javax.swing.JFrame;
23-
import javax.swing.JLabel;
2414
import javax.swing.JOptionPane;
25-
import javax.swing.JPanel;
2615
import javax.swing.SwingUtilities;
2716
import javax.swing.UIManager;
2817
import javax.swing.WindowConstants;
2918

19+
import org.janelia.saalfeldlab.control.mcu.XTouchMiniMCUControlPanel;
3020
import org.joml.Matrix4f;
3121
import org.joml.Vector3f;
3222

@@ -40,7 +30,6 @@
4030

4131
import ij.IJ;
4232
import ij.ImageJ;
43-
import ij.Prefs;
4433
import ij.macro.ExtensionDescriptor;
4534
import ij.macro.Functions;
4635
import ij.macro.MacroExtension;
@@ -88,6 +77,7 @@
8877
import bigtrace.gui.AnisotropicTransformAnimator3D;
8978
import bigtrace.gui.AxesOverlayRenderer;
9079
import bigtrace.gui.GuiMisc;
80+
import bigtrace.gui.MCUBVVControls;
9181
import bigtrace.gui.TaskBT;
9282
import bigtrace.gui.VisualBoxes;
9383
import bigtrace.io.ViewsIO;
@@ -203,6 +193,8 @@ public void run(String arg)
203193
if(arg.equals(""))
204194
{
205195
btData.sFileNameFullImg = IJ.getFilePath("Open TIF/BDV/Bioformats file (3D, composite, time)...");
196+
if(btData.sFileNameFullImg == null)
197+
return;
206198
}
207199
else
208200
{
@@ -378,6 +370,12 @@ public void windowClosing( WindowEvent ev )
378370

379371
btPanel.finFrame.addWindowListener( closeWA );
380372
bvvFrame.addWindowListener( closeWA );
373+
try {
374+
final XTouchMiniMCUControlPanel controlPanel = XTouchMiniMCUControlPanel.build();
375+
new MCUBVVControls(
376+
bvvHandle.getViewerPanel(),
377+
controlPanel);
378+
} catch (final Exception e) {}
381379
bInputLock = false;
382380

383381
//check if there is a saved view
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
/*-
2+
* #%L
3+
* browsing large volumetric data
4+
* %%
5+
* Copyright (C) 2025 - 2026 Cell Biology, Neurobiology and Biophysics Department of Utrecht University.
6+
* %%
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice,
11+
* this list of conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright notice,
13+
* this list of conditions and the following disclaimer in the documentation
14+
* and/or other materials provided with the distribution.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
20+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
* POSSIBILITY OF SUCH DAMAGE.
27+
* #L%
28+
*/
29+
package bigtrace.gui;
30+
31+
import java.util.function.IntConsumer;
32+
33+
import net.imglib2.realtransform.AffineTransform3D;
34+
35+
import org.janelia.saalfeldlab.control.ButtonControl;
36+
import org.janelia.saalfeldlab.control.VPotControl;
37+
import org.janelia.saalfeldlab.control.mcu.MCUControlPanel;
38+
39+
import bdv.viewer.Interpolation;
40+
import bdv.viewer.SynchronizedViewerState;
41+
import bvvpg.core.VolumeViewerPanel;
42+
import bdv.viewer.AbstractViewerPanel.AlignPlane;
43+
44+
public class MCUBVVControls
45+
{
46+
/**
47+
* One step of rotation (radian).
48+
*/
49+
final private static double step = Math.PI / 180;
50+
51+
private final VolumeViewerPanel viewerPanel;
52+
53+
public MCUBVVControls(final VolumeViewerPanel viewer, final MCUControlPanel panel) {
54+
55+
this.viewerPanel = viewer;
56+
57+
/* add handlers */
58+
VPotControl control = panel.getVPotControl(0);
59+
control.setAbsolute(false);
60+
control.setMinMax(-10, 10);
61+
control.setDisplayType(VPotControl.DISPLAY_TRIM);
62+
control.addListener(new VPotAxisShiftHandler(0));
63+
64+
control = panel.getVPotControl(1);
65+
control.setAbsolute(false);
66+
control.setMinMax(-10, 10);
67+
control.setDisplayType(VPotControl.DISPLAY_TRIM);
68+
control.addListener(new VPotAxisShiftHandler(1));
69+
70+
control = panel.getVPotControl(2);
71+
control.setAbsolute(false);
72+
control.setMinMax(-10, 10);
73+
control.setDisplayType(VPotControl.DISPLAY_TRIM);
74+
control.addListener(new VPotAxisShiftHandler(2));
75+
76+
control = panel.getVPotControl(3);
77+
control.setAbsolute(false);
78+
control.setMinMax(-10, 10);
79+
control.setDisplayType(VPotControl.DISPLAY_TRIM);
80+
control.addListener(new VPotAxisRotationHandler(0));
81+
82+
control = panel.getVPotControl(4);
83+
control.setAbsolute(false);
84+
control.setMinMax(-10, 10);
85+
control.setDisplayType(VPotControl.DISPLAY_TRIM);
86+
control.addListener(new VPotAxisRotationHandler(1));
87+
88+
control = panel.getVPotControl(5);
89+
control.setAbsolute(false);
90+
control.setMinMax(-10, 10);
91+
control.setDisplayType(VPotControl.DISPLAY_TRIM);
92+
control.addListener(new VPotAxisRotationHandler(2));
93+
94+
control = panel.getVPotControl(6);
95+
control.setAbsolute(false);
96+
control.setMinMax(-10, 10);
97+
control.setDisplayType(VPotControl.DISPLAY_TRIM);
98+
control.addListener(new VPotZoomHandler());
99+
100+
ButtonControl key = panel.getButtonControl(0);
101+
key.setToggle(true);
102+
key.addListener(new InterpolationSwitcher());
103+
104+
key = panel.getButtonControl(18);
105+
key.setToggle(false);
106+
key.addListener(i -> {
107+
if (i != 0)
108+
viewer.align(AlignPlane.ZY);
109+
});
110+
111+
key = panel.getButtonControl(19);
112+
key.setToggle(false);
113+
key.addListener(i -> {
114+
if (i != 0)
115+
viewer.align(AlignPlane.XZ);
116+
});
117+
118+
key = panel.getButtonControl(20);
119+
key.setToggle(false);
120+
key.addListener(i -> {
121+
if (i != 0)
122+
viewer.align(AlignPlane.XY);
123+
});
124+
125+
//System.out.println(viewerPanel.getRootPane().getParent());
126+
}
127+
128+
public class VPotAxisRotationHandler implements IntConsumer {
129+
130+
private final int axis;
131+
132+
public VPotAxisRotationHandler(final int axis) {
133+
134+
this.axis = axis;
135+
}
136+
137+
@Override
138+
public void accept(final int value) {
139+
140+
final SynchronizedViewerState state = viewerPanel.state();
141+
final AffineTransform3D viewerTransform = state.getViewerTransform();
142+
143+
// center shift
144+
final double cX = 0.5 * viewerPanel.getWidth();
145+
final double cY = 0.5 * viewerPanel.getHeight();
146+
viewerTransform.set(viewerTransform.get(0, 3) - cX, 0, 3);
147+
viewerTransform.set(viewerTransform.get(1, 3) - cY, 1, 3);
148+
149+
// rotate
150+
viewerTransform.rotate(axis, value * step);
151+
152+
// center un-shift
153+
viewerTransform.set(viewerTransform.get(0, 3) + cX, 0, 3);
154+
viewerTransform.set(viewerTransform.get(1, 3) + cY, 1, 3);
155+
156+
state.setViewerTransform(viewerTransform);
157+
}
158+
}
159+
160+
public class VPotAxisShiftHandler implements IntConsumer {
161+
162+
private final int axis;
163+
164+
public VPotAxisShiftHandler(final int axis) {
165+
166+
this.axis = axis;
167+
}
168+
169+
@Override
170+
public void accept(final int value) {
171+
172+
final SynchronizedViewerState state = viewerPanel.state();
173+
final AffineTransform3D viewerTransform = state.getViewerTransform();
174+
175+
viewerTransform.set(viewerTransform.get(axis, 3) + value, axis, 3);
176+
177+
state.setViewerTransform(viewerTransform);
178+
}
179+
}
180+
181+
public class VPotZoomHandler implements IntConsumer {
182+
183+
@Override
184+
public void accept(final int value) {
185+
186+
final SynchronizedViewerState state = viewerPanel.state();
187+
final AffineTransform3D viewerTransform = state.getViewerTransform();
188+
189+
// center shift
190+
final double cX = 0.5 * viewerPanel.getWidth();
191+
final double cY = 0.5 * viewerPanel.getHeight();
192+
viewerTransform.set(viewerTransform.get(0, 3) - cX, 0, 3);
193+
viewerTransform.set(viewerTransform.get(1, 3) - cY, 1, 3);
194+
195+
// rotate
196+
final double dScale = 1.0 + 0.05;
197+
viewerTransform.scale(Math.pow(dScale, value));
198+
199+
// center un-shift
200+
viewerTransform.set(viewerTransform.get(0, 3) + cX, 0, 3);
201+
viewerTransform.set(viewerTransform.get(1, 3) + cY, 1, 3);
202+
203+
state.setViewerTransform(viewerTransform);
204+
}
205+
}
206+
207+
public class InterpolationSwitcher implements IntConsumer {
208+
209+
@Override
210+
public void accept(final int value) {
211+
212+
final SynchronizedViewerState state = viewerPanel.state();
213+
state.setInterpolation(value == 0 ? Interpolation.NEARESTNEIGHBOR : Interpolation.NLINEAR);
214+
}
215+
}
216+
}

src/main/java/bigtrace/math/OneClickTrace.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,8 +239,7 @@ public void runTracing ()
239239
//fill array of previous point
240240
allPointsIntersection = existingTracing.makeJointSegmentDouble();
241241
nTotPoints = allPointsIntersection.size();
242-
}
243-
242+
}
244243

245244
if(bNewTrace)
246245
{
@@ -397,7 +396,7 @@ public int traceOneDirection(boolean bFirstTrace, int nCountIn)
397396
}
398397
}
399398
//adding last part of the trace
400-
bt.roiManager.addSegment(points.get(points.size()-1), points);
399+
bt.roiManager.addSegment( points.get( points.size() - 1 ), points);
401400

402401
return nCountPoints;
403402
}

src/main/java/bigtrace/rois/RoiManager3D.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ public synchronized void addRoi(final Roi3D newRoi)
483483
rois.add(newRoi);
484484
if(!bt.btMacro.bMacroMode)
485485
{
486-
TaskBT.runOnEDT( ()->
486+
TaskBT.runOnEDTAndWait( ()->
487487
{
488488
listModel.addElement(getFullDisplayedRoiName(newRoi));
489489
jlist.setSelectedIndex( rois.size() - 1 );
@@ -521,7 +521,7 @@ public synchronized void insertRoi(final Roi3D newRoi, final int nInsertN)
521521
rois.add(nInsertN, newRoi);
522522
if(!bt.btMacro.bMacroMode)
523523
{
524-
TaskBT.runOnEDT( ()->
524+
TaskBT.runOnEDTAndWait( ()->
525525
{
526526
listModel.insertElementAt(newRoi.getName(), nInsertN);
527527
jlist.setSelectedIndex( nInsertN );
@@ -1367,8 +1367,7 @@ public void setOneClickTracing(boolean bBegin)
13671367
else
13681368
{
13691369
roiPolyOneClickMode.setIcon(tabIconOCTrace);
1370-
roiPolyOneClickMode.setToolTipText("One click trace");
1371-
1370+
roiPolyOneClickMode.setToolTipText("One click trace");
13721371
}
13731372
}
13741373

0 commit comments

Comments
 (0)