public class TrakEM2_Add_Balls implements PlugIn {
public void run(String arg) {
// 1 - Obtain an open TrakEM2 project: the one selected in the ControlWindow
final Project project = ControlWindow.getActive();
if (null == project) {
Utils.log("Open or create a TrakEM2 project first!");
return;
}
// Else, you could create a project like:
// Project project = Project.newFSProject("blank", null, "/path/to/storage_folder/");
// 2 - Define two sets of x,y,z,r coordinates to import as 3D-positioned balls of radius r
// X Y Z R
final double[][] set1 = {{ 100, 100, 0, 25 },
{ 130, 120, 1, 30 },
{ 110, 150, 0, 15 }};
final double[][] set2 = {{ 200, 200, 1, 45 },
{ 240, 190, 0, 35 },
{ 220, 250, 1, 55 }};
// 3 - Insert each set as a Ball object, each containing 3 x,y,z,r spheres:
Ball b1 = addBallObject(project, set1, "Set 1");
Ball b2 = addBallObject(project, set2, "Set 2");
// 4 - Change colors and settings:
b1.setColor(Color.green);
b2.setColor(Color.magenta); // yellow is default color
// NOTICE that the color cues will paint each individual ball red in the previous layer,
// and blue in the next one -- the color is used to paint in the actual layer where it lives.
// (Scroll through the stack to see the effect -- the color cues help in noticing whether
// a ball already exists at the location in the previous or next slice/Layer).
// You can TURN OFF color cues with the 'p' keyboard shortcut on a Display,
// or programmatically by:
// project.setProperty("no_color_cues", true);
// 5 - Add nodes automatically to the Template and Project trees (REQUIRED):
// (can be rearranged manually later, or could be added with way more precision programmatically)
ArrayList al = new ArrayList();
al.add(b1);
al.add(b2);
project.getProjectTree().insertSegmentations(project, al);
// 6 - Automatically scroll LayerSet to the first layer of the first ball (OPTIONAL):
Display.getFront().setLayer(b1.getFirstLayer());
// 7 - Show the balls in 3D (OPTIONAL):
ProjectThing p1 = project.findProjectThing(b1); // a Project tree node
ProjectThing p2 = project.findProjectThing(b2); // a Project tree node
Future<List<Content>> fu1 = Display3D.show(p1, true, 1); // wait, and resample 1 ( but resample only affects image volumes and AreaList meshes!)
Future<List<Content>> fu2 = Display3D.show(p2, true, 1); // If not waiting, then since its threaded, the saveAsWaveFront below would find nothing to save.
// WAIT until added, so we know the Display3D has been created
try {
fu1.get();
fu2.get();
} catch (InterruptedException ie) {
//
} catch (ExecutionException ee) {
ee.printStackTrace();
}
// 8 - Export the balls meshes to a .obj wavefront file (OPTIONAL):
// (This will export all the current contents of the Display3D that can be exported as meshes.
// One could refine what to export with:
// Content c1 = univ.getContent(Display3D.makeTitle(b1)); // by title
// Content c2 = ...
// ... and then adding them to a Collection.
//
Image3DUniverse univ = Display3D.getDisplay(project.getRootLayerSet()).getUniverse();
Collection all = univ.getContents();
MeshExporter.saveAsWaveFront(all); // pops up file dialog to save
}