Search in sources :

Example 16 with IntersectionPoint

use of maspack.collision.IntersectionPoint in project artisynth_core by artisynth.

the class SurfaceMeshIntersector method findIntersectionContour.

/*
    * Given a Face and a HalfEdge from two PolygonalMeshes that intersect at an
    * initial MeshIntersectionPoint, trace their intersection contour. Return a
    * MeshIntersectionContour of MeshIntersectionPoints. Stop tracing when: -
    * the contour is closed, - a duplicate intersection point is encountered -
    * the maximum number of points (maxContourPoints) is exceeded, or - the edge
    * of the mesh surface is encountered.
    */
private IntersectionContour findIntersectionContour(HalfEdge edge, Face f, boolean edgeOnMesh0) {
    IntersectionContour contour = new IntersectionContour();
    IntersectionPoint mip = myWorkPoint;
    if (!addContourPoint(myWorkPoint, contour)) {
        // May be rejected if it's a duplicate intersection.
        return null;
    }
    myWorkPoint = new IntersectionPoint();
    // There are two possible directions to trace. First choose the one
    // associated with this half edge.
    Face edgeFace = mip.edge.getFace();
    if (edgeFace != null) {
        traceIntersectionContour(contour, edgeFace, edgeOnMesh0);
    }
    if (traceContourDebug) {
        System.out.println("isContinuable=" + contour.isContinuable);
        System.out.println("isClosed=" + contour.isClosed());
    }
    if (contour.isContinuable) {
        // The contour encountered a mesh edge and is open. Continue the trace
        // in the opposite direction.
        HalfEdge opposite = mip.edge.opposite;
        if (opposite != null) {
            edgeFace = opposite.getFace();
            if (edgeFace != null) {
                contour.reverse();
                traceIntersectionContour(contour, edgeFace, edgeOnMesh0);
            }
        }
    }
    if (contour.size() == 1) {
        if (traceContourDebug) {
            System.out.println("single point or coincident contour");
        }
        removeContourPoint(contour.get(0));
        return null;
    }
    return contour;
}
Also used : IntersectionPoint(maspack.collision.IntersectionPoint)

Example 17 with IntersectionPoint

use of maspack.collision.IntersectionPoint in project artisynth_core by artisynth.

the class SurfaceMeshIntersector method differentEdgeIntersectingFace.

/*
    * Return a HalfEdge of a Face which intersects 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). If excludeEdge is specified: - excludeEdge
    * must be a HalfEdge of the Face - only test the other two HalfEdges of
    * this Face for intersection, and return null if neither intersect.
    */
private HalfEdge differentEdgeIntersectingFace(Face face, Face otherFace, HalfEdge excludeEdge, IntersectionContour contour) {
    HalfEdge he0 = face.firstHalfEdge();
    boolean edgeOnMesh0 = (otherFace.getMesh() == myMesh1);
    HalfEdge he = he0;
    do {
        if (he != excludeEdge & he != excludeEdge.opposite) {
            if (intersectEdgeFace(he.getPrimary(), otherFace, myWorkPoint, edgeOnMesh0)) {
                if (addContourPoint(myWorkPoint, contour)) {
                    Point3d wpnt = new Point3d();
                    if (debug2) {
                        wpnt.set(myWorkPoint);
                        if (debugTBW != null) {
                        }
                    }
                    myWorkPoint = new IntersectionPoint();
                    return he;
                }
            }
        }
        he = he.getNext();
    } while (he != he0);
    return null;
}
Also used : IntersectionPoint(maspack.collision.IntersectionPoint)

Example 18 with IntersectionPoint

use of maspack.collision.IntersectionPoint in project artisynth_core by artisynth.

the class SurfaceMeshIntersector method findPenetrationRegion.

/**
 * Finds the penetration region on <code>mesh0</code> that is associated
 * with a single specific contour. As the region is traversed, other
 * contours may be found to be associated with it; these may be determined
 * by querying the {@link PenetrationRegion#getContours} method for the
 * returned region.
 *
 * @param contour contour
 * @param mesh0 mesh on which the region resides
 * @param mesh1 other mesh which is intersecting <code>mesh0</code>
 * @param clockwise <code>true</code> if intersection contours are
 * oriented clockwise with respect to <code>mesh0</code>
 * @return penetration region associated with <code>contour</code>
 */
