Search in sources :

Example 11 with Face

use of maspack.geometry.Face in project artisynth_core by artisynth.

the class FemMeshComp method createPointAttachment.

public PointFem3dAttachment createPointAttachment(Point pnt) {
    if (!(getMesh() instanceof PolygonalMesh)) {
        return null;
    }
    PolygonalMesh mesh = (PolygonalMesh) getMesh();
    if (!mesh.isTriangular()) {
        return null;
    }
    // Find nearest face to the point. The vertices of this face will be used
    // to find the nodes and weight for the attachment.
    BVFeatureQuery query = new BVFeatureQuery();
    Point3d near = new Point3d();
    Vector2d uv = new Vector2d();
    Face face = query.nearestFaceToPoint(near, uv, mesh, pnt.getPosition());
    Vertex3d[] vtxs = face.getTriVertices();
    double[] wgts = new double[] { 1 - uv.x - uv.y, uv.x, uv.y };
    HashMap<FemNode, Double> nodeWeights = new HashMap<FemNode, Double>();
    for (int i = 0; i < vtxs.length; i++) {
        PointAttachment va = myVertexAttachments.get(vtxs[i].getIndex());
        if (va instanceof PointParticleAttachment) {
            PointParticleAttachment ppa = (PointParticleAttachment) va;
            FemNode node = (FemNode) ppa.getParticle();
            accumulateNodeWeights(node, wgts[i], nodeWeights);
        } else if (va instanceof PointFem3dAttachment) {
            PointFem3dAttachment pfa = (PointFem3dAttachment) va;
            for (int k = 0; k < pfa.numMasters(); k++) {
                FemNode node = pfa.getNodes()[k];
                double w = pfa.getCoordinate(k);
                accumulateNodeWeights(node, w * wgts[i], nodeWeights);
            }
        }
    }
    // Create a new PointFem3dAttachment
    PointFem3dAttachment ax = new PointFem3dAttachment(pnt);
    VectorNd weightVec = new VectorNd();
    for (Double d : nodeWeights.values()) {
        weightVec.append(d);
    }
    ax.setFromNodes(nodeWeights.keySet(), weightVec);
    return ax;
}
Also used : Vertex3d(maspack.geometry.Vertex3d) HashMap(java.util.HashMap) PointAttachment(artisynth.core.mechmodels.PointAttachment) PolygonalMesh(maspack.geometry.PolygonalMesh) BVFeatureQuery(maspack.geometry.BVFeatureQuery) ContactPoint(artisynth.core.mechmodels.ContactPoint) Point(artisynth.core.mechmodels.Point) Vector2d(maspack.matrix.Vector2d) Point3d(maspack.matrix.Point3d) VectorNd(maspack.matrix.VectorNd) Face(maspack.geometry.Face) PointParticleAttachment(artisynth.core.mechmodels.PointParticleAttachment)

Example 12 with Face

use of maspack.geometry.Face in project artisynth_core by artisynth.

the class FemMeshComp method createSurface.

