diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..3d47f986c41db29ec6dc0d5036bf760b3a1cf366 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.idea/ +target/ +.settings/ +*.iml +.project +.classpath \ No newline at end of file diff --git a/export.jardesc b/export.jardesc new file mode 100644 index 0000000000000000000000000000000000000000..e77c24867e74d71b8eb75983f47d5bcdb8072367 --- /dev/null +++ b/export.jardesc @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="WINDOWS-1252" standalone="no"?> +<jardesc> + <jar path="sphereVTK/drawSphereVTK.jar"/> + <options buildIfNeeded="true" compress="true" descriptionLocation="/sphereVTK/export.jardesc" exportErrors="false" exportWarnings="true" includeDirectoryEntries="true" overwrite="true" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/> + <storedRefactorings deprecationInfo="true" structuralOnly="false"/> + <selectedProjects/> + <manifest generateManifest="true" manifestLocation="/Icy-Kernel/META-INF/MANIFEST.MF" manifestVersion="1.0" reuseManifest="false" saveManifest="false" usesManifest="true"> + <sealing sealJar="false"> + <packagesToSeal/> + <packagesToUnSeal/> + </sealing> + </manifest> + <selectedElements exportClassFiles="true" exportJavaFiles="true" exportOutputFolder="false"> + <javaElement handleIdentifier="=sphereVTK/src"/> + </selectedElements> +</jardesc> diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..b80d4c1341c5aa0c515f2c4e6ffcbac15139dd8b --- /dev/null +++ b/pom.xml @@ -0,0 +1,101 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <!-- Inherited Icy Parent POM --> + <parent> + <groupId>org.bioimageanalysis.icy</groupId> + <artifactId>parent-pom-plugin</artifactId> + <version>1.0.3</version> + </parent> + + <!-- Project Information --> + <artifactId>3d-spheres-vtk</artifactId> + <version>1.0.0</version> + + <packaging>jar</packaging> + + <name>Draw 3D Spheres with VTK.</name> + <description> + This protocol’s block draws 3D spheres with VTK from a list of cartesian coordinates (x,y,z). It is used by SODA-STORM protocol to + visualize SODA results obtained with single localizations microscopy (STORM). + Mapping molecular assemblies with fluorescence microscopy and object-based spatial statistics: + https://www.nature.com/articles/s41467-018-03053-x + </description> + <url>http://icy.bioimageanalysis.org/plugin/draw-3d-spheres-with-vtk/</url> + <inceptionYear>2020</inceptionYear> + + <organization> + <name>Institut Pasteur</name> + <url>https://pasteur.fr</url> + </organization> + + <licenses> + <license> + <name>GNU GPLv3</name> + <url>https://www.gnu.org/licenses/gpl-3.0.en.html</url> + <distribution>repo</distribution> + </license> + </licenses> + + <developers> + <developer> + <id>lagache</id> + <name>Thibault Lagache</name> + <url>https://research.pasteur.fr/fr/member/thibault-lagache/</url> + <roles> + <role>founder</role> + <role>developer</role> + </roles> + </developer> + <developer> + <id>sdallongeville</id> + <name>Stéphane Dallongeville</name> + <url>https://research.pasteur.fr/fr/member/stephane-dallongeville/</url> + <roles> + <role>founder</role> + <role>lead</role> + <role>architect</role> + <role>developer</role> + <role>debugger</role> + <role>tester</role> + <role>maintainer</role> + <role>support</role> + </roles> + </developer> + </developers> + + <!-- Project properties --> + <properties> + + </properties> + + <!-- Project build configuration --> + <build> + + </build> + + <!-- List of project's dependencies --> + <dependencies> + <!-- The core of Icy --> + <dependency> + <groupId>org.bioimageanalysis.icy</groupId> + <artifactId>icy-kernel</artifactId> + </dependency> + <dependency> + <groupId>org.bioimageanalysis.icy</groupId> + <artifactId>protocols</artifactId> + </dependency> + </dependencies> + + <!-- Icy Maven repository (to find parent POM) --> + <repositories> + <repository> + <id>icy</id> + <name>Icy's Nexus</name> + <url>https://icy-nexus.pasteur.fr/repository/Icy/</url> + </repository> + </repositories> +</project> diff --git a/src/main/java/plugins/lagache/spherevtk/DrawSpheresVTK.java b/src/main/java/plugins/lagache/spherevtk/DrawSpheresVTK.java new file mode 100644 index 0000000000000000000000000000000000000000..5347509d4b748190c25b60c880b1528ce03c7b1d --- /dev/null +++ b/src/main/java/plugins/lagache/spherevtk/DrawSpheresVTK.java @@ -0,0 +1,60 @@ +package plugins.lagache.spherevtk; + +import java.awt.Color; +import java.awt.geom.Point2D; +import java.util.ArrayList; + +import icy.plugin.abstract_.Plugin; +import icy.roi.BooleanMask2D; +import icy.roi.ROI; +import icy.roi.ROI2D; +import plugins.adufour.blocks.lang.Block; +import plugins.adufour.blocks.util.VarList; +import plugins.adufour.vars.lang.VarColor; +import plugins.adufour.vars.lang.VarDouble; +import plugins.adufour.vars.lang.VarDoubleArrayNative; +import plugins.adufour.vars.lang.VarROIArray; +import plugins.adufour.vars.lang.VarSequence; +import plugins.adufour.vars.lang.VarString; +import plugins.kernel.roi.roi2d.ROI2DPoint; + +// Colocalisation with Ripley function K +// Significant + +public class DrawSpheresVTK extends Plugin implements Block { + + VarSequence input_sequence = new VarSequence("Input sequence", null); + VarDoubleArrayNative x= new VarDoubleArrayNative("x", null); + VarDoubleArrayNative y= new VarDoubleArrayNative("y", null); + VarDoubleArrayNative z= new VarDoubleArrayNative("z", null); + VarString name = new VarString("Name of the overlay", "detections"); + VarColor color = new VarColor("Color", Color.blue); + VarDouble size = new VarDouble("Size", 1.0); + @Override + public void declareInput(VarList inputMap) { + + inputMap.add("Input Sequence", input_sequence); + inputMap.add("x",x); + inputMap.add("y",y); + inputMap.add("z",z); + inputMap.add("Size",size); + inputMap.add("Color",color); + inputMap.add("Name of the overlay",name); + } + + @Override + public void declareOutput(VarList outputMap) { + } + + @Override + public void run() { + + // Add the cross overlay, it becomes active after being added. + input_sequence.getValue().addOverlay(new SphereVTK(x.getValue(),y.getValue(),z.getValue(),size.getValue(),color.getValue(),name.getValue())); + } + + } + + + + \ No newline at end of file diff --git a/src/main/java/plugins/lagache/spherevtk/SphereVTK.java b/src/main/java/plugins/lagache/spherevtk/SphereVTK.java new file mode 100644 index 0000000000000000000000000000000000000000..1f038980d4c36d1dfedd41268da1da62b3f7ed60 --- /dev/null +++ b/src/main/java/plugins/lagache/spherevtk/SphereVTK.java @@ -0,0 +1,224 @@ +/* + * Copyright 2010, 2011 Institut Pasteur. + * + * This file is part of ICY. + * + * ICY is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ICY is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ICY. If not, see <http://www.gnu.org/licenses/>. + */ +package plugins.lagache.spherevtk; + +import icy.canvas.IcyCanvas; +import icy.painter.Overlay; +import icy.painter.VtkPainter; +import icy.sequence.Sequence; +import icy.vtk.VtkUtil; + +import java.awt.Color; +import java.awt.Graphics2D; + +import plugins.kernel.canvas.VtkCanvas; +import vtk.vtkActor; +import vtk.vtkFloatArray; +import vtk.vtkGlyph3D; +import vtk.vtkLookupTable; +import vtk.vtkMolecule; +import vtk.vtkMoleculeMapper; +import vtk.vtkPoints; +import vtk.vtkPolyDataMapper; +import vtk.vtkProp; +import vtk.vtkSphereSource; +import vtk.vtkUnsignedShortArray; +import vtk.vtkUnstructuredGrid; + +/** + * @author stephane + */ +public class SphereVTK extends Overlay implements VtkPainter +{ + double[] x, y, z; + double size; + Color color; + + private vtkActor[] sphere_ens; + + public SphereVTK(double[] x, double[] y, double[] z, double size, Color color, String name) + { + super(name); + + this.x = x; + this.y = y; + this.z = z; + this.size = size; + this.color = color; + + init(); + } + + private void init() + { + // create points + final vtkPoints points = new vtkPoints(); + // setup scales + final vtkFloatArray scales = new vtkFloatArray(); + scales.SetName("scales"); + // setup color label + final vtkFloatArray col = new vtkFloatArray(); + col.SetName("col"); + + // setup lookupTable and add some colors + final vtkLookupTable colors = new vtkLookupTable(); + colors.SetNumberOfTableValues(1); + // index, R, G, B, A + colors.SetTableValue(0, color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f, 1.0); + + for (int i = 0; i < x.length; i++) + { + points.InsertNextPoint(x[i], y[i], z[i]); + scales.InsertNextValue(1); + col.InsertNextValue(0); // first color + } + + // grid structured to append center, radius and color label + final vtkUnstructuredGrid grid = new vtkUnstructuredGrid(); + + grid.SetPoints(points); + grid.GetPointData().AddArray(scales); + grid.GetPointData().SetActiveScalars("scales"); // !!!to set radius first + grid.GetPointData().AddArray(col); + + points.Delete(); + scales.Delete(); + col.Delete(); + + // create anything you want here, we will use a sphere for the demo + final vtkSphereSource sphere = new vtkSphereSource(); + + sphere.SetRadius(size); + sphere.SetThetaResolution(6); + sphere.SetPhiResolution(6); + + // object to group sphere and grid and keep smooth interaction + final vtkGlyph3D glyph3D = new vtkGlyph3D(); + + glyph3D.SetInputData(grid); + glyph3D.SetSourceConnection(sphere.GetOutputPort()); + + // create a mapper and actor + final vtkPolyDataMapper mapper = new vtkPolyDataMapper(); + mapper.SetInputConnection(glyph3D.GetOutputPort()); + + mapper.SetScalarModeToUsePointFieldData(); // without, color are displayed regarding radius and not color label + // mapper.SetScalarRange(0, 3); // to scale color label (without, col should be between 0 and 1) + mapper.SelectColorArray("col"); // !!!to set color (nevertheless you will have nothing) + mapper.SetLookupTable(colors); + + final vtkActor actor = new vtkActor(); + actor.SetMapper(mapper); + + sphere_ens = new vtkActor[1]; + sphere_ens[0] = actor; + } + + // init vtk objects + private void init_2() + { + final double[] pts = new double[x.length * 3]; + + // convert to single array + for (int i = 0; i < x.length; i++) + { + pts[(i * 3) + 0] = x[i]; + pts[(i * 3) + 1] = y[i]; + pts[(i * 3) + 2] = z[i]; + } + + final vtkPoints vtkPts = VtkUtil.getPoints(pts); + + sphere_ens = new vtkActor[1]; + final vtkMolecule mol = new vtkMolecule(); + + mol.SetPoints(vtkPts); + vtkPts.Delete(); + + final vtkUnsignedShortArray atomicNums = (vtkUnsignedShortArray) mol.GetVertexData().GetScalars(); + + // set atomic num + for (int i = 0; i < x.length; i++) + atomicNums.InsertValue(i, 0); + + // mapper + final vtkMoleculeMapper molMapper = new vtkMoleculeMapper(); + + molMapper.SetInputData(mol); + molMapper.UseFastSettings(); + + // molMapper.SetRenderAtoms(true); + // molMapper.SetRenderBonds(false); + + // actor + final vtkActor molActor = new vtkActor(); + molActor.SetMapper(molMapper); + + sphere_ens[0] = molActor; + } + + // init vtk objects + private void init_old() + { + sphere_ens = new vtkActor[x.length]; + for (int i = 0; i < x.length; i++) + { + // source + final vtkSphereSource sphere = new vtkSphereSource(); + sphere.SetRadius(size); + sphere.SetThetaResolution(6); + sphere.SetPhiResolution(6); + + sphere.SetCenter(x[i], y[i], z[i]); + + // mapper + final vtkPolyDataMapper map = new vtkPolyDataMapper(); + map.SetInputConnection(sphere.GetOutputPort()); + + // actor + vtkActor aSphere = new vtkActor(); + aSphere.SetMapper(map); + // double total = color.getRed()+ color.getGreen()+ color.getBlue(); + double red = color.getRed() / 255.; + double green = color.getGreen() / 255.; + double blue = color.getBlue() / 255.; + + aSphere.GetProperty().SetColor(red, green, blue); + sphere_ens[i] = aSphere; + } + } + + @Override + public void paint(Graphics2D g, Sequence sequence, IcyCanvas canvas) + { + super.paint(g, sequence, canvas); + + if (canvas instanceof VtkCanvas) + { + // disable picking by using this property + ((VtkCanvas) canvas).getPicker().PickFromListOn(); + } + } + + @Override + public vtkProp[] getProps() + { + return sphere_ens; + } +} \ No newline at end of file