void MeshMassPropertiesTests::testClosedTetrahedronMesh() { // given a tetrahedron as a closed mesh of four tiangles // verify MeshMassProperties computes the right nubers // these numbers from the Tonon paper: VectorOfPoints points; points.push_back(btVector3(8.33220f, -11.86875f, 0.93355f)); points.push_back(btVector3(0.75523f, 5.00000f, 16.37072f)); points.push_back(btVector3(52.61236f, 5.00000f, -5.38580f)); points.push_back(btVector3(2.00000f, 5.00000f, 3.00000f)); btScalar expectedVolume = 1873.233236f; btMatrix3x3 expectedInertia; expectedInertia[0][0] = 43520.33257f; expectedInertia[1][1] = 194711.28938f; expectedInertia[2][2] = 191168.76173f; expectedInertia[1][2] = -4417.66150f; expectedInertia[2][1] = -4417.66150f; expectedInertia[0][2] = 46343.16662f; expectedInertia[2][0] = 46343.16662f; expectedInertia[0][1] = -11996.20119f; expectedInertia[1][0] = -11996.20119f; btVector3 expectedCenterOfMass = 0.25f * (points[0] + points[1] + points[2] + points[3]); VectorOfIndices triangles; pushTriangle(triangles, 0, 2, 1); pushTriangle(triangles, 0, 3, 2); pushTriangle(triangles, 0, 1, 3); pushTriangle(triangles, 1, 2, 3); // compute mass properties MeshMassProperties mesh(points, triangles); // verify QCOMPARE_WITH_ABS_ERROR(mesh._volume, expectedVolume, acceptableRelativeError * expectedVolume); QCOMPARE_WITH_ABS_ERROR(mesh._centerOfMass, expectedCenterOfMass, acceptableAbsoluteError); QCOMPARE_WITH_RELATIVE_ERROR(mesh._inertia, expectedInertia, acceptableRelativeError); // test again, but this time shift the points so that the origin is definitely OUTSIDE the mesh btVector3 shift = points[0] + expectedCenterOfMass; for (int i = 0; i < (int)points.size(); ++i) { points[i] += shift; } expectedCenterOfMass = 0.25f * (points[0] + points[1] + points[2] + points[3]); // compute mass properties mesh.computeMassProperties(points, triangles); // verify // QCOMPARE_WITH_ABS_ERROR(mesh._volume, expectedVolume, acceptableRelativeError * expectedVolume); // QCOMPARE_WITH_ABS_ERROR(mesh._centerOfMass, expectedCenterOfMass, acceptableAbsoluteError); // QCOMPARE_WITH_RELATIVE_ERROR(mesh._inertia, expectedInertia, acceptableRelativeError); }
Mesh Mesh::fromPointcloud(const VectorOfPoints &pointcloud, bool centralizeLoadedMesh, bool calculateTriangles) { Mesh m; int n = pointcloud.size(); m.pointsMat = Matrix(n, 3); for (int i = 0; i < n; i++) { const cv::Point3d &p = pointcloud.at(i); m.pointsMat(i, 0) = p.x; m.pointsMat(i, 1) = p.y; m.pointsMat(i, 2) = p.z; } if (calculateTriangles) m.calculateTriangles(); m.recalculateMinMax(); if (centralizeLoadedMesh) m.centralize(); return m; }