use of cbit.vcell.geometry.surface.Quadrilateral in project vcell by virtualcell.
the class RegionImage method verifyQuadVertexOrdering.
public void verifyQuadVertexOrdering(double maxAngleDegrees) {
if (maxAngleDegrees > 180 || maxAngleDegrees < 0) {
throw new IllegalArgumentException("maxAngleDegrees must be between 0 and 180");
}
for (int s = 0; s < surfaceCollection.getSurfaceCount(); s++) {
Surface surface = surfaceCollection.getSurfaces(s);
for (int p = 0; p < surface.getPolygonCount(); p++) {
Quadrilateral quad = (Quadrilateral) surface.getPolygons(p);
// average the polygon vertices to get the center of the quad
// this is also halfway between the coordinates of the inside and outside volume elements.
cbit.vcell.geometry.surface.Node[] nodes = quad.getNodes();
// have normal go in direction from low region index to high region index
int lowVolumeIndex = quad.getVolIndexNeighbor1();
int hiVolumeIndex = quad.getVolIndexNeighbor2();
int lowRegionIndex = getRegionInfoFromOffset(quad.getVolIndexNeighbor1()).getRegionIndex();
int hiRegionIndex = getRegionInfoFromOffset(quad.getVolIndexNeighbor2()).getRegionIndex();
if (lowRegionIndex > hiRegionIndex) {
int temp = lowVolumeIndex;
lowVolumeIndex = hiVolumeIndex;
hiVolumeIndex = temp;
temp = lowRegionIndex;
lowRegionIndex = hiRegionIndex;
hiRegionIndex = temp;
}
if (surface.getInteriorRegionIndex() != lowRegionIndex || surface.getExteriorRegionIndex() != hiRegionIndex) {
StringBuffer buffer = new StringBuffer();
buffer.append("Surface interiorRegionIndex=" + surface.getInteriorRegionIndex() + " and exteriorRegionIndex=" + surface.getExteriorRegionIndex());
buffer.append("Polygon lowRegionIndex=" + lowRegionIndex + ", hiRegionIndex=" + hiRegionIndex);
throw new RuntimeException("surface and polygon indices don't agree\n" + buffer.toString());
}
Vect3d v0 = new Vect3d(nodes[0].getX(), nodes[0].getY(), nodes[0].getZ());
Vect3d v1 = new Vect3d(nodes[1].getX(), nodes[1].getY(), nodes[1].getZ());
Vect3d v2 = new Vect3d(nodes[2].getX(), nodes[2].getY(), nodes[2].getZ());
Vect3d v3 = new Vect3d(nodes[3].getX(), nodes[3].getY(), nodes[3].getZ());
int volumeIndexNormalDiff = hiVolumeIndex - lowVolumeIndex;
Vect3d v01 = Vect3d.sub(v1, v0);
Vect3d v02 = Vect3d.sub(v2, v0);
Vect3d unit012 = v01.cross(v02);
unit012.unit();
Vect3d v03 = Vect3d.sub(v3, v0);
Vect3d unit023 = v02.cross(v03);
unit023.unit();
Vect3d gridNormal = null;
if (volumeIndexNormalDiff == 1) {
// y-z plane, normal is [1 0 0]
gridNormal = new Vect3d(1, 0, 0);
} else if (volumeIndexNormalDiff == -1) {
// y-z plane, normal is [-1 0 0]
gridNormal = new Vect3d(-1, 0, 0);
} else if (volumeIndexNormalDiff == getNumX()) {
// y-z plane, normal is [0 1 0]
gridNormal = new Vect3d(0, 1, 0);
} else if (volumeIndexNormalDiff == -getNumX()) {
// y-z plane, normal is [0 -1 0]
gridNormal = new Vect3d(0, -1, 0);
} else if (volumeIndexNormalDiff == getNumX() * getNumY()) {
// y-z plane, normal is [0 0 1]
gridNormal = new Vect3d(0, 0, 1);
} else if (volumeIndexNormalDiff == -getNumX() * getNumY()) {
// y-z plane, normal is [0 0 -1]
gridNormal = new Vect3d(0, 0, -1);
}
if (this.filterCutoffFrequency < NO_SMOOTHING) {
// after smoothing ... should point in general direction (<90 degrees).
if (unit012.dot(unit023) < Math.cos(maxAngleDegrees / 180.0 * Math.PI)) {
StringBuffer buffer = new StringBuffer();
buffer.append("normal_012 = [" + unit012.getX() + " " + unit012.getY() + " " + unit012.getZ() + "]\n");
buffer.append("normal_023 = [" + unit023.getX() + " " + unit023.getY() + " " + unit023.getZ() + "]\n");
buffer.append("gridNormal = [" + gridNormal.getX() + " " + gridNormal.getY() + " " + gridNormal.getZ() + "]\n");
throw new RuntimeException("quad(" + p + ") on surface(" + s + "): two triangles from same quad (norm1.dot(norm2)=" + unit012.dot(unit023) + ") are > " + maxAngleDegrees + " degrees or inner product < " + Math.cos(maxAngleDegrees / 180.0 * Math.PI) + ":\n" + buffer.toString());
} else if (unit012.dot(gridNormal) < Math.cos(maxAngleDegrees / 180.0 * Math.PI)) {
StringBuffer buffer = new StringBuffer();
buffer.append("normal_012 = [" + unit012.getX() + " " + unit012.getY() + " " + unit012.getZ() + "]\n");
buffer.append("normal_023 = [" + unit023.getX() + " " + unit023.getY() + " " + unit023.getZ() + "]\n");
buffer.append("gridNormal = [" + gridNormal.getX() + " " + gridNormal.getY() + " " + gridNormal.getZ() + "]\n");
throw new RuntimeException("quad(" + p + ") on surface(" + s + "): quad normal compared with grid normal (norm.dot(gridNormal)=" + unit012.dot(unit023) + ") is > " + maxAngleDegrees + " degrees or inner product < " + Math.cos(maxAngleDegrees / 180.0 * Math.PI) + " from orginal staircase:\n" + buffer.toString());
} else {
// System.out.println("normals ok");
}
} else {
// no smoothing ... both triangle normals must light up exactly
if (Math.abs(unit012.dot(unit023) - 1.0) > 1e-8) {
StringBuffer buffer = new StringBuffer();
buffer.append("two triangles contradicted themselves\n");
buffer.append("normal_012 = [" + unit012.getX() + " " + unit012.getY() + " " + unit012.getZ() + "]\n");
buffer.append("normal_023 = [" + unit023.getX() + " " + unit023.getY() + " " + unit023.getZ() + "]\n");
buffer.append("gridNormal = [" + gridNormal.getX() + " " + gridNormal.getY() + " " + gridNormal.getZ() + "]\n");
throw new RuntimeException("two triangles from same quad have normals that are in opposite directions:\n" + buffer.toString());
} else if (Math.abs(unit012.dot(gridNormal) - 1.0) > 1e-8) {
StringBuffer buffer = new StringBuffer();
buffer.append("normal_012 = [" + unit012.getX() + " " + unit012.getY() + " " + unit012.getZ() + "]\n");
buffer.append("normal_023 = [" + unit023.getX() + " " + unit023.getY() + " " + unit023.getZ() + "]\n");
buffer.append("gridNormal = [" + gridNormal.getX() + " " + gridNormal.getY() + " " + gridNormal.getZ() + "]\n");
throw new RuntimeException("triangles contradict grid normal:\n" + buffer.toString());
} else {
// System.out.println("normals ok");
}
}
}
}
}
use of cbit.vcell.geometry.surface.Quadrilateral in project vcell by virtualcell.
the class RegionImage method calculateNeighbors.
private void calculateNeighbors() {
// Find neighbors
SortEdgesLikeCplusplus sortEdgesLikeCplusplus = new SortEdgesLikeCplusplus();
membraneEdgeNeighbors = new ArrayList[surfaceCollection.getSurfaceCount()][];
for (int surfindex = 0; surfindex < surfaceCollection.getSurfaceCount(); surfindex++) {
membraneEdgeNeighbors[surfindex] = new ArrayList[surfaceCollection.getSurfaces(surfindex).getPolygonCount()];
for (int wantNeighborsOfThisQuadUnRemappedIndex = 0; wantNeighborsOfThisQuadUnRemappedIndex < surfaceCollection.getSurfaces(surfindex).getPolygonCount(); wantNeighborsOfThisQuadUnRemappedIndex++) {
if (DEBUG) {
System.out.println("neighbors surf=" + surfindex + " quad=" + wantNeighborsOfThisQuadUnRemappedIndex + " quadmaster=" + remapQuadIndexes[surfindex][wantNeighborsOfThisQuadUnRemappedIndex]);
}
membraneEdgeNeighbors[surfindex][wantNeighborsOfThisQuadUnRemappedIndex] = new ArrayList<>();
Quadrilateral wantNieghborsOfThisQuad = (Quadrilateral) surfaceCollection.getSurfaces(surfindex).getPolygons(wantNeighborsOfThisQuadUnRemappedIndex);
int wantQuadNodeCount = wantNieghborsOfThisQuad.getNodeCount();
for (int wantedQuadNodeIndex = 0; wantedQuadNodeIndex < wantQuadNodeCount; wantedQuadNodeIndex++) {
int edgeNodePoint1 = wantNieghborsOfThisQuad.getNodes()[wantedQuadNodeIndex].getGlobalIndex();
int edgeNodePoint2 = wantNieghborsOfThisQuad.getNodes()[(wantedQuadNodeIndex == (wantQuadNodeCount - 1) ? 0 : wantedQuadNodeIndex + 1)].getGlobalIndex();
if (edgeNodePoint1 > edgeNodePoint2) {
edgeNodePoint1 = edgeNodePoint2;
edgeNodePoint2 = wantNieghborsOfThisQuad.getNodes()[wantedQuadNodeIndex].getGlobalIndex();
}
TreeSet<MembraneElementIdentifier> neighborsSharingThisEdge = edgeMap.get(edgeNodePoint1).get(edgeNodePoint2);
Iterator<MembraneElementIdentifier> neighborsOfEdgeIter = neighborsSharingThisEdge.iterator();
boolean bEdgeHasNeighbors = false;
while (neighborsOfEdgeIter.hasNext()) {
MembraneElementIdentifier neighborOfEdge = neighborsOfEdgeIter.next();
// add neighbors on my surface (exclude edge share from other surfaces) and exclude myself from neighbor list
if (neighborOfEdge.surfaceIndex == surfindex) {
if (neighborOfEdge.nonMasterPolygonIndex != wantNeighborsOfThisQuadUnRemappedIndex) {
if (neighborsSharingThisEdge.size() > 2 && (getRegionInfoFromOffset(((Quadrilateral) surfaceCollection.getSurfaces(neighborOfEdge.surfaceIndex).getPolygons(neighborOfEdge.nonMasterPolygonIndex)).getVolIndexNeighbor2()).regionIndex == getRegionInfoFromOffset(wantNieghborsOfThisQuad.getVolIndexNeighbor2()).regionIndex && ((Quadrilateral) surfaceCollection.getSurfaces(neighborOfEdge.surfaceIndex).getPolygons(neighborOfEdge.nonMasterPolygonIndex)).getVolIndexNeighbor2() != wantNieghborsOfThisQuad.getVolIndexNeighbor2())) {
// do nothing
// Quadrilateral q2 =
// (Quadrilateral)surfaceCollection.getSurfaces(surfindex).getPolygons(neighborOfEdge.nonMasterPolygonIndex);
// System.out.println("removed "+remapQuadIndexes[neighborOfEdge.surfaceIndex][neighborOfEdge.nonMasterPolygonIndex]+" "+q2);
} else {
bEdgeHasNeighbors = true;
membraneEdgeNeighbors[surfindex][wantNeighborsOfThisQuadUnRemappedIndex].add(new MembraneEdgeNeighbor(neighborOfEdge, remapQuadIndexes[neighborOfEdge.surfaceIndex][neighborOfEdge.nonMasterPolygonIndex], edgeNodePoint1, edgeNodePoint2));
}
} else {
sortEdgesLikeCplusplus.setPerpendicularAxis(neighborOfEdge.planePerpendicularToAxis);
}
}
}
if (!bEdgeHasNeighbors) {
// Add empty edge neighbor
membraneEdgeNeighbors[surfindex][wantNeighborsOfThisQuadUnRemappedIndex].add(new MembraneEdgeNeighbor(edgeNodePoint1, edgeNodePoint2));
}
}
// //Fix ambiguous
// Iterator<Entry<Integer, HashMap<Integer, ArrayList<MembraneEdgeNeighbor>>>> iterator1 = foundNeighborsByEdge.entrySet().iterator();
// while(iterator1.hasNext()){
// Entry<Integer, HashMap<Integer, ArrayList<MembraneEdgeNeighbor>>> entry1 = iterator1.next();
// Iterator<Entry<Integer, ArrayList<MembraneEdgeNeighbor>>> iterator2 = entry1.getValue().entrySet().iterator();
// while(iterator2.hasNext()){
// Entry<Integer, ArrayList<MembraneEdgeNeighbor>> entry2 = iterator2.next();
// if(entry2.getValue().size() > 2){
// ArrayList<MembraneEdgeNeighbor> removethese = new ArrayList<>();
// for(int i=0;i<entry2.getValue().size();i++){
// MembraneEdgeNeighbor membraneEdgeNeighbor = entry2.getValue().get(i);
// Quadrilateral q2 =
// (Quadrilateral)surfaceCollection.getSurfaces(membraneEdgeNeighbor.getMembraneElementIdentifier().surfaceIndex).getPolygons(membraneEdgeNeighbor.getMembraneElementIdentifier().nonMasterPolygonIndex);
// if(DEBUG){
// System.out.println(
// wantNeighborsOfThisQuadUnRemappedIndex+" "+wantNieghborsOfThisQuad.getVolIndexNeighbor2()+" "+getRegionInfoFromOffset(wantNieghborsOfThisQuad.getVolIndexNeighbor2()).regionIndex+" "+
// membraneEdgeNeighbor.getMembraneElementIdentifier().nonMasterPolygonIndex+" q2="+
// q2.getVolIndexNeighbor1()+" "+getRegionInfoFromOffset(q2.getVolIndexNeighbor1()).regionIndex+" "+
// q2.getVolIndexNeighbor2()+" "+getRegionInfoFromOffset(q2.getVolIndexNeighbor2()).regionIndex+" "+
// surfaceCollection.getNodes()[membraneEdgeNeighbor.edgeBaseNodeIndex]+" "+surfaceCollection.getNodes()[membraneEdgeNeighbor.edgeOtherNodeIndex]);
// }
// if(getRegionInfoFromOffset(q2.getVolIndexNeighbor2()).regionIndex == getRegionInfoFromOffset(wantNieghborsOfThisQuad.getVolIndexNeighbor2()).regionIndex &&
// q2.getVolIndexNeighbor2() != wantNieghborsOfThisQuad.getVolIndexNeighbor2()){
// if(DEBUG){System.out.println("remove "+membraneEdgeNeighbor.getMembraneElementIdentifier().nonMasterPolygonIndex);}
// removethese.add(membraneEdgeNeighbor);
// }
// }
// for(int i=0;i<removethese.size();i++){
// membraneEdgeNeighbors[surfindex][wantNeighborsOfThisQuadUnRemappedIndex].remove(removethese.get(i));
// }
// if(DEBUG){System.out.println("");}
// // System.out.println("Quad "+wantNeighborsOfThisQuadUnRemappedIndex+" has Edge "+entry1.getKey()+" "+entry2.getKey()+" with "+entry2.getValue().size()+" neighbors");
// }
// }
// }
Collections.sort(membraneEdgeNeighbors[surfindex][wantNeighborsOfThisQuadUnRemappedIndex], sortEdgesLikeCplusplus);
}
}
}
use of cbit.vcell.geometry.surface.Quadrilateral in project vcell by virtualcell.
the class GeometryFileWriter method write.
/**
* Insert the method's description here.
* Creation date: (7/19/2004 10:54:30 AM)
* @param geometrySurfaceDescription cbit.vcell.geometry.surface.GeometrySurfaceDescription
* @throws IOException
*/
public static void write(Writer writer, Geometry resampledGeometry) throws IOException {
//
// "name" name
// "dimension" dimension
// "extent" extentx extenty extentz
// "origin" originx originy originz
// "volumeRegions" num
// name totalVolume featureHandle
// "membraneRegions" num
// name totalArea volumeRegionIndex1 volumeRegionIndex2
// "volumeSamples" numX, numY, numZ
// uncompressed regionIndexs for each volume element
// compressed regionIndexs for each volume element
// "nodes" num
// nodeIndex x y z
// "cells" num
// cellIndex patchIndex node1 node2 node3 node4
// "celldata"
// insideVolumeIndex outsideVolumeIndex area normalx normaly normalz
//
//
// When we are writing volume regions, we sort regions so that ID is equal to index
//
writer.write("name " + resampledGeometry.getName() + "\n");
writer.write("dimension " + resampledGeometry.getDimension() + "\n");
org.vcell.util.Extent extent = resampledGeometry.getExtent();
org.vcell.util.Origin origin = resampledGeometry.getOrigin();
switch(resampledGeometry.getDimension()) {
case 1:
writer.write("size " + extent.getX() + "\n");
writer.write("origin " + origin.getX() + "\n");
break;
case 2:
writer.write("size " + extent.getX() + " " + extent.getY() + "\n");
writer.write("origin " + origin.getX() + " " + origin.getY() + "\n");
break;
case 3:
writer.write("size " + extent.getX() + " " + extent.getY() + " " + extent.getZ() + "\n");
writer.write("origin " + origin.getX() + " " + origin.getY() + " " + origin.getZ() + "\n");
break;
}
GeometrySurfaceDescription geoSurfaceDesc = resampledGeometry.getGeometrySurfaceDescription();
RegionImage regionImage = geoSurfaceDesc.getRegionImage();
SurfaceCollection surfaceCollection = geoSurfaceDesc.getSurfaceCollection();
GeometricRegion[] geometricRegions = geoSurfaceDesc.getGeometricRegions();
int numVolumeRegions = 0;
int numMembraneRegions = 0;
Vector<VolumeGeometricRegion> volRegionList = new Vector<VolumeGeometricRegion>();
if (geometricRegions != null) {
for (int i = 0; i < geometricRegions.length; i++) {
if (geometricRegions[i] instanceof VolumeGeometricRegion) {
numVolumeRegions++;
volRegionList.add((VolumeGeometricRegion) geometricRegions[i]);
} else if (geometricRegions[i] instanceof SurfaceGeometricRegion) {
numMembraneRegions++;
}
}
}
//
// get ordered array of volume regions (where "id" == index into array)... fail if impossible
//
java.util.Collections.sort(volRegionList, new Comparator<VolumeGeometricRegion>() {
public int compare(VolumeGeometricRegion reg1, VolumeGeometricRegion reg2) {
if (reg1.getRegionID() < reg2.getRegionID()) {
return -1;
} else if (reg1.getRegionID() > reg2.getRegionID()) {
return 1;
} else {
return 0;
}
}
public boolean equals(Object obj) {
return this == obj;
}
});
VolumeGeometricRegion[] volRegions = (VolumeGeometricRegion[]) org.vcell.util.BeanUtils.getArray(volRegionList, VolumeGeometricRegion.class);
writer.write("volumeRegions " + numVolumeRegions + "\n");
for (int i = 0; i < volRegions.length; i++) {
if (volRegions[i].getRegionID() != i) {
throw new RuntimeException("Region ID != Region Index, they must be the same!");
}
writer.write(volRegions[i].getName() + " " + volRegions[i].getSize() + " " + volRegions[i].getSubVolume().getHandle() + "\n");
}
writer.write("membraneRegions " + numMembraneRegions + "\n");
if (geometricRegions != null) {
for (int i = 0; i < geometricRegions.length; i++) {
if (geometricRegions[i] instanceof SurfaceGeometricRegion) {
SurfaceGeometricRegion surfaceRegion = (SurfaceGeometricRegion) geometricRegions[i];
GeometricRegion[] neighbors = surfaceRegion.getAdjacentGeometricRegions();
VolumeGeometricRegion insideRegion = (VolumeGeometricRegion) neighbors[0];
VolumeGeometricRegion outsideRegion = (VolumeGeometricRegion) neighbors[1];
writer.write(surfaceRegion.getName() + " " + surfaceRegion.getSize() + " " + insideRegion.getRegionID() + " " + outsideRegion.getRegionID() + "\n");
}
}
}
//
// write volume samples
//
ISize volumeSampleSize = geoSurfaceDesc.getVolumeSampleSize();
switch(resampledGeometry.getDimension()) {
case 1:
writer.write("volumeSamples " + volumeSampleSize.getX() + "\n");
break;
case 2:
writer.write("volumeSamples " + volumeSampleSize.getX() + " " + volumeSampleSize.getY() + "\n");
break;
case 3:
writer.write("volumeSamples " + volumeSampleSize.getX() + " " + volumeSampleSize.getY() + " " + volumeSampleSize.getZ() + "\n");
break;
}
// regionImage
if (regionImage != null) {
if (regionImage.getNumRegions() > 65536) {
throw new RuntimeException("cannot process a geometry with more than 65536 volume regions");
}
byte[] uncompressedRegionIDs = new byte[2 * regionImage.getNumX() * regionImage.getNumY() * regionImage.getNumZ()];
for (int i = 0, j = 0; i < uncompressedRegionIDs.length; i += 2, j++) {
int regindex = regionImage.getRegionInfoFromOffset(j).getRegionIndex();
uncompressedRegionIDs[i] = (byte) (regindex & 0x000000ff);
uncompressedRegionIDs[i + 1] = (byte) ((regindex & 0x0000ff00) >> 8);
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DeflaterOutputStream dos = new DeflaterOutputStream(bos);
dos.write(uncompressedRegionIDs, 0, uncompressedRegionIDs.length);
dos.close();
byte[] compressedRegionIDs = bos.toByteArray();
writer.write(org.vcell.util.Hex.toString(compressedRegionIDs) + "\n");
} else {
writer.write("\n");
}
//
if (surfaceCollection == null) {
throw new RuntimeException("geometry is not updated");
}
int numCells = surfaceCollection.getTotalPolygonCount();
writer.write("cells " + numCells + "\n");
// "celldata"
// insideVolumeIndex outsideVolumeIndex area normalx normaly normalz
//
int cellID = 0;
int dimension = resampledGeometry.getDimension();
double correctCoeff = 1;
if (dimension == 1) {
correctCoeff = extent.getY() * extent.getZ();
} else if (dimension == 2) {
correctCoeff = extent.getZ();
}
if (surfaceCollection != null) {
for (int i = 0; i < surfaceCollection.getSurfaceCount(); i++) {
Surface surface = surfaceCollection.getSurfaces(i);
int region1Outside = 0;
int region1Inside = 0;
for (int j = 0; j < surface.getPolygonCount(); j++) {
Quadrilateral polygon = (Quadrilateral) surface.getPolygons(j);
Node[] node = polygon.getNodes();
cbit.vcell.render.Vect3d elementCoord = new cbit.vcell.render.Vect3d();
int nodesOnBoundary = 0;
for (int k = 0; k < node.length; k++) {
if (!node[k].getMoveX() || (dimension > 1 && !node[k].getMoveY()) || (dimension == 3 && !node[k].getMoveZ())) {
nodesOnBoundary++;
}
}
if (nodesOnBoundary == 0) {
for (int k = 0; k < node.length; k++) {
elementCoord.add(new cbit.vcell.render.Vect3d(node[k].getX(), node[k].getY(), node[k].getZ()));
}
elementCoord.scale(0.25);
} else if (nodesOnBoundary == 2) {
for (int k = 0; k < node.length; k++) {
if (!node[k].getMoveX() || !node[k].getMoveY() || !node[k].getMoveZ()) {
elementCoord.add(new cbit.vcell.render.Vect3d(node[k].getX(), node[k].getY(), node[k].getZ()));
}
}
elementCoord.scale(0.5);
} else if (nodesOnBoundary == 3) {
for (int k = 0; k < node.length; k++) {
if (!node[k].getMoveX() && !node[k].getMoveY() || !node[k].getMoveY() && !node[k].getMoveZ() || !node[k].getMoveX() && !node[k].getMoveZ()) {
elementCoord.set(node[k].getX(), node[k].getY(), node[k].getZ());
}
}
} else {
throw new RuntimeException("Unexcepted number of nodes on boundary for a polygon: " + nodesOnBoundary);
}
cbit.vcell.render.Vect3d unitNormal = new cbit.vcell.render.Vect3d();
polygon.getUnitNormal(unitNormal);
int volNeighbor1Region = regionImage.getRegionInfoFromOffset(polygon.getVolIndexNeighbor1()).getRegionIndex();
int volNeighbor2Region = regionImage.getRegionInfoFromOffset(polygon.getVolIndexNeighbor2()).getRegionIndex();
if (surface.getExteriorRegionIndex() == volNeighbor1Region && surface.getInteriorRegionIndex() == volNeighbor2Region) {
region1Outside++;
}
if (surface.getExteriorRegionIndex() == volNeighbor2Region && surface.getInteriorRegionIndex() == volNeighbor1Region) {
region1Inside++;
}
writer.write(cellID + " " + polygon.getVolIndexNeighbor1() + " " + polygon.getVolIndexNeighbor2() + " " + polygon.getArea() / correctCoeff + " " + elementCoord.getX() + " " + elementCoord.getY() + " " + elementCoord.getZ() + " " + unitNormal.getX() + " " + unitNormal.getY() + " " + unitNormal.getZ() + "\n");
cellID++;
}
if (region1Inside != surface.getPolygonCount() && region1Outside != surface.getPolygonCount()) {
throw new RuntimeException("Volume neighbor regions not consistent: [total, inside, outside]=" + surface.getPolygonCount() + "," + region1Inside + "," + region1Outside + "]");
}
}
}
}
use of cbit.vcell.geometry.surface.Quadrilateral in project vcell by virtualcell.
the class ExportDocument method writeStanfordPolygon.
public static void writeStanfordPolygon(GeometrySurfaceDescription geometrySurfaceDescription, Writer writer) throws IOException {
int faceCount = geometrySurfaceDescription.getSurfaceCollection().getTotalPolygonCount();
int vertCount = geometrySurfaceDescription.getSurfaceCollection().getNodes().length;
writer.write("ply\n");
writer.write("format ascii 1.0\n");
writer.write("comment " + geometrySurfaceDescription.getGeometry().getName() + "\n");
writer.write("element vertex " + vertCount + "\n");
writer.write("property float x\n");
writer.write("property float y\n");
writer.write("property float z\n");
writer.write("element face " + faceCount + "\n");
writer.write("property list uchar int vertex_index\n");
writer.write("end_header\n");
// write verts x y z
for (int i = 0; i < vertCount; i++) {
Node vertex = geometrySurfaceDescription.getSurfaceCollection().getNodes()[i];
writer.write((float) vertex.getX() + " " + (float) vertex.getY() + " " + (float) vertex.getZ() + "\n");
}
// write faces as a set of connected vertex indexes
for (int i = 0; i < geometrySurfaceDescription.getSurfaceCollection().getSurfaceCount(); i++) {
for (int j = 0; j < geometrySurfaceDescription.getSurfaceCollection().getSurfaces(i).getPolygonCount(); j++) {
Quadrilateral quad = (Quadrilateral) geometrySurfaceDescription.getSurfaceCollection().getSurfaces(i).getPolygons(j);
writer.write(quad.getNodeCount() + "");
for (int k = 0; k < quad.getNodeCount(); k++) {
writer.write(" ");
writer.write(quad.getNodes(k).getGlobalIndex() + "");
}
writer.write("\n");
}
}
}
use of cbit.vcell.geometry.surface.Quadrilateral in project vcell by virtualcell.
the class DataValueSurfaceViewer method updatePickInfoDisplay.
/**
* Insert the method's description here.
* Creation date: (10/2/2005 8:12:14 AM)
*/
private void updatePickInfoDisplay() {
if (getSurfaceCollectionDataInfoProvider() != null) {
SurfaceCanvas.SurfaceCollectionPick currentPick = null;
if (lastMouse != null) {
currentPick = getSurfaceCanvas1().pickPolygon(lastMouse.getX(), lastMouse.getY());
}
if (currentPick != null) {
org.vcell.util.Coordinate centroid = ((Quadrilateral) getSurfaceCollectionDataInfo().getSurfaceCollection().getSurfaces(currentPick.surfaceIndex).getPolygons(currentPick.polygonIndex)).calculateCentroid();
df.setMaximumFractionDigits(5);
double area = getSurfaceCollectionDataInfoProvider().getArea(currentPick.surfaceIndex, currentPick.polygonIndex);
int membrIndex = getSurfaceCollectionDataInfoProvider().getMembraneIndex(currentPick.surfaceIndex, currentPick.polygonIndex);
String valText = "unknown";
try {
valText = "" + (getSurfaceCollectionDataInfoProvider().isMembrIndexInVarDomain(membrIndex) ? (float) getSurfaceCollectionDataInfoProvider().getValue(currentPick.surfaceIndex, currentPick.polygonIndex) : "undefined");
} catch (Exception e) {
e.printStackTrace();
valText = "Err: " + e.getClass().getSimpleName();
}
getJLabelInfo().setText(" index=" + membrIndex + " val=" + valText + " area=" + (area != MembraneElement.AREA_UNDEFINED ? df.format(area) + "" : "No Calc") + " centroid=(" + df.format(centroid.getX()) + "," + df.format(centroid.getY()) + "," + df.format(centroid.getZ()) + ")");
return;
} else {
String aoiString = " ";
int count = 0;
double aoiArea = 0;
double min = Double.POSITIVE_INFINITY;
double max = Double.NEGATIVE_INFINITY;
double mean = 0;
double wmean = 0;
boolean isAreaUndefined = false;
if (bAOI != null) {
for (int i = 0; i < bAOI.length; i += 1) {
for (int j = 0; j < bAOI[i].length; j += 1) {
if (bAOI[i][j]) {
count += 1;
double area = getSurfaceCollectionDataInfoProvider().getArea(i, j);
if (area == cbit.vcell.solvers.MembraneElement.AREA_UNDEFINED) {
isAreaUndefined = true;
} else {
aoiArea += area;
}
double val = getSurfaceCollectionDataInfoProvider().getValue(i, j);
mean += val;
if (val < min) {
min = val;
}
if (val > max) {
max = val;
}
if (!isAreaUndefined) {
wmean += val * area;
}
}
}
}
if (count > 0) {
mean /= count;
if (!isAreaUndefined) {
wmean /= aoiArea;
}
}
}
if (count > 0) {
aoiString = "AOI(" + count + ") Area=" + (isAreaUndefined ? "No Calc" : "" + (float) aoiArea) + " WMEAN=" + (isAreaUndefined ? "No Calc" : "" + wmean) + ",Min=" + (float) min + ",Max=" + (float) max + ",Mean=" + mean;
}
String lineString = "";
if (polylinePicks.size() > 0) {
double lineLength = 0;
org.vcell.util.Coordinate lastCentroid = null;
for (int i = 0; i < polylinePicks.size(); i += 1) {
SurfaceCanvas.SurfaceCollectionPick lineElement = (SurfaceCanvas.SurfaceCollectionPick) polylinePicks.elementAt(i);
cbit.vcell.geometry.surface.Quadrilateral quad = (cbit.vcell.geometry.surface.Quadrilateral) getSurfaceCollectionDataInfo().getSurfaceCollection().getSurfaces(lineElement.surfaceIndex).getPolygons(lineElement.polygonIndex);
org.vcell.util.Coordinate centroid = quad.calculateCentroid();
if (i > 0) {
lineLength += centroid.distanceTo(lastCentroid);
}
lastCentroid = centroid;
}
lineString = "Line(" + polylinePicks.size() + ") Len=" + (float) lineLength;
}
getJLabelInfo().setText(lineString + (lineString.length() > 0 && !aoiString.equals(" ") ? " -- " : "") + aoiString);
if (getJLabelInfo().getText().trim().equals("")) {
getJLabelInfo().setText("info");
}
}
} else {
getJLabelInfo().setText("No Information Provider for Pick");
}
}
Aggregations