use of maspack.geometry.Face in project artisynth_core by artisynth.
the class MFreeFactory method generatePointLocations.
public static Point3d[] generatePointLocations(PolygonalMesh mesh, int[] res, int nPoints) {
Vector3d centroid = new Vector3d();
mesh.computeCentroid(centroid);
RigidTransform3d trans = new RigidTransform3d();
trans.setTranslation(centroid);
OBB obb = PointDistributor.getTightOBB(mesh, trans);
Vector3d widths = new Vector3d();
obb.getWidths(widths);
obb.getTransform(trans);
int nx = res[0];
int ny = res[1];
int nz = res[2];
double dx, dy, dz;
double xOffset, yOffset, zOffset;
if (nx == 1) {
widths.x = 0;
dx = 0;
} else {
dx = widths.x / (nx - 1);
}
if (ny == 1) {
widths.y = 0;
dy = 0;
} else {
dy = widths.y / (ny - 1);
}
if (nz == 1) {
widths.z = 0;
dz = 0;
} else {
dz = widths.z / (nz - 1);
}
xOffset = -widths.x / 2;
yOffset = -widths.y / 2;
zOffset = -widths.z / 2;
// generate a grid of points that fall inside domain
Point3d[][][] pnts = new Point3d[nx][ny][nz];
// BVFeatureQuery query = new BVFeatureQuery();
Vector3i sdres = new Vector3i(2 * nx, 2 * ny, 2 * nz);
sdres.x = Math.min(sdres.x, 30);
sdres.y = Math.min(sdres.y, 30);
sdres.z = Math.min(sdres.z, 30);
Logger.getSystemLogger().debug("Creating signed distance grid");
List<Face> faces = mesh.getFaces();
DistanceGrid sdgrid = new DistanceGrid(faces, 0.1, sdres, true);
Logger.getSystemLogger().debug("done");
double tol = 1e-15;
Logger.getSystemLogger().debug("Generating " + nx + "x" + ny + "x" + nz + " points");
double x, y, z;
for (int i = 0; i < nx; i++) {
x = xOffset + i * dx;
for (int j = 0; j < ny; j++) {
y = yOffset + j * dy;
for (int k = 0; k < nz; k++) {
z = zOffset + k * dz;
Point3d pnt = new Point3d(x, y, z);
pnt.transform(trans);
double d = sdgrid.getLocalDistanceAndNormal(null, null, pnt);
if (d < tol) {
pnts[i][j][k] = pnt;
} else {
pnts[i][j][k] = null;
}
// InsideQuery rayTest = query.isInsideMesh(mesh, pnt, tol);
// if (rayTest == InsideQuery.INSIDE) {
// pnts[i][j][k] = pnt;
// } else if (rayTest == InsideQuery.OUTSIDE) {
// pnts[i][j][k] = null;
// } else {
// System.out.println("unsure");
// }
}
}
}
Logger.getSystemLogger().debug("done.");
Logger.getSystemLogger().debug("Farthest point sampling...");
Point3dGridUtility pgu = new Point3dGridUtility(pnts);
FastRadialMarcher marcher = new FastRadialMarcher(nx * ny * nz, pgu);
marcher.initializeArrays();
double[] dists = marcher.getDistance();
// mark null points as having distance of -1 (never to be selected)
for (int i = 0; i < nx; i++) {
for (int j = 0; j < ny; j++) {
for (int k = 0; k < nz; k++) {
if (pnts[i][j][k] == null) {
dists[k + j * nz + i * ny * nz] = -1;
}
}
}
}
// initialize heap to include all indices
marcher.getDistanceHeap().setAll();
// farthest-point sampling
Point3d[] out = new Point3d[nPoints];
int i, j, k;
for (int idx = 0; idx < nPoints; idx++) {
int farthest = 0;
IndexedBinaryHeap dheap = marcher.getDistanceHeap();
farthest = dheap.peek();
// get next furthest
int nextSample = farthest;
// idx = i*ny*nz+j*nz+k
k = nextSample % nz;
j = ((nextSample - k) / nz) % ny;
i = (nextSample - k - j * nz) / (ny * nz);
out[idx] = pnts[i][j][k];
// update distances to first point
marcher.march(nextSample);
}
Logger.getSystemLogger().debug("done.");
return out;
}
use of maspack.geometry.Face in project artisynth_core by artisynth.
the class RigidBody method getDistanceGrid.
/**
* Returns a signed distance grid that can be used with a
* SignedDistanceCollider, or <code>null</code> if a grid is not available
* (i.e., if {@link #hasDistanceGrid} returns <code>false</code>).
* The number of divisons in the grid is controlled explicitly by the
* property <code>distanceGridRes</code>, or, that is 0, by the property
* <code>distanceGridMaxRes</code>. If both properties are 0, no grid is
* available and <code>null</code> will be returned.
*
* @return signed distance grid, or <code>null</code> if a grid is
* not available this RigidBody
* @see #getDistanceGridMaxRes
* @see #getDistanceGridRes
*/
public DistanceGrid getDistanceGrid() {
if (mySDGrid == null || !mySDGridValid) {
int maxRes = myDistanceGridMaxRes;
if (!myDistanceGridRes.equals(Vector3i.ZERO) || maxRes > 0) {
if (!myDistanceGridRes.equals(Vector3i.ZERO)) {
mySDGrid = new DistanceGrid(myDistanceGridRes);
maxRes = 0;
} else {
// resolution will be recomputed in computeFromFeatures
mySDGrid = new DistanceGrid(new Vector3i(1, 1, 1));
}
mySDGrid.setDrawEdges(true);
List<Face> faces = getMesh().getFaces();
if (myDistanceGridOBB) {
mySDGrid.computeFromFeaturesOBB(faces, myGridMargin, maxRes, /*signed=*/
true);
} else {
mySDGrid.computeFromFeatures(faces, myGridMargin, /*TGL=*/
null, maxRes, /*signed=*/
true);
}
mySDGrid.setLocalToWorld(getPose());
} else {
mySDGrid = null;
}
// mySDGrid.smooth (0.33, -0.34, 2);
mySDSurface = null;
mySDGridValid = true;
}
return mySDGrid;
}
use of maspack.geometry.Face in project artisynth_core by artisynth.
the class MeshIntersectingProbe method trimFaces.
protected static PolygonalMesh trimFaces(PolygonalMesh mesh, HashMap<Vertex3d, Boolean> vtxIndicatorMap) {
PolygonalMesh out = new PolygonalMesh();
HashMap<Vertex3d, Vertex3d> vtxMap = new HashMap<Vertex3d, Vertex3d>(mesh.numVertices());
for (Vertex3d vtx : mesh.getVertices()) {
if (vtxIndicatorMap.get(vtx)) {
Vertex3d nvtx = new Vertex3d(new Point3d(vtx.getPosition()));
vtxMap.put(vtx, nvtx);
out.addVertex(nvtx);
}
}
for (Face face : mesh.getFaces()) {
boolean add = true;
for (Vertex3d vtx : face.getVertices()) {
if (vtxIndicatorMap.get(vtx) == false) {
add = false;
break;
}
}
if (add) {
Vertex3d[] oldVtxs = face.getVertices();
Vertex3d[] vtxs = new Vertex3d[face.numVertices()];
for (int i = 0; i < vtxs.length; i++) {
vtxs[i] = vtxMap.get(oldVtxs[i]);
}
out.addFace(vtxs);
}
}
return out;
}
use of maspack.geometry.Face in project artisynth_core by artisynth.
the class MeshIntersectingProbe method getFaces.
/**
* Returns a list of all faces that use this vertex
*/
public ArrayList<Face> getFaces(Vertex3d vtx) {
Iterator<HalfEdge> hit = vtx.getIncidentHalfEdges();
ArrayList<Face> faces = new ArrayList<Face>();
while (hit.hasNext()) {
HalfEdge he = hit.next();
faces.add(he.getFace());
}
return faces;
}
use of maspack.geometry.Face in project artisynth_core by artisynth.
the class MeshIntersectingProbe method splitFace.
// splits a face at a point
private static ArrayList<Face> splitFace(PolygonalMesh mesh, Face face, Vertex3d vtx, double tol) {
ArrayList<Face> newFaces = new ArrayList<Face>();
Vertex3d[] verts = face.getVertices();
// if the vtx is one of the corners, don't do anything
for (Vertex3d v : verts) {
if (v == vtx) {
newFaces.add(face);
return newFaces;
}
}
if (!mesh.containsVertex(vtx)) {
// transform to mesh coordinate system,
// then add
vtx.pnt.inverseTransform(mesh.getMeshToWorld());
mesh.addVertex(vtx);
}
mesh.removeFace(face);
Vertex3d v1, v2, v3;
v1 = vtx;
for (int i = 0; i < verts.length; i++) {
int j = (i + 1) % verts.length;
v2 = verts[i];
v3 = verts[j];
if (getSignedTriangleArea(v1.getWorldPoint(), v2.getWorldPoint(), v3.getWorldPoint(), face.getWorldNormal()) > tol) {
newFaces.add(mesh.addFace(v1, v2, v3));
}
}
return newFaces;
}
Aggregations