// Create a polygonal mesh for this torus using parameterization as follows: // u = [0, 2*Pi] traces a circle in the x-y plane with radius torusRadius, // which is the centroid of the torus. A point P on this circle is // given by P = torusRadius*~[cos(u) sin(u) 0]. // v = [0, 2*Pi] traces a circle arond the cross-section (or tube) of the // torus with radius tubeRadius, at a given u. A point Q on this circle // is given by Q = (torusRadius + tubeRadius*cos(v))*e1 + tubeRadius*(~[0 0 1]*sin(v)) // where e1 = ~[sin(u) cos(u) 0]. The tube circle is in a plane spanned // by e1 and the z-axis. void ContactGeometry::Torus::Impl::createPolygonalMesh(PolygonalMesh& mesh) const { // TODO add resolution argument const int numSides = 12; //*resolution; const int numSlices = 36; //*resolution; // add vertices for (int i = 0; i < numSlices; ++i) { Real u = Real((i*2*SimTK_PI)/numSlices); UnitVec3 e1(std::sin(u), std::cos(u), 0); // torus circle aligned with z-axis (z-axis through hole) for (int j = 0; j < numSides; ++j) { Real v = Real((j*2*SimTK_PI)/numSides); Vec3 vtx = (torusRadius + tubeRadius*std::cos(v))*e1 + tubeRadius*std::sin(v)*Vec3(0,0,1); // use ZAXIS? mesh.addVertex(vtx); } } // add faces, be careful to wrap indices for the last slice int numVertices = mesh.getNumVertices(); // cout << "num verts = " << numVertices << endl; for (int i = 0; i < numVertices; ++i) { // cout << "v" << i << ": " << mesh.getVertexPosition(i) << endl; // define counter-clockwise quad faces Array_<int> faceIndices; faceIndices.push_back(i); // u_i,v_i faceIndices.push_back((i+1)%numVertices); // u_i, v_i+1 faceIndices.push_back((i+1+numSides)%numVertices); // u_i+1, v_i+1 faceIndices.push_back((i+numSides)%numVertices); // u_i+1, v_i mesh.addFace(faceIndices); } }
void ContactGeometry::TriangleMesh::Impl:: createPolygonalMesh(PolygonalMesh& mesh) const { for (unsigned vx=0; vx < vertices.size(); ++vx) mesh.addVertex(vertices[vx].pos); for (unsigned fx=0; fx < faces.size(); ++fx) { const Face& face = faces[fx]; const ArrayViewConst_<int> verts(face.vertices, face.vertices+3); mesh.addFace(verts); } }
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); }