Search in sources :

Example 31 with IntersectionPoint

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);
}
Also used : IntersectionPoint(maspack.collision.IntersectionPoint) IntersectionPoint(maspack.collision.IntersectionPoint)

Example 32 with IntersectionPoint

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;
        }
    }
}
Also used : IntersectionPoint(maspack.collision.IntersectionPoint) IntersectionPoint(maspack.collision.IntersectionPoint)

Example 33 with IntersectionPoint

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]);
            }
        }
    }
}
Also used : IntersectionPoint(maspack.collision.IntersectionPoint) IntersectionPoint(maspack.collision.IntersectionPoint)

Example 34 with IntersectionPoint

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;
}
Also used : IntersectionPoint(maspack.collision.IntersectionPoint)

Example 35 with IntersectionPoint

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);
            }
        }
    }
}
Also used : IntersectionPoint(maspack.collision.IntersectionPoint)

Aggregations

IntersectionPoint (maspack.collision.IntersectionPoint)40 IntersectionContour (maspack.collision.IntersectionContour)3 HalfEdge (maspack.geometry.HalfEdge)3 ContactInfo (maspack.collision.ContactInfo)2 PenetratingPoint (maspack.collision.PenetratingPoint)2 BVNode (maspack.geometry.BVNode)2 Face (maspack.geometry.Face)2 Point3d (maspack.matrix.Point3d)2 Group (artisynth.core.mechmodels.Collidable.Group)1 Method (artisynth.core.mechmodels.CollisionBehavior.Method)1 ArrayList (java.util.ArrayList)1 ContactPlane (maspack.collision.ContactPlane)1 EdgeEdgeContact (maspack.collision.EdgeEdgeContact)1 PenetrationRegion (maspack.collision.PenetrationRegion)1 BVTree (maspack.geometry.BVTree)1 Boundable (maspack.geometry.Boundable)1 TriTriIntersection (maspack.geometry.TriTriIntersection)1 Vertex3d (maspack.geometry.Vertex3d)1 RenderObject (maspack.render.RenderObject)1 BooleanHolder (maspack.util.BooleanHolder)1