use of cbit.vcell.geometry.SubVolume in project vcell by virtualcell.
the class DistanceMapGenerator method computeDistanceMaps.
public static SubvolumeSignedDistanceMap[] computeDistanceMaps(Geometry geometry, VCImage subvolumeHandleImage, boolean bCellCentered, boolean insideOnly) throws ImageException {
double[] samplesX = new double[subvolumeHandleImage.getNumX()];
double[] samplesY = new double[subvolumeHandleImage.getNumY()];
double[] samplesZ = new double[subvolumeHandleImage.getNumZ()];
ISize sampleSize = new ISize(subvolumeHandleImage.getNumX(), subvolumeHandleImage.getNumY(), subvolumeHandleImage.getNumZ());
byte[] pixels = subvolumeHandleImage.getPixels();
boolean[] ignoreMask = new boolean[sampleSize.getXYZ()];
Origin origin = geometry.getOrigin();
Extent extent = geometry.getExtent();
RayCaster.sampleXYZCoordinates(sampleSize, origin, extent, samplesX, samplesY, samplesZ, bCellCentered);
ArrayList<SubvolumeSignedDistanceMap> distanceMaps = new ArrayList<SubvolumeSignedDistanceMap>();
int count = 0;
for (SubVolume subVolume : geometry.getGeometrySpec().getSubVolumes()) {
//
// find surfaces that bound the current SubVolume
//
ArrayList<Surface> surfaces = new ArrayList<Surface>();
for (GeometricRegion geometricRegion : geometry.getGeometrySurfaceDescription().getGeometricRegions()) {
if (geometricRegion instanceof SurfaceGeometricRegion) {
SurfaceGeometricRegion surfaceGeometricRegion = (SurfaceGeometricRegion) geometricRegion;
for (GeometricRegion adjacentRegion : ((SurfaceGeometricRegion) geometricRegion).getAdjacentGeometricRegions()) {
if (adjacentRegion instanceof VolumeGeometricRegion && ((VolumeGeometricRegion) adjacentRegion).getSubVolume() == subVolume) {
surfaces.add(geometry.getGeometrySurfaceDescription().getSurfaceCollection().getSurface(surfaceGeometricRegion));
}
}
}
}
// find unsigned distances in a narrow band for surfaces that bound this SubVolume (expensive)
// values outside the band are assumed to be initialized to MAX_NUMBER
long t1 = System.currentTimeMillis();
double[] distanceMap = localUnsignedDistanceMap(surfaces, samplesX, samplesY, samplesZ, 3);
long t2 = System.currentTimeMillis();
System.out.println(" Distance to triangle: " + (int) ((t2 - t1) / 1000) + " sec.");
// extend signed distance map using fast marching method from narrow band to all points.
// will do it in 2 steps, positive growth first towards inside, then change the sign of the whole
// distance map, then positive growth towards the exterior
// this way, the interior distances will end negative and the exterior distances positive
// 2 step growth saves memory and reduces the number of elements present at any given time in the binary
// heap (binary heap manipulation is the most time consuming factor and it depends on the # of elements)
Arrays.fill(ignoreMask, true);
int subvolumeHandle = subVolume.getHandle();
for (int i = 0; i < ignoreMask.length; i++) {
if (pixels[i] == subvolumeHandle) {
// inside
ignoreMask[i] = false;
} else {
// outside
if (distanceMap[i] < MAX_NUMBER) {
// make negative the part of narrow band which is outside
distanceMap[i] = -distanceMap[i];
}
}
}
// // step 1, we compute distances for the points "inside"
// // the points outside are cold (we don't compute their distances this step)
double deltaX = samplesX[1] - samplesX[0];
double deltaY = samplesY[1] - samplesY[0];
double deltaZ = samplesZ[1] - samplesZ[0];
FastMarchingMethodHA fmm = new FastMarchingMethodHA(samplesX.length, samplesY.length, samplesZ.length, deltaX, deltaY, deltaZ, distanceMap, ignoreMask);
fmm.march();
if (!insideOnly) {
// sign change of the half-completed distance map, the "interior" will become negative as it should be
for (int i = 0; i < distanceMap.length; i++) {
if (distanceMap[i] < MAX_NUMBER) {
distanceMap[i] = -distanceMap[i];
}
}
// step 2, we compute distances for the points "outside"
// no cold points (points we don't care about) this time, they are already frozen
fmm = new FastMarchingMethodHA(samplesX.length, samplesY.length, samplesZ.length, deltaX, deltaY, deltaZ, distanceMap, null);
fmm.march();
} else {
// sign change of the half-completed distance map, the "interior" will become negative as it should be
for (int i = 0; i < distanceMap.length; i++) {
if (distanceMap[i] < MAX_NUMBER) {
if (pixels[i] != subvolumeHandle) {
// need to filter out the part of the narrow band which is not inside
distanceMap[i] = MAX_NUMBER;
} else {
distanceMap[i] = -distanceMap[i];
}
}
}
}
// try { // save some points in a VisIt compatible format
// int xm = samplesX.length;
// int ym = samplesY.length;
// BufferedWriter out = new BufferedWriter(new FileWriter("c:\\TEMP\\2D_circle" + count + ".3D"));
// out.write("x y z value\n");
//
// for(int j=0; j<distanceMap.length; j++) {
// int x = getX(j,xm,ym);
// int y = getY(j,xm,ym);
// int z = getZ(j,xm,ym);
// if(distanceMap[j] < MAX_NUMBER) {
// if((j%2 == 0 || j%3 == 0) && (distanceMap[j] <= -2)) {
// out.write(x + " " + y + " " + z + " " + (int)(distanceMap[j]*10) + "\n");
// } else if((j%17 == 0 || j%23 == 0) && (distanceMap[j] <= 0.5) && (distanceMap[j] > -2)) {
// out.write(x + " " + y + " " + z + " " + (int)(distanceMap[j]*10) + "\n");
// } else if((j%31 == 0 || j%41 == 0) && (distanceMap[j] > 0.5)) {
// out.write(x + " " + y + " " + z + " " + (int)(distanceMap[j]*10) + "\n");
// }
// }
// if(distanceMap[j] < MAX_NUMBER) {
// if(j%2 == 0) {
// out.write(x + " " + y + " " + z + " " + (int)(distanceMap[j]*100) + "\n");
// }
// }
// if(x==50 && y==50 && z==25) { // on the surface
// out.write(x + " " + y + " " + z + " " + (int)(distanceMap[j]*100) + "\n");
// }
// if(x==0 && y==0 && z==0) {
// out.write(x + " " + y + " " + z + " " + 0 + "\n");
// }
// if(x==100 && y==100 && z==100) {
// out.write(x + " " + y + " " + z + " " + 0 + "\n");
// }
//
// }
// out.close();
// } catch (IOException e) {
// }
SubvolumeSignedDistanceMap subvolumeSignedDistanceMap = new SubvolumeSignedDistanceMap(subVolume, samplesX, samplesY, samplesZ, distanceMap);
distanceMaps.add(subvolumeSignedDistanceMap);
count++;
}
return distanceMaps.toArray(new SubvolumeSignedDistanceMap[distanceMaps.size()]);
}
use of cbit.vcell.geometry.SubVolume in project vcell by virtualcell.
the class GeometrySurfaceDescription method refreshSurfaceClasses.
private void refreshSurfaceClasses() {
if (getGeometricRegions() == null) {
return;
}
boolean bChanged = false;
ArrayList<SurfaceClass> surfaceClasses = new ArrayList<SurfaceClass>();
for (int i = 0; i < getGeometricRegions().length; i++) {
if (getGeometricRegions()[i] instanceof SurfaceGeometricRegion) {
SurfaceGeometricRegion surfaceRegion = (SurfaceGeometricRegion) getGeometricRegions()[i];
GeometricRegion[] adjacentRegions = surfaceRegion.getAdjacentGeometricRegions();
if (adjacentRegions.length != 2) {
throw new RuntimeException("found a Surface Region with " + adjacentRegions.length + " adjacent regions, expected 2");
}
if (adjacentRegions[0] instanceof VolumeGeometricRegion && adjacentRegions[1] instanceof VolumeGeometricRegion) {
VolumeGeometricRegion volumeRegion0 = (VolumeGeometricRegion) adjacentRegions[0];
SubVolume subVolume0 = volumeRegion0.getSubVolume();
VolumeGeometricRegion volumeRegion1 = (VolumeGeometricRegion) adjacentRegions[1];
SubVolume subVolume1 = volumeRegion1.getSubVolume();
Set<SubVolume> subvolumes = new HashSet<SubVolume>();
subvolumes.add(subVolume0);
subvolumes.add(subVolume1);
SurfaceClass surfaceClass = (fieldSurfaceClasses == null ? null : getSurfaceClass(subVolume0, subVolume1));
if (surfaceClass == null) {
bChanged = true;
surfaceClass = new SurfaceClass(subvolumes, null, SurfaceClass.createName(subVolume0.getName(), subVolume1.getName()));
}
boolean bFound = false;
for (int j = 0; j < surfaceClasses.size(); j++) {
if (surfaceClass.compareEqual(surfaceClasses.get(j))) {
bFound = true;
break;
}
}
if (!bFound) {
surfaceClasses.add(surfaceClass);
}
}
}
}
if (bChanged || fieldSurfaceClasses.getCurrentValue() == null || fieldSurfaceClasses.getCurrentValue().length != surfaceClasses.size()) {
try {
setSurfaceClasses(surfaceClasses.toArray(new SurfaceClass[surfaceClasses.size()]));
} catch (PropertyVetoException e) {
e.printStackTrace();
throw new RuntimeException("SurfaceClass refresh error: " + e.getMessage(), e);
}
}
}
use of cbit.vcell.geometry.SubVolume in project vcell by virtualcell.
the class GeometrySurfaceDescription method propertyChange.
/**
* This method gets called when a bound property is changed.
* @param evt A PropertyChangeEvent object describing the event source
* and the property that has changed.
*/
public void propertyChange(java.beans.PropertyChangeEvent evt) {
if (evt.getSource() == this && evt.getPropertyName().equals("volumeSampleSize")) {
ISize oldValue = (ISize) evt.getOldValue();
ISize newValue = (ISize) evt.getNewValue();
if (!oldValue.compareEqual(newValue)) {
try {
// nobody listens to this, updateAll() will propagate changes
getRegionImage0().setDirty();
getSurfaceCollection0().setDirty();
fieldGeometricRegions.setDirty();
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
}
if (evt.getSource() == this && evt.getPropertyName().equals("filterCutoffFrequency")) {
Double oldValue = (Double) evt.getOldValue();
Double newValue = (Double) evt.getNewValue();
if (!oldValue.equals(newValue)) {
try {
getSurfaceCollection0().setDirty();
fieldGeometricRegions.setDirty();
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
}
if (evt.getSource() == this && evt.getPropertyName().equals(PROPERTY_NAME_GEOMETRIC_REGIONS)) {
refreshSurfaceClasses();
}
if (evt.getSource() == getGeometry().getGeometrySpec() && (evt.getPropertyName().equals("extent") || evt.getPropertyName().equals("origin"))) {
Matchable oldExtentOrOrigin = (Matchable) evt.getOldValue();
Matchable newExtentOrOrigin = (Matchable) evt.getNewValue();
if (!Compare.isEqual(oldExtentOrOrigin, newExtentOrOrigin)) {
try {
// nobody listens to this, updateAll() will propagate changes
getRegionImage0().setDirty();
getSurfaceCollection0().setDirty();
fieldGeometricRegions.setDirty();
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
}
if (evt.getSource() instanceof AnalyticSubVolume && evt.getPropertyName().equals("expression")) {
Expression oldExpression = (Expression) evt.getOldValue();
Expression newExpression = (Expression) evt.getNewValue();
if (!Compare.isEqual(oldExpression, newExpression)) {
try {
// nobody listens to this, updateAll() will propagate changes
getRegionImage0().setDirty();
getSurfaceCollection0().setDirty();
fieldGeometricRegions.setDirty();
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
}
if (evt.getSource() instanceof CSGObject && evt.getPropertyName().equals(CSGObject.PROPERTY_NAME_ROOT)) {
try {
// nobody listens to this, updateAll() will propagate changes
getRegionImage0().setDirty();
getSurfaceCollection0().setDirty();
fieldGeometricRegions.setDirty();
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
if (evt.getSource() instanceof SubVolume && evt.getPropertyName().equals("name")) {
String oldName = (String) evt.getOldValue();
String newName = (String) evt.getNewValue();
if (!Compare.isEqual(oldName, newName)) {
try {
fieldGeometricRegions.setDirty();
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
}
if (evt.getSource() == getGeometry().getGeometrySpec() && evt.getPropertyName().equals("subVolumes")) {
SubVolume[] oldValue = (SubVolume[]) evt.getOldValue();
SubVolume[] newValue = (SubVolume[]) evt.getNewValue();
//
for (int i = 0; oldValue != null && i < oldValue.length; i++) {
oldValue[i].removePropertyChangeListener(this);
}
for (int i = 0; newValue != null && i < newValue.length; i++) {
newValue[i].addPropertyChangeListener(this);
}
//
if (oldValue == null || newValue == null || !Compare.isEqualStrict(oldValue, newValue)) {
try {
// nobody listens to this, updateAll() will propagate changes
getRegionImage0().setDirty();
getSurfaceCollection0().setDirty();
fieldGeometricRegions.setDirty();
} catch (Exception e) {
e.printStackTrace(System.out);
}
} else if (fieldGeometricRegions.getCurrentValue() != null && oldValue != newValue) {
//
for (int i = 0; i < newValue.length; i++) {
SubVolume subVolume = newValue[i];
for (int j = 0; j < fieldGeometricRegions.getCurrentValue().length; j++) {
if (fieldGeometricRegions.getCurrentValue()[j] instanceof VolumeGeometricRegion) {
VolumeGeometricRegion volumeRegion = (VolumeGeometricRegion) fieldGeometricRegions.getCurrentValue()[j];
//
if (volumeRegion.getSubVolume().compareEqual(subVolume) && volumeRegion.getSubVolume() != subVolume) {
volumeRegion.setSubVolume(subVolume);
}
}
}
}
}
}
}
use of cbit.vcell.geometry.SubVolume in project vcell by virtualcell.
the class RayCaster method sampleGeometry.
public static VCImage sampleGeometry(Geometry geometry, ISize sampleSize, boolean bCellCentered) throws ImageException, PropertyVetoException, GeometryException, ExpressionException {
int numX = sampleSize.getX();
int numY = sampleSize.getY();
int numZ = sampleSize.getZ();
Origin origin = geometry.getOrigin();
Extent extent = geometry.getExtent();
SurfaceCollection surfaceCollection = geometry.getGeometrySurfaceDescription().getSurfaceCollection();
int surfaceCount = surfaceCollection.getSurfaceCount();
//
if (surfaceCount == 0 && geometry.getGeometrySpec().getNumSubVolumes() == 1) {
byte[] pixels = new byte[numX * numY * numZ];
SubVolume subVolume = geometry.getGeometrySpec().getSubVolumes()[0];
Arrays.fill(pixels, (byte) subVolume.getHandle());
VCImageUncompressed vcImage = new VCImageUncompressed(null, pixels, extent, numX, numY, numZ);
return vcImage;
}
VolumeSamples volumeSamples = volumeSampleSurface(surfaceCollection, sampleSize, origin, extent, bCellCentered);
// for each mask bit, find union of masks which contain that bit ... iterate until no change.
HashSet<Long> uniqueMasks = volumeSamples.getUniqueMasks();
ArrayList<Long> consensusMaskArray = new ArrayList<Long>(uniqueMasks);
// boolean bChanged = true;
// while (bChanged){
// bChanged = false;
// for (int i=0;i<consensusMaskArray.size();i++){
// for (int j=i+1;j<consensusMaskArray.size();j++){
// if ((((long)consensusMaskArray.get(i)) & ((long)consensusMaskArray.get(j))) != 0L && (((long)consensusMaskArray.get(i))!=((long)consensusMaskArray.get(j)))){
// long merged = consensusMaskArray.get(i) | consensusMaskArray.get(j);
// if ((((merged<<1) & merged)==0L) && (((merged>>1) & merged)==0L)){
// System.out.println("++++++++++++++++++++++++++++++++ merged "+Long.toBinaryString(consensusMaskArray.get(i))+" with "+Long.toBinaryString(consensusMaskArray.get(j))+" to get "+Long.toBinaryString(merged));
// consensusMaskArray.set(i, merged);
// consensusMaskArray.set(j, merged);
// bChanged = true;
// }
// }
// }
// }
// }
/*
for (Long l : consensusMaskArray) {
System.out.println("++++++++++++++++++++++++++++++++ final mask "+Long.toBinaryString(l));
}
*/
HashSet<Long> consensusSet = new HashSet<Long>(consensusMaskArray);
byte[] pixels = new byte[numX * numY * numZ];
setSurfaceMasks(geometry.getGeometrySurfaceDescription().getSurfaceCollection());
for (long mask : consensusSet) {
// for this consensus mask, find the subvolume that is associated
SubVolume subvolume = getSubvolume(geometry, mask);
if (subvolume == null) {
throw new RuntimeException("could not reconcile volume samples with original geometry");
}
byte pixelValue = (byte) subvolume.getHandle();
for (int i = 0; i < volumeSamples.getNumXYZ(); i++) {
if ((volumeSamples.getMask(i) & mask) != 0) {
pixels[i] = (byte) pixelValue;
}
}
}
VCImageUncompressed vcImage = new VCImageUncompressed(null, pixels, extent, numX, numY, numZ);
return vcImage;
}
use of cbit.vcell.geometry.SubVolume in project vcell by virtualcell.
the class GeometryClassLegendShape method paintSelf.
@Override
public void paintSelf(Graphics2D g, int absPosX, int absPosY) {
// draw elipse
if (geometryClass instanceof SubVolume) {
SubVolume subVolume = (SubVolume) geometryClass;
Color fillColor = getSubvolumeColor(subVolume);
g.setColor(fillColor);
g.fill3DRect(absPosX + 1, absPosY + 1, 2 * radius - 1, 2 * radius - 1, true);
g.setColor(forgroundColor);
g.draw3DRect(absPosX, absPosY, 2 * radius, 2 * radius, true);
} else if (geometryClass instanceof SurfaceClass) {
SurfaceClass surfaceClass = (SurfaceClass) geometryClass;
Set<SubVolume> adjacentSubVolumes = surfaceClass.getAdjacentSubvolumes();
Iterator<SubVolume> iterator = adjacentSubVolumes.iterator();
SubVolume subVolume1 = iterator.next();
SubVolume subVolume2 = iterator.next();
Color fillColor1 = null;
Color fillColor2 = null;
// make same choice each time so that repaint don't flicker
if (subVolume1.getName().compareTo(subVolume2.getName()) > 0) {
fillColor1 = getSubvolumeColor(subVolume1);
fillColor2 = getSubvolumeColor(subVolume2);
} else {
fillColor1 = getSubvolumeColor(subVolume2);
fillColor2 = getSubvolumeColor(subVolume1);
}
g.setColor(fillColor1);
g.fill3DRect(absPosX + 1, absPosY + 1, radius, 2 * radius - 1, true);
g.setColor(fillColor2);
g.fill3DRect(absPosX + 1 + radius, absPosY + 1, radius - 1, 2 * radius - 1, true);
g.setColor(forgroundColor);
g.draw3DRect(absPosX, absPosY, 2 * radius, 2 * radius, true);
}
int textX = getLabelPos().x + absPosX;
int textY = getLabelPos().y + absPosY;
g.setColor(forgroundColor);
if (getLabel() != null && getLabel().length() > 0) {
g.drawString(getLabel(), textX, textY);
}
return;
}
Aggregations