Пример #1
0
void testCreateMesh() {
    PolygonalMesh mesh;
    ASSERT(mesh.getNumFaces() == 0);
    ASSERT(mesh.getNumVertices() == 0);
    ASSERT(mesh.addVertex(Vec3(0)) == 0);
    ASSERT(mesh.addVertex(Vec3(0, 1, 0)) == 1);
    ASSERT(mesh.addVertex(Vec3(0, 0, 1)) == 2);
    Array_<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(0);
    ASSERT(mesh.addFace(v) == 0);
    ASSERT(mesh.getNumFaces() == 1);
    ASSERT(mesh.getNumVertices() == 3);
    ASSERT(mesh.getFaceVertex(0, 0) == 1);
    ASSERT(mesh.getFaceVertex(0, 1) == 2);
    ASSERT(mesh.getFaceVertex(0, 2) == 0);
    ASSERT(mesh.getVertexPosition(0) == Vec3(0));
    ASSERT(mesh.getVertexPosition(1) == Vec3(0, 1, 0));
    ASSERT(mesh.getVertexPosition(2) == Vec3(0, 0, 1));

    // Make sure copy and assignment are shallow.
    PolygonalMesh mesh2(mesh); // shallow copy construction
    ASSERT(&mesh2.getImpl() == &mesh.getImpl());
    ASSERT(mesh.getImplHandleCount()==2);

    PolygonalMesh mesh3;
    mesh3 = mesh; // shallow assignment
    ASSERT(&mesh3.getImpl() == &mesh.getImpl());
    ASSERT(mesh.getImplHandleCount()==3);

    PolygonalMesh mesh4;
    mesh4.copyAssign(mesh); // deep copy
    ASSERT(mesh4.getNumVertices() == mesh.getNumVertices());
    ASSERT(&mesh4.getImpl() != &mesh.getImpl());
    ASSERT(mesh4.getImplHandleCount()==1);
    ASSERT(mesh.getImplHandleCount()==3);
}
Пример #2
0
void VisualizerProtocol::drawPolygonalMesh(const PolygonalMesh& mesh, const Transform& X_GM, const Vec3& scale, const Vec4& color, int representation) {
    const void* impl = &mesh.getImpl();
    map<const void*, unsigned short>::const_iterator iter = meshes.find(impl);

    if (iter != meshes.end()) {
        // This mesh was already cached; just reference it by index number.
        drawMesh(X_GM, scale, color, (short)representation, iter->second, 0);
        return;
    }

    // This is a new mesh, so we need to send it to the visualizer. Build lists
    // of vertices and faces, triangulating as necessary.

    vector<float> vertices;
    vector<unsigned short> faces;
    for (int i = 0; i < mesh.getNumVertices(); i++) {
        Vec3 pos = mesh.getVertexPosition(i);
        vertices.push_back((float) pos[0]);
        vertices.push_back((float) pos[1]);
        vertices.push_back((float) pos[2]);
    }
    for (int i = 0; i < mesh.getNumFaces(); i++) {
        int numVert = mesh.getNumVerticesForFace(i);
        if (numVert < 3)
            continue; // Ignore it.
        if (numVert == 3) {
            faces.push_back((unsigned short) mesh.getFaceVertex(i, 0));
            faces.push_back((unsigned short) mesh.getFaceVertex(i, 1));
            faces.push_back((unsigned short) mesh.getFaceVertex(i, 2));
        }
        else if (numVert == 4) {
            // Split it into two triangles.

            faces.push_back((unsigned short) mesh.getFaceVertex(i, 0));
            faces.push_back((unsigned short) mesh.getFaceVertex(i, 1));
            faces.push_back((unsigned short) mesh.getFaceVertex(i, 2));
            faces.push_back((unsigned short) mesh.getFaceVertex(i, 2));
            faces.push_back((unsigned short) mesh.getFaceVertex(i, 3));
            faces.push_back((unsigned short) mesh.getFaceVertex(i, 0));
        }
        else {
            // Add a vertex at the center, then split it into triangles.

            Vec3 center(0);
            for (int j = 0; j < numVert; j++) {
                Vec3 pos = mesh.getVertexPosition(mesh.getFaceVertex(i,j));
                center += pos;
            }
            center /= numVert;
            vertices.push_back((float) center[0]);
            vertices.push_back((float) center[1]);
            vertices.push_back((float) center[2]);
            const unsigned newIndex = (unsigned)(vertices.size()/3-1);
            for (int j = 0; j < numVert-1; j++) {
                faces.push_back((unsigned short) mesh.getFaceVertex(i, j));
                faces.push_back((unsigned short) mesh.getFaceVertex(i, j+1));
                faces.push_back((unsigned short) newIndex);
            }
            // Close the face (thanks, Alexandra Zobova).
            faces.push_back((unsigned short) mesh.getFaceVertex(i, numVert-1));
            faces.push_back((unsigned short) mesh.getFaceVertex(i, 0));
            faces.push_back((unsigned short) newIndex);
        }
    }
    SimTK_ERRCHK1_ALWAYS(vertices.size() <= 65535*3, 
        "VisualizerProtocol::drawPolygonalMesh()",
        "Can't display a DecorativeMesh with more than 65535 vertices;"
        " received one with %llu.", (unsigned long long)vertices.size());
    SimTK_ERRCHK1_ALWAYS(faces.size() <= 65535*3, 
        "VisualizerProtocol::drawPolygonalMesh()",
        "Can't display a DecorativeMesh with more than 65535 vertices;"
        " received one with %llu.", (unsigned long long)faces.size());

    const int index = NumPredefinedMeshes + (int)meshes.size();
    SimTK_ERRCHK_ALWAYS(index <= 65535,
        "VisualizerProtocol::drawPolygonalMesh()",
        "Too many unique DecorativeMesh objects; max is 65535.");
    
    meshes[impl] = (unsigned short)index;    // insert new mesh
    WRITE(outPipe, &DefineMesh, 1);
    unsigned short numVertices = (unsigned short)(vertices.size()/3);
    unsigned short numFaces = (unsigned short)(faces.size()/3);
    WRITE(outPipe, &numVertices, sizeof(short));
    WRITE(outPipe, &numFaces, sizeof(short));
    WRITE(outPipe, &vertices[0], (unsigned)(vertices.size()*sizeof(float)));
    WRITE(outPipe, &faces[0], (unsigned)(faces.size()*sizeof(short)));

    drawMesh(X_GM, scale, color, (short) representation, (unsigned short)index, 0);
}