use of maspack.collision.IntersectionPoint in project artisynth_core by artisynth.
the class SurfaceMeshIntersector method traceIntersectionContour.
/*
* contour is an ArrayList of MeshIntersectionPoints with one element. The
* first element is the intersection of edge and otherFace. edgeFace is an
* adjacent edge to otherFace. It provides the initial search direction. Find
* successive points in the intersection to continue the contour until it is
* closed or an edge is encountered or it becomes too large.
*
* <p>
* The contour has flags isClosed and isContinuable which are set
* when points are added to it.
*
* The basic idea is this: given an intersection edge0/Face1 between Face0
* and Face1, find the next intersection by intersecting edge0.opposite with
* Face1 and discarding the intersection involving edge0. That will yield
* either an intersection edgex/Face1 or edgey/edge.opposite, where edgex !=
* edge0 is an edge of edge.opposite, or edgey is an edge of Face1.
*/
private void traceIntersectionContour(IntersectionContour contour, Face anEdgeFace, boolean edgeOnMesh0) {
// SurfaceMeshCollider.collisionMetrics.walkTime -= System.nanoTime();
IntersectionPoint mip = contour.get(contour.size() - 1);
Face edgeFace = anEdgeFace;
Face otherFace = mip.face;
Face tmpFace;
HalfEdge edge = mip.edge;
HalfEdge nextEdge = null;
do {
nextEdge = differentEdgeIntersectingFace(edgeFace, otherFace, edge, contour);
if (nextEdge != null) {
// Move to next edge and face in the same
edge = nextEdge.opposite;
// mesh radiating from the same vertex.
if (edge == null) {
contour.openMesh = true;
edgeFace = null;
} else {
edgeFace = edge.getFace();
}
} else {
edge = edgeIntersectingFace(otherFace, edgeFace, contour);
if (edge == null) {
if (traceContourDebug) {
System.out.println("edgeFace set to null");
}
edgeFace = null;
} else {
edge = edge.opposite;
if (edge == null) {
contour.openMesh = true;
edgeFace = null;
} else {
// Chain-linked triangles - swap
tmpFace = edge.getFace();
// meshes and continue.
otherFace = edgeFace;
edgeFace = tmpFace;
}
}
}
} while (edgeFace != null && contour.isContinuable);
}
use of maspack.collision.IntersectionPoint in project artisynth_core by artisynth.
the class SurfaceMeshIntersector method removeIntersectionFromEdge.
/**
* Remove an intersection point <code>mip</code> from the set of
* intersections associated with its edge.
*/
void removeIntersectionFromEdge(IntersectionPoint mip) {
EdgeInfo einfo = myEdgeInfos.get(mip.edge);
if (einfo == null) {
throw new InternalErrorException("No edge intersections found for edge + " + mip.edge.vertexStr());
}
int i = einfo.indexOfMip(mip);
if (i == -1) {
throw new InternalErrorException("Intersection point not found on edge + " + mip.edge.vertexStr());
}
// if (mip.isCoincident) {
// // XXX need to fix this
// }
einfo.removeMip(i);
// if (einfo.isEmpty()) {
// myEdgeInfos.remove (mip.edge);
// }
}
use of maspack.collision.IntersectionPoint in project artisynth_core by artisynth.
the class SurfaceMeshIntersector method createTestPoint.
/**
* Get a test point that is inside a planar contour (with the plane normal
* given by nrm), for use in testing its relationship with other contours.
*/
Point3d createTestPoint(IntersectionContour c, Vector3d nrm, boolean clockwise) {
Point3d pt = new Point3d();
IntersectionPoint p0 = c.get(0);
IntersectionPoint p1 = null;
IntersectionPoint p2 = null;
IntersectionPoint p;
for (p = p0.next(); p != p0 && p != null; p = p.next()) {
if (p.distance(p0) > myPositionTol) {
p1 = p;
break;
}
}
if (p1 != null) {
for (p = p1.next(); p != p0 && p != null; p = p.next()) {
if (LineSegment.distance(p0, p, p1) > myPositionTol) {
p2 = p;
break;
}
}
}
if (p1 == null || p2 == null) {
// can't find a corner point - just use p0
return new Point3d(p0);
} else {
// compute a small point interior to the corner
Vector3d xprod = new Vector3d();
Vector3d dir = new Vector3d();
Vector3d d01 = new Vector3d();
Vector3d d12 = new Vector3d();
d01.sub(p1, p0);
d12.sub(p2, p1);
xprod.cross(d01, d12);
if (xprod.dot(nrm) > 0) {
dir.sub(d12, d01);
} else {
dir.sub(d01, d12);
}
if (clockwise) {
dir.negate();
}
Point3d pr = new Point3d(p1);
pr.scaledAdd(100 * myPositionTol, dir);
return pr;
}
}
use of maspack.collision.IntersectionPoint in project artisynth_core by artisynth.
the class SurfaceMeshIntersector method findIntersectionContours.
/**
* Examine corresponding nodes pairs in the lists nodes0 and nodes1
* for intersecting triangles. When a new intersecting triangle
* is found, use this as the starting point for tracing a new
* intersection contour.
*/
ArrayList<IntersectionContour> findIntersectionContours(ArrayList<BVNode> nodes0, ArrayList<BVNode> nodes1) {
ArrayList<IntersectionContour> contours = new ArrayList<IntersectionContour>();
myEdgeFaceIntersections.clear();
myEdgeInfos.clear();
myFaceCalcs0 = new FaceCalculator[myMesh0.numFaces()];
myFaceCalcs1 = new FaceCalculator[myMesh1.numFaces()];
for (int i = 0; i < nodes0.size(); i++) {
BVNode node0 = nodes0.get(i);
BVNode node1 = nodes1.get(i);
int nc = findIntersectionContours(contours, node1.getElements(), node0.getElements(), /*edgeOnMesh0=*/
true);
// mesh0 == mesh1.
if (nc == 0) {
findIntersectionContours(contours, node0.getElements(), node1.getElements(), /*edgeOnMesh0=*/
false);
}
}
// myContours is used for debugging
myContours = contours;
// make each contour counterClockwise with respect to mesh0
for (IntersectionContour c : contours) {
if (c.isClockwise(myMesh0, myMesh1)) {
c.reverse();
}
checkCoincidentPoints(c);
}
if (true) {
checkEdgeMipsParameterValue();
}
if (false) {
for (IntersectionContour c : myContours) {
System.out.println("contour " + getContourIndex(c));
c.printCornerPoints("", "%18.14f,", null);
for (IntersectionPoint p : c) {
// System.out.println (toString (p));
}
}
}
return contours;
}
use of maspack.collision.IntersectionPoint in project artisynth_core by artisynth.
the class SurfaceMeshIntersector method addEmptyFaceVertices.
public Vertex3d addEmptyFaceVertices(Vertex3dList poly, HalfEdge edge, IntersectionPoint emip, IntersectionPoint xmip, PenetrationRegion region, Vertex3d curVtx, boolean clockwise, boolean debug) {
if (!addEmptyFaceVertices) {
return curVtx;
}
// FaceEdgeCalculator fcalc =
// new FaceEdgeCalculator (edge.opposite, region, clockwise, debug);
Face emptyFace = edge.opposite.getFace();
PolygonalMesh mesh = (PolygonalMesh) emptyFace.getMesh();
int meshNum = (region.myMesh == myMesh0 ? 0 : 1);
FaceCalculator fcalc;
if (mesh == myMesh0) {
fcalc = getFaceCalculator(emptyFace, myFaceCalcs0);
} else {
fcalc = getFaceCalculator(emptyFace, myFaceCalcs1);
}
fcalc.initializeForEdgeCalcs(clockwise, debug);
if (debug) {
System.out.println(" EmptyFace opposite " + edge.opposite.vertexStr() + " clockwise=" + clockwise + " emip=" + (emip == null ? "null" : emip.contourIndex));
}
double se = 0.0;
double sx;
if (emip != null) {
se = fcalc.edgeProjection(edge.opposite, emip);
} else {
emip = fcalc.findNearestEnteringXip(edge.opposite, region, myPositionTol);
}
if (xmip != null) {
sx = fcalc.edgeProjection(edge.opposite, xmip);
} else {
sx = fcalc.edgeLength(edge.opposite);
}
if (emip != null) {
IntersectionPoint emip0 = emip;
emip = emip.next();
while (emip != null && emip != emip0 && // (emip.findSegmentFace(mesh) == emptyFace ||
(emip.getEffectiveFace(meshNum) == emptyFace || emip.distance(emip0) <= myPositionTol)) {
if (fcalc.projectsToEdge(emip, edge.opposite, se, sx, myPositionTol)) {
if (emip.myVertex != curVtx) {
if (debug) {
System.out.println(" ADD extra vertex " + emip.contourIndex + " " + emip.toString("%12.8f"));
}
curVtx = emip.myVertex;
poly.add(curVtx);
}
}
emip = emip.next();
}
}
return curVtx;
}
Aggregations