use of maspack.matrix.AffineTransform3d in project artisynth_core by artisynth.
the class MeshICP method align.
public static AffineTransform3d align(PolygonalMesh mesh1, PolygonalMesh mesh2, AlignmentType alignType, double eps, int maxIters, PolygonalMesh out) {
// align meshes
ArrayList<Point3d> outPnts = new ArrayList<Point3d>();
AffineTransform3d trans = align(mesh1, mesh2, alignType, eps, maxIters, outPnts);
if (out != null) {
Point3d[] nodes = outPnts.toArray(new Point3d[outPnts.size()]);
ArrayList<Face> faces = mesh1.getFaces();
int[][] faceIndices = new int[faces.size()][];
for (int i = 0; i < faceIndices.length; i++) {
faceIndices[i] = faces.get(i).getVertexIndices();
}
// construct new mesh from outPnts and connectivity from mesh1
out.set(nodes, faceIndices);
}
return trans;
}
use of maspack.matrix.AffineTransform3d in project artisynth_core by artisynth.
the class MeshICP method align.
public static AffineTransform3d align(PolygonalMesh mesh1, PolygonalMesh mesh2, AlignmentType alignType, double eps, int maxIters, ArrayList<Point3d> out) {
// align mesh1 to mesh2, then return inverse transform
// OBBTree obbt = mesh2.getObbtree(); // for projecting points onto mesh1
// TriangleIntersector ti = new TriangleIntersector(); // stores information in nearest face
// algorithm
// barycentric coordinates of closest
Vector2d coords = new Vector2d();
// point
// mean distance error
double err = Double.POSITIVE_INFINITY;
// previous mean error
double prevErr = Double.POSITIVE_INFINITY;
// number of iterations
int iters = 0;
// get points
ArrayList<Point3d> pnts = new ArrayList<Point3d>();
ArrayList<Point3d> projected = new ArrayList<Point3d>();
// incremental transformation
AffineTransform3d transInc = new AffineTransform3d();
// total transform
AffineTransform3d transOut = new AffineTransform3d();
// clear point sets
pnts.clear();
for (Vertex3d v : mesh1.getVertices()) {
pnts.add(new Point3d(v.getWorldPoint()));
}
do {
projected.clear();
for (int i = 0; i < pnts.size(); i++) {
Point3d p = pnts.get(i);
Point3d q = new Point3d();
BVFeatureQuery.getNearestFaceToPoint(q, coords, mesh2, p);
// q is the closest point on mesh2 to p
projected.add(q);
}
switch(alignType) {
case AFFINE:
// affine
transInc.fit(projected, pnts);
break;
case ORTHOGONAL:
// allow orthogonal scaling
transInc.fitOrthogonal(projected, pnts);
break;
case RIGID:
// rigid no scaling
transInc.fitRigid(projected, pnts, false);
break;
case RIGID_WITH_SCALING:
// rigid with scaling
transInc.fitRigid(projected, pnts, true);
break;
}
// concatenate transforms through pre-multiplication
transOut.mul(transInc, transOut);
// compute error
prevErr = err;
err = 0;
for (int i = 0; i < pnts.size(); i++) {
pnts.get(i).transform(transInc);
err += pnts.get(i).distance(projected.get(i));
}
// mean error
err = err / pnts.size();
iters++;
// stop when we mean error has converged or maxIters is reached.
} while (Math.abs(err - prevErr) > eps && iters < maxIters);
// copy projected points to out (so in same reference coordinate as mesh2)
if (out != null) {
out.clear();
for (int i = 0; i < projected.size(); i++) {
Point3d p = projected.get(i);
// p.transform(transOut);
out.add(p);
}
}
// transOut now holds mesh1 -> mesh2 transform, we want opposite
transOut.invert();
return transOut;
}
use of maspack.matrix.AffineTransform3d in project artisynth_core by artisynth.
the class MayaAsciiReader method recursiveBuildParentTransform.
private void recursiveBuildParentTransform(Node<MayaNode> leaf, AffineTransform3d trans, UnitInfo units) {
if (leaf.getNumberOfParents() > 0) {
Node<MayaNode> parent = leaf.getParent(0);
MayaNode data = parent.getData();
if (data instanceof MayaTransform) {
MayaTransform dtrans = (MayaTransform) data;
AffineTransform3d tu = new AffineTransform3d();
dtrans.getTransform(tu);
// convert units
tu.p.scale(dtrans.units.length.getSI() / units.length.getSI());
if (dtrans.inheritsTransform()) {
trans.mul(tu);
} else {
trans.set(tu);
}
}
recursiveBuildParentTransform(parent, trans, units);
}
}
use of maspack.matrix.AffineTransform3d in project artisynth_core by artisynth.
the class MayaAsciiReader method getPolygonalMesh.
public PolygonalMesh getPolygonalMesh(Node<MayaNode> root, UnitInfo units) {
if (units == null) {
units = defaultUnits;
}
PolygonalMesh mesh = new PolygonalMesh();
AffineTransform3d trans = new AffineTransform3d();
recursiveBuildParentTransform(root, trans, units);
recursiveAddPolygonalMeshes(root, mesh, trans, units);
return mesh;
}
use of maspack.matrix.AffineTransform3d in project artisynth_core by artisynth.
the class MayaAsciiReader method recursiveAddPolylines.
private void recursiveAddPolylines(Node<MayaNode> root, PolylineMesh mesh, AffineTransform3d trans, UnitInfo units, Pattern pregex) {
// make copy so can traverse
trans = new AffineTransform3d(trans);
// children independently
MayaNode data = root.getData();
if (data instanceof MayaTransform) {
MayaTransform dtrans = (MayaTransform) data;
AffineTransform3d tu = new AffineTransform3d();
dtrans.getTransform(tu);
// convert units
tu.p.scale(dtrans.units.length.getSI() / units.length.getSI());
if (dtrans.inheritsTransform()) {
trans.mul(tu);
} else {
trans.set(tu);
}
} else if (data instanceof MayaNurbsCurve) {
MayaNurbsCurve mnc = (MayaNurbsCurve) data;
if (pregex == null || pregex.matcher(mnc.getName()).matches()) {
Polyline line = new Polyline(mnc.curve);
if (line != null) {
// transform line
for (Vertex3d vtx : line.getVertices()) {
vtx.pnt.scale(mnc.units.length.getSI() / units.length.getSI());
vtx.pnt.transform(trans);
}
mesh.addLine(line);
}
}
}
for (Node<MayaNode> child : root.getChildren()) {
recursiveAddPolylines(child, mesh, trans, units, pregex);
}
}
Aggregations