use of ini.trakem2.display.ZDisplayable in project TrakEM2 by trakem2.
the class Project method removeAll.
/**
* Remove any set of Displayable objects from the Layer, LayerSet and Project Tree as necessary.
* ASSUMES there aren't any nested LayerSet objects in @param col.
*/
public final boolean removeAll(final Set<Displayable> col, final DefaultMutableTreeNode top_node) {
// 0. Sort into Displayable and ZDisplayable
final Set<ZDisplayable> zds = new HashSet<ZDisplayable>();
final List<Displayable> ds = new ArrayList<Displayable>();
for (final Displayable d : col) {
if (d instanceof ZDisplayable) {
zds.add((ZDisplayable) d);
} else {
ds.add(d);
}
}
// Displayable:
// 1. First the Profile from the Project Tree, one by one,
// while creating a map of Layer vs Displayable list to remove in that layer:
final HashMap<Layer, Set<Displayable>> ml = new HashMap<Layer, Set<Displayable>>();
for (final Iterator<Displayable> it = ds.iterator(); it.hasNext(); ) {
final Displayable d = it.next();
if (d.getClass() == Profile.class) {
if (!project_tree.remove(false, findProjectThing(d), null)) {
// like Profile.remove2
Utils.log("Could NOT delete " + d);
continue;
}
// remove the Profile
it.remove();
continue;
}
// The map of Layer vs Displayable list
Set<Displayable> l = ml.get(d.getLayer());
if (null == l) {
l = new HashSet<Displayable>();
ml.put(d.getLayer(), l);
}
l.add(d);
}
// 2. Then the rest, in bulk:
if (ml.size() > 0) {
for (final Map.Entry<Layer, Set<Displayable>> e : ml.entrySet()) {
e.getKey().removeAll(e.getValue());
}
}
// 3. Stacks
if (zds.size() > 0) {
final Set<ZDisplayable> stacks = new HashSet<ZDisplayable>();
for (final Iterator<ZDisplayable> it = zds.iterator(); it.hasNext(); ) {
final ZDisplayable zd = it.next();
if (zd.getClass() == Stack.class) {
it.remove();
stacks.add(zd);
}
}
layer_set.removeAll(stacks);
}
// 4. ZDisplayable: bulk removal
if (zds.size() > 0) {
// 1. From the Project Tree:
Set<Displayable> not_removed = project_tree.remove(zds, top_node);
// 2. Then only those successfully removed, from the LayerSet:
zds.removeAll(not_removed);
layer_set.removeAll(zds);
}
// TODO
return true;
}
use of ini.trakem2.display.ZDisplayable in project TrakEM2 by trakem2.
the class Project method openDBProject.
/**
* Open a TrakEM2 project from the database. Queries the database for existing projects and if more than one, asks which one to open.
*/
public static Project openDBProject() {
if (Utils.wrongImageJVersion())
return null;
DBLoader loader = new DBLoader();
if (!loader.isReady())
return null;
// check connection
if (!loader.isConnected()) {
Utils.showMessage("Can't talk to database.");
loader.destroy();
return null;
}
// query the database for existing projects
Project[] projects = loader.getProjects();
if (null == projects) {
Utils.showMessage("Can't talk to database (null list of projects).");
loader.destroy();
return null;
}
Project project = null;
if (0 == projects.length) {
Utils.showMessage("No projects in this database.");
loader.destroy();
return null;
} else if (1 == projects.length) {
project = projects[0];
} else {
// ask to choose one
String[] titles = new String[projects.length];
for (int i = 0; i < projects.length; i++) {
titles[i] = projects[i].title;
}
GenericDialog gd = new GenericDialog("Choose");
gd.addMessage("Choose project to open:");
gd.addChoice("project: ", titles, titles[titles.length - 1]);
gd.showDialog();
if (gd.wasCanceled()) {
loader.destroy();
return null;
}
project = projects[gd.getNextChoiceIndex()];
}
// check if the selected project is open already
for (final Project p : al_open_projects) {
if (loader.isIdenticalProjectSource(p.loader) && p.id == project.id && p.title.equals(project.title)) {
Utils.showMessage("A project with title " + p.title + " and id " + p.id + " from the same database is already open.");
loader.destroy();
return null;
}
}
// now, open the selected project
// assign loader
project.loader = loader;
// grab the XML template
TemplateThing template_root = loader.getTemplateRoot(project);
if (null == template_root) {
Utils.showMessage("Failed to retrieve the template tree.");
project.destroy();
return null;
}
project.template_tree = new TemplateTree(project, template_root);
synchronized (project.ht_unique_tt) {
project.ht_unique_tt.clear();
project.ht_unique_tt.putAll(template_root.getUniqueTypes(new HashMap<String, TemplateThing>()));
}
// create the project Thing, to be root of the whole user Thing tree (and load all its objects)
// to collect all created displayables, and then reassign to the proper layers.
HashMap<Long, Displayable> hs_d = new HashMap<Long, Displayable>();
try {
// create a template for the project Thing
TemplateThing project_template = new TemplateThing("project");
project.ht_unique_tt.put("project", project_template);
project_template.addChild(template_root);
project.root_pt = loader.getRootProjectThing(project, template_root, project_template, hs_d);
// restore parent/child and attribute ownership and values (now that all Things exist)
project.root_pt.setup();
} catch (Exception e) {
Utils.showMessage("Failed to retrieve the Thing tree for the project.");
IJError.print(e);
project.destroy();
return null;
}
// create the user objects tree
project.project_tree = new ProjectTree(project, project.root_pt);
// restore the expanded state of each node
loader.restoreNodesExpandedState(project);
// create the layers templates
project.createLayerTemplates();
// fetch the root layer thing and the root layer set (will load all layers and layer sets, with minimal contents of patches; gets the basic objects -profile, pipe, etc.- from the project.root_pt). Will open all existing displays for each layer.
LayerThing root_layer_thing = null;
try {
root_layer_thing = loader.getRootLayerThing(project, project.root_pt, Project.layer_set_template, Project.layer_template);
if (null == root_layer_thing) {
project.destroy();
Utils.showMessage("Could not retrieve the root layer thing.");
return null;
}
// set the child/parent relationships now that everything exists
root_layer_thing.setup();
project.layer_set = (LayerSet) root_layer_thing.getObject();
if (null == project.layer_set) {
project.destroy();
Utils.showMessage("Could not retrieve the root layer set.");
return null;
}
// set the active layer to each ZDisplayable
project.layer_set.setup();
// debug:
// Utils.log2("$$$ root_lt: " + root_layer_thing + " ob: " + root_layer_thing.getObject().getClass().getName() + "\n children: " + ((LayerSet)root_layer_thing.getObject()).getLayers().size());
project.layer_tree = new LayerTree(project, root_layer_thing);
project.root_lt = root_layer_thing;
} catch (Exception e) {
Utils.showMessage("Failed to retrieve the Layer tree for the project.");
IJError.print(e);
project.destroy();
return null;
}
// if all when well, register as open:
al_open_projects.add(project);
// create the project control window, containing the trees in a double JSplitPane
ControlWindow.add(project, project.template_tree, project.project_tree, project.layer_tree);
// now open the displays that were stored for later, if any:
Display.openLater();
return project;
}
use of ini.trakem2.display.ZDisplayable in project TrakEM2 by trakem2.
the class Project method createSubproject.
/**
* Create a new subproject for the given layer range and ROI.
* Create a new Project using the given project as template. This means the DTD of the given project is copied, as well as the storage and mipmaps folders; everything else is empty in the new project.
*/
public Project createSubproject(final Rectangle roi, final Layer first, final Layer last, final boolean ignore_hidden_patches) {
try {
// The order matters.
final Project pr = new Project(new FSLoader(this.getLoader().getStorageFolder()));
pr.id = this.id;
// copy properties
pr.title = this.title;
pr.ht_props.putAll(this.ht_props);
// copy template
pr.root_tt = this.root_tt.clone(pr, true);
pr.template_tree = new TemplateTree(pr, pr.root_tt);
synchronized (pr.ht_unique_tt) {
pr.ht_unique_tt.clear();
pr.ht_unique_tt.putAll(root_tt.getUniqueTypes(new HashMap<String, TemplateThing>()));
}
TemplateThing project_template = new TemplateThing("project");
project_template.addChild(pr.root_tt);
pr.ht_unique_tt.put("project", project_template);
// create the layers templates
pr.createLayerTemplates();
// copy LayerSet and all involved Displayable objects
// (A two-step process to provide the layer_set pointer and all Layer pointers to the ZDisplayable to copy and crop.)
pr.layer_set = (LayerSet) this.layer_set.clone(pr, first, last, roi, false, true, ignore_hidden_patches);
LayerSet.cloneInto(this.layer_set, first, last, pr, pr.layer_set, roi, true);
// create layer tree
pr.root_lt = new LayerThing(Project.layer_set_template, pr, pr.layer_set);
pr.layer_tree = new LayerTree(pr, pr.root_lt);
// add layer nodes to the layer tree (solving chicken-and-egg problem)
pr.layer_set.updateLayerTree();
// copy project tree
pr.root_pt = this.root_pt.subclone(pr);
pr.project_tree = new ProjectTree(pr, pr.root_pt);
// not copying node expanded state.
// register
al_open_projects.add(pr);
// add to gui:
ControlWindow.add(pr, pr.template_tree, pr.project_tree, pr.layer_tree);
// Above, the id of each object is preserved from this project into the subproject.
// The abstract structure should be copied in full regardless, without the basic objects
// included if they intersect the roi.
// Regenerate mipmaps (blocks GUI from interaction other than navigation)
pr.loader.regenerateMipMaps(pr.layer_set.getDisplayables(Patch.class));
pr.restartAutosaving();
return pr;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
use of ini.trakem2.display.ZDisplayable in project TrakEM2 by trakem2.
the class Loader method getFlatAWTImage.
/**
* @param layer The layer from which to collect visible Displayable instances that intersect the srcRect.
* @param srcRect_ Rectangle in World coordinates representing the field of view to paint into the image, and defines the width and height of the image together with the scale.
* @param scale Value between 0 and 1.
* @param c_alphas Which color channels to include when painting Patch instances that hold an RGB image.
* @param type Either ImagePlus.GRAY8 or ImagePlus.COLOR_RGB
* @param clazz Include only Displayable instances of this class; use Displayable.class for all.
* @param al_displ List of Displayable instances to include. Use null to include all visible intersected by srcRect.
* @param quality Whether to attempt to create a larger image and then scale it down with area averaging for best quality.
* @param background The color of the areas of the image where no Displayable paints.
* @param active Whether to paint a particular Displayable instance in an active state (as if it was selected in the UI).
* @return
*/
public Image getFlatAWTImage(final Layer layer, final Rectangle srcRect_, final double scale, final int c_alphas, final int type, final Class<?> clazz, List<? extends Displayable> al_displ, boolean quality, final Color background, final Displayable active) {
try {
// dimensions
int w = 0;
int h = 0;
Rectangle srcRect = (null == srcRect_) ? null : (Rectangle) srcRect_.clone();
if (null != srcRect) {
w = srcRect.width;
h = srcRect.height;
} else {
w = (int) Math.ceil(layer.getLayerWidth());
h = (int) Math.ceil(layer.getLayerHeight());
srcRect = new Rectangle(0, 0, w, h);
}
Utils.log2("Loader.getFlatImage: using rectangle " + srcRect);
/*
* output size including excess space for not entirely covered
* pixels
*/
final int ww = (int) Math.ceil(w * scale);
final int hh = (int) Math.ceil(h * scale);
/* The size of the buffered image to be generated */
final int biw, bih;
final double scaleP, scalePX, scalePY;
// on scaling down to output resolution.
if (quality) {
if (ww * hh >= Math.pow(2, 30)) {
// 1 GB
// While perhaps scale could be increased to an image size of up to 2 GB, it is not advisable
scaleP = scalePX = scalePY = scale;
quality = false;
biw = ww;
bih = hh;
Utils.log("Can't use 'quality' flag for getFlatAWTImage: would be too large");
// If the image is larger than 2 GB, it will thrown a NegativeArraySizeException below and stop.
} else {
// Max area: the smallest of the srcRect at 100x magnification and 1 GB
final double max_area = Math.min(srcRect.width * srcRect.height, Math.pow(2, 30));
final double ratio = ww / (double) hh;
// area = w * h
// ratio = w / h
// w = ratio * h
// area = ratio * h * h
// h = sqrt(area / ratio)
// scaleP is then the ratio between the real-world height and the target height
// (And clamp to a maximum of 1.0: above makes no sense)
scaleP = Math.min(1.0, srcRect.height / Math.sqrt(max_area / ratio));
biw = (int) Math.ceil(ww / scale);
bih = (int) Math.ceil(hh / scale);
/* compensate for excess space due to ceiling */
scalePX = (double) biw / (double) ww * scale;
scalePY = (double) bih / (double) hh * scale;
Utils.log("getFlatAWTImage -- scale: " + scale + "; quality scale: " + scaleP);
}
} else {
scaleP = scalePX = scalePY = scale;
biw = ww;
bih = hh;
}
// estimate image size
final long n_bytes = (long) ((biw * bih * (ImagePlus.GRAY8 == type ? 1.0 : /*byte*/
4.0)));
Utils.log2("Flat image estimated size in bytes: " + Long.toString(n_bytes) + " w,h : " + (int) Math.ceil(biw) + "," + (int) Math.ceil(bih) + (quality ? " (using 'quality' flag: scaling to " + scale + " is done later with area averaging)" : ""));
releaseToFit(n_bytes);
// go
BufferedImage bi = null;
switch(type) {
case ImagePlus.GRAY8:
bi = new BufferedImage(biw, bih, BufferedImage.TYPE_BYTE_INDEXED, GRAY_LUT);
break;
case ImagePlus.COLOR_RGB:
bi = new BufferedImage(biw, bih, BufferedImage.TYPE_INT_ARGB);
break;
default:
Utils.log2("Left bi,icm as null");
break;
}
final Graphics2D g2d = bi.createGraphics();
g2d.setColor(background);
g2d.fillRect(0, 0, bi.getWidth(), bi.getHeight());
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
// TODO Stephan, test if that introduces offset vs nearest neighbor
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
// to smooth edges of the images
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
ArrayList<ZDisplayable> al_zdispl = null;
if (null == al_displ) {
al_displ = new ArrayList<Displayable>(layer.find(clazz, srcRect, true, true));
al_zdispl = new ArrayList<ZDisplayable>((Collection) layer.getParent().findZDisplayables(clazz, layer, srcRect, true, true));
} else {
// separate ZDisplayables into their own array
al_displ = new ArrayList<Displayable>(al_displ);
final HashSet<ZDisplayable> az = new HashSet<ZDisplayable>();
for (final Iterator<?> it = al_displ.iterator(); it.hasNext(); ) {
final Object ob = it.next();
if (ob instanceof ZDisplayable) {
it.remove();
az.add((ZDisplayable) ob);
}
}
// order ZDisplayables by their stack order
final ArrayList<ZDisplayable> al_zdispl2 = layer.getParent().getZDisplayables();
for (final Iterator<ZDisplayable> it = al_zdispl2.iterator(); it.hasNext(); ) {
if (!az.contains(it.next()))
it.remove();
}
al_zdispl = al_zdispl2;
}
// prepare the canvas for the srcRect and magnification
final AffineTransform at_original = g2d.getTransform();
final AffineTransform atc = new AffineTransform();
atc.scale(scalePX, scalePY);
atc.translate(-srcRect.x, -srcRect.y);
at_original.preConcatenate(atc);
g2d.setTransform(at_original);
// Utils.log2("will paint: " + al_displ.size() + " displ and " + al_zdispl.size() + " zdispl");
// int total = al_displ.size() + al_zdispl.size();
int count = 0;
boolean zd_done = false;
final List<Layer> layers = layer.getParent().getColorCueLayerRange(layer);
for (final Displayable d : al_displ) {
// paint the ZDisplayables before the first label, if any
if (!zd_done && d instanceof DLabel) {
zd_done = true;
for (final ZDisplayable zd : al_zdispl) {
if (!zd.isOutOfRepaintingClip(scaleP, srcRect, null)) {
zd.paint(g2d, srcRect, scaleP, active == zd, c_alphas, layer, layers);
}
count++;
// Utils.log2("Painted " + count + " of " + total);
}
}
if (!d.isOutOfRepaintingClip(scaleP, srcRect, null)) {
d.paintOffscreen(g2d, srcRect, scaleP, active == d, c_alphas, layer, layers);
// Utils.log("painted: " + d + "\n with: " + scaleP + ", " + c_alphas + ", " + layer);
} else {
// Utils.log2("out: " + d);
}
count++;
// Utils.log2("Painted " + count + " of " + total);
}
if (!zd_done) {
zd_done = true;
for (final ZDisplayable zd : al_zdispl) {
if (!zd.isOutOfRepaintingClip(scaleP, srcRect, null)) {
zd.paint(g2d, srcRect, scaleP, active == zd, c_alphas, layer, layers);
}
count++;
// Utils.log2("Painted " + count + " of " + total);
}
}
// ensure enough memory is available for the processor and a new awt from it
// locks on its own
releaseToFit((long) (n_bytes * 2.3));
try {
if (quality) {
// need to scale back down
Image scaled = null;
if (!isMipMapsRegenerationEnabled() || scale >= 0.499) {
// there are no proper mipmaps above 50%, so there's need for SCALE_AREA_AVERAGING.
// very slow, but best by far
scaled = bi.getScaledInstance(ww, hh, Image.SCALE_AREA_AVERAGING);
if (ImagePlus.GRAY8 == type) {
// getScaledInstance generates RGB images for some reason.
final BufferedImage bi8 = new BufferedImage(ww, hh, BufferedImage.TYPE_BYTE_GRAY);
bi8.createGraphics().drawImage(scaled, 0, 0, null);
scaled.flush();
scaled = bi8;
}
} else {
// faster, but requires gaussian blurred images (such as the mipmaps)
if (bi.getType() == BufferedImage.TYPE_BYTE_INDEXED) {
scaled = new BufferedImage(ww, hh, bi.getType(), GRAY_LUT);
} else {
scaled = new BufferedImage(ww, hh, bi.getType());
}
final Graphics2D gs = (Graphics2D) scaled.getGraphics();
// gs.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
gs.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
gs.drawImage(bi, 0, 0, ww, hh, null);
}
bi.flush();
return scaled;
} else {
// else the image was made scaled down already, and of the proper type
return bi;
}
} catch (final OutOfMemoryError oome) {
Utils.log("Not enough memory to create the ImagePlus. Try scaling it down or not using the 'quality' flag.");
}
} catch (final Exception e) {
IJError.print(e);
}
return null;
}
use of ini.trakem2.display.ZDisplayable in project TrakEM2 by trakem2.
the class ProjectTree method rawSendToSiblingProject.
/**
* Assumes that both projects have the same TemplateThing structure,
* and assumes that the parent of the ({@code source_pt} and the {@code landing_parent}
* instances are of the same type.
*
* @param source_pt The {@link ProjectThing} to be cloned.
* @param transfer_mode Either 0 ("As is") or 1 ("Transformed with the images").
* @param target_project The sibling project into which insert a clone of the {@code source_pt}.
* @param landing_parent The ProjectThing in the sibling project that receives the cloned {@code source_pt}.
*/
public boolean rawSendToSiblingProject(// the source ProjectThing to copy to the target project
final ProjectThing source_pt, final int transfer_mode, final Project target_project, final ProjectThing landing_parent) {
try {
// Check that all the Layers used by the objects to transfer also exist in the target project!
// 1 - Cheap way: check if all layers in the target project exist in the source project, by id
HashSet<Long> lids = new HashSet<Long>();
for (final Layer layer : this.project.getRootLayerSet().getLayers()) {
lids.add(layer.getId());
}
HashSet<Long> tgt_lids = new HashSet<Long>(lids);
for (final Layer layer : target_project.getRootLayerSet().getLayers()) {
lids.remove(layer.getId());
tgt_lids.add(layer.getId());
}
List<Displayable> original_vdata = null;
final Set<Long> lids_to_operate = new HashSet<Long>();
if (0 != lids.size()) {
original_vdata = new ArrayList<Displayable>();
// All their layers MUST be in the target project.
for (final ProjectThing child : source_pt.findChildrenOfTypeR(Displayable.class)) {
final Displayable d = (Displayable) child.getObject();
if (!tgt_lids.containsAll(d.getLayerIds())) {
Utils.log("CANNOT transfer: not all required layers are present in the target project!\n First object that couldn't be transfered: \n " + d);
return false;
}
if (d instanceof VectorData) {
original_vdata.add(d);
lids_to_operate.addAll(d.getLayerIds());
}
}
}
// Deep cloning of the ProjectThing to transfer, then added to the landing_parent in the other tree.
ProjectThing copy;
try {
// new ids, taken from target_project
copy = source_pt.deepClone(target_project, false);
} catch (Exception ee) {
Utils.logAll("Can't send: " + ee.getMessage());
IJError.print(ee);
return false;
}
if (null == landing_parent.getChildTemplate(copy.getTemplate().getType())) {
// ensure a copy is there
landing_parent.getTemplate().addChild(copy.getTemplate().shallowCopy());
}
if (!landing_parent.addChild(copy)) {
Utils.log("Could NOT transfer the node!");
return false;
}
// Get the list of Profile instances in the source Project, in the same order
// that they will be in the target project:
final List<Profile> srcProfiles = new ArrayList<Profile>();
for (final ProjectThing profile_pt : source_pt.findChildrenOfTypeR(Profile.class)) {
srcProfiles.add((Profile) profile_pt.getObject());
}
final List<ProjectThing> copies = copy.findChildrenOfTypeR(Displayable.class);
final List<Profile> newProfiles = new ArrayList<Profile>();
// Utils.log2("copies size: " + copies.size());
final List<Displayable> vdata = new ArrayList<Displayable>();
final List<ZDisplayable> zd = new ArrayList<ZDisplayable>();
for (final ProjectThing t : copies) {
final Displayable d = (Displayable) t.getObject();
// all should be, this is just future-proof code.
if (d instanceof VectorData)
vdata.add(d);
if (d instanceof ZDisplayable) {
zd.add((ZDisplayable) d);
} else {
// profile: always special
newProfiles.add((Profile) d);
}
}
// Fix Profile instances: exploit that the order as been conserved when copying.
int profileIndex = 0;
for (final Profile newProfile : newProfiles) {
// Corresponding Profile:
final Profile srcProfile = srcProfiles.get(profileIndex++);
// Corresponding layer: layers have the same IDs by definition of what a sibling Project is.
final Layer newLayer = target_project.getRootLayerSet().getLayer(srcProfile.getLayer().getId());
newLayer.add(newProfile);
// Corresponding links
for (final Displayable srcLinkedProfile : srcProfile.getLinked(Profile.class)) {
newProfile.link(newProfiles.get(srcProfiles.indexOf(srcLinkedProfile)));
}
}
// add them all in one shot
target_project.getRootLayerSet().addAll(zd);
// could have changed
target_project.getTemplateTree().rebuild();
// When trying to rebuild just the landing_parent, it doesn't always work. Needs checking TODO
target_project.getProjectTree().rebuild();
// Open up the path to the landing parent node
final TreePath tp = new TreePath(DNDTree.findNode(landing_parent, target_project.getProjectTree()).getPath());
Utils.invokeLater(new Runnable() {
public void run() {
target_project.getProjectTree().scrollPathToVisible(tp);
target_project.getProjectTree().setSelectionPath(tp);
}
});
if (1 == transfer_mode) {
// Collect original vdata
if (null == original_vdata) {
original_vdata = new ArrayList<Displayable>();
for (final ProjectThing child : source_pt.findChildrenOfTypeR(Displayable.class)) {
final Displayable d = (Displayable) child.getObject();
if (d instanceof VectorData) {
original_vdata.add(d);
lids_to_operate.addAll(d.getLayerIds());
}
}
}
// Utils.log2("original vdata:", original_vdata);
// Utils.log2("vdata:", vdata);
// Transform with images
AlignTask.transformVectorData(AlignTask.createTransformPropertiesTable(original_vdata, vdata, lids_to_operate), vdata, target_project.getRootLayerSet());
}
return true;
} catch (Exception e) {
IJError.print(e);
}
return false;
}
Aggregations