use of maspack.geometry.OBB in project artisynth_core by artisynth.
the class MeshInfo method doPrintBounds.
private static void doPrintBounds(MeshBase mesh) {
double inf = Double.POSITIVE_INFINITY;
Point3d max = new Point3d(-inf, -inf, -inf);
Point3d min = new Point3d(inf, inf, inf);
Point3d tmp = new Point3d();
mesh.updateBounds(min, max);
tmp.sub(max, min);
System.out.println("boundingBoxWidths= " + tmp.toString("%8.3f"));
System.out.println("boundingBoxDiameter= " + tmp.norm());
tmp.add(max, min);
tmp.scale(0.5);
System.out.println("boundingBoxCenter= " + tmp.toString("%8.3f"));
OBB obb = new OBB();
obb.set(mesh, 0, OBB.Method.Points);
obb.getWidths(tmp);
System.out.println("obbWidths= " + tmp.toString("%8.3f"));
System.out.println("obbCenter= " + obb.getTransform().p.toString("%8.3f"));
System.out.println("minPoint= " + min.toString("%.8f"));
System.out.println("maxPoint= " + max.toString("%.8f"));
}
use of maspack.geometry.OBB 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.OBB in project artisynth_core by artisynth.
the class PointDistributor method getTightOBB.
public static OBB getTightOBB(Point3d[] pnts, RigidTransform3d principal) {
Vector3d[] axis = new Vector3d[3];
double[][] projBounds = new double[3][2];
for (int i = 0; i < 3; i++) {
axis[i] = new Vector3d();
principal.R.getColumn(i, axis[i]);
}
Vector3d p = principal.p;
// loop through all nodes, projecting onto axes
for (int i = 0; i < pnts.length; i++) {
for (int j = 0; j < 3; j++) {
Vector3d vec = new Vector3d();
vec.sub(pnts[i], p);
double d = vec.dot(axis[j]);
if (d < projBounds[j][0]) {
projBounds[j][0] = d;
} else if (d > projBounds[j][1]) {
projBounds[j][1] = d;
}
}
// end looping through axes
}
// end looping over vertices
// construct bounds
Point3d c = new Point3d(0, 0, 0);
Vector3d widths = new Vector3d();
for (int i = 0; i < 3; i++) {
c.set(i, 0);
widths.set(i, projBounds[i][1] - projBounds[i][0]);
c.set(i, p.get(i) + (projBounds[i][0] + projBounds[i][1]) / 2);
}
RigidTransform3d trans = new RigidTransform3d(c, principal.R);
OBB obb = new OBB(widths, trans);
return obb;
}
use of maspack.geometry.OBB in project artisynth_core by artisynth.
the class MultiPointSpring method computeDefaultMaxWrapDisplacement.
private double computeDefaultMaxWrapDisplacement() {
double mind = Double.POSITIVE_INFINITY;
CompositeComponent comp = ComponentUtils.nearestEncapsulatingAncestor(this);
if (comp instanceof Renderable) {
mind = RenderableUtils.getRadius((Renderable) comp) / 10;
}
for (Wrappable w : myWrappables) {
if (w instanceof HasSurfaceMesh) {
PolygonalMesh mesh = ((HasSurfaceMesh) w).getSurfaceMesh();
if (mesh != null) {
OBB obb = new OBB(mesh);
Vector3d widths = new Vector3d();
obb.getWidths(widths);
double hw = widths.minElement() / 2;
if (hw < mind) {
mind = hw / 2;
}
}
}
}
if (mind == Double.POSITIVE_INFINITY) {
mind = 1.0;
}
return mind;
}
use of maspack.geometry.OBB in project artisynth_core by artisynth.
the class MFreeFactory method createModel.
public static MFreeModel3d createModel(MFreeModel3d model, PolygonalMesh surface, RigidTransform3d transform, int nNodes, int nIPnts, int[] gridRes, RadialWeightFunctionType fType) {
if (model == null) {
model = new MFreeModel3d();
}
if (transform != null) {
surface.transform(transform);
}
if (gridRes == null) {
OBB meshObb = new OBB(surface);
Vector3d hw = new Vector3d(meshObb.getHalfWidths());
double vol = hw.x * hw.y * hw.z * 8;
double ipntVol = vol / nIPnts;
// find rough dimensions of one ipnt, same proportions
// as root OBB
double scale = Math.pow(ipntVol / vol, 0.333);
// we want at least 20? points along each dimension,
// find minimum distance
double min = hw.minElement();
double minFactor = 1.0 / scale * 15;
int nx = (int) Math.ceil(minFactor * hw.x / min);
int ny = (int) Math.ceil(minFactor * hw.y / min);
int nz = (int) Math.ceil(minFactor * hw.z / min);
gridRes = new int[] { nx, ny, nz };
}
surface.triangulate();
Point3d[] ipntLocs = generatePointLocations(surface, gridRes, nIPnts);
// cut first section
Point3d[] nodeLocs = Arrays.copyOf(ipntLocs, nNodes);
createModel(model, nodeLocs, ipntLocs, surface, fType);
return model;
}
Aggregations