Commit f845c80d authored by Stéphane  DALLONGEVILLE's avatar Stéphane DALLONGEVILLE
Browse files

Optimized ROI logical operation processing by caching BooleanMask object

parent d4943cc5
package plugins.stef.roi.bloc.op;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import icy.plugin.abstract_.Plugin;
import icy.plugin.interface_.PluginBundled;
import icy.plugin.interface_.PluginLibrary;
import icy.roi.BooleanMask2D;
import icy.roi.BooleanMask3D;
import icy.roi.ROI;
import icy.roi.ROI2D;
import icy.roi.ROI3D;
import icy.type.collection.CollectionUtil;
import plugins.adufour.blocks.tools.roi.ROIBlock;
import plugins.adufour.blocks.util.VarList;
......@@ -85,11 +92,53 @@ public class LogicalOperationROI extends Plugin implements ROIBlock, PluginLibra
boolean copyRois)
{
final List<ROI> result = new ArrayList<ROI>();
final Map<ROI, SoftReference<BooleanMask2D>> masks2d = new HashMap<>();
final Map<ROI, SoftReference<BooleanMask3D>> masks3d = new HashMap<>();
try
{
for (ROI roi : roiSetA)
{
if (roi instanceof ROI2D)
masks2d.put(roi, new SoftReference<>(((ROI2D) roi).getBooleanMask(true)));
else if (roi instanceof ROI3D)
masks3d.put(roi, new SoftReference<>(((ROI3D) roi).getBooleanMask(true)));
}
for (ROI roi : roiSetB)
{
if (roi instanceof ROI2D)
masks2d.put(roi, new SoftReference<>(((ROI2D) roi).getBooleanMask(true)));
else if (roi instanceof ROI3D)
masks3d.put(roi, new SoftReference<>(((ROI3D) roi).getBooleanMask(true)));
}
}
catch (OutOfMemoryError error)
{
// not enough memory to build out the masks cache, we will use what we have...
}
for (ROI roiA : roiSetA)
{
SoftReference<?> ref;
if (roiA != null)
{
BooleanMask2D mask2dA = null;
BooleanMask3D mask3dA = null;
// try to get masks from hashmap
ref = masks2d.get(roiA);
if (ref != null)
mask2dA = (BooleanMask2D) ref.get();
else
{
ref = masks3d.get(roiA);
if (ref != null)
mask3dA = (BooleanMask3D) ref.get();
}
boolean cond = (logicOp == LogicOperator.A_NOT_CONTAINED_IN_B)
|| (logicOp == LogicOperator.A_NOT_CONTAINING_B)
|| (logicOp == LogicOperator.A_NOT_INTERSECTING_B);
......@@ -97,12 +146,45 @@ public class LogicalOperationROI extends Plugin implements ROIBlock, PluginLibra
for (ROI roiB : roiSetB)
{
BooleanMask2D mask2dB = null;
BooleanMask3D mask3dB = null;
// try to get mask from hashmap
ref = masks2d.get(roiB);
if (ref != null)
mask2dB = (BooleanMask2D) ref.get();
else
{
ref = masks3d.get(roiB);
if (ref != null)
mask3dB = (BooleanMask3D) ref.get();
}
switch (logicOp)
{
default:
case A_CONTAINED_IN_B:
case A_NOT_CONTAINED_IN_B:
if (roiB.contains(roiA))
// we have the 2D masks ? --> use them
if ((mask2dA != null) && (mask2dB != null))
{
if (mask2dB.contains(mask2dA))
{
done = true;
cond = (logicOp == LogicOperator.A_CONTAINED_IN_B);
}
}
// we have the 3D masks ? --> use them
else if ((mask3dA != null) && (mask3dB != null))
{
if (mask3dB.contains(mask3dA))
{
done = true;
cond = (logicOp == LogicOperator.A_CONTAINED_IN_B);
}
}
// do the generic test
else if (roiB.contains(roiA))
{
done = true;
cond = (logicOp == LogicOperator.A_CONTAINED_IN_B);
......@@ -111,7 +193,26 @@ public class LogicalOperationROI extends Plugin implements ROIBlock, PluginLibra
case A_CONTAINING_B:
case A_NOT_CONTAINING_B:
if (roiA.contains(roiB))
// we have the 2D masks ? --> use them
if ((mask2dA != null) && (mask2dB != null))
{
if (mask2dA.contains(mask2dB))
{
done = true;
cond = (logicOp == LogicOperator.A_CONTAINING_B);
}
}
// we have the 3D masks ? --> use them
else if ((mask3dA != null) && (mask3dB != null))
{
if (mask3dA.contains(mask3dB))
{
done = true;
cond = (logicOp == LogicOperator.A_CONTAINING_B);
}
}
// do the generic test
else if (roiA.contains(roiB))
{
done = true;
cond = (logicOp == LogicOperator.A_CONTAINING_B);
......@@ -120,7 +221,26 @@ public class LogicalOperationROI extends Plugin implements ROIBlock, PluginLibra
case A_INTERSECTING_B:
case A_NOT_INTERSECTING_B:
if (roiA.intersects(roiB))
// we have the 2D masks ? --> use them
if ((mask2dA != null) && (mask2dB != null))
{
if (mask2dA.intersects(mask2dB))
{
done = true;
cond = (logicOp == LogicOperator.A_INTERSECTING_B);
}
}
// we have the 3D masks ? --> use them
else if ((mask3dA != null) && (mask3dB != null))
{
if (mask3dA.intersects(mask3dB))
{
done = true;
cond = (logicOp == LogicOperator.A_INTERSECTING_B);
}
}
// do the generic test
else if (roiA.intersects(roiB))
{
done = true;
cond = (logicOp == LogicOperator.A_INTERSECTING_B);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment