From 3601b063dcba3531a0a5202c092fc384a1cbdc84 Mon Sep 17 00:00:00 2001 From: Sam Haves Date: Wed, 11 Mar 2026 13:14:35 -0700 Subject: [PATCH] Modify mjCMesh vert_ field to be vector instead of vector. PiperOrigin-RevId: 882162404 Change-Id: Ia97439420f284d594f5cb1a91cd0fb640ac8dff0 --- src/user/user_flexcomp.cc | 2 +- src/user/user_mesh.cc | 210 ++++++++++++++++++++------------------ src/user/user_objects.cc | 3 + src/user/user_objects.h | 36 ++++--- 4 files changed, 131 insertions(+), 120 deletions(-) diff --git a/src/user/user_flexcomp.cc b/src/user/user_flexcomp.cc index 867f0707..c349fb28 100644 --- a/src/user/user_flexcomp.cc +++ b/src/user/user_flexcomp.cc @@ -1185,7 +1185,7 @@ bool mjCFlexcomp::MakeMesh(mjCModel* model, mjsCompiler* compiler, char* error, } // copy vertices - point = mesh.Vert(); + point.assign(mesh.Vert().begin(), mesh.Vert().end()); if (mesh.HasTexcoord()) { texcoord = mesh.Texcoord(); diff --git a/src/user/user_mesh.cc b/src/user/user_mesh.cc index ad350223..db852729 100644 --- a/src/user/user_mesh.cc +++ b/src/user/user_mesh.cc @@ -492,7 +492,7 @@ void mjCMesh::CacheMesh(mjCCache* cache, const mjResource* resource) { // calculate estimated size of mesh std::size_t size = sizeof(mjCMesh) - + (sizeof(double) * vert_.size()) + + (sizeof(float) * vert_.size()) + (sizeof(float) * normal_.size()) + (sizeof(float) * texcoord_.size()) + (sizeof(int) * face_.size()) @@ -538,7 +538,7 @@ struct VertexKey { -// convert vertices to double precision and remove repeated vertices if requested +// process and remove repeated vertices if requested void mjCMesh::ProcessVertices(const std::vector& vert, bool remove_repeated) { vert_.clear(); int nvert = vert.size(); @@ -775,24 +775,24 @@ void mjCMesh::TryCompile(const mjVFS* vfs) { // compute mesh properties if (!fromCache) { Process(); - } - // make octree - if (!needsdf) { - octree_.Clear(); // this occurs when a non-SDF mesh is loaded from a cached SDF mesh - } else if (octree_.NumNodes() == 0) { - octree_.SetFace(vert_, face_); - octree_.CreateOctree(aamm_); - - // compute sdf coefficients - if (!plugin.active) { - octree_.ComputeSdfCoeffs(vert_.data(), nvert(), face_.data(), nface(), tree_); + if (!file_.empty()) { + CacheMesh(cache, resource_); + } + } else { + // When a mesh is loaded from the cache, has no octree but needs one, + // we need to compute it here. If inversely it has an octree but we *do not* + // need one, we clear it. + if (!needsdf) { + octree_.Clear(); + } else if (octree_.NumNodes() == 0) { + std::vector dvert(vert_.begin(), vert_.end()); + octree_.SetFace(dvert, face_); + octree_.CreateOctree(aamm_); + if (!plugin.active) { + octree_.ComputeSdfCoeffs(dvert.data(), nvert(), face_.data(), nface(), tree_); + } } - } - - // cache mesh - if (!fromCache && !file_.empty()) { - CacheMesh(cache, resource_); } // close resource @@ -805,18 +805,18 @@ void mjCMesh::TryCompile(const mjVFS* vfs) { // get bounding volume -void mjCMesh::SetBoundingVolume(int faceid) { +void mjCMesh::SetBoundingVolume(int faceid, const double* dvert) { constexpr double kMaxVal = std::numeric_limits::max(); double face_aamm[6] = {kMaxVal, kMaxVal, kMaxVal, -kMaxVal, -kMaxVal, -kMaxVal}; for (int j = 0; j < 3; j++) { int vertid = face_[3*faceid + j]; - face_aamm[0] = std::min(face_aamm[0], vert_[3*vertid + 0]); - face_aamm[1] = std::min(face_aamm[1], vert_[3*vertid + 1]); - face_aamm[2] = std::min(face_aamm[2], vert_[3*vertid + 2]); - face_aamm[3] = std::max(face_aamm[3], vert_[3*vertid + 0]); - face_aamm[4] = std::max(face_aamm[4], vert_[3*vertid + 1]); - face_aamm[5] = std::max(face_aamm[5], vert_[3*vertid + 2]); + face_aamm[0] = std::min(face_aamm[0], dvert[3*vertid + 0]); + face_aamm[1] = std::min(face_aamm[1], dvert[3*vertid + 1]); + face_aamm[2] = std::min(face_aamm[2], dvert[3*vertid + 2]); + face_aamm[3] = std::max(face_aamm[3], dvert[3*vertid + 0]); + face_aamm[4] = std::max(face_aamm[4], dvert[3*vertid + 1]); + face_aamm[5] = std::max(face_aamm[5], dvert[3*vertid + 2]); } face_aabb_.push_back(.5 * (face_aamm[0] + face_aamm[3])); @@ -851,9 +851,7 @@ bool mjCMesh::HasTexcoord() const { void mjCMesh::CopyVert(float* arr) const { - for (int i = 0; i < vert_.size(); ++i) { - arr[i] = (float)vert_[i]; - } + std::copy(vert_.begin(), vert_.end(), arr); } @@ -1187,16 +1185,15 @@ void mjCMesh::LoadMSH(mjResource* resource, bool remove_repeated) { // compute the volume and center-of-mass of the mesh given the face centroid -double mjCMesh::ComputeVolume(double CoM[3], const double facecen[3]) const { +double mjCMesh::ComputeVolume(double CoM[3], const double facecen[3], const double* dvert) const { double normal[3], center[3], total_volume = 0; CoM[0] = CoM[1] = CoM[2] = 0; int nf = (inertia == mjMESH_INERTIA_CONVEX) ? graph_[1] : nface(); const int* f = (inertia == mjMESH_INERTIA_CONVEX) ? GraphFaces() : face_.data(); for (int i = 0; i < nf; i++) { - // get area, normal and center - double area = triangle(normal, center, &vert_[3*f[3*i]], &vert_[3*f[3*i + 1]], - &vert_[3*f[3*i + 2]]); + double area = triangle(normal, center, &dvert[3*f[3*i]], &dvert[3*f[3*i + 1]], + &dvert[3*f[3*i + 2]]); // compute and add volume double vec[3] = {center[0] - facecen[0], center[1] - facecen[1], center[2] - facecen[2]}; @@ -1226,14 +1223,13 @@ double mjCMesh::ComputeVolume(double CoM[3], const double facecen[3]) const { // compute the surface area and center-of-mass of the mesh given the face centroid -double mjCMesh::ComputeSurfaceArea(double CoM[3], const double facecen[3]) const { +double mjCMesh::ComputeSurfaceArea(double CoM[3], const double facecen[3], const double* dvert) const { double surface = 0; CoM[0] = CoM[1] = CoM[2] = 0; for (int i = 0; i < nface(); i++) { - // get area and center double area, center[3]; - area = triangle(nullptr, center, &vert_[3*face_[3*i]], - &vert_[3*face_[3*i + 1]], &vert_[3*face_[3*i + 2]]); + area = triangle(nullptr, center, &dvert[3*face_[3*i]], + &dvert[3*face_[3*i + 1]], &dvert[3*face_[3*i + 2]]); // add pyramid com surface += area; @@ -1254,28 +1250,24 @@ double mjCMesh::ComputeSurfaceArea(double CoM[3], const double facecen[3]) const // apply transformations -void mjCMesh::ApplyTransformations() { - // translate +void mjCMesh::ApplyTransformations(double* dvert) { if (refpos[0] != 0 || refpos[1] != 0 || refpos[2] != 0) { int nv = nvert(); for (int i = 0; i < nv; i++) { - vert_[3*i + 0] -= refpos[0]; - vert_[3*i + 1] -= refpos[1]; - vert_[3*i + 2] -= refpos[2]; + dvert[3*i + 0] -= refpos[0]; + dvert[3*i + 1] -= refpos[1]; + dvert[3*i + 2] -= refpos[2]; } } - // rotate if (refquat[0] != 1 || refquat[1] != 0 || refquat[2] != 0 || refquat[3] != 0) { - // prepare rotation double quat[4] = {refquat[0], refquat[1], refquat[2], refquat[3]}; double mat[9]; mjuu_normvec(quat, 4); mjuu_quat2mat(mat, quat); - // process vertices for (int i = 0; i < nvert(); i++) { - mjuu_mulvecmatT(&vert_[3*i], &vert_[3*i], mat); + mjuu_mulvecmatT(&dvert[3*i], &dvert[3*i], mat); } // process normals @@ -1291,9 +1283,9 @@ void mjCMesh::ApplyTransformations() { // scale if (scale[0] != 1 || scale[1] != 1 || scale[2] != 1) { for (int i = 0; i < nvert(); i++) { - vert_[3*i + 0] *= scale[0]; - vert_[3*i + 1] *= scale[1]; - vert_[3*i + 2] *= scale[2]; + dvert[3*i + 0] *= scale[0]; + dvert[3*i + 1] *= scale[1]; + dvert[3*i + 2] *= scale[2]; } for (int i = 0; i < nnormal(); i++) { @@ -1325,14 +1317,13 @@ void mjCMesh::ApplyTransformations() { // find centroid of faces, return total area -double mjCMesh::ComputeFaceCentroid(double facecen[3]) const { +double mjCMesh::ComputeFaceCentroid(double facecen[3], const double* dvert) const { double total_area = 0; for (int i = 0; i < nface(); i++) { - // get area and center double area, center[3]; - area = triangle(nullptr, center, &vert_[3*face_[3*i]], - &vert_[3*face_[3*i + 1]], &vert_[3*face_[3*i + 2]]); + area = triangle(nullptr, center, &dvert[3*face_[3*i]], + &dvert[3*face_[3*i + 1]], &dvert[3*face_[3*i + 2]]); // accumulate facecen[0] += area * center[0]; @@ -1353,13 +1344,15 @@ double mjCMesh::ComputeFaceCentroid(double facecen[3]) const { void mjCMesh::Process() { + std::vector dvert(vert_.begin(), vert_.end()); + // create half-edge structure (if mesh was in XML) if (halfedge_.empty()) { for (int i = 0; i < nface(); i++) { int v0 = face_[3*i + 0]; int v1 = face_[3*i + 1]; int v2 = face_[3*i + 2]; - if (triangle(nullptr, nullptr, &vert_[3*v0], &vert_[3*v1], &vert_[3*v2]) > sqrt(mjMINVAL)) { + if (triangle(nullptr, nullptr, &dvert[3*v0], &dvert[3*v1], &dvert[3*v2]) > sqrt(mjMINVAL)) { halfedge_.push_back({v0, v1}); halfedge_.push_back({v1, v2}); halfedge_.push_back({v2, v0}); @@ -1383,7 +1376,7 @@ void mjCMesh::Process() { // make graph describing convex hull if (needhull_ || face_.empty()) { - MakeGraph(); + MakeGraph(dvert.data()); } // no faces: copy from convex hull @@ -1393,7 +1386,7 @@ void mjCMesh::Process() { // no normals: make if (normal_.empty()) { - MakeNormal(); + MakeNormal(dvert.data()); } // check facenormal size @@ -1416,7 +1409,7 @@ void mjCMesh::Process() { } if (szgraph_) { - MakePolygons(); + MakePolygons(dvert.data()); } else { polygon_map_.resize(nvert()); } @@ -1436,11 +1429,11 @@ void mjCMesh::Process() { } // user offset, rotation, scaling - ApplyTransformations(); + ApplyTransformations(dvert.data()); // find centroid of faces double facecen[3] = {0, 0, 0}; - if (ComputeFaceCentroid(facecen) < mjMINVAL) { + if (ComputeFaceCentroid(facecen, dvert.data()) < mjMINVAL) { throw mjCError(this, "mesh surface area is too small: %s", name.c_str()); } @@ -1451,12 +1444,12 @@ void mjCMesh::Process() { // compute CoM and volume/area if (inertia == mjMESH_INERTIA_SHELL) { - surface_ = ComputeSurfaceArea(CoM, facecen); + surface_ = ComputeSurfaceArea(CoM, facecen, dvert.data()); if (surface_ < mjMINVAL) { throw mjCError(this, "mesh surface area is too small: %s", name.c_str()); } } else { - if ((volume_ = ComputeVolume(CoM, facecen)) < mjMINVAL) { + if ((volume_ = ComputeVolume(CoM, facecen, dvert.data())) < mjMINVAL) { if (volume_ < 0) { throw mjCError(this, "mesh volume is negative (misoriented triangles): %s", name.c_str()); } else { @@ -1467,7 +1460,7 @@ void mjCMesh::Process() { } // compute inertia - double total_volume = ComputeInertia(inert, CoM); + double total_volume = ComputeInertia(inert, CoM, dvert.data()); if (inertia == mjMESH_INERTIA_SHELL) { surface_ = total_volume; } else { @@ -1511,11 +1504,11 @@ void mjCMesh::Process() { // transform CoM to origin for (int i=0; i < nvert(); i++) { - vert_[3*i + 0] -= CoM[0]; - vert_[3*i + 1] -= CoM[1]; - vert_[3*i + 2] -= CoM[2]; + dvert[3*i + 0] -= CoM[0]; + dvert[3*i + 1] -= CoM[1]; + dvert[3*i + 2] -= CoM[2]; } - Rotate(quattmp); + Rotate(quattmp, dvert.data()); // save the pos and quat that was used to transform the mesh mjuu_copyvec(pos_, CoM, 3); @@ -1525,11 +1518,11 @@ void mjCMesh::Process() { // no radii: make if (!center_) { - MakeCenter(); + MakeCenter(dvert.data()); } // recompute polygon normals - MakePolygonNormals(); + MakePolygonNormals(dvert.data()); // make bounding volume hierarchy if (tree_.Bvh().empty()) { @@ -1537,16 +1530,31 @@ void mjCMesh::Process() { face_aabb_.reserve(3*face_.size()); tree_.AllocateBoundingVolumes(nface()); for (int i = 0; i < nface(); i++) { - SetBoundingVolume(i); + SetBoundingVolume(i, dvert.data()); } tree_.CreateBVH(); } + + // make octree + if (needsdf) { + octree_.SetFace(dvert, face_); + octree_.CreateOctree(aamm_); + + if (!plugin.active) { + octree_.ComputeSdfCoeffs(dvert.data(), nvert(), face_.data(), nface(), tree_); + } + } + + // narrow back to float + for (int i = 0; i < (int)dvert.size(); i++) { + vert_[i] = (float)dvert[i]; + } } // compute abstract (unitless) inertia, recompute area / volume -double mjCMesh::ComputeInertia(double inert[6], const double CoM[3]) const { +double mjCMesh::ComputeInertia(double inert[6], const double CoM[3], const double* dvert) const { double total_volume = 0; // copy vertices to avoid modifying the original mesh @@ -1555,9 +1563,9 @@ double mjCMesh::ComputeInertia(double inert[6], const double CoM[3]) const { // translate vertices to origin in order to compute inertia for (int i = 0; i < nvert(); i++) { - vert_centered.push_back(vert_[3*i + 0] - CoM[0]); - vert_centered.push_back(vert_[3*i + 1] - CoM[1]); - vert_centered.push_back(vert_[3*i + 2] - CoM[2]); + vert_centered.push_back(dvert[3*i + 0] - CoM[0]); + vert_centered.push_back(dvert[3*i + 1] - CoM[1]); + vert_centered.push_back(dvert[3*i + 2] - CoM[2]); } // accumulate products of inertia, recompute volume @@ -1612,22 +1620,20 @@ double mjCMesh::ComputeInertia(double inert[6], const double CoM[3]) const { -void mjCMesh::Rotate(double quat[4]) { - // rotate vertices and normals of mesh by quaternion +void mjCMesh::Rotate(double quat[4], double* dvert) { double neg[4] = {quat[0], -quat[1], -quat[2], -quat[3]}; double mat[9]; mjuu_quat2mat(mat, neg); int nv = nvert(); for (int i = 0; i < nv; i++) { - mjuu_mulvecmat(&vert_[3*i], &vert_[3*i], mat); + mjuu_mulvecmat(&dvert[3*i], &dvert[3*i], mat); - // axis-aligned bounding box - aamm_[0] = std::min(aamm_[0], vert_[3*i + 0]); - aamm_[3] = std::max(aamm_[3], vert_[3*i + 0]); - aamm_[1] = std::min(aamm_[1], vert_[3*i + 1]); - aamm_[4] = std::max(aamm_[4], vert_[3*i + 1]); - aamm_[2] = std::min(aamm_[2], vert_[3*i + 2]); - aamm_[5] = std::max(aamm_[5], vert_[3*i + 2]); + aamm_[0] = std::min(aamm_[0], dvert[3*i + 0]); + aamm_[3] = std::max(aamm_[3], dvert[3*i + 0]); + aamm_[1] = std::min(aamm_[1], dvert[3*i + 1]); + aamm_[4] = std::max(aamm_[4], dvert[3*i + 1]); + aamm_[2] = std::min(aamm_[2], dvert[3*i + 2]); + aamm_[5] = std::max(aamm_[5], dvert[3*i + 2]); } for (int i=0; i < nnormal(); i++) { @@ -1699,7 +1705,7 @@ double mjCMesh::GetVolumeRef() const { // make graph describing convex hull -void mjCMesh::MakeGraph() { +void mjCMesh::MakeGraph(const double* dvert) { int adr, ok, curlong, totlong, exitcode; facetT* facet, **facetp; vertexT* vertex, *vertex1, **vertex1p; @@ -1728,7 +1734,7 @@ void mjCMesh::MakeGraph() { if (!exitcode) { // actual init qh_initflags(qh, const_cast(qhopt.c_str())); - qh_init_B(qh, vert_.data(), nvert(), 3, qh_False); + qh_init_B(qh, const_cast(dvert), nvert(), 3, qh_False); // construct convex hull qh_qhull(qh); @@ -2403,7 +2409,7 @@ void mjCMesh::MakeCone(int nedge, double radius) { // compute vertex normals -void mjCMesh::MakeNormal() { +void mjCMesh::MakeNormal(const double* dvert) { // only if normal data is missing if (!normal_.empty()) { return; @@ -2427,8 +2433,8 @@ void mjCMesh::MakeNormal() { // get triangle edges double vec01[3], vec02[3]; for (int j=0; j < 3; j++) { - vec01[j] = vert_[3*vertid[1]+j] - vert_[3*vertid[0]+j]; - vec02[j] = vert_[3*vertid[2]+j] - vert_[3*vertid[0]+j]; + vec01[j] = dvert[3*vertid[1]+j] - dvert[3*vertid[0]+j]; + vec02[j] = dvert[3*vertid[2]+j] - dvert[3*vertid[0]+j]; } // compute face normal @@ -2462,8 +2468,8 @@ void mjCMesh::MakeNormal() { // get triangle edges double vec01[3], vec02[3]; for (int j=0; j < 3; j++) { - vec01[j] = vert_[3*vertid[1]+j] - vert_[3*vertid[0]+j]; - vec02[j] = vert_[3*vertid[2]+j] - vert_[3*vertid[0]+j]; + vec01[j] = dvert[3*vertid[1]+j] - dvert[3*vertid[0]+j]; + vec02[j] = dvert[3*vertid[2]+j] - dvert[3*vertid[0]+j]; } // compute face normal @@ -2515,7 +2521,7 @@ void mjCMesh::MakeNormal() { // compute face circumradii -void mjCMesh::MakeCenter() { +void mjCMesh::MakeCenter(const double* dvert) { if (center_) { return; } @@ -2531,8 +2537,8 @@ void mjCMesh::MakeCenter() { // get triangle edges double a[3], b[3]; for (int j=0; j < 3; j++) { - a[j] = vert_[3*vertid[0]+j] - vert_[3*vertid[2]+j]; - b[j] = vert_[3*vertid[1]+j] - vert_[3*vertid[2]+j]; + a[j] = dvert[3*vertid[0]+j] - dvert[3*vertid[2]+j]; + b[j] = dvert[3*vertid[1]+j] - dvert[3*vertid[2]+j]; } // compute face normal @@ -2551,20 +2557,20 @@ void mjCMesh::MakeCenter() { norm_a_2 * b[2] - norm_b_2 * a[2] }; mjuu_crossvec(res, vec, nrm); - center_[3*i+0] = res[0]/(2*area*area) + vert_[3*vertid[2]+0]; - center_[3*i+1] = res[1]/(2*area*area) + vert_[3*vertid[2]+1]; - center_[3*i+2] = res[2]/(2*area*area) + vert_[3*vertid[2]+2]; + center_[3*i+0] = res[0]/(2*area*area) + dvert[3*vertid[2]+0]; + center_[3*i+1] = res[1]/(2*area*area) + dvert[3*vertid[2]+1]; + center_[3*i+2] = res[2]/(2*area*area) + dvert[3*vertid[2]+2]; } } // compute the normals of the polygons -void mjCMesh::MakePolygonNormals() { +void mjCMesh::MakePolygonNormals(const double* dvert) { for (int i = 0; i < polygons_.size(); ++i) { double n[3]; - mjuu_makenormal(n, &vert_[3*polygons_[i][0]], &vert_[3*polygons_[i][1]], - &vert_[3*polygons_[i][2]]); + mjuu_makenormal(n, &dvert[3*polygons_[i][0]], &dvert[3*polygons_[i][1]], + &dvert[3*polygons_[i][2]]); polygon_normals_[3*i + 0] = n[0]; polygon_normals_[3*i + 1] = n[1]; polygon_normals_[3*i + 2] = n[2]; @@ -2803,7 +2809,7 @@ struct PairHash { // merge coplanar mesh triangular faces into polygonal sides to represent the geometry of the mesh -void mjCMesh::MakePolygons() { +void mjCMesh::MakePolygons(const double* dvert) { constexpr double kAngleTol = 0.01; std::unordered_map, MeshPolygon, PairHash> mesh_polygons; polygons_.clear(); @@ -2820,9 +2826,9 @@ void mjCMesh::MakePolygons() { int vi1 = faces[3*i + 0]; int vi2 = faces[3*i + 1]; int vi3 = faces[3*i + 2]; - double* v1 = &vert_[3*vi1]; - double* v2 = &vert_[3*vi2]; - double* v3 = &vert_[3*vi3]; + const double* v1 = &dvert[3*vi1]; + const double* v2 = &dvert[3*vi2]; + const double* v3 = &dvert[3*vi3]; std::pair key; if (!MeshPolygonKey(key, v1, v2, v3, kAngleTol)) { diff --git a/src/user/user_objects.cc b/src/user/user_objects.cc index 718c9f70..30c1c525 100644 --- a/src/user/user_objects.cc +++ b/src/user/user_objects.cc @@ -587,6 +587,7 @@ void mjCOctree::CopyCoeff(mjtNum* coeff) const { void mjCOctree::SetFace(const std::vector& vert, const std::vector& face) { + face_.reserve(face.size()/3); for (int i = 0; i < face.size(); i += 3) { std::array v0 = {vert[3*face[i+0]], vert[3*face[i+0]+1], vert[3*face[i+0]+2]}; std::array v1 = {vert[3*face[i+1]], vert[3*face[i+1]+1], vert[3*face[i+1]+2]}; @@ -613,6 +614,8 @@ void mjCOctree::Make(std::vector& elements) { void mjCOctree::CreateOctree(const double aamm[6]) { + Clear(); + double aabb[6] = {(aamm[0] + aamm[3]) / 2, (aamm[1] + aamm[4]) / 2, (aamm[2] + aamm[5]) / 2, (aamm[3] - aamm[0]) / 2, (aamm[4] - aamm[1]) / 2, (aamm[5] - aamm[2]) / 2}; double box[6] = {aabb[0] - 1.1 * aabb[3], aabb[1] - 1.1 * aabb[4], aabb[2] - 1.1 * aabb[5], diff --git a/src/user/user_objects.h b/src/user/user_objects.h index 88599740..232d0470 100644 --- a/src/user/user_objects.h +++ b/src/user/user_objects.h @@ -299,8 +299,11 @@ class mjCOctree : public mjCOctree_ { sizeof(Point) * vert_.size(); } void Clear() { + nnode_ = 0; + nvert_ = 0; node_.clear(); - face_.clear(); + vert_.clear(); + hang_.clear(); } void AddCoeff(int n, int v, double coeff) { node_[n].coeff[v] = coeff; } double Coeff(int n, int v) const { return node_[n].coeff[v]; } @@ -1071,7 +1074,7 @@ class mjCMesh_ : public mjCBase { std::string content_type_ = ""; // content type of file std::string file_; // mesh file mjResource* resource_ = nullptr; // resource for mesh file - std::vector vert_; // vertex data + std::vector vert_; // vertex data std::vector normal_; // normal data std::vector texcoord_; // texcoord data std::vector face_; // vertex indices @@ -1156,8 +1159,8 @@ class mjCMesh: public mjCMesh_, private mjsMesh { const double* Refquat() const { return refquat; } const double* Scale() const { return scale; } bool SmoothNormal() const { return smoothnormal; } - const std::vector& Vert() const { return vert_; } - double Vert(int i) const { return vert_[i]; } + const std::vector& Vert() const { return vert_; } + float Vert(int i) const { return vert_[i]; } const std::vector& UserVert() const { return spec_vert_; } const std::vector& UserNormal() const { return spec_normal_; } const std::vector& Texcoord() const { return texcoord_; } @@ -1233,7 +1236,7 @@ class mjCMesh: public mjCMesh_, private mjsMesh { void CopyPolygonNormals(mjtNum* arr); // sets properties of a bounding volume given a face id - void SetBoundingVolume(int faceid); + void SetBoundingVolume(int faceid, const double* dvert); // load from OBJ, STL, or MSH file; throws mjCError on failure void LoadFromResource(mjResource* resource, bool remove_repeated = false); @@ -1264,22 +1267,22 @@ class mjCMesh: public mjCMesh_, private mjsMesh { void LoadMSH(mjResource* resource, bool remove_repeated); // load mesh in MSH BIN format void LoadSDF(); // generate mesh using marching cubes - void MakeGraph(); // make graph of convex hull + void MakeGraph(const double* dvert); // make graph of convex hull void CopyGraph(); // copy graph into face data - void MakeNormal(); // compute vertex normals - void MakeCenter(); // compute face circumcircle data + void MakeNormal(const double* dvert); // compute vertex normals + void MakeCenter(const double* dvert); // compute face circumcircle data void Process(); // compute inertial properties - void ApplyTransformations(); // apply user transformations - double ComputeFaceCentroid(double[3]) const; // compute centroid of all faces + void ApplyTransformations(double* dvert); // apply user transformations + double ComputeFaceCentroid(double[3], const double* dvert) const; void CheckInitialMesh() const; // check if initial mesh is valid void CopyPlugin(); - void Rotate(double quat[4]); // rotate mesh by quaternion + void Rotate(double quat[4], double* dvert); // rotate mesh by quaternion void Transform(double pos[3], double quat[4]); // transform mesh by position and quaternion - void MakePolygons(); // compute the polygon sides of the mesh - void MakePolygonNormals(); // compute the normals of the polygons + void MakePolygons(const double* dvert); // compute the polygon sides of the mesh + void MakePolygonNormals(const double* dvert); // compute the normals of the polygons // computes the inertia matrix of the mesh given the type of inertia - double ComputeInertia(double inert[6], const double CoM[3]) const; + double ComputeInertia(double inert[6], const double CoM[3], const double* dvert) const; int* GraphFaces() const { return graph_ + 2 + 3*(graph_[0] + graph_[1]); @@ -1295,9 +1298,8 @@ class mjCMesh: public mjCMesh_, private mjsMesh { std::vector> polygon_map_; // map from vertex to polygon // compute the volume and center-of-mass of the mesh given the face centroid - double ComputeVolume(double CoM[3], const double facecen[3]) const; - // compute the surface area and center-of-mass of the mesh given the face centroid - double ComputeSurfaceArea(double CoM[3], const double facecen[3]) const; + double ComputeVolume(double CoM[3], const double facecen[3], const double* dvert) const; + double ComputeSurfaceArea(double CoM[3], const double facecen[3], const double* dvert) const; };