From 28afd09b7614a5312a2f3adbe3aa9116e4bc6b22 Mon Sep 17 00:00:00 2001 From: Kyle IS Harrington Date: Mon, 5 Oct 2020 20:23:50 +0200 Subject: [PATCH 01/23] Rename .java to .kt --- .../sc/iview/commands/LaunchViewer.kt} | 0 .../MenuWeights.java => kotlin/sc/iview/commands/MenuWeights.kt} | 0 .../sc/iview/commands/demo/VolumeRenderDemo.kt} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename src/main/{java/sc/iview/commands/LaunchViewer.java => kotlin/sc/iview/commands/LaunchViewer.kt} (100%) rename src/main/{java/sc/iview/commands/MenuWeights.java => kotlin/sc/iview/commands/MenuWeights.kt} (100%) rename src/main/{java/sc/iview/commands/demo/VolumeRenderDemo.java => kotlin/sc/iview/commands/demo/VolumeRenderDemo.kt} (100%) diff --git a/src/main/java/sc/iview/commands/LaunchViewer.java b/src/main/kotlin/sc/iview/commands/LaunchViewer.kt similarity index 100% rename from src/main/java/sc/iview/commands/LaunchViewer.java rename to src/main/kotlin/sc/iview/commands/LaunchViewer.kt diff --git a/src/main/java/sc/iview/commands/MenuWeights.java b/src/main/kotlin/sc/iview/commands/MenuWeights.kt similarity index 100% rename from src/main/java/sc/iview/commands/MenuWeights.java rename to src/main/kotlin/sc/iview/commands/MenuWeights.kt diff --git a/src/main/java/sc/iview/commands/demo/VolumeRenderDemo.java b/src/main/kotlin/sc/iview/commands/demo/VolumeRenderDemo.kt similarity index 100% rename from src/main/java/sc/iview/commands/demo/VolumeRenderDemo.java rename to src/main/kotlin/sc/iview/commands/demo/VolumeRenderDemo.kt From fb50dd42f0e3b30d7af8ba09e74a3ae814085821 Mon Sep 17 00:00:00 2001 From: Kyle IS Harrington Date: Mon, 5 Oct 2020 20:23:50 +0200 Subject: [PATCH 02/23] Refactor MenuWeights, LaunchViewer, VolumeRenderDemo to Kotlin --- .../kotlin/sc/iview/commands/LaunchViewer.kt | 57 +++---- .../kotlin/sc/iview/commands/MenuWeights.kt | 117 +++++++------- .../iview/commands/demo/VolumeRenderDemo.kt | 148 ++++++++---------- 3 files changed, 140 insertions(+), 182 deletions(-) diff --git a/src/main/kotlin/sc/iview/commands/LaunchViewer.kt b/src/main/kotlin/sc/iview/commands/LaunchViewer.kt index bbbab351..142f3ff4 100644 --- a/src/main/kotlin/sc/iview/commands/LaunchViewer.kt +++ b/src/main/kotlin/sc/iview/commands/LaunchViewer.kt @@ -26,55 +26,42 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package sc.iview.commands; +package sc.iview.commands -import org.scijava.ItemIO; -import org.scijava.command.Command; -import org.scijava.display.DisplayService; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.Plugin; -import org.scijava.ui.UIService; - -import sc.iview.SciView; -import sc.iview.SciViewService; -import sc.iview.display.SciViewDisplay; +import org.scijava.ItemIO +import org.scijava.command.Command +import org.scijava.display.DisplayService +import org.scijava.plugin.Parameter +import org.scijava.plugin.Plugin +import org.scijava.ui.UIService +import sc.iview.SciView +import sc.iview.SciViewService +import sc.iview.display.SciViewDisplay /** * Command to launch SciView * * @author Kyle Harrington - * */ -@Plugin(type = Command.class, menuPath = "Plugins>SciView") -public class LaunchViewer implements Command { - +@Plugin(type = Command::class, menuPath = "Plugins>SciView") +class LaunchViewer : Command { @Parameter - private DisplayService displayService; + private lateinit var displayService: DisplayService @Parameter - private SciViewService sciViewService; - - @Parameter(required = false) - private UIService uiService; + private lateinit var sciViewService: SciViewService @Parameter(type = ItemIO.OUTPUT) - private SciView sciView = null; - - @Override - public void run() { - final SciViewDisplay display = displayService.getActiveDisplay(SciViewDisplay.class); + private var sciView: SciView? = null + override fun run() { + val display = displayService.getActiveDisplay(SciViewDisplay::class.java) try { if (display == null) { - sciView = sciViewService.getOrCreateActiveSciView(); - } - else - sciViewService.createSciView(); - } catch (Exception e) { - e.printStackTrace(); + sciView = sciViewService.orCreateActiveSciView + } else sciViewService.createSciView() + } catch (e: Exception) { + e.printStackTrace() } - -// else if (uiService != null) -// uiService.showDialog( "The SciView window is already open. For now, only one SciView window is supported.", "SciView" ); } -} +} \ No newline at end of file diff --git a/src/main/kotlin/sc/iview/commands/MenuWeights.kt b/src/main/kotlin/sc/iview/commands/MenuWeights.kt index e737709b..bcbfd18b 100644 --- a/src/main/kotlin/sc/iview/commands/MenuWeights.kt +++ b/src/main/kotlin/sc/iview/commands/MenuWeights.kt @@ -26,7 +26,7 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package sc.iview.commands; +package sc.iview.commands /** * Constants for coherent menu ordering. @@ -34,66 +34,55 @@ package sc.iview.commands; * @author Curtis Rueden * @author Kyle Harrington */ -public final class MenuWeights { - private MenuWeights() { - // NB: Prevent instantiation of utility class. - } - - public static final double FILE = 0; - public static final double EDIT = 1; - public static final double PROCESS = 2; - public static final double VIEW = 3; - public static final double DEMO = 4; - public static final double HELP = 4; - - public static final double FILE_OPEN = 0; - public static final double FILE_EXPORT_STL = 100; - - public static final double EDIT_ADD_BOX = 0; - public static final double EDIT_ADD_SPHERE = 1; - public static final double EDIT_ADD_LINE = 2; - public static final double EDIT_ADD_POINT_LIGHT = 3; - public static final double EDIT_ADD_LABEL_IMAGE = 4; - public static final double EDIT_ADD_VOLUME = 5; - public static final double EDIT_ADD_CAMERA = 6; - public static final double EDIT_ADD_COMPASS = 49; - public static final double EDIT_TOGGLE_FLOOR = 50; - public static final double EDIT_DELETE_OBJECT = 100; - public static final double EDIT_SCIVIEW_SETTINGS = 200; - - public static final double PROCESS_ISOSURFACE = 0; - public static final double PROCESS_CONVEX_HULL = 1; - public static final double PROCESS_MESH_TO_IMAGE = 2; - public static final double PROCESS_INTERACTIVE_CONVEX_MESH = 3; - public static final double PROCESS_DRAW_LINES = 4; - - public static final double VIEW_ROTATE = 0; - public static final double VIEW_STOP_ANIMATION = 1; - public static final double VIEW_TOGGLE_UNLIMITED_FRAMERATE = 2; - public static final double VIEW_SET_SUPERSAMPLING_FACTOR = 3; - public static final double VIEW_SET_FAR_PLANE = 4; - public static final double VIEW_START_RECORDING_VIDEO = 98; - public static final double VIEW_STOP_RECORDING_VIDEO = 99; - public static final double VIEW_SCREENSHOT = 100; - public static final double VIEW_SET_LUT = 101; - public static final double VIEW_TOGGLE_BOUNDING_GRID = 102; - public static final double VIEW_CENTER_ON_ACTIVE_NODE = 103; - public static final double VIEW_RESET_CAMERA_ROTATION = 202; - public static final double VIEW_RESET_CAMERA_POSITION = 203; - public static final double VIEW_SAVE_CAMERA_CONFIGURATION = 204; - public static final double VIEW_TOGGLE_INSPECTOR = 302; - public static final double VIEW_RENDER_TO_OPENVR = 303; - public static final double VIEW_SET_TRANSFER_FUNCTION = 400; - - - public static final double DEMO_LINES = 0; - public static final double DEMO_MESH = 1; - public static final double DEMO_MESH_TEXTURE = 2; - public static final double DEMO_VOLUME_RENDER = 3; - public static final double DEMO_GAME_OF_LIFE = 4; - public static final double DEMO_TEXT = 5; - public static final double DEMO_EMBRYO = 6; - - public static final double HELP_HELP = 0; - public static final double HELP_ABOUT = 200; -} +object MenuWeights { + const val FILE = 0.0 + const val EDIT = 1.0 + const val PROCESS = 2.0 + const val VIEW = 3.0 + const val DEMO = 4.0 + const val HELP = 4.0 + const val FILE_OPEN = 0.0 + const val FILE_EXPORT_STL = 100.0 + const val EDIT_ADD_BOX = 0.0 + const val EDIT_ADD_SPHERE = 1.0 + const val EDIT_ADD_LINE = 2.0 + const val EDIT_ADD_POINT_LIGHT = 3.0 + const val EDIT_ADD_LABEL_IMAGE = 4.0 + const val EDIT_ADD_VOLUME = 5.0 + const val EDIT_ADD_CAMERA = 6.0 + const val EDIT_ADD_COMPASS = 49.0 + const val EDIT_TOGGLE_FLOOR = 50.0 + const val EDIT_DELETE_OBJECT = 100.0 + const val EDIT_SCIVIEW_SETTINGS = 200.0 + const val PROCESS_ISOSURFACE = 0.0 + const val PROCESS_CONVEX_HULL = 1.0 + const val PROCESS_MESH_TO_IMAGE = 2.0 + const val PROCESS_INTERACTIVE_CONVEX_MESH = 3.0 + const val PROCESS_DRAW_LINES = 4.0 + const val VIEW_ROTATE = 0.0 + const val VIEW_STOP_ANIMATION = 1.0 + const val VIEW_TOGGLE_UNLIMITED_FRAMERATE = 2.0 + const val VIEW_SET_SUPERSAMPLING_FACTOR = 3.0 + const val VIEW_SET_FAR_PLANE = 4.0 + const val VIEW_START_RECORDING_VIDEO = 98.0 + const val VIEW_STOP_RECORDING_VIDEO = 99.0 + const val VIEW_SCREENSHOT = 100.0 + const val VIEW_SET_LUT = 101.0 + const val VIEW_TOGGLE_BOUNDING_GRID = 102.0 + const val VIEW_CENTER_ON_ACTIVE_NODE = 103.0 + const val VIEW_RESET_CAMERA_ROTATION = 202.0 + const val VIEW_RESET_CAMERA_POSITION = 203.0 + const val VIEW_SAVE_CAMERA_CONFIGURATION = 204.0 + const val VIEW_TOGGLE_INSPECTOR = 302.0 + const val VIEW_RENDER_TO_OPENVR = 303.0 + const val VIEW_SET_TRANSFER_FUNCTION = 400.0 + const val DEMO_LINES = 0.0 + const val DEMO_MESH = 1.0 + const val DEMO_MESH_TEXTURE = 2.0 + const val DEMO_VOLUME_RENDER = 3.0 + const val DEMO_GAME_OF_LIFE = 4.0 + const val DEMO_TEXT = 5.0 + const val DEMO_EMBRYO = 6.0 + const val HELP_HELP = 0.0 + const val HELP_ABOUT = 200.0 +} \ No newline at end of file diff --git a/src/main/kotlin/sc/iview/commands/demo/VolumeRenderDemo.kt b/src/main/kotlin/sc/iview/commands/demo/VolumeRenderDemo.kt index 7e209987..2c7c01ab 100644 --- a/src/main/kotlin/sc/iview/commands/demo/VolumeRenderDemo.kt +++ b/src/main/kotlin/sc/iview/commands/demo/VolumeRenderDemo.kt @@ -26,34 +26,28 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package sc.iview.commands.demo; - -import graphics.scenery.Node; -import graphics.scenery.volumes.Volume; -import io.scif.services.DatasetIOService; -import net.imagej.Dataset; -import net.imagej.mesh.Mesh; -import net.imagej.ops.OpService; -import net.imagej.ops.geom.geom3d.mesh.BitTypeVertexInterpolator; -import net.imglib2.img.Img; -import net.imglib2.type.logic.BitType; -import net.imglib2.type.numeric.integer.UnsignedByteType; -import org.joml.Vector3f; -import org.scijava.command.Command; -import org.scijava.command.CommandService; -import org.scijava.log.LogService; -import org.scijava.plugin.Menu; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.Plugin; -import sc.iview.SciView; -import sc.iview.process.MeshConverter; - -import java.io.File; -import java.io.IOException; -import java.util.HashMap; - -import static sc.iview.commands.MenuWeights.DEMO; -import static sc.iview.commands.MenuWeights.DEMO_VOLUME_RENDER; +package sc.iview.commands.demo + +import graphics.scenery.volumes.Volume +import io.scif.services.DatasetIOService +import net.imagej.Dataset +import net.imagej.ops.OpService +import net.imagej.ops.geom.geom3d.mesh.BitTypeVertexInterpolator +import net.imglib2.img.Img +import net.imglib2.type.logic.BitType +import net.imglib2.type.numeric.integer.UnsignedByteType +import org.scijava.command.Command +import org.scijava.command.CommandService +import org.scijava.log.LogService +import org.scijava.plugin.Menu +import org.scijava.plugin.Parameter +import org.scijava.plugin.Plugin +import sc.iview.SciView +import sc.iview.commands.MenuWeights.DEMO +import sc.iview.commands.MenuWeights.DEMO_VOLUME_RENDER +import sc.iview.process.MeshConverter +import java.io.IOException +import java.util.* /** * A demo of volume rendering. @@ -61,73 +55,61 @@ import static sc.iview.commands.MenuWeights.DEMO_VOLUME_RENDER; * @author Kyle Harrington * @author Curtis Rueden */ -@Plugin(type = Command.class, label = "Volume Render/Isosurface Demo", menuRoot = "SciView", // - menu = { @Menu(label = "Demo", weight = DEMO), // - @Menu(label = "Volume Render/Isosurface", weight = DEMO_VOLUME_RENDER) }) -public class VolumeRenderDemo implements Command { - +@Plugin(type = Command::class, label = "Volume Render/Isosurface Demo", menuRoot = "SciView", menu = [Menu(label = "Demo", weight = DEMO), Menu(label = "Volume Render/Isosurface", weight = DEMO_VOLUME_RENDER)]) +class VolumeRenderDemo : Command { @Parameter - private DatasetIOService datasetIO; + private lateinit var datasetIO: DatasetIOService @Parameter - private LogService log; + private lateinit var log: LogService @Parameter - private OpService ops; + private lateinit var ops: OpService @Parameter - private SciView sciView; + private lateinit var sciView: SciView @Parameter(label = "Show isosurface") - private boolean iso = true; - - @Override - public void run() { - final Dataset cube; - try { - File cubeFile = ResourceLoader.createFile( getClass(), "/cored_cube_var2_8bit.tif" ); - - cube = datasetIO.open( cubeFile.getAbsolutePath() ); - } - catch (IOException exc) { - log.error( exc ); - return; + private var iso: Boolean = true + + override fun run() { + val cube: Dataset + cube = try { + val cubeFile = ResourceLoader.createFile(javaClass, "/cored_cube_var2_8bit.tif") + datasetIO.open(cubeFile.absolutePath) + } catch (exc: IOException) { + log.error(exc) + return } - - Volume v = (Volume) sciView.addVolume( cube, new float[] { 1, 1, 1 } ); - v.setPixelToWorldRatio(0.05f); - v.setName( "Volume Render Demo" ); - v.setDirty(true); - v.setNeedsUpdate(true); - + val v = sciView.addVolume(cube, floatArrayOf(1f, 1f, 1f)) as Volume + v.pixelToWorldRatio = 0.05f + v.name = "Volume Render Demo" + v.dirty = true + v.needsUpdate = true if (iso) { - int isoLevel = 1; - - @SuppressWarnings("unchecked") - Img cubeImg = ( Img ) cube.getImgPlus().getImg(); - - Img bitImg = ( Img ) ops.threshold().apply( cubeImg, new UnsignedByteType( isoLevel ) ); - - Mesh m = ops.geom().marchingCubes( bitImg, isoLevel, new BitTypeVertexInterpolator() ); - - graphics.scenery.Mesh isoSurfaceMesh = MeshConverter.toScenery(m,false); - v.addChild(isoSurfaceMesh); - - isoSurfaceMesh.setName( "Volume Render Demo Isosurface" ); + val isoLevel = 1 + + @Suppress("UNCHECKED_CAST") + val cubeImg = cube.imgPlus.img as Img + val bitImg = ops.threshold().apply(cubeImg, UnsignedByteType(isoLevel)) as Img + val m = ops.geom().marchingCubes(bitImg, isoLevel.toDouble(), BitTypeVertexInterpolator()) + val isoSurfaceMesh = MeshConverter.toScenery(m, false) + v.addChild(isoSurfaceMesh) + isoSurfaceMesh.name = "Volume Render Demo Isosurface" } - - sciView.setActiveNode(v); - sciView.centerOnNode( sciView.getActiveNode() ); + sciView.activeNode = v + sciView.centerOnNode(sciView.activeNode) } - public static void main(String... args) throws Exception { - SciView sv = SciView.create(); - - CommandService command = sv.getScijavaContext().getService(CommandService.class); - - HashMap argmap = new HashMap(); - argmap.put("iso",true); - - command.run(VolumeRenderDemo.class, true, argmap); + companion object { + @Throws(Exception::class) + @JvmStatic + fun main(args: Array) { + val sv = SciView.create() + val command = sv.scijavaContext!!.getService(CommandService::class.java) + val argmap = HashMap() + argmap["iso"] = true + command.run(VolumeRenderDemo::class.java, true, argmap) + } } -} +} \ No newline at end of file From 535e33f12e36849a55c1bd46212d1304e9cd68ad Mon Sep 17 00:00:00 2001 From: Kyle IS Harrington Date: Mon, 5 Oct 2020 20:37:37 +0200 Subject: [PATCH 03/23] Update to latest scenery --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 33389c8c..75f39b02 100644 --- a/pom.xml +++ b/pom.xml @@ -108,7 +108,7 @@ deploy-to-scijava - b5c63ad + e5ca73c 1.4.10 From 934f1b9987d69681456fd7867dff12186c9e8d54 Mon Sep 17 00:00:00 2001 From: Kyle IS Harrington Date: Mon, 5 Oct 2020 20:53:02 +0200 Subject: [PATCH 04/23] Refactor ToggleUnlimitedFramerate to Kotlin --- .../view/ToggleUnlimitedFramerate.java | 64 ------------------- .../commands/view/ToggleUnlimitedFramerate.kt | 24 +++++++ 2 files changed, 24 insertions(+), 64 deletions(-) delete mode 100644 src/main/java/sc/iview/commands/view/ToggleUnlimitedFramerate.java create mode 100644 src/main/kotlin/sc/iview/commands/view/ToggleUnlimitedFramerate.kt diff --git a/src/main/java/sc/iview/commands/view/ToggleUnlimitedFramerate.java b/src/main/java/sc/iview/commands/view/ToggleUnlimitedFramerate.java deleted file mode 100644 index d3399138..00000000 --- a/src/main/java/sc/iview/commands/view/ToggleUnlimitedFramerate.java +++ /dev/null @@ -1,64 +0,0 @@ -/*- - * #%L - * Scenery-backed 3D visualization package for ImageJ. - * %% - * Copyright (C) 2016 - 2020 SciView 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 sc.iview.commands.view; - -import org.scijava.command.Command; -import org.scijava.log.LogService; -import org.scijava.plugin.Menu; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.Plugin; -import sc.iview.SciView; - -import static sc.iview.commands.MenuWeights.VIEW; -import static sc.iview.commands.MenuWeights.VIEW_TOGGLE_UNLIMITED_FRAMERATE; - -/** - * Command to toggle scenery's PushMode. If this is true the scene only renders when it is changed, otherwise it is - * continuously rendered - * - * @author Kyle Harrington - * - */ -@Plugin(type = Command.class, menuRoot = "SciView", // - menu = {@Menu(label = "View", weight = VIEW), // - @Menu(label = "Toggle Unlimited Framerate", weight = VIEW_TOGGLE_UNLIMITED_FRAMERATE)}) -public class ToggleUnlimitedFramerate implements Command { - - @Parameter - private LogService logService; - - @Parameter - private SciView sciView; - - @Override - public void run() { - sciView.setPushMode(!sciView.getPushMode()); - } - -} diff --git a/src/main/kotlin/sc/iview/commands/view/ToggleUnlimitedFramerate.kt b/src/main/kotlin/sc/iview/commands/view/ToggleUnlimitedFramerate.kt new file mode 100644 index 00000000..5838d0f8 --- /dev/null +++ b/src/main/kotlin/sc/iview/commands/view/ToggleUnlimitedFramerate.kt @@ -0,0 +1,24 @@ +package sc.iview.commands.view + +import org.scijava.command.Command +import org.scijava.plugin.Menu +import org.scijava.plugin.Parameter +import org.scijava.plugin.Plugin +import sc.iview.SciView +import sc.iview.commands.MenuWeights + +/** + * Command to toggle scenery's PushMode. If this is true the scene only renders when it is changed, otherwise it is + * continuously rendered + * + * @author Kyle Harrington + */ +@Plugin(type = Command::class, menuRoot = "SciView", menu = [Menu(label = "View", weight = MenuWeights.VIEW), Menu(label = "Toggle Unlimited Framerate", weight = MenuWeights.VIEW_TOGGLE_UNLIMITED_FRAMERATE)]) +class ToggleUnlimitedFramerate : Command { + @Parameter + private lateinit var sciView: SciView + + override fun run() { + sciView.pushMode = !sciView.pushMode + } +} \ No newline at end of file From a26a6c69e80cd3dbaca31f5207e3657bf87f52ce Mon Sep 17 00:00:00 2001 From: Kyle IS Harrington Date: Mon, 5 Oct 2020 20:55:26 +0200 Subject: [PATCH 05/23] Rename .java to .kt --- .../sc/iview/commands/view/ToggleInspector.kt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/main/{java/sc/iview/commands/view/ToggleInspector.java => kotlin/sc/iview/commands/view/ToggleInspector.kt} (100%) diff --git a/src/main/java/sc/iview/commands/view/ToggleInspector.java b/src/main/kotlin/sc/iview/commands/view/ToggleInspector.kt similarity index 100% rename from src/main/java/sc/iview/commands/view/ToggleInspector.java rename to src/main/kotlin/sc/iview/commands/view/ToggleInspector.kt From 5ec505522c2f06dbf1e9d830ab37ada0235d361a Mon Sep 17 00:00:00 2001 From: Kyle IS Harrington Date: Mon, 5 Oct 2020 20:55:26 +0200 Subject: [PATCH 06/23] Convert ToggleInspector to Kotlin --- .../sc/iview/commands/view/ToggleInspector.kt | 35 ++++++++----------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/src/main/kotlin/sc/iview/commands/view/ToggleInspector.kt b/src/main/kotlin/sc/iview/commands/view/ToggleInspector.kt index c277ef3e..6e80b439 100644 --- a/src/main/kotlin/sc/iview/commands/view/ToggleInspector.kt +++ b/src/main/kotlin/sc/iview/commands/view/ToggleInspector.kt @@ -26,32 +26,27 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package sc.iview.commands.view; +package sc.iview.commands.view -import org.scijava.command.Command; -import org.scijava.plugin.Menu; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.Plugin; - -import sc.iview.SciView; - -import static sc.iview.commands.MenuWeights.*; +import org.scijava.command.Command +import org.scijava.plugin.Menu +import org.scijava.plugin.Parameter +import org.scijava.plugin.Plugin +import sc.iview.SciView +import sc.iview.commands.MenuWeights.VIEW +import sc.iview.commands.MenuWeights.VIEW_TOGGLE_INSPECTOR /** - * Command that displays a {@link NodePropertyEditor} window. + * Command that displays a [NodePropertyEditor] window. * * @author Curtis Rueden */ -@Plugin(type = Command.class, initializer = "initValues", menuRoot = "SciView", // - menu = { @Menu(label = "View", weight = VIEW), // - @Menu(label = "Toggle Inspector", weight = VIEW_TOGGLE_INSPECTOR) }) -public class ToggleInspector implements Command { - +@Plugin(type = Command::class, initializer = "initValues", menuRoot = "SciView", menu = [Menu(label = "View", weight = VIEW), Menu(label = "Toggle Inspector", weight = VIEW_TOGGLE_INSPECTOR)]) +class ToggleInspector : Command { @Parameter - private SciView sciView; + private lateinit var sciView: SciView - @Override - public void run() { - sciView.toggleInspectorWindow(); + override fun run() { + sciView.toggleInspectorWindow() } -} +} \ No newline at end of file From d0eb507e9386b0a4ea8539eb19c98f6d857feb9a Mon Sep 17 00:00:00 2001 From: Kyle IS Harrington Date: Tue, 6 Oct 2020 14:31:42 +0200 Subject: [PATCH 07/23] Rename .java to .kt --- .../sc/iview/commands/view/ToggleBoundingGrid.kt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/main/{java/sc/iview/commands/view/ToggleBoundingGrid.java => kotlin/sc/iview/commands/view/ToggleBoundingGrid.kt} (100%) diff --git a/src/main/java/sc/iview/commands/view/ToggleBoundingGrid.java b/src/main/kotlin/sc/iview/commands/view/ToggleBoundingGrid.kt similarity index 100% rename from src/main/java/sc/iview/commands/view/ToggleBoundingGrid.java rename to src/main/kotlin/sc/iview/commands/view/ToggleBoundingGrid.kt From 1c67e832c6259126772f24ba8a77f30e709b21b6 Mon Sep 17 00:00:00 2001 From: Kyle IS Harrington Date: Tue, 6 Oct 2020 14:31:42 +0200 Subject: [PATCH 08/23] Convert ToggleBoundingGrid to Kotlin --- .../iview/commands/view/ToggleBoundingGrid.kt | 65 ++++++++----------- 1 file changed, 28 insertions(+), 37 deletions(-) diff --git a/src/main/kotlin/sc/iview/commands/view/ToggleBoundingGrid.kt b/src/main/kotlin/sc/iview/commands/view/ToggleBoundingGrid.kt index eb5a9ee7..12553719 100644 --- a/src/main/kotlin/sc/iview/commands/view/ToggleBoundingGrid.kt +++ b/src/main/kotlin/sc/iview/commands/view/ToggleBoundingGrid.kt @@ -26,57 +26,48 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package sc.iview.commands.view; +package sc.iview.commands.view -import graphics.scenery.BoundingGrid; -import graphics.scenery.Mesh; -import graphics.scenery.Node; -import org.scijava.command.Command; -import org.scijava.log.LogService; -import org.scijava.plugin.Menu; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.Plugin; -import sc.iview.SciView; - -import static sc.iview.commands.MenuWeights.*; +import graphics.scenery.BoundingGrid +import graphics.scenery.Mesh +import graphics.scenery.Node +import org.scijava.command.Command +import org.scijava.log.LogService +import org.scijava.plugin.Menu +import org.scijava.plugin.Parameter +import org.scijava.plugin.Plugin +import sc.iview.SciView +import sc.iview.commands.MenuWeights.VIEW +import sc.iview.commands.MenuWeights.VIEW_TOGGLE_BOUNDING_GRID /** * Command to toggle the bounding grid around a Node * * @author Kyle Harrington - * */ -@Plugin(type = Command.class, menuRoot = "SciView", // -menu = {@Menu(label = "View", weight = VIEW), // - @Menu(label = "Toggle Bounding Grid", weight = VIEW_TOGGLE_BOUNDING_GRID)}) -public class ToggleBoundingGrid implements Command { - +@Plugin(type = Command::class, menuRoot = "SciView", menu = [Menu(label = "View", weight = VIEW), Menu(label = "Toggle Bounding Grid", weight = VIEW_TOGGLE_BOUNDING_GRID)]) +class ToggleBoundingGrid : Command { @Parameter - private LogService logService; + private lateinit var logService: LogService @Parameter - private SciView sciView; + private lateinit var sciView: SciView @Parameter - private Node node; - - @Override - public void run() { - if( node instanceof Mesh ) { + private lateinit var node: Node - if( node.getMetadata().containsKey("BoundingGrid") ) { - BoundingGrid bg = (BoundingGrid) node.getMetadata().get("BoundingGrid"); - bg.setNode( null ); - node.getMetadata().remove("BoundingGrid"); - bg.getScene().removeChild(bg); + override fun run() { + if (node is Mesh) { + if (node.metadata.containsKey("BoundingGrid")) { + val bg = node.metadata["BoundingGrid"] as BoundingGrid? + bg!!.node = null + node.metadata.remove("BoundingGrid") + bg.getScene()!!.removeChild(bg) } else { - BoundingGrid bg = new BoundingGrid(); - bg.setNode(node); - - node.getMetadata().put("BoundingGrid", bg); + val bg = BoundingGrid() + bg.node = node + node.metadata["BoundingGrid"] = bg } } - } - -} +} \ No newline at end of file From dd27ad39e07918562304ddd1a546c4e688a384da Mon Sep 17 00:00:00 2001 From: Kyle IS Harrington Date: Tue, 6 Oct 2020 14:33:50 +0200 Subject: [PATCH 09/23] Rename .java to .kt --- .../sc/iview/commands/view/StopRecordingVideo.kt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/main/{java/sc/iview/commands/view/StopRecordingVideo.java => kotlin/sc/iview/commands/view/StopRecordingVideo.kt} (100%) diff --git a/src/main/java/sc/iview/commands/view/StopRecordingVideo.java b/src/main/kotlin/sc/iview/commands/view/StopRecordingVideo.kt similarity index 100% rename from src/main/java/sc/iview/commands/view/StopRecordingVideo.java rename to src/main/kotlin/sc/iview/commands/view/StopRecordingVideo.kt From b10187e7594acafd32c85cba9aee1bf3673e19e7 Mon Sep 17 00:00:00 2001 From: Kyle IS Harrington Date: Tue, 6 Oct 2020 14:33:50 +0200 Subject: [PATCH 10/23] Convert StopRecordingVideo to Kotlin --- .../iview/commands/view/StopRecordingVideo.kt | 34 ++++++++----------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/src/main/kotlin/sc/iview/commands/view/StopRecordingVideo.kt b/src/main/kotlin/sc/iview/commands/view/StopRecordingVideo.kt index db9b2f88..b28ec6fa 100644 --- a/src/main/kotlin/sc/iview/commands/view/StopRecordingVideo.kt +++ b/src/main/kotlin/sc/iview/commands/view/StopRecordingVideo.kt @@ -26,33 +26,27 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package sc.iview.commands.view; +package sc.iview.commands.view -import org.scijava.command.Command; -import org.scijava.plugin.Menu; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.Plugin; -import sc.iview.SciView; - -import static sc.iview.commands.MenuWeights.VIEW; -import static sc.iview.commands.MenuWeights.VIEW_STOP_RECORDING_VIDEO; +import org.scijava.command.Command +import org.scijava.plugin.Menu +import org.scijava.plugin.Parameter +import org.scijava.plugin.Plugin +import sc.iview.SciView +import sc.iview.commands.MenuWeights.VIEW +import sc.iview.commands.MenuWeights.VIEW_STOP_RECORDING_VIDEO /** * Command to stop recording the current video * * @author Kyle Harrington - * */ -@Plugin(type = Command.class, menuRoot = "SciView", // - menu = { @Menu(label = "View", weight = VIEW), // - @Menu(label = "Stop recording video", weight = VIEW_STOP_RECORDING_VIDEO) }) -public class StopRecordingVideo implements Command { - +@Plugin(type = Command::class, menuRoot = "SciView", menu = [Menu(label = "View", weight = VIEW), Menu(label = "Stop recording video", weight = VIEW_STOP_RECORDING_VIDEO)]) +class StopRecordingVideo : Command { @Parameter - private SciView sciView; + private lateinit var sciView: SciView - @Override - public void run() { - sciView.toggleRecordVideo(); + override fun run() { + sciView.toggleRecordVideo() } -} +} \ No newline at end of file From 3c5824b9d7f56f71bcec4bbe3af10e6a44bab8c9 Mon Sep 17 00:00:00 2001 From: Kyle IS Harrington Date: Tue, 6 Oct 2020 15:08:52 +0200 Subject: [PATCH 11/23] Rename .java to .kt --- .../sc/iview/commands/view/CenterOnActiveNode.kt} | 0 .../sc/iview/commands/view/DisplayVertices.kt} | 0 .../sc/iview/commands/view/RenderToOpenVRHMD.kt} | 0 .../sc/iview/commands/view/ResetCameraPosition.kt} | 0 .../sc/iview/commands/view/ResetCameraRotation.kt} | 0 .../sc/iview/commands/view/RotateView.kt} | 0 .../sc/iview/commands/view/SaveCameraConfiguration.kt} | 0 .../sc/iview/commands/view/Screenshot.kt} | 0 .../sc/iview/commands/view/SetFarPlane.kt} | 0 .../view/SetLUT.java => kotlin/sc/iview/commands/view/SetLUT.kt} | 0 .../sc/iview/commands/view/SetSupersamplingFactor.kt} | 0 .../sc/iview/commands/view/SetTransferFunction.kt} | 0 .../sc/iview/commands/view/StartRecordingVideo.kt} | 0 .../sc/iview/commands/view/StopAnimation.kt} | 0 14 files changed, 0 insertions(+), 0 deletions(-) rename src/main/{java/sc/iview/commands/view/CenterOnActiveNode.java => kotlin/sc/iview/commands/view/CenterOnActiveNode.kt} (100%) rename src/main/{java/sc/iview/commands/view/DisplayVertices.java => kotlin/sc/iview/commands/view/DisplayVertices.kt} (100%) rename src/main/{java/sc/iview/commands/view/RenderToOpenVRHMD.java => kotlin/sc/iview/commands/view/RenderToOpenVRHMD.kt} (100%) rename src/main/{java/sc/iview/commands/view/ResetCameraPosition.java => kotlin/sc/iview/commands/view/ResetCameraPosition.kt} (100%) rename src/main/{java/sc/iview/commands/view/ResetCameraRotation.java => kotlin/sc/iview/commands/view/ResetCameraRotation.kt} (100%) rename src/main/{java/sc/iview/commands/view/RotateView.java => kotlin/sc/iview/commands/view/RotateView.kt} (100%) rename src/main/{java/sc/iview/commands/view/SaveCameraConfiguration.java => kotlin/sc/iview/commands/view/SaveCameraConfiguration.kt} (100%) rename src/main/{java/sc/iview/commands/view/Screenshot.java => kotlin/sc/iview/commands/view/Screenshot.kt} (100%) rename src/main/{java/sc/iview/commands/view/SetFarPlane.java => kotlin/sc/iview/commands/view/SetFarPlane.kt} (100%) rename src/main/{java/sc/iview/commands/view/SetLUT.java => kotlin/sc/iview/commands/view/SetLUT.kt} (100%) rename src/main/{java/sc/iview/commands/view/SetSupersamplingFactor.java => kotlin/sc/iview/commands/view/SetSupersamplingFactor.kt} (100%) rename src/main/{java/sc/iview/commands/view/SetTransferFunction.java => kotlin/sc/iview/commands/view/SetTransferFunction.kt} (100%) rename src/main/{java/sc/iview/commands/view/StartRecordingVideo.java => kotlin/sc/iview/commands/view/StartRecordingVideo.kt} (100%) rename src/main/{java/sc/iview/commands/view/StopAnimation.java => kotlin/sc/iview/commands/view/StopAnimation.kt} (100%) diff --git a/src/main/java/sc/iview/commands/view/CenterOnActiveNode.java b/src/main/kotlin/sc/iview/commands/view/CenterOnActiveNode.kt similarity index 100% rename from src/main/java/sc/iview/commands/view/CenterOnActiveNode.java rename to src/main/kotlin/sc/iview/commands/view/CenterOnActiveNode.kt diff --git a/src/main/java/sc/iview/commands/view/DisplayVertices.java b/src/main/kotlin/sc/iview/commands/view/DisplayVertices.kt similarity index 100% rename from src/main/java/sc/iview/commands/view/DisplayVertices.java rename to src/main/kotlin/sc/iview/commands/view/DisplayVertices.kt diff --git a/src/main/java/sc/iview/commands/view/RenderToOpenVRHMD.java b/src/main/kotlin/sc/iview/commands/view/RenderToOpenVRHMD.kt similarity index 100% rename from src/main/java/sc/iview/commands/view/RenderToOpenVRHMD.java rename to src/main/kotlin/sc/iview/commands/view/RenderToOpenVRHMD.kt diff --git a/src/main/java/sc/iview/commands/view/ResetCameraPosition.java b/src/main/kotlin/sc/iview/commands/view/ResetCameraPosition.kt similarity index 100% rename from src/main/java/sc/iview/commands/view/ResetCameraPosition.java rename to src/main/kotlin/sc/iview/commands/view/ResetCameraPosition.kt diff --git a/src/main/java/sc/iview/commands/view/ResetCameraRotation.java b/src/main/kotlin/sc/iview/commands/view/ResetCameraRotation.kt similarity index 100% rename from src/main/java/sc/iview/commands/view/ResetCameraRotation.java rename to src/main/kotlin/sc/iview/commands/view/ResetCameraRotation.kt diff --git a/src/main/java/sc/iview/commands/view/RotateView.java b/src/main/kotlin/sc/iview/commands/view/RotateView.kt similarity index 100% rename from src/main/java/sc/iview/commands/view/RotateView.java rename to src/main/kotlin/sc/iview/commands/view/RotateView.kt diff --git a/src/main/java/sc/iview/commands/view/SaveCameraConfiguration.java b/src/main/kotlin/sc/iview/commands/view/SaveCameraConfiguration.kt similarity index 100% rename from src/main/java/sc/iview/commands/view/SaveCameraConfiguration.java rename to src/main/kotlin/sc/iview/commands/view/SaveCameraConfiguration.kt diff --git a/src/main/java/sc/iview/commands/view/Screenshot.java b/src/main/kotlin/sc/iview/commands/view/Screenshot.kt similarity index 100% rename from src/main/java/sc/iview/commands/view/Screenshot.java rename to src/main/kotlin/sc/iview/commands/view/Screenshot.kt diff --git a/src/main/java/sc/iview/commands/view/SetFarPlane.java b/src/main/kotlin/sc/iview/commands/view/SetFarPlane.kt similarity index 100% rename from src/main/java/sc/iview/commands/view/SetFarPlane.java rename to src/main/kotlin/sc/iview/commands/view/SetFarPlane.kt diff --git a/src/main/java/sc/iview/commands/view/SetLUT.java b/src/main/kotlin/sc/iview/commands/view/SetLUT.kt similarity index 100% rename from src/main/java/sc/iview/commands/view/SetLUT.java rename to src/main/kotlin/sc/iview/commands/view/SetLUT.kt diff --git a/src/main/java/sc/iview/commands/view/SetSupersamplingFactor.java b/src/main/kotlin/sc/iview/commands/view/SetSupersamplingFactor.kt similarity index 100% rename from src/main/java/sc/iview/commands/view/SetSupersamplingFactor.java rename to src/main/kotlin/sc/iview/commands/view/SetSupersamplingFactor.kt diff --git a/src/main/java/sc/iview/commands/view/SetTransferFunction.java b/src/main/kotlin/sc/iview/commands/view/SetTransferFunction.kt similarity index 100% rename from src/main/java/sc/iview/commands/view/SetTransferFunction.java rename to src/main/kotlin/sc/iview/commands/view/SetTransferFunction.kt diff --git a/src/main/java/sc/iview/commands/view/StartRecordingVideo.java b/src/main/kotlin/sc/iview/commands/view/StartRecordingVideo.kt similarity index 100% rename from src/main/java/sc/iview/commands/view/StartRecordingVideo.java rename to src/main/kotlin/sc/iview/commands/view/StartRecordingVideo.kt diff --git a/src/main/java/sc/iview/commands/view/StopAnimation.java b/src/main/kotlin/sc/iview/commands/view/StopAnimation.kt similarity index 100% rename from src/main/java/sc/iview/commands/view/StopAnimation.java rename to src/main/kotlin/sc/iview/commands/view/StopAnimation.kt From 3d618603ab25ad5f0abb2d3f011e585cc1e4863b Mon Sep 17 00:00:00 2001 From: Kyle IS Harrington Date: Tue, 6 Oct 2020 15:08:52 +0200 Subject: [PATCH 12/23] Convert most of sc.iview.commands.view package to Kotlin --- .../sc/iview/commands/edit/Properties.java | 8 +- .../iview/commands/view/CenterOnActiveNode.kt | 52 ++++------- .../sc/iview/commands/view/DisplayVertices.kt | 92 ++++++++---------- .../iview/commands/view/RenderToOpenVRHMD.kt | 33 +++---- .../commands/view/ResetCameraPosition.kt | 41 ++++---- .../commands/view/ResetCameraRotation.kt | 41 ++++---- .../sc/iview/commands/view/RotateView.kt | 50 +++++----- .../commands/view/SaveCameraConfiguration.kt | 93 ++++++++----------- .../sc/iview/commands/view/Screenshot.kt | 72 +++++--------- .../sc/iview/commands/view/SetFarPlane.kt | 43 ++++----- .../kotlin/sc/iview/commands/view/SetLUT.kt | 84 ++++++++--------- .../commands/view/SetSupersamplingFactor.kt | 43 ++++----- .../commands/view/SetTransferFunction.kt | 77 ++++++--------- .../commands/view/StartRecordingVideo.kt | 46 +++++---- .../sc/iview/commands/view/StopAnimation.kt | 35 +++---- 15 files changed, 327 insertions(+), 483 deletions(-) diff --git a/src/main/java/sc/iview/commands/edit/Properties.java b/src/main/java/sc/iview/commands/edit/Properties.java index 0bd1a18a..99819a96 100644 --- a/src/main/java/sc/iview/commands/edit/Properties.java +++ b/src/main/java/sc/iview/commands/edit/Properties.java @@ -316,11 +316,11 @@ public void playTimeSeries() { while(playing) { try { int nextTimepoint = v.getCurrentTimepoint() + 1; - if(nextTimepoint >= v.getMaxTimepoint()) { + if(nextTimepoint >= v.getTimepointCount()) { nextTimepoint = 0; } - v.goToTimePoint(nextTimepoint); + v.goToTimepoint(nextTimepoint); Thread.sleep(1000L/playSpeed); } catch (InterruptedException e) { @@ -399,7 +399,7 @@ public void updateCommandFields() { getInfo().getMutableInput("timepoint", Integer.class).setMinimumValue(0); getInfo().getMutableInput("timepoint", Integer.class).setMaximumValue( rai.numDimensions() > 3 ? - ((graphics.scenery.volumes.Volume) currentSceneNode).getMaxTimepoint() : + ((graphics.scenery.volumes.Volume) currentSceneNode).getTimepointCount() : 0 ); min = (int)((Volume)currentSceneNode).getConverterSetups().get(0).getDisplayRangeMin(); @@ -526,7 +526,7 @@ protected void updateNodeProperties() { System.err.println("Could not load LUT " + colormapName); } - ((graphics.scenery.volumes.Volume) currentSceneNode).goToTimePoint(timepoint); + ((graphics.scenery.volumes.Volume) currentSceneNode).goToTimepoint(timepoint); ((Volume) currentSceneNode).getConverterSetups().get(0).setDisplayRange(min, max); } diff --git a/src/main/kotlin/sc/iview/commands/view/CenterOnActiveNode.kt b/src/main/kotlin/sc/iview/commands/view/CenterOnActiveNode.kt index 5924164e..bc4fc3f9 100644 --- a/src/main/kotlin/sc/iview/commands/view/CenterOnActiveNode.kt +++ b/src/main/kotlin/sc/iview/commands/view/CenterOnActiveNode.kt @@ -26,46 +26,32 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package sc.iview.commands.view; - -import graphics.scenery.Mesh; -import graphics.scenery.Node; -import org.scijava.command.Command; -import org.scijava.log.LogService; -import org.scijava.plugin.Menu; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.Plugin; -import sc.iview.SciView; - -import static sc.iview.commands.MenuWeights.VIEW; -import static sc.iview.commands.MenuWeights.VIEW_CENTER_ON_ACTIVE_NODE; +package sc.iview.commands.view + +import graphics.scenery.Mesh +import org.scijava.command.Command +import org.scijava.log.LogService +import org.scijava.plugin.Menu +import org.scijava.plugin.Parameter +import org.scijava.plugin.Plugin +import sc.iview.SciView +import sc.iview.commands.MenuWeights.VIEW +import sc.iview.commands.MenuWeights.VIEW_CENTER_ON_ACTIVE_NODE /** * Command to center the camera on the currently active Node * * @author Kyle Harrington - * */ -@Plugin(type = Command.class, menuRoot = "SciView", // -menu = {@Menu(label = "View", weight = VIEW), // - @Menu(label = "Center On Active Node", weight = VIEW_CENTER_ON_ACTIVE_NODE)}) -public class CenterOnActiveNode implements Command { - - @Parameter - private LogService logService; - +@Plugin(type = Command::class, menuRoot = "SciView", menu = [Menu(label = "View", weight = VIEW), Menu(label = "Center On Active Node", weight = VIEW_CENTER_ON_ACTIVE_NODE)]) +class CenterOnActiveNode : Command { @Parameter - private SciView sciView; - - @Override - public void run() { - if( sciView.getActiveNode() instanceof Mesh ) { - Node currentNode = sciView.getActiveNode(); - - sciView.centerOnNode( currentNode ); + private lateinit var sciView: SciView + override fun run() { + if (sciView.activeNode is Mesh) { + val currentNode = sciView.activeNode + sciView.centerOnNode(currentNode) } - } - -} +} \ No newline at end of file diff --git a/src/main/kotlin/sc/iview/commands/view/DisplayVertices.kt b/src/main/kotlin/sc/iview/commands/view/DisplayVertices.kt index 9102ff6a..df2206a9 100644 --- a/src/main/kotlin/sc/iview/commands/view/DisplayVertices.kt +++ b/src/main/kotlin/sc/iview/commands/view/DisplayVertices.kt @@ -26,72 +26,62 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package sc.iview.commands.view; +package sc.iview.commands.view -import graphics.scenery.Mesh; -import net.imagej.mesh.Vertex; -import org.scijava.ItemIO; -import org.scijava.command.Command; -import org.scijava.log.LogService; -import org.scijava.plugin.Menu; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.Plugin; -import org.scijava.table.*; -import sc.iview.SciView; -import sc.iview.process.MeshConverter; - -import static sc.iview.commands.MenuWeights.VIEW; -import static sc.iview.commands.MenuWeights.VIEW_SET_TRANSFER_FUNCTION; +import graphics.scenery.Mesh +import org.scijava.ItemIO +import org.scijava.command.Command +import org.scijava.log.LogService +import org.scijava.plugin.Menu +import org.scijava.plugin.Parameter +import org.scijava.plugin.Plugin +import org.scijava.table.DefaultGenericTable +import org.scijava.table.DoubleColumn +import org.scijava.table.GenericColumn +import org.scijava.table.Table +import sc.iview.SciView +import sc.iview.commands.MenuWeights.VIEW +import sc.iview.commands.MenuWeights.VIEW_SET_TRANSFER_FUNCTION +import sc.iview.process.MeshConverter /** * Command to display the vertices of the currently active Node as a table. * * @author Kyle Harrington - * */ -@Plugin(type = Command.class, menuRoot = "SciView", // - menu = {@Menu(label = "View", weight = VIEW), // - @Menu(label = "Display Vertices", weight = VIEW_SET_TRANSFER_FUNCTION)}) -public class DisplayVertices implements Command { - - @Parameter - private LogService logService; - +@Plugin(type = Command::class, menuRoot = "SciView", menu = [Menu(label = "View", weight = VIEW), Menu(label = "Display Vertices", weight = VIEW_SET_TRANSFER_FUNCTION)]) +class DisplayVertices : Command { @Parameter - private SciView sciView; + private lateinit var sciView: SciView // TODO: this should be the way to do this instead of using sciView.activeNode() -// @Parameter -// private Mesh mesh; + // @Parameter + // private Mesh mesh; @Parameter(type = ItemIO.OUTPUT) - private Table table; - - @Override - public void run() { - if( sciView.getActiveNode() instanceof Mesh ) { - Mesh scMesh = (Mesh) sciView.getActiveNode(); - net.imagej.mesh.Mesh mesh = MeshConverter.toImageJ(scMesh); + private lateinit var table: Table<*, *> - table = new DefaultGenericTable(); + override fun run() { + if (sciView.activeNode is Mesh) { + val scMesh = sciView.activeNode as Mesh + val mesh = MeshConverter.toImageJ(scMesh) + table = DefaultGenericTable() // we create two columns - GenericColumn idColumn = new GenericColumn("ID"); - DoubleColumn xColumn = new DoubleColumn("X"); - DoubleColumn yColumn = new DoubleColumn("Y"); - DoubleColumn zColumn = new DoubleColumn("Z"); - - for (Vertex v : mesh.vertices()) { - idColumn.add(v.index()); - xColumn.add(v.x()); - yColumn.add(v.y()); - zColumn.add(v.z()); + val idColumn = GenericColumn("ID") + val xColumn = DoubleColumn("X") + val yColumn = DoubleColumn("Y") + val zColumn = DoubleColumn("Z") + for (v in mesh.vertices()) { + idColumn.add(v.index()) + xColumn.add(v.x()) + yColumn.add(v.y()) + zColumn.add(v.z()) } - - table.add(idColumn); - table.add(xColumn); - table.add(yColumn); - table.add(zColumn); + (table as DefaultGenericTable).add(idColumn) + (table as DefaultGenericTable).add(xColumn) + (table as DefaultGenericTable).add(yColumn) + (table as DefaultGenericTable).add(zColumn) } } -} +} \ No newline at end of file diff --git a/src/main/kotlin/sc/iview/commands/view/RenderToOpenVRHMD.kt b/src/main/kotlin/sc/iview/commands/view/RenderToOpenVRHMD.kt index fe251778..58270614 100644 --- a/src/main/kotlin/sc/iview/commands/view/RenderToOpenVRHMD.kt +++ b/src/main/kotlin/sc/iview/commands/view/RenderToOpenVRHMD.kt @@ -26,32 +26,27 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package sc.iview.commands.view; +package sc.iview.commands.view -import org.scijava.command.Command; -import org.scijava.plugin.Menu; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.Plugin; - -import sc.iview.SciView; - -import static sc.iview.commands.MenuWeights.*; +import org.scijava.command.Command +import org.scijava.plugin.Menu +import org.scijava.plugin.Parameter +import org.scijava.plugin.Plugin +import sc.iview.SciView +import sc.iview.commands.MenuWeights.VIEW +import sc.iview.commands.MenuWeights.VIEW_RENDER_TO_OPENVR /** * Activates rendering to an OpenVR headset * * @author Ulrik Guenther */ -@Plugin(type = Command.class, initializer = "initValues", menuRoot = "SciView", selectable = true, - menu = { @Menu(label = "View", weight = VIEW), - @Menu(label = "Render to OpenVR Headset", weight = VIEW_RENDER_TO_OPENVR) }) -public class RenderToOpenVRHMD implements Command { - +@Plugin(type = Command::class, initializer = "initValues", menuRoot = "SciView", selectable = true, menu = [Menu(label = "View", weight = VIEW), Menu(label = "Render to OpenVR Headset", weight = VIEW_RENDER_TO_OPENVR)]) +class RenderToOpenVRHMD : Command { @Parameter - private SciView sciView; + private lateinit var sciView: SciView - @Override - public void run() { - sciView.toggleVRRendering(); + override fun run() { + sciView.toggleVRRendering() } -} +} \ No newline at end of file diff --git a/src/main/kotlin/sc/iview/commands/view/ResetCameraPosition.kt b/src/main/kotlin/sc/iview/commands/view/ResetCameraPosition.kt index f710cbb1..a77fb375 100644 --- a/src/main/kotlin/sc/iview/commands/view/ResetCameraPosition.kt +++ b/src/main/kotlin/sc/iview/commands/view/ResetCameraPosition.kt @@ -26,39 +26,32 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package sc.iview.commands.view; +package sc.iview.commands.view -import org.joml.Vector3f; -import org.scijava.command.Command; -import org.scijava.log.LogService; -import org.scijava.plugin.Menu; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.Plugin; -import sc.iview.SciView; - -import static sc.iview.commands.MenuWeights.VIEW; -import static sc.iview.commands.MenuWeights.VIEW_RESET_CAMERA_POSITION; +import org.joml.Vector3f +import org.scijava.command.Command +import org.scijava.log.LogService +import org.scijava.plugin.Menu +import org.scijava.plugin.Parameter +import org.scijava.plugin.Plugin +import sc.iview.SciView +import sc.iview.commands.MenuWeights.VIEW +import sc.iview.commands.MenuWeights.VIEW_RESET_CAMERA_POSITION /** * Command to set the camera position to the default position * * @author Kyle Harrington - * */ -@Plugin(type = Command.class, menuRoot = "SciView", // -menu = {@Menu(label = "View", weight = VIEW), // - @Menu(label = "Reset Camera Position", weight = VIEW_RESET_CAMERA_POSITION)}) -public class ResetCameraPosition implements Command { - +@Plugin(type = Command::class, menuRoot = "SciView", menu = [Menu(label = "View", weight = VIEW), Menu(label = "Reset Camera Position", weight = VIEW_RESET_CAMERA_POSITION)]) +class ResetCameraPosition : Command { @Parameter - private LogService logService; + private lateinit var logService: LogService @Parameter - private SciView sciView; + private lateinit var sciView: SciView - @Override - public void run() { - sciView.getCamera().setPosition( new Vector3f(0,5,5) ); + override fun run() { + sciView.camera.position = Vector3f(0.0f, 1.65f, 5f) } - -} +} \ No newline at end of file diff --git a/src/main/kotlin/sc/iview/commands/view/ResetCameraRotation.kt b/src/main/kotlin/sc/iview/commands/view/ResetCameraRotation.kt index 88782bfb..934e065f 100644 --- a/src/main/kotlin/sc/iview/commands/view/ResetCameraRotation.kt +++ b/src/main/kotlin/sc/iview/commands/view/ResetCameraRotation.kt @@ -26,39 +26,32 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package sc.iview.commands.view; +package sc.iview.commands.view -import org.joml.Quaternionf; -import org.scijava.command.Command; -import org.scijava.log.LogService; -import org.scijava.plugin.Menu; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.Plugin; -import sc.iview.SciView; - -import static sc.iview.commands.MenuWeights.VIEW; -import static sc.iview.commands.MenuWeights.VIEW_RESET_CAMERA_ROTATION; +import org.joml.Quaternionf +import org.scijava.command.Command +import org.scijava.log.LogService +import org.scijava.plugin.Menu +import org.scijava.plugin.Parameter +import org.scijava.plugin.Plugin +import sc.iview.SciView +import sc.iview.commands.MenuWeights.VIEW +import sc.iview.commands.MenuWeights.VIEW_RESET_CAMERA_ROTATION /** * Command to set the camera rotation to the default orientation. * * @author Kyle Harrington - * */ -@Plugin(type = Command.class, menuRoot = "SciView", // -menu = {@Menu(label = "View", weight = VIEW), // - @Menu(label = "Reset Camera Rotation", weight = VIEW_RESET_CAMERA_ROTATION)}) -public class ResetCameraRotation implements Command { - +@Plugin(type = Command::class, menuRoot = "SciView", menu = [Menu(label = "View", weight = VIEW), Menu(label = "Reset Camera Rotation", weight = VIEW_RESET_CAMERA_ROTATION)]) +class ResetCameraRotation : Command { @Parameter - private LogService logService; + private lateinit var logService: LogService @Parameter - private SciView sciView; + private lateinit var sciView: SciView - @Override - public void run() { - sciView.getCamera().setRotation( new Quaternionf(0, 0, 0, 1) ); + override fun run() { + sciView.camera.rotation = Quaternionf(0f, 0f, 0f, 1f) } - -} +} \ No newline at end of file diff --git a/src/main/kotlin/sc/iview/commands/view/RotateView.kt b/src/main/kotlin/sc/iview/commands/view/RotateView.kt index 922c071b..9335b24d 100644 --- a/src/main/kotlin/sc/iview/commands/view/RotateView.kt +++ b/src/main/kotlin/sc/iview/commands/view/RotateView.kt @@ -26,45 +26,37 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package sc.iview.commands.view; +package sc.iview.commands.view -import static sc.iview.commands.MenuWeights.VIEW; -import static sc.iview.commands.MenuWeights.VIEW_ROTATE; - -import org.scijava.command.Command; -import org.scijava.plugin.Menu; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.Plugin; - -import sc.iview.SciView; +import org.scijava.command.Command +import org.scijava.plugin.Menu +import org.scijava.plugin.Parameter +import org.scijava.plugin.Plugin +import sc.iview.SciView +import sc.iview.commands.MenuWeights.VIEW +import sc.iview.commands.MenuWeights.VIEW_ROTATE /** * Command to circle the camera around the currently active Node * * @author Kyle Harrington - * */ -@Plugin(type = Command.class, menuRoot = "SciView", // - menu = { @Menu(label = "View", weight = VIEW), // - @Menu(label = "Circle camera around current object", weight = VIEW_ROTATE) }) -public class RotateView implements Command { - +@Plugin(type = Command::class, menuRoot = "SciView", menu = [Menu(label = "View", weight = VIEW), Menu(label = "Circle camera around current object", weight = VIEW_ROTATE)]) +class RotateView : Command { @Parameter - private SciView sciView; + private lateinit var sciView: SciView @Parameter - private int xSpeed = 3; + private var xSpeed = 3 @Parameter - private int ySpeed = 0; - - @Override - public void run() { - sciView.animate( 30, () -> { - sciView.getTargetArcball().init( 1, 1 ); - sciView.getTargetArcball().drag( 1+xSpeed, 1+ySpeed ); - sciView.getTargetArcball().end( 1+xSpeed, 1+ySpeed ); - } ); + private var ySpeed = 0 + + override fun run() { + sciView.animate(30) { + sciView.targetArcball.init(1, 1) + sciView.targetArcball.drag(1 + xSpeed, 1 + ySpeed) + sciView.targetArcball.end(1 + xSpeed, 1 + ySpeed) + } } - -} +} \ No newline at end of file diff --git a/src/main/kotlin/sc/iview/commands/view/SaveCameraConfiguration.kt b/src/main/kotlin/sc/iview/commands/view/SaveCameraConfiguration.kt index b5115335..3421f8bb 100644 --- a/src/main/kotlin/sc/iview/commands/view/SaveCameraConfiguration.kt +++ b/src/main/kotlin/sc/iview/commands/view/SaveCameraConfiguration.kt @@ -26,73 +26,54 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package sc.iview.commands.view; +package sc.iview.commands.view -import com.google.common.io.Files; -import org.joml.Quaternionf; -import org.joml.Vector3f; -import org.scijava.command.Command; -import org.scijava.log.LogService; -import org.scijava.plugin.Menu; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.Plugin; -import org.scijava.script.ScriptService; -import sc.iview.SciView; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; - -import static sc.iview.commands.MenuWeights.VIEW; -import static sc.iview.commands.MenuWeights.VIEW_SAVE_CAMERA_CONFIGURATION; +import com.google.common.io.Files +import org.scijava.command.Command +import org.scijava.log.LogService +import org.scijava.plugin.Menu +import org.scijava.plugin.Parameter +import org.scijava.plugin.Plugin +import org.scijava.script.ScriptService +import sc.iview.SciView +import sc.iview.commands.MenuWeights.VIEW +import sc.iview.commands.MenuWeights.VIEW_SAVE_CAMERA_CONFIGURATION +import java.io.BufferedWriter +import java.io.File +import java.io.FileWriter +import java.io.IOException /** * Save the current camera configuration to file. * * @author Kyle Harrington - * */ -@Plugin(type = Command.class, menuRoot = "SciView", // -menu = {@Menu(label = "View", weight = VIEW), // - @Menu(label = "Save Camera Configuration", weight = VIEW_SAVE_CAMERA_CONFIGURATION)}) -public class SaveCameraConfiguration implements Command { - - @Parameter - private LogService logService; - - @Parameter - private SciView sciView; - +@Suppress("UnstableApiUsage") +@Plugin(type = Command::class, menuRoot = "SciView", menu = [Menu(label = "View", weight = VIEW), Menu(label = "Save Camera Configuration", weight = VIEW_SAVE_CAMERA_CONFIGURATION)]) +class SaveCameraConfiguration : Command { @Parameter - private File saveFile; + private lateinit var sciView: SciView @Parameter - private ScriptService scriptService; + private lateinit var saveFile: File - @Override - public void run() { + override fun run() { try { - FileWriter fw = new FileWriter(saveFile); - BufferedWriter bw = new BufferedWriter(fw); - - if( !Files.getFileExtension(saveFile.getAbsolutePath()).equalsIgnoreCase("clj") ) - throw new IOException("File must be Clojure (extension = .clj)"); - - Vector3f pos = sciView.getCamera().getPosition(); - Quaternionf rot = sciView.getCamera().getRotation(); - - String scriptContents = "; @SciView sciView\n\n"; - scriptContents += "(.setPosition (.getCamera sciView) (cleargl.GLVector. (float-array [" + pos.x() + " " + pos.y() + " " + pos.z() + "])))\n"; - scriptContents += "(.setRotation (.getCamera sciView) (com.jogamp.opengl.math.Quaternion. " + rot.x() + " " + rot.y() + " " + rot.z() + " " + rot.w() + "))\n"; - - bw.write(scriptContents); - - bw.close(); - fw.close(); - } catch (IOException e) { - e.printStackTrace(); + val fw = FileWriter(saveFile) + val bw = BufferedWriter(fw) + if (!Files.getFileExtension(saveFile.absolutePath).equals("clj", ignoreCase = true)) throw IOException("File must be Clojure (extension = .clj)") + val pos = sciView.camera.position + val rot = sciView.camera.rotation + var scriptContents = "; @SciView sciView\n\n" + scriptContents += """(.setPosition (.getCamera sciView) (cleargl.GLVector. (float-array [${pos.x()} ${pos.y()} ${pos.z()}]))) +""" + scriptContents += """(.setRotation (.getCamera sciView) (com.jogamp.opengl.math.Quaternion. ${rot.x()} ${rot.y()} ${rot.z()} ${rot.w()})) +""" + bw.write(scriptContents) + bw.close() + fw.close() + } catch (e: IOException) { + e.printStackTrace() } } - -} +} \ No newline at end of file diff --git a/src/main/kotlin/sc/iview/commands/view/Screenshot.kt b/src/main/kotlin/sc/iview/commands/view/Screenshot.kt index ac7ad65a..10ff364e 100644 --- a/src/main/kotlin/sc/iview/commands/view/Screenshot.kt +++ b/src/main/kotlin/sc/iview/commands/view/Screenshot.kt @@ -26,66 +26,40 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package sc.iview.commands.view; +package sc.iview.commands.view -import graphics.scenery.backends.RenderedImage; -import net.imagej.Dataset; -import net.imagej.ImgPlus; -import net.imagej.ops.OpService; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.img.Img; -import net.imglib2.img.display.imagej.ImageJFunctions; -import net.imglib2.type.numeric.ARGBType; -import org.scijava.ItemIO; -import org.scijava.command.Command; -import org.scijava.io.IOService; -import org.scijava.plugin.Menu; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.Plugin; -import org.scijava.ui.UIService; -import sc.iview.SciView; - -import javax.imageio.ImageIO; -import java.awt.image.BufferedImage; -import java.awt.image.DataBufferByte; -import java.io.File; -import java.io.IOException; - -import static sc.iview.commands.MenuWeights.VIEW; -import static sc.iview.commands.MenuWeights.VIEW_SCREENSHOT; +import net.imagej.ImgPlus +import net.imagej.ops.OpService +import org.scijava.ItemIO +import org.scijava.command.Command +import org.scijava.io.IOService +import org.scijava.plugin.Menu +import org.scijava.plugin.Parameter +import org.scijava.plugin.Plugin +import org.scijava.ui.UIService +import sc.iview.SciView +import sc.iview.commands.MenuWeights.VIEW +import sc.iview.commands.MenuWeights.VIEW_SCREENSHOT /** * Command to take a screenshot. The screenshot is opened in ImageJ. * * @author Kyle Harrington - * */ -@Plugin(type = Command.class, menuRoot = "SciView", // - menu = { @Menu(label = "View", weight = VIEW), // - @Menu(label = "Screenshot", weight = VIEW_SCREENSHOT) }) -public class Screenshot implements Command { - - @Parameter - private SciView sciView; - - @Parameter - private OpService opService; - +@Plugin(type = Command::class, menuRoot = "SciView", menu = [Menu(label = "View", weight = VIEW), Menu(label = "Screenshot", weight = VIEW_SCREENSHOT)]) +class Screenshot : Command { @Parameter - private IOService ioService; + private lateinit var sciView: SciView @Parameter - private UIService uiService; + private lateinit var uiService: UIService @Parameter(type = ItemIO.OUTPUT) - private ImgPlus img; - - @Override - public void run() { - Img screenshot = sciView.getARGBScreenshot(); - - img = new ImgPlus<>(screenshot); + private var img: ImgPlus<*>? = null - uiService.show(img); + override fun run() { + val screenshot = sciView.argbScreenshot + img = ImgPlus(screenshot) + uiService.show(img) } -} +} \ No newline at end of file diff --git a/src/main/kotlin/sc/iview/commands/view/SetFarPlane.kt b/src/main/kotlin/sc/iview/commands/view/SetFarPlane.kt index 78ecf8f2..45995e70 100644 --- a/src/main/kotlin/sc/iview/commands/view/SetFarPlane.kt +++ b/src/main/kotlin/sc/iview/commands/view/SetFarPlane.kt @@ -26,42 +26,31 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package sc.iview.commands.view; +package sc.iview.commands.view -import org.scijava.command.Command; -import org.scijava.log.LogService; -import org.scijava.plugin.Menu; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.Plugin; -import sc.iview.SciView; - -import static sc.iview.commands.MenuWeights.*; +import org.scijava.command.Command +import org.scijava.log.LogService +import org.scijava.plugin.Menu +import org.scijava.plugin.Parameter +import org.scijava.plugin.Plugin +import sc.iview.SciView +import sc.iview.commands.MenuWeights.VIEW +import sc.iview.commands.MenuWeights.VIEW_SET_FAR_PLANE /** * Command to set the far plane for the renderer. Everything beyond this **will not** be rendered * * @author Kyle Harrington - * */ -@Plugin(type = Command.class, menuRoot = "SciView", // - menu = {@Menu(label = "View", weight = VIEW), // - @Menu(label = "Set Far Plane", weight = VIEW_SET_FAR_PLANE)}) -public class SetFarPlane implements Command { - - @Parameter - private LogService logService; - +@Plugin(type = Command::class, menuRoot = "SciView", menu = [Menu(label = "View", weight = VIEW), Menu(label = "Set Far Plane", weight = VIEW_SET_FAR_PLANE)]) +class SetFarPlane : Command { @Parameter - private SciView sciView; + private lateinit var sciView: SciView @Parameter - private float farPlane = 1000f; - - @Override - public void run() { - - sciView.getCamera().setFarPlaneDistance(farPlane); + private var farPlane = 1000f + override fun run() { + sciView.camera.farPlaneDistance = farPlane } - -} +} \ No newline at end of file diff --git a/src/main/kotlin/sc/iview/commands/view/SetLUT.kt b/src/main/kotlin/sc/iview/commands/view/SetLUT.kt index 954cae95..e2f2ee5a 100644 --- a/src/main/kotlin/sc/iview/commands/view/SetLUT.kt +++ b/src/main/kotlin/sc/iview/commands/view/SetLUT.kt @@ -26,74 +26,66 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package sc.iview.commands.view; +package sc.iview.commands.view -import graphics.scenery.Node; -import net.imagej.lut.LUTService; -import net.imglib2.display.AbstractArrayColorTable; -import net.imglib2.display.ColorTable; -import org.scijava.command.Command; -import org.scijava.command.DynamicCommand; -import org.scijava.module.MutableModuleItem; -import org.scijava.plugin.Menu; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.Plugin; -import sc.iview.SciView; - -import java.io.IOException; -import java.util.ArrayList; - -import static sc.iview.commands.MenuWeights.VIEW; -import static sc.iview.commands.MenuWeights.VIEW_SET_LUT; +import graphics.scenery.Node +import net.imagej.lut.LUTService +import net.imglib2.display.AbstractArrayColorTable +import net.imglib2.display.ColorTable +import org.scijava.command.Command +import org.scijava.command.DynamicCommand +import org.scijava.plugin.Menu +import org.scijava.plugin.Parameter +import org.scijava.plugin.Plugin +import sc.iview.SciView +import sc.iview.commands.MenuWeights.VIEW +import sc.iview.commands.MenuWeights.VIEW_SET_LUT +import java.io.IOException +import java.util.* /** * Command to set the currently used Look Up Table (LUT). This is a colormap for the volume. * * @author Kyle Harrington - * */ -@Plugin(type = Command.class, menuRoot = "SciView", // - menu = { @Menu(label = "View", weight = VIEW), // - @Menu(label = "Set LUT", weight = VIEW_SET_LUT) }) -public class SetLUT extends DynamicCommand { - +@Suppress("TYPE_INFERENCE_ONLY_INPUT_TYPES_WARNING") +@Plugin(type = Command::class, menuRoot = "SciView", menu = [Menu(label = "View", weight = VIEW), Menu(label = "Set LUT", weight = VIEW_SET_LUT)]) +class SetLUT : DynamicCommand() { @Parameter - private SciView sciView; + private lateinit var sciView: SciView @Parameter - private LUTService lutService; + private lateinit var lutService: LUTService @Parameter(label = "Node") - private Node node; + private lateinit var node: Node - @Parameter(label = "Selected LUT", choices = {}, callback = "lutNameChanged") - private String lutName; + @Parameter(label = "Selected LUT", choices = [], callback = "lutNameChanged") + private lateinit var lutName: String @Parameter(label = "LUT Selection") - private ColorTable colorTable; + private lateinit var colorTable: ColorTable - protected void lutNameChanged() { - final MutableModuleItem lutNameItem = getInfo().getMutableInput("lutName", String.class); + protected fun lutNameChanged() { + val lutNameItem = info.getMutableInput("lutName", String::class.java) try { - colorTable = lutService.loadLUT( lutService.findLUTs().get( lutName ) ); - } catch (IOException e) { - e.printStackTrace(); + colorTable = lutService.loadLUT(lutService.findLUTs()[lutNameItem]) + } catch (e: IOException) { + e.printStackTrace() } } - @Override - public void initialize() { + override fun initialize() { try { - colorTable = lutService.loadLUT( lutService.findLUTs().get( "Red.lut" ) ); - } catch (IOException e) { - e.printStackTrace(); + colorTable = lutService.loadLUT(lutService.findLUTs()["Red.lut"]) + } catch (e: IOException) { + e.printStackTrace() } - final MutableModuleItem lutNameItem = getInfo().getMutableInput("lutName", String.class ); - lutNameItem.setChoices( new ArrayList( lutService.findLUTs().keySet() ) ); + val lutNameItem = info.getMutableInput("lutName", String::class.java) + lutNameItem.choices = ArrayList(lutService.findLUTs().keys) } - @Override - public void run() { - sciView.setColormap( node, (AbstractArrayColorTable) colorTable); + override fun run() { + sciView.setColormap(node, colorTable as AbstractArrayColorTable<*>?) } -} +} \ No newline at end of file diff --git a/src/main/kotlin/sc/iview/commands/view/SetSupersamplingFactor.kt b/src/main/kotlin/sc/iview/commands/view/SetSupersamplingFactor.kt index ff95132a..ff93fcad 100644 --- a/src/main/kotlin/sc/iview/commands/view/SetSupersamplingFactor.kt +++ b/src/main/kotlin/sc/iview/commands/view/SetSupersamplingFactor.kt @@ -26,42 +26,31 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package sc.iview.commands.view; +package sc.iview.commands.view -import org.scijava.command.Command; -import org.scijava.log.LogService; -import org.scijava.plugin.Menu; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.Plugin; -import sc.iview.SciView; - -import static sc.iview.commands.MenuWeights.*; +import org.scijava.command.Command +import org.scijava.log.LogService +import org.scijava.plugin.Menu +import org.scijava.plugin.Parameter +import org.scijava.plugin.Plugin +import sc.iview.SciView +import sc.iview.commands.MenuWeights.VIEW +import sc.iview.commands.MenuWeights.VIEW_SET_SUPERSAMPLING_FACTOR /** * Command to set scenery's Supersampling Factor * * @author Kyle Harrington - * */ -@Plugin(type = Command.class, menuRoot = "SciView", // - menu = {@Menu(label = "View", weight = VIEW), // - @Menu(label = "Set Supersampling Factor", weight = VIEW_SET_SUPERSAMPLING_FACTOR)}) -public class SetSupersamplingFactor implements Command { - - @Parameter - private LogService logService; - +@Plugin(type = Command::class, menuRoot = "SciView", menu = [Menu(label = "View", weight = VIEW), Menu(label = "Set Supersampling Factor", weight = VIEW_SET_SUPERSAMPLING_FACTOR)]) +class SetSupersamplingFactor : Command { @Parameter - private SciView sciView; + private lateinit var sciView: SciView @Parameter - private double supersamplingFactor = 1.0; - - @Override - public void run() { - - sciView.getSceneryRenderer().getSettings().set("Renderer.SupersamplingFactor",supersamplingFactor); + private var supersamplingFactor = 1.0 + override fun run() { + sciView.sceneryRenderer.settings.set("Renderer.SupersamplingFactor", supersamplingFactor) } - -} +} \ No newline at end of file diff --git a/src/main/kotlin/sc/iview/commands/view/SetTransferFunction.kt b/src/main/kotlin/sc/iview/commands/view/SetTransferFunction.kt index 61a9ef6d..db8409ea 100644 --- a/src/main/kotlin/sc/iview/commands/view/SetTransferFunction.kt +++ b/src/main/kotlin/sc/iview/commands/view/SetTransferFunction.kt @@ -26,74 +26,53 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package sc.iview.commands.view; +package sc.iview.commands.view -import graphics.scenery.volumes.TransferFunction; -import graphics.scenery.volumes.Volume; -import org.scijava.command.Command; -import org.scijava.command.InteractiveCommand; -import org.scijava.log.LogService; -import org.scijava.plugin.Menu; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.Plugin; -import org.scijava.widget.NumberWidget; -import sc.iview.SciView; - -import static sc.iview.commands.MenuWeights.VIEW; -import static sc.iview.commands.MenuWeights.VIEW_SET_TRANSFER_FUNCTION; +import graphics.scenery.volumes.Volume +import org.scijava.command.Command +import org.scijava.command.InteractiveCommand +import org.scijava.log.LogService +import org.scijava.plugin.Menu +import org.scijava.plugin.Parameter +import org.scijava.plugin.Plugin +import org.scijava.widget.NumberWidget +import sc.iview.SciView +import sc.iview.commands.MenuWeights.VIEW +import sc.iview.commands.MenuWeights.VIEW_SET_TRANSFER_FUNCTION /** * Command to set the transfer function of a Volume * * @author Kyle Harrington - * */ -@Plugin(type = Command.class, menuRoot = "SciView", // - menu = {@Menu(label = "View", weight = VIEW), // - @Menu(label = "Set Transfer Function", weight = VIEW_SET_TRANSFER_FUNCTION)}) -public class SetTransferFunction extends InteractiveCommand { - - @Parameter - private LogService logService; - - @Parameter - private SciView sciView; - +@Plugin(type = Command::class, menuRoot = "SciView", menu = [Menu(label = "View", weight = VIEW), Menu(label = "Set Transfer Function", weight = VIEW_SET_TRANSFER_FUNCTION)]) +class SetTransferFunction : InteractiveCommand() { @Parameter(label = "Target Volume") - private Volume volume; + private lateinit var volume: Volume - @Parameter(label = "TF Ramp Min", style = NumberWidget.SLIDER_STYLE, // - min = "0", max = "1.0", stepSize = "0.001", callback = "updateTransferFunction") - private float rampMin = 0; + @Parameter(label = "TF Ramp Min", style = NumberWidget.SLIDER_STYLE, min = "0", max = "1.0", stepSize = "0.001", callback = "updateTransferFunction") + private var rampMin = 0f - @Parameter(label = "TF Ramp Max", style = NumberWidget.SLIDER_STYLE, // - min = "0", max = "1.0", stepSize = "0.001", callback = "updateTransferFunction") - private float rampMax = 1.0f; + @Parameter(label = "TF Ramp Max", style = NumberWidget.SLIDER_STYLE, min = "0", max = "1.0", stepSize = "0.001", callback = "updateTransferFunction") + private var rampMax = 1.0f /** * Nothing happens here, as cancelling the dialog is not possible. */ - @Override - public void cancel() { - - } + override fun cancel() {} /** * Nothing is done here, as the refreshing of the objects properties works via * callback methods. */ - @Override - public void run() { - - } - - protected void updateTransferFunction() { - TransferFunction tf = volume.getTransferFunction(); + override fun run() {} + protected fun updateTransferFunction() { + val tf = volume.transferFunction //float currentOffset = tf.getControlPoint$scenery(1).getValue(); //float currentFactor = tf.getControlPoint$scenery(2).getFactor(); - tf.clear(); - tf.addControlPoint(0.0f, 0.0f); - tf.addControlPoint(rampMin, 0.0f); - tf.addControlPoint(1.0f, rampMax); + tf.clear() + tf.addControlPoint(0.0f, 0.0f) + tf.addControlPoint(rampMin, 0.0f) + tf.addControlPoint(1.0f, rampMax) } -} +} \ No newline at end of file diff --git a/src/main/kotlin/sc/iview/commands/view/StartRecordingVideo.kt b/src/main/kotlin/sc/iview/commands/view/StartRecordingVideo.kt index f76bac48..282a82e0 100644 --- a/src/main/kotlin/sc/iview/commands/view/StartRecordingVideo.kt +++ b/src/main/kotlin/sc/iview/commands/view/StartRecordingVideo.kt @@ -26,40 +26,38 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package sc.iview.commands.view; +package sc.iview.commands.view -import org.scijava.command.Command; -import org.scijava.plugin.Menu; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.Plugin; -import sc.iview.SciView; - -import static sc.iview.commands.MenuWeights.*; +import org.scijava.command.Command +import org.scijava.plugin.Menu +import org.scijava.plugin.Parameter +import org.scijava.plugin.Plugin +import sc.iview.SciView +import sc.iview.commands.MenuWeights.VIEW +import sc.iview.commands.MenuWeights.VIEW_START_RECORDING_VIDEO +import kotlin.math.max /** * Command to start recording a video. Currently this will record to ~/Desktop * * @author Kyle Harrington - * */ -@Plugin(type = Command.class, menuRoot = "SciView", // - menu = { @Menu(label = "View", weight = VIEW), // - @Menu(label = "Start recording video", weight = VIEW_START_RECORDING_VIDEO) }) -public class StartRecordingVideo implements Command { +@Plugin(type = Command::class, menuRoot = "SciView", menu = [Menu(label = "View", weight = VIEW), Menu(label = "Start recording video", weight = VIEW_START_RECORDING_VIDEO)]) +class StartRecordingVideo : Command { @Parameter - private SciView sciView; + private lateinit var sciView: SciView @Parameter - private int bitrate = 10000000;// 10 MBit + private var bitrate = 10000000 // 10 MBit - @Parameter(choices={"VeryLow", "Low", "Medium", "High", "Ultra", "Insane"}, style="listBox") - private String videoEncodingQuality;// listed as an enum here, cant access from java https://github.com/scenerygraphics/scenery/blob/1a451c2864e5a48e47622d9313fe1681e47d7958/src/main/kotlin/graphics/scenery/utils/H264Encoder.kt#L65 + @Parameter(choices = ["VeryLow", "Low", "Medium", "High", "Ultra", "Insane"], style = "listBox") + private lateinit var videoEncodingQuality // listed as an enum here, cant access from java https://github.com/scenerygraphics/scenery/blob/1a451c2864e5a48e47622d9313fe1681e47d7958/src/main/kotlin/graphics/scenery/utils/H264Encoder.kt#L65 + : String - @Override - public void run() { - bitrate = Math.max(0,bitrate); - sciView.getScenerySettings().set("VideoEncoder.Bitrate", bitrate); - sciView.getScenerySettings().set("VideoEncoder.Quality", videoEncodingQuality); - sciView.toggleRecordVideo(); + override fun run() { + bitrate = max(0, bitrate) + sciView.scenerySettings.set("VideoEncoder.Bitrate", bitrate) + sciView.scenerySettings.set("VideoEncoder.Quality", videoEncodingQuality) + sciView.toggleRecordVideo() } -} +} \ No newline at end of file diff --git a/src/main/kotlin/sc/iview/commands/view/StopAnimation.kt b/src/main/kotlin/sc/iview/commands/view/StopAnimation.kt index 38899f2e..cd0b1307 100644 --- a/src/main/kotlin/sc/iview/commands/view/StopAnimation.kt +++ b/src/main/kotlin/sc/iview/commands/view/StopAnimation.kt @@ -26,34 +26,27 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package sc.iview.commands.view; +package sc.iview.commands.view -import static sc.iview.commands.MenuWeights.VIEW; -import static sc.iview.commands.MenuWeights.VIEW_STOP_ANIMATION; - -import org.scijava.command.Command; -import org.scijava.plugin.Menu; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.Plugin; - -import sc.iview.SciView; +import org.scijava.command.Command +import org.scijava.plugin.Menu +import org.scijava.plugin.Parameter +import org.scijava.plugin.Plugin +import sc.iview.SciView +import sc.iview.commands.MenuWeights.VIEW +import sc.iview.commands.MenuWeights.VIEW_STOP_ANIMATION /** * Command to stop all current animations * * @author Kyle Harrington - * */ -@Plugin(type = Command.class, menuRoot = "SciView", // - menu = { @Menu(label = "View", weight = VIEW), // - @Menu(label = "Stop Animation", weight = VIEW_STOP_ANIMATION) }) -public class StopAnimation implements Command { - +@Plugin(type = Command::class, menuRoot = "SciView", menu = [Menu(label = "View", weight = VIEW), Menu(label = "Stop Animation", weight = VIEW_STOP_ANIMATION)]) +class StopAnimation : Command { @Parameter - private SciView sciView; + private lateinit var sciView: SciView - @Override - public void run() { - sciView.stopAnimation(); + override fun run() { + sciView.stopAnimation() } -} +} \ No newline at end of file From 84c9844a9775f7e754858b28f4831ef01d398d26 Mon Sep 17 00:00:00 2001 From: Kyle IS Harrington Date: Wed, 7 Oct 2020 20:21:49 +0200 Subject: [PATCH 13/23] Normalize compass rotation --- .../java/sc/iview/commands/edit/AddOrientationCompass.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/sc/iview/commands/edit/AddOrientationCompass.java b/src/main/java/sc/iview/commands/edit/AddOrientationCompass.java index c9da9995..2df81396 100644 --- a/src/main/java/sc/iview/commands/edit/AddOrientationCompass.java +++ b/src/main/java/sc/iview/commands/edit/AddOrientationCompass.java @@ -121,10 +121,9 @@ public void run() { root.getUpdate().add(() -> { final Camera cam = sciView.getCamera(); root.setPosition(cam.viewportToView(new Vector2f(-0.9f, 0.7f))); - root.setRotation(new Quaternionf(sciView.getCamera().getRotation()).conjugate()); + root.setRotation(new Quaternionf(sciView.getCamera().getRotation()).conjugate().normalize()); return null; }); - } public static void main(String... args) throws Exception { From 9fb593a12a8d2cb3ab1b42fecec802dfe0a2b4ce Mon Sep 17 00:00:00 2001 From: Kyle IS Harrington Date: Wed, 7 Oct 2020 23:03:32 +0200 Subject: [PATCH 14/23] Rename .java to .kt --- src/main/java/sc/iview/{SciView.java => SciView.kt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/main/java/sc/iview/{SciView.java => SciView.kt} (100%) diff --git a/src/main/java/sc/iview/SciView.java b/src/main/java/sc/iview/SciView.kt similarity index 100% rename from src/main/java/sc/iview/SciView.java rename to src/main/java/sc/iview/SciView.kt From 59049579ab53cd04b26be559fc6a4b079a4e5e40 Mon Sep 17 00:00:00 2001 From: Kyle IS Harrington Date: Wed, 7 Oct 2020 23:03:32 +0200 Subject: [PATCH 15/23] wip: stuck on generics --- src/main/java/sc/iview/SciView.kt | 2841 +++++++++++++---------------- 1 file changed, 1259 insertions(+), 1582 deletions(-) diff --git a/src/main/java/sc/iview/SciView.kt b/src/main/java/sc/iview/SciView.kt index bf4a415a..f1a79b99 100644 --- a/src/main/java/sc/iview/SciView.kt +++ b/src/main/java/sc/iview/SciView.kt @@ -26,122 +26,118 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package sc.iview; - -import bdv.BigDataViewer; -import bdv.cache.CacheControl; -import bdv.tools.brightness.ConverterSetup; -import bdv.util.AxisOrder; -import bdv.util.RandomAccessibleIntervalSource; -import bdv.util.RandomAccessibleIntervalSource4D; -import bdv.util.volatiles.VolatileView; -import bdv.util.volatiles.VolatileViewData; -import bdv.viewer.Source; -import bdv.viewer.SourceAndConverter; -import cleargl.GLVector; -import com.formdev.flatlaf.FlatLightLaf; -import com.intellij.ui.tabs.JBTabsPosition; -import com.intellij.ui.tabs.TabInfo; -import com.intellij.ui.tabs.impl.JBEditorTabs; -import graphics.scenery.Box; -import graphics.scenery.*; -import graphics.scenery.backends.RenderedImage; -import graphics.scenery.backends.Renderer; -import graphics.scenery.backends.opengl.OpenGLRenderer; -import graphics.scenery.backends.vulkan.VulkanRenderer; -import graphics.scenery.controls.InputHandler; -import graphics.scenery.controls.OpenVRHMD; -import graphics.scenery.controls.TrackerInput; -import graphics.scenery.controls.behaviours.ArcballCameraControl; -import graphics.scenery.controls.behaviours.FPSCameraControl; -import graphics.scenery.controls.behaviours.MovementCommand; -import graphics.scenery.controls.behaviours.SelectCommand; -import graphics.scenery.utils.*; -import graphics.scenery.volumes.Colormap; -import graphics.scenery.volumes.RAIVolume; -import graphics.scenery.volumes.TransferFunction; -import graphics.scenery.volumes.Volume; -import io.scif.SCIFIOService; -import kotlin.Unit; -import kotlin.jvm.functions.Function1; -import kotlin.jvm.functions.Function3; -import net.imagej.Dataset; -import net.imagej.ImageJService; -import net.imagej.axis.CalibratedAxis; -import net.imagej.axis.DefaultAxisType; -import net.imagej.axis.DefaultLinearAxis; -import net.imagej.interval.CalibratedRealInterval; -import net.imagej.lut.LUTService; -import net.imagej.ops.OpService; -import net.imagej.units.UnitService; -import net.imglib2.Cursor; -import net.imglib2.RandomAccess; -import net.imglib2.*; -import net.imglib2.display.ColorTable; -import net.imglib2.img.Img; -import net.imglib2.realtransform.AffineTransform3D; -import net.imglib2.type.numeric.ARGBType; -import net.imglib2.type.numeric.RealType; -import net.imglib2.type.numeric.integer.UnsignedByteType; -import net.imglib2.view.Views; -import org.joml.Quaternionf; -import org.joml.Vector2f; -import org.joml.Vector3f; -import org.lwjgl.system.Platform; -import org.scijava.Context; -import org.scijava.display.Display; -import org.scijava.display.DisplayService; -import org.scijava.event.EventHandler; -import org.scijava.event.EventService; -import org.scijava.io.IOService; -import org.scijava.log.LogLevel; -import org.scijava.log.LogService; -import org.scijava.menu.MenuService; -import org.scijava.object.ObjectService; -import org.scijava.plugin.Parameter; -import org.scijava.service.SciJavaService; -import org.scijava.thread.ThreadService; -import org.scijava.ui.behaviour.ClickBehaviour; -import org.scijava.ui.behaviour.InputTrigger; -import org.scijava.ui.swing.menu.SwingJMenuBarCreator; -import org.scijava.util.ColorRGB; -import org.scijava.util.Colors; -import org.scijava.util.VersionUtils; -import sc.iview.commands.view.NodePropertyEditor; -import sc.iview.controls.behaviours.CameraTranslateControl; -import sc.iview.controls.behaviours.NodeTranslateControl; -import sc.iview.event.NodeActivatedEvent; -import sc.iview.event.NodeAddedEvent; -import sc.iview.event.NodeChangedEvent; -import sc.iview.event.NodeRemovedEvent; -import sc.iview.process.MeshConverter; -import sc.iview.ui.ContextPopUp; -import sc.iview.ui.REPLPane; -import sc.iview.vector.JOMLVector3; -import sc.iview.vector.Vector3; -import tpietzsch.example2.VolumeViewerOptions; - -import javax.imageio.ImageIO; -import javax.script.ScriptException; -import javax.swing.*; -import java.awt.Image; -import java.awt.*; -import java.awt.event.*; -import java.awt.geom.AffineTransform; -import java.awt.image.BufferedImage; -import java.awt.image.DataBufferByte; -import java.io.*; -import java.net.URL; -import java.nio.ByteBuffer; -import java.nio.FloatBuffer; -import java.util.List; -import java.util.Queue; -import java.util.*; -import java.util.concurrent.Future; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.function.Supplier; -import java.util.stream.Collectors; +package sc.iview + +import bdv.BigDataViewer +import bdv.cache.CacheControl +import bdv.tools.brightness.ConverterSetup +import bdv.util.AxisOrder +import bdv.util.RandomAccessibleIntervalSource +import bdv.util.RandomAccessibleIntervalSource4D +import bdv.util.volatiles.VolatileView +import bdv.viewer.Source +import bdv.viewer.SourceAndConverter +import cleargl.GLVector +import com.formdev.flatlaf.FlatLightLaf +import com.intellij.ui.tabs.JBTabsPosition +import com.intellij.ui.tabs.TabInfo +import com.intellij.ui.tabs.impl.JBEditorTabs +import graphics.scenery.* +import graphics.scenery.Box +import graphics.scenery.Scene.RaycastResult +import graphics.scenery.backends.Renderer +import graphics.scenery.backends.opengl.OpenGLRenderer +import graphics.scenery.backends.vulkan.VulkanRenderer +import graphics.scenery.controls.InputHandler +import graphics.scenery.controls.OpenVRHMD +import graphics.scenery.controls.TrackerInput +import graphics.scenery.controls.behaviours.ArcballCameraControl +import graphics.scenery.controls.behaviours.FPSCameraControl +import graphics.scenery.controls.behaviours.MovementCommand +import graphics.scenery.controls.behaviours.SelectCommand +import graphics.scenery.utils.* +import graphics.scenery.utils.ExtractsNatives.Companion.getPlatform +import graphics.scenery.volumes.Colormap +import graphics.scenery.volumes.RAIVolume +import graphics.scenery.volumes.Volume +import graphics.scenery.volumes.Volume.Companion.fromXML +import graphics.scenery.volumes.Volume.Companion.setupId +import graphics.scenery.volumes.Volume.VolumeDataSource.RAISource +import io.scif.SCIFIOService +import net.imagej.Dataset +import net.imagej.ImageJService +import net.imagej.axis.CalibratedAxis +import net.imagej.axis.DefaultAxisType +import net.imagej.axis.DefaultLinearAxis +import net.imagej.interval.CalibratedRealInterval +import net.imagej.lut.LUTService +import net.imagej.mesh.Mesh +import net.imagej.ops.OpService +import net.imagej.units.UnitService +import net.imglib2.* +import net.imglib2.display.ColorTable +import net.imglib2.img.Img +import net.imglib2.realtransform.AffineTransform3D +import net.imglib2.type.numeric.ARGBType +import net.imglib2.type.numeric.RealType +import net.imglib2.type.numeric.integer.UnsignedByteType +import net.imglib2.view.Views +import org.joml.Quaternionf +import org.joml.Vector2f +import org.joml.Vector3f +import org.lwjgl.system.Platform +import org.scijava.Context +import org.scijava.`object`.ObjectService +import org.scijava.display.Display +import org.scijava.display.DisplayService +import org.scijava.event.EventHandler +import org.scijava.event.EventService +import org.scijava.io.IOService +import org.scijava.log.LogLevel +import org.scijava.log.LogService +import org.scijava.menu.MenuService +import org.scijava.plugin.Parameter +import org.scijava.service.SciJavaService +import org.scijava.thread.ThreadService +import org.scijava.ui.behaviour.ClickBehaviour +import org.scijava.ui.swing.menu.SwingJMenuBarCreator +import org.scijava.util.ColorRGB +import org.scijava.util.Colors +import org.scijava.util.VersionUtils +import sc.iview.SciView +import sc.iview.commands.view.NodePropertyEditor +import sc.iview.controls.behaviours.CameraTranslateControl +import sc.iview.controls.behaviours.NodeTranslateControl +import sc.iview.event.NodeActivatedEvent +import sc.iview.event.NodeAddedEvent +import sc.iview.event.NodeChangedEvent +import sc.iview.event.NodeRemovedEvent +import sc.iview.process.MeshConverter +import sc.iview.ui.ContextPopUp +import sc.iview.ui.REPLPane +import sc.iview.vector.JOMLVector3 +import sc.iview.vector.Vector3 +import tpietzsch.example2.VolumeViewerOptions +import java.awt.* +import java.awt.event.* +import java.awt.image.BufferedImage +import java.awt.image.DataBufferByte +import java.io.* +import java.net.URL +import java.nio.ByteBuffer +import java.nio.FloatBuffer +import java.util.* +import java.util.concurrent.Future +import java.util.function.Consumer +import java.util.function.Function +import java.util.function.Predicate +import java.util.function.Supplier +import java.util.stream.Collectors +import javax.imageio.ImageIO +import javax.script.ScriptException +import javax.swing.* +import kotlin.math.cos +import kotlin.math.sin /** * Main SciView class. @@ -150,116 +146,143 @@ import java.util.stream.Collectors; */ // we suppress unused warnings here because @Parameter-annotated fields // get updated automatically by SciJava. -@SuppressWarnings({"unused", "WeakerAccess"}) -public class SciView extends SceneryBase implements CalibratedRealInterval { +class SciView : SceneryBase, CalibratedRealInterval { + private val sceneryPanel = arrayOf(null) - public static final ColorRGB DEFAULT_COLOR = Colors.LIGHTGRAY; - private final SceneryPanel[] sceneryPanel = { null }; /** * Mouse controls for FPS movement and Arcball rotation */ - protected ArcballCameraControl targetArcball; - protected FPSCameraControl fpsControl; + var targetArcball: ArcballCameraControl? = null + protected set + protected var fpsControl: FPSCameraControl? = null + /* + * Return the default floor object + *//* + * Set the default floor object + */ /** * The floor that orients the user in the scene */ - protected Node floor; - protected boolean vrActive = false; + var floor: Node? = null + protected var vrActive = false + /** * The primary camera/observer in the scene */ - Camera camera = null; + var camera: Camera? = null + set(value) { + field = value + setActiveObserver(field) + } + /** * Geometry/Image information of scene */ - private CalibratedAxis[] axes; + private lateinit var axes: Array @Parameter - private LogService log; + private val log: LogService? = null + @Parameter - private MenuService menus; + private val menus: MenuService? = null + @Parameter - private IOService io; + private val io: IOService? = null + @Parameter - private OpService ops; + private val ops: OpService? = null + @Parameter - private EventService eventService; + private val eventService: EventService? = null + @Parameter - private DisplayService displayService; + private val displayService: DisplayService? = null + @Parameter - private LUTService lutService; + private val lutService: LUTService? = null + @Parameter - private ThreadService threadService; + private val threadService: ThreadService? = null + @Parameter - private ObjectService objectService; + private val objectService: ObjectService? = null + @Parameter - private UnitService unitService; + private val unitService: UnitService? = null + /** * Queue keeps track of the currently running animations - **/ - private Queue animations; + */ + private var animations: Queue>? = null + /** * Animation pause tracking - **/ - private boolean animating; + */ + private var animating = false + /** * This tracks the actively selected Node in the scene */ - private Node activeNode = null; + var activeNode: Node? = null + private set + /** * Speeds for input controls */ - private float fpsScrollSpeed = 0.05f; - private float mouseSpeedMult = 0.25f; - private Display scijavaDisplay; - private SplashLabel splashLabel; - private SceneryJPanel panel; - private JSplitPane mainSplitPane; - private JSplitPane inspector; - private JSplitPane interpreterSplitPane; - private REPLPane interpreterPane; - private NodePropertyEditor nodePropertyEditor; - private ArrayList lights; - private Stack> controlStack; - private JFrame frame; - private Predicate notAbstractNode = (Predicate) node -> !( (node instanceof Camera) || (node instanceof Light) || (node==getFloor())); - private boolean isClosed = false; - private Function> notAbstractBranchingFunction = node -> node.getChildren().stream().filter(notAbstractNode).collect(Collectors.toList()); + private var fpsScrollSpeed = 0.05f + private var mouseSpeedMult = 0.25f + + /* + * Return the SciJava Display that contains SciView + *//* + * Set the SciJava Display + */ var display: Display<*>? = null + private var splashLabel: SplashLabel? = null + + /** + * Return the current SceneryJPanel. This is necessary for custom context menus + * @return panel the current SceneryJPanel + */ + var sceneryJPanel: SceneryJPanel? = null + private set + private var mainSplitPane: JSplitPane? = null + private var inspector: JSplitPane? = null + private val interpreterSplitPane: JSplitPane? = null + private var interpreterPane: REPLPane? = null + private var nodePropertyEditor: NodePropertyEditor? = null + var lights: ArrayList? = null + private set + private var controlStack: Stack>? = null + private var frame: JFrame? = null + private val notAbstractNode: Predicate = Predicate { node: Node -> !(node is Camera || node is Light || node === floor) } + var isClosed = false + private set + private val notAbstractBranchingFunction = Function { node: Node -> node.children.stream().filter(notAbstractNode).collect(Collectors.toList()) } // If true, then when a new node is added to the scene, the camera will refocus on this node by default - private boolean centerOnNewNodes; + var centerOnNewNodes = false // If true, then when a new node is added the thread will block until the node is added to the scene. This is required for // centerOnNewNodes - private boolean blockOnNewNodes; - private PointLight headlight; - - public SciView( Context context ) { - super( "SciView", 1280, 720, false, context ); - context.inject( this ); - } + var blockOnNewNodes = false + private var headlight: PointLight? = null - public SciView( String applicationName, int windowWidth, int windowHeight ) { - super( applicationName, windowWidth, windowHeight, false ); + constructor(context: Context) : super("SciView", 1280, 720, false, context) { + context.inject(this) } - public boolean isClosed() { - return isClosed; - } + constructor(applicationName: String?, windowWidth: Int, windowHeight: Int) : super(applicationName!!, windowWidth, windowHeight, false) {} - public InputHandler publicGetInputHandler() { - return getInputHandler(); + fun publicGetInputHandler(): InputHandler { + return inputHandler!! } /** * Toggle video recording with scenery's video recording mechanism * Note: this video recording may skip frames because it is asynchronous */ - public void toggleRecordVideo() { - if( getRenderer() instanceof OpenGLRenderer ) - ((OpenGLRenderer)getRenderer()).recordMovie(); - else - ((VulkanRenderer)getRenderer()).recordMovie(); + fun toggleRecordVideo() { + if (renderer is OpenGLRenderer) (renderer as OpenGLRenderer).recordMovie() else (renderer as VulkanRenderer).recordMovie() } /** @@ -269,123 +292,106 @@ public class SciView extends SceneryBase implements CalibratedRealInterval controlState = new HashMap(); - controlStack.push(controlState); + fun stashControls() { + val controlState = HashMap() + controlStack!!.push(controlState) } /** * This pops/restores the previously stashed controls. Emits a warning if there are no stashed controls */ - public void restoreControls() { - HashMap controlState = controlStack.pop(); + fun restoreControls() { + val controlState = controlStack!!.pop() // This isnt how it should work - setObjectSelectionMode(); - resetFPSInputs(); + setObjectSelectionMode() + resetFPSInputs() } /** * Place the camera such that all objects in the scene are within the field of view */ - public void fitCameraToScene() { - centerOnNode(getScene()); - } - - public ArrayList getLights() { - return lights; + fun fitCameraToScene() { + centerOnNode(scene) } /** * Reset the scene to initial conditions */ - public void reset() { + fun reset() { // Initialize the 3D axes - axes = new CalibratedAxis[3]; - - axes[0] = new DefaultLinearAxis(new DefaultAxisType("X", true), "um", 1); - axes[1] = new DefaultLinearAxis(new DefaultAxisType("Y", true), "um", 1); - axes[2] = new DefaultLinearAxis(new DefaultAxisType("Z", true), "um", 1); + axes = arrayOf( + DefaultLinearAxis(DefaultAxisType("X", true), "um", 1.0), + DefaultLinearAxis(DefaultAxisType("Y", true), "um", 1.0), + DefaultLinearAxis(DefaultAxisType("Z", true), "um", 1.0) + ) // Remove everything except camera - Node[] toRemove = getSceneNodes( n -> !( n instanceof Camera ) ); - for( Node n : toRemove ) { - deleteNode(n, false); + val toRemove = getSceneNodes { n: Node? -> n !is Camera } + for (n in toRemove) { + deleteNode(n, false) } // Setup camera - Camera cam; - if( getCamera() == null ) { - cam = new DetachedHeadCamera(); - this.camera = cam; - cam.setPosition(new Vector3f(0.0f, 1.65f, 0.0f)); - getScene().addChild( cam ); - } else { - cam = getCamera(); + if (camera == null) { + camera = DetachedHeadCamera() + (camera as DetachedHeadCamera).position = Vector3f(0.0f, 1.65f, 0.0f) + scene.addChild(camera as DetachedHeadCamera) } - cam.setPosition( new Vector3f( 0.0f, 1.65f, 5.0f ) ); - cam.perspectiveCamera( 50.0f, getWindowWidth(), getWindowHeight(), 0.1f, 1000.0f ); + camera!!.position = Vector3f(0.0f, 1.65f, 5.0f) + camera!!.perspectiveCamera(50.0f, windowWidth, windowHeight, 0.1f, 1000.0f) // Setup lights - Vector3f[] tetrahedron = new Vector3f[4]; - tetrahedron[0] = new Vector3f( 1.0f, 0f, -1.0f/(float)Math.sqrt(2.0f) ); - tetrahedron[1] = new Vector3f( -1.0f,0f,-1.0f/(float)Math.sqrt(2.0) ); - tetrahedron[2] = new Vector3f( 0.0f,1.0f,1.0f/(float)Math.sqrt(2.0) ); - tetrahedron[3] = new Vector3f( 0.0f,-1.0f,1.0f/(float)Math.sqrt(2.0) ); - - lights = new ArrayList<>(); - - for( int i = 0; i < 4; i++ ) {// TODO allow # initial lights to be customizable? - PointLight light = new PointLight(150.0f); - light.setPosition( tetrahedron[i].mul(25.0f) ); - light.setEmissionColor( new Vector3f( 1.0f, 1.0f, 1.0f ) ); - light.setIntensity( 1.0f ); - lights.add( light ); + val tetrahedron = arrayOfNulls(4) + tetrahedron[0] = Vector3f(1.0f, 0f, -1.0f / Math.sqrt(2.0).toFloat()) + tetrahedron[1] = Vector3f(-1.0f, 0f, -1.0f / Math.sqrt(2.0).toFloat()) + tetrahedron[2] = Vector3f(0.0f, 1.0f, 1.0f / Math.sqrt(2.0).toFloat()) + tetrahedron[3] = Vector3f(0.0f, -1.0f, 1.0f / Math.sqrt(2.0).toFloat()) + lights = ArrayList() + for (i in 0..3) { // TODO allow # initial lights to be customizable? + val light = PointLight(150.0f) + light.position = tetrahedron[i]!!.mul(25.0f) + light.emissionColor = Vector3f(1.0f, 1.0f, 1.0f) + light.intensity = 1.0f + lights!!.add(light) //camera.addChild( light ); - getScene().addChild( light ); + scene.addChild(light) } // Make a headlight for the camera - headlight = new PointLight(150.0f); - headlight.setPosition( new Vector3f(0f, 0f, -1f).mul(25.0f) ); - headlight.setEmissionColor( new Vector3f( 1.0f, 1.0f, 1.0f ) ); - headlight.setIntensity( 0.5f ); - headlight.setName("headlight"); - - - Icosphere lightSphere = new Icosphere(1.0f, 2); - headlight.addChild(lightSphere); - lightSphere.getMaterial().setDiffuse(headlight.getEmissionColor()); - lightSphere.getMaterial().setSpecular(headlight.getEmissionColor()); - lightSphere.getMaterial().setAmbient(headlight.getEmissionColor()); - lightSphere.getMaterial().setWireframe(true); - lightSphere.setVisible(false); + headlight = PointLight(150.0f) + headlight!!.position = Vector3f(0f, 0f, -1f).mul(25.0f) + headlight!!.emissionColor = Vector3f(1.0f, 1.0f, 1.0f) + headlight!!.intensity = 0.5f + headlight!!.name = "headlight" + val lightSphere = Icosphere(1.0f, 2) + headlight!!.addChild(lightSphere) + lightSphere.material.diffuse = headlight!!.emissionColor + lightSphere.material.specular = headlight!!.emissionColor + lightSphere.material.ambient = headlight!!.emissionColor + lightSphere.material.wireframe = true + lightSphere.visible = false //lights.add( light ); - camera.setNearPlaneDistance(0.01f); - camera.setFarPlaneDistance(1000.0f); - camera.addChild( headlight ); - - floor = new InfinitePlane();//new Box( new Vector3f( 500f, 0.2f, 500f ) ); - ((InfinitePlane)floor).setType(InfinitePlane.Type.Grid); - floor.setName( "Floor" ); - getScene().addChild( floor ); - + camera!!.nearPlaneDistance = 0.01f + camera!!.farPlaneDistance = 1000.0f + camera!!.addChild(headlight!!) + floor = InfinitePlane() //new Box( new Vector3f( 500f, 0.2f, 500f ) ); + (floor as InfinitePlane).type = InfinitePlane.Type.Grid + (floor as Node).name = "Floor" + scene.addChild(floor as Node) } /** * Initialization of SWING and scenery. Also triggers an initial population of lights/camera in the scene */ - @SuppressWarnings("restriction") @Override public void init() { + override fun init() { // Darcula dependency went missing from maven repo, factor it out // if(Boolean.parseBoolean(System.getProperty("sciview.useDarcula", "false"))) { @@ -396,745 +402,580 @@ public class SciView extends SceneryBase implements CalibratedRealInterval { - if(name.startsWith("scenery.LogLevel")) { - LogbackUtils.setLogLevel("", System.getProperty(name, "info")); + val logLevel = System.getProperty("scenery.LogLevel", "info") + log!!.level = LogLevel.value(logLevel) + LogbackUtils.setLogLevel(null, logLevel) + System.getProperties().stringPropertyNames().forEach(Consumer { name: String -> + if (name.startsWith("scenery.LogLevel")) { + LogbackUtils.setLogLevel("", System.getProperty(name, "info")) } - }); + }) // determine imagej-launcher version and to disable Vulkan if XInitThreads() fix // is not deployed try { - final Class launcherClass = Class.forName("net.imagej.launcher.ClassLauncher"); - String versionString = VersionUtils.getVersion(launcherClass); - - if (versionString != null && ExtractsNatives.Companion.getPlatform() == ExtractsNatives.Platform.LINUX) { - versionString = versionString.substring(0, 5); - - final Version launcherVersion = new Version(versionString); - final Version nonWorkingVersion = new Version("4.0.5"); - + val launcherClass = Class.forName("net.imagej.launcher.ClassLauncher") + var versionString = VersionUtils.getVersion(launcherClass) + if (versionString != null && getPlatform() == ExtractsNatives.Platform.LINUX) { + versionString = versionString.substring(0, 5) + val launcherVersion = Version(versionString) + val nonWorkingVersion = Version("4.0.5") if (launcherVersion.compareTo(nonWorkingVersion) <= 0 - && !Boolean.parseBoolean(System.getProperty("sciview.DisableLauncherVersionCheck", "false"))) { - getLogger().info("imagej-launcher version smaller or equal to non-working version (" + versionString + " vs. 4.0.5), disabling Vulkan as rendering backend. Disable check by setting 'scenery.DisableLauncherVersionCheck' system property to 'true'."); - System.setProperty("scenery.Renderer", "OpenGLRenderer"); + && !java.lang.Boolean.parseBoolean(System.getProperty("sciview.DisableLauncherVersionCheck", "false"))) { + logger.info("imagej-launcher version smaller or equal to non-working version ($versionString vs. 4.0.5), disabling Vulkan as rendering backend. Disable check by setting 'scenery.DisableLauncherVersionCheck' system property to 'true'.") + System.setProperty("scenery.Renderer", "OpenGLRenderer") } else { - getLogger().info("imagej-launcher version bigger that non-working version (" + versionString + " vs. 4.0.5), all good."); + logger.info("imagej-launcher version bigger that non-working version ($versionString vs. 4.0.5), all good.") } } - } catch (ClassNotFoundException cnfe) { + } catch (cnfe: ClassNotFoundException) { // Didn't find the launcher, so we're probably good. - getLogger().info("imagej-launcher not found, not touching renderer preferences."); + logger.info("imagej-launcher not found, not touching renderer preferences.") } // TODO: check for jdk 8 v. jdk 11 on linux and choose renderer accordingly - if( Platform.get() == Platform.LINUX ) { - String version = System.getProperty("java.version"); - if( version.startsWith("1.") ) { - version = version.substring(2, 3); + if (Platform.get() === Platform.LINUX) { + var version = System.getProperty("java.version") + if (version.startsWith("1.")) { + version = version.substring(2, 3) } else { - int dot = version.indexOf("."); + val dot = version.indexOf(".") if (dot != -1) { - version = version.substring(0, dot); + version = version.substring(0, dot) } } // If Linux and JDK 8, then use OpenGLRenderer - if( version.equals("8") ) - System.setProperty("scenery.Renderer", "OpenGLRenderer"); + if (version == "8") System.setProperty("scenery.Renderer", "OpenGLRenderer") } - - int x, y; - + var x: Int + var y: Int try { - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - - x = screenSize.width/2 - getWindowWidth()/2; - y = screenSize.height/2 - getWindowHeight()/2; - } catch(HeadlessException e) { - x = 10; - y = 10; - } - - frame = new JFrame("SciView"); - frame.setLayout(new BorderLayout(0, 0)); - frame.setSize(getWindowWidth(), getWindowHeight()); - frame.setLocation(x, y); - frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - nodePropertyEditor = new NodePropertyEditor( this ); - - final JPanel p = new JPanel(new BorderLayout(0, 0)); - panel = new SceneryJPanel(); - - JPopupMenu.setDefaultLightWeightPopupEnabled(false); - final JMenuBar swingMenuBar = new JMenuBar(); - new SwingJMenuBarCreator().createMenus(menus.getMenu("SciView"), swingMenuBar); - frame.setJMenuBar(swingMenuBar); - - p.setLayout(new OverlayLayout(p)); - p.setBackground(new Color(50, 48, 47)); - p.add(panel, BorderLayout.CENTER); - panel.setVisible(true); - - nodePropertyEditor.getComponent(); // Initialize node property panel - - JTree inspectorTree = nodePropertyEditor.getTree(); - inspectorTree.setToggleClickCount(0);// This disables expanding menus on double click - JPanel inspectorProperties = nodePropertyEditor.getProps(); - - JBEditorTabs tp = new JBEditorTabs(null); - tp.setTabsPosition(JBTabsPosition.right); - tp.setSideComponentVertical(true); - - inspector = new JSplitPane(JSplitPane.VERTICAL_SPLIT, // - new JScrollPane( inspectorTree ), - new JScrollPane( inspectorProperties )); - inspector.setDividerLocation( getWindowHeight() / 3 ); - inspector.setContinuousLayout(true); - inspector.setBorder(BorderFactory.createEmptyBorder()); - inspector.setDividerSize(1); - ImageIcon inspectorIcon = getScaledImageIcon(this.getClass().getResource("toolbox.png"), 16, 16); - - TabInfo tiInspector = new TabInfo(inspector, inspectorIcon); - tiInspector.setText(""); - tp.addTab(tiInspector); + val screenSize = Toolkit.getDefaultToolkit().screenSize + x = screenSize.width / 2 - windowWidth / 2 + y = screenSize.height / 2 - windowHeight / 2 + } catch (e: HeadlessException) { + x = 10 + y = 10 + } + frame = JFrame("SciView") + frame!!.layout = BorderLayout(0, 0) + frame!!.setSize(windowWidth, windowHeight) + frame!!.setLocation(x, y) + frame!!.defaultCloseOperation = JFrame.DISPOSE_ON_CLOSE + nodePropertyEditor = NodePropertyEditor(this) + val p = JPanel(BorderLayout(0, 0)) + sceneryJPanel = SceneryJPanel() + JPopupMenu.setDefaultLightWeightPopupEnabled(false) + val swingMenuBar = JMenuBar() + SwingJMenuBarCreator().createMenus(menus!!.getMenu("SciView"), swingMenuBar) + frame!!.jMenuBar = swingMenuBar + p.layout = OverlayLayout(p) + p.background = Color(50, 48, 47) + p.add(sceneryJPanel, BorderLayout.CENTER) + sceneryJPanel!!.isVisible = true + nodePropertyEditor!!.component // Initialize node property panel + val inspectorTree = nodePropertyEditor!!.tree + inspectorTree.toggleClickCount = 0 // This disables expanding menus on double click + val inspectorProperties = nodePropertyEditor!!.props + val tp = JBEditorTabs(null) + tp.tabsPosition = JBTabsPosition.right + tp.isSideComponentVertical = true + inspector = JSplitPane(JSplitPane.VERTICAL_SPLIT, // + JScrollPane(inspectorTree), + JScrollPane(inspectorProperties)) + inspector!!.dividerLocation = windowHeight / 3 + inspector!!.isContinuousLayout = true + inspector!!.border = BorderFactory.createEmptyBorder() + inspector!!.dividerSize = 1 + val inspectorIcon = getScaledImageIcon(this.javaClass.getResource("toolbox.png"), 16, 16) + val tiInspector = TabInfo(inspector, inspectorIcon) + tiInspector.text = "" + tp.addTab(tiInspector) // We need to get the surface scale here before initialising scenery's renderer, as // the information is needed already at initialisation time. - final AffineTransform dt = frame.getGraphicsConfiguration().getDefaultTransform(); - final Vector2f surfaceScale = new Vector2f((float)dt.getScaleX(), (float)dt.getScaleY()); - getSettings().set("Renderer.SurfaceScale", surfaceScale); - - interpreterPane = new REPLPane(getScijavaContext()); - interpreterPane.getComponent().setBorder(BorderFactory.createEmptyBorder()); - ImageIcon interpreterIcon = getScaledImageIcon(this.getClass().getResource("terminal.png"), 16, 16); - - TabInfo tiREPL = new TabInfo(interpreterPane.getComponent(), interpreterIcon); - tiREPL.setText(""); - tp.addTab(tiREPL); - - tp.addTabMouseListener(new MouseListener() { - private boolean hidden = false; - private int previousPosition = 0; - - @Override - public void mouseClicked(MouseEvent e) { - if(e.getClickCount() == 2) { - toggleSidebar(); + val dt = frame!!.graphicsConfiguration.defaultTransform + val surfaceScale = Vector2f(dt.scaleX.toFloat(), dt.scaleY.toFloat()) + settings.set("Renderer.SurfaceScale", surfaceScale) + interpreterPane = REPLPane(scijavaContext) + interpreterPane!!.component.border = BorderFactory.createEmptyBorder() + val interpreterIcon = getScaledImageIcon(this.javaClass.getResource("terminal.png"), 16, 16) + val tiREPL = TabInfo(interpreterPane!!.component, interpreterIcon) + tiREPL.text = "" + tp.addTab(tiREPL) + tp.addTabMouseListener(object : MouseListener { + private val hidden = false + private val previousPosition = 0 + override fun mouseClicked(e: MouseEvent) { + if (e.clickCount == 2) { + toggleSidebar() } } - @Override - public void mousePressed(MouseEvent e) { - - } - - @Override - public void mouseReleased(MouseEvent e) { - - } - - @Override - public void mouseEntered(MouseEvent e) { - - } - - @Override - public void mouseExited(MouseEvent e) { - - } - }); - - initializeInterpreter(); - - mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, // + override fun mousePressed(e: MouseEvent) {} + override fun mouseReleased(e: MouseEvent) {} + override fun mouseEntered(e: MouseEvent) {} + override fun mouseExited(e: MouseEvent) {} + }) + initializeInterpreter() + mainSplitPane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT, // p, - tp.getComponent() - ); - mainSplitPane.setDividerLocation(frame.getSize().width - 36); - mainSplitPane.setBorder(BorderFactory.createEmptyBorder()); - mainSplitPane.setDividerSize(1); - mainSplitPane.setResizeWeight(0.9); - sidebarHidden = true; + tp.component + ) + mainSplitPane!!.dividerLocation = frame!!.size.width - 36 + mainSplitPane!!.border = BorderFactory.createEmptyBorder() + mainSplitPane!!.dividerSize = 1 + mainSplitPane!!.resizeWeight = 0.9 + sidebarHidden = true //frame.add(mainSplitPane, BorderLayout.CENTER); - frame.add(mainSplitPane, BorderLayout.CENTER); - - SciView sciView = this; - frame.addWindowListener(new WindowAdapter() { - @Override public void windowClosing(WindowEvent e) { - getLogger().debug("Closing SciView window."); - close(); - getScijavaContext().service(SciViewService.class).close(sciView); - isClosed = true; + frame!!.add(mainSplitPane, BorderLayout.CENTER) + val sciView = this + frame!!.addWindowListener(object : WindowAdapter() { + override fun windowClosing(e: WindowEvent) { + logger.debug("Closing SciView window.") + close() + scijavaContext!!.service(SciViewService::class.java).close(sciView) + isClosed = true } - }); - - splashLabel = new SplashLabel(); - frame.setGlassPane(splashLabel); - frame.getGlassPane().setVisible(true); - frame.getGlassPane().requestFocusInWindow(); -// frame.getGlassPane().setBackground(new java.awt.Color(50, 48, 47, 255)); - frame.setVisible(true); - - sceneryPanel[0] = panel; - - setRenderer( Renderer.createRenderer( getHub(), getApplicationName(), getScene(), - getWindowWidth(), getWindowHeight(), - sceneryPanel[0]) ); - - getHub().add( SceneryElement.Renderer, getRenderer() ); - - reset(); - - animations = new LinkedList<>(); - controlStack = new Stack<>(); - - SwingUtilities.invokeLater(() -> { + }) + splashLabel = SplashLabel() + frame!!.glassPane = splashLabel + frame!!.glassPane.isVisible = true + frame!!.glassPane.requestFocusInWindow() + // frame.getGlassPane().setBackground(new java.awt.Color(50, 48, 47, 255)); + frame!!.isVisible = true + sceneryPanel[0] = sceneryJPanel + renderer = Renderer.createRenderer(hub, applicationName, scene, + windowWidth, windowHeight, + sceneryPanel[0]) + hub.add(SceneryElement.Renderer, renderer!!) + reset() + animations = LinkedList() + controlStack = Stack() + SwingUtilities.invokeLater { try { - while (!getSceneryRenderer().getFirstImageReady()) { - getLogger().debug("Waiting for renderer initialisation"); - Thread.sleep(300); + while (!getSceneryRenderer()!!.firstImageReady) { + logger.debug("Waiting for renderer initialisation") + Thread.sleep(300) } - - Thread.sleep(200); - } catch (InterruptedException e) { - getLogger().error("Renderer construction interrupted."); + Thread.sleep(200) + } catch (e: InterruptedException) { + logger.error("Renderer construction interrupted.") } - - nodePropertyEditor.rebuildTree(); - getLogger().info("Done initializing SciView"); + nodePropertyEditor!!.rebuildTree() + logger.info("Done initializing SciView") // subscribe to Node{Added, Removed, Changed} events - eventService.subscribe(this); - frame.getGlassPane().setVisible(false); - panel.setVisible(true); + eventService!!.subscribe(this) + frame!!.glassPane.isVisible = false + sceneryJPanel!!.isVisible = true // install hook to keep inspector updated on external changes (scripting, etc) - getScene().getOnNodePropertiesChanged().put("updateInspector", - node -> { - if( node == nodePropertyEditor.getCurrentNode() ) { - nodePropertyEditor.updateProperties(node); - } - return null; - }); + scene.onNodePropertiesChanged["updateInspector"] = { node: Node -> + if (node === nodePropertyEditor!!.currentNode) { + nodePropertyEditor!!.updateProperties(node) + } + null + } // Enable push rendering by default - getRenderer().setPushMode( true ); - - sciView.getCamera().setPosition(1.65, 1); - - }); + renderer!!.pushMode = true + sciView.camera!!.setPosition(1.65, 1) + } } - private boolean sidebarHidden = false; - private int previousSidebarPosition = 0; - - public boolean toggleSidebar() { - if(!sidebarHidden) { - previousSidebarPosition = mainSplitPane.getDividerLocation(); + private var sidebarHidden = false + private var previousSidebarPosition = 0 + fun toggleSidebar(): Boolean { + if (!sidebarHidden) { + previousSidebarPosition = mainSplitPane!!.dividerLocation // TODO: remove hard-coded tab width - mainSplitPane.setDividerLocation(frame.getSize().width - 36); - sidebarHidden = true; + mainSplitPane!!.dividerLocation = frame!!.size.width - 36 + sidebarHidden = true } else { - if(previousSidebarPosition == 0) { - previousSidebarPosition = getWindowWidth()/3 * 2; + if (previousSidebarPosition == 0) { + previousSidebarPosition = windowWidth / 3 * 2 } - - mainSplitPane.setDividerLocation(previousSidebarPosition); - sidebarHidden = false; + mainSplitPane!!.dividerLocation = previousSidebarPosition + sidebarHidden = false } - - return sidebarHidden; + return sidebarHidden } - private ImageIcon getScaledImageIcon(final URL resource, int width, int height) { - final ImageIcon first = new ImageIcon(resource); - final Image image = first.getImage(); - - BufferedImage resizedImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); - Graphics2D g2 = resizedImg.createGraphics(); - - g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); - g2.drawImage(first.getImage(), 0, 0, width, height, null); - g2.dispose(); - - return new ImageIcon(resizedImg); + private fun getScaledImageIcon(resource: URL, width: Int, height: Int): ImageIcon { + val first = ImageIcon(resource) + val image = first.image + val resizedImg = BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB) + val g2 = resizedImg.createGraphics() + g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR) + g2.drawImage(first.image, 0, 0, width, height, null) + g2.dispose() + return ImageIcon(resizedImg) } - private void initializeInterpreter() { - String startupCode = ""; - startupCode = new Scanner(SciView.class.getResourceAsStream("startup.py"), "UTF-8").useDelimiter("\\A").next(); - interpreterPane.getREPL().getInterpreter().getBindings().put("sciView", this); + private fun initializeInterpreter() { + var startupCode: String? = "" + startupCode = Scanner(SciView::class.java.getResourceAsStream("startup.py"), "UTF-8").useDelimiter("\\A").next() + interpreterPane!!.repl.interpreter.bindings["sciView"] = this try { - interpreterPane.getREPL().getInterpreter().eval(startupCode); - } catch (ScriptException e) { - e.printStackTrace(); + interpreterPane!!.repl.interpreter.eval(startupCode) + } catch (e: ScriptException) { + e.printStackTrace() } } /* * Completely close the SciView window + cleanup */ - public void closeWindow() { - frame.dispose(); - } - - /* - * Return the default floor object - */ - public Node getFloor() { - return floor; - } - - /* - * Set the default floor object - */ - public void setFloor( Node n ) { - floor = n; - } - - /** - * Return the current SceneryJPanel. This is necessary for custom context menus - * @return panel the current SceneryJPanel - */ - public SceneryJPanel getSceneryJPanel() { - return panel; + fun closeWindow() { + frame!!.dispose() } /* * Return true if the scene has been initialized */ - public boolean isInitialized() { - return sceneInitialized(); - } - - /* - * Return the current camera that is rendering the scene - */ - public Camera getCamera() { - return camera; - } - - /* - * Return the SciJava Display that contains SciView - */ - public Display getDisplay() { - return scijavaDisplay; - } - - /* - * Set the SciJava Display - */ - public void setDisplay( Display display ) { - scijavaDisplay = display; - } + val isInitialized: Boolean + get() = sceneInitialized() /* * Center the camera on the scene such that all objects are within the field of view */ - public void centerOnScene() { - centerOnNode(getScene()); + fun centerOnScene() { + centerOnNode(scene) } /* * Get the InputHandler that is managing mouse, input, VR controls, etc. */ - public InputHandler getSceneryInputHandler() { - return getInputHandler(); - } + val sceneryInputHandler: InputHandler + get() = inputHandler!! /* * Return a bounding box around a subgraph of the scenegraph */ - public OrientedBoundingBox getSubgraphBoundingBox( Node n ) { - Function> predicate = node -> node.getChildren(); - return getSubgraphBoundingBox(n,predicate); + fun getSubgraphBoundingBox(n: Node): OrientedBoundingBox? { + val predicate = Function> { node: Node -> node.children } + return getSubgraphBoundingBox(n, predicate) } /* * Return a bounding box around a subgraph of the scenegraph */ - public OrientedBoundingBox getSubgraphBoundingBox( Node n, Function> branchFunction ) { - if(n.getBoundingBox() == null && n.getChildren().size() != 0) { - return n.getMaximumBoundingBox().asWorld(); + fun getSubgraphBoundingBox(n: Node, branchFunction: Function>): OrientedBoundingBox? { + if (n.boundingBox == null && n.children.size != 0) { + return n.getMaximumBoundingBox().asWorld() } - - List branches = branchFunction.apply(n); - if( branches.size() == 0 ) { - if( n.getBoundingBox() == null ) - return null; - else - return n.getBoundingBox().asWorld(); + val branches = branchFunction.apply(n) + if (branches.size == 0) { + return if (n.boundingBox == null) null else n.boundingBox!!.asWorld() } - - OrientedBoundingBox bb = n.getMaximumBoundingBox(); - for( Node c : branches ){ - OrientedBoundingBox cBB = getSubgraphBoundingBox(c, branchFunction); - if( cBB != null ) - bb = bb.expand(bb, cBB); + var bb = n.getMaximumBoundingBox() + for (c in branches) { + val cBB = getSubgraphBoundingBox(c, branchFunction) + if (cBB != null) bb = bb.expand(bb, cBB) } - return bb; + return bb } /* * Center the camera on the specified Node */ - public void centerOnNode( Node currentNode ) { - centerOnNode(currentNode,notAbstractBranchingFunction); - } - /* * Center the camera on the specified Node */ - public void centerOnNode( Node currentNode, Function> branchFunction ) { - if( currentNode == null ) { - log.info("Cannot center on node. CurrentNode is null" ); - return; + @JvmOverloads + fun centerOnNode(currentNode: Node?, branchFunction: Function> = notAbstractBranchingFunction) { + if (currentNode == null) { + log!!.info("Cannot center on node. CurrentNode is null") + return } - - OrientedBoundingBox bb = getSubgraphBoundingBox(currentNode, branchFunction); + val bb = getSubgraphBoundingBox(currentNode, branchFunction) ?: return // TODO: find the widest dimensions of BB and align to that normal - - if( bb == null ) return; - System.out.println("CurrentNode BoundingBox " + bb + " " + bb.getBoundingSphere().getOrigin() + " " + bb.getBoundingSphere().getRadius()); - - if(Float.isNaN(bb.getBoundingSphere().getOrigin().x()) || - Float.isNaN(bb.getBoundingSphere().getOrigin().y()) || - Float.isNaN(bb.getBoundingSphere().getOrigin().z()) || - Float.isNaN(bb.getBoundingSphere().getRadius())) { - log.warn("Bounding box contains NaN, not adjusting camera."); - return; + println("CurrentNode BoundingBox " + bb + " " + bb.getBoundingSphere().origin + " " + bb.getBoundingSphere().radius) + if (java.lang.Float.isNaN(bb.getBoundingSphere().origin.x()) || + java.lang.Float.isNaN(bb.getBoundingSphere().origin.y()) || + java.lang.Float.isNaN(bb.getBoundingSphere().origin.z()) || + java.lang.Float.isNaN(bb.getBoundingSphere().radius)) { + log!!.warn("Bounding box contains NaN, not adjusting camera.") + return } - - getCamera().setTarget( bb.getBoundingSphere().getOrigin() ); - getCamera().setTargeted( true ); + camera!!.target = bb.getBoundingSphere().origin + camera!!.targeted = true // Set forward direction to point from camera at active node - Vector3f forward = bb.getBoundingSphere().getOrigin().sub( getCamera().getPosition() ).normalize(); - - float distance = (float) (bb.getBoundingSphere().getRadius() / Math.tan( getCamera().getFov() / 360 * Math.PI )); - - headlight.setLightRadius(distance * 1.1f); + val forward = bb.getBoundingSphere().origin.sub(camera!!.position).normalize() + val distance = (bb.getBoundingSphere().radius / Math.tan(camera!!.fov / 360 * Math.PI)).toFloat() + headlight!!.lightRadius = distance * 1.1f // Solve for the proper rotation - Quaternionf rotation = new Quaternionf().lookAlong(forward, new Vector3f(0,1,0)); - - getCamera().setRotation( rotation.normalize() ); - getCamera().setPosition( bb.getBoundingSphere().getOrigin().add( getCamera().getForward().mul( distance * -1.33f ) ) ); + val rotation = Quaternionf().lookAlong(forward, Vector3f(0.0f, 1.0f, 0.0f)) + camera!!.rotation = rotation.normalize() + camera!!.position = bb.getBoundingSphere().origin.add(camera!!.forward.mul(distance * -1.33f)) // getCamera().setDirty(true); // getCamera().setNeedsUpdate(true); } - public float getFPSSpeed() { - return fpsScrollSpeed; - } - - public void setFPSSpeed( float newspeed ) { - if( newspeed < 0.30f ) newspeed = 0.3f; - else if( newspeed > 30.0f ) newspeed = 30.0f; - fpsScrollSpeed = newspeed; - //log.debug( "FPS scroll speed: " + fpsScrollSpeed ); - } - - public float getMouseSpeed() { - return mouseSpeedMult; - } + //log.debug( "FPS scroll speed: " + fpsScrollSpeed ); + var fPSSpeed: Float + get() = fpsScrollSpeed + set(newspeed) { + var newspeed = newspeed + if (newspeed < 0.30f) newspeed = 0.3f else if (newspeed > 30.0f) newspeed = 30.0f + fpsScrollSpeed = newspeed + //log.debug( "FPS scroll speed: " + fpsScrollSpeed ); + } - public void setMouseSpeed( float newspeed ) { - if( newspeed < 0.30f ) newspeed = 0.3f; - else if( newspeed > 3.0f ) newspeed = 3.0f; - mouseSpeedMult = newspeed; - //log.debug( "Mouse speed: " + mouseSpeedMult ); - } + //log.debug( "Mouse speed: " + mouseSpeedMult ); + var mouseSpeed: Float + get() = mouseSpeedMult + set(newspeed) { + var newspeed = newspeed + if (newspeed < 0.30f) newspeed = 0.3f else if (newspeed > 3.0f) newspeed = 3.0f + mouseSpeedMult = newspeed + //log.debug( "Mouse speed: " + mouseSpeedMult ); + } /* * Reset the input handler to first-person-shooter (FPS) style controls */ - public void resetFPSInputs() { - InputHandler h = getInputHandler(); - if(h == null) { - getLogger().error("InputHandler is null, cannot change bindings."); - return; - } - - h.addBehaviour( "move_forward_scroll", - new MovementCommand( "move_forward", "forward", () -> getScene().findObserver(), - getFPSSpeed() ) ); - h.addBehaviour( "move_forward", - new MovementCommand( "move_forward", "forward", () -> getScene().findObserver(), - getFPSSpeed() ) ); - h.addBehaviour( "move_back", - new MovementCommand( "move_back", "back", () -> getScene().findObserver(), - getFPSSpeed() ) ); - h.addBehaviour( "move_left", - new MovementCommand( "move_left", "left", () -> getScene().findObserver(), - getFPSSpeed() ) ); - h.addBehaviour( "move_right", - new MovementCommand( "move_right", "right", () -> getScene().findObserver(), - getFPSSpeed() ) ); - h.addBehaviour( "move_up", - new MovementCommand( "move_up", "up", () -> getScene().findObserver(), - getFPSSpeed() ) ); - h.addBehaviour( "move_down", - new MovementCommand( "move_down", "down", () -> getScene().findObserver(), - getFPSSpeed() ) ); - - h.addKeyBinding( "move_forward_scroll", "scroll" ); - } - - public void setObjectSelectionMode() { - Function3 selectAction = (nearest,x,y) -> { - if( !nearest.getMatches().isEmpty() ) { - setActiveNode( nearest.getMatches().get( 0 ).getNode() ); - nodePropertyEditor.trySelectNode( getActiveNode() ); - log.info( "Selected node: " + getActiveNode().getName() + " at " + x + "," + y); + fun resetFPSInputs() { + val h = inputHandler + if (h == null) { + logger.error("InputHandler is null, cannot change bindings.") + return + } + h.addBehaviour("move_forward_scroll", + MovementCommand("move_forward", "forward", { scene.findObserver() }, + fPSSpeed)) + h.addBehaviour("move_forward", + MovementCommand("move_forward", "forward", { scene.findObserver() }, + fPSSpeed)) + h.addBehaviour("move_back", + MovementCommand("move_back", "back", { scene.findObserver() }, + fPSSpeed)) + h.addBehaviour("move_left", + MovementCommand("move_left", "left", { scene.findObserver() }, + fPSSpeed)) + h.addBehaviour("move_right", + MovementCommand("move_right", "right", { scene.findObserver() }, + fPSSpeed)) + h.addBehaviour("move_up", + MovementCommand("move_up", "up", { scene.findObserver() }, + fPSSpeed)) + h.addBehaviour("move_down", + MovementCommand("move_down", "down", { scene.findObserver() }, + fPSSpeed)) + h.addKeyBinding("move_forward_scroll", "scroll") + } + + fun setObjectSelectionMode() { + val selectAction: Function3 = { (matches), x: Int, y: Int -> + if (!matches.isEmpty()) { + setActiveNode(matches[0].node) + nodePropertyEditor!!.trySelectNode(activeNode) + log!!.info("Selected node: " + activeNode!!.name + " at " + x + "," + y) // Setup the context menu for this node - - ContextPopUp menu = new ContextPopUp(nearest.getMatches().get(0).getNode()); - menu.show(panel, x, y); + val menu = ContextPopUp(matches[0].node) + menu.show(sceneryJPanel, x, y) } - return Unit.INSTANCE; - }; - setObjectSelectionMode(selectAction); + } + setObjectSelectionMode(selectAction) } /* * Set the action used during object selection */ - public void setObjectSelectionMode(Function3 selectAction) { - final InputHandler h = getInputHandler(); - List> ignoredObjects = new ArrayList<>(); - ignoredObjects.add( BoundingGrid.class ); - - if(h == null) { - getLogger().error("InputHandler is null, cannot change object selection mode."); - return; + fun setObjectSelectionMode(selectAction: Function3) { + val h = inputHandler + val ignoredObjects: MutableList> = ArrayList() + ignoredObjects.add(BoundingGrid::class.java) + if (h == null) { + logger.error("InputHandler is null, cannot change object selection mode.") + return } - h.addBehaviour( "object_selection_mode", - new SelectCommand( "objectSelector", getRenderer(), getScene(), - () -> getScene().findObserver(), false, ignoredObjects, - selectAction ) ); - h.addKeyBinding( "object_selection_mode", "double-click button1" ); + h.addBehaviour("object_selection_mode", + SelectCommand("objectSelector", renderer!!, scene, + { scene.findObserver() }, false, ignoredObjects, + selectAction)) + h.addKeyBinding("object_selection_mode", "double-click button1") } /* * Initial configuration of the scenery InputHandler * This is automatically called and should not be used directly */ - @Override public void inputSetup() { - final InputHandler h = getInputHandler(); - if(h == null) { - getLogger().error("InputHandler is null, cannot run input setup."); - return; + override fun inputSetup() { + val h = inputHandler + if (h == null) { + logger.error("InputHandler is null, cannot run input setup.") + return } // TODO: Maybe get rid of this? - h.useDefaultBindings( "" ); + h.useDefaultBindings("") // Mouse controls - setObjectSelectionMode(); - NodeTranslateControl nodeTranslate = new NodeTranslateControl(this, 0.0005f); - h.addBehaviour( "mouse_control_nodetranslate", nodeTranslate ); - h.addKeyBinding( "mouse_control_nodetranslate", "ctrl button1" ); - h.addBehaviour( "scroll_nodetranslate", nodeTranslate ); - h.addKeyBinding( "scroll_nodetranslate", "ctrl scroll" ); - - h.addBehaviour("move_up_slow", new MovementCommand("move_up", "up", () -> getScene().findObserver(), fpsScrollSpeed ) ); - h.addBehaviour("move_down_slow", new MovementCommand("move_down", "down", () -> getScene().findObserver(), fpsScrollSpeed ) ); - h.addBehaviour("move_up_fast", new MovementCommand("move_up", "up", () -> getScene().findObserver(), 1.0f ) ); - h.addBehaviour("move_down_fast", new MovementCommand("move_down", "down", () -> getScene().findObserver(), 1.0f ) ); - - h.addKeyBinding("move_up_slow", "X"); - h.addKeyBinding("move_down_slow", "C"); - h.addKeyBinding("move_up_fast", "shift X"); - h.addKeyBinding("move_down_fast", "shift C"); - - enableArcBallControl(); - enableFPSControl(); + setObjectSelectionMode() + val nodeTranslate = NodeTranslateControl(this, 0.0005f) + h.addBehaviour("mouse_control_nodetranslate", nodeTranslate) + h.addKeyBinding("mouse_control_nodetranslate", "ctrl button1") + h.addBehaviour("scroll_nodetranslate", nodeTranslate) + h.addKeyBinding("scroll_nodetranslate", "ctrl scroll") + h.addBehaviour("move_up_slow", MovementCommand("move_up", "up", { scene.findObserver() }, fpsScrollSpeed)) + h.addBehaviour("move_down_slow", MovementCommand("move_down", "down", { scene.findObserver() }, fpsScrollSpeed)) + h.addBehaviour("move_up_fast", MovementCommand("move_up", "up", { scene.findObserver() }, 1.0f)) + h.addBehaviour("move_down_fast", MovementCommand("move_down", "down", { scene.findObserver() }, 1.0f)) + h.addKeyBinding("move_up_slow", "X") + h.addKeyBinding("move_down_slow", "C") + h.addKeyBinding("move_up_fast", "shift X") + h.addKeyBinding("move_down_fast", "shift C") + enableArcBallControl() + enableFPSControl() // Extra keyboard controls - h.addBehaviour( "show_help", new showHelpDisplay() ); - h.addKeyBinding( "show_help", "U" ); - - h.addBehaviour( "enable_decrease", new enableDecrease() ); - h.addKeyBinding( "enable_decrease", "M" ); - - h.addBehaviour( "enable_increase", new enableIncrease() ); - h.addKeyBinding( "enable_increase", "N" ); + h.addBehaviour("show_help", showHelpDisplay()) + h.addKeyBinding("show_help", "U") + h.addBehaviour("enable_decrease", enableDecrease()) + h.addKeyBinding("enable_decrease", "M") + h.addBehaviour("enable_increase", enableIncrease()) + h.addKeyBinding("enable_increase", "N") //float veryFastSpeed = getScene().getMaximumBoundingBox().getBoundingSphere().getRadius()/50f; - float veryFastSpeed = 100f; - h.addBehaviour("move_forward_veryfast", new MovementCommand("move_forward", "forward", () -> getScene().findObserver(), veryFastSpeed)); - h.addBehaviour("move_back_veryfast", new MovementCommand("move_back", "back", () -> getScene().findObserver(), veryFastSpeed)); - h.addBehaviour("move_left_veryfast", new MovementCommand("move_left", "left", () -> getScene().findObserver(), veryFastSpeed)); - h.addBehaviour("move_right_veryfast", new MovementCommand("move_right", "right", () -> getScene().findObserver(), veryFastSpeed)); - h.addBehaviour("move_up_veryfast", new MovementCommand("move_up", "up", () -> getScene().findObserver(), veryFastSpeed)); - h.addBehaviour("move_down_veryfast", new MovementCommand("move_down", "down", () -> getScene().findObserver(), veryFastSpeed)); - - h.addKeyBinding("move_forward_veryfast", "ctrl shift W"); - h.addKeyBinding("move_back_veryfast", "ctrl shift S"); - h.addKeyBinding("move_left_veryfast", "ctrl shift A"); - h.addKeyBinding("move_right_veryfast", "ctrl shift D"); - h.addKeyBinding("move_up_veryfast", "ctrl shift X"); - h.addKeyBinding("move_down_veryfast", "ctrl shift C"); - + val veryFastSpeed = 100f + h.addBehaviour("move_forward_veryfast", MovementCommand("move_forward", "forward", { scene.findObserver() }, veryFastSpeed)) + h.addBehaviour("move_back_veryfast", MovementCommand("move_back", "back", { scene.findObserver() }, veryFastSpeed)) + h.addBehaviour("move_left_veryfast", MovementCommand("move_left", "left", { scene.findObserver() }, veryFastSpeed)) + h.addBehaviour("move_right_veryfast", MovementCommand("move_right", "right", { scene.findObserver() }, veryFastSpeed)) + h.addBehaviour("move_up_veryfast", MovementCommand("move_up", "up", { scene.findObserver() }, veryFastSpeed)) + h.addBehaviour("move_down_veryfast", MovementCommand("move_down", "down", { scene.findObserver() }, veryFastSpeed)) + h.addKeyBinding("move_forward_veryfast", "ctrl shift W") + h.addKeyBinding("move_back_veryfast", "ctrl shift S") + h.addKeyBinding("move_left_veryfast", "ctrl shift A") + h.addKeyBinding("move_right_veryfast", "ctrl shift D") + h.addKeyBinding("move_up_veryfast", "ctrl shift X") + h.addKeyBinding("move_down_veryfast", "ctrl shift C") } /* * Change the control mode to circle around the active object in an arcball */ - private void enableArcBallControl() { - final InputHandler h = getInputHandler(); - if(h == null) { - getLogger().error("InputHandler is null, cannot setup arcball."); - return; + private fun enableArcBallControl() { + val h = inputHandler + if (h == null) { + logger.error("InputHandler is null, cannot setup arcball.") + return } - - Vector3f target; - if( getActiveNode() == null ) { - target = new Vector3f( 0, 0, 0 ); + val target: Vector3f + target = if (activeNode == null) { + Vector3f(0.0f, 0.0f, 0.0f) } else { - target = getActiveNode().getPosition(); + activeNode!!.position } - - float mouseSpeed = 0.25f; - mouseSpeed = getMouseSpeed(); - - Supplier cameraSupplier = () -> getScene().findObserver(); - targetArcball = new ArcballCameraControl( "mouse_control_arcball", cameraSupplier, - getRenderer().getWindow().getWidth(), - getRenderer().getWindow().getHeight(), target ); - targetArcball.setMaximumDistance( Float.MAX_VALUE ); - targetArcball.setMouseSpeedMultiplier( mouseSpeed ); - targetArcball.setScrollSpeedMultiplier( 0.05f ); - targetArcball.setDistance( getCamera().getPosition().sub( target ).length() ); + var mouseSpeed = 0.25f + mouseSpeed = mouseSpeed + val cameraSupplier = Supplier { scene.findObserver() } + targetArcball = ArcballCameraControl("mouse_control_arcball", cameraSupplier, + renderer!!.window.width, + renderer!!.window.height, target) + targetArcball!!.maximumDistance = Float.MAX_VALUE + targetArcball!!.mouseSpeedMultiplier = mouseSpeed + targetArcball!!.scrollSpeedMultiplier = 0.05f + targetArcball!!.distance = camera!!.position.sub(target).length() // FIXME: Swing seems to have issues with shift-scroll actions, so we change - // this to alt-scroll here for the moment. - h.addBehaviour( "mouse_control_arcball", targetArcball ); - h.addKeyBinding( "mouse_control_arcball", "shift button1" ); - h.addBehaviour( "scroll_arcball", targetArcball ); - h.addKeyBinding( "scroll_arcball", "shift scroll" ); + // this to alt-scroll here for the moment. + h.addBehaviour("mouse_control_arcball", targetArcball!!) + h.addKeyBinding("mouse_control_arcball", "shift button1") + h.addBehaviour("scroll_arcball", targetArcball!!) + h.addKeyBinding("scroll_arcball", "shift scroll") } /* * Enable FPS style controls */ - private void enableFPSControl() { - final InputHandler h = getInputHandler(); - if(h == null) { - getLogger().error("InputHandler is null, cannot setup fps control."); - return; + private fun enableFPSControl() { + val h = inputHandler + if (h == null) { + logger.error("InputHandler is null, cannot setup fps control.") + return } - - Supplier cameraSupplier = () -> getScene().findObserver(); - fpsControl = new FPSCameraControl( "mouse_control", cameraSupplier, getRenderer().getWindow().getWidth(), - getRenderer().getWindow().getHeight() ); - - h.addBehaviour( "mouse_control", fpsControl ); - h.addKeyBinding( "mouse_control", "button1" ); - - h.addBehaviour( "mouse_control_cameratranslate", new CameraTranslateControl( this, 0.002f ) ); - h.addKeyBinding( "mouse_control_cameratranslate", "button2" ); - - resetFPSInputs(); + val cameraSupplier = Supplier { scene.findObserver() } + fpsControl = FPSCameraControl("mouse_control", cameraSupplier, renderer!!.window.width, + renderer!!.window.height) + h.addBehaviour("mouse_control", fpsControl!!) + h.addKeyBinding("mouse_control", "button1") + h.addBehaviour("mouse_control_cameratranslate", CameraTranslateControl(this, 0.002f)) + h.addKeyBinding("mouse_control_cameratranslate", "button2") + resetFPSInputs() } - /** - * Add a box to the scene with default parameters - * @return the Node corresponding to the box - */ - public Node addBox() { - return addBox( new JOMLVector3( 0.0f, 0.0f, 0.0f ) ); - } - - /** - * Add a box at the specific position and unit size + * Add a box at the specified position with specified size, color, and normals on the inside/outside * @param position position to put the box + * @param size size of the box + * @param color color of the box + * @param inside are normals inside the box? * @return the Node corresponding to the box */ - public Node addBox( Vector3 position ) { - return addBox( position, new JOMLVector3( 1.0f, 1.0f, 1.0f ) ); - } - /** * Add a box at the specified position and with the specified size * @param position position to put the box * @param size size of the box * @return the Node corresponding to the box */ - public Node addBox( Vector3 position, Vector3 size ) { - return addBox( position, size, DEFAULT_COLOR, false ); - } - /** - * Add a box at the specified position with specified size, color, and normals on the inside/outside + * Add a box at the specific position and unit size * @param position position to put the box - * @param size size of the box - * @param color color of the box - * @param inside are normals inside the box? * @return the Node corresponding to the box */ - public Node addBox( final Vector3 position, final Vector3 size, final ColorRGB color, - final boolean inside ) { + /** + * Add a box to the scene with default parameters + * @return the Node corresponding to the box + */ + @JvmOverloads + fun addBox(position: Vector3? = JOMLVector3(0.0f, 0.0f, 0.0f), size: Vector3? = JOMLVector3(1.0f, 1.0f, 1.0f), color: ColorRGB? = DEFAULT_COLOR, + inside: Boolean = false): Node { // TODO: use a material from the current palate by default - final Material boxmaterial = new Material(); - boxmaterial.setAmbient( new Vector3f( 1.0f, 0.0f, 0.0f ) ); - boxmaterial.setDiffuse( Utils.convertToVector3f( color ) ); - boxmaterial.setSpecular( new Vector3f( 1.0f, 1.0f, 1.0f ) ); - - final Box box = new Box( JOMLVector3.convert( size ), inside ); - box.setMaterial( boxmaterial ); - box.setPosition( JOMLVector3.convert( position ) ); - - return addNode( box ); + val boxmaterial = Material() + boxmaterial.ambient = Vector3f(1.0f, 0.0f, 0.0f) + boxmaterial.diffuse = Utils.convertToVector3f(color) + boxmaterial.specular = Vector3f(1.0f, 1.0f, 1.0f) + val box = Box(JOMLVector3.convert(size), inside) + box.material = boxmaterial + box.position = JOMLVector3.convert(position) + return addNode(box) } - /** - * Add a unit sphere at the origin - * @return the Node corresponding to the sphere + * Add a sphere at the specified positoin with a given radius and color + * @param position position to put the sphere + * @param radius radius the sphere + * @param color color of the sphere + * @return the Node corresponding to the sphere */ - public Node addSphere() { - return addSphere( new JOMLVector3( 0.0f, 0.0f, 0.0f ), 1 ); - } - /** * Add a sphere at the specified position with a given radius * @param position position to put the sphere * @param radius radius of the sphere * @return the Node corresponding to the sphere */ - public Node addSphere( Vector3 position, float radius ) { - return addSphere( position, radius, DEFAULT_COLOR ); - } - /** - * Add a sphere at the specified positoin with a given radius and color - * @param position position to put the sphere - * @param radius radius the sphere - * @param color color of the sphere - * @return the Node corresponding to the sphere + * Add a unit sphere at the origin + * @return the Node corresponding to the sphere */ - public Node addSphere( final Vector3 position, final float radius, final ColorRGB color ) { - final Material material = new Material(); - material.setAmbient( new Vector3f( 1.0f, 0.0f, 0.0f ) ); - material.setDiffuse( Utils.convertToVector3f( color ) ); - material.setSpecular( new Vector3f( 1.0f, 1.0f, 1.0f ) ); - - final Sphere sphere = new Sphere( radius, 20 ); - sphere.setMaterial( material ); - sphere.setPosition( JOMLVector3.convert( position ) ); - - return addNode( sphere ); + @JvmOverloads + fun addSphere(position: Vector3? = JOMLVector3(0.0f, 0.0f, 0.0f), radius: Float = 1f, color: ColorRGB? = DEFAULT_COLOR): Node { + val material = Material() + material.ambient = Vector3f(1.0f, 0.0f, 0.0f) + material.diffuse = Utils.convertToVector3f(color) + material.specular = Vector3f(1.0f, 1.0f, 1.0f) + val sphere = Sphere(radius, 20) + sphere.material = material + sphere.position = JOMLVector3.convert(position) + return addNode(sphere) } /** @@ -1145,10 +986,10 @@ public class SciView extends SceneryBase implements CalibratedRealInterval, color: ColorRGB?, edgeWidth: Double): Node { + val material = Material() + material.ambient = Vector3f(1.0f, 1.0f, 1.0f) + material.diffuse = Utils.convertToVector3f(color) + material.specular = Vector3f(1.0f, 1.0f, 1.0f) + val line = Line(points.size) + for (pt in points) { + line.addPoint(JOMLVector3.convert(pt)) } - - line.setEdgeWidth( ( float ) edgeWidth ); - - line.setMaterial( material ); - line.setPosition( JOMLVector3.convert( points[0] ) ); - - return addNode( line ); + line.edgeWidth = edgeWidth.toFloat() + line.material = material + line.position = JOMLVector3.convert(points[0]) + return addNode(line) } /** * Add a PointLight source at the origin * @return a Node corresponding to the PointLight */ - public Node addPointLight() { - final Material material = new Material(); - material.setAmbient( new Vector3f( 1.0f, 0.0f, 0.0f ) ); - material.setDiffuse( new Vector3f( 0.0f, 1.0f, 0.0f ) ); - material.setSpecular( new Vector3f( 1.0f, 1.0f, 1.0f ) ); - - final PointLight light = new PointLight( 5.0f ); - light.setMaterial( material ); - light.setPosition( new Vector3f( 0.0f, 0.0f, 0.0f ) ); - lights.add(light); - - return addNode( light ); + fun addPointLight(): Node { + val material = Material() + material.ambient = Vector3f(1.0f, 0.0f, 0.0f) + material.diffuse = Vector3f(0.0f, 1.0f, 0.0f) + material.specular = Vector3f(1.0f, 1.0f, 1.0f) + val light = PointLight(5.0f) + light.material = material + light.position = Vector3f(0.0f, 0.0f, 0.0f) + lights!!.add(light) + return addNode(light) } /** * Position all lights that were initialized by default around the scene in a circle at Y=0 */ - public void surroundLighting() { - OrientedBoundingBox bb = getSubgraphBoundingBox(getScene(), notAbstractBranchingFunction); - OrientedBoundingBox.BoundingSphere boundingSphere = bb.getBoundingSphere(); + fun surroundLighting() { + val bb = getSubgraphBoundingBox(scene, notAbstractBranchingFunction) + val (c, r) = bb!!.getBoundingSphere() // Choose a good y-position, then place lights around the cross-section through this plane - float y = 0; - Vector3f c = boundingSphere.getOrigin(); - float r = boundingSphere.getRadius(); - for( int k = 0; k < lights.size(); k++ ) { - PointLight light = lights.get(k); - float x = (float) (c.x() + r * Math.cos( k == 0 ? 0 : Math.PI * 2 * ((float)k / (float)lights.size()) )); - float z = (float) (c.y() + r * Math.sin( k == 0 ? 0 : Math.PI * 2 * ((float)k / (float)lights.size()) )); - light.setLightRadius( 2 * r ); - light.setPosition( new Vector3f( x, y, z ) ); + val y = 0f + for (k in lights!!.indices) { + val light = lights!![k] + val x = (c.x() + r * cos(if (k == 0) 0.0 else Math.PI * 2 * (k.toFloat() / lights!!.size.toFloat()))).toFloat() + val z = (c.y() + r * sin(if (k == 0) 0.0 else Math.PI * 2 * (k.toFloat() / lights!!.size.toFloat()))).toFloat() + light.lightRadius = 2 * r + light.position = Vector3f(x, y, z) } } @@ -1262,44 +1078,40 @@ public class SciView extends SceneryBase implements CalibratedRealInterval verts ) { - float[] normals = new float[verts.size()];// div3 * 3coords - - for( int k = 0; k < verts.size(); k += 3 ) { - Vector3f v1 = new Vector3f( verts.get( k ).getFloatPosition( 0 ), // - verts.get( k ).getFloatPosition( 1 ), // - verts.get( k ).getFloatPosition( 2 ) ); - Vector3f v2 = new Vector3f( verts.get( k + 1 ).getFloatPosition( 0 ), - verts.get( k + 1 ).getFloatPosition( 1 ), - verts.get( k + 1 ).getFloatPosition( 2 ) ); - Vector3f v3 = new Vector3f( verts.get( k + 2 ).getFloatPosition( 0 ), - verts.get( k + 2 ).getFloatPosition( 1 ), - verts.get( k + 2 ).getFloatPosition( 2 ) ); - Vector3f a = v2.sub( v1 ); - Vector3f b = v3.sub( v1 ); - Vector3f n = a.cross( b ).normalize(); - normals[k / 3] = n.get( 0 ); - normals[k / 3 + 1] = n.get( 1 ); - normals[k / 3 + 2] = n.get( 2 ); + fun makeNormalsFromVertices(verts: ArrayList): FloatArray { + val normals = FloatArray(verts.size) // div3 * 3coords + var k = 0 + while (k < verts.size) { + val v1 = Vector3f(verts[k].getFloatPosition(0), // + verts[k].getFloatPosition(1), // + verts[k].getFloatPosition(2)) + val v2 = Vector3f(verts[k + 1].getFloatPosition(0), + verts[k + 1].getFloatPosition(1), + verts[k + 1].getFloatPosition(2)) + val v3 = Vector3f(verts[k + 2].getFloatPosition(0), + verts[k + 2].getFloatPosition(1), + verts[k + 2].getFloatPosition(2)) + val a = v2.sub(v1) + val b = v3.sub(v1) + val n = a.cross(b).normalize() + normals[k / 3] = n[0] + normals[k / 3 + 1] = n[1] + normals[k / 3 + 2] = n[2] + k += 3 } - return normals; + return normals } /** @@ -1335,86 +1148,77 @@ public class SciView extends SceneryBase implements CalibratedRealInterval list = ( List ) data; - if( list.isEmpty() ) { - throw new IllegalArgumentException( "Data source '" + source + "' appears empty." ); - } - final Object element = list.get( 0 ); - if( element instanceof RealLocalizable ) { + @Throws(IOException::class) + fun open(source: String) { + if (source.endsWith(".xml")) { + addNode(fromXML(source, hub, VolumeViewerOptions())) + return + } + val data = io!!.open(source) + if (data is Mesh) + addMesh(data) + else if (data is graphics.scenery.Mesh) + addMesh(data) + else if (data is PointCloud) + addPointCloud(data) + else if (data is Dataset) + addVolume(data) + else if (data is RandomAccessibleInterval<*>) + addVolume(data as RandomAccessibleInterval>, source) + else if (data is List<*>) { + val list = data + require(!list.isEmpty()) { "Data source '$source' appears empty." } + val element = list[0] + if (element is RealLocalizable) { // NB: For now, we assume all elements will be RealLocalizable. // Highly likely to be the case, barring antagonistic importers. - @SuppressWarnings("unchecked") final List points = ( List ) list; - addPointCloud( points, source ); + val points = list as List + addPointCloud(points, source) } else { - final String type = element == null ? "" : element.getClass().getName(); - throw new IllegalArgumentException( "Data source '" + source + // - "' contains elements of unknown type '" + type + "'" ); + val type = if (element == null) "" else element.javaClass.name + throw IllegalArgumentException("Data source '" + source + // + "' contains elements of unknown type '" + type + "'") } } else { - final String type = data == null ? "" : data.getClass().getName(); - throw new IllegalArgumentException( "Data source '" + source + // - "' contains data of unknown type '" + type + "'" ); + val type = if (data == null) "" else data.javaClass.name + throw IllegalArgumentException("Data source '" + source + // + "' contains data of unknown type '" + type + "'") } } - /** - * Add the given points to the scene as a PointCloud - * @param points points to use in a PointCloud - * @return a Node corresponding to the PointCloud - */ - public Node addPointCloud( Collection points ) { - return addPointCloud( points, "PointCloud" ); - } - /** * Add the given points to the scene as a PointCloud with a given name * @param points points to use in a PointCloud * @param name name of the PointCloud * @return */ - public Node addPointCloud( final Collection points, - final String name ) { - final float[] flatVerts = new float[points.size() * 3]; - int k = 0; - for( final RealLocalizable point : points ) { - flatVerts[k * 3] = point.getFloatPosition( 0 ); - flatVerts[k * 3 + 1] = point.getFloatPosition( 1 ); - flatVerts[k * 3 + 2] = point.getFloatPosition( 2 ); - k++; + @JvmOverloads + fun addPointCloud(points: Collection, + name: String? = "PointCloud"): Node { + val flatVerts = FloatArray(points.size * 3) + var k = 0 + for (point in points) { + flatVerts[k * 3] = point.getFloatPosition(0) + flatVerts[k * 3 + 1] = point.getFloatPosition(1) + flatVerts[k * 3 + 2] = point.getFloatPosition(2) + k++ } - - final PointCloud pointCloud = new PointCloud( getDefaultPointSize(), name ); - final Material material = new Material(); - final FloatBuffer vBuffer = BufferUtils.allocateFloat( flatVerts.length * 4 ); - final FloatBuffer nBuffer = BufferUtils.allocateFloat( 0 ); - - vBuffer.put( flatVerts ); - vBuffer.flip(); - - pointCloud.setVertices( vBuffer ); - pointCloud.setNormals( nBuffer ); - pointCloud.setIndices( BufferUtils.allocateInt( 0 ) ); - pointCloud.setupPointCloud(); - material.setAmbient( new Vector3f( 1.0f, 1.0f, 1.0f ) ); - material.setDiffuse( new Vector3f( 1.0f, 1.0f, 1.0f ) ); - material.setSpecular( new Vector3f( 1.0f, 1.0f, 1.0f ) ); - pointCloud.setMaterial( material ); - pointCloud.setPosition( new Vector3f( 0f, 0f, 0f ) ); - - return addNode( pointCloud ); + val pointCloud = PointCloud(defaultPointSize, name!!) + val material = Material() + val vBuffer: FloatBuffer = BufferUtils.allocateFloat(flatVerts.size * 4) + val nBuffer: FloatBuffer = BufferUtils.allocateFloat(0) + vBuffer.put(flatVerts) + vBuffer.flip() + pointCloud.vertices = vBuffer + pointCloud.normals = nBuffer + pointCloud.indices = BufferUtils.allocateInt(0) + pointCloud.setupPointCloud() + material.ambient = Vector3f(1.0f, 1.0f, 1.0f) + material.diffuse = Vector3f(1.0f, 1.0f, 1.0f) + material.specular = Vector3f(1.0f, 1.0f, 1.0f) + pointCloud.material = material + pointCloud.position = Vector3f(0f, 0f, 0f) + return addNode(pointCloud) } /** @@ -1422,23 +1226,13 @@ public class SciView extends SceneryBase implements CalibratedRealInterval (sciView.find(n.getName()) == null), 20); + @JvmOverloads + fun addNode(n: Node, activePublish: Boolean = true): Node { + scene.addChild(n) + objectService?.addObject(n) + if (blockOnNewNodes) { + blockWhile({ sciView: SciView -> sciView.find(n.name) == null }, 20) //System.out.println("find(name) " + find(n.getName()) ); } - - if( activePublish ) { + if (activePublish) { // Set new node as active and center - if( getCenterOnNewNodes() ) { - setActiveNode(n); - centerOnNode(n); + if (centerOnNewNodes) { + setActiveNode(n) + centerOnNode(n) } - - eventService.publish(new NodeAddedEvent(n)); + eventService!!.publish(NodeAddedEvent(n)) } - return n; + return n } /** @@ -1474,18 +1265,15 @@ public class SciView extends SceneryBase implements CalibratedRealInterval new Vector3f( 0, 0, 0 ) : () -> n.getMaximumBoundingBox().getBoundingSphere().getOrigin()); - eventService.publish( new NodeActivatedEvent( activeNode ) ); - - return activeNode; + fun setActiveNode(n: Node?): Node? { + if (activeNode === n) return activeNode + activeNode = n + targetArcball!!.target = { n?.getMaximumBoundingBox()?.getBoundingSphere()?.origin ?: Vector3f(0.0f, 0.0f, 0.0f) } + eventService!!.publish(NodeActivatedEvent(activeNode)) + return activeNode } @EventHandler - protected void onNodeAdded(NodeAddedEvent event) { - nodePropertyEditor.rebuildTree(); + protected fun onNodeAdded(event: NodeAddedEvent?) { + nodePropertyEditor!!.rebuildTree() } @EventHandler - protected void onNodeRemoved(NodeRemovedEvent event) { - nodePropertyEditor.rebuildTree(); + protected fun onNodeRemoved(event: NodeRemovedEvent?) { + nodePropertyEditor!!.rebuildTree() } @EventHandler - protected void onNodeChanged(NodeChangedEvent event) { - nodePropertyEditor.rebuildTree(); + protected fun onNodeChanged(event: NodeChangedEvent?) { + nodePropertyEditor!!.rebuildTree() } @EventHandler - protected void onNodeActivated(NodeActivatedEvent event) { + protected fun onNodeActivated(event: NodeActivatedEvent?) { // TODO: add listener code for node activation, if necessary // NOTE: do not update property window here, this will lead to a loop. } - public void toggleInspectorWindow() - { - toggleSidebar(); + fun toggleInspectorWindow() { + toggleSidebar() } - public void setInspectorWindowVisibility(boolean visible) - { + fun setInspectorWindowVisibility(visible: Boolean) { // inspector.setVisible(visible); // if( visible ) // mainSplitPane.setDividerLocation(getWindowWidth()/4 * 3); @@ -1564,8 +1341,7 @@ public class SciView extends SceneryBase implements CalibratedRealInterval animate(int fps, Runnable action ) { + @Synchronized + fun animate(fps: Int, action: Runnable): Future<*> { // TODO: Make animation speed less laggy and more accurate. - final int delay = 1000 / fps; - Future thread = threadService.run(() -> { + val delay = 1000 / fps + val thread = threadService!!.run { while (animating) { - action.run(); + action.run() try { - Thread.sleep(delay); - } catch (InterruptedException e) { - break; + Thread.sleep(delay.toLong()) + } catch (e: InterruptedException) { + break } } - }); - animations.add( thread ); - animating = true; - return thread; + } + animations!!.add(thread) + animating = true + return thread } /** * Stop all animations */ - public synchronized void stopAnimation() { - animating = false; - while( !animations.isEmpty() ) { - animations.peek().cancel( true ); - animations.remove(); + @Synchronized + fun stopAnimation() { + animating = false + while (!animations!!.isEmpty()) { + animations!!.peek().cancel(true) + animations!!.remove() } } /** * Take a screenshot and save it to the default scenery location */ - public void takeScreenshot() { - getRenderer().screenshot(); + fun takeScreenshot() { + renderer!!.screenshot() } /** * Take a screenshot and save it to the specified path * @param path path for saving the screenshot */ - public void takeScreenshot( String path ) { - getRenderer().screenshot( path, false ); + fun takeScreenshot(path: String?) { + renderer!!.screenshot(path!!, false) } /** * Take a screenshot and return it as an Img * @return an Img of type UnsignedByteType */ - public Img getScreenshot() { - RenderedImage screenshot = getSceneryRenderer().requestScreenshot(); - - BufferedImage image = new BufferedImage(screenshot.getWidth(), screenshot.getHeight(), BufferedImage.TYPE_4BYTE_ABGR); - byte[] imgData = ((DataBufferByte) image.getRaster().getDataBuffer()).getData(); - System.arraycopy(screenshot.getData(), 0, imgData, 0, screenshot.getData().length); - - Img img = null; - File tmpFile = null; - try { - tmpFile = File.createTempFile("sciview-", "-tmp.png"); - ImageIO.write(image, "png", tmpFile); - img = (Img)io.open(tmpFile.getAbsolutePath()); - tmpFile.delete(); - } catch (IOException e) { - e.printStackTrace(); + val screenshot: Img? + get() { + val screenshot = getSceneryRenderer()!!.requestScreenshot() + val image = BufferedImage(screenshot.width, screenshot.height, BufferedImage.TYPE_4BYTE_ABGR) + val imgData = (image.raster.dataBuffer as DataBufferByte).data + System.arraycopy(screenshot.data, 0, imgData, 0, screenshot.data!!.size) + var img: Img? = null + var tmpFile: File? = null + try { + tmpFile = File.createTempFile("sciview-", "-tmp.png") + ImageIO.write(image, "png", tmpFile) + img = io!!.open(tmpFile.absolutePath) as Img + tmpFile.delete() + } catch (e: IOException) { + e.printStackTrace() + } + return img } - return img; - } /** * Take a screenshot and return it as an Img * @return an Img of type UnsignedByteType */ - public Img getARGBScreenshot() { - Img screenshot = getScreenshot(); - - return Utils.convertToARGB(screenshot); - } + val aRGBScreenshot: Img + get() { + val screenshot = screenshot + return Utils.convertToARGB(screenshot) + } /** * @param name The name of the node to find. * @return the node object or null, if the node has not been found. */ - public Node find(final String name) { - final Node n = getScene().find(name); - - if(n == null) { - getLogger().warn("Node with name " + name + " not found."); + fun find(name: String): Node? { + val n = scene.find(name) + if (n == null) { + logger.warn("Node with name $name not found.") } - - return n; + return n } /** * @return an array of all nodes in the scene except Cameras and PointLights */ - public Node[] getSceneNodes() { - return getSceneNodes( n -> !( n instanceof Camera ) && !( n instanceof PointLight ) ); - } + val sceneNodes: Array + get() = getSceneNodes { n: Node? -> n !is Camera && n !is PointLight } /** * Get a list of nodes filtered by filter predicate * @param filter, a predicate that filters the candidate nodes * @return all nodes that match the predicate */ - public Node[] getSceneNodes( Predicate filter ) { - return getScene().getChildren().stream().filter( filter ).toArray( Node[]::new ); + fun getSceneNodes(filter: Predicate): Array { + return scene.children.filter{ filter.test(it) }.toTypedArray() } /** * @return an array of all Node's in the scene */ - public Node[] getAllSceneNodes() { - return getSceneNodes( n -> true ); - } + val allSceneNodes: Array + get() = getSceneNodes { n: Node? -> true } /** * Delete the current active node */ - public void deleteActiveNode() { - deleteNode( getActiveNode() ); + fun deleteActiveNode() { + deleteNode(activeNode) } - /** - * Delete the specified node, this event is published + * Delete a specified node and control whether the event is published * @param node node to delete from scene + * @param activePublish whether the deletion should be published */ - public void deleteNode( Node node ) { - deleteNode( node, true ); - } - /** - * Delete a specified node and control whether the event is published + * Delete the specified node, this event is published * @param node node to delete from scene - * @param activePublish whether the deletion should be published */ - public void deleteNode( Node node, boolean activePublish ) { - for( Node child : node.getChildren() ) { - deleteNode(child, activePublish); + @JvmOverloads + fun deleteNode(node: Node?, activePublish: Boolean = true) { + for (child in node!!.children) { + deleteNode(child, activePublish) } - - objectService.removeObject(node); - node.getParent().removeChild( node ); - if( activePublish ) { - eventService.publish(new NodeRemovedEvent(node)); - if (activeNode == node) setActiveNode(null); + objectService?.removeObject(node) + node.parent!!.removeChild(node) + if (activePublish) { + eventService!!.publish(NodeRemovedEvent(node)) + if (activeNode === node) setActiveNode(null) } } /** * Dispose the current scenery renderer, hub, and other scenery things */ - public void dispose() { - List objs = objectService.getObjects(Node.class); - for( Node obj : objs ) { - objectService.removeObject(obj); + fun dispose() { + val objs: List = objectService!!.getObjects(Node::class.java) + for (obj in objs) { + objectService?.removeObject(obj) } - getScijavaContext().service(SciViewService.class).close(this); - this.close(); + scijavaContext!!.service(SciViewService::class.java).close(this) + close() } - - public void close() { - super.close(); - - frame.dispose(); + override fun close() { + super.close() + frame!!.dispose() } /** * Move the current active camera to the specified position * @param position position to move the camera to */ - public void moveCamera( float[] position ) { - getCamera().setPosition( new Vector3f( position[0], position[1], position[2] ) ); + fun moveCamera(position: FloatArray) { + camera!!.position = Vector3f(position[0], position[1], position[2]) } /** * Move the current active camera to the specified position * @param position position to move the camera to */ - public void moveCamera( double[] position ) { - getCamera().setPosition( new Vector3f( ( float ) position[0], ( float ) position[1], ( float ) position[2] ) ); + fun moveCamera(position: DoubleArray) { + camera!!.position = Vector3f(position[0].toFloat(), position[1].toFloat(), position[2].toFloat()) } /** * Get the current application name * @return a String of the application name */ - public String getName() { - return getApplicationName(); + fun getName(): String { + return applicationName } /** * Add a child to the scene. you probably want addNode * @param node node to add as a child to the scene */ - public void addChild( Node node ) { - getScene().addChild( node ); + fun addChild(node: Node?) { + scene.addChild(node!!) } /** @@ -1784,18 +1549,13 @@ public class SciView extends SceneryBase implements CalibratedRealInterval>(image.imgPlus as RandomAccessibleInterval>, image.name, + *voxelDimensions) } - /** - * Add a RandomAccessibleInterval to the image - * @param image image to add as a volume - * @param name name of image - * @param extra, kludge argument to prevent matching issues - * @param pixel type of image - * @return a Node corresponding to the volume - */ - public > Node addVolume( RandomAccessibleInterval image, String name, String extra ) { - return addVolume( image, name, 1, 1, 1 ); - } +// /** +// * Add a RandomAccessibleInterval to the image +// * @param image image to add as a volume +// * @param name name of image +// * @param extra, kludge argument to prevent matching issues +// * @param pixel type of image +// * @return a Node corresponding to the volume +// */ +// fun ?> addVolume(image: RandomAccessibleInterval, name: String?, extra: String?): Node { +// return addVolume(image, name, 1f, 1f, 1f) +// } /** * Add a RandomAccessibleInterval to the image * @param image image to add as a volume * @param pixel type of image * @return a Node corresponding to the volume - */ - public > Node addVolume(RandomAccessibleInterval image, String name) { - return addVolume(image, name, 1f, 1f, 1f); + */ + fun > addVolume(image: RandomAccessibleInterval, name: String?): Node { + return addVolume(image, name, 1f, 1f, 1f) } /** @@ -1836,11 +1596,10 @@ public class SciView extends SceneryBase implements CalibratedRealInterval pixel type of image * @return a Node corresponding to the volume - */ - public > Node addVolume( RandomAccessibleInterval image, float[] voxelDimensions ) { - long[] pos = new long[]{10, 10, 10}; - - return addVolume( image, "volume", voxelDimensions ); + */ + fun > addVolume(image: RandomAccessibleInterval, voxelDimensions: FloatArray): Node { + val pos = longArrayOf(10, 10, 10) + return addVolume(image, "volume", *voxelDimensions) } /** @@ -1848,12 +1607,13 @@ public class SciView extends SceneryBase implements CalibratedRealInterval * @return a Node corresponding to the Volume - */ - public > Node addVolume( IterableInterval image ) throws Exception { - if( image instanceof RandomAccessibleInterval ) { - return addVolume((RandomAccessibleInterval) image, "Volume"); + */ + @Throws(Exception::class) + fun ?> addVolume(image: IterableInterval): Node { + return if (image is RandomAccessibleInterval<*>) { + addVolume(image as RandomAccessibleInterval>, "Volume") } else { - throw new Exception("Unsupported Volume type:" + image); + throw Exception("Unsupported Volume type:$image") } } @@ -1863,12 +1623,13 @@ public class SciView extends SceneryBase implements CalibratedRealInterval pixel type of image * @return a Node corresponding to the Volume - */ - public > Node addVolume( IterableInterval image, String name ) throws Exception { - if( image instanceof RandomAccessibleInterval ) { - return addVolume( (RandomAccessibleInterval) image, name, 1, 1, 1 ); + */ + @Throws(Exception::class) + fun ?> addVolume(image: IterableInterval, name: String?): Node { + return if (image is RandomAccessibleInterval<*>) { + addVolume(image as RandomAccessibleInterval>, name, 1f, 1f, 1f) } else { - throw new Exception("Unsupported Volume type:" + image); + throw Exception("Unsupported Volume type:$image") } } @@ -1877,11 +1638,11 @@ public class SciView extends SceneryBase implements CalibratedRealInterval Type of the dataset. * @return THe node corresponding to the volume just added. - */ - public > Node addVolume(SourceAndConverter sac, - int numTimepoints, - String name, - float... voxelDimensions ) { - List> sources = new ArrayList<>(); - sources.add(sac); - - return addVolume(sources, numTimepoints, name, voxelDimensions); + */ + fun > addVolume(sac: SourceAndConverter, + numTimepoints: Int, + name: String?, + vararg voxelDimensions: Float): Node { + val sources: MutableList> = ArrayList() + sources.add(sac) + return addVolume(sources, numTimepoints, name, *voxelDimensions) } /** @@ -1950,47 +1703,40 @@ public class SciView extends SceneryBase implements CalibratedRealInterval pixel type of image * @return a Node corresponding to the Volume - */ - public > Node addVolume( RandomAccessibleInterval image, String name, - float... voxelDimensions ) { + */ + fun > addVolume(image: RandomAccessibleInterval, name: String?, + vararg voxelDimensions: Float): Node { //log.debug( "Add Volume " + name + " image: " + image ); - - long[] dimensions = new long[image.numDimensions()]; - image.dimensions( dimensions ); - - long[] minPt = new long[image.numDimensions()]; + val dimensions = LongArray(image.numDimensions()) + image.dimensions(dimensions) + val minPt = LongArray(image.numDimensions()) // Get type at min point - RandomAccess imageRA = image.randomAccess(); - image.min(minPt); - imageRA.setPosition(minPt); - T voxelType = imageRA.get().createVariable(); - - ArrayList converterSetups = new ArrayList(); - ArrayList> stacks = AxisOrder.splitInputStackIntoSourceStacks(image, AxisOrder.getAxisOrder(AxisOrder.DEFAULT, image, false)); - AffineTransform3D sourceTransform = new AffineTransform3D(); - ArrayList> sources = new ArrayList(); - - int numTimepoints = 1; - for (RandomAccessibleInterval stack : stacks) { - Source s; + val imageRA = image.randomAccess() + image.min(minPt) + imageRA.setPosition(minPt) + val voxelType = imageRA.get()!!.createVariable() + val converterSetups: ArrayList = ArrayList() + val stacks = AxisOrder.splitInputStackIntoSourceStacks(image, AxisOrder.getAxisOrder(AxisOrder.DEFAULT, image, false)) + val sourceTransform = AffineTransform3D() + val sources: ArrayList> = ArrayList>() + var numTimepoints = 1 + for (stack in stacks) { + var s: Source if (stack.numDimensions() > 3) { - numTimepoints = (int) (stack.max(3) + 1); - s = new RandomAccessibleIntervalSource4D(stack, voxelType, sourceTransform, name); + numTimepoints = (stack.max(3) + 1).toInt() + s = RandomAccessibleIntervalSource4D(stack, voxelType, sourceTransform, name) } else { - s = new RandomAccessibleIntervalSource(stack, voxelType, sourceTransform, name); + s = RandomAccessibleIntervalSource(stack, voxelType, sourceTransform, name) } - SourceAndConverter source = BigDataViewer.wrapWithTransformedSource( - new SourceAndConverter(s, BigDataViewer.createConverterToARGB(voxelType))); - converterSetups.add(BigDataViewer.createConverterSetup(source, Volume.Companion.getSetupId().getAndIncrement())); - sources.add(source); + val source = BigDataViewer.wrapWithTransformedSource( + SourceAndConverter(s, BigDataViewer.createConverterToARGB(voxelType))) + converterSetups.add(BigDataViewer.createConverterSetup(source, setupId.getAndIncrement())) + sources.add(source) } - - Node v = addVolume(sources, numTimepoints, name, voxelDimensions); - - v.getMetadata().put("RandomAccessibleInterval", image); - - return v; + val v = addVolume(sources, numTimepoints, name, *voxelDimensions) + v.metadata["RandomAccessibleInterval"] = image + return v } /** @@ -2003,63 +1749,53 @@ public class SciView extends SceneryBase implements CalibratedRealInterval Type of the dataset. * @return THe node corresponding to the volume just added. - */ - public > Node addVolume(List> sources, - ArrayList converterSetups, - int numTimepoints, - String name, - float... voxelDimensions ) { - - CacheControl cacheControl = null; + */ + fun ?> addVolume(sources: List>>, + converterSetups: ArrayList?, + numTimepoints: Int, + name: String?, + vararg voxelDimensions: Float): Node { + var numTimepoints = numTimepoints + var cacheControl: CacheControl? = null // RandomAccessibleInterval image = // ((RandomAccessibleIntervalSource4D) sources.get(0).getSpimSource()). // .getSource(0, 0); - RandomAccessibleInterval image = sources.get(0).getSpimSource().getSource(0, 0); - - if (image instanceof VolatileView) { - VolatileViewData> viewData = ((VolatileView>) image).getVolatileViewData(); - cacheControl = viewData.getCacheControl(); + val image = sources[0]!!.spimSource.getSource(0, 0) + if (image is VolatileView<*, *>) { + val viewData = (image as VolatileView?>).volatileViewData + cacheControl = viewData.cacheControl } - - long[] dimensions = new long[image.numDimensions()]; - image.dimensions( dimensions ); - - long[] minPt = new long[image.numDimensions()]; + val dimensions = LongArray(image.numDimensions()) + image.dimensions(dimensions) + val minPt = LongArray(image.numDimensions()) // Get type at min point - RandomAccess imageRA = image.randomAccess(); - image.min(minPt); - imageRA.setPosition(minPt); - T voxelType = imageRA.get().createVariable(); - - System.out.println("addVolume " + image.numDimensions() + " interval " + ((Interval) image) ); + val imageRA = image.randomAccess() + image.min(minPt) + imageRA.setPosition(minPt) + val voxelType = imageRA.get()!!.createVariable() as RealType<*> + println("addVolume " + image.numDimensions() + " interval " + image as Interval) //int numTimepoints = 1; - if( image.numDimensions() > 3 ) { - numTimepoints = (int) image.dimension(3); + if (image.numDimensions() > 3) { + numTimepoints = image.dimension(3).toInt() } - - Volume.VolumeDataSource.RAISource ds = new Volume.VolumeDataSource.RAISource(voxelType, sources, converterSetups, numTimepoints, cacheControl); - VolumeViewerOptions options = new VolumeViewerOptions(); - - Volume v = new RAIVolume(ds, options, getHub()); - v.setName(name); - - v.getMetadata().put("sources", sources); - - TransferFunction tf = v.getTransferFunction(); - float rampMin = 0f; - float rampMax = 0.1f; - tf.clear(); - tf.addControlPoint(0.0f, 0.0f); - tf.addControlPoint(rampMin, 0.0f); - tf.addControlPoint(1.0f, rampMax); - - BoundingGrid bg = new BoundingGrid(); - bg.setNode(v); - - return addNode(v); + val ds = RAISource(voxelType, sources, converterSetups!!, numTimepoints, cacheControl) + val options = VolumeViewerOptions() + val v: Volume = RAIVolume(ds, options, hub) + v.name = name!! + v.metadata["sources"] = sources + val tf = v.transferFunction + val rampMin = 0f + val rampMax = 0.1f + tf.clear() + tf.addControlPoint(0.0f, 0.0f) + tf.addControlPoint(rampMin, 0.0f) + tf.addControlPoint(1.0f, rampMax) + val bg = BoundingGrid() + bg.node = v + return addNode(v) } /** @@ -2068,12 +1804,12 @@ public class SciView extends SceneryBase implements CalibratedRealInterval predicate, int waitTime) { - while( predicate.apply(this) ) { + private fun blockWhile(predicate: Function, waitTime: Int) { + while (predicate.apply(this)) { try { - Thread.sleep(waitTime); - } catch (InterruptedException e) { - e.printStackTrace(); + Thread.sleep(waitTime.toLong()) + } catch (e: InterruptedException) { + e.printStackTrace() } } } @@ -2086,18 +1822,17 @@ public class SciView extends SceneryBase implements CalibratedRealInterval Type of the dataset. * @return THe node corresponding to the volume just added. - */ - public > Node addVolume(List> sources, - int numTimepoints, - String name, - float... voxelDimensions ) { - int setupId = 0; - ArrayList converterSetups = new ArrayList<>(); - for( SourceAndConverter source: sources ) { - converterSetups.add(BigDataViewer.createConverterSetup(source, setupId++)); + */ + fun > addVolume(sources: List>, + numTimepoints: Int, + name: String?, + vararg voxelDimensions: Float): Node { + var setupId = 0 + val converterSetups = ArrayList() + for (source in sources) { + converterSetups.add(BigDataViewer.createConverterSetup(source, setupId++)) } - - return addVolume(sources, converterSetups, numTimepoints, name, voxelDimensions); + return addVolume(sources, converterSetups, numTimepoints, name, *voxelDimensions) } /** @@ -2109,37 +1844,33 @@ public class SciView extends SceneryBase implements CalibratedRealInterval pixel type of image * @return a Node corresponding to the input volume - */ - public > Node updateVolume( IterableInterval image, String name, - float[] voxelDimensions, Volume v ) { - List> sacs = (List>) v.getMetadata().get("sources"); - - RandomAccessibleInterval source = sacs.get(0).getSpimSource().getSource(0, 0);// hard coded to timepoint and mipmap 0 - - Cursor sCur = Views.iterable(source).cursor(); - Cursor iCur = image.cursor(); - while( sCur.hasNext() ) { - sCur.fwd(); - iCur.fwd(); - sCur.get().set(iCur.get()); + */ + fun ?> updateVolume(image: IterableInterval, name: String?, + voxelDimensions: FloatArray?, v: Volume): Node { + val sacs = v.metadata["sources"] as List>? + val source = sacs!![0].spimSource.getSource(0, 0) // hard coded to timepoint and mipmap 0 + val sCur = Views.iterable(source).cursor() + val iCur = image.cursor() + while (sCur.hasNext()) { + sCur.fwd() + iCur.fwd() + sCur.get()!!.set(iCur.get()) } - - v.getVolumeManager().notifyUpdate(v); - v.getVolumeManager().requestRepaint(); + v.volumeManager.notifyUpdate(v) + v.volumeManager.requestRepaint() //v.getCacheControls().clear(); //v.setDirty( true ); - v.setNeedsUpdate( true ); + v.needsUpdate = true //v.setNeedsUpdateWorld( true ); - - return v; + return v } /** * * @return whether PushMode is currently active */ - public boolean getPushMode() { - return getRenderer().getPushMode(); + fun getPushMode(): Boolean { + return renderer!!.pushMode } /** @@ -2147,99 +1878,72 @@ public class SciView extends SceneryBase implements CalibratedRealInterval) { + axes = calibratedAxes } - @Override - public void setAxis(CalibratedAxis calibratedAxis, int i) { - axes[i] = calibratedAxis; + override fun setAxis(calibratedAxis: CalibratedAxis, i: Int) { + axes[i] = calibratedAxis } - @Override - public double realMin(int i) { - return Double.NEGATIVE_INFINITY; + override fun realMin(i: Int): Double { + return Double.NEGATIVE_INFINITY } - @Override - public void realMin(double[] doubles) { - for( int i = 0; i < doubles.length; i++ ) { - doubles[i] = Double.NEGATIVE_INFINITY; + override fun realMin(doubles: DoubleArray) { + for (i in doubles.indices) { + doubles[i] = Double.NEGATIVE_INFINITY } } - @Override - public void realMin(RealPositionable realPositionable) { - for( int i = 0; i < realPositionable.numDimensions(); i++ ) { - realPositionable.move(Double.NEGATIVE_INFINITY, i); + override fun realMin(realPositionable: RealPositionable) { + for (i in 0 until realPositionable.numDimensions()) { + realPositionable.move(Double.NEGATIVE_INFINITY, i) } } - @Override - public double realMax(int i) { - return Double.POSITIVE_INFINITY; + override fun realMax(i: Int): Double { + return Double.POSITIVE_INFINITY } - @Override - public void realMax(double[] doubles) { - for( int i = 0; i < doubles.length; i++ ) { - doubles[i] = Double.POSITIVE_INFINITY; + override fun realMax(doubles: DoubleArray) { + for (i in doubles.indices) { + doubles[i] = Double.POSITIVE_INFINITY } } - @Override - public void realMax(RealPositionable realPositionable) { - for( int i = 0; i < realPositionable.numDimensions(); i++ ) { - realPositionable.move(Double.POSITIVE_INFINITY, i); + override fun realMax(realPositionable: RealPositionable) { + for (i in 0 until realPositionable.numDimensions()) { + realPositionable.move(Double.POSITIVE_INFINITY, i) } } - @Override - public int numDimensions() { - return axes.length; + override fun numDimensions(): Int { + return axes.size } - public void setCamera(Camera camera) { - this.camera = camera; - setActiveObserver(camera); + fun setActiveObserver(screenshotCam: Camera?) { + scene.activeObserver = screenshotCam } - public void setActiveObserver(Camera screenshotCam) { - getScene().setActiveObserver(screenshotCam); + fun getActiveObserver(): Camera? { + return scene.activeObserver } - public Camera getActiveObserver() { - return getScene().getActiveObserver(); - } - - public void setCenterOnNewNodes(boolean centerOnNewNodes) { - this.centerOnNewNodes = centerOnNewNodes; - } - - public boolean getCenterOnNewNodes() { - return centerOnNewNodes; - } - - public void setBlockOnNewNodes(boolean blockOnNewNodes) { - this.blockOnNewNodes = blockOnNewNodes; - } - - public boolean getBlockOnNewNodes() { - return blockOnNewNodes; - } - - public class TransparentSlider extends JSlider { + inner class TransparentSlider : JSlider() { + override fun paintComponent(g: Graphics) { + val g2d = g.create() as Graphics2D + g2d.color = background + g2d.composite = AlphaComposite.SrcOver.derive(0.9f) + g2d.fillRect(0, 0, width, height) + g2d.dispose() + super.paintComponent(g) + } - public TransparentSlider() { + init { // Important, we taking over the filling of the // component... - setOpaque(false); - setBackground(Color.DARK_GRAY); - setForeground(Color.LIGHT_GRAY); - } - - @Override - protected void paintComponent(Graphics g) { - Graphics2D g2d = (Graphics2D) g.create(); - g2d.setColor(getBackground()); - g2d.setComposite(AlphaComposite.SrcOver.derive(0.9f)); - g2d.fillRect(0, 0, getWidth(), getHeight()); - g2d.dispose(); - - super.paintComponent(g); + isOpaque = false + background = Color.DARK_GRAY + foreground = Color.LIGHT_GRAY } - } - class enableIncrease implements ClickBehaviour { - - @Override public void click( int x, int y ) { - setFPSSpeed( getFPSSpeed() + 0.5f ); - setMouseSpeed( getMouseSpeed() + 0.05f ); + internal inner class enableIncrease : ClickBehaviour { + override fun click(x: Int, y: Int) { + fPSSpeed = fPSSpeed + 0.5f + mouseSpeed = mouseSpeed + 0.05f //log.debug( "Increasing FPS scroll Speed" ); - - resetFPSInputs(); + resetFPSInputs() } } - class enableDecrease implements ClickBehaviour { - - @Override public void click( int x, int y ) { - setFPSSpeed( getFPSSpeed() - 0.1f ); - setMouseSpeed( getMouseSpeed() - 0.05f ); + internal inner class enableDecrease : ClickBehaviour { + override fun click(x: Int, y: Int) { + fPSSpeed = fPSSpeed - 0.1f + mouseSpeed = mouseSpeed - 0.05f //log.debug( "Decreasing FPS scroll Speed" ); - - resetFPSInputs(); + resetFPSInputs() } } - class showHelpDisplay implements ClickBehaviour { - - @Override public void click( int x, int y ) { - StringBuilder helpString = new StringBuilder("SciView help:\n\n"); - for( InputTrigger trigger : getInputHandler().getAllBindings().keySet() ) { - helpString.append(trigger).append("\t-\t").append(getInputHandler().getAllBindings().get(trigger)).append("\n"); + internal inner class showHelpDisplay : ClickBehaviour { + override fun click(x: Int, y: Int) { + val helpString = StringBuilder("SciView help:\n\n") + for (trigger in inputHandler!!.getAllBindings().keys) { + helpString.append(trigger).append("\t-\t").append(inputHandler!!.getAllBindings()[trigger]).append("\n") } // HACK: Make the console pop via stderr. // Later, we will use a nicer dialog box or some such. - log.warn(helpString.toString()); + log!!.warn(helpString.toString()) } } @@ -2425,50 +2089,63 @@ public class SciView extends SceneryBase implements CalibratedRealInterval findNodes(Function1 nodeMatchPredicate) { - return getScene().discover(getScene(), nodeMatchPredicate, false); + fun findNodes(nodeMatchPredicate: Function1): List { + return scene.discover(scene, nodeMatchPredicate, false) } /* * Convenience function for getting a string of info about a Node */ - public String nodeInfoString(Node n) { - return "Node name: " + n.getName() + " Node type: " + n.getNodeType() + " To String: " + n; + fun nodeInfoString(n: Node): String { + return "Node name: " + n.name + " Node type: " + n.nodeType + " To String: " + n } - /** - * Static launching method - * - * @return a newly created SciView - */ - public static SciView create() throws Exception { - SceneryBase.xinitThreads(); + companion object { + @JvmField + val DEFAULT_COLOR = Colors.LIGHTGRAY - FlatLightLaf.install(); - try { - UIManager.setLookAndFeel( new FlatLightLaf() ); - } catch( Exception ex ) { - System.err.println( "Failed to initialize Flat Light LaF, falling back to Swing default." ); + /** + * Utility function to generate GLVector in cases like usage from Python + * @param x x coord + * @param y y coord + * @param z z coord + * @return a GLVector of x,y,z + */ + fun getGLVector(x: Float, y: Float, z: Float): GLVector { + return GLVector(x, y, z) } - System.setProperty( "scijava.log.level:sc.iview", "debug" ); - Context context = new Context( ImageJService.class, SciJavaService.class, SCIFIOService.class, ThreadService.class); - - SciViewService sciViewService = context.service( SciViewService.class ); - SciView sciView = sciViewService.getOrCreateActiveSciView(); - - return sciView; - } + /** + * Static launching method + * + * @return a newly created SciView + */ + @JvmStatic + @Throws(Exception::class) + fun create(): SciView { + xinitThreads() + FlatLightLaf.install() + try { + UIManager.setLookAndFeel(FlatLightLaf()) + } catch (ex: Exception) { + System.err.println("Failed to initialize Flat Light LaF, falling back to Swing default.") + } + System.setProperty("scijava.log.level:sc.iview", "debug") + val context = Context(ImageJService::class.java, SciJavaService::class.java, SCIFIOService::class.java, ThreadService::class.java) + val sciViewService = context.service(SciViewService::class.java) + return sciViewService.orCreateActiveSciView + } - /** - * Static launching method - * [DEPRECATED] use SciView.create() instead - * - * @return a newly created SciView - */ - @Deprecated - public static SciView createSciView() throws Exception { - return create(); + /** + * Static launching method + * [DEPRECATED] use SciView.create() instead + * + * @return a newly created SciView + */ + @Deprecated("") + @Throws(Exception::class) + fun createSciView(): SciView { + return create() + } } - -} +} \ No newline at end of file From 1baa88106dd8cede849d430146150f6677b69fba Mon Sep 17 00:00:00 2001 From: Ulrik Guenther Date: Thu, 12 Nov 2020 17:33:37 +0100 Subject: [PATCH 16/23] SciView: Unstuck generics! --- src/main/java/sc/iview/SciView.kt | 96 +++++++++++++------------------ 1 file changed, 41 insertions(+), 55 deletions(-) diff --git a/src/main/java/sc/iview/SciView.kt b/src/main/java/sc/iview/SciView.kt index f1a79b99..cece4f32 100644 --- a/src/main/java/sc/iview/SciView.kt +++ b/src/main/java/sc/iview/SciView.kt @@ -79,6 +79,7 @@ import net.imglib2.display.ColorTable import net.imglib2.img.Img import net.imglib2.realtransform.AffineTransform3D import net.imglib2.type.numeric.ARGBType +import net.imglib2.type.numeric.NumericType import net.imglib2.type.numeric.RealType import net.imglib2.type.numeric.integer.UnsignedByteType import net.imglib2.view.Views @@ -104,7 +105,6 @@ import org.scijava.ui.swing.menu.SwingJMenuBarCreator import org.scijava.util.ColorRGB import org.scijava.util.Colors import org.scijava.util.VersionUtils -import sc.iview.SciView import sc.iview.commands.view.NodePropertyEditor import sc.iview.controls.behaviours.CameraTranslateControl import sc.iview.controls.behaviours.NodeTranslateControl @@ -189,15 +189,9 @@ class SciView : SceneryBase, CalibratedRealInterval { @Parameter private val io: IOService? = null - @Parameter - private val ops: OpService? = null - @Parameter private val eventService: EventService? = null - @Parameter - private val displayService: DisplayService? = null - @Parameter private val lutService: LUTService? = null @@ -247,7 +241,6 @@ class SciView : SceneryBase, CalibratedRealInterval { private set private var mainSplitPane: JSplitPane? = null private var inspector: JSplitPane? = null - private val interpreterSplitPane: JSplitPane? = null private var interpreterPane: REPLPane? = null private var nodePropertyEditor: NodePropertyEditor? = null var lights: ArrayList? = null @@ -308,8 +301,6 @@ class SciView : SceneryBase, CalibratedRealInterval { * This pops/restores the previously stashed controls. Emits a warning if there are no stashed controls */ fun restoreControls() { - val controlState = controlStack!!.pop() - // This isnt how it should work setObjectSelectionMode() resetFPSInputs() @@ -505,8 +496,6 @@ class SciView : SceneryBase, CalibratedRealInterval { tiREPL.text = "" tp.addTab(tiREPL) tp.addTabMouseListener(object : MouseListener { - private val hidden = false - private val previousPosition = 0 override fun mouseClicked(e: MouseEvent) { if (e.clickCount == 2) { toggleSidebar() @@ -577,7 +566,6 @@ class SciView : SceneryBase, CalibratedRealInterval { if (node === nodePropertyEditor!!.currentNode) { nodePropertyEditor!!.updateProperties(node) } - null } // Enable push rendering by default @@ -606,7 +594,6 @@ class SciView : SceneryBase, CalibratedRealInterval { private fun getScaledImageIcon(resource: URL, width: Int, height: Int): ImageIcon { val first = ImageIcon(resource) - val image = first.image val resizedImg = BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB) val g2 = resizedImg.createGraphics() g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR) @@ -616,8 +603,7 @@ class SciView : SceneryBase, CalibratedRealInterval { } private fun initializeInterpreter() { - var startupCode: String? = "" - startupCode = Scanner(SciView::class.java.getResourceAsStream("startup.py"), "UTF-8").useDelimiter("\\A").next() + val startupCode = Scanner(SciView::class.java.getResourceAsStream("startup.py"), "UTF-8").useDelimiter("\\A").next() interpreterPane!!.repl.interpreter.bindings["sciView"] = this try { interpreterPane!!.repl.interpreter.eval(startupCode) @@ -723,9 +709,9 @@ class SciView : SceneryBase, CalibratedRealInterval { var fPSSpeed: Float get() = fpsScrollSpeed set(newspeed) { - var newspeed = newspeed - if (newspeed < 0.30f) newspeed = 0.3f else if (newspeed > 30.0f) newspeed = 30.0f - fpsScrollSpeed = newspeed + var speed = newspeed + if (newspeed < 0.30f) speed = 0.3f else if (newspeed > 30.0f) speed = 30.0f + fpsScrollSpeed = speed //log.debug( "FPS scroll speed: " + fpsScrollSpeed ); } @@ -733,9 +719,9 @@ class SciView : SceneryBase, CalibratedRealInterval { var mouseSpeed: Float get() = mouseSpeedMult set(newspeed) { - var newspeed = newspeed - if (newspeed < 0.30f) newspeed = 0.3f else if (newspeed > 3.0f) newspeed = 3.0f - mouseSpeedMult = newspeed + var speed = newspeed + if (newspeed < 0.30f) speed = 0.3f else if (newspeed > 3.0f) speed = 3.0f + mouseSpeedMult = speed //log.debug( "Mouse speed: " + mouseSpeedMult ); } @@ -921,21 +907,6 @@ class SciView : SceneryBase, CalibratedRealInterval { * @param inside are normals inside the box? * @return the Node corresponding to the box */ - /** - * Add a box at the specified position and with the specified size - * @param position position to put the box - * @param size size of the box - * @return the Node corresponding to the box - */ - /** - * Add a box at the specific position and unit size - * @param position position to put the box - * @return the Node corresponding to the box - */ - /** - * Add a box to the scene with default parameters - * @return the Node corresponding to the box - */ @JvmOverloads fun addBox(position: Vector3? = JOMLVector3(0.0f, 0.0f, 0.0f), size: Vector3? = JOMLVector3(1.0f, 1.0f, 1.0f), color: ColorRGB? = DEFAULT_COLOR, inside: Boolean = false): Node { @@ -1148,6 +1119,7 @@ class SciView : SceneryBase, CalibratedRealInterval { * @param source string of a data source * @throws IOException */ + @Suppress("UNCHECKED_CAST") @Throws(IOException::class) fun open(source: String) { if (source.endsWith(".xml")) { @@ -1308,21 +1280,25 @@ class SciView : SceneryBase, CalibratedRealInterval { return activeNode } + @Suppress("UNUSED_PARAMETER") @EventHandler protected fun onNodeAdded(event: NodeAddedEvent?) { nodePropertyEditor!!.rebuildTree() } + @Suppress("UNUSED_PARAMETER") @EventHandler protected fun onNodeRemoved(event: NodeRemovedEvent?) { nodePropertyEditor!!.rebuildTree() } + @Suppress("UNUSED_PARAMETER") @EventHandler protected fun onNodeChanged(event: NodeChangedEvent?) { nodePropertyEditor!!.rebuildTree() } + @Suppress("UNUSED_PARAMETER") @EventHandler protected fun onNodeActivated(event: NodeActivatedEvent?) { // TODO: add listener code for node activation, if necessary @@ -1333,6 +1309,7 @@ class SciView : SceneryBase, CalibratedRealInterval { toggleSidebar() } + @Suppress("UNUSED_PARAMETER") fun setInspectorWindowVisibility(visible: Boolean) { // inspector.setVisible(visible); // if( visible ) @@ -1341,6 +1318,7 @@ class SciView : SceneryBase, CalibratedRealInterval { // mainSplitPane.setDividerLocation(getWindowWidth()); } + @Suppress("UNUSED_PARAMETER") fun setInterpreterWindowVisibility(visible: Boolean) { // interpreterPane.getComponent().setVisible(visible); // if( visible ) @@ -1412,10 +1390,10 @@ class SciView : SceneryBase, CalibratedRealInterval { val imgData = (image.raster.dataBuffer as DataBufferByte).data System.arraycopy(screenshot.data, 0, imgData, 0, screenshot.data!!.size) var img: Img? = null - var tmpFile: File? = null try { - tmpFile = File.createTempFile("sciview-", "-tmp.png") + val tmpFile = File.createTempFile("sciview-", "-tmp.png") ImageIO.write(image, "png", tmpFile) + @Suppress("UNCHECKED_CAST") img = io!!.open(tmpFile.absolutePath) as Img tmpFile.delete() } catch (e: IOException) { @@ -1465,7 +1443,7 @@ class SciView : SceneryBase, CalibratedRealInterval { * @return an array of all Node's in the scene */ val allSceneNodes: Array - get() = getSceneNodes { n: Node? -> true } + get() = getSceneNodes { _: Node? -> true } /** * Delete the current active node @@ -1501,7 +1479,7 @@ class SciView : SceneryBase, CalibratedRealInterval { fun dispose() { val objs: List = objectService!!.getObjects(Node::class.java) for (obj in objs) { - objectService?.removeObject(obj) + objectService.removeObject(obj) } scijavaContext!!.service(SciViewService::class.java).close(this) close() @@ -1564,6 +1542,7 @@ class SciView : SceneryBase, CalibratedRealInterval { * @param voxelDimensions dimensions of voxels in volume * @return a Node corresponding to the Volume */ + @Suppress("UNCHECKED_CAST") fun addVolume(image: Dataset, voxelDimensions: FloatArray): Node { return addVolume>(image.imgPlus as RandomAccessibleInterval>, image.name, *voxelDimensions) @@ -1598,7 +1577,6 @@ class SciView : SceneryBase, CalibratedRealInterval { * @return a Node corresponding to the volume */ fun > addVolume(image: RandomAccessibleInterval, voxelDimensions: FloatArray): Node { - val pos = longArrayOf(10, 10, 10) return addVolume(image, "volume", *voxelDimensions) } @@ -1608,6 +1586,7 @@ class SciView : SceneryBase, CalibratedRealInterval { * @param * @return a Node corresponding to the Volume */ + @Suppress("UNCHECKED_CAST") @Throws(Exception::class) fun ?> addVolume(image: IterableInterval): Node { return if (image is RandomAccessibleInterval<*>) { @@ -1624,6 +1603,7 @@ class SciView : SceneryBase, CalibratedRealInterval { * @param pixel type of image * @return a Node corresponding to the Volume */ + @Suppress("UNCHECKED_CAST") @Throws(Exception::class) fun ?> addVolume(image: IterableInterval, name: String?): Node { return if (image is RandomAccessibleInterval<*>) { @@ -1750,18 +1730,19 @@ class SciView : SceneryBase, CalibratedRealInterval { * @param Type of the dataset. * @return THe node corresponding to the volume just added. */ - fun ?> addVolume(sources: List>>, - converterSetups: ArrayList?, - numTimepoints: Int, - name: String?, - vararg voxelDimensions: Float): Node { - var numTimepoints = numTimepoints + @Suppress("UNCHECKED_CAST") + fun > addVolume(sources: List>, + converterSetups: ArrayList?, + numTimepoints: Int, + name: String?, + vararg voxelDimensions: Float): Node { + var timepoints = numTimepoints var cacheControl: CacheControl? = null // RandomAccessibleInterval image = // ((RandomAccessibleIntervalSource4D) sources.get(0).getSpimSource()). // .getSource(0, 0); - val image = sources[0]!!.spimSource.getSource(0, 0) + val image = sources[0].spimSource.getSource(0, 0) if (image is VolatileView<*, *>) { val viewData = (image as VolatileView?>).volatileViewData cacheControl = viewData.cacheControl @@ -1774,18 +1755,19 @@ class SciView : SceneryBase, CalibratedRealInterval { val imageRA = image.randomAccess() image.min(minPt) imageRA.setPosition(minPt) - val voxelType = imageRA.get()!!.createVariable() as RealType<*> + val voxelType = imageRA.get()!!.createVariable() as T println("addVolume " + image.numDimensions() + " interval " + image as Interval) //int numTimepoints = 1; if (image.numDimensions() > 3) { - numTimepoints = image.dimension(3).toInt() + timepoints = image.dimension(3).toInt() } - val ds = RAISource(voxelType, sources, converterSetups!!, numTimepoints, cacheControl) + val ds = RAISource(voxelType, sources, converterSetups!!, timepoints, cacheControl) val options = VolumeViewerOptions() val v: Volume = RAIVolume(ds, options, hub) v.name = name!! v.metadata["sources"] = sources + v.metadata["VoxelDimensions"] = voxelDimensions val tf = v.transferFunction val rampMin = 0f val rampMax = 0.1f @@ -1845,8 +1827,9 @@ class SciView : SceneryBase, CalibratedRealInterval { * @param pixel type of image * @return a Node corresponding to the input volume */ - fun ?> updateVolume(image: IterableInterval, name: String?, - voxelDimensions: FloatArray?, v: Volume): Node { + @Suppress("UNCHECKED_CAST") + fun > updateVolume(image: IterableInterval, name: String, + voxelDimensions: FloatArray, v: Volume): Node { val sacs = v.metadata["sources"] as List>? val source = sacs!![0].spimSource.getSource(0, 0) // hard coded to timepoint and mipmap 0 val sCur = Views.iterable(source).cursor() @@ -1856,6 +1839,8 @@ class SciView : SceneryBase, CalibratedRealInterval { iCur.fwd() sCur.get()!!.set(iCur.get()) } + v.name = name + v.metadata["VoxelDimensions"] = voxelDimensions v.volumeManager.notifyUpdate(v) v.volumeManager.requestRepaint() //v.getCacheControls().clear(); @@ -1962,6 +1947,7 @@ class SciView : SceneryBase, CalibratedRealInterval { n.scale = Vector3f(x, y, z) } + @Suppress("UNUSED_PARAMETER") fun setColor(n: Node, x: Float, y: Float, z: Float, w: Float) { val col = Vector3f(x, y, z) n.material.ambient = col @@ -2138,7 +2124,7 @@ class SciView : SceneryBase, CalibratedRealInterval { /** * Static launching method - * [DEPRECATED] use SciView.create() instead + * DEPRECATED use SciView.create() instead * * @return a newly created SciView */ From 3d5cf1c437c7c4739582cb3b53dcb38b332da058 Mon Sep 17 00:00:00 2001 From: Ulrik Guenther Date: Thu, 12 Nov 2020 17:34:02 +0100 Subject: [PATCH 17/23] Clean up Kotlin code to make warning-free --- pom.xml | 2 +- .../iview/commands/demo/VolumeRenderDemo.kt | 2 +- .../commands/view/ResetCameraPosition.kt | 2 +- .../commands/view/ResetCameraRotation.kt | 2 +- .../sc/iview/commands/view/RotateView.kt | 6 ++--- .../commands/view/SaveCameraConfiguration.kt | 6 +++-- .../sc/iview/commands/view/Screenshot.kt | 2 +- .../sc/iview/commands/view/SetFarPlane.kt | 2 +- .../kotlin/sc/iview/commands/view/SetLUT.kt | 2 +- .../commands/view/SetSupersamplingFactor.kt | 2 +- .../commands/view/StartRecordingVideo.kt | 4 +-- .../commands/view/ToggleUnlimitedFramerate.kt | 2 +- .../behaviours/CameraTranslateControl.kt | 9 ++++--- .../behaviours/NodeTranslateControl.kt | 27 +++++++++++-------- .../kotlin/sc/iview/process/ControlPoints.kt | 12 +++++---- 15 files changed, 46 insertions(+), 36 deletions(-) diff --git a/pom.xml b/pom.xml index 75f39b02..5a1abd4e 100644 --- a/pom.xml +++ b/pom.xml @@ -108,7 +108,7 @@ deploy-to-scijava - e5ca73c + 0.7.0-beta-8-SNAPSHOT 1.4.10 diff --git a/src/main/kotlin/sc/iview/commands/demo/VolumeRenderDemo.kt b/src/main/kotlin/sc/iview/commands/demo/VolumeRenderDemo.kt index 2c7c01ab..d5c07c42 100644 --- a/src/main/kotlin/sc/iview/commands/demo/VolumeRenderDemo.kt +++ b/src/main/kotlin/sc/iview/commands/demo/VolumeRenderDemo.kt @@ -97,7 +97,7 @@ class VolumeRenderDemo : Command { v.addChild(isoSurfaceMesh) isoSurfaceMesh.name = "Volume Render Demo Isosurface" } - sciView.activeNode = v + sciView.setActiveNode(v) sciView.centerOnNode(sciView.activeNode) } diff --git a/src/main/kotlin/sc/iview/commands/view/ResetCameraPosition.kt b/src/main/kotlin/sc/iview/commands/view/ResetCameraPosition.kt index a77fb375..4ff62b25 100644 --- a/src/main/kotlin/sc/iview/commands/view/ResetCameraPosition.kt +++ b/src/main/kotlin/sc/iview/commands/view/ResetCameraPosition.kt @@ -52,6 +52,6 @@ class ResetCameraPosition : Command { private lateinit var sciView: SciView override fun run() { - sciView.camera.position = Vector3f(0.0f, 1.65f, 5f) + sciView.camera?.position = Vector3f(0.0f, 1.65f, 5f) } } \ No newline at end of file diff --git a/src/main/kotlin/sc/iview/commands/view/ResetCameraRotation.kt b/src/main/kotlin/sc/iview/commands/view/ResetCameraRotation.kt index 934e065f..d89faae4 100644 --- a/src/main/kotlin/sc/iview/commands/view/ResetCameraRotation.kt +++ b/src/main/kotlin/sc/iview/commands/view/ResetCameraRotation.kt @@ -52,6 +52,6 @@ class ResetCameraRotation : Command { private lateinit var sciView: SciView override fun run() { - sciView.camera.rotation = Quaternionf(0f, 0f, 0f, 1f) + sciView.camera?.rotation = Quaternionf(0f, 0f, 0f, 1f) } } \ No newline at end of file diff --git a/src/main/kotlin/sc/iview/commands/view/RotateView.kt b/src/main/kotlin/sc/iview/commands/view/RotateView.kt index 9335b24d..6f942d1f 100644 --- a/src/main/kotlin/sc/iview/commands/view/RotateView.kt +++ b/src/main/kotlin/sc/iview/commands/view/RotateView.kt @@ -54,9 +54,9 @@ class RotateView : Command { override fun run() { sciView.animate(30) { - sciView.targetArcball.init(1, 1) - sciView.targetArcball.drag(1 + xSpeed, 1 + ySpeed) - sciView.targetArcball.end(1 + xSpeed, 1 + ySpeed) + sciView.targetArcball?.init(1, 1) + sciView.targetArcball?.drag(1 + xSpeed, 1 + ySpeed) + sciView.targetArcball?.end(1 + xSpeed, 1 + ySpeed) } } } \ No newline at end of file diff --git a/src/main/kotlin/sc/iview/commands/view/SaveCameraConfiguration.kt b/src/main/kotlin/sc/iview/commands/view/SaveCameraConfiguration.kt index 3421f8bb..4d726ea8 100644 --- a/src/main/kotlin/sc/iview/commands/view/SaveCameraConfiguration.kt +++ b/src/main/kotlin/sc/iview/commands/view/SaveCameraConfiguration.kt @@ -59,11 +59,13 @@ class SaveCameraConfiguration : Command { override fun run() { try { + val cam = sciView.camera ?: return + val fw = FileWriter(saveFile) val bw = BufferedWriter(fw) if (!Files.getFileExtension(saveFile.absolutePath).equals("clj", ignoreCase = true)) throw IOException("File must be Clojure (extension = .clj)") - val pos = sciView.camera.position - val rot = sciView.camera.rotation + val pos = cam.position + val rot = cam.rotation var scriptContents = "; @SciView sciView\n\n" scriptContents += """(.setPosition (.getCamera sciView) (cleargl.GLVector. (float-array [${pos.x()} ${pos.y()} ${pos.z()}]))) """ diff --git a/src/main/kotlin/sc/iview/commands/view/Screenshot.kt b/src/main/kotlin/sc/iview/commands/view/Screenshot.kt index 10ff364e..4b598f92 100644 --- a/src/main/kotlin/sc/iview/commands/view/Screenshot.kt +++ b/src/main/kotlin/sc/iview/commands/view/Screenshot.kt @@ -58,7 +58,7 @@ class Screenshot : Command { private var img: ImgPlus<*>? = null override fun run() { - val screenshot = sciView.argbScreenshot + val screenshot = sciView.aRGBScreenshot img = ImgPlus(screenshot) uiService.show(img) } diff --git a/src/main/kotlin/sc/iview/commands/view/SetFarPlane.kt b/src/main/kotlin/sc/iview/commands/view/SetFarPlane.kt index 45995e70..24c2b8ed 100644 --- a/src/main/kotlin/sc/iview/commands/view/SetFarPlane.kt +++ b/src/main/kotlin/sc/iview/commands/view/SetFarPlane.kt @@ -51,6 +51,6 @@ class SetFarPlane : Command { private var farPlane = 1000f override fun run() { - sciView.camera.farPlaneDistance = farPlane + sciView.camera?.farPlaneDistance = farPlane } } \ No newline at end of file diff --git a/src/main/kotlin/sc/iview/commands/view/SetLUT.kt b/src/main/kotlin/sc/iview/commands/view/SetLUT.kt index e2f2ee5a..9a8bc975 100644 --- a/src/main/kotlin/sc/iview/commands/view/SetLUT.kt +++ b/src/main/kotlin/sc/iview/commands/view/SetLUT.kt @@ -86,6 +86,6 @@ class SetLUT : DynamicCommand() { } override fun run() { - sciView.setColormap(node, colorTable as AbstractArrayColorTable<*>?) + sciView.setColormap(node, colorTable) } } \ No newline at end of file diff --git a/src/main/kotlin/sc/iview/commands/view/SetSupersamplingFactor.kt b/src/main/kotlin/sc/iview/commands/view/SetSupersamplingFactor.kt index ff93fcad..b9699f75 100644 --- a/src/main/kotlin/sc/iview/commands/view/SetSupersamplingFactor.kt +++ b/src/main/kotlin/sc/iview/commands/view/SetSupersamplingFactor.kt @@ -51,6 +51,6 @@ class SetSupersamplingFactor : Command { private var supersamplingFactor = 1.0 override fun run() { - sciView.sceneryRenderer.settings.set("Renderer.SupersamplingFactor", supersamplingFactor) + sciView.getSceneryRenderer()?.settings?.set("Renderer.SupersamplingFactor", supersamplingFactor) } } \ No newline at end of file diff --git a/src/main/kotlin/sc/iview/commands/view/StartRecordingVideo.kt b/src/main/kotlin/sc/iview/commands/view/StartRecordingVideo.kt index 282a82e0..64d935c2 100644 --- a/src/main/kotlin/sc/iview/commands/view/StartRecordingVideo.kt +++ b/src/main/kotlin/sc/iview/commands/view/StartRecordingVideo.kt @@ -56,8 +56,8 @@ class StartRecordingVideo : Command { override fun run() { bitrate = max(0, bitrate) - sciView.scenerySettings.set("VideoEncoder.Bitrate", bitrate) - sciView.scenerySettings.set("VideoEncoder.Quality", videoEncodingQuality) + sciView.getScenerySettings().set("VideoEncoder.Bitrate", bitrate) + sciView.getScenerySettings().set("VideoEncoder.Quality", videoEncodingQuality) sciView.toggleRecordVideo() } } \ No newline at end of file diff --git a/src/main/kotlin/sc/iview/commands/view/ToggleUnlimitedFramerate.kt b/src/main/kotlin/sc/iview/commands/view/ToggleUnlimitedFramerate.kt index 5838d0f8..494aecf1 100644 --- a/src/main/kotlin/sc/iview/commands/view/ToggleUnlimitedFramerate.kt +++ b/src/main/kotlin/sc/iview/commands/view/ToggleUnlimitedFramerate.kt @@ -19,6 +19,6 @@ class ToggleUnlimitedFramerate : Command { private lateinit var sciView: SciView override fun run() { - sciView.pushMode = !sciView.pushMode + sciView.setPushMode(!sciView.getPushMode()) } } \ No newline at end of file diff --git a/src/main/kotlin/sc/iview/controls/behaviours/CameraTranslateControl.kt b/src/main/kotlin/sc/iview/controls/behaviours/CameraTranslateControl.kt index 64d05a98..c3ba3d9f 100644 --- a/src/main/kotlin/sc/iview/controls/behaviours/CameraTranslateControl.kt +++ b/src/main/kotlin/sc/iview/controls/behaviours/CameraTranslateControl.kt @@ -31,14 +31,15 @@ class CameraTranslateControl(protected var sciView: SciView, var dragSpeed: Floa } override fun drag(x: Int, y: Int) { - if (!sciView.camera.lock.tryLock()) { + val cam = sciView.camera ?: return + if (!cam.lock.tryLock()) { return } val translationVector = Vector3f((x - lastX) * dragSpeed, (y - lastY) * dragSpeed, 0.0f) - Quaternionf(sciView.camera.rotation).conjugate().transform(translationVector) + Quaternionf(cam.rotation).conjugate().transform(translationVector) translationVector.y *= -1f - sciView.camera.position = sciView.camera.position.add(Vector3f(translationVector.x(), translationVector.y(), translationVector.z())) - sciView.camera.lock.unlock() + cam.position = cam.position.add(Vector3f(translationVector.x(), translationVector.y(), translationVector.z())) + cam.lock.unlock() } override fun end(x: Int, y: Int) { diff --git a/src/main/kotlin/sc/iview/controls/behaviours/NodeTranslateControl.kt b/src/main/kotlin/sc/iview/controls/behaviours/NodeTranslateControl.kt index 5d193550..8ab8d9c2 100644 --- a/src/main/kotlin/sc/iview/controls/behaviours/NodeTranslateControl.kt +++ b/src/main/kotlin/sc/iview/controls/behaviours/NodeTranslateControl.kt @@ -50,7 +50,7 @@ class NodeTranslateControl(protected var sciView: SciView, var dragSpeed: Float) protected var axes // Tracking the rendered axes : MutableList? = null val camera: Camera - get() = sciView.camera + get() = sciView.camera!! // Object mode val lRAxis: Vector3f @@ -75,8 +75,9 @@ class NodeTranslateControl(protected var sciView: SciView, var dragSpeed: Float) * y position in window */ override fun init(x: Int, y: Int) { + val activeNode = sciView.activeNode ?: return camera.targeted = true - camera.target = sciView.activeNode.position + camera.target = activeNode.position if (firstEntered) { lastX = x lastY = y @@ -96,7 +97,7 @@ class NodeTranslateControl(protected var sciView: SciView, var dragSpeed: Float) mat.diffuse = Vector3f(1.0f, 0.0f, 0.0f) mat.ambient = Vector3f(1.0f, 0.0f, 0.0f) cylinder.material = mat - cylinder.position = sciView.activeNode.getMaximumBoundingBox().getBoundingSphere().origin.add(lRAxis.mul(lineLengths.toFloat())) + cylinder.position = activeNode.getMaximumBoundingBox().getBoundingSphere().origin.add(lRAxis.mul(lineLengths.toFloat())) sciView.addNode(cylinder, false) (axes as ArrayList).add(cylinder) @@ -110,7 +111,7 @@ class NodeTranslateControl(protected var sciView: SciView, var dragSpeed: Float) mat.diffuse = Vector3f(0.25f, 1f, 0.25f) mat.ambient = Vector3f(0.25f, 1f, 0.25f) cylinder.material = mat - cylinder.position = sciView.activeNode.getMaximumBoundingBox().getBoundingSphere().origin.add(getUDAxis().mul(lineLengths.toFloat())) + cylinder.position = activeNode.getMaximumBoundingBox().getBoundingSphere().origin.add(getUDAxis().mul(lineLengths.toFloat())) sciView.addNode(cylinder, false) (axes as ArrayList).add(cylinder) @@ -124,20 +125,22 @@ class NodeTranslateControl(protected var sciView: SciView, var dragSpeed: Float) mat.diffuse = Vector3f(0f, 0.5f, 1f) mat.ambient = Vector3f(0f, 0.5f, 1f) cylinder.material = mat - cylinder.position = sciView.activeNode.getMaximumBoundingBox().getBoundingSphere().origin.add(getFBAxis().mul(lineLengths.toFloat())) + cylinder.position = activeNode.getMaximumBoundingBox().getBoundingSphere().origin.add(getFBAxis().mul(lineLengths.toFloat())) sciView.addNode(cylinder, false) (axes as ArrayList).add(cylinder) } } override fun drag(x: Int, y: Int) { - if (sciView.activeNode == null || !sciView.activeNode.lock.tryLock()) { + val activeNode = sciView.activeNode ?: return + + if (sciView.activeNode == null || !activeNode.lock.tryLock()) { return } - sciView.activeNode.position = sciView.activeNode.position.add( + activeNode.position = activeNode.position.add( lRAxis.mul((x - lastX) * dragSpeed)).add( getUDAxis().mul(-1 * (y - lastY) * dragSpeed)) - sciView.activeNode.lock.unlock() + activeNode.lock.unlock() } override fun end(x: Int, y: Int) { @@ -149,11 +152,13 @@ class NodeTranslateControl(protected var sciView: SciView, var dragSpeed: Float) } override fun scroll(wheelRotation: Double, isHorizontal: Boolean, x: Int, y: Int) { - if (sciView.activeNode == null || !sciView.activeNode.lock.tryLock()) { + val activeNode = sciView.activeNode ?: return + + if (sciView.activeNode == null || !activeNode.lock.tryLock()) { return } - sciView.activeNode.position = sciView.activeNode.position.add( + activeNode.position = activeNode.position.add( getFBAxis().mul(wheelRotation.toFloat() * dragSpeed)) - sciView.activeNode.lock.unlock() + activeNode.lock.unlock() } } \ No newline at end of file diff --git a/src/main/kotlin/sc/iview/process/ControlPoints.kt b/src/main/kotlin/sc/iview/process/ControlPoints.kt index 654a109c..20f73276 100644 --- a/src/main/kotlin/sc/iview/process/ControlPoints.kt +++ b/src/main/kotlin/sc/iview/process/ControlPoints.kt @@ -20,7 +20,7 @@ import java.util.ArrayList */ class ControlPoints { protected var nodes: MutableList - private var targetPoint: Node? = null + private lateinit var targetPoint: Node private var controlPointDistance = 0f fun clearPoints() { nodes.clear() @@ -55,6 +55,7 @@ class ControlPoints { } fun initializeSciView(sciView: SciView, controlPointDistance: Float) { + val cam= sciView.camera ?: return // This is where the command should change the current inputs setup sciView.stashControls() sciView.sceneryInputHandler.addBehaviour("place_control_point", @@ -72,14 +73,14 @@ class ControlPoints { mat.ambient = Utils.convertToVector3f(TARGET_COLOR) mat.diffuse = Utils.convertToVector3f(TARGET_COLOR) (targetPoint as Sphere).material = mat - (targetPoint as Sphere).position = sciView.camera.position.add(sciView.camera.forward.mul(controlPointDistance)) + (targetPoint as Sphere).position = cam.position.add(cam.forward.mul(controlPointDistance)) sciView.addNode(targetPoint, false) //sciView.getCamera().addChild(targetPoint); (targetPoint as Sphere).update.add { //targetPoint.getRotation().set(sciView.getCamera().getRotation().conjugate().rotateByAngleY((float) Math.PI)); // Set rotation before setting position - (targetPoint as Sphere).position = sciView.camera.position.add(sciView.camera.forward.mul(controlPointDistance)) + (targetPoint as Sphere).position = cam.position.add(cam.forward.mul(controlPointDistance)) } } @@ -89,8 +90,9 @@ class ControlPoints { private fun distanceControlPointBehaviour(sciView: SciView): Behaviour { return ScrollBehaviour { wheelRotation, _, _, _ -> + val cam = sciView.camera!! controlPointDistance += wheelRotation.toFloat() - targetPoint!!.position = sciView.camera.position.add(sciView.camera.forward.mul(controlPointDistance)) + targetPoint.position = cam.position.add(cam.forward.mul(controlPointDistance)) } } @@ -102,7 +104,7 @@ class ControlPoints { controlPoint.material = mat //controlPoint.setPosition( sciView.getCamera().getTransformation().mult(targetPoint.getPosition().xyzw()) ); - controlPoint.position = targetPoint!!.position + controlPoint.position = targetPoint.position addPoint(controlPoint) sciView.addNode(controlPoint, false) } From 4bed0df23ddf3ef298f92358cefa99048fecedf2 Mon Sep 17 00:00:00 2001 From: Ulrik Guenther Date: Thu, 12 Nov 2020 17:34:54 +0100 Subject: [PATCH 18/23] Add ImageJMain to have a way to launch sciview in conjunction with ImageJ from IDE --- src/main/java/sc/iview/ImageJMain.kt | 60 ++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/main/java/sc/iview/ImageJMain.kt diff --git a/src/main/java/sc/iview/ImageJMain.kt b/src/main/java/sc/iview/ImageJMain.kt new file mode 100644 index 00000000..7f98b55f --- /dev/null +++ b/src/main/java/sc/iview/ImageJMain.kt @@ -0,0 +1,60 @@ +/*- + * #%L + * Scenery-backed 3D visualization package for ImageJ. + * %% + * Copyright (C) 2016 - 2020 SciView 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 sc.iview + +import net.imagej.lut.LUTService +import net.imagej.ops.OpService +import net.imagej.units.UnitService +import org.scijava.Context +import org.scijava.console.ConsoleService +import org.scijava.io.IOService +import org.scijava.menu.MenuService +import org.scijava.options.OptionsService +import org.scijava.tool.ToolService +import org.scijava.ui.UIService +import org.scijava.ui.swing.SwingIconService + +/** + * Entry point for testing SciView functionality. + * + * @author Kyle Harrington + * @author Ulrik Guenther + */ +object ImageJMain { + @Throws(Exception::class) + @JvmStatic + fun main(args: Array) { + val context = Context() + val uiService = context.service(UIService::class.java) + val sciViewService = context.service(SciViewService::class.java) + + uiService.showUI() + sciViewService.createSciView() + } +} From d99015421d89a55703f3b9cf8ba75b0e01f43772 Mon Sep 17 00:00:00 2001 From: Kyle IS Harrington Date: Fri, 13 Nov 2020 18:28:08 +0100 Subject: [PATCH 19/23] Remove Vector3 and Vector4 --- src/main/java/sc/iview/SciView.kt | 103 ++--- .../sc/iview/commands/demo/Line3DDemo.java | 7 +- .../java/sc/iview/commands/demo/LineDemo.java | 12 +- .../demo/LoadCremiDatasetAndNeurons.kt | 3 - .../java/sc/iview/commands/edit/AddBox.java | 7 +- .../sc/iview/commands/edit/AddCamera.java | 5 +- .../java/sc/iview/commands/edit/AddLine.java | 5 +- .../sc/iview/commands/edit/AddSphere.java | 5 +- .../sc/iview/commands/process/DrawLines.java | 5 +- .../process/InteractiveConvexMesh.java | 6 +- src/main/java/sc/iview/node/Line3D.kt | 19 +- .../java/sc/iview/process/ControlPoints.kt | 13 +- .../java/sc/iview/vector/DoubleVector3.java | 72 ---- .../java/sc/iview/vector/DoubleVector4.java | 76 ---- .../java/sc/iview/vector/FloatVector3.java | 64 --- .../java/sc/iview/vector/FloatVector4.java | 66 --- .../java/sc/iview/vector/JOMLVector3.java | 75 ---- .../java/sc/iview/vector/JOMLVector4.java | 76 ---- src/main/java/sc/iview/vector/Vector3.java | 344 ---------------- src/main/java/sc/iview/vector/Vector4.java | 384 ------------------ src/test/tests/sc/iview/test/SciViewTest.java | 3 +- 21 files changed, 93 insertions(+), 1257 deletions(-) delete mode 100644 src/main/java/sc/iview/vector/DoubleVector3.java delete mode 100644 src/main/java/sc/iview/vector/DoubleVector4.java delete mode 100644 src/main/java/sc/iview/vector/FloatVector3.java delete mode 100644 src/main/java/sc/iview/vector/FloatVector4.java delete mode 100644 src/main/java/sc/iview/vector/JOMLVector3.java delete mode 100644 src/main/java/sc/iview/vector/JOMLVector4.java delete mode 100644 src/main/java/sc/iview/vector/Vector3.java delete mode 100644 src/main/java/sc/iview/vector/Vector4.java diff --git a/src/main/java/sc/iview/SciView.kt b/src/main/java/sc/iview/SciView.kt index cb67e716..084e334e 100644 --- a/src/main/java/sc/iview/SciView.kt +++ b/src/main/java/sc/iview/SciView.kt @@ -115,8 +115,6 @@ import sc.iview.event.NodeRemovedEvent import sc.iview.process.MeshConverter import sc.iview.ui.ContextPopUpNodeChooser import sc.iview.ui.REPLPane -import sc.iview.vector.JOMLVector3 -import sc.iview.vector.Vector3 import tpietzsch.example2.VolumeViewerOptions import java.awt.* import java.awt.event.* @@ -1192,16 +1190,18 @@ class SciView : SceneryBase, CalibratedRealInterval { * @return the Node corresponding to the box */ @JvmOverloads - fun addBox(position: Vector3? = JOMLVector3(0.0f, 0.0f, 0.0f), size: Vector3? = JOMLVector3(1.0f, 1.0f, 1.0f), color: ColorRGB? = DEFAULT_COLOR, - inside: Boolean = false): Node { + fun addBox(position: Vector3f? = Vector3f(0.0f, 0.0f, 0.0f), size: Vector3f? = Vector3f(1.0f, 1.0f, 1.0f), color: ColorRGB? = DEFAULT_COLOR, + inside: Boolean = false): Node? { // TODO: use a material from the current palate by default val boxmaterial = Material() boxmaterial.ambient = Vector3f(1.0f, 0.0f, 0.0f) boxmaterial.diffuse = Utils.convertToVector3f(color) boxmaterial.specular = Vector3f(1.0f, 1.0f, 1.0f) - val box = Box(JOMLVector3.convert(size), inside) - box.material = boxmaterial - box.position = JOMLVector3.convert(position) + val box = size?.let { Box(it, inside) } + box?.material = boxmaterial + if (position != null) { + box?.position = position + } return addNode(box) } /** @@ -1222,14 +1222,16 @@ class SciView : SceneryBase, CalibratedRealInterval { * @return the Node corresponding to the sphere */ @JvmOverloads - fun addSphere(position: Vector3? = JOMLVector3(0.0f, 0.0f, 0.0f), radius: Float = 1f, color: ColorRGB? = DEFAULT_COLOR): Node { + fun addSphere(position: Vector3f? = Vector3f(0.0f, 0.0f, 0.0f), radius: Float = 1f, color: ColorRGB? = DEFAULT_COLOR): Node? { val material = Material() material.ambient = Vector3f(1.0f, 0.0f, 0.0f) material.diffuse = Utils.convertToVector3f(color) material.specular = Vector3f(1.0f, 1.0f, 1.0f) val sphere = Sphere(radius, 20) sphere.material = material - sphere.position = JOMLVector3.convert(position) + if (position != null) { + sphere.position = position + } return addNode(sphere) } @@ -1241,9 +1243,11 @@ class SciView : SceneryBase, CalibratedRealInterval { * @param num_segments number of segments to represent the cylinder * @return the Node corresponding to the cylinder */ - fun addCylinder(position: Vector3?, radius: Float, height: Float, num_segments: Int): Node { + fun addCylinder(position: Vector3f?, radius: Float, height: Float, num_segments: Int): Node? { val cyl = Cylinder(radius, height, num_segments) - cyl.position = JOMLVector3.convert(position) + if (position != null) { + cyl.position = position + } return addNode(cyl) } @@ -1255,9 +1259,11 @@ class SciView : SceneryBase, CalibratedRealInterval { * @param num_segments number of segments used to represent cone * @return the Node corresponding to the cone */ - fun addCone(position: Vector3?, radius: Float, height: Float, num_segments: Int): Node { + fun addCone(position: Vector3f?, radius: Float, height: Float, num_segments: Int): Node? { val cone = Cone(radius, height, num_segments, Vector3f(0.0f, 0.0f, 1.0f)) - cone.position = JOMLVector3.convert(position) + if (position != null) { + cone.position = position + } return addNode(cone) } @@ -1269,7 +1275,7 @@ class SciView : SceneryBase, CalibratedRealInterval { * @return the Node corresponding to the line */ @JvmOverloads - fun addLine(start: Vector3 = JOMLVector3(0.0f, 0.0f, 0.0f), stop: Vector3 = JOMLVector3(1.0f, 1.0f, 1.0f), color: ColorRGB? = DEFAULT_COLOR): Node { + fun addLine(start: Vector3f = Vector3f(0.0f, 0.0f, 0.0f), stop: Vector3f = Vector3f(1.0f, 1.0f, 1.0f), color: ColorRGB? = DEFAULT_COLOR): Node? { return addLine(arrayOf(start, stop), color, 0.1) } @@ -1280,18 +1286,18 @@ class SciView : SceneryBase, CalibratedRealInterval { * @param edgeWidth width of line segments * @return the Node corresponding to the line */ - fun addLine(points: Array, color: ColorRGB?, edgeWidth: Double): Node { + fun addLine(points: Array, color: ColorRGB?, edgeWidth: Double): Node? { val material = Material() material.ambient = Vector3f(1.0f, 1.0f, 1.0f) material.diffuse = Utils.convertToVector3f(color) material.specular = Vector3f(1.0f, 1.0f, 1.0f) val line = Line(points.size) for (pt in points) { - line.addPoint(JOMLVector3.convert(pt)) + line.addPoint(pt) } line.edgeWidth = edgeWidth.toFloat() line.material = material - line.position = JOMLVector3.convert(points[0]) + line.position = points[0] return addNode(line) } @@ -1299,7 +1305,7 @@ class SciView : SceneryBase, CalibratedRealInterval { * Add a PointLight source at the origin * @return a Node corresponding to the PointLight */ - fun addPointLight(): Node { + fun addPointLight(): Node? { val material = Material() material.ambient = Vector3f(1.0f, 0.0f, 0.0f) material.diffuse = Vector3f(0.0f, 1.0f, 0.0f) @@ -1450,7 +1456,7 @@ class SciView : SceneryBase, CalibratedRealInterval { */ @JvmOverloads fun addPointCloud(points: Collection, - name: String? = "PointCloud"): Node { + name: String? = "PointCloud"): Node? { val flatVerts = FloatArray(points.size * 3) var k = 0 for (point in points) { @@ -1482,7 +1488,7 @@ class SciView : SceneryBase, CalibratedRealInterval { * @param pointCloud existing PointCloud to add to scene * @return a Node corresponding to the PointCloud */ - fun addPointCloud(pointCloud: PointCloud): Node { + fun addPointCloud(pointCloud: PointCloud): Node? { pointCloud.setupPointCloud() pointCloud.material.ambient = Vector3f(1.0f, 1.0f, 1.0f) pointCloud.material.diffuse = Vector3f(1.0f, 1.0f, 1.0f) @@ -1498,22 +1504,23 @@ class SciView : SceneryBase, CalibratedRealInterval { * @return a Node corresponding to the Node */ @JvmOverloads - fun addNode(n: Node, activePublish: Boolean = true): Node { - scene.addChild(n) - objectService?.addObject(n) - if (blockOnNewNodes) { - blockWhile({ sciView: SciView -> sciView.find(n.name) == null }, 20) - //System.out.println("find(name) " + find(n.getName()) ); - } - // Set new node as active and centered? - setActiveNode(n); - if( centerOnNewNodes ) { - centerOnNode(n) - } - if( activePublish ) { - eventService?.publish(NodeAddedEvent(n)); + fun addNode(n: Node?, activePublish: Boolean = true): Node? { + n?.let { + scene.addChild(it) + objectService?.addObject(n) + if (blockOnNewNodes) { + blockWhile({ sciView: SciView -> sciView.find(n.name) == null }, 20) + //System.out.println("find(name) " + find(n.getName()) ); + } + // Set new node as active and centered? + setActiveNode(n); + if (centerOnNewNodes) { + centerOnNode(n) + } + if (activePublish) { + eventService?.publish(NodeAddedEvent(n)); + } } - return n; } @@ -1522,7 +1529,7 @@ class SciView : SceneryBase, CalibratedRealInterval { * @param scMesh scenery mesh to add to scene * @return a Node corresponding to the mesh */ - fun addMesh(scMesh: graphics.scenery.Mesh): Node { + fun addMesh(scMesh: graphics.scenery.Mesh): Node? { val material = Material() material.ambient = Vector3f(1.0f, 0.0f, 0.0f) material.diffuse = Vector3f(0.0f, 1.0f, 0.0f) @@ -1538,7 +1545,7 @@ class SciView : SceneryBase, CalibratedRealInterval { * @param mesh net.imagej.mesh to add to scene * @return a Node corresponding to the mesh */ - fun addMesh(mesh: Mesh): Node { + fun addMesh(mesh: Mesh): Node? { val scMesh = MeshConverter.toScenery(mesh) return addMesh(scMesh) } @@ -1816,7 +1823,7 @@ class SciView : SceneryBase, CalibratedRealInterval { * @param image image to add as a volume * @return a Node corresponding to the Volume */ - fun addVolume(image: Dataset): Node { + fun addVolume(image: Dataset): Node? { val voxelDims = FloatArray(image.numDimensions()) for (d in voxelDims.indices) { val inValue = image.axis(d).averageScale(0.0, 1.0) @@ -1832,7 +1839,7 @@ class SciView : SceneryBase, CalibratedRealInterval { * @return a Node corresponding to the Volume */ @Suppress("UNCHECKED_CAST") - fun addVolume(image: Dataset, voxelDimensions: FloatArray): Node { + fun addVolume(image: Dataset, voxelDimensions: FloatArray): Node? { return addVolume>(image.imgPlus as RandomAccessibleInterval>, image.name, *voxelDimensions) } @@ -1855,7 +1862,7 @@ class SciView : SceneryBase, CalibratedRealInterval { * @param pixel type of image * @return a Node corresponding to the volume */ - fun > addVolume(image: RandomAccessibleInterval, name: String?): Node { + fun > addVolume(image: RandomAccessibleInterval, name: String?): Node? { return addVolume(image, name, 1f, 1f, 1f) } @@ -1865,7 +1872,7 @@ class SciView : SceneryBase, CalibratedRealInterval { * @param pixel type of image * @return a Node corresponding to the volume */ - fun > addVolume(image: RandomAccessibleInterval, voxelDimensions: FloatArray): Node { + fun > addVolume(image: RandomAccessibleInterval, voxelDimensions: FloatArray): Node? { return addVolume(image, "volume", *voxelDimensions) } @@ -1877,7 +1884,7 @@ class SciView : SceneryBase, CalibratedRealInterval { */ @Suppress("UNCHECKED_CAST") @Throws(Exception::class) - fun ?> addVolume(image: IterableInterval): Node { + fun ?> addVolume(image: IterableInterval): Node? { return if (image is RandomAccessibleInterval<*>) { addVolume(image as RandomAccessibleInterval>, "Volume") } else { @@ -1894,7 +1901,7 @@ class SciView : SceneryBase, CalibratedRealInterval { */ @Suppress("UNCHECKED_CAST") @Throws(Exception::class) - fun ?> addVolume(image: IterableInterval, name: String?): Node { + fun ?> addVolume(image: IterableInterval, name: String?): Node? { return if (image is RandomAccessibleInterval<*>) { addVolume(image as RandomAccessibleInterval>, name, 1f, 1f, 1f) } else { @@ -1958,7 +1965,7 @@ class SciView : SceneryBase, CalibratedRealInterval { fun > addVolume(sac: SourceAndConverter, numTimepoints: Int, name: String?, - vararg voxelDimensions: Float): Node { + vararg voxelDimensions: Float): Node? { val sources: MutableList> = ArrayList() sources.add(sac) return addVolume(sources, numTimepoints, name, *voxelDimensions) @@ -1974,7 +1981,7 @@ class SciView : SceneryBase, CalibratedRealInterval { * @return a Node corresponding to the Volume */ fun > addVolume(image: RandomAccessibleInterval, name: String?, - vararg voxelDimensions: Float): Node { + vararg voxelDimensions: Float): Node? { //log.debug( "Add Volume " + name + " image: " + image ); val dimensions = LongArray(image.numDimensions()) image.dimensions(dimensions) @@ -2004,7 +2011,7 @@ class SciView : SceneryBase, CalibratedRealInterval { sources.add(source) } val v = addVolume(sources, numTimepoints, name, *voxelDimensions) - v.metadata["RandomAccessibleInterval"] = image + v?.metadata?.set("RandomAccessibleInterval", image) return v } @@ -2024,7 +2031,7 @@ class SciView : SceneryBase, CalibratedRealInterval { converterSetups: ArrayList?, numTimepoints: Int, name: String?, - vararg voxelDimensions: Float): Node { + vararg voxelDimensions: Float): Node? { var timepoints = numTimepoints var cacheControl: CacheControl? = null @@ -2097,7 +2104,7 @@ class SciView : SceneryBase, CalibratedRealInterval { fun > addVolume(sources: List>, numTimepoints: Int, name: String?, - vararg voxelDimensions: Float): Node { + vararg voxelDimensions: Float): Node? { var setupId = 0 val converterSetups = ArrayList() for (source in sources) { diff --git a/src/main/java/sc/iview/commands/demo/Line3DDemo.java b/src/main/java/sc/iview/commands/demo/Line3DDemo.java index 931e4330..7c35024f 100644 --- a/src/main/java/sc/iview/commands/demo/Line3DDemo.java +++ b/src/main/java/sc/iview/commands/demo/Line3DDemo.java @@ -28,6 +28,7 @@ */ package sc.iview.commands.demo; +import org.joml.Vector3f; import org.scijava.command.Command; import org.scijava.command.CommandService; import org.scijava.plugin.Menu; @@ -36,8 +37,6 @@ import org.scijava.util.ColorRGB; import sc.iview.SciView; import sc.iview.node.Line3D; -import sc.iview.vector.JOMLVector3; -import sc.iview.vector.Vector3; import java.util.ArrayList; import java.util.HashMap; @@ -62,11 +61,11 @@ public class Line3DDemo implements Command { @Override public void run() { int numPoints = 25; - List points = new ArrayList<>(); + List points = new ArrayList<>(); List colors = new ArrayList<>(); for( int k = 0; k < numPoints; k++ ) { - points.add( new JOMLVector3( ( float ) ( 10.0f * Math.random() - 5.0f ), // + points.add( new Vector3f( ( float ) ( 10.0f * Math.random() - 5.0f ), // ( float ) ( 10.0f * Math.random() - 5.0f ), // ( float ) ( 10.0f * Math.random() - 5.0f ) ) ); colors.add(new ColorRGB((int) (Math.random()*255), (int) (Math.random()*255), (int) (Math.random()*255))); diff --git a/src/main/java/sc/iview/commands/demo/LineDemo.java b/src/main/java/sc/iview/commands/demo/LineDemo.java index b601e72f..89802452 100644 --- a/src/main/java/sc/iview/commands/demo/LineDemo.java +++ b/src/main/java/sc/iview/commands/demo/LineDemo.java @@ -31,6 +31,7 @@ import static sc.iview.commands.MenuWeights.DEMO; import static sc.iview.commands.MenuWeights.DEMO_LINES; +import org.joml.Vector3f; import org.scijava.command.Command; import org.scijava.command.CommandService; import org.scijava.plugin.Menu; @@ -39,9 +40,6 @@ import org.scijava.util.Colors; import sc.iview.SciView; -import sc.iview.vector.JOMLVector3; -import sc.iview.vector.Vector3; - import java.util.HashMap; /** @@ -61,12 +59,12 @@ public class LineDemo implements Command { @Override public void run() { int numPoints = 25; - Vector3[] points = new Vector3[numPoints]; + Vector3f[] points = new Vector3f[numPoints]; for( int k = 0; k < numPoints; k++ ) { - points[k] = new JOMLVector3( ( float ) ( 10.0f * Math.random() - 5.0f ), // - ( float ) ( 10.0f * Math.random() - 5.0f ), // - ( float ) ( 10.0f * Math.random() - 5.0f ) ); + points[k] = new Vector3f( ( float ) ( 10.0f * Math.random() - 5.0f ), // + ( float ) ( 10.0f * Math.random() - 5.0f ), // + ( float ) ( 10.0f * Math.random() - 5.0f ) ); } double edgeWidth = 0.1; diff --git a/src/main/java/sc/iview/commands/demo/LoadCremiDatasetAndNeurons.kt b/src/main/java/sc/iview/commands/demo/LoadCremiDatasetAndNeurons.kt index ce118ffa..f67dcb06 100644 --- a/src/main/java/sc/iview/commands/demo/LoadCremiDatasetAndNeurons.kt +++ b/src/main/java/sc/iview/commands/demo/LoadCremiDatasetAndNeurons.kt @@ -5,10 +5,8 @@ import bdv.viewer.Interpolation import ch.systemsx.cisd.hdf5.HDF5Factory import graphics.scenery.Material import graphics.scenery.Origin -import graphics.scenery.numerics.Random import graphics.scenery.utils.extensions.xyz import graphics.scenery.volumes.Colormap -import graphics.scenery.volumes.Colormap.Companion.fromColorTable import graphics.scenery.volumes.TransferFunction import graphics.scenery.volumes.Volume import net.imagej.lut.LUTService @@ -35,7 +33,6 @@ import org.scijava.plugin.Plugin import org.scijava.ui.UIService import org.scijava.widget.FileWidget import sc.iview.SciView -import sc.iview.SciViewService import sc.iview.commands.MenuWeights import sc.iview.process.MeshConverter import java.io.FileFilter diff --git a/src/main/java/sc/iview/commands/edit/AddBox.java b/src/main/java/sc/iview/commands/edit/AddBox.java index 31558031..47ab4542 100644 --- a/src/main/java/sc/iview/commands/edit/AddBox.java +++ b/src/main/java/sc/iview/commands/edit/AddBox.java @@ -31,6 +31,7 @@ import static sc.iview.commands.MenuWeights.EDIT; import static sc.iview.commands.MenuWeights.EDIT_ADD_BOX; +import org.joml.Vector3f; import org.scijava.command.Command; import org.scijava.display.DisplayService; import org.scijava.plugin.Menu; @@ -39,8 +40,6 @@ import org.scijava.util.ColorRGB; import sc.iview.SciView; -import sc.iview.vector.JOMLVector3; -import sc.iview.vector.Vector3; /** * Command to add a box to the scene @@ -75,8 +74,8 @@ public class AddBox implements Command { @Override public void run() { //final Vector3 pos = ClearGLVector3.parse( position ); - final Vector3 pos = new JOMLVector3(0, 0, 0); - final Vector3 vSize = new JOMLVector3( size, size, size ); + final Vector3f pos = new Vector3f(0f, 0f, 0f); + final Vector3f vSize = new Vector3f( size, size, size ); sciView.addBox( pos, vSize, color, inside ); } } diff --git a/src/main/java/sc/iview/commands/edit/AddCamera.java b/src/main/java/sc/iview/commands/edit/AddCamera.java index 666c77a8..d5738492 100644 --- a/src/main/java/sc/iview/commands/edit/AddCamera.java +++ b/src/main/java/sc/iview/commands/edit/AddCamera.java @@ -29,14 +29,13 @@ package sc.iview.commands.edit; import graphics.scenery.DetachedHeadCamera; +import org.joml.Vector3f; import org.scijava.command.Command; import org.scijava.display.DisplayService; import org.scijava.plugin.Menu; import org.scijava.plugin.Parameter; import org.scijava.plugin.Plugin; import sc.iview.SciView; -import sc.iview.vector.JOMLVector3; -import sc.iview.vector.Vector3; import static sc.iview.commands.MenuWeights.EDIT; import static sc.iview.commands.MenuWeights.EDIT_ADD_CAMERA; @@ -74,7 +73,7 @@ public class AddCamera implements Command { @Override public void run() { //final Vector3 pos = ClearGLVector3.parse( position ); - final Vector3 pos = new JOMLVector3(0, 0, 0); + final Vector3f pos = new Vector3f(0, 0, 0); final DetachedHeadCamera cam = new DetachedHeadCamera(); cam.perspectiveCamera( fov, sciView.getWindowWidth(), sciView.getWindowHeight(), Math.min(nearPlane, farPlane), Math.max(nearPlane, farPlane) ); cam.setPosition( pos ); diff --git a/src/main/java/sc/iview/commands/edit/AddLine.java b/src/main/java/sc/iview/commands/edit/AddLine.java index 5288e327..e1386b37 100644 --- a/src/main/java/sc/iview/commands/edit/AddLine.java +++ b/src/main/java/sc/iview/commands/edit/AddLine.java @@ -31,6 +31,7 @@ import static sc.iview.commands.MenuWeights.EDIT; import static sc.iview.commands.MenuWeights.EDIT_ADD_LINE; +import org.joml.Vector3f; import org.scijava.command.Command; import org.scijava.plugin.Menu; import org.scijava.plugin.Parameter; @@ -38,8 +39,6 @@ import org.scijava.util.ColorRGB; import sc.iview.SciView; -import sc.iview.vector.JOMLVector3; -import sc.iview.vector.Vector3; /** * Command to add a line in the scene @@ -71,7 +70,7 @@ public class AddLine implements Command { @Override public void run() { //Vector3[] endpoints = { JOMLVector3.parse( start ), JOMLVector3.parse( stop ) }; - Vector3[] endpoints = { new JOMLVector3( 0, 0, 0 ), new JOMLVector3( 1, 1, 1 ) }; + Vector3f[] endpoints = { new Vector3f( 0, 0, 0 ), new Vector3f( 1, 1, 1 ) }; sciView.addLine( endpoints, color, edgeWidth ); } } diff --git a/src/main/java/sc/iview/commands/edit/AddSphere.java b/src/main/java/sc/iview/commands/edit/AddSphere.java index 23f9a05d..69fbd560 100644 --- a/src/main/java/sc/iview/commands/edit/AddSphere.java +++ b/src/main/java/sc/iview/commands/edit/AddSphere.java @@ -31,6 +31,7 @@ import static sc.iview.commands.MenuWeights.EDIT; import static sc.iview.commands.MenuWeights.EDIT_ADD_SPHERE; +import org.joml.Vector3f; import org.scijava.command.Command; import org.scijava.plugin.Menu; import org.scijava.plugin.Parameter; @@ -38,8 +39,6 @@ import org.scijava.util.ColorRGB; import sc.iview.SciView; -import sc.iview.vector.JOMLVector3; -import sc.iview.vector.Vector3; /** * Command to add a sphere in the scene @@ -67,7 +66,7 @@ public class AddSphere implements Command { @Override public void run() { //final Vector3 pos = ClearGLVector3.parse( position ); - final Vector3 pos = new JOMLVector3(0, 0, 0); + final Vector3f pos = new Vector3f(0, 0, 0); sciView.addSphere( pos, radius, color ); } } diff --git a/src/main/java/sc/iview/commands/process/DrawLines.java b/src/main/java/sc/iview/commands/process/DrawLines.java index 2fbfd7f4..2a760d11 100644 --- a/src/main/java/sc/iview/commands/process/DrawLines.java +++ b/src/main/java/sc/iview/commands/process/DrawLines.java @@ -41,7 +41,6 @@ import sc.iview.SciView; import sc.iview.node.Line3D; import sc.iview.process.ControlPoints; -import sc.iview.vector.Vector3; import java.util.ArrayList; @@ -84,8 +83,8 @@ public void createLine() { //Line line = new Line(); ArrayList points = new ArrayList<>(); - for( Vector3 v : controlPoints.getVertices() ) { - points.add(new Vector3f(v.xf(), v.yf(), v.zf())); + for( Vector3f v : controlPoints.getVertices() ) { + points.add(new Vector3f(v.x(), v.y(), v.z())); } float r = 0.1f; diff --git a/src/main/java/sc/iview/commands/process/InteractiveConvexMesh.java b/src/main/java/sc/iview/commands/process/InteractiveConvexMesh.java index f7029431..408c6d9c 100644 --- a/src/main/java/sc/iview/commands/process/InteractiveConvexMesh.java +++ b/src/main/java/sc/iview/commands/process/InteractiveConvexMesh.java @@ -33,6 +33,7 @@ import net.imagej.mesh.naive.NaiveDoubleMesh; import net.imagej.ops.OpService; import net.imagej.ops.geom.geom3d.DefaultConvexHull3D; +import org.joml.Vector3f; import org.scijava.command.Command; import org.scijava.command.InteractiveCommand; import org.scijava.plugin.Menu; @@ -41,7 +42,6 @@ import org.scijava.widget.Button; import sc.iview.SciView; import sc.iview.process.ControlPoints; -import sc.iview.vector.Vector3; import java.util.List; @@ -83,8 +83,8 @@ public void run() { public void createMesh() { Mesh mesh = new NaiveDoubleMesh(); - for( Vector3 v : controlPoints.getVertices() ) { - mesh.vertices().add(v.xf(), v.yf(), v.zf()); + for( Vector3f v : controlPoints.getVertices() ) { + mesh.vertices().add(v.x(), v.y(), v.z()); } final List result = (List) opService.run(DefaultConvexHull3D.class, mesh ); diff --git a/src/main/java/sc/iview/node/Line3D.kt b/src/main/java/sc/iview/node/Line3D.kt index cef1dfad..2addae63 100644 --- a/src/main/java/sc/iview/node/Line3D.kt +++ b/src/main/java/sc/iview/node/Line3D.kt @@ -1,11 +1,10 @@ package sc.iview.node import graphics.scenery.* +import org.joml.Vector3f import org.scijava.util.ColorRGB import org.scijava.util.Colors import sc.iview.Utils -import sc.iview.vector.JOMLVector3 -import sc.iview.vector.Vector3 import java.util.ArrayList /** @@ -24,7 +23,7 @@ class Line3D : Node { edges = ArrayList() } - constructor(points: List, colorRGB: ColorRGB, edgeWidth: Double) { + constructor(points: List, colorRGB: ColorRGB, edgeWidth: Double) { defaultColor = colorRGB this.edgeWidth = edgeWidth edges = ArrayList() @@ -32,8 +31,8 @@ class Line3D : Node { for (k in points.indices) { if (k > 0) { val edge: Node = Cylinder.betweenPoints( - JOMLVector3.convert(points[k - 1]), - JOMLVector3.convert(points[k]), + points[k - 1], + points[k], edgeWidth.toFloat(), 1f, 15) @@ -41,14 +40,14 @@ class Line3D : Node { } if (sphereJoints) { val joint: Node = Sphere(edgeWidth.toFloat(), 15) - joint.position = JOMLVector3.convert(points[k]) + joint.position = points[k] joints!!.add(joint) addChild(joint) } } } - constructor(points: List, colors: List, edgeWidth: Double) { + constructor(points: List, colors: List, edgeWidth: Double) { this.edgeWidth = edgeWidth edges = ArrayList() if (sphereJoints) joints = ArrayList() @@ -60,8 +59,8 @@ class Line3D : Node { mat.specular = c if (k > 0) { val edge: Node = Cylinder.betweenPoints( - JOMLVector3.convert(points[k - 1]), - JOMLVector3.convert(points[k]), + points[k - 1], + points[k], edgeWidth.toFloat(), 1f, 15) @@ -71,7 +70,7 @@ class Line3D : Node { if (sphereJoints) { val joint: Node = Sphere(edgeWidth.toFloat(), 15) joint.material = mat - joint.position = JOMLVector3.convert(points[k]) + joint.position = points[k] joints!!.add(joint) addChild(joint) } diff --git a/src/main/java/sc/iview/process/ControlPoints.kt b/src/main/java/sc/iview/process/ControlPoints.kt index 20f73276..666a7bcd 100644 --- a/src/main/java/sc/iview/process/ControlPoints.kt +++ b/src/main/java/sc/iview/process/ControlPoints.kt @@ -3,14 +3,13 @@ package sc.iview.process import graphics.scenery.Material import graphics.scenery.Node import graphics.scenery.Sphere +import org.joml.Vector3f import org.scijava.ui.behaviour.Behaviour import org.scijava.ui.behaviour.ClickBehaviour import org.scijava.ui.behaviour.ScrollBehaviour import org.scijava.util.ColorRGB import sc.iview.SciView import sc.iview.Utils -import sc.iview.vector.JOMLVector3 -import sc.iview.vector.Vector3 import java.util.ArrayList /** @@ -26,21 +25,21 @@ class ControlPoints { nodes.clear() } - val vertices: List + val vertices: List get() { - val points: MutableList = ArrayList() + val points: MutableList = ArrayList() for (k in nodes.indices) { - points.add(JOMLVector3(nodes[k].position)) + points.add(Vector3f(nodes[k].position)) } return points } - fun setPoints(newPoints: Array) { + fun setPoints(newPoints: Array) { nodes.clear() nodes = ArrayList() for (k in newPoints.indices) { val cp = Sphere(DEFAULT_RADIUS, DEFAULT_SEGMENTS) - cp.position = JOMLVector3.convert(newPoints[k]) + cp.position = newPoints[k] nodes.add(cp) } } diff --git a/src/main/java/sc/iview/vector/DoubleVector3.java b/src/main/java/sc/iview/vector/DoubleVector3.java deleted file mode 100644 index fcdf293f..00000000 --- a/src/main/java/sc/iview/vector/DoubleVector3.java +++ /dev/null @@ -1,72 +0,0 @@ -/*- - * #%L - * Scenery-backed 3D visualization package for ImageJ. - * %% - * Copyright (C) 2016 - 2020 SciView 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 sc.iview.vector; - -/** - * {@link Vector3} backed by three {@code double}s. - * - * @author Curtis Rueden - * @author Kyle Harrington - */ -public class DoubleVector3 implements Vector3 { - - private double x, y, z; - - public DoubleVector3( double x, double y, double z ) { - this.x = x; - this.y = y; - this.z = z; - } - - @Override public float xf() { return (float) x; } - @Override public float yf() { return (float) y; } - @Override public float zf() { return (float) z; } - - @Override public void setX( float position ) { x = position; } - @Override public void setY( float position ) { y = position; } - @Override public void setZ( float position ) { z = position; } - - @Override public double xd() { return x; } - @Override public double yd() { return y; } - @Override public double zd() { return z; } - - @Override public void setX( double position ) { x = position; } - @Override public void setY( double position ) { y = position; } - @Override public void setZ( double position ) { z = position; } - - @Override - public Vector3 copy() { - return new DoubleVector3(xd(),yd(),zd()); - } - - @Override - public String toString() { - return "[" + xd() + "; " + yd() + "; " + zd() + "]"; - } -} diff --git a/src/main/java/sc/iview/vector/DoubleVector4.java b/src/main/java/sc/iview/vector/DoubleVector4.java deleted file mode 100644 index b1c4ec75..00000000 --- a/src/main/java/sc/iview/vector/DoubleVector4.java +++ /dev/null @@ -1,76 +0,0 @@ -/*- - * #%L - * Scenery-backed 3D visualization package for ImageJ. - * %% - * Copyright (C) 2016 - 2020 SciView 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 sc.iview.vector; - -/** - * {@link Vector4} backed by three {@code double}s. - * - * @author Kyle Harrington - */ -public class DoubleVector4 implements Vector4 { - - private double x, y, z, w; - - public DoubleVector4(double x, double y, double z, double w ) { - this.x = x; - this.y = y; - this.z = z; - this.w = w; - } - - @Override public float xf() { return (float) x; } - @Override public float yf() { return (float) y; } - @Override public float zf() { return (float) z; } - @Override public float wf() { return (float) w; } - - @Override public void setX( float position ) { x = position; } - @Override public void setY( float position ) { y = position; } - @Override public void setZ( float position ) { z = position; } - @Override public void setW( float position ) { w = position; } - - @Override public double xd() { return x; } - @Override public double yd() { return y; } - @Override public double zd() { return z; } - @Override public double wd() { return w; } - - @Override public void setX( double position ) { x = position; } - @Override public void setY( double position ) { y = position; } - @Override public void setZ( double position ) { z = position; } - @Override public void setW( double position ) { w = position; } - - @Override - public Vector4 copy() { - return new DoubleVector4(xd(),yd(),zd(),wd()); - } - - @Override - public String toString() { - return "[" + xd() + "; " + yd() + "; " + zd() + "; " + wd() + "]"; - } -} diff --git a/src/main/java/sc/iview/vector/FloatVector3.java b/src/main/java/sc/iview/vector/FloatVector3.java deleted file mode 100644 index 4c57084a..00000000 --- a/src/main/java/sc/iview/vector/FloatVector3.java +++ /dev/null @@ -1,64 +0,0 @@ -/*- - * #%L - * Scenery-backed 3D visualization package for ImageJ. - * %% - * Copyright (C) 2016 - 2020 SciView 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 sc.iview.vector; - -/** - * {@link Vector3} backed by three {@code float}s. - * - * @author Curtis Rueden - * @author Kyle Harrington - */ -public class FloatVector3 implements Vector3 { - - private float x, y, z; - - public FloatVector3( float x, float y, float z ) { - this.x = x; - this.y = y; - this.z = z; - } - - @Override public float xf() { return x; } - @Override public float yf() { return y; } - @Override public float zf() { return z; } - - @Override public void setX( float position ) { x = position; } - @Override public void setY( float position ) { y = position; } - @Override public void setZ( float position ) { z = position; } - - @Override - public Vector3 copy() { - return new FloatVector3(xf(),yf(),zf()); - } - - @Override - public String toString() { - return "[" + xf() + "; " + yf() + "; " + zf() + "]"; - } -} diff --git a/src/main/java/sc/iview/vector/FloatVector4.java b/src/main/java/sc/iview/vector/FloatVector4.java deleted file mode 100644 index 282bdd6d..00000000 --- a/src/main/java/sc/iview/vector/FloatVector4.java +++ /dev/null @@ -1,66 +0,0 @@ -/*- - * #%L - * Scenery-backed 3D visualization package for ImageJ. - * %% - * Copyright (C) 2016 - 2020 SciView 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 sc.iview.vector; - -/** - * {@link Vector4} backed by three {@code float}s. - * - * @author Kyle Harrington - */ -public class FloatVector4 implements Vector4 { - - private float x, y, z, w; - - public FloatVector4(float x, float y, float z, float w ) { - this.x = x; - this.y = y; - this.z = z; - this.w = w; - } - - @Override public float xf() { return x; } - @Override public float yf() { return y; } - @Override public float zf() { return z; } - @Override public float wf() { return w; } - - @Override public void setX( float position ) { x = position; } - @Override public void setY( float position ) { y = position; } - @Override public void setZ( float position ) { z = position; } - @Override public void setW( float position ) { w = position; } - - @Override - public Vector4 copy() { - return new FloatVector4(xf(),yf(),zf(),wf()); - } - - @Override - public String toString() { - return "[" + xf() + "; " + yf() + "; " + zf() + "; " + wf() + "]"; - } -} diff --git a/src/main/java/sc/iview/vector/JOMLVector3.java b/src/main/java/sc/iview/vector/JOMLVector3.java deleted file mode 100644 index 855ca1fd..00000000 --- a/src/main/java/sc/iview/vector/JOMLVector3.java +++ /dev/null @@ -1,75 +0,0 @@ -/*- - * #%L - * Scenery-backed 3D visualization package for ImageJ. - * %% - * Copyright (C) 2016 - 2020 SciView 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 sc.iview.vector; - -import org.joml.Vector3f; - -/** - * {@link Vector3} backed by a JOML {@link Vector3f}. - * - * @author Kyle Harrington - * @author Curtis Rueden - */ -public class JOMLVector3 implements Vector3 { - - private Vector3f source; - - public JOMLVector3( float x, float y, float z ) { - this( new Vector3f( x, y, z ) ); - } - - public JOMLVector3( Vector3f source ) { - this.source = source; - } - - public Vector3f source() { return source; } - - @Override public float xf() { return source.x(); } - @Override public float yf() { return source.y(); } - @Override public float zf() { return source.z(); } - - @Override public void setX( float position ) { source.set( position, yf(), zf() ); } - @Override public void setY( float position ) { source.set( xf(), position, zf() ); } - @Override public void setZ( float position ) { source.set( xf(), yf(), position ); } - - @Override - public Vector3 copy() { - return new JOMLVector3(xf(),yf(),zf()); - } - - @Override - public String toString() { - return "[" + xf() + "; " + yf() + "; " + zf() + "]"; - } - - public static Vector3f convert( Vector3 v ) { - if( v instanceof JOMLVector3 ) return (( JOMLVector3 ) v).source(); - return new Vector3f( v.xf(), v.yf(), v.zf() ); - } -} diff --git a/src/main/java/sc/iview/vector/JOMLVector4.java b/src/main/java/sc/iview/vector/JOMLVector4.java deleted file mode 100644 index ed45f396..00000000 --- a/src/main/java/sc/iview/vector/JOMLVector4.java +++ /dev/null @@ -1,76 +0,0 @@ -/*- - * #%L - * Scenery-backed 3D visualization package for ImageJ. - * %% - * Copyright (C) 2016 - 2020 SciView 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 sc.iview.vector; - -import org.joml.Vector4f; - -/** - * {@link Vector4} backed by a JOML {@link Vector4f}. - * - * @author Kyle Harrington - */ -public class JOMLVector4 implements Vector4 { - - private Vector4f source; - - public JOMLVector4(float x, float y, float z, float w ) { - this( new Vector4f( x, y, z, w ) ); - } - - public JOMLVector4(Vector4f source ) { - this.source = source; - } - - public Vector4f source() { return source; } - - @Override public float xf() { return source.x(); } - @Override public float yf() { return source.y(); } - @Override public float zf() { return source.z(); } - @Override public float wf() { return source.w(); } - - @Override public void setX( float position ) { source.set( position, yf(), zf(), wf() ); } - @Override public void setY( float position ) { source.set( xf(), position, zf(), wf() ); } - @Override public void setZ( float position ) { source.set( xf(), yf(), position, wf() ); } - @Override public void setW( float position ) { source.set( xf(), yf(), zf(), position ); } - - @Override - public Vector4 copy() { - return new JOMLVector4(xf(),yf(),zf(),wf()); - } - - @Override - public String toString() { - return "[" + xf() + "; " + yf() + "; " + zf() + "; " + wf() + "]"; - } - - public static Vector4f convert( Vector4 v ) { - if( v instanceof JOMLVector4) return ((JOMLVector4) v).source(); - return new Vector4f( v.xf(), v.yf(), v.zf(), v.wf() ); - } -} diff --git a/src/main/java/sc/iview/vector/Vector3.java b/src/main/java/sc/iview/vector/Vector3.java deleted file mode 100644 index d65a0f83..00000000 --- a/src/main/java/sc/iview/vector/Vector3.java +++ /dev/null @@ -1,344 +0,0 @@ -/*- - * #%L - * Scenery-backed 3D visualization package for ImageJ. - * %% - * Copyright (C) 2016 - 2020 SciView 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 sc.iview.vector; - -import net.imglib2.Localizable; -import net.imglib2.RealLocalizable; -import net.imglib2.RealPositionable; - -/** - * Interface for 3D vectors. - * - * @author Kyle Harrington - * @author Curtis Rueden - */ -public interface Vector3 extends RealLocalizable, RealPositionable { - - // -- Vector3 methods -- - - float xf(); - float yf(); - float zf(); - - default void moveX(float distance) { setX( xf() + distance ); } - default void moveY(float distance) { setY( yf() + distance ); } - default void moveZ(float distance) { setZ( zf() + distance ); } - default void move( float xDist, float yDist, float zDist ) { - moveX( xDist ); - moveY( yDist ); - moveZ( zDist ); - } - - void setX(float position); - void setY(float position); - void setZ(float position); - - default void setPosition( float x, float y, float z ) { - setX( x ); - setY( y ); - setZ( z ); - } - - default double xd() { return xf(); } - default double yd() { return yf(); } - default double zd() { return zf(); } - - default void moveX(double distance) { setX( xd() + distance ); } - default void moveY(double distance) { setY( yd() + distance ); } - default void moveZ(double distance) { setZ( zd() + distance ); } - default void move( double xDist, double yDist, double zDist ) { - moveX( xDist ); - moveY( yDist ); - moveZ( zDist ); - } - - default void setX(double position) { setX((float) position); } - default void setY(double position) { setY((float) position); } - default void setZ(double position) { setZ((float) position); } - - default void setPosition( double x, double y, double z ) { - setX( x ); - setY( y ); - setZ( z ); - } - - // -- RealLocalizable methods -- - - @Override - default void localize( float[] position ) { - position[0] = xf(); - position[1] = yf(); - position[2] = zf(); - } - - @Override - default void localize( double[] position ) { - position[0] = xd(); - position[1] = yd(); - position[2] = zd(); - } - - @Override - default float getFloatPosition( int d ) { - if( d == 0 ) return xf(); - if( d == 1 ) return yf(); - if( d == 2 ) return zf(); - throw new IndexOutOfBoundsException( "" + d ); - } - - @Override - default double getDoublePosition( int d ) { - if( d == 0 ) return xd(); - if( d == 1 ) return yd(); - if( d == 2 ) return zd(); - throw new IndexOutOfBoundsException( "" + d ); - } - - // -- RealPositionable methods -- - - @Override - default void move( float distance, int d ) { - if( d == 0 ) moveX( distance ); - else if( d == 1 ) moveY( distance ); - else if( d == 2 ) moveZ( distance ); - else throw new IndexOutOfBoundsException( "" + d ); - } - - @Override - default void move( double distance, int d ) { - if( d == 0 ) moveX( distance ); - else if( d == 1 ) moveY( distance ); - else if( d == 2 ) moveZ( distance ); - else throw new IndexOutOfBoundsException( "" + d ); - } - - @Override - default void move( RealLocalizable distance ) { - moveX( distance.getDoublePosition( 0 ) ); - moveY( distance.getDoublePosition( 1 ) ); - moveZ( distance.getDoublePosition( 2 ) ); - } - - @Override - default void move( float[] distance ) { - moveX( distance[0] ); - moveY( distance[1] ); - moveZ( distance[2] ); - } - - @Override - default void move( double[] distance ) { - moveX( distance[0] ); - moveY( distance[1] ); - moveZ( distance[2] ); - } - - @Override - default void setPosition( RealLocalizable localizable ) { - setX( localizable.getDoublePosition( 0 ) ); - setY( localizable.getDoublePosition( 1 ) ); - setZ( localizable.getDoublePosition( 2 ) ); - } - - @Override - default void setPosition( float[] position ) { - setX( position[0] ); - setY( position[1] ); - setZ( position[2] ); - } - - @Override - default void setPosition( double[] position ) { - setX( position[0] ); - setY( position[1] ); - setZ( position[2] ); - } - - @Override - default void setPosition( float position, int d ) { - if( d == 0 ) setX( position ); - else if( d == 1 ) setY( position ); - else if( d == 2 ) setZ( position ); - else throw new IndexOutOfBoundsException( "" + d ); - } - - @Override - default void setPosition( double position, int d ) { - if( d == 0 ) setX( position ); - else if( d == 1 ) setY( position ); - else if( d == 2 ) setZ( position ); - else throw new IndexOutOfBoundsException( "" + d ); - } - - // -- Positionable methods -- - - @Override - default void fwd( int d ) { move( 1, d ); } - @Override - default void bck( int d ) { move( 1, d ); } - - @Override - default void move( int distance, int d ) { - move( ( double ) distance, d ); - } - - @Override - default void move( long distance, int d ) { - move( ( double ) distance, d ); - } - - @Override - default void move( Localizable distance ) { - moveX( distance.getDoublePosition( 0 ) ); - moveY( distance.getDoublePosition( 1 ) ); - moveZ( distance.getDoublePosition( 2 ) ); - } - - @Override - default void move( int[] distance ) { - moveX( (double) distance[0] ); - moveY( (double) distance[1] ); - moveZ( (double) distance[2] ); - } - - @Override - default void move( long[] distance ) { - moveX( (double) distance[0] ); - moveY( (double) distance[1] ); - moveZ( (double) distance[2] ); - } - - @Override - default void setPosition( Localizable localizable ) { - setX( localizable.getDoublePosition( 0 ) ); - setY( localizable.getDoublePosition( 1 ) ); - setZ( localizable.getDoublePosition( 2 ) ); - } - - @Override - default void setPosition( int[] position ) { - setX( (double) position[0] ); - setY( (double) position[1] ); - setZ( (double) position[2] ); - } - - @Override - default void setPosition( long[] position ) { - setX( (double) position[0] ); - setY( (double) position[1] ); - setZ( (double) position[2] ); - } - - @Override - default void setPosition( int position, int d ) { - setPosition( ( double ) position, d ); - } - - @Override - default void setPosition( long position, int d ) { - setPosition( ( double ) position, d ); - } - - // -- EuclideanSpace methods -- - - @Override - default int numDimensions() { return 3; } - - // Extra convenience methods - default double getLength() { - return Math.sqrt( getDoublePosition(0) * getDoublePosition(0) + getDoublePosition(1) * getDoublePosition(1) + getDoublePosition(2) * getDoublePosition(2) ); - } - - default Vector3 add(Vector3 p2) { - Vector3 result = this.copy(); - result.moveX(p2.getDoublePosition(0)); - result.moveY(p2.getDoublePosition(1)); - result.moveZ(p2.getDoublePosition(2)); - return result; - } - - default Vector3 minus(Vector3 p2) { - Vector3 result = this.copy(); - result.moveX(-p2.getDoublePosition(0)); - result.moveY(-p2.getDoublePosition(1)); - result.moveZ(-p2.getDoublePosition(2)); - return result; - } - - default Vector3 multiply(float s) { - Vector3 result = this.copy(); - result.setPosition( result.getDoublePosition(0) * s, 0 ); - result.setPosition( result.getDoublePosition(1) * s, 1 ); - result.setPosition( result.getDoublePosition(2) * s, 2 ); - return result; - } - - default float[] asFloatArray() { - float[] a = new float[3]; - a[0] = xf(); - a[1] = yf(); - a[2] = zf(); - return a; - } - - default double[] asDoubleArray() { - double[] a = new double[3]; - a[0] = xd(); - a[1] = yd(); - a[2] = zd(); - return a; - } - - default Vector3 cross(Vector3 v2) { - return new JOMLVector3(JOMLVector3.convert(this).cross(JOMLVector3.convert(v2))); - } - - default Vector3 elmul(Vector3 v2) { - Vector3 r = this.copy(); - r.setX( r.xf() * v2.xf() ); - r.setY( r.yf() * v2.yf() ); - r.setZ( r.zf() * v2.zf() ); - return r; - } - - default float dot(Vector3 v2) { - return ( this.xf() * v2.xf() + this.yf() * v2.yf() + this.zf() * v2.zf() ); - } - - default Vector3 normalize() { - Vector3 r = this.copy(); - double f = 1 / this.getLength(); - r.setX(r.xf() * f); - r.setY(r.yf() * f); - r.setZ(r.zf() * f); - return r; - } - - Vector3 copy(); -} diff --git a/src/main/java/sc/iview/vector/Vector4.java b/src/main/java/sc/iview/vector/Vector4.java deleted file mode 100644 index a640cbab..00000000 --- a/src/main/java/sc/iview/vector/Vector4.java +++ /dev/null @@ -1,384 +0,0 @@ -/*- - * #%L - * Scenery-backed 3D visualization package for ImageJ. - * %% - * Copyright (C) 2016 - 2020 SciView 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 sc.iview.vector; - -import net.imglib2.Localizable; -import net.imglib2.RealLocalizable; -import net.imglib2.RealPositionable; - -/** - * Interface for 4D vectors. - * - * @author Kyle Harrington - */ -public interface Vector4 extends RealLocalizable, RealPositionable { - - // -- Vector3 methods -- - - float xf(); - float yf(); - float zf(); - float wf(); - - default void moveX(float distance) { setX( xf() + distance ); } - default void moveY(float distance) { setY( yf() + distance ); } - default void moveZ(float distance) { setZ( zf() + distance ); } - default void moveW(float distance) { setZ( wf() + distance ); } - default void move(float xDist, float yDist, float zDist, float wDist) { - moveX( xDist ); - moveY( yDist ); - moveZ( zDist ); - moveW( wDist ); - } - - void setX(float position); - void setY(float position); - void setZ(float position); - void setW(float position); - - default void setPosition(float x, float y, float z, float w) { - setX( x ); - setY( y ); - setZ( z ); - setW( w ); - } - - default double xd() { return xf(); } - default double yd() { return yf(); } - default double zd() { return zf(); } - default double wd() { return wf(); } - - default void moveX(double distance) { setX( xd() + distance ); } - default void moveY(double distance) { setY( yd() + distance ); } - default void moveZ(double distance) { setZ( zd() + distance ); } - default void moveW(double distance) { setW( wd() + distance ); } - default void move(double xDist, double yDist, double zDist, double wDist) { - moveX( xDist ); - moveY( yDist ); - moveZ( zDist ); - moveW( wDist ); - } - - default void setX(double position) { setX((float) position); } - default void setY(double position) { setY((float) position); } - default void setZ(double position) { setZ((float) position); } - default void setW(double position) { setW((float) position); } - - default void setPosition(double x, double y, double z, double w) { - setX( x ); - setY( y ); - setZ( z ); - setW( w ); - } - - // -- RealLocalizable methods -- - - @Override - default void localize(float[] position) { - position[0] = xf(); - position[1] = yf(); - position[2] = zf(); - position[3] = wf(); - } - - @Override - default void localize(double[] position) { - position[0] = xd(); - position[1] = yd(); - position[2] = zd(); - position[3] = wd(); - } - - @Override - default float getFloatPosition(int d) { - if( d == 0 ) return xf(); - if( d == 1 ) return yf(); - if( d == 2 ) return zf(); - if( d == 3 ) return wf(); - throw new IndexOutOfBoundsException( "" + d ); - } - - @Override - default double getDoublePosition(int d) { - if( d == 0 ) return xd(); - if( d == 1 ) return yd(); - if( d == 2 ) return zd(); - if( d == 3 ) return wd(); - throw new IndexOutOfBoundsException( "" + d ); - } - - // -- RealPositionable methods -- - - @Override - default void move(float distance, int d) { - if( d == 0 ) moveX( distance ); - else if( d == 1 ) moveY( distance ); - else if( d == 2 ) moveZ( distance ); - else if( d == 3 ) moveW( distance ); - else throw new IndexOutOfBoundsException( "" + d ); - } - - @Override - default void move(double distance, int d) { - if( d == 0 ) moveX( distance ); - else if( d == 1 ) moveY( distance ); - else if( d == 2 ) moveZ( distance ); - else if( d == 3 ) moveW( distance ); - else throw new IndexOutOfBoundsException( "" + d ); - } - - @Override - default void move(RealLocalizable distance) { - moveX( distance.getDoublePosition( 0 ) ); - moveY( distance.getDoublePosition( 1 ) ); - moveZ( distance.getDoublePosition( 2 ) ); - moveW( distance.getDoublePosition( 3 ) ); - } - - @Override - default void move(float[] distance) { - moveX( distance[0] ); - moveY( distance[1] ); - moveZ( distance[2] ); - moveW( distance[3] ); - } - - @Override - default void move(double[] distance) { - moveX( distance[0] ); - moveY( distance[1] ); - moveZ( distance[2] ); - moveW( distance[3] ); - } - - @Override - default void setPosition(RealLocalizable localizable) { - setX( localizable.getDoublePosition( 0 ) ); - setY( localizable.getDoublePosition( 1 ) ); - setZ( localizable.getDoublePosition( 2 ) ); - setW( localizable.getDoublePosition( 3 ) ); - } - - @Override - default void setPosition(float[] position) { - setX( position[0] ); - setY( position[1] ); - setZ( position[2] ); - setW( position[3] ); - } - - @Override - default void setPosition(double[] position) { - setX( position[0] ); - setY( position[1] ); - setZ( position[2] ); - setW( position[3] ); - } - - @Override - default void setPosition(float position, int d) { - if( d == 0 ) setX( position ); - else if( d == 1 ) setY( position ); - else if( d == 2 ) setZ( position ); - else if( d == 3 ) setW( position ); - else throw new IndexOutOfBoundsException( "" + d ); - } - - @Override - default void setPosition(double position, int d) { - if( d == 0 ) setX( position ); - else if( d == 1 ) setY( position ); - else if( d == 2 ) setZ( position ); - else if( d == 3 ) setW( position ); - else throw new IndexOutOfBoundsException( "" + d ); - } - - // -- Positionable methods -- - - @Override - default void fwd(int d) { move( 1, d ); } - @Override - default void bck(int d) { move( 1, d ); } - - @Override - default void move(int distance, int d) { - move( ( double ) distance, d ); - } - - @Override - default void move(long distance, int d) { - move( ( double ) distance, d ); - } - - @Override - default void move(Localizable distance) { - moveX( distance.getDoublePosition( 0 ) ); - moveY( distance.getDoublePosition( 1 ) ); - moveZ( distance.getDoublePosition( 2 ) ); - moveW( distance.getDoublePosition( 3 ) ); - } - - @Override - default void move(int[] distance) { - moveX( (double) distance[0] ); - moveY( (double) distance[1] ); - moveZ( (double) distance[2] ); - moveW( (double) distance[3] ); - } - - @Override - default void move(long[] distance) { - moveX( (double) distance[0] ); - moveY( (double) distance[1] ); - moveZ( (double) distance[2] ); - moveW( (double) distance[3] ); - } - - @Override - default void setPosition(Localizable localizable) { - setX( localizable.getDoublePosition( 0 ) ); - setY( localizable.getDoublePosition( 1 ) ); - setZ( localizable.getDoublePosition( 2 ) ); - setW( localizable.getDoublePosition( 3 ) ); - } - - @Override - default void setPosition(int[] position) { - setX( (double) position[0] ); - setY( (double) position[1] ); - setZ( (double) position[2] ); - setW( (double) position[3] ); - } - - @Override - default void setPosition(long[] position) { - setX( (double) position[0] ); - setY( (double) position[1] ); - setZ( (double) position[2] ); - setW( (double) position[3] ); - } - - @Override - default void setPosition(int position, int d) { - setPosition( ( double ) position, d ); - } - - @Override - default void setPosition(long position, int d) { - setPosition( ( double ) position, d ); - } - - // -- EuclideanSpace methods -- - - @Override - default int numDimensions() { return 3; } - - // Extra convenience methods - default double getLength() { - return Math.sqrt( getDoublePosition(0) * getDoublePosition(0) + // - getDoublePosition(1) * getDoublePosition(1) + // - getDoublePosition(2) * getDoublePosition(2) + // - getDoublePosition(3) * getDoublePosition(3) ); - } - - default Vector4 add(Vector4 p2) { - Vector4 result = this.copy(); - result.moveX(p2.getDoublePosition(0)); - result.moveY(p2.getDoublePosition(1)); - result.moveZ(p2.getDoublePosition(2)); - result.moveW(p2.getDoublePosition(3)); - return result; - } - - default Vector4 minus(Vector4 p2) { - Vector4 result = this.copy(); - result.moveX(-p2.getDoublePosition(0)); - result.moveY(-p2.getDoublePosition(1)); - result.moveZ(-p2.getDoublePosition(2)); - result.moveW(-p2.getDoublePosition(3)); - return result; - } - - default Vector4 multiply(float s) { - Vector4 result = this.copy(); - result.setPosition( result.getDoublePosition(0) * s, 0 ); - result.setPosition( result.getDoublePosition(1) * s, 1 ); - result.setPosition( result.getDoublePosition(2) * s, 2 ); - result.setPosition( result.getDoublePosition(3) * s, 3 ); - return result; - } - - default float[] asFloatArray() { - float[] a = new float[4]; - a[0] = xf(); - a[1] = yf(); - a[2] = zf(); - a[3] = wf(); - return a; - } - - default double[] asDoubleArray() { - double[] a = new double[4]; - a[0] = xd(); - a[1] = yd(); - a[2] = zd(); - a[3] = wd(); - return a; - } - - default Vector4 cross(Vector4 v2) { - JOMLVector4 v = new JOMLVector4(JOMLVector4.convert(this)); - return v.cross(new JOMLVector4(JOMLVector4.convert(v2))); - } - - default Vector4 elmul(Vector4 v2) { - Vector4 r = this.copy(); - r.setX( r.xf() * v2.xf() ); - r.setY( r.yf() * v2.yf() ); - r.setZ( r.zf() * v2.zf() ); - r.setW( r.wf() * v2.wf() ); - return r; - } - - default float dot(Vector4 v2) { - return ( this.xf() * v2.xf() + this.yf() * v2.yf() + this.zf() * v2.zf() + this.wf() * v2.wf() ); - } - - default Vector4 normalize() { - Vector4 r = this.copy(); - double f = 1 / this.getLength(); - r.setX(r.xf() * f); - r.setY(r.yf() * f); - r.setZ(r.zf() * f); - r.setW(r.wf() * f); - return r; - } - - Vector4 copy(); -} diff --git a/src/test/tests/sc/iview/test/SciViewTest.java b/src/test/tests/sc/iview/test/SciViewTest.java index 84f6be0f..87720af5 100644 --- a/src/test/tests/sc/iview/test/SciViewTest.java +++ b/src/test/tests/sc/iview/test/SciViewTest.java @@ -39,7 +39,6 @@ import org.scijava.thread.ThreadService; import sc.iview.SciView; import sc.iview.SciViewService; -import sc.iview.vector.JOMLVector3; public class SciViewTest { @@ -83,7 +82,7 @@ public void nestedNodeDeletionTest() throws Exception { final Sphere sphere = new Sphere( 1, 20 ); sphere.setMaterial( material ); - sphere.setPosition( JOMLVector3.convert( new JOMLVector3(0,0,0) ) ); + sphere.setPosition( new Vector3f(0,0,0) ); //sphere.setParent(group); group.addChild(sphere); sciView.addNode(group); From 005c220259d35c8a787d33b2aa3d82fba7d7c8fd Mon Sep 17 00:00:00 2001 From: Ulrik Guenther Date: Mon, 16 Nov 2020 19:41:13 +0100 Subject: [PATCH 20/23] GameOfLife3D: Port to Kotlin --- .../sc/iview/commands/demo/GameOfLife3D.java | 380 ------------------ .../sc/iview/commands/demo/GameOfLife3D.kt | 346 ++++++++++++++++ 2 files changed, 346 insertions(+), 380 deletions(-) delete mode 100644 src/main/java/sc/iview/commands/demo/GameOfLife3D.java create mode 100644 src/main/java/sc/iview/commands/demo/GameOfLife3D.kt diff --git a/src/main/java/sc/iview/commands/demo/GameOfLife3D.java b/src/main/java/sc/iview/commands/demo/GameOfLife3D.java deleted file mode 100644 index 83589e7e..00000000 --- a/src/main/java/sc/iview/commands/demo/GameOfLife3D.java +++ /dev/null @@ -1,380 +0,0 @@ -/*- - * #%L - * Scenery-backed 3D visualization package for ImageJ. - * %% - * Copyright (C) 2016 - 2020 SciView 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 sc.iview.commands.demo; - -import bdv.BigDataViewer; -import bdv.util.RandomAccessibleIntervalSource; -import bdv.viewer.SourceAndConverter; -import cleargl.GLVector; -import graphics.scenery.BoundingGrid; -import graphics.scenery.volumes.Volume; -import ij.gui.GenericDialog; -import ij.gui.NonBlockingGenericDialog; -import net.imglib2.Cursor; -import net.imglib2.RandomAccess; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.Sampler; -import net.imglib2.img.Img; -import net.imglib2.img.array.ArrayImgs; -import net.imglib2.type.numeric.integer.UnsignedByteType; -import org.joml.Vector3f; -import org.scijava.command.Command; -import org.scijava.command.CommandService; -import org.scijava.command.InteractiveCommand; -import org.scijava.event.EventHandler; -import org.scijava.plugin.Menu; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.Plugin; -import org.scijava.widget.Button; -import org.scijava.widget.NumberWidget; -import sc.iview.SciView; -import sc.iview.event.NodeRemovedEvent; - -import javax.swing.*; - -import java.util.HashMap; - -import static sc.iview.commands.MenuWeights.DEMO; -import static sc.iview.commands.MenuWeights.DEMO_GAME_OF_LIFE; - -/** - * Conway's Game of Life—in 3D! - * - * @author Curtis Rueden - * @author Kyle Harrington - */ -@Plugin(type = Command.class, menuRoot = "SciView", // - menu = { @Menu(label = "Demo", weight = DEMO), // - @Menu(label = "Game of Life 3D", weight = DEMO_GAME_OF_LIFE) }) -public class GameOfLife3D implements Command { - - private static final int ALIVE = 255; - private static final int DEAD = 16; - - private static final String SIX = "6-connected"; - private static final String EIGHTEEN = "18-connected"; - private static final String TWENTY_SIX = "26-connected"; - - @Parameter - private SciView sciView; - - @Parameter(label = "Starvation threshold", min = "0", max = "26", persist = false) - private int starvation = 5; - - @Parameter(label = "Birth threshold", min = "0", max = "26", persist = false) - private int birth = 6; - - @Parameter(label = "Suffocation threshold", min = "0", max = "26", persist = false) - private int suffocation = 9; - - @Parameter(choices = { SIX, EIGHTEEN, TWENTY_SIX }, persist = false) - private String connectedness = TWENTY_SIX; - - @Parameter(label = "Initial saturation % when randomizing", min = "1", max = "99", style = NumberWidget.SCROLL_BAR_STYLE, persist = false) - private int saturation = 10; - -// @Parameter(label = "Play speed", min = "1", max="100", style = NumberWidget.SCROLL_BAR_STYLE, persist = false) - private int playSpeed = 10; -// - @Parameter(callback = "iterate") - private Button iterate; - - @Parameter(callback = "randomize") - private Button randomize; - - @Parameter(callback = "play") - private Button play; - - @Parameter(callback = "pause") - private Button pause; - - private int w = 64, h = 64, d = 64; - private Img field; - private String name; - private float[] voxelDims; - private Volume volume; - - /** Temporary buffer for use while recomputing the image. */ - private boolean[] bits = new boolean[w * h * d]; - private GenericDialog dialog; - - /** Repeatedly iterates the simulation until stopped **/ - public void play() { - sciView.animate( playSpeed, this::iterate); - } - - /** Stops the simulation **/ - public void pause() { - sciView.stopAnimation(); - } - - /** Randomizes a new bit field. */ - public void randomize() { - final Cursor cursor = field.localizingCursor(); - final double chance = saturation / 100d; - while( cursor.hasNext() ) { - final boolean alive = Math.random() <= chance; - cursor.next().set( alive ? ALIVE : DEAD ); - } - updateVolume(); - } - - /** Performs one iteration of the game. */ - public void iterate() { - final int connected; - switch( connectedness ) { - case SIX: connected = 6; break; - case EIGHTEEN: connected = 18; break; - default: connected = 26; break; - } - - // compute the new image field - final RandomAccess access = field.randomAccess(); - - //RandomAccess access = ((SourceAndConverter) ((Volume.VolumeDataSource.RAIISource) volume.getDataSource()).getSources().get(0)).getSpimSource().getSource(0, 0).randomAccess(); - - for( int z = 0; z < d; z++ ) { - for( int y = 0; y < h; y++ ) { - for( int x = 0; x < w; x++ ) { - final int i = z * w * h + y * w + x; - final int n = neighbors( access, x, y, z, connected ); - access.setPosition( x, 0 ); - access.setPosition( y, 1 ); - access.setPosition( y, 2 ); - if( alive( access ) ) { - // Living cell stays alive within (starvation, suffocation). - bits[i] = n > starvation && n < suffocation; - } else { - // New cell forms within [birth, suffocation). - bits[i] = n >= birth && n < suffocation; - } - } - } - } - - // write the new bit field into the image - final Cursor cursor = field.localizingCursor(); - while( cursor.hasNext() ) { - cursor.fwd(); - final int x = cursor.getIntPosition( 0 ); - final int y = cursor.getIntPosition( 1 ); - final int z = cursor.getIntPosition( 2 ); - final boolean alive = bits[z * w * h + y * w + x]; - cursor.get().set( alive ? ALIVE : DEAD ); - } - -// for( int z = 0; z < d; z++ ) { -// for( int y = 0; y < h; y++ ) { -// for( int x = 0; x < w; x++ ) { -// access.setPosition( x, 0 ); -// access.setPosition( y, 1 ); -// access.setPosition( y, 2 ); -// final boolean alive = bits[z * w * h + y * w + x]; -// access.get().set( alive ? ALIVE : DEAD ); -// } -// } -// } - - updateVolume(); - } - - @Override - public void run() { - field = ArrayImgs.unsignedBytes( w, h, d ); - randomize(); - - dialog = new GenericDialog("Game of Life 3D"); - dialog.addNumericField("Starvation threshold", starvation, 0); - dialog.addNumericField("Birth threshold", birth, 0); - dialog.addNumericField("Suffocation threshold", suffocation, 0); - dialog.addNumericField("Initial saturation % when randomizing", saturation, 0); - dialog.showDialog(); - - if( dialog.wasCanceled() ) return; - - starvation = (int) dialog.getNextNumber(); - birth = (int) dialog.getNextNumber(); - suffocation = (int) dialog.getNextNumber(); - saturation = (int) dialog.getNextNumber(); - - randomize(); - play(); - -// -// @Parameter(callback = "iterate") -// private Button iterate; -// -// @Parameter(callback = "randomize") -// private Button randomize; -// -// @Parameter(callback = "play") -// private Button play; -// -// @Parameter(callback = "pause") -// private Button pause; - - //play(); - - //eventService.subscribe(this); - } - - - // -- Helper methods -- - - private int neighbors( RandomAccess access, int x, int y, int z, int connected ) { - int n = 0; - // six-connected - n += val( access, x - 1, y, z ); - n += val( access, x + 1, y, z ); - n += val( access, x, y - 1, z ); - n += val( access, x, y + 1, z ); - n += val( access, x, y, z - 1 ); - n += val( access, x, y, z + 1 ); - // eighteen-connected - if( connected >= 18 ) { - n += val( access, x - 1, y - 1, z ); - n += val( access, x + 1, y - 1, z ); - n += val( access, x - 1, y + 1, z ); - n += val( access, x + 1, y + 1, z ); - n += val( access, x - 1, y, z - 1 ); - n += val( access, x + 1, y, z - 1 ); - n += val( access, x - 1, y, z + 1 ); - n += val( access, x + 1, y, z + 1 ); - n += val( access, x, y - 1, z - 1 ); - n += val( access, x, y + 1, z - 1 ); - n += val( access, x, y - 1, z + 1 ); - n += val( access, x, y + 1, z + 1 ); - } - // twenty-six-connected - if( connected == 26 ) { - n += val( access, x - 1, y - 1, z - 1 ); - n += val( access, x + 1, y - 1, z - 1 ); - n += val( access, x - 1, y + 1, z - 1 ); - n += val( access, x + 1, y + 1, z - 1 ); - n += val( access, x - 1, y - 1, z + 1 ); - n += val( access, x + 1, y - 1, z + 1 ); - n += val( access, x - 1, y + 1, z + 1 ); - n += val( access, x + 1, y + 1, z + 1 ); - } - return n; - } - - - - private int val( RandomAccess access, int x, int y, int z ) { - if( x < 0 || x >= w || y < 0 || y >= h || z < 0 || z >= d ) return 0; - access.setPosition( x, 0 ); - access.setPosition( y, 1 ); - access.setPosition( z, 2 ); - return alive( access ) ? 1 : 0; - } - - private boolean alive( final Sampler access ) { - return access.get().get() == ALIVE; - } - - private long tick; - - private void updateVolume() { - if( volume == null ) { - name = "Life Simulation"; - voxelDims = new float[] { 1, 1, 1 }; - volume = ( Volume ) sciView.addVolume( field, name, voxelDims ); - - BoundingGrid bg = new BoundingGrid(); - bg.setNode( volume ); - -// volume.setVoxelSizeX(10.0f); -// volume.setVoxelSizeY(10.0f); -// volume.setVoxelSizeZ(10.0f); - - volume.putAbove(new Vector3f(0.0f, 0.0f, 0.0f)); -// volume.setRenderingMethod(2); - volume.getTransferFunction().addControlPoint(0.0f, 0.0f); - volume.getTransferFunction().addControlPoint(0.4f, 0.3f); - - volume.setName( "Game of Life 3D" ); - - sciView.centerOnNode(volume); - } else { - // NB: Name must be unique each time. - sciView.updateVolume( field, name + "-" + ++tick, voxelDims, volume ); - -// RandomAccessibleIntervalSource newSource = new RandomAccessibleIntervalSource(field, new UnsignedByteType(), name + "-" + ++tick); -// -// SourceAndConverter sourceAndConverter = BigDataViewer.wrapWithTransformedSource( -// new SourceAndConverter<>(newSource, BigDataViewer.createConverterToARGB(new UnsignedByteType()))); -// -// ((Volume.VolumeDataSource.RAISource) volume.getDataSource()).getSources().set(0, sourceAndConverter); -// -// volume.getVolumeManager().notifyUpdate(volume); -// -// volume.setDirty(true); -// volume.setNeedsUpdate(true); -// volume.getVolumeManager().requestRepaint(); - //volume.getCacheControl().prepareNextFrame(); - } - } - - /** - * Stops the animation when the volume node is removed. - * @param event - */ - @EventHandler - private void onNodeRemoved(NodeRemovedEvent event) { - if(event.getNode() == volume) { - sciView.stopAnimation(); - } - } - - /** - * Returns the current Img - */ - public Img getImg() { - return field; - } - - /** - * Returns the scenery volume node. - */ - public Volume getVolume() { - return volume; - } - - public static void main(String... args) throws Exception { - SciView sv = SciView.create(); - - CommandService command = sv.getScijavaContext().getService(CommandService.class); - - HashMap argmap = new HashMap<>(); - - command.run(GameOfLife3D.class, true, argmap); - } -} diff --git a/src/main/java/sc/iview/commands/demo/GameOfLife3D.kt b/src/main/java/sc/iview/commands/demo/GameOfLife3D.kt new file mode 100644 index 00000000..72650e12 --- /dev/null +++ b/src/main/java/sc/iview/commands/demo/GameOfLife3D.kt @@ -0,0 +1,346 @@ +/*- + * #%L + * Scenery-backed 3D visualization package for ImageJ. + * %% + * Copyright (C) 2016 - 2020 SciView 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 sc.iview.commands.demo + +import graphics.scenery.BoundingGrid +import graphics.scenery.volumes.Volume +import ij.gui.GenericDialog +import net.imglib2.IterableInterval +import net.imglib2.RandomAccess +import net.imglib2.RandomAccessibleInterval +import net.imglib2.Sampler +import net.imglib2.img.Img +import net.imglib2.img.array.ArrayImgs +import net.imglib2.type.numeric.integer.UnsignedByteType +import org.joml.Vector3f +import org.scijava.command.Command +import org.scijava.command.CommandService +import org.scijava.event.EventHandler +import org.scijava.plugin.Menu +import org.scijava.plugin.Parameter +import org.scijava.plugin.Plugin +import org.scijava.widget.Button +import org.scijava.widget.NumberWidget +import sc.iview.SciView +import sc.iview.commands.MenuWeights +import sc.iview.event.NodeRemovedEvent +import java.util.* + +/** + * Conway's Game of Lifein 3D! + * + * @author Curtis Rueden + * @author Kyle Harrington + * @author Ulrik Guenther + */ +@Plugin(type = Command::class, menuRoot = "SciView", menu = [Menu(label = "Demo", weight = MenuWeights.DEMO), Menu(label = "Game of Life 3D", weight = MenuWeights.DEMO_GAME_OF_LIFE)]) +class GameOfLife3D : Command { + @Parameter + private lateinit var sciView: SciView + + @Parameter(label = "Starvation threshold", min = "0", max = "26", persist = false) + private var starvation = 5 + + @Parameter(label = "Birth threshold", min = "0", max = "26", persist = false) + private var birth = 6 + + @Parameter(label = "Suffocation threshold", min = "0", max = "26", persist = false) + private var suffocation = 9 + + @Parameter(choices = [SIX, EIGHTEEN, TWENTY_SIX], persist = false) + private var connectedness = TWENTY_SIX + + @Parameter(label = "Initial saturation % when randomizing", min = "1", max = "99", style = NumberWidget.SCROLL_BAR_STYLE, persist = false) + private var saturation = 10 + + // @Parameter(label = "Play speed", min = "1", max="100", style = NumberWidget.SCROLL_BAR_STYLE, persist = false) + private val playSpeed = 10 + + // + @Parameter(callback = "iterate") + private lateinit var iterate: Button + + @Parameter(callback = "randomize") + private lateinit var randomize: Button + + @Parameter(callback = "play") + private lateinit var play: Button + + @Parameter(callback = "pause") + private lateinit var pause: Button + private val w = 64 + private val h = 64 + private val d = 64 + + /** + * Returns the current Img + */ + var img: Img? = null + private set + private var name: String? = null + private var voxelDims: FloatArray = floatArrayOf(1.0f, 1.0f, 1.0f) + + /** + * Returns the scenery volume node. + */ + var volume: Volume? = null + private set + + /** Temporary buffer for use while recomputing the image. */ + private val bits = BooleanArray(w * h * d) + private var dialog: GenericDialog? = null + + /** Repeatedly iterates the simulation until stopped */ + fun play() { + sciView.animate(playSpeed) { iterate() } + } + + /** Stops the simulation */ + fun pause() { + sciView.stopAnimation() + } + + /** Randomizes a new bit field. */ + fun randomize() { + val cursor = img!!.localizingCursor() + val chance = saturation / 100.0 + while (cursor.hasNext()) { + val alive = Math.random() <= chance + cursor.next().set(if (alive) ALIVE else DEAD) + } + updateVolume() + } + + /** Performs one iteration of the game. */ + fun iterate() { + val connected = when (connectedness) { + SIX -> 6 + EIGHTEEN -> 18 + else -> 26 + } + + // compute the new image field + val access = img!!.randomAccess() + + //RandomAccess access = ((SourceAndConverter) ((Volume.VolumeDataSource.RAIISource) volume.getDataSource()).getSources().get(0)).getSpimSource().getSource(0, 0).randomAccess(); + for (z in 0 until d) { + for (y in 0 until h) { + for (x in 0 until w) { + val i = z * w * h + y * w + x + val n = neighbors(access, x, y, z, connected) + access.setPosition(x, 0) + access.setPosition(y, 1) + access.setPosition(y, 2) + if (alive(access)) { + // Living cell stays alive within (starvation, suffocation). + bits[i] = n > starvation && n < suffocation + } else { + // New cell forms within [birth, suffocation). + bits[i] = n >= birth && n < suffocation + } + } + } + } + + // write the new bit field into the image + val cursor = img!!.localizingCursor() + while (cursor.hasNext()) { + cursor.fwd() + val x = cursor.getIntPosition(0) + val y = cursor.getIntPosition(1) + val z = cursor.getIntPosition(2) + val alive = bits[z * w * h + y * w + x] + cursor.get().set(if (alive) ALIVE else DEAD) + } + +// for( int z = 0; z < d; z++ ) { +// for( int y = 0; y < h; y++ ) { +// for( int x = 0; x < w; x++ ) { +// access.setPosition( x, 0 ); +// access.setPosition( y, 1 ); +// access.setPosition( y, 2 ); +// final boolean alive = bits[z * w * h + y * w + x]; +// access.get().set( alive ? ALIVE : DEAD ); +// } +// } +// } + updateVolume() + } + + override fun run() { + img = ArrayImgs.unsignedBytes(w.toLong(), h.toLong(), d.toLong()) + randomize() + dialog = GenericDialog("Game of Life 3D") + dialog!!.addNumericField("Starvation threshold", starvation.toDouble(), 0) + dialog!!.addNumericField("Birth threshold", birth.toDouble(), 0) + dialog!!.addNumericField("Suffocation threshold", suffocation.toDouble(), 0) + dialog!!.addNumericField("Initial saturation % when randomizing", saturation.toDouble(), 0) + dialog!!.showDialog() + if (dialog!!.wasCanceled()) return + starvation = dialog!!.nextNumber.toInt() + birth = dialog!!.nextNumber.toInt() + suffocation = dialog!!.nextNumber.toInt() + saturation = dialog!!.nextNumber.toInt() + randomize() + play() + +// +// @Parameter(callback = "iterate") +// private Button iterate; +// +// @Parameter(callback = "randomize") +// private Button randomize; +// +// @Parameter(callback = "play") +// private Button play; +// +// @Parameter(callback = "pause") +// private Button pause; + + //play(); + + //eventService.subscribe(this); + } + + // -- Helper methods -- + private fun neighbors(access: RandomAccess, x: Int, y: Int, z: Int, connected: Int): Int { + var n = 0 + // six-connected + n += value(access, x - 1, y, z) + n += value(access, x + 1, y, z) + n += value(access, x, y - 1, z) + n += value(access, x, y + 1, z) + n += value(access, x, y, z - 1) + n += value(access, x, y, z + 1) + // eighteen-connected + if (connected >= 18) { + n += value(access, x - 1, y - 1, z) + n += value(access, x + 1, y - 1, z) + n += value(access, x - 1, y + 1, z) + n += value(access, x + 1, y + 1, z) + n += value(access, x - 1, y, z - 1) + n += value(access, x + 1, y, z - 1) + n += value(access, x - 1, y, z + 1) + n += value(access, x + 1, y, z + 1) + n += value(access, x, y - 1, z - 1) + n += value(access, x, y + 1, z - 1) + n += value(access, x, y - 1, z + 1) + n += value(access, x, y + 1, z + 1) + } + // twenty-six-connected + if (connected == 26) { + n += value(access, x - 1, y - 1, z - 1) + n += value(access, x + 1, y - 1, z - 1) + n += value(access, x - 1, y + 1, z - 1) + n += value(access, x + 1, y + 1, z - 1) + n += value(access, x - 1, y - 1, z + 1) + n += value(access, x + 1, y - 1, z + 1) + n += value(access, x - 1, y + 1, z + 1) + n += value(access, x + 1, y + 1, z + 1) + } + return n + } + + private fun value(access: RandomAccess, x: Int, y: Int, z: Int): Int { + if (x < 0 || x >= w || y < 0 || y >= h || z < 0 || z >= d) return 0 + access.setPosition(x, 0) + access.setPosition(y, 1) + access.setPosition(z, 2) + return if (alive(access)) 1 else 0 + } + + private fun alive(access: Sampler): Boolean { + return access.get().get() == ALIVE + } + + private var tick: Long = 0 + private fun updateVolume() { + if (volume == null) { + name = "Life Simulation" + voxelDims = floatArrayOf(1f, 1f, 1f) + volume = sciView.addVolume(img as RandomAccessibleInterval, name, *voxelDims) as Volume? + val bg = BoundingGrid() + bg.node = volume + +// volume.setVoxelSizeX(10.0f); +// volume.setVoxelSizeY(10.0f); +// volume.setVoxelSizeZ(10.0f); + volume!!.putAbove(Vector3f(0.0f, 0.0f, 0.0f)) + // volume.setRenderingMethod(2); + volume!!.transferFunction.addControlPoint(0.0f, 0.0f) + volume!!.transferFunction.addControlPoint(0.4f, 0.3f) + volume!!.name = "Game of Life 3D" + sciView.centerOnNode(volume) + } else { + // NB: Name must be unique each time. + sciView.updateVolume(img as IterableInterval, name + "-" + ++tick, voxelDims, volume!!) + +// RandomAccessibleIntervalSource newSource = new RandomAccessibleIntervalSource(field, new UnsignedByteType(), name + "-" + ++tick); +// +// SourceAndConverter sourceAndConverter = BigDataViewer.wrapWithTransformedSource( +// new SourceAndConverter<>(newSource, BigDataViewer.createConverterToARGB(new UnsignedByteType()))); +// +// ((Volume.VolumeDataSource.RAISource) volume.getDataSource()).getSources().set(0, sourceAndConverter); +// +// volume.getVolumeManager().notifyUpdate(volume); +// +// volume.setDirty(true); +// volume.setNeedsUpdate(true); +// volume.getVolumeManager().requestRepaint(); + //volume.getCacheControl().prepareNextFrame(); + } + } + + /** + * Stops the animation when the volume node is removed. + * @param event + */ + @EventHandler + private fun onNodeRemoved(event: NodeRemovedEvent) { + if (event.node === volume) { + sciView.stopAnimation() + } + } + + companion object { + private const val ALIVE = 255 + private const val DEAD = 16 + private const val SIX = "6-connected" + private const val EIGHTEEN = "18-connected" + private const val TWENTY_SIX = "26-connected" + @Throws(Exception::class) + @JvmStatic + fun main(args: Array) { + val sv = SciView.create() + val command = sv.scijavaContext!!.getService(CommandService::class.java) + val argmap = HashMap() + command.run(GameOfLife3D::class.java, true, argmap) + } + } +} \ No newline at end of file From 8a801f0388ca66a9316ed0c6d4e18db9c2e26b33 Mon Sep 17 00:00:00 2001 From: Ulrik Guenther Date: Tue, 17 Nov 2020 20:21:54 +0100 Subject: [PATCH 21/23] RotateView: Make rotation work again --- src/main/java/sc/iview/commands/view/RotateView.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/sc/iview/commands/view/RotateView.kt b/src/main/java/sc/iview/commands/view/RotateView.kt index 84777fda..9335b24d 100644 --- a/src/main/java/sc/iview/commands/view/RotateView.kt +++ b/src/main/java/sc/iview/commands/view/RotateView.kt @@ -54,10 +54,9 @@ class RotateView : Command { override fun run() { sciView.animate(30) { - // TODO: Make work again -// sciView.targetArcball?.init(1, 1) -// sciView.targetArcball?.drag(1 + xSpeed, 1 + ySpeed) -// sciView.targetArcball?.end(1 + xSpeed, 1 + ySpeed) + sciView.targetArcball.init(1, 1) + sciView.targetArcball.drag(1 + xSpeed, 1 + ySpeed) + sciView.targetArcball.end(1 + xSpeed, 1 + ySpeed) } } } \ No newline at end of file From 7aaa0335ea7ef9c20cd8a81e908ee154825c7f78 Mon Sep 17 00:00:00 2001 From: Ulrik Guenther Date: Tue, 17 Nov 2020 20:22:33 +0100 Subject: [PATCH 22/23] Add TaskManager, Task, and ProgressPie classes --- src/main/java/sc/iview/SciView.kt | 27 +++++++++++ src/main/java/sc/iview/ui/ProgressPie.kt | 60 ++++++++++++++++++++++++ src/main/java/sc/iview/ui/Task.kt | 3 ++ src/main/java/sc/iview/ui/TaskManager.kt | 40 ++++++++++++++++ 4 files changed, 130 insertions(+) create mode 100644 src/main/java/sc/iview/ui/ProgressPie.kt create mode 100644 src/main/java/sc/iview/ui/Task.kt create mode 100644 src/main/java/sc/iview/ui/TaskManager.kt diff --git a/src/main/java/sc/iview/SciView.kt b/src/main/java/sc/iview/SciView.kt index 084e334e..dbdc1a3b 100644 --- a/src/main/java/sc/iview/SciView.kt +++ b/src/main/java/sc/iview/SciView.kt @@ -114,7 +114,9 @@ import sc.iview.event.NodeChangedEvent import sc.iview.event.NodeRemovedEvent import sc.iview.process.MeshConverter import sc.iview.ui.ContextPopUpNodeChooser +import sc.iview.ui.ProgressPie import sc.iview.ui.REPLPane +import sc.iview.ui.TaskManager import tpietzsch.example2.VolumeViewerOptions import java.awt.* import java.awt.event.* @@ -248,6 +250,8 @@ class SciView : SceneryBase, CalibratedRealInterval { private set private val notAbstractBranchingFunction = Function { node: Node -> node.children.stream().filter(notAbstractNode).collect(Collectors.toList()) } + val taskManager = TaskManager() + // If true, then when a new node is added to the scene, the camera will refocus on this node by default var centerOnNewNodes = false @@ -524,10 +528,33 @@ class SciView : SceneryBase, CalibratedRealInterval { JPopupMenu.setDefaultLightWeightPopupEnabled(false) val swingMenuBar = JMenuBar() SwingJMenuBarCreator().createMenus(menus!!.getMenu("SciView"), swingMenuBar) + val bar = ProgressPie() +// progress.add(bar) + bar.value = 0.0 + bar.minimumSize = Dimension(30, 30) + bar.maximumSize = Dimension(30, 30) + bar.preferredSize = Dimension(30, 30) + val progressLabel = JLabel("") + progressLabel.horizontalAlignment = SwingConstants.RIGHT + swingMenuBar.add(javax.swing.Box.createHorizontalGlue()) + swingMenuBar.add(progressLabel) + swingMenuBar.add(bar) frame!!.jMenuBar = swingMenuBar p.layout = OverlayLayout(p) p.background = Color(50, 48, 47) p.add(sceneryJPanel, BorderLayout.CENTER) + + taskManager.update = { current -> + if(current != null) { + progressLabel.text = "${current.source}: ${current.status} " + bar.value = current.completion.toDouble() + } else { + progressLabel.text = "" + bar.value = 0.0 + } + + bar.repaint() + } sceneryJPanel!!.isVisible = true nodePropertyEditor!!.component // Initialize node property panel val inspectorTree = nodePropertyEditor!!.tree diff --git a/src/main/java/sc/iview/ui/ProgressPie.kt b/src/main/java/sc/iview/ui/ProgressPie.kt new file mode 100644 index 00000000..497225d7 --- /dev/null +++ b/src/main/java/sc/iview/ui/ProgressPie.kt @@ -0,0 +1,60 @@ +package sc.iview.ui + +import graphics.scenery.utils.LazyLogger +import java.awt.Color +import java.awt.Graphics +import java.awt.Graphics2D +import java.awt.Rectangle +import javax.swing.JComponent +import kotlin.math.roundToInt + +class ProgressPie: JComponent() { + class Slice(var value: Double, var color: Color) + private val logger by LazyLogger() + + private var slices = arrayOf( + Slice(0.0, Color.WHITE), Slice(100.0, Color.LIGHT_GRAY) + ) + + init { + isVisible = true + } + + var value = 0.0 + set(value) { + slices[1].value = value + slices[0].value = 100.0 - value + field = value + } + + override fun paintComponent(g: Graphics) { + super.paintComponent(g) + drawPie(g, bounds, slices) + } + + fun drawPie(graphics: Graphics, area: Rectangle, slices: Array) { + val g = graphics.create() as Graphics2D + + var total = 0.0 + for (i in slices.indices) { + total += slices[i].value + } + var curValue = 0.0 + var startAngle: Int + for (i in slices.indices) { + // angles for fillArc start at East, so we move back 90 degrees to start at North + startAngle = (curValue * 360 / total).toInt() + 90 + val arcAngle = (slices[i].value * 360 / total).toInt() + g.color = slices[i].color + + val relativeSize = 0.75f + val size = (area.height * relativeSize).roundToInt() + val centerX = (size*(1.0f-relativeSize)/2.0f).roundToInt() + val centerY = (size*(1.0f-relativeSize)/2.0f).roundToInt() + g.fillArc(centerX, centerY, size, size, startAngle, arcAngle) + curValue += slices[i].value + } + + graphics.dispose() + } +} \ No newline at end of file diff --git a/src/main/java/sc/iview/ui/Task.kt b/src/main/java/sc/iview/ui/Task.kt new file mode 100644 index 00000000..bc98e3bb --- /dev/null +++ b/src/main/java/sc/iview/ui/Task.kt @@ -0,0 +1,3 @@ +package sc.iview.ui + +data class Task(val source: String, var status: String, var completion: Float = 0.0f) \ No newline at end of file diff --git a/src/main/java/sc/iview/ui/TaskManager.kt b/src/main/java/sc/iview/ui/TaskManager.kt new file mode 100644 index 00000000..bbdefe23 --- /dev/null +++ b/src/main/java/sc/iview/ui/TaskManager.kt @@ -0,0 +1,40 @@ +package sc.iview.ui + +import graphics.scenery.utils.LazyLogger +import java.util.* +import java.util.concurrent.CopyOnWriteArrayList +import javax.swing.JLabel + +class TaskManager(var update: ((Task?) -> Any)? = null) { + val currentTasks = CopyOnWriteArrayList() + val pie = ProgressPie() + val label = JLabel() + val logger by LazyLogger() + + init { + + val timerTask = object: TimerTask() { + override fun run() { + currentTasks.removeIf { it.completion > 99.9999f } + val current = currentTasks.lastOrNull() + + update?.invoke(current) + } + } + Timer().scheduleAtFixedRate(timerTask, 0L, 200L) + } + + fun addTask(task: Task) { + currentTasks.add(task) + } + + fun newTask(source: String, status: String = ""): Task { + val task = Task(source, status, 0.0f) + currentTasks.add(task) + return task + } + + fun removeTask(task: Task) { + currentTasks.remove(task) + } +} \ No newline at end of file From 622d0dba6ab829f7d5b1da0539294bc909ebbfb7 Mon Sep 17 00:00:00 2001 From: Ulrik Guenther Date: Tue, 17 Nov 2020 20:22:51 +0100 Subject: [PATCH 23/23] LoadCremeDatasetAndNeurons: Update example and make use of TaskManager --- .../commands/demo/LoadCremiDatasetAndNeurons.kt | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/main/java/sc/iview/commands/demo/LoadCremiDatasetAndNeurons.kt b/src/main/java/sc/iview/commands/demo/LoadCremiDatasetAndNeurons.kt index f67dcb06..818e7ebb 100644 --- a/src/main/java/sc/iview/commands/demo/LoadCremiDatasetAndNeurons.kt +++ b/src/main/java/sc/iview/commands/demo/LoadCremiDatasetAndNeurons.kt @@ -11,6 +11,7 @@ import graphics.scenery.volumes.TransferFunction import graphics.scenery.volumes.Volume import net.imagej.lut.LUTService import net.imagej.mesh.Mesh +import net.imagej.mesh.Meshes import net.imagej.ops.OpService import net.imagej.ops.geom.geom3d.mesh.BitTypeVertexInterpolator import net.imglib2.RandomAccessibleInterval @@ -84,6 +85,7 @@ class LoadCremiDatasetAndNeurons: Command { * @see Thread.run */ override fun run() { + val task = sciview.taskManager.newTask("Cremi", "Loading dataset") val filter = FileFilter { file -> val extension = file.name.substringAfterLast(".").toLowerCase() @@ -109,6 +111,8 @@ class LoadCremiDatasetAndNeurons: Command { volume?.scale = Vector3f(0.04f, 0.04f, 2.5f) volume?.transferFunction = TransferFunction.ramp(0.3f, 0.1f, 0.1f) // min 20, max 180, color map fire + + volume?.transferFunction?.addControlPoint(0.3f, 0.5f) volume?.transferFunction?.addControlPoint(0.8f, 0.01f) volume?.converterSetups?.get(0)?.setDisplayRange(20.0, 220.0) val colormap = lut.loadLUT(lut.findLUTs().get("Grays.lut")) @@ -117,6 +121,8 @@ class LoadCremiDatasetAndNeurons: Command { volume?.colormap = Colormap.fromColorTable(colormap) + task.status = "Creating labeling" + task.completion = 10.0f val rai = nai.second log.info("Got ${nai.first.size} labels") @@ -135,9 +141,11 @@ class LoadCremiDatasetAndNeurons: Command { regions.filter { largestNeuronLabels.contains(it.label.toLong() + 1L) }.forEachIndexed { i, region -> log.info("Meshing neuron ${i + 1}/${largestNeuronLabels.size} with label ${region.label}...") + task.status = "Meshing neuron ${i+1}/${largestNeuronLabels.size}" + // ui.show(region) // Generate the mesh with imagej-ops - val m: Mesh = ops.geom().marchingCubes(region, 1.0, BitTypeVertexInterpolator()) + val m: Mesh = Meshes.marchingCubes(region); log.info("Converting neuron ${i + 1}/${largestNeuronLabels.size} to scenery format...") // Convert the mesh into a scenery mesh for visualization @@ -146,11 +154,13 @@ class LoadCremiDatasetAndNeurons: Command { mesh.material.diffuse = colormapNeurons.lookupARGB(0.0, 255.0, kotlin.random.Random.nextDouble(0.0, 255.0)).toRGBColor().xyz() mesh.material.roughness = 0.0f - // marching cubes produces CW meshes, not CCW as expected by default - mesh.material.cullingMode = Material.CullingMode.Front mesh.name = "Neuron $i" sciview.addNode(mesh) + val completion = 10.0f + ((i+1)/largestNeuronLabels.size.toFloat())*90.0f + task.completion = completion } + + task.completion = 100.0f } fun readCremiHDF5(path: String, scale: Double = 1.0): NeuronsAndImage? {