use of maspack.geometry.BVTree in project artisynth_core by artisynth.
the class MFreeMuscleModel method computeAverageFiberDirection.
public static boolean computeAverageFiberDirection(Vector3d dir, Point3d pos, double rad, PolylineMesh mesh) {
BVTree bvh = mesh.getBVTree();
ArrayList<BVNode> nodes = new ArrayList<BVNode>();
Matrix3d cov = new Matrix3d();
SVDecomposition3d svd = new SVDecomposition3d();
Vector3d tmp = new Vector3d();
Matrix3d tmp2 = new Matrix3d();
bvh.intersectSphere(nodes, pos, rad);
dir.setZero();
int nsegs = 0;
// for computing sign of direction vector
Vector3d segmentSum = new Vector3d();
// System.out.println("p=[");
for (BVNode n : nodes) {
Boundable[] elements = n.getElements();
for (int i = 0; i < elements.length; i++) {
LineSegment seg = (LineSegment) elements[i];
seg = getSegmentInsideSphere(seg, pos, rad);
if (seg != null) {
tmp.sub(seg.myVtx1.pnt, seg.myVtx0.pnt);
if (tmp.norm() >= 1e-8 * rad) {
// System.out.println(seg.myVtx0.getPosition() + " " +
// seg.myVtx1.getPosition());
nsegs++;
// prepare to average directions using SVD
computeCov(tmp2, tmp);
cov.add(tmp2);
segmentSum.add(tmp);
}
}
}
}
if (nsegs > 0) {
// we are technically including both +/- directions, so
// we have twice the number of points
cov.scale(2.0 / (2.0 * nsegs - 1));
try {
svd.factor(cov);
} catch (Exception e) {
// System.err.println(e.getMessage());
}
// principal components
tmp2 = svd.getU();
tmp2.getColumn(0, dir);
dir.normalize();
// most line segments
if (dir.dot(segmentSum) < 0) {
dir.scale(-1);
}
return true;
} else {
return false;
}
}
use of maspack.geometry.BVTree in project artisynth_core by artisynth.
the class PointDistributor method sphereGridFill.
// fills a mesh based on a regular grid of points
public static Point3d[] sphereGridFill(PolygonalMesh mesh, double r) {
ArrayList<Point3d> pnts = new ArrayList<Point3d>();
RigidTransform3d trans = getPrincipalAxes(mesh);
Point3d[] box = getTightBox(mesh, trans);
Point3d center = new Point3d(box[0]);
center.add(box[6]);
center.scale(0.5);
trans.setTranslation(center);
Vector3d l = new Vector3d(box[0]);
l.sub(box[6]);
l.inverseTransform(trans);
double alpha = 2 * Math.sqrt(2) * r;
int nx = (int) Math.ceil(l.x / alpha) + 1;
int ny = (int) Math.ceil(l.y / alpha) + 1;
int nz = (int) Math.ceil(l.z / alpha) + 1;
double xoffset = -(nx - 1) * alpha / 2;
double yoffset = -(ny - 1) * alpha / 2;
double zoffset = -(nz - 1) * alpha / 2;
BVTree bvh = mesh.getBVTree();
Vector2d coords = new Vector2d();
Point3d nearest = new Point3d();
BVFeatureQuery query = new BVFeatureQuery();
Point3d p;
for (int i = 0; i < nx; i++) {
for (int j = 0; j < ny; j++) {
for (int k = 0; k < nz; k++) {
double x = i * alpha + xoffset;
double y = j * alpha + yoffset;
double z = k * alpha + zoffset;
p = new Point3d(x, y, z);
p.transform(trans);
addIfIntersects(pnts, p, r, bvh, nearest, coords, query);
}
}
}
return pnts.toArray(new Point3d[pnts.size()]);
}
use of maspack.geometry.BVTree in project artisynth_core by artisynth.
the class PointDistributor method sphereFCCFill.
// fills a mesh with spheres based on face-centered cubic packing
public static Point3d[] sphereFCCFill(PolygonalMesh mesh, double r) {
ArrayList<Point3d> pnts = new ArrayList<Point3d>();
RigidTransform3d trans = getPrincipalAxes(mesh);
Point3d[] box = getTightBox(mesh, trans);
Point3d center = new Point3d(box[0]);
center.add(box[6]);
center.scale(0.5);
trans.setTranslation(center);
Vector3d l = new Vector3d(box[0]);
l.sub(box[6]);
l.inverseTransform(trans);
double alpha = 2 * Math.sqrt(2) * r;
int nx = (int) Math.ceil(l.x / alpha) + 1;
int ny = (int) Math.ceil(l.y / alpha) + 1;
int nz = (int) Math.ceil(l.z / alpha) + 1;
double xoffset = -(nx - 1) * alpha / 2;
double yoffset = -(ny - 1) * alpha / 2;
double zoffset = -(nz - 1) * alpha / 2;
BVTree bvh = mesh.getBVTree();
Vector2d coords = new Vector2d();
Point3d nearest = new Point3d();
BVFeatureQuery query = new BVFeatureQuery();
Point3d p;
for (int i = 0; i < nx; i++) {
for (int j = 0; j < ny; j++) {
for (int k = 0; k < nz; k++) {
double x = i * alpha + xoffset;
double y = j * alpha + yoffset;
double z = k * alpha + zoffset;
p = new Point3d(x, y, z);
p.transform(trans);
addIfIntersects(pnts, p, r, bvh, nearest, coords, query);
// face centers
if (i < nx - 1 && k < nz - 1) {
p = new Point3d(x + alpha / 2, y, z + alpha / 2);
p.transform(trans);
addIfIntersects(pnts, p, r, bvh, nearest, coords, query);
}
if (j < ny - 1 && k < nz - 1) {
p = new Point3d(x, y + alpha / 2, z + alpha / 2);
p.transform(trans);
addIfIntersects(pnts, p, r, bvh, nearest, coords, query);
}
if (i < nx - 1 && j < ny - 1) {
p = new Point3d(x + alpha / 2, y + alpha / 2, z);
p.transform(trans);
addIfIntersects(pnts, p, r, bvh, nearest, coords, query);
}
}
}
}
return pnts.toArray(new Point3d[pnts.size()]);
}
Aggregations