// Throwable throwable = null;
public void createSurface(Collection<FemElement3d> elems) {
    initializeSurfaceBuild();
    // nodeVertexMap is used during the construction of this surface,
    // so we build it during the construction rather then letting
    // it be built in finalizeSurfaceBuild()
    myNodeVertexMap = new HashMap<FemNode3d, Vertex3d>();
    myNumSingleAttachments = 0;
    LinkedList<FaceNodes3d> allFaces = new LinkedList<FaceNodes3d>();
    // faces adjacent to each node
    ArrayList<LinkedList<FaceNodes3d>> nodeFaces = new ArrayList<LinkedList<FaceNodes3d>>(myFem.numNodes());
    for (int i = 0; i < myFem.numNodes(); i++) {
        nodeFaces.add(new LinkedList<FaceNodes3d>());
    }
    PointList<FemNode3d> femNodes = myFem.getNodes();
    // each node, create a list of all the faces it is associated with
    for (FemElement3d e : elems) {
        FaceNodes3d[] faces = e.getFaces();
        for (FaceNodes3d f : faces) {
            addEdgeNodesToFace(f, myFem);
            for (FemNode3d n : f.getAllNodes()) {
                int idx = femNodes.indexOf(n);
                if (idx == -1) {
                    throw new InternalErrorException("Element " + e.getNumber() + ": bad node " + n.getNumber());
                }
                nodeFaces.get(femNodes.indexOf(n)).add(f);
            }
            allFaces.add(f);
        }
    }
    // now for each face, check to see if it is overlapping with other faces
    HashSet<FaceNodes3d> adjacentFaces = new HashSet<FaceNodes3d>();
    for (FaceNodes3d f : allFaces) {
        if (!f.isHidden()) {
            adjacentFaces.clear();
            for (FemNode3d n : f.getAllNodes()) {
                Iterator<FaceNodes3d> it = nodeFaces.get(femNodes.indexOf(n)).iterator();
                while (it.hasNext()) {
                    FaceNodes3d g = it.next();
                    if (g.isHidden()) {
                        it.remove();
                    } else if (g.getElement() != f.getElement()) {
                        adjacentFaces.add(g);
                    }
                }
            }
            for (FaceNodes3d g : adjacentFaces) {
                if (f.isContained(g)) {
                    f.setHidden(true);
                    g.setOverlapping(true);
                }
                if (g.isContained(f)) {
                    g.setHidden(true);
                    f.setOverlapping(true);
                }
            }
        }
    }
    int num = 0;
    for (FaceNodes3d f : allFaces) {
        if (!f.isOverlapping() && !f.isSelfAttachedToFace()) {
            num++;
        }
    }
    // form the surface mesh from the non-overlapping faces
    PolygonalMesh mesh = (PolygonalMesh) getMesh();
    for (FaceNodes3d f : allFaces) {
        if (!f.isOverlapping() && !f.hasSelfAttachedNode() && !f.isSelfAttachedToFace()) {
            FemNode3d[][] triangles = f.triangulate();
            boolean triangulatedQuad = (triangles.length == 2 && triangles[0][0] == triangles[1][0]);
            for (int i = 0; i < triangles.length; i++) {
                FemNode3d[] tri = triangles[i];
                Vertex3d[] vtxs = new Vertex3d[3];
                for (int j = 0; j < 3; j++) {
                    FemNode3d node = tri[j];
                    if ((vtxs[j] = myNodeVertexMap.get(node)) == null) {
                        Vertex3d vtx = new Vertex3d(new Point3d(node.getPosition()));
                        mesh.addVertex(vtx);
                        myVertexAttachments.add(new PointParticleAttachment(node, null));
                        myNumSingleAttachments++;
                        myNodeVertexMap.put(node, vtx);
                        vtxs[j] = vtx;
                    }
                }
                Face face = mesh.addFace(vtxs);
                if (triangulatedQuad && i == 0) {
                    face.setFirstQuadTriangle(true);
                }
            }
        }
    }
    finalizeSurfaceBuild();
// throwable = null;
}
Also used : Vertex3d(maspack.geometry.Vertex3d) ArrayList(java.util.ArrayList) InternalErrorException(maspack.util.InternalErrorException) PolygonalMesh(maspack.geometry.PolygonalMesh) LinkedList(java.util.LinkedList) ContactPoint(artisynth.core.mechmodels.ContactPoint) Point(artisynth.core.mechmodels.Point) Point3d(maspack.matrix.Point3d) Face(maspack.geometry.Face) PointParticleAttachment(artisynth.core.mechmodels.PointParticleAttachment) HashSet(java.util.HashSet)

Example 13 with Face

use of maspack.geometry.Face in project artisynth_core by artisynth.

the class FemIntersector method makeConvexFace.

