Search in sources :

Example 26 with PolygonalMesh

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

the class TetGenReader method readFaces.

public static PolygonalMesh readFaces(Vector3d scale, Reader nodeReader, Reader faceReader) throws IOException {
    PolygonalMesh mesh = new PolygonalMesh();
    ReaderTokenizer nodeFile = new ReaderTokenizer(new BufferedReader(nodeReader));
    nodeFile.nextToken();
    nodeFile.nextToken();
    nodeFile.nextToken();
    nodeFile.nextToken();
    while (nodeFile.nextToken() != ReaderTokenizer.TT_EOF) {
        Point3d coords = new Point3d();
        for (int i = 0; i < 3; i++) {
            coords.set(i, nodeFile.scanNumber());
        }
        if (scale != null) {
            coords.x *= scale.x;
            coords.y *= scale.y;
            coords.z *= scale.z;
        }
        mesh.addVertex(coords.x, coords.y, coords.z);
    }
    ReaderTokenizer faceFile = new ReaderTokenizer(new BufferedReader(faceReader));
    faceFile.nextToken();
    faceFile.nextToken();
    while (faceFile.nextToken() != ReaderTokenizer.TT_EOF) {
        Vertex3d[] vtxs = new Vertex3d[3];
        for (int i = 0; i < vtxs.length; i++) {
            vtxs[i] = mesh.getVertices().get(faceFile.scanInteger());
        }
        // discard
        faceFile.scanInteger();
        mesh.addFace(vtxs);
    }
    return mesh;
}
Also used : Vertex3d(maspack.geometry.Vertex3d) Point3d(maspack.matrix.Point3d) ReaderTokenizer(maspack.util.ReaderTokenizer) PolygonalMesh(maspack.geometry.PolygonalMesh)

Example 27 with PolygonalMesh

use of maspack.geometry.PolygonalMesh 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 28 with PolygonalMesh

use of maspack.geometry.PolygonalMesh 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 29 with PolygonalMesh

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

the class FemIntersector method intersectPlane.

/**
 * Intersects a FEM 3d model with a plane, returning a Polygonal mesh
 * on the plane corresponding to inside the FEM
 * @param fem model to intersect with the plane
 * @param plane plane to intersect with
 * @return intersection mesh
 */
public PolygonalMesh intersectPlane(FemModel3d fem, Plane plane) {
    AABBTree aabb = new AABBTree();
    FemElement3d[] elements = fem.getElements().toArray(new FemElement3d[fem.numElements()]);
    aabb.build(elements, fem.numElements());
    ArrayList<BVNode> nodes = new ArrayList<BVNode>();
    aabb.intersectPlane(nodes, plane);
    DirectedGraph<Point3d, Vector3d> nodeGraph = new DirectedGraph<Point3d, Vector3d>();
    TriangleIntersector ti = new TriangleIntersector();
    ti.setEpsilon(epsilon);
    for (BVNode node : nodes) {
        Boundable[] elems = node.getElements();
        for (int i = 0; i < node.getNumElements(); i++) {
            FemElement3d elem = (FemElement3d) elems[i];
            FaceNodes3d[] faceNodes = elem.getFaces();
            for (FaceNodes3d fn : faceNodes) {
                FemNode3d[][] faces = fn.triangulate();
                for (FemNode3d[] face : faces) {
                    addIfUnique(ti.intersectTrianglePlane(face[0].getPosition(), face[1].getPosition(), face[2].getPosition(), plane), nodeGraph, epsilon);
                }
            // end loop through faces
            }
        // end loop through "face nodes"
        }
    // end looping through elements
    }
    // end looping through BVNodes
    // reduceGraph(nodeGraph, tol);
    fixOverlaps(nodeGraph, epsilon);
    PolygonalMesh mesh = buildMesh(nodeGraph, plane.normal);
    removeBackFaces(mesh, plane.normal);
    nonConvexTriangulate(mesh, plane.normal, epsilon);
    return mesh;
}
Also used : ArrayList(java.util.ArrayList) TriangleIntersector(maspack.geometry.TriangleIntersector) PolygonalMesh(maspack.geometry.PolygonalMesh) DirectedGraph(maspack.graph.DirectedGraph) AABBTree(maspack.geometry.AABBTree) Vector3d(maspack.matrix.Vector3d) BVNode(maspack.geometry.BVNode) Point3d(maspack.matrix.Point3d) Boundable(maspack.geometry.Boundable)

Example 30 with PolygonalMesh

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

the class FemIntersector method buildMesh.

private PolygonalMesh buildMesh(DirectedGraph<Point3d, Vector3d> graph, Vector3d normal) {
    PolygonalMesh mesh = new PolygonalMesh();
    LinkedList<DirectedEdge<Point3d, Vector3d>> remainingEdges = new LinkedList<DirectedEdge<Point3d, Vector3d>>(graph.getEdges());
    HashMap<Point3d, Vertex3d> vtxMap = new HashMap<Point3d, Vertex3d>(graph.numVertices());
    for (Vertex<Point3d, Vector3d> v : graph.getVertices()) {
        Vertex3d vtx = mesh.addVertex(v.getData());
        vtxMap.put(v.getData(), vtx);
    }
    while (remainingEdges.size() > 0) {
        DirectedEdge<Point3d, Vector3d> e = remainingEdges.get(0);
        ArrayList<DirectedEdge<Point3d, Vector3d>> face = findFace(e, graph, normal);
        if (face == null) {
            remainingEdges.remove(0);
        } else {
            Vertex3d[] vtxs = new Vertex3d[face.size()];
            int idx = 0;
            for (DirectedEdge<Point3d, Vector3d> edge : face) {
                vtxs[idx++] = vtxMap.get(edge.getVertex(0).getData());
                remainingEdges.remove(edge);
            }
            mesh.addFace(vtxs);
        }
    }
    return mesh;
}
Also used : Vertex3d(maspack.geometry.Vertex3d) HashMap(java.util.HashMap) PolygonalMesh(maspack.geometry.PolygonalMesh) LinkedList(java.util.LinkedList) DirectedEdge(maspack.graph.DirectedEdge) Vector3d(maspack.matrix.Vector3d) Point3d(maspack.matrix.Point3d)

Aggregations

PolygonalMesh (maspack.geometry.PolygonalMesh)128 Point3d (maspack.matrix.Point3d)30 Vertex3d (maspack.geometry.Vertex3d)24 Vector3d (maspack.matrix.Vector3d)23 RigidTransform3d (maspack.matrix.RigidTransform3d)21 IOException (java.io.IOException)18 ArrayList (java.util.ArrayList)18 File (java.io.File)14 Face (maspack.geometry.Face)14 ContactPoint (artisynth.core.mechmodels.ContactPoint)11 Point (artisynth.core.mechmodels.Point)11 PointParticleAttachment (artisynth.core.mechmodels.PointParticleAttachment)10 Color (java.awt.Color)10 MeshBase (maspack.geometry.MeshBase)10 RigidBody (artisynth.core.mechmodels.RigidBody)9 MechModel (artisynth.core.mechmodels.MechModel)8 BufferedReader (java.io.BufferedReader)8 AxisAngle (maspack.matrix.AxisAngle)8 RenderProps (maspack.render.RenderProps)8 HashMap (java.util.HashMap)7