Skip to content

Commit 4d024f9

Browse files
kbayescopybara-github
authored andcommitted
Convert internal representation of vertices to double. Also replace remove duplicate vertices with fast hash implementation.
PiperOrigin-RevId: 734516595 Change-Id: Ic78556688d5f2b75d69cd286b8d060e2cdeb7c48
1 parent e4ee00e commit 4d024f9

9 files changed

+435
-363
lines changed

doc/XMLreference.rst

+8-7
Original file line numberDiff line numberDiff line change
@@ -3397,10 +3397,11 @@ saving the XML:
33973397
compatible with :at:`dim=1`.
33983398

33993399
**mesh** loads the flexcomp points and elements (i.e. triangles) from a mesh file, in the same file formats as mesh
3400-
assets. A mesh asset is not actually added to the model. Instead the vertex and face data from the mesh file are used
3401-
to populate the point and element data of the flexcomp. :at:`dim` is automatically set to 2. Recall that a mesh asset
3402-
in MuJoCo can be used as a rigid geom attached to a single body. In contrast, the flex generated here corresponds to
3403-
a soft mesh with the same initial shape, where each vertex is a separate moving body (unless pinned).
3400+
assets, excluding the legacy .msh format. A mesh asset is not actually added to the model. Instead the vertex and
3401+
face data from the mesh file are used to populate the point and element data of the flexcomp. :at:`dim` is
3402+
automatically set to 2. Recall that a mesh asset in MuJoCo can be used as a rigid geom attached to a single body. In
3403+
contrast, the flex generated here corresponds to a soft mesh with the same initial shape, where each vertex is a
3404+
separate moving body (unless pinned).
34043405

34053406
.. _gmsh-file-docs:
34063407

@@ -3471,9 +3472,9 @@ saving the XML:
34713472

34723473
:at:`file`: :at-val:`string, optional`
34733474
The name of the file from which a **surface** (triangular) or **volumetric** (tetrahedral) mesh is loaded. For
3474-
surface meshes, the file extension is used to determine the file format. Supported formats are the same as in
3475-
:ref:`mesh assets<asset-mesh>` and also including GMSH. Volumetric meshes are supported only in GMSH format.
3476-
See :ref:`here<gmsh-file-docs>` for more information on GMSH files.
3475+
surface meshes, the file extension is used to determine the file format. Supported formats are GMSH and the formats
3476+
specified in :ref:`mesh assets<asset-mesh>`, excluding the legacy .msh format. Volumetric meshes are supported only
3477+
in GMSH format. See :ref:`here<gmsh-file-docs>` for more information on GMSH files.
34773478

34783479
.. _body-flexcomp-rigid:
34793480

src/user/user_flexcomp.cc

+12-37
Original file line numberDiff line numberDiff line change
@@ -989,14 +989,6 @@ bool mjCFlexcomp::MakeMesh(mjCModel* model, char* error, int error_sz) {
989989
return comperr(error, "File is required", error_sz);
990990
}
991991

992-
// get extension and check; must be STL, OBJ or MSH
993-
std::string ext = mjuu_getext(file);
994-
if (strcasecmp(ext.c_str(), ".stl") &&
995-
strcasecmp(ext.c_str(), ".obj") &&
996-
strcasecmp(ext.c_str(), ".msh")) {
997-
return comperr(error, "Mesh file extension must be stl, obj or msh", error_sz);
998-
}
999-
1000992
// check dim
1001993
if (def.spec.flex->dim < 2) {
1002994
return comperr(error, "Flex dim must be at least 2 for mesh", error_sz);
@@ -1006,53 +998,36 @@ bool mjCFlexcomp::MakeMesh(mjCModel* model, char* error, int error_sz) {
1006998
std::string filename = mjuu_combinePaths(mjs_getString(model->spec.meshdir), file);
1007999
mjResource* resource = nullptr;
10081000

1001+
1002+
if (mjCMesh::IsMSH(filename)) {
1003+
return comperr(error, "legacy MSH files are not supported in flexcomp", error_sz);
1004+
}
1005+
10091006
try {
10101007
resource = mjCBase::LoadResource(mjs_getString(model->spec.modelfiledir),
10111008
filename, 0);
10121009
} catch (mjCError err) {
10131010
return comperr(error, err.message, error_sz);
10141011
}
10151012

1013+
10161014
// load mesh
10171015
mjCMesh mesh;
1018-
bool isobj = false;
10191016
try {
1020-
if (!strcasecmp(ext.c_str(), ".stl")) {
1021-
mesh.LoadSTL(resource);
1022-
} else if (!strcasecmp(ext.c_str(), ".obj")) {
1023-
isobj = true;
1024-
mesh.LoadOBJ(resource);
1025-
} else {
1026-
mesh.LoadMSH(resource);
1027-
}
1017+
mesh.LoadFromResource(resource, true);
10281018
mju_closeResource(resource);
10291019
} catch (mjCError err) {
10301020
mju_closeResource(resource);
10311021
return comperr(error, err.message, error_sz);
10321022
}
10331023

1034-
// LoadOBJ uses userXXX, extra processing needed
1035-
if (isobj) {
1036-
// check sizes
1037-
if (mesh.Vert().empty() || mesh.Face().empty()) {
1038-
return comperr(error, "Vertex and face data required", error_sz);
1039-
}
1040-
if (mesh.Vert().size()%3) {
1041-
return comperr(error, "Vertex data must be multiple of 3", error_sz);
1042-
}
1043-
if (mesh.Face().size()%3) {
1044-
return comperr(error, "Face data must be multiple of 3", error_sz);
1045-
}
1046-
1047-
// remove repeated vertices (not called in LoadOBJ)
1048-
mesh.RemoveRepeated();
1024+
// check sizes
1025+
if (mesh.Vert().empty() || mesh.Face().empty()) {
1026+
return comperr(error, "Vertex and face data required", error_sz);
10491027
}
10501028

1051-
// copy vertices, convert from float to double
1052-
point = vector<double> (mesh.nvert()*3);
1053-
for (int i=0; i < mesh.nvert()*3; i++) {
1054-
point[i] = (double) mesh.Vert(i);
1055-
}
1029+
// copy vertices
1030+
point = mesh.Vert();
10561031

10571032
if (mesh.HasTexcoord()) {
10581033
texcoord = mesh.Texcoord();

0 commit comments

Comments
 (0)