PenetrationRegion findPenetrationRegion(IntersectionContour contour, PolygonalMesh mesh0, PolygonalMesh mesh1, boolean clockwise) {
    PenetrationRegion region = new PenetrationRegion(mesh0, clockwise, myPositionTol);
    Deque<IntersectionContour> contoursToTrace = new ArrayDeque<IntersectionContour>();
    region.myContours.add(contour);
    contoursToTrace.offerLast(contour);
    Deque<Vertex3d> verticesToTrace = new ArrayDeque<Vertex3d>();
    FaceCalculator[] faceCalcs = (mesh0 == myMesh0 ? myFaceCalcs0 : myFaceCalcs1);
    boolean[] visitedFaces = new boolean[mesh0.numFaces()];
    IntersectionContour c;
    while ((c = contoursToTrace.pollFirst()) != null) {
        // (getContourIndex(c) == 0 && mesh0 == myMesh0);
        boolean debug = false;
        int kenter = c.getFirstFaceEntryIndex(mesh0, /*face=*/
        null);
        if (kenter == -1) {
            // contour is not open and is confined to a single face
            // region.myInsideFaces.add (lastFace);
            Face face = c.findSegmentFace(0, mesh0);
            region.mySingleFace = face;
            c.containingFace = face;
            FaceCalculator fcalc = getFaceCalculator(face, faceCalcs);
            fcalc.setContour(c);
            if (!visitedFaces[face.getIndex()]) {
                visitedFaces[face.getIndex()] = true;
                fcalc.outsideArea = 0;
            }
            for (int i = 0; i < c.size(); i++) {
                IntersectionPoint pa = c.get(i);
                IntersectionPoint pb = c.getWrapped(i + 1);
                fcalc.addOutsideArea(pa, pb, clockwise);
            }
            region.mySingleFaceArea = -fcalc.outsideArea;
            c.singleFaceArea = region.mySingleFaceArea;
            if (fcalc.outsideArea <= 0) {
                fcalc.outsideArea += face.computeArea();
            }
        } else {
            // Go along the contour, looking for face transitions. At each
            // transition, examine the associated edge for adjacent vertices or
            // contours.
            // point where the contour enters
            IntersectionPoint pentry = null;
            // a face
            FaceCalculator fcalc = null;
            Face lastFace = c.findSegmentFace(kenter - 1, mesh0);
            int k = kenter;
            for (int i = 0; i < c.size(); i++) {
                IntersectionPoint pa = c.getWrapped(k);
                IntersectionPoint pb = c.getWrapped(k + 1);
                Face face = c.findSegmentFace(k, mesh0);
                if (lastFace != face) {
                    boolean headInsideFace;
                    HalfEdge faceEdge;
                    if (face != null) {
                        // we are leaving lastFace and entering face
                        // region.myInsideFaces.add (face);
                        faceEdge = getPointEdge(pa, face);
                        pentry = pa;
                        fcalc = getFaceCalculator(face, faceCalcs);
                        if (fcalc.contour != c) {
                            fcalc.setContour(c);
                        }
                        if (!visitedFaces[face.getIndex()]) {
                            visitedFaces[face.getIndex()] = true;
                            fcalc.outsideArea = 0;
                        }
                        headInsideFace = clockwise;
                    } else {
                        // Last point of an open contour. Choose faceEdge using
                        // lastFace
                        faceEdge = getPointEdge(pa, lastFace);
                        headInsideFace = !clockwise;
                    }
                    Vertex3d insideVtx;
                    if (headInsideFace) {
                        insideVtx = faceEdge.getHead();
                    } else {
                        insideVtx = faceEdge.getTail();
                    }
                    EdgeInfo einfo = myEdgeInfos.get(faceEdge.getPrimary());
                    if (einfo != null && einfo.indexOfMip(pa) != -1) {
                        region.myEdges.add(faceEdge.getPrimary());
                        if (debug)
                            debugMipEdge = faceEdge.vertexStr();
                        IntersectionPoint insideMip = nearestInsideMip(pa, faceEdge, insideVtx, mesh0);
                        if (debug) {
                            // DBG
                            debugMipEdge = "";
                            System.out.println(" insideMip=" + insideMip);
                        }
                        if (insideMip == null) {
                            if (region.myVertices.add(insideVtx)) {
                                verticesToTrace.offerLast(insideVtx);
                            }
                        } else {
                            String rname = getRegionName(region);
                            if (region.myContours.add(insideMip.contour)) {
                                if (regionAddingDebug) {
                                    System.out.println("added " + getContourIndex(insideMip.contour) + " to " + rname);
                                }
                                contoursToTrace.offerLast(insideMip.contour);
                            }
                        }
                    }
                }
                if (face != null) {
                    fcalc.addOutsideArea(pa, pb, clockwise);
                    Face nextFace = c.findSegmentFace(k + 1, mesh0);
                    if (nextFace != face) {
                        // exiting face
                        // compute area contribution for face boundary from exit to
                        // entry
                        fcalc.addBoundaryArea(pb, pentry, clockwise);
                    }
                }
                lastFace = face;
                k = c.getWrappedIndex(k + 1);
            }
        }
        Vertex3d vtx;
        while ((vtx = verticesToTrace.pollFirst()) != null) {
            Iterator<HalfEdge> incidentEdges = vtx.getIncidentHalfEdges();
            while (incidentEdges.hasNext()) {
                HalfEdge edge = incidentEdges.next().getPrimary();
                if (region.myEdges.add(edge)) {
                    visitedFaces[edge.getFace().getIndex()] = true;
                    if (edge.opposite != null) {
                        visitedFaces[edge.opposite.getFace().getIndex()] = true;
                    }
                    Vertex3d v = edge.head;
                    if (v == vtx) {
                        v = edge.tail;
                    }
                    IntersectionPoint mip = nearestMipToVertex(edge, vtx, mesh0);
                    if (mip != null) {
                        String rname = getRegionName(region);
                        if (region.myContours.add(mip.contour)) {
                            if (regionAddingDebug) {
                                System.out.println("added (v) " + getContourIndex(mip.contour) + " to " + rname);
                            }
                            contoursToTrace.offerLast(mip.contour);
                        }
                    } else {
                        if (region.myVertices.add(v)) {
                            verticesToTrace.offerLast(v);
                        }
                    }
                }
            }
        }
    }
    double regionArea = 0;
    for (int i = 0; i < visitedFaces.length; i++) {
        // for (FaceCalculator fcalc : faceCalcMap.values()) {
        if (visitedFaces[i]) {
            Face face = mesh0.getFace(i);
            double insideArea = face.computeArea();
            FaceCalculator fcalc = faceCalcs[i];
            if (fcalc != null) {
                insideArea = face.computeArea() - fcalc.outsideArea;
                fcalc.outsideArea = 0;
            }
            regionArea += insideArea;
            double atol = (removeZeroAreaFaces ? myAreaTol : 0);
            if (insideArea >= atol) {
                region.myFaces.add(face);
            }
        }
    }
    region.setArea(regionArea);
    return region;
}
Also used : IntersectionPoint(maspack.collision.IntersectionPoint) IntersectionPoint(maspack.collision.IntersectionPoint)

