use of org.vcell.vis.vismesh.thrift.VisPoint in project vcell by virtualcell.
the class ComsolMeshReader method read.
public static void read(VisMesh visMesh, File comsolFile) throws IOException {
ArrayList<Field> fields = new ArrayList<Field>();
try (BufferedReader br = new BufferedReader(new FileReader(comsolFile))) {
//
// read header lines
//
String model = readStringParameter(br.readLine(), "Model");
String version = readStringParameter(br.readLine(), "Version");
String date = readStringParameter(br.readLine(), "Date");
int dimension = readIntegerParameter(br.readLine(), "Dimension");
int numNodes = readIntegerParameter(br.readLine(), "Nodes");
int numElements = readIntegerParameter(br.readLine(), "Elements");
int numExpressions = readIntegerParameter(br.readLine(), "Expressions");
String description = readStringParameter(br.readLine(), "Description");
String lengthUnit = readStringParameter(br.readLine(), "Length unit");
visMesh.setDimension(dimension);
//
// read coordinates (and set points, origin and extent on VisMesh
//
readCoordinates(br, visMesh, numNodes);
List<VisPoint> points = visMesh.getPoints();
double minX = Double.POSITIVE_INFINITY;
double minY = Double.POSITIVE_INFINITY;
double minZ = Double.POSITIVE_INFINITY;
double maxX = Double.NEGATIVE_INFINITY;
double maxY = Double.NEGATIVE_INFINITY;
double maxZ = Double.NEGATIVE_INFINITY;
for (VisPoint p : points) {
minX = Math.min(p.x, minX);
minY = Math.min(p.y, minY);
minZ = Math.min(p.z, minZ);
maxX = Math.max(p.x, maxX);
maxY = Math.max(p.y, maxY);
maxZ = Math.max(p.z, maxZ);
}
visMesh.setExtent(new Vect3D(maxX - minX, maxY - minY, maxZ - minZ));
visMesh.setOrigin(new Vect3D(minX, minY, minZ));
//
// read triangles
//
readElements(br, visMesh, numElements);
//
for (int fieldIndex = 0; fieldIndex < numExpressions; fieldIndex++) {
fields.add(readField(br, numNodes));
}
}
VtkService vtkService = VtkService.getInstance();
String prefix = comsolFile.getName().replace(".comsoldat", "");
File vtuFile = new File(comsolFile.getParentFile(), prefix + ".vtu");
File indexFile = new File(comsolFile.getParentFile(), prefix + ".comsolindex");
vtkService.writeComsolVtkGridAndIndexData(visMesh, "domain", vtuFile, indexFile);
HashSet<Double> times = new HashSet<Double>();
for (Field field : fields) {
times.add(field.time);
int timeIndex = times.size() - 1;
File outputMeshFile = new File(comsolFile.getParentFile(), prefix + "_" + field.name + "_" + timeIndex + ".vtu");
VisMeshUtils.writePointDataToVtu(vtuFile, field.name, field.data, outputMeshFile);
}
}
use of org.vcell.vis.vismesh.thrift.VisPoint in project vcell by virtualcell.
the class ChomboMeshMapping method cropVoxels.
private void cropVoxels(VisMesh visMesh, ChomboBoundaries chomboBoundaries, ChomboCombinedVolumeMembraneDomain chomboCombinedVolumeMembraneDomain) {
if (visMesh.getDimension() != 3) {
throw new RuntimeException("expecting 3D mesh");
}
List<VisVoxel> origVoxelList = visMesh.getVisVoxels();
ArrayList<VisVoxel> newVoxelList = new ArrayList<VisVoxel>();
List<VisPoint> points = visMesh.getPoints();
List<VisSurfaceTriangle> triangles = visMesh.getSurfaceTriangles();
for (VisVoxel visVoxel : origVoxelList) {
List<Integer> polyhedronPointIndices = visVoxel.getPointIndices();
if (visVoxel.getChomboVolumeIndex().getFraction() < 1.0) {
int p0 = polyhedronPointIndices.get(0);
int p1 = polyhedronPointIndices.get(1);
int p2 = polyhedronPointIndices.get(2);
int p3 = polyhedronPointIndices.get(3);
int p4 = polyhedronPointIndices.get(4);
int p5 = polyhedronPointIndices.get(5);
int p6 = polyhedronPointIndices.get(6);
int p7 = polyhedronPointIndices.get(7);
VisPoint vp0 = points.get(p0);
VisPoint vp1 = points.get(p1);
VisPoint vp2 = points.get(p2);
VisPoint vp3 = points.get(p3);
VisPoint vp4 = points.get(p4);
VisPoint vp5 = points.get(p5);
VisPoint vp6 = points.get(p6);
VisPoint vp7 = points.get(p7);
ArrayList<VisSurfaceTriangle> intersectingTriangles = new ArrayList<VisSurfaceTriangle>();
for (VisSurfaceTriangle triangle : triangles) {
boolean bInRange = true;
for (int pi = 0; pi < 3; pi++) {
VisPoint tp = points.get(triangle.getPointIndices().get(pi));
if (!inLoHi(tp, vp0, vp7)) {
bInRange = false;
}
}
if (bInRange) {
intersectingTriangles.add(triangle);
}
}
if (intersectingTriangles.size() == 0) {
LG.info("fraction<1.0 but found no triangles");
newVoxelList.add(visVoxel);
continue;
}
// p6-------------------p7
// /| /|
// / | / |
// p4-------------------p5 |
// | | | | face number coordinates
// | | | |
// | | | | 5 3 z y
// | p2................|..p3 | / | /
// | / | / | / | /
// |/ |/ |/ |/
// p0-------------------p1 0 ---'---- 1 '----- x
// /|
// / |
// 2 4
BorderCellInfo borderCellInfo = chomboBoundaries.getMeshMetrics().getBorderCellInfo(intersectingTriangles.get(0).getChomboSurfaceIndex().getIndex());
//
// have o flip the inside/outside if domain ordinal is > 0 ... note that "^" is the exclusive or ... to flip a bit
//
VoxelPoint[] v = new VoxelPoint[8];
for (int i = 0; i < 8; ++i) {
int p = polyhedronPointIndices.get(i);
VisPoint vp = points.get(p);
v[i] = new VoxelPoint(p, vp, chomboCombinedVolumeMembraneDomain.shouldIncludeVertex(borderCellInfo.isVertexInPhase1(i)));
}
// choosing an arbitrary face (A,B,C,D) see below
//
// pA pB
//
// pD pC
//
// face 0 (X-)
VoxelFace face0 = new VoxelFace(Face.Xm, v[0], v[4], v[6], v[2]);
// face 1 (X+)
VoxelFace face1 = new VoxelFace(Face.Xp, v[1], v[3], v[7], v[5]);
// face 2 (Y-)
VoxelFace face2 = new VoxelFace(Face.Ym, v[0], v[1], v[5], v[4]);
// face 3 (Y+)
VoxelFace face3 = new VoxelFace(Face.Yp, v[2], v[3], v[7], v[6]);
// face 4 (Z-)
VoxelFace face4 = new VoxelFace(Face.Zm, v[0], v[2], v[3], v[1]);
// face 5 (Z+)
VoxelFace face5 = new VoxelFace(Face.Zp, v[4], v[5], v[7], v[6]);
ClippedVoxel clippedVoxel = new ClippedVoxel(face0, face1, face2, face3, face4, face5);
clippedVoxel.surfaceTriangles.addAll(intersectingTriangles);
VisIrregularPolyhedron clippedPolyhedron = createClippedPolyhedron(clippedVoxel, visMesh, visVoxel);
// VisIrregularPolyhedron clippedPolyhedron = new VisIrregularPolyhedron(visVoxel.getLevel(),visVoxel.getBoxNumber(),visVoxel.getBoxIndex(),visVoxel.getFraction());
// clippedPolyhedron.addFace(new PolyhedronFace(new int[] { p0, p1, p4} ));
// clippedPolyhedron.addFace(new PolyhedronFace(new int[] { p0, p2, p1} ));
// clippedPolyhedron.addFace(new PolyhedronFace(new int[] { p0, p4, p2} ));
// clippedPolyhedron.addFace(new PolyhedronFace(new int[] { p2, p4, p1} ));
visMesh.addToIrregularPolyhedra(clippedPolyhedron);
// VisTetrahedron[] delaunayTets = VtkGridUtils.createTetrahedra(clippedPolyhedron, visMesh);
// for (VisTetrahedron tet : delaunayTets){
// newPolyhedraList.add(tet);
// }
} else {
// fraction >= 1.0
newVoxelList.add(visVoxel);
}
}
// for loop (orig polyhedra)
visMesh.getVisVoxels().clear();
visMesh.getVisVoxels().addAll(newVoxelList);
}
use of org.vcell.vis.vismesh.thrift.VisPoint in project vcell by virtualcell.
the class CartesianMeshMapping method fromMesh3DMembrane.
private VisMesh fromMesh3DMembrane(CartesianMesh cartesianMesh, String domainName) {
ISize size = cartesianMesh.getSize();
int numX = size.getX();
int numY = size.getY();
int dimension = 3;
Vect3D origin = new Vect3D(cartesianMesh.getOrigin().x, cartesianMesh.getOrigin().y, cartesianMesh.getOrigin().z);
Vect3D extent = new Vect3D(cartesianMesh.getExtent().x, cartesianMesh.getExtent().y, cartesianMesh.getExtent().z);
// invoke VisMesh() constructor
VisMesh visMesh = new VisMesh(dimension, origin, extent);
int currPointIndex = 0;
HashMap<String, Integer> pointDict = new HashMap<String, Integer>();
List<MembraneElement> membraneElements = cartesianMesh.getMembraneElements(domainName);
for (MembraneElement membraneElement : membraneElements) {
// inside
int insideVolumeIndex = membraneElement.getInsideVolumeIndex();
int insideI = insideVolumeIndex % numX;
int insideJ = (insideVolumeIndex % (numX * numY)) / numX;
int insideK = insideVolumeIndex / (numX * numY);
Box3D insideBox = cartesianMesh.getVolumeElementBox(insideI, insideJ, insideK);
// outside
int outsideVolumeIndex = membraneElement.getOutsideVolumeIndex();
int outsideI = outsideVolumeIndex % numX;
int outsideJ = (outsideVolumeIndex % (numX * numY)) / numX;
int outsideK = outsideVolumeIndex / (numX * numY);
VisPoint p1Coord;
VisPoint p2Coord;
VisPoint p3Coord;
VisPoint p4Coord;
if (insideI == outsideI + 1) {
// x- z cross y
double x = insideBox.x_lo;
p1Coord = new VisPoint(x, insideBox.y_lo, insideBox.z_lo);
p2Coord = new VisPoint(x, insideBox.y_lo, insideBox.z_hi);
p3Coord = new VisPoint(x, insideBox.y_hi, insideBox.z_hi);
p4Coord = new VisPoint(x, insideBox.y_hi, insideBox.z_lo);
} else if (outsideI == insideI + 1) {
// x+ y cross z
double x = insideBox.x_hi;
p1Coord = new VisPoint(x, insideBox.y_lo, insideBox.z_lo);
p2Coord = new VisPoint(x, insideBox.y_hi, insideBox.z_lo);
p3Coord = new VisPoint(x, insideBox.y_hi, insideBox.z_hi);
p4Coord = new VisPoint(x, insideBox.y_lo, insideBox.z_hi);
} else if (insideJ == outsideJ + 1) {
// y- x cross z
double y = insideBox.y_lo;
p1Coord = new VisPoint(insideBox.x_lo, y, insideBox.z_lo);
p2Coord = new VisPoint(insideBox.x_hi, y, insideBox.z_lo);
p3Coord = new VisPoint(insideBox.x_hi, y, insideBox.z_hi);
p4Coord = new VisPoint(insideBox.x_lo, y, insideBox.z_hi);
} else if (outsideJ == insideJ + 1) {
// y+ z cross x
double y = insideBox.y_hi;
p1Coord = new VisPoint(insideBox.x_lo, y, insideBox.z_lo);
p2Coord = new VisPoint(insideBox.x_lo, y, insideBox.z_hi);
p3Coord = new VisPoint(insideBox.x_hi, y, insideBox.z_hi);
p4Coord = new VisPoint(insideBox.x_hi, y, insideBox.z_lo);
} else if (insideK == outsideK + 1) {
// z- y cross x
double z = insideBox.z_lo;
p1Coord = new VisPoint(insideBox.x_lo, insideBox.y_lo, z);
p2Coord = new VisPoint(insideBox.x_lo, insideBox.y_hi, z);
p3Coord = new VisPoint(insideBox.x_hi, insideBox.y_hi, z);
p4Coord = new VisPoint(insideBox.x_hi, insideBox.y_lo, z);
} else if (outsideK == insideK + 1) {
// z+ x cross y
double z = insideBox.z_hi;
p1Coord = new VisPoint(insideBox.x_lo, insideBox.y_lo, z);
p2Coord = new VisPoint(insideBox.x_hi, insideBox.y_lo, z);
p3Coord = new VisPoint(insideBox.x_hi, insideBox.y_hi, z);
p4Coord = new VisPoint(insideBox.x_lo, insideBox.y_hi, z);
} else {
throw new RuntimeException("inside/outside volume indices not reconciled in membraneElement " + membraneElement.getMembraneIndex() + " in domain " + domainName);
}
//
// make sure vertices are added to model without duplicates and get the assigned identifier.
//
String p1Key = toStringKey(p1Coord);
Integer i1 = pointDict.get(p1Key);
if (i1 == null) {
pointDict.put(p1Key, currPointIndex);
i1 = currPointIndex;
visMesh.addToPoints(p1Coord);
currPointIndex++;
}
String p2Key = toStringKey(p2Coord);
Integer i2 = pointDict.get(p2Key);
if (i2 == null) {
pointDict.put(p2Key, currPointIndex);
i2 = currPointIndex;
visMesh.addToPoints(p2Coord);
currPointIndex++;
}
String p3Key = toStringKey(p3Coord);
Integer i3 = pointDict.get(p3Key);
if (i3 == null) {
pointDict.put(p3Key, currPointIndex);
i3 = currPointIndex;
visMesh.addToPoints(p3Coord);
currPointIndex++;
}
String p4Key = toStringKey(p4Coord);
Integer i4 = pointDict.get(p4Key);
if (i4 == null) {
pointDict.put(p4Key, currPointIndex);
i4 = currPointIndex;
visMesh.addToPoints(p4Coord);
currPointIndex++;
}
VisPolygon quad = new VisPolygon(Arrays.asList(new Integer[] { i1, i2, i3, i4 }));
quad.setFiniteVolumeIndex(new FiniteVolumeIndex(membraneElement.getMembraneIndex(), cartesianMesh.getMembraneRegionIndex(membraneElement.getMembraneIndex())));
// print('adding a cell at level '+str(currLevel.getLevel())+" from "+str(p1Coord)+" to "+str(p3Coord))
visMesh.addToPolygons(quad);
}
return visMesh;
}
use of org.vcell.vis.vismesh.thrift.VisPoint in project vcell by virtualcell.
the class ComsolMeshReader method readCoordinates.
private static void readCoordinates(BufferedReader br, VisMesh visMesh, int numNodes) throws IOException {
String line = br.readLine();
String coordinatesTag = "% Coordinates";
if (!line.trim().equals(coordinatesTag)) {
throw new RuntimeException("read " + line + "\nexpected " + coordinatesTag);
}
for (int i = 0; i < numNodes; i++) {
line = br.readLine();
String[] tokens = line.split("\\ +");
double x = Double.parseDouble(tokens[0]);
double y = Double.parseDouble(tokens[1]);
double z = 0.0;
visMesh.addToPoints(new VisPoint(x, y, z));
}
}
use of org.vcell.vis.vismesh.thrift.VisPoint in project vcell by virtualcell.
the class ChomboMeshMapping method cropQuads.
private void cropQuads(VisMesh visMesh) {
if (visMesh.getDimension() != 2) {
throw new RuntimeException("expecting 2D mesh");
}
List<VisPolygon> polygons = visMesh.getPolygons();
List<VisPoint> points = visMesh.getPoints();
List<VisLine> lines = visMesh.getVisLines();
for (VisPolygon polygon : polygons) {
List<Integer> polygonPointIndices = polygon.getPointIndices();
double fraction = polygon.getChomboVolumeIndex().getFraction();
if (fraction < 1.0 && polygonPointIndices.size() == 4) {
int p0 = polygonPointIndices.get(0);
int p1 = polygonPointIndices.get(1);
int p2 = polygonPointIndices.get(2);
int p3 = polygonPointIndices.get(3);
VisPoint point0 = points.get(p0);
VisPoint point1 = points.get(p1);
VisPoint point2 = points.get(p2);
VisPoint point3 = points.get(p3);
double p0x = point0.x;
double p0y = point0.y;
double p1x = point1.x;
double p1y = point1.y;
double p2x = point2.x;
double p2y = point2.y;
double p3x = point3.x;
double p3y = point3.y;
double pLowX = p0x;
double pLowY = p0y;
double pHiX = p2x;
double pHiY = p2y;
for (VisLine segment : lines) {
VisPoint segpoint1 = points.get(segment.getP1());
double s1x = segpoint1.x;
double s1y = segpoint1.y;
if (s1x <= pHiX && s1x >= pLowX && s1y <= pHiY && s1y >= pLowY) {
VisPoint segpoint2 = points.get(segment.getP2());
double s2x = segpoint2.x;
double s2y = segpoint2.y;
if (s2x <= pHiX && s2x >= pLowX && s2y <= pHiY && s2y >= pLowY) {
//
if (p0x == s1x && p0y == s2y) {
if (fraction > 0.5) {
polygon.setPointIndices(Arrays.asList(new Integer[] { segment.getP2(), segment.getP1(), p1, p2, p3 }));
} else {
polygon.setPointIndices(Arrays.asList(new Integer[] { segment.getP2(), p0, segment.getP1() }));
}
} else if (p0x == s2x && p0y == s1y) {
if (fraction > 0.5) {
polygon.setPointIndices(Arrays.asList(new Integer[] { segment.getP1(), segment.getP2(), p1, p2, p3 }));
} else {
polygon.setPointIndices(Arrays.asList(new Integer[] { segment.getP1(), p0, segment.getP2() }));
}
// case 2) { (remove point one && replace with segment
//
// 0 3 0 3
// s1 => s1 or s1
// 1 s2 2 1 s2 s2 2
//
} else if (p1x == s1x && p1y == s2y) {
if (fraction > 0.5) {
polygon.setPointIndices(Arrays.asList(new Integer[] { p0, segment.getP1(), segment.getP2(), p2, p3 }));
} else {
polygon.setPointIndices(Arrays.asList(new Integer[] { segment.getP1(), p1, segment.getP2() }));
}
} else if (p1x == s2x && p1y == s1y) {
if (fraction > 0.5) {
polygon.setPointIndices(Arrays.asList(new Integer[] { p0, segment.getP2(), segment.getP1(), p2, p3 }));
} else {
polygon.setPointIndices(Arrays.asList(new Integer[] { segment.getP2(), p1, segment.getP1() }));
}
// case 3) { (remove point two && replace with segment
//
// 0 3 0 3
// s2 => s2 or s2
// 1 s1 2 s1 2 1 s1
//
} else if (p2x == s1x && p2y == s2y) {
if (fraction > 0.5) {
polygon.setPointIndices(Arrays.asList(new Integer[] { p0, p1, segment.getP2(), segment.getP1(), p3 }));
} else {
polygon.setPointIndices(Arrays.asList(new Integer[] { segment.getP2(), p2, segment.getP1() }));
}
} else if (p2x == s2x && p2y == s1y) {
if (fraction > 0.5) {
polygon.setPointIndices(Arrays.asList(new Integer[] { p0, p1, segment.getP1(), segment.getP2(), p3 }));
} else {
polygon.setPointIndices(Arrays.asList(new Integer[] { segment.getP1(), p2, segment.getP2() }));
}
// case 4) { (remove point three && replace with segment
//
// 0 s2 3 s2 3 0 s2
// s1 => s1 or s1
// 1 2 1 2
//
} else if (p3x == s1x && p3y == s2y) {
if (fraction > 0.5) {
polygon.setPointIndices(Arrays.asList(new Integer[] { p0, p1, p2, segment.getP1(), segment.getP2() }));
} else {
polygon.setPointIndices(Arrays.asList(new Integer[] { segment.getP1(), p3, segment.getP2() }));
}
} else if (p3x == s2x && p3y == s1y) {
if (fraction > 0.5) {
polygon.setPointIndices(Arrays.asList(new Integer[] { p0, p1, p2, segment.getP2(), segment.getP1() }));
} else {
polygon.setPointIndices(Arrays.asList(new Integer[] { segment.getP2(), p3, segment.getP1() }));
}
// case 5) { (remove points 0 && 1 verticle cut)
//
// 0 s1 3 0 s1 s1 3
// => or
// 1 s2 2 1 s2 s2 2
//
} else if (p0y == s1y && p1y == s2y) {
boolean bigleft = ((s1x - p0x) + (s2x - p0x) > p3x - p0x);
if ((fraction > 0.5 && bigleft) || (fraction <= 0.5 && !bigleft)) {
polygon.setPointIndices(Arrays.asList(new Integer[] { p0, p1, segment.getP2(), segment.getP1() }));
} else {
polygon.setPointIndices(Arrays.asList(new Integer[] { segment.getP1(), segment.getP2(), p2, p3 }));
}
} else if (p0y == s2y && p1y == s1y) {
boolean bigleft = ((s1x - p0x) + (s2x - p0x) > p3x - p0x);
if ((fraction > 0.5 && bigleft) || (fraction <= 0.5 && !bigleft)) {
polygon.setPointIndices(Arrays.asList(new Integer[] { p0, p1, segment.getP1(), segment.getP2() }));
} else {
polygon.setPointIndices(Arrays.asList(new Integer[] { segment.getP2(), segment.getP1(), p2, p3 }));
}
// case 6) { (remove points 0 && 1 horizontal cut)
//
// 0 3 0 3
// s1 s2 => s1 s2 or s1 s2
// 1 2 1 2
//
} else if (p0x == s1x && p3x == s2x) {
boolean bigtop = ((s1y - p0y) + (s2y - p0y) > p1y - p0y);
if ((fraction > 0.5 && bigtop) || (fraction <= 0.5 && !bigtop)) {
polygon.setPointIndices(Arrays.asList(new Integer[] { p0, segment.getP1(), segment.getP2(), p3 }));
} else {
polygon.setPointIndices(Arrays.asList(new Integer[] { segment.getP2(), segment.getP1(), p1, p2 }));
}
} else if (p0x == s2x && p3x == s1x) {
boolean bigtop = ((s1y - p0y) + (s2y - p0y) > p1y - p0y);
if ((fraction > 0.5 && bigtop) || (fraction <= 0.5 && !bigtop)) {
polygon.setPointIndices(Arrays.asList(new Integer[] { p0, segment.getP2(), segment.getP1(), p3 }));
} else {
polygon.setPointIndices(Arrays.asList(new Integer[] { segment.getP1(), segment.getP2(), p1, p2 }));
}
} else {
LG.warn("found the segment for this polygon, don't know how to crop this one yet");
}
}
}
}
}
}
}
Aggregations