use of maspack.geometry.Face in project artisynth_core by artisynth.
the class MeshIntersectingProbe method clipMesh.
// does the clipping of a planar surface based on a contour
private void clipMesh(PolygonalMesh surface, LinkedList<Point3d> contour, double tol) {
SplitStorage info = new SplitStorage();
Intersector2d ti = new Intersector2d();
ti.setEpsilon(tol);
// coordinate system
Vector3d vx = new Vector3d();
Vector3d vy = new Vector3d();
Point3d o = getPosition();
XGridToWorld.R.getColumn(0, vx);
XGridToWorld.R.getColumn(1, vy);
OBBTree obbt = new OBBTree(surface, 2, tol);
ArrayList<Face> faceList = null;
while (info.idx + 1 < contour.size()) {
if (info.vtx == null) {
Face face = findNextFace(contour.get(info.idx), contour, obbt, ti, vx, vy, o, info);
// so now I have a vertex and a face it lies on
if (face != null) {
// we may be on multiple faces
faceList = findFaces(info.vtx.getWorldPoint(), obbt, vx, vy, o, tol);
for (Face f : faceList) {
splitFace(surface, f, info.vtx, tol);
}
}
} else {
// find all faces this vertex is on, project in direction of contour
faceList = getFaces(info.vtx);
HalfEdge he = findNextEdge(contour, faceList, ti, info, vx, vy, o);
if (he != null) {
// we landed on an edge
Face oppFace = null;
if (he.opposite != null) {
oppFace = he.opposite.getFace();
}
splitFace(surface, he.getFace(), info.vtx, tol);
if (oppFace != null) {
splitFace(surface, oppFace, info.vtx, tol);
}
} else if (info.face != null) {
splitFace(surface, info.face, info.vtx, tol);
} else {
// move to next point
info.idx++;
info.vtx = null;
}
}
}
}
use of maspack.geometry.Face in project artisynth_core by artisynth.
the class SurfaceMeshCollider method collideVerticesWithFaces.
/*
* For each penetrating vertex, find the closest opposing face and add a
* corresponding new element to the list of ContactPenetratingPoints
*/
public static void collideVerticesWithFaces(ArrayList<PenetratingPoint> cpps, PenetrationRegion region, PolygonalMesh otherMesh) {
BVFeatureQuery query = new BVFeatureQuery();
Vector2d uv = new Vector2d();
Point3d nearPnt = new Point3d();
Vector3d disp = new Vector3d();
Point3d wpnt = new Point3d();
PenetratingPoint cpp;
for (Vertex3d vtx : region.myVertices) {
vtx.getWorldPoint(wpnt);
Face face = query.nearestFaceToPoint(nearPnt, uv, otherMesh, wpnt);
disp.sub(nearPnt, wpnt);
cpp = new PenetratingPoint(vtx, face, uv, nearPnt, disp, region);
cpps.add(cpp);
}
}
use of maspack.geometry.Face in project artisynth_core by artisynth.
the class SurfaceMeshContourIxer method getAllMIPs.
/**
* Return an unordered list of MeshIntersectionPoints representing all
* edge/face collisions between the lists of BVs nodes0 and nodes1.
*
* New MeshIntersectionPoints are generated and appended to allMips.
* All Faces are assumed to be triangular! Undetermined behaviour if not the case.
*
* @param allMips Initialized ArrayList of MeshIntersectionPoints
* @param nodes0 first list of BVs from BVTree.intersectTree
* @param nodes1 second list of BVs from BVTree.intersectTree (same length as nodes0)
*
* @throws DegeneratePairCaseException if a degenerate case is detected.
* Points of those faces are perturbed before this exception is re-thrown
*/
protected void getAllMIPs(ArrayList<IntersectionPoint> allMips, ArrayList<BVNode> nodes0, ArrayList<BVNode> nodes1) throws DegeneratePairCaseException {
assert nodes0.size() == nodes1.size();
for (int i = 0; i < nodes0.size(); i++) {
BVNode n0 = nodes0.get(i);
BVNode n1 = nodes1.get(i);
for (Boundable b0 : n0.getElements()) {
for (Boundable b1 : n1.getElements()) {
if (b0 instanceof Face && b1 instanceof Face) {
Face f0 = (Face) b0;
Face f1 = (Face) b1;
int numFound = 0;
numFound += doFaceFaceCollision(allMips, f0, f1, true);
numFound += doFaceFaceCollision(allMips, f1, f0, false);
if (myHandleDegen) {
if (numFound != 0 && numFound != 2) {
perturbVertices(f0);
perturbVertices(f1);
// System.out.println("Found " + numFound + " ixps");
throw new DegeneratePairCaseException();
}
}
}
}
}
}
}
use of maspack.geometry.Face in project artisynth_core by artisynth.
the class IntersectionContour method isClockwise.
/**
* Computes whether or not this contour is oriented clockwise
* with respect to the penetrating region for mesh0.
*
* @return true of contour is clockwise with respect to mesh0.
*/
boolean isClockwise(PolygonalMesh mesh0, PolygonalMesh mesh1) {
int csize = size();
// find the largest contour segment
Vector3d dir = new Vector3d();
Vector3d xprod = new Vector3d();
double dmax = 0;
boolean clockwise = true;
int nsegs = isClosed ? csize : csize - 1;
for (int i = 0; i < nsegs; i++) {
IntersectionPoint pa = get((i) % csize);
IntersectionPoint pb = get((i + 1) % csize);
Face face0 = findSegmentFace(pa, pb, mesh0);
Face face1 = findSegmentFace(pa, pb, mesh1);
dir.sub(pb, pa);
xprod.cross(face1.getWorldNormal(), dir);
double dot = face0.getWorldNormal().dot(xprod);
if (Math.abs(dot) > dmax) {
dmax = Math.abs(dot);
clockwise = (dot < 0);
}
}
return clockwise;
}
use of maspack.geometry.Face in project artisynth_core by artisynth.
the class IntersectionContour method findSegmentFaceStart.
/**
* Returns an index at which the indicated face first appears as a segment
* face for the indicated mesh, or -1 if no such starting index is found,
* which means either that the segment face does not appear at all, or
* appears along the whole contour.
*/
public int findSegmentFaceStart(Face face, PolygonalMesh mesh) {
Face lastFace = findSegmentFace(size() - 1, mesh);
for (int k = 0; k < size(); k++) {
Face segFace = findSegmentFace(k, mesh);
if (segFace == face && lastFace != face) {
return k;
}
lastFace = segFace;
}
return -1;
}
Aggregations