// ear splitting technique
protected static void makeConvexFace(PolygonalMesh mesh, Face face, Vector3d normal, double tol) {
    if (face.isTriangle()) {
        return;
    }
    Vector3d v1 = new Vector3d();
    Vector3d v2 = new Vector3d();
    Vertex3d[] vtxs = face.getVertices();
    for (int i = 0; i < vtxs.length; i++) {
        Vertex3d vm1 = vtxs[(i + vtxs.length - 1) % vtxs.length];
        Vertex3d v0 = vtxs[i];
        Vertex3d vp1 = vtxs[(i + 1) % vtxs.length];
        v1.sub(v0.getWorldPoint(), vm1.getWorldPoint());
        v2.sub(vp1.getWorldPoint(), v0.getWorldPoint());
        double ang = getAngle(1, v1, 1, v2, normal);
        if (ang > -tol) {
            for (int j = 1; j < vtxs.length - 1; j++) {
                vp1 = vtxs[(i + j + 1) % vtxs.length];
                v2.sub(vp1.getWorldPoint(), v0.getWorldPoint());
                ang = getAngle(1, v1, 1, v2, normal);
                if (ang < -tol) {
                    // XXX check that doesn't intersect any edges?
                    Vertex3d[] f1 = new Vertex3d[j + 2];
                    Vertex3d[] f2 = new Vertex3d[vtxs.length - j];
                    for (int k = 0; k < f1.length; k++) {
                        f1[k] = vtxs[(i + k) % vtxs.length];
                    }
                    for (int k = 0; k < f2.length - 2; k++) {
                        f2[k] = vtxs[(i + k + f1.length) % vtxs.length];
                    }
                    f2[f2.length - 2] = v0;
                    f2[f2.length - 1] = f1[f1.length - 1];
                    mesh.removeFace(face);
                    Face face1 = mesh.addFace(f1);
                    Face face2 = mesh.addFace(f2);
                    makeConvexFace(mesh, face1, normal, tol);
                    makeConvexFace(mesh, face2, normal, tol);
                    return;
                }
            }
        }
    }
}
Also used : Vertex3d(maspack.geometry.Vertex3d) Vector3d(maspack.matrix.Vector3d) Face(maspack.geometry.Face)

Example 14 with Face

use of maspack.geometry.Face in project artisynth_core by artisynth.

the class Cell method writeVTK.

public static void writeVTK(String filename, PolygonalMesh mesh, ArrayList<String> pointData_scalar_names, ArrayList<double[]> pointData_scalar_data, ArrayList<String> pointData_vector_names, ArrayList<ArrayList<double[]>> pointData_vector_data, ArrayList<String> cellData_scalar_names, ArrayList<double[]> cellData_scalar_data, ArrayList<String> cellData_vector_names, ArrayList<ArrayList<double[]>> cellData_vector_data) {
    // this writes a surface geometry
    int nPoints = mesh.numVertices();
    int nCells = mesh.numFaces();
    try {
        PrintWriter file = new PrintWriter(new BufferedWriter(new FileWriter(filename, false)));
        // header
        file.println("# vtk DataFile Version 3.0");
        // title
        file.println("SurfaceMesh");
        // data type: ASCII or BINARY
        file.println("ASCII");
        // dataset type: STRUCTURED_POINTS, STRUCTURED_GRID, UNSTRUCTURED_GRID, POLYDATA, RECTILINEAR_GRID,  FIELD
        file.println("DATASET POLYDATA");
        // write points
        file.println();
        file.printf("POINTS %d float\n", nPoints);
        for (Vertex3d v : mesh.getVertices()) {
            Point3d p = v.getPosition();
            file.printf("%f %f %f\n", p.x, p.y, p.z);
        }
        // write cells
        int nCellPoints = 0;
        for (Face f : mesh.getFaces()) nCellPoints = nCellPoints + f.getVertexIndices().length;
        file.println();
        file.printf("POLYGONS %d %d\n", nCells, nCellPoints + nCells);
        for (Face f : mesh.getFaces()) {
            int[] indices = f.getVertexIndices();
            int nInd = indices.length;
            file.printf("%d", nInd);
            for (int a = 0; a < nInd; a++) file.printf(" %d", indices[a]);
            file.println();
        }
        // write point data
        writePointData(file, nPoints, pointData_scalar_names, pointData_scalar_data, pointData_vector_names, pointData_vector_data);
        // write cell data
        writeCellData(file, nCells, cellData_scalar_names, cellData_scalar_data, cellData_vector_names, cellData_vector_data);
        // file.flush();
        file.close();
    } catch (Exception e) {
    }
}
Also used : Vertex3d(maspack.geometry.Vertex3d) Point3d(maspack.matrix.Point3d) Face(maspack.geometry.Face)