Example 19 with IntersectionPoint

use of maspack.collision.IntersectionPoint in project artisynth_core by artisynth.

the class SurfaceMeshIntersector method createPolyFromContour.

Vertex3dList createPolyFromContour(IntersectionContour contour) {
    Vertex3dList poly = new Vertex3dList(/*closed=*/
    true);
    Vertex3d curVtx = null;
    IntersectionPoint mip = contour.get(0);
    if (contour.isClosed()) {
        // back up until previous mip has a different vertex
        IntersectionPoint prev = mip.prev();
        if (prev.myVertex == mip.myVertex) {
            IntersectionPoint mip0 = contour.get(0);
            do {
                mip = prev;
                prev = mip.prev();
            } while (prev.myVertex == mip.myVertex && mip != mip0);
        }
    }
    for (int i = 0; i < contour.size(); i++) {
        if (mip.myVertex != curVtx) {
            curVtx = mip.myVertex;
            poly.add(curVtx);
        }
        mip = mip.next();
    }
    return poly;
}
Also used : IntersectionPoint(maspack.collision.IntersectionPoint) IntersectionPoint(maspack.collision.IntersectionPoint)

Example 20 with IntersectionPoint

use of maspack.collision.IntersectionPoint in project artisynth_core by artisynth.

the class CollisionRenderer method prerender.

