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); }
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); }