use of maspack.matrix.Vector3d in project artisynth_core by artisynth.
the class DistanceGrid method buildRenderObject.
/**
* Creates a new render object for rendering the points and normals
* of this grid.
*
* @return new render object
*/
RenderObject buildRenderObject(RenderProps props) {
RenderObject rob = new RenderObject();
if (myDrawEdges) {
// create line groups for both normals and edges
rob.createLineGroup();
rob.createLineGroup();
} else {
// just one line group for normals
rob.createLineGroup();
}
Vector3d widths = getCellWidths();
double len = 0.66 * widths.minElement();
if (myColorMap != null) {
for (Color color : myColors) {
rob.addColor(color);
}
}
int vidx = 0;
Vector3d coords = new Vector3d();
int xlo = myRenderRanges[0];
int xhi = myRenderRanges[1];
int ylo = myRenderRanges[2];
int yhi = myRenderRanges[3];
int zlo = myRenderRanges[4];
int zhi = myRenderRanges[5];
rob.lineGroup(NORMAL_GROUP);
for (int xi = xlo; xi < xhi; xi++) {
for (int yj = ylo; yj < yhi; yj++) {
for (int zk = zlo; zk < zhi; zk++) {
coords.set(xi, yj, zk);
myGridToLocal.transformPnt(coords, coords);
int vi = xyzIndicesToVertex(xi, yj, zk);
int cidx = myColorMap != null ? myColorIndices[vi] : -1;
rob.addPosition(coords);
rob.addVertex(vidx, -1, cidx, -1);
coords.scaledAdd(len, getLocalVertexNormal(xi, yj, zk));
rob.addPosition(coords);
rob.addVertex(vidx + 1, -1, cidx, -1);
rob.addPoint(vidx);
rob.addLine(vidx, vidx + 1);
vidx += 2;
}
}
}
if (myDrawEdges) {
rob.lineGroup(EDGE_GROUP);
int nvx = xhi - xlo;
int nvy = yhi - ylo;
int nvz = zhi - zlo;
// lines parallel to x
if (nvx > 1) {
for (int j = 0; j < nvy; j++) {
for (int k = 0; k < nvz; k++) {
int vidx0 = 2 * (j * nvz + k);
int vidx1 = 2 * ((nvx - 1) * nvy * nvz + j * nvz + k);
rob.addLine(vidx0, vidx1);
}
}
}
// lines parallel to y
if (nvy > 1) {
for (int i = 0; i < nvx; i++) {
for (int k = 0; k < nvz; k++) {
int vidx0 = 2 * (i * nvy * nvz + k);
int vidx1 = 2 * (i * nvy * nvz + (nvy - 1) * nvz + k);
rob.addLine(vidx0, vidx1);
}
}
}
// lines parallel to z
if (nvz > 1) {
for (int i = 0; i < nvx; i++) {
for (int j = 0; j < nvy; j++) {
int vidx0 = 2 * (i * nvy * nvz + j * nvz);
int vidx1 = 2 * (i * nvy * nvz + j * nvz + (nvz - 1));
rob.addLine(vidx0, vidx1);
}
}
}
}
return rob;
}
use of maspack.matrix.Vector3d in project artisynth_core by artisynth.
the class DistanceGrid method createQuadDistanceSurface.
/**
* Creates a triangular mesh approximating the surface on which the
* quadratically interpolated distance function equals <code>val</code>.
*
* @param val iso surface value
* @param res multiplies the resolution of this grid to obtain the
* resolution of the grid used to create the mesh.
* @return iso surface for quadratic interpolation
*/
public PolygonalMesh createQuadDistanceSurface(double val, int res) {
MarchingTetrahedra marcher = new MarchingTetrahedra();
// sample at a res X higher resolution so we can get
// a better sense of the smooth surface
Vector3i cellRes = new Vector3i(getResolution());
cellRes.scale(res);
int nvx = cellRes.x + 1;
int nvy = cellRes.y + 1;
int nvz = cellRes.z + 1;
double[] dists = new double[nvx * nvy * nvz];
double invRes = 1.0 / res;
Point3d q = new Point3d();
// build a high res distance map by iterating through all the quad grid
// cells:
double[] a = new double[10];
for (int i = 0; i < myQx; i++) {
for (int j = 0; j < myQy; j++) {
for (int k = 0; k < myQz; k++) {
Vector3i vidx = new Vector3i(i, j, k);
double cx, cy, cz;
int maxci = ((i < myQx - 1) ? 2 * res - 1 : 2 * res);
int maxcj = ((j < myQy - 1) ? 2 * res - 1 : 2 * res);
int maxck = ((k < myQz - 1) ? 2 * res - 1 : 2 * res);
for (int ci = 0; ci <= maxci; ci++) {
cx = ci * invRes / 2;
for (int cj = 0; cj <= maxcj; cj++) {
cy = cj * invRes / 2;
for (int ck = 0; ck <= maxck; ck++) {
cz = ck * invRes / 2;
TetDesc tdesc = new TetDesc(vidx, TetID.findSubTet(cx, cy, cz));
computeQuadCoefs(a, tdesc);
dists[(2 * i * res + ci) + (2 * j * res + cj) * nvx + (2 * k * res + ck) * nvx * nvy] = computeQuadDistance(a, cx, cy, cz);
}
}
}
}
}
}
PolygonalMesh mesh = marcher.createMesh(dists, Vector3d.ZERO, new Vector3d(invRes, invRes, invRes), cellRes, val);
mesh.transform(myGridToLocal);
return mesh;
}
use of maspack.matrix.Vector3d in project artisynth_core by artisynth.
the class DistanceGrid method doGetQuadDistance.
protected double doGetQuadDistance(Point3d point, VectorTransformer3d quadGridToX) {
Vector3d coords = new Vector3d();
double[] a;
double dx, dy, dz;
if (storeQuadCoefs) {
updateQuadCoefsIfNecessary();
int voff = getQuadCellCoords(coords, null, point, quadGridToX);
if (voff == -1) {
return OUTSIDE_GRID;
}
dx = coords.x;
dy = coords.y;
dz = coords.z;
a = myQuadCoefs[6 * voff + TetID.findSubTetIdx(dx, dy, dz)];
} else {
// Change to grid coordinates
Vector3i vidx = new Vector3i();
if (getQuadCellCoords(coords, vidx, point, quadGridToX) == -1) {
return OUTSIDE_GRID;
}
dx = coords.x;
dy = coords.y;
dz = coords.z;
a = new double[10];
TetDesc tdesc = new TetDesc(vidx, TetID.findSubTet(dx, dy, dz));
computeQuadCoefs(a, tdesc);
}
return computeQuadDistance(a, dx, dy, dz);
}
use of maspack.matrix.Vector3d in project artisynth_core by artisynth.
the class DistanceGrid method getQuadCellCoords.
protected int getQuadCellCoords(Vector3d coords, Vector3i vidx, Point3d ploc, VectorTransformer3d quadGridToX) {
Vector3d pgrid = new Vector3d();
quadGridToX.inverseTransformPnt(pgrid, ploc);
int xi, yj, zk;
if (pgrid.x < 0 || pgrid.x > myQx) {
return -1;
} else if (pgrid.x == myQx) {
xi = (int) pgrid.x - 1;
} else {
xi = (int) pgrid.x;
}
if (pgrid.y < 0 || pgrid.y > myQy) {
return -1;
} else if (pgrid.y == myQy) {
yj = (int) pgrid.y - 1;
} else {
yj = (int) pgrid.y;
}
if (pgrid.z < 0 || pgrid.z > myQz) {
return -1;
} else if (pgrid.z == myQz) {
zk = (int) pgrid.z - 1;
} else {
zk = (int) pgrid.z;
}
coords.x = pgrid.x - xi;
coords.y = pgrid.y - yj;
coords.z = pgrid.z - zk;
if (vidx != null) {
vidx.x = xi;
vidx.y = yj;
vidx.z = zk;
}
return xi + myQx * yj + myQxQy * zk;
}
use of maspack.matrix.Vector3d in project artisynth_core by artisynth.
the class DistanceGrid method getLocalDistanceAndGradient.
/**
* Calculates the distance and gradient at an arbitrary point in local
* coordinates using multilinear interpolation of the vertex values for the
* grid cell containing the point. The gradient is the true derivative
* of the interpolated distance function within the cell, and is
* in fact linear within the cell.
* If the point lies outside the grid volume, {@link #OUTSIDE_GRID} is
* returned.
*
* @param grad returns the gradient direction (local coordinates)
* @param point point at which to calculate the gradient and distance
* (local coordinates).
* @return interpolated distance, or <code>OUTSIDE_GRID</code>.
*/
public double getLocalDistanceAndGradient(Vector3d grad, Point3d point) {
Vector3d coords = new Vector3d();
Vector3i vidx = new Vector3i();
if (!getCellCoords(vidx, coords, point)) {
return OUTSIDE_GRID;
}
double dx = coords.x;
double dy = coords.y;
double dz = coords.z;
double w100x = (1 - dy) * (1 - dz);
double w101x = (1 - dy) * dz;
double w110x = dy * (1 - dz);
double w111x = dy * dz;
double w010y = (1 - dx) * (1 - dz);
double w011y = (1 - dx) * dz;
double w110y = dx * (1 - dz);
double w111y = dx * dz;
double w001z = (1 - dx) * (1 - dy);
double w011z = (1 - dx) * dy;
double w101z = dx * (1 - dy);
double w111z = dx * dy;
double w000 = w001z * (1 - dz);
double w001 = w001z * dz;
double w010 = w011z * (1 - dz);
double w011 = w011z * dz;
double w100 = w101z * (1 - dz);
double w101 = w101z * dz;
double w110 = w111z * (1 - dz);
double w111 = w111z * dz;
double d000 = getVertexDistance(vidx.x, vidx.y, vidx.z);
double d001 = getVertexDistance(vidx.x, vidx.y, vidx.z + 1);
double d010 = getVertexDistance(vidx.x, vidx.y + 1, vidx.z);
double d011 = getVertexDistance(vidx.x, vidx.y + 1, vidx.z + 1);
double d100 = getVertexDistance(vidx.x + 1, vidx.y, vidx.z);
double d101 = getVertexDistance(vidx.x + 1, vidx.y, vidx.z + 1);
double d110 = getVertexDistance(vidx.x + 1, vidx.y + 1, vidx.z);
double d111 = getVertexDistance(vidx.x + 1, vidx.y + 1, vidx.z + 1);
if (grad != null) {
grad.x = (-w100x * d000 - w101x * d001 - w110x * d010 - w111x * d011 + w100x * d100 + w101x * d101 + w110x * d110 + w111x * d111);
grad.y = (-w010y * d000 - w011y * d001 + w010y * d010 + w011y * d011 - w110y * d100 - w111y * d101 + w110y * d110 + w111y * d111);
grad.z = (-w001z * d000 + w001z * d001 - w011z * d010 + w011z * d011 - w101z * d100 + w101z * d101 - w111z * d110 + w111z * d111);
myGridToLocal.transformCovec(grad, grad);
}
return (w000 * d000 + w001 * d001 + w010 * d010 + w011 * d011 + w100 * d100 + w101 * d101 + w110 * d110 + w111 * d111);
}
Aggregations