use of maspack.matrix.Point3d in project artisynth_core by artisynth.
the class MeshFactory method createQuadPrism.
// For a prism with a non-degenerate top and bottom,
// with n sides, the faces are indexed as followes:
//
// sides: 0 ... n-1 counter-clockwise about the z axies
// top: n
// bottom: n+1
//
// The first n vertices surround the top and next n vertices surround
// the bottom.
//
public static PolygonalMesh createQuadPrism(double[] xyTop, double[] xyBot, double h) {
int nsides = Math.max(xyTop.length / 2, xyBot.length / 2);
Point3d[] vlist;
int[][] faces;
if (nsides < 3) {
throw new IllegalArgumentException("either xyTop or xyBot must have at least 2*3 elements");
}
if (xyTop.length / 2 < 3 || xyBot.length / 2 < 3) {
vlist = new Point3d[nsides + 1];
faces = new int[nsides + 1][];
faces[nsides] = new int[nsides];
} else {
vlist = new Point3d[2 * nsides];
faces = new int[nsides + 2][];
faces[nsides] = new int[nsides];
faces[nsides + 1] = new int[nsides];
}
if (xyTop.length / 2 < 3) {
// top has a single point
vlist[0] = new Point3d(xyTop[0], xyTop[1], h / 2);
for (int i = 0; i < nsides; i++) {
vlist[i + 1] = new Point3d(xyBot[i * 2], xyBot[i * 2 + 1], -h / 2);
int i_next = (i + 1) % nsides;
faces[i] = new int[] { 0, i + 1, i_next + 1 };
faces[nsides][i] = nsides - i;
}
} else if (xyBot.length / 2 < 3) {
// bottom has a single point
vlist[nsides] = new Point3d(xyBot[0], xyBot[1], -h / 2);
for (int i = 0; i < nsides; i++) {
vlist[i] = new Point3d(xyTop[i * 2], xyTop[i * 2 + 1], h / 2);
int i_next = (i + 1) % nsides;
faces[i] = new int[] { i_next, i, nsides };
faces[nsides][i] = i;
}
} else {
for (int i = 0; i < nsides; i++) {
vlist[i] = new Point3d(xyTop[i * 2], xyTop[i * 2 + 1], h / 2);
vlist[i + nsides] = new Point3d(xyBot[i * 2], xyBot[i * 2 + 1], -h / 2);
int i_next = (i + 1) % nsides;
faces[i] = new int[] { i, i + nsides, i_next + nsides, i_next };
faces[nsides][i] = i;
faces[nsides + 1][i] = 2 * nsides - 1 - i;
}
}
PolygonalMesh mesh = new PolygonalMesh();
mesh.set(vlist, faces);
return mesh;
}
use of maspack.matrix.Point3d in project artisynth_core by artisynth.
the class MeshFactory method createBox.
/**
* Creates a box mesh, with a specified mesh resolution in each direction,
* and centered at a defined center point. The faces type is specified
* by <code>faceType</code>
*
* @param wx width in the x direction
* @param wy width in the y direction
* @param wz width in the z direction
* @param center center of the box
* @param nx number of subdivisions along x
* @param ny number of subdivisions along y
* @param nz number of subdivisions along z
* @param addNormals if <code>true</code>, generates normals perpendicular
* to each side
* @param faceType specifies the face type to be either quads, triangles,
* or triangles with alternating diagonals
*/
public static PolygonalMesh createBox(double wx, double wy, double wz, Point3d center, int nx, int ny, int nz, boolean addNormals, FaceType faceType) {
PolygonalMesh mesh = new PolygonalMesh();
Vertex3d[][][] vtxs = new Vertex3d[nx + 1][ny + 1][nz + 1];
Vertex3d[] faceVtxs = new Vertex3d[4];
ArrayList<Vector3d> nrmls = null;
int[] nrmlIdxs = null;
if (addNormals) {
nrmls = new ArrayList<Vector3d>();
nrmls.add(new Vector3d(1, 0, 0));
nrmls.add(new Vector3d(0, 1, 0));
nrmls.add(new Vector3d(0, 0, 1));
nrmls.add(new Vector3d(-1, 0, 0));
nrmls.add(new Vector3d(0, -1, 0));
nrmls.add(new Vector3d(0, 0, -1));
int nindices;
if (faceType == FaceType.QUAD) {
nindices = 8 * (nx * ny + nx * nz + ny * nz);
} else {
// trianglar
nindices = 12 * (nx * ny + nx * nz + ny * nz);
}
nrmlIdxs = new int[nindices];
}
Vector3d dx = new Vector3d(wx / (nx), wy / (ny), wz / (nz));
Point3d offset = new Point3d(-wx / 2, -wy / 2, -wz / 2);
boolean[] hardEdges;
// bottom/top (sides in x/y plane)
for (int i = 0; i < nx; i++) {
for (int j = 0; j < ny; j++) {
faceVtxs[0] = getOrCreateVertex(i, j, 0, vtxs, offset, dx, mesh);
faceVtxs[1] = getOrCreateVertex(i, j + 1, 0, vtxs, offset, dx, mesh);
faceVtxs[2] = getOrCreateVertex(i + 1, j + 1, 0, vtxs, offset, dx, mesh);
faceVtxs[3] = getOrCreateVertex(i + 1, j, 0, vtxs, offset, dx, mesh);
// notes: edge(i) appears *before* vertex(i).
hardEdges = new boolean[] { j == 0, i == 0, j == ny - 1, i == nx - 1 };
addFaces(mesh, faceVtxs, hardEdges, 5, nrmlIdxs, i + j, faceType);
faceVtxs[0] = getOrCreateVertex(i, j, nz, vtxs, offset, dx, mesh);
faceVtxs[3] = getOrCreateVertex(i, j + 1, nz, vtxs, offset, dx, mesh);
faceVtxs[2] = getOrCreateVertex(i + 1, j + 1, nz, vtxs, offset, dx, mesh);
faceVtxs[1] = getOrCreateVertex(i + 1, j, nz, vtxs, offset, dx, mesh);
hardEdges = new boolean[] { i == 0, j == 0, i == nx - 1, j == ny - 1 };
addFaces(mesh, faceVtxs, hardEdges, 2, nrmlIdxs, i + j, faceType);
}
}
// back/front (sides in z/x plane)
for (int i = 0; i < nx; i++) {
for (int k = 0; k < nz; k++) {
faceVtxs[0] = getOrCreateVertex(i, 0, k, vtxs, offset, dx, mesh);
faceVtxs[3] = getOrCreateVertex(i, 0, k + 1, vtxs, offset, dx, mesh);
faceVtxs[2] = getOrCreateVertex(i + 1, 0, k + 1, vtxs, offset, dx, mesh);
faceVtxs[1] = getOrCreateVertex(i + 1, 0, k, vtxs, offset, dx, mesh);
hardEdges = new boolean[] { i == 0, k == 0, i == nx - 1, k == nz - 1 };
addFaces(mesh, faceVtxs, hardEdges, 4, nrmlIdxs, i + k, faceType);
faceVtxs[0] = getOrCreateVertex(i, ny, k, vtxs, offset, dx, mesh);
faceVtxs[1] = getOrCreateVertex(i, ny, k + 1, vtxs, offset, dx, mesh);
faceVtxs[2] = getOrCreateVertex(i + 1, ny, k + 1, vtxs, offset, dx, mesh);
faceVtxs[3] = getOrCreateVertex(i + 1, ny, k, vtxs, offset, dx, mesh);
hardEdges = new boolean[] { k == 0, i == 0, k == nz - 1, i == nx - 1 };
addFaces(mesh, faceVtxs, hardEdges, 1, nrmlIdxs, i + k, faceType);
}
}
// left/right (sides in y/z plane)
for (int j = 0; j < ny; j++) {
for (int k = 0; k < nz; k++) {
faceVtxs[0] = getOrCreateVertex(0, j, k, vtxs, offset, dx, mesh);
faceVtxs[3] = getOrCreateVertex(0, j + 1, k, vtxs, offset, dx, mesh);
faceVtxs[2] = getOrCreateVertex(0, j + 1, k + 1, vtxs, offset, dx, mesh);
faceVtxs[1] = getOrCreateVertex(0, j, k + 1, vtxs, offset, dx, mesh);
hardEdges = new boolean[] { k == 0, j == 0, k == nz - 1, j == ny - 1 };
addFaces(mesh, faceVtxs, hardEdges, 3, nrmlIdxs, j + k, faceType);
faceVtxs[0] = getOrCreateVertex(nx, j, k, vtxs, offset, dx, mesh);
faceVtxs[1] = getOrCreateVertex(nx, j + 1, k, vtxs, offset, dx, mesh);
faceVtxs[2] = getOrCreateVertex(nx, j + 1, k + 1, vtxs, offset, dx, mesh);
faceVtxs[3] = getOrCreateVertex(nx, j, k + 1, vtxs, offset, dx, mesh);
hardEdges = new boolean[] { j == 0, k == 0, j == ny - 1, k == nz - 1 };
addFaces(mesh, faceVtxs, hardEdges, 0, nrmlIdxs, j + k, faceType);
}
}
if (addNormals) {
mesh.setNormals(nrmls, nrmlIdxs);
}
if (center != null) {
mesh.transform(new RigidTransform3d(center.x, center.y, center.z));
}
return mesh;
}
use of maspack.matrix.Point3d in project artisynth_core by artisynth.
the class MeshFactory method createPointedCylinder.
public static PolygonalMesh createPointedCylinder(double r, double h, double tiph, int nsides) {
// start by creating a mesh.
PolygonalMesh mesh = createCylinder(r, h, nsides);
// and then adjust the top vertex XXXX
double EPS = 1e-12;
for (Vertex3d vtx : mesh.getVertices()) {
Point3d p = vtx.pnt;
if (Math.abs(p.x) < EPS && Math.abs(p.y) < EPS && p.z > 0) {
vtx.pnt.set(0, 0, p.z + tiph);
mesh.notifyVertexPositionsModified();
break;
}
}
return mesh;
}
use of maspack.matrix.Point3d in project artisynth_core by artisynth.
the class MeshFactory method triangulateFaceCentroid.
public static void triangulateFaceCentroid(Face face) {
PolygonalMesh mesh = (PolygonalMesh) face.getMesh();
Point3d centroid = new Point3d();
face.computeCentroid(centroid);
Vertex3d midVtx = mesh.addVertex(centroid);
mesh.removeFace(face);
Vertex3d[] vtxs = face.getVertices();
for (int i = 0; i < vtxs.length; i++) {
int next = (i + 1) % vtxs.length;
mesh.addFace(vtxs[i], vtxs[next], midVtx);
}
}
use of maspack.matrix.Point3d in project artisynth_core by artisynth.
the class MeshFactory method collectEdgeVertices.
private static Vertex3d[] collectEdgeVertices(HashMap<HalfEdge, Vertex3d[]> edgeVertices, PolygonalMesh mesh, Face face, int edgeNum, int res, NagataInterpolator interp) {
int numv = res + 1;
HalfEdge he = face.getEdge(edgeNum);
Vertex3d[] vtxs = edgeVertices.get(he.opposite);
if (vtxs == null) {
// need to create the vertices
vtxs = new Vertex3d[numv];
vtxs[0] = he.getTail();
vtxs[numv - 1] = he.getHead();
// create vertices along edge
for (int i = 1; i < numv - 1; i++) {
Point3d pnt = new Point3d();
double eta, zeta;
double s = i / (double) res;
switch(edgeNum) {
case 1:
{
eta = s;
zeta = 0;
break;
}
case 2:
{
eta = 1;
zeta = s;
break;
}
case 0:
{
eta = 1 - s;
zeta = 1 - s;
break;
}
default:
{
throw new InternalErrorException("Illegal edgeNum " + edgeNum);
}
}
interp.interpolateVertex(pnt, eta, zeta);
// pnt.combine (0.5, vtxs[0].pnt, 0.5, vtxs[numv-1].pnt);
vtxs[i] = new Vertex3d(pnt);
mesh.addVertex(vtxs[i]);
}
edgeVertices.put(he, vtxs);
return vtxs;
} else {
// vertices in the wrong order; return a reversed list of them.
Vertex3d[] vtxsRev = new Vertex3d[numv];
for (int i = 0; i < numv; i++) {
vtxsRev[i] = vtxs[numv - 1 - i];
}
return vtxsRev;
}
}
Aggregations