use of ini.trakem2.display.Polyline in project TrakEM2 by trakem2.
the class ProjectTree method insertSegmentations.
/* // makes no sense, because there may be multiple projects open and thus the viewport and position may interfere with each other across multiple projects. Saving the collapsed node state suffices.
public void exportXML(final StringBuffer sb_body, String indent, JScrollPane jsp) {
Point p = jsp.getViewport().getViewPosition();
Dimension d = jsp.getSize(null);
sb_body.append(indent).append("<t2_tree")
.append(" width=\"").append(d.width).append('\"')
.append(" height=\"").append(d.height).append('\"')
.append(" viewport_x=\"").append(p.e).append('\"')
.append(" viewport_y=\"").append(p.y).append('\"')
;
sb_body.append("\n").append(indent).append("</t2_tree>\n");
}
*/
/**
* Creates a new node of basic type for each AreaList, Ball, Pipe or Polyline present in the ArrayList. Other elements are ignored.
*/
public void insertSegmentations(final Collection<? extends Displayable> al) {
final TemplateThing tt_root = (TemplateThing) project.getTemplateTree().getRoot().getUserObject();
// create a new abstract node called "imported_segmentations", if not there
final String imported_labels = "imported_labels";
if (!project.typeExists(imported_labels)) {
// create it
// yes I know I should check for the project of each Displayable in the ArrayList
TemplateThing tet = new TemplateThing(imported_labels, project);
project.addUniqueType(tet);
DefaultMutableTreeNode root = project.getTemplateTree().getRoot();
tt_root.addChild(tet);
DefaultMutableTreeNode child_node = addChild(tet, root);
DNDTree.expandNode(project.getTemplateTree(), child_node);
// JTree is serious pain
}
// it's the same as 'tet' above, unless it existed
TemplateThing tt_is = project.getTemplateThing(imported_labels);
// create a project node from "imported_segmentations" template under a new top node
final DefaultMutableTreeNode project_node = project.getProjectTree().getRoot();
ProjectThing project_pt = (ProjectThing) project_node.getUserObject();
final ProjectThing ct = project_pt.createChild(tt_root.getType());
ProjectThing pt_is = ct.createChild(imported_labels);
// addChild(pt_is, ctn);
final DefaultMutableTreeNode node_pt_is = new DefaultMutableTreeNode(pt_is);
final HashMap<Class<?>, String> types = new HashMap<Class<?>, String>();
types.put(AreaList.class, "area_list");
types.put(Pipe.class, "pipe");
types.put(Polyline.class, "polyline");
types.put(Ball.class, "ball");
types.put(Treeline.class, "treeline");
types.put(AreaTree.class, "areatree");
types.put(Connector.class, "connector");
// now, insert a new ProjectThing if of type AreaList, Ball and/or Pipe under node_child
for (final Displayable d : al) {
final String type = types.get(d.getClass());
if (null == type) {
Utils.log("insertSegmentations: ignoring " + d);
continue;
}
try {
final TemplateThing tt = getOrCreateChildTemplateThing(tt_is, type);
ProjectThing one = new ProjectThing(tt, project, d);
pt_is.addChild(one);
// addChild(one, node_pt_is);
// at the end
node_pt_is.add(new DefaultMutableTreeNode(one));
// Utils.log2("one parent : " + one.getParent());
} catch (Exception e) {
IJError.print(e);
}
}
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
DefaultMutableTreeNode ctn = addChild(ct, project_node);
ctn.add(node_pt_is);
try {
ProjectTree.this.scrollPathToVisible(new TreePath(node_pt_is.getPath()));
} catch (Exception e) {
e.printStackTrace();
}
}
});
DNDTree.expandNode(this, node_pt_is);
}
use of ini.trakem2.display.Polyline in project TrakEM2 by trakem2.
the class Polyline method measure.
@Override
public ResultsTable measure(ResultsTable rt) {
// reload
if (-1 == n_points)
setupForDisplay();
if (0 == n_points)
return rt;
if (null == rt)
rt = Utils.createResultsTable("Polyline results", new String[] { "id", "length", "name-id" });
// measure length
double len = 0;
final Calibration cal = layer_set.getCalibration();
if (n_points > 1) {
final VectorString3D vs = asVectorString3D();
vs.calibrate(cal);
// no resampling
len = vs.computeLength();
}
rt.incrementCounter();
rt.addLabel("units", cal.getUnit());
rt.addValue(0, this.id);
rt.addValue(1, len);
rt.addValue(2, getNameId());
return rt;
}
use of ini.trakem2.display.Polyline in project TrakEM2 by trakem2.
the class Polyline method mousePressed.
@Override
public void mousePressed(final MouseEvent me, final Layer layer, int x_p, int y_p, final double mag) {
// transform the x_p, y_p to the local coordinates
final int x_pd = x_p;
final int y_pd = y_p;
if (!this.at.isIdentity()) {
final Point2D.Double po = inverseTransformPoint(x_p, y_p);
x_p = (int) po.x;
y_p = (int) po.y;
}
final int tool = ProjectToolbar.getToolId();
final Display display = ((DisplayCanvas) me.getSource()).getDisplay();
final long layer_id = layer.getId();
index = findPoint(x_p, y_p, layer_id, mag);
if (ProjectToolbar.PENCIL == tool && n_points > 0 && -1 == index && !me.isShiftDown() && !Utils.isControlDown(me)) {
// Check that there are any images -- otherwise may hang. TODO
if (layer_set.getDisplayables(Patch.class).isEmpty()) {
Utils.log("No images are present!");
return;
}
final double scale = layer_set.getVirtualizationScale();
// Ok now with all found images, create a virtual stack that provides access to them all, with caching.
final Worker[] worker = new Worker[2];
final TraceParameters tr_ = tr_map.get(layer_set);
final TraceParameters tr = null == tr_ ? new TraceParameters() : tr_;
if (null == tr_) {
synchronized (tr_map) {
tr_map.put(layer_set, tr);
}
}
if (tr.update) {
worker[0] = new Worker("Preparing Hessian...") {
@Override
public void run() {
startedWorking();
try {
Utils.log("Push ESCAPE key to cancel autotrace anytime.");
final ImagePlus virtual = new LayerStack(layer_set, scale, ImagePlus.GRAY8, Patch.class, display.getDisplayChannelAlphas(), Segmentation.fmp.SNT_invert_image).getImagePlus();
// virtual.show();
final Calibration cal = virtual.getCalibration();
double minimumSeparation = 1;
if (cal != null)
minimumSeparation = Math.min(cal.pixelWidth, Math.min(cal.pixelHeight, cal.pixelDepth));
final ComputeCurvatures hessian = new ComputeCurvatures(virtual, minimumSeparation, null, cal != null);
hessian.run();
tr.virtual = virtual;
// tr.scale = scale;
tr.hessian = hessian;
tr.update = false;
} catch (final Exception e) {
IJError.print(e);
}
finishedWorking();
}
};
Bureaucrat.createAndStart(worker[0], project);
}
final Point2D.Double po = transformPoint(p[0][n_points - 1], p[1][n_points - 1]);
final int start_x = (int) po.x;
final int start_y = (int) po.y;
// 0-based
final int start_z = layer_set.indexOf(layer_set.getLayer(p_layer[n_points - 1]));
// must transform into virtual space
final int goal_x = (int) (x_pd * scale);
final int goal_y = (int) (y_pd * scale);
final int goal_z = layer_set.indexOf(layer);
/*
Utils.log2("x_pd, y_pd : " + x_pd + ", " + y_pd);
Utils.log2("scale: " + scale);
Utils.log2("start: " + start_x + "," + start_y + ", " + start_z);
Utils.log2("goal: " + goal_x + "," + goal_y + ", " + goal_z);
Utils.log2("virtual: " + tr.virtual);
*/
final boolean simplify = me.isAltDown();
worker[1] = new Worker("Tracer - waiting on hessian") {
@Override
public void run() {
startedWorking();
try {
if (null != worker[0]) {
// Wait until hessian is ready
worker[0].join();
}
setTaskName("Tracing path");
final int reportEveryMilliseconds = 2000;
tr.tracer = new TracerThread(tr.virtual, 0, 255, // timeout seconds
120, reportEveryMilliseconds, start_x, start_y, start_z, goal_x, goal_y, goal_z, // reciproal pix values at start and goal
true, tr.virtual.getStackSize() == 1, tr.hessian, null == tr.hessian ? 1 : 4, null, null != tr.hessian);
tr.tracer.addProgressListener(new SearchProgressCallback() {
@Override
public void pointsInSearch(final SearchInterface source, final int inOpen, final int inClosed) {
worker[1].setTaskName("Tracing path: open=" + inOpen + " closed=" + inClosed);
}
@Override
public void finished(final SearchInterface source, final boolean success) {
if (!success) {
Utils.logAll("Could NOT trace a path");
}
}
@Override
public void threadStatus(final SearchInterface source, final int currentStatus) {
// This method gets called every reportEveryMilliseconds
if (worker[1].hasQuitted()) {
source.requestStop();
}
}
});
tr.tracer.run();
final Path result = tr.tracer.getResult();
tr.tracer = null;
if (null == result) {
// : "+
Utils.log("Finding a path failed");
// not public //SearchThread.exitReasonStrings[tracer.getExitReason()]);
return;
}
// TODO: precise_x_positions etc are likely to be broken (calibrated or something)
// Remove bogus points: those at the end with 0,0 coords
int len = result.points;
final double[][] pos = result.getXYZUnscaled();
for (int i = len - 1; i > -1; i--) {
if (0 == pos[0][i] && 0 == pos[1][i]) {
len--;
} else
break;
}
// Transform points: undo scale, and bring to this Polyline AffineTransform:
final AffineTransform aff = new AffineTransform();
/* Inverse order: */
/* 2 */
aff.concatenate(Polyline.this.at.createInverse());
/* 1 */
aff.scale(1 / scale, 1 / scale);
final double[] po = new double[len * 2];
for (int i = 0, j = 0; i < len; i++, j += 2) {
po[j] = pos[0][i];
po[j + 1] = pos[1][i];
}
final double[] po2 = new double[len * 2];
// what a stupid format: consecutive x,y pairs
aff.transform(po, 0, po2, 0, len);
long[] p_layer_ids = new long[len];
double[] pox = new double[len];
double[] poy = new double[len];
for (int i = 0, j = 0; i < len; i++, j += 2) {
// z_positions in 0-(N-1), not in 1-N like slices!
p_layer_ids[i] = layer_set.getLayer((int) pos[2][i]).getId();
pox[i] = po2[j];
poy[i] = po2[j + 1];
}
// Simplify path: to steps of 5 calibration units, or 5 pixels when not calibrated.
if (simplify) {
setTaskName("Simplifying path");
final Object[] ob = Polyline.simplify(pox, poy, p_layer_ids, 10000, layer_set);
pox = (double[]) ob[0];
poy = (double[]) ob[1];
p_layer_ids = (long[]) ob[2];
len = pox.length;
}
// Record the first newly-added autotraced point index:
last_autotrace_start = Polyline.this.n_points;
Polyline.this.appendPoints(pox, poy, p_layer_ids, len);
Polyline.this.repaint(true, null);
Utils.logAll("Added " + len + " new points.");
} catch (final Exception e) {
IJError.print(e);
}
finishedWorking();
}
};
Bureaucrat.createAndStart(worker[1], project);
index = -1;
return;
}
if (ProjectToolbar.PEN == tool || ProjectToolbar.PENCIL == tool) {
if (Utils.isControlDown(me) && me.isShiftDown()) {
final long lid = Display.getFrontLayer(this.project).getId();
if (-1 == index || lid != p_layer[index]) {
index = findNearestPoint(x_p, y_p, layer_id);
}
if (-1 != index) {
// delete point
removePoint(index);
index = -1;
repaint(false, null);
}
// In any case, terminate
return;
}
if (// disable!
-1 != index && layer_id != p_layer[index])
// disable!
index = -1;
else // if no conditions are met, attempt to add point
if (-1 == index && !me.isShiftDown() && !me.isAltDown()) {
// add a new point
index = addPoint(x_p, y_p, layer_id, mag);
is_new_point = true;
repaint(false, null);
return;
}
}
}
Aggregations