public void prerender(CollisionHandler handler, RenderProps props) {
    RenderObject ro = new RenderObject();
    ro.clearAll();
    // constraints
    ro.createLineGroup();
    // segments
    ro.createLineGroup();
    // contours
    ro.createLineGroup();
    // contact info
    ro.createPointGroup();
    // intersection faces
    ro.createTriangleGroup();
    // create default dummy normal
    ro.addNormal(0, 0, 0);
    CollisionBehavior behav = handler.myBehavior;
    ContactInfo cinfo = handler.getLastContactInfo();
    if (behav.myDrawConstraints) {
        ro.lineGroup(CONSTRAINT_GRP);
        double nrmlLen = handler.getContactNormalLen();
        if (nrmlLen > 0) {
            addConstraintRenderInfo(ro, handler.myBilaterals0.values(), nrmlLen);
            addConstraintRenderInfo(ro, handler.myBilaterals1.values(), nrmlLen);
            addConstraintRenderInfo(ro, handler.myUnilaterals, nrmlLen);
        }
    }
    double normalLen = 0;
    if (behav.getDrawContactNormals()) {
        normalLen = handler.getContactNormalLen();
    }
    if (normalLen != 0 && cinfo != null) {
        ro.lineGroup(SEGMENT_GRP);
        Method method = handler.getMethod();
        if (method == Method.CONTOUR_REGION) {
            int numc = 0;
            for (ContactPlane region : cinfo.getContactPlanes()) {
                for (Point3d p : region.points) {
                    if (numc >= handler.myMaxUnilaterals) {
                        break;
                    }
                    addLineSeg(ro, p, region.normal, normalLen);
                }
            }
        } else if (method != Method.INACTIVE) {
            for (ContactConstraint cc : handler.myBilaterals0.values()) {
                maybeAddVertexFaceNormal(ro, cc, normalLen);
            }
            for (ContactConstraint cc : handler.myBilaterals1.values()) {
                maybeAddVertexFaceNormal(ro, cc, normalLen);
            }
        }
    }
    if (behav.myDrawIntersectionContours && props.getEdgeWidth() > 0 && cinfo != null) {
        ro.lineGroup(CONTOUR_GRP);
        // offset lines
        if (cinfo.getContours() != null) {
            for (IntersectionContour contour : cinfo.getContours()) {
                int vidx0 = ro.numVertices();
                for (IntersectionPoint p : contour) {
                    ro.addVertex(ro.addPosition((float) p.x, (float) p.y, (float) p.z));
                }
                int vidx1 = ro.numVertices() - 1;
                ro.addLineLoop(vidx0, vidx1);
            }
        } else if (cinfo.getIntersections() != null) {
            // use intersections to render lines
            for (TriTriIntersection tsect : cinfo.getIntersections()) {
                addLineSeg(ro, tsect.points[0], tsect.points[1]);
            }
        }
    }
    if (behav.myDrawIntersectionPoints && cinfo != null) {
        if (cinfo.getIntersections() != null) {
            for (TriTriIntersection tsect : cinfo.getIntersections()) {
                for (Point3d pnt : tsect.points) {
                    addPoint(ro, pnt);
                }
            }
        }
        for (PenetratingPoint cpp : cinfo.getPenetratingPoints(0)) {
            if (cpp.distance > 0) {
                addPoint(ro, cpp.vertex.getWorldPoint());
            }
        }
        for (PenetratingPoint cpp : cinfo.getPenetratingPoints(1)) {
            if (cpp.distance > 0) {
                addPoint(ro, cpp.vertex.getWorldPoint());
            }
        }
        if (behav.getMethod() == CollisionBehavior.Method.VERTEX_EDGE_PENETRATION) {
            if (cinfo.getEdgeEdgeContacts() != null) {
                for (EdgeEdgeContact eec : cinfo.getEdgeEdgeContacts()) {
                    addPoint(ro, eec.point0);
                    addPoint(ro, eec.point1);
                }
            }
        }
    }
    if (behav.myDrawIntersectionFaces && cinfo != null) {
        ArrayList<TriTriIntersection> intersections = cinfo.getIntersections();
        if (intersections != null) {
            buildFaceSegments(ro, handler, intersections);
        }
    }
    RenderObject oldRob = myRob;
    myRob = ro;
    // if (oldRob != null) {
    // oldRob.dispose();
    // }
    RenderObject rd = null;
    if (behav.myDrawPenetrationDepth != -1 && cinfo != null) {
        int num = behav.myDrawPenetrationDepth;
        Collidable b0 = behav.getCollidable(0);
        CollidableBody h0 = handler.getCollidable(0);
        if (!(b0 instanceof Group)) {
            if (h0 != b0 && h0.getCollidableAncestor() != b0) {
                // then we want the *other* collidable body, so switch num
                num = (num == 0 ? 1 : 0);
            }
        }
        ArrayList<PenetrationRegion> regions;
        ArrayList<PenetratingPoint> points;
        if (num == 0) {
            regions = cinfo.getRegions(0);
            points = cinfo.getPenetratingPoints(0);
        } else {
            regions = cinfo.getRegions(1);
            points = cinfo.getPenetratingPoints(1);
        }
        if (regions != null && regions.size() > 0) {
            rd = createPenetrationRenderObject(handler, points, regions);
        }
    }
    oldRob = myDepthRob;
    myDepthRob = rd;
// if (oldRob != null) {
// oldRob.dispose();
// }
}
Also used : Group(artisynth.core.mechmodels.Collidable.Group) ContactPlane(maspack.collision.ContactPlane) TriTriIntersection(maspack.geometry.TriTriIntersection) Method(artisynth.core.mechmodels.CollisionBehavior.Method) IntersectionPoint(maspack.collision.IntersectionPoint) PenetratingPoint(maspack.collision.PenetratingPoint) EdgeEdgeContact(maspack.collision.EdgeEdgeContact) IntersectionContour(maspack.collision.IntersectionContour) PenetratingPoint(maspack.collision.PenetratingPoint) IntersectionPoint(maspack.collision.IntersectionPoint) Point3d(maspack.matrix.Point3d) ContactInfo(maspack.collision.ContactInfo) RenderObject(maspack.render.RenderObject) PenetrationRegion(maspack.collision.PenetrationRegion)

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