use of maspack.collision.IntersectionPoint in project artisynth_core by artisynth.
the class SurfaceMeshIntersector method printFaceXips.
private void printFaceXips(Face face) {
HalfEdge he0 = face.firstHalfEdge();
HalfEdge he = he0;
PolygonalMesh mesh = (PolygonalMesh) face.getMesh();
int meshNum = (mesh == myMesh0 ? 0 : 1);
do {
EdgeInfo einfo = myEdgeInfos.get(he.getPrimary());
System.out.println(" " + he.vertexStr() + " " + (he == he.getPrimary() ? ">" : "<"));
NumberFormat fmt = new NumberFormat("%3d");
if (einfo != null) {
for (int k = 0; k < einfo.numXips(); k++) {
IntersectionPoint p = einfo.getXip(k, he, /*clockwise=*/
false);
char[] desc = new char[] { ' ', ' ', ' ' };
int emptyMark = p.getEmptyMark(meshNum);
if (p.findSegmentFace(mesh) == face) {
if (he.getPrimary() == p.edge) {
desc[0] = 'E';
}
if ((emptyMark & IntersectionPoint.EMPTY_PROJECTED) != 0) {
desc[1] = 'P';
}
if ((emptyMark & IntersectionPoint.EMPTY_BEGIN) != 0) {
desc[2] = 'B';
} else if ((emptyMark & IntersectionPoint.EMPTY_END) != 0) {
desc[2] = 'E';
}
} else {
if (he.getPrimary() == p.edge) {
desc[0] = 'X';
}
if ((emptyMark & IntersectionPoint.EMPTY_PROJECTED) != 0) {
desc[1] = 'O';
}
if ((emptyMark & IntersectionPoint.EMPTY_BEGIN) != 0) {
desc[2] = 'B';
} else if ((emptyMark & IntersectionPoint.EMPTY_END) != 0) {
desc[2] = 'E';
}
}
System.out.println(" " + fmt.format(p.contourIndex) + " " + p.toString("%12.8f") + " " + getContourIndex(p.contour) + " " + new String(desc) + " " + (p.isCoincident() ? "C" : " "));
}
}
he = he.getNext();
} while (he != he0);
}
use of maspack.collision.IntersectionPoint in project artisynth_core by artisynth.
the class SurfaceMeshIntersector method findEmptySegments.
private void findEmptySegments(PenetrationRegion region, PolygonalMesh mesh, RegionType type) {
FaceCalculator[] faceCalcs;
boolean clockwise;
int meshNum;
boolean debug = false;
if (mesh == myMesh0) {
faceCalcs = myFaceCalcs0;
clockwise = (type == RegionType.OUTSIDE);
meshNum = 0;
} else {
faceCalcs = myFaceCalcs1;
clockwise = (type == RegionType.INSIDE);
meshNum = 1;
}
if (debug) {
System.out.println("mesh=" + mesh + " meshNum=" + meshNum);
}
for (IntersectionContour c : region.myContours) {
if (debug) {
System.out.println("contour " + getContourIndex(c) + " size=" + c.size() + " containingFace=" + (c.containingFace != null ? c.containingFace.getIndex() : "null"));
}
IntersectionPoint mip0;
// debug = (getContourIndex(c)==2 && meshNum == 1);
int numSegs;
if (c.isClosed()) {
mip0 = c.firstFaceEntryPoint(mesh, null);
if (mip0 == null) {
mip0 = backupToNonCoincident(c.get(0));
// XXX HACK: if containingFace != null, then we add an
// additional loop interation to process the final segment
numSegs = c.size() + 1;
} else {
numSegs = c.size();
}
} else {
mip0 = c.get(0);
numSegs = c.size() - 1;
}
Face face = c.findSegmentFace(mip0, mesh);
Face effectiveFace = face;
FaceCalculator fcalc = faceCalcs[face.getIndex()];
fcalc.initializeForEdgeCalcs(clockwise, false);
HalfEdge lastEdge = null;
if (c.containingFace == null) {
lastEdge = getPointEdge(mip0, face);
} else {
lastEdge = fcalc.findNearEdge(mip0);
}
IntersectionPoint prevp = null;
IntersectionPoint lastp = mip0;
IntersectionPoint mip = mip0;
boolean marked = false;
for (int i = 0; i < numSegs; i++) {
mip = mip.next();
Face segFace = c.findSegmentFace(mip, mesh);
if (debug) {
System.out.println("mip=" + mip.contourIndex + " face=" + segFace.getIndex() + " " + mip.toString("%8.3f") + " lastEdge=" + (lastEdge != null ? lastEdge.vertexStr() : "null"));
}
if (segFace == face && mip.myVertex == lastp.myVertex) {
continue;
}
if (mip.myVertex != lastp.myVertex) {
if (lastEdge == null) {
// Off edge
lastEdge = fcalc.findNearEdge(mip);
} else {
HalfEdge nextEdge;
if (fcalc.onEdge(mip, lastEdge)) {
nextEdge = lastEdge;
} else {
nextEdge = fcalc.findNearEdge(mip);
}
if (debug) {
System.out.println("nextEdge=" + (nextEdge != null ? nextEdge.vertexStr() : "null"));
}
boolean emptySegment = false;
if (nextEdge != null && fcalc.onEdge(lastp, nextEdge)) {
Vector3d d10 = new Vector3d();
d10.sub(mip, lastp);
emptySegment = fcalc.dotEdge(d10, nextEdge) < 0;
if (clockwise) {
emptySegment = !emptySegment;
}
}
if (nextEdge != null && emptySegment) {
Face nextFace = nextEdge.getOppositeFace();
if (effectiveFace != nextFace) {
if (effectiveFace == face && // the last iteration or we'll get redundant ENTERs
(c.containingFace == null || i < numSegs - 1)) {
if (debug) {
System.out.println("ENTERING face " + nextFace.getIndex() + " edge=" + nextEdge.vertexStr() + " lastp=" + lastp.contourIndex + " mip=" + mip.contourIndex);
System.out.println("mip=" + mip.toString("%8.3f"));
System.out.println("lst=" + lastp.toString("%8.3f"));
}
markEmptySegBegin(lastp, nextEdge, clockwise);
marked = true;
} else {
// corner point; leaving effectiveFace and entering
// next face; no need to do anything
// System.out.println (
// "CORNER between " + effectiveFace.getIndex() +
// " and " + nextFace.getIndex());
//
// XXX do we want to add point anyway?
}
effectiveFace = nextFace;
} else {
// continuing empty segment on nextFace
if (debug) {
System.out.println("CONTINUING face " + effectiveFace.getIndex());
}
markEmptySegMip(lastp, nextEdge, clockwise);
}
} else {
if (effectiveFace != face) {
if (debug) {
System.out.println("LEAVING2 face " + effectiveFace.getIndex());
}
markEmptySegEnd(lastp, lastEdge, clockwise);
effectiveFace = face;
} else {
// XXX test here for empty enter/exit
}
}
lastEdge = nextEdge;
}
}
if (segFace != face && segFace != null) {
// exiting face; entering segFace
face = segFace;
effectiveFace = face;
fcalc = faceCalcs[face.getIndex()];
fcalc.initializeForEdgeCalcs(clockwise, false);
lastEdge = getPointEdge(mip, face);
}
prevp = lastp;
lastp = mip;
}
if (c.containingFace != null && c.containingFace.getMesh() == mesh) {
c.emptySegmentsMarked = marked;
}
}
}
use of maspack.collision.IntersectionPoint in project artisynth_core by artisynth.
the class SurfaceMeshIntersector method checkEdgeMipsParameterValue.
void checkEdgeMipsParameterValue() {
for (HalfEdge edge : myEdgeInfos.keySet()) {
EdgeInfo einfo = myEdgeInfos.get(edge);
Vector3d udir = new Vector3d();
Point3d head = new Point3d();
Point3d tail = new Point3d();
edge.getHead().getWorldPoint(head);
edge.getTail().getWorldPoint(tail);
udir.sub(head, tail);
double ulen = udir.norm();
udir.scale(1 / ulen);
Vector3d r = new Vector3d();
double[] svals = new double[einfo.numMips()];
for (int i = 0; i < einfo.numMips(); i++) {
IntersectionPoint mip = einfo.getMip(i);
r.sub(mip, tail);
double s = r.dot(udir);
if (s < 0) {
s = 0;
} else if (s > ulen) {
s = ulen;
}
svals[i] = s;
}
for (int i = 1; i < einfo.numMips(); i++) {
IntersectionPoint mip = einfo.getMip(i);
if (svals[i] < svals[i - 1] && (einfo.getMip(i).primaryCoincident != einfo.getMip(i - 1).primaryCoincident)) {
System.out.println("MIP s decreasing: " + svals[i - 1] + " vs " + svals[i]);
} else if (svals[i] == svals[i - 1] && (einfo.getMip(i).primaryCoincident != einfo.getMip(i - 1).primaryCoincident)) {
System.out.println("MIP s equal: " + svals[i - 1] + " vs " + svals[i]);
}
}
}
}
use of maspack.collision.IntersectionPoint in project artisynth_core by artisynth.
the class SurfaceMeshIntersector method edgeIntersectingFace.
/*
* Return a HalfEdge of ta Face which intersects the another Face, and
* add the new intersection point to the contour. Return null if no HalfEdge
* of the Face intersects the other Face, or if no intersection point is
* found that can be added to the contour (duplicate points will be rejected,
* or the contour may be full).
*/
public HalfEdge edgeIntersectingFace(Face face, Face otherFace, IntersectionContour contour) {
boolean edgeOnMesh0 = (otherFace.getMesh() == myMesh1);
HalfEdge he0 = face.firstHalfEdge();
HalfEdge he = he0;
do {
if (intersectEdgeFace(he.getPrimary(), otherFace, myWorkPoint, edgeOnMesh0)) {
if (addContourPoint(myWorkPoint, contour)) {
myWorkPoint = new IntersectionPoint();
return he;
}
}
he = he.getNext();
} while (he != he0);
return null;
}
use of maspack.collision.IntersectionPoint in project artisynth_core by artisynth.
the class SurfaceMeshIntersector method markEmptySegMip.
/**
* State transitions as we track points within a face:
*
* Start, on edge (effectiveFace == face)
* off edge
* nothing
* on empty segment
* effectiveFace = segment.opFace
* on full segment
* nothing
*
* On edge (effectiveFace == face)
* off edge
* if (lastp not on lastEdge) {
* check for empty contact and add exit/enter if necessary
* }
* on empty segment
* if (nextEdge == lastEdge) {
* if (lastp on lastEdge) {
* remove lastp from lastEdge;
* }
* else {
* add lastp to lastEdge;
* }
* }
* else { //nextEdge != lastEdge
*
* }
* effectiveFace = segment.opFace
* on full segment
* nothing
*
* Off edge (effectiveFace == face)
* on edge
*
* On empty segment (effectiveFace == segment.opFace)
* off edge
* effectiveFace = face
* on empty segment
* effectiveFace = segment.opFace
* on full segment
* effectiveFace = face
*
* On full segment (effectiveFace == face)
* off edge
* nothing
* on empty segment
* effectiveFace = segment.opFace
* on full segment
* nothing
*/
void markEmptySegMip(IntersectionPoint mip, HalfEdge edge, boolean clockwise) {
Face face = edge.getFace();
PolygonalMesh mesh = (PolygonalMesh) face.getMesh();
int meshNum = (mesh == myMesh0 ? 0 : 1);
EdgeInfo einfo = getEdgeInfo(edge.getPrimary());
if (mip.edge.getHead().getMesh() != mesh) {
boolean tailToHead = (edge == einfo.myEdge);
if (clockwise) {
tailToHead = !clockwise;
}
EdgeInfo.PointData xdata = null;
double s = einfo.project(mip);
double slo = 0;
double shi = einfo.myUlen;
int idx;
if (tailToHead) {
for (idx = 0; idx < einfo.numXips(); idx++) {
shi = einfo.getXipData(idx).s;
if (shi - myPositionTol >= s) {
break;
}
slo = shi;
}
if (idx == einfo.numXips()) {
shi = einfo.myUlen;
}
} else {
for (idx = einfo.numXips() - 1; idx >= 0; idx--) {
slo = einfo.getXipData(idx).s;
if (slo + myPositionTol <= s) {
break;
}
shi = slo;
}
if (idx == -1) {
slo = 0;
}
idx++;
}
if (slo + myPositionTol < s && shi - myPositionTol > s) {
mip.setEmptyMark(meshNum, IntersectionPoint.EMPTY_PROJECTED);
if (useEmptySegmentProjection) {
einfo.addXip(idx, mip, s);
}
}
}
}
Aggregations