Example 15 with Face

use of maspack.geometry.Face in project artisynth_core by artisynth.

the class CollisionRenderer method createPenetrationRenderObject.

RenderObject createPenetrationRenderObject(CollisionHandler handler, ArrayList<PenetratingPoint> points, ArrayList<PenetrationRegion> regions) {
    RenderObject rd = new RenderObject();
    HashMap<Vertex3d, Double> depthMap = new HashMap<Vertex3d, Double>();
    double maxd = 0;
    for (PenetratingPoint pp : points) {
        depthMap.put(pp.vertex, pp.distance);
        if (pp.distance > maxd) {
            maxd = pp.distance;
        }
    }
    ScalarRange range = handler.myBehavior.myPenetrationDepthRange;
    range.updateInterval(0, maxd);
    float[] rgb = new float[3];
    for (int i = 0; i < 256; i++) {
        handler.myManager.myColorMap.getRGB(i / 255.0, rgb);
        rd.addColor(rgb);
    }
    Point3d wpnt = new Point3d();
    Vector3d wnrm = new Vector3d();
    for (PenetrationRegion region : regions) {
        for (Face face : region.getFaces()) {
            HalfEdge he = face.firstHalfEdge();
            Vertex3d v0 = he.getHead();
            Vertex3d v1 = he.getNext().getHead();
            Vertex3d v2 = he.getTail();
            v0.getWorldPoint(wpnt);
            int pi0 = rd.addPosition(wpnt);
            v1.getWorldPoint(wpnt);
            int pi1 = rd.addPosition(wpnt);
            v2.getWorldPoint(wpnt);
            int pi2 = rd.addPosition(wpnt);
            int ci0 = getColorIndex(range, v0, depthMap);
            int ci1 = getColorIndex(range, v1, depthMap);
            int ci2 = getColorIndex(range, v2, depthMap);
            face.getWorldNormal(wnrm);
            int ni = rd.addNormal(wnrm);
            int v0idx = rd.addVertex(pi0, ni, ci0, -1);
            int v1idx = rd.addVertex(pi1, ni, ci1, -1);
            int v2idx = rd.addVertex(pi2, ni, ci2, -1);
            rd.addTriangle(v0idx, v1idx, v2idx);
        }
    }
    return rd;
}
Also used : Vertex3d(maspack.geometry.Vertex3d) HashMap(java.util.HashMap) HalfEdge(maspack.geometry.HalfEdge) IntersectionPoint(maspack.collision.IntersectionPoint) PenetratingPoint(maspack.collision.PenetratingPoint) PenetratingPoint(maspack.collision.PenetratingPoint) Vector3d(maspack.matrix.Vector3d) Point3d(maspack.matrix.Point3d) RenderObject(maspack.render.RenderObject) Face(maspack.geometry.Face) PenetrationRegion(maspack.collision.PenetrationRegion) ScalarRange(artisynth.core.util.ScalarRange)

Aggregations

Face (maspack.geometry.Face)49 Vertex3d (maspack.geometry.Vertex3d)30 Point3d (maspack.matrix.Point3d)25 Vector3d (maspack.matrix.Vector3d)20 HalfEdge (maspack.geometry.HalfEdge)16 PolygonalMesh (maspack.geometry.PolygonalMesh)14 ArrayList (java.util.ArrayList)11 Vector2d (maspack.matrix.Vector2d)9 ContactPoint (artisynth.core.mechmodels.ContactPoint)7 Point (artisynth.core.mechmodels.Point)7 HashMap (java.util.HashMap)7 BVFeatureQuery (maspack.geometry.BVFeatureQuery)6 PointParticleAttachment (artisynth.core.mechmodels.PointParticleAttachment)5 IntersectionPoint (maspack.collision.IntersectionPoint)5 BufferedWriter (java.io.BufferedWriter)4 OutputStreamWriter (java.io.OutputStreamWriter)4 PrintWriter (java.io.PrintWriter)4 DistanceGrid (maspack.geometry.DistanceGrid)4 PointAttachment (artisynth.core.mechmodels.PointAttachment)3 PenetratingPoint (maspack.collision.PenetratingPoint)3