Add maxhullvert.

PiperOrigin-RevId: 641092710
Change-Id: Ib4fa828a9c82531614f0a67de9990340dbb25406
This commit is contained in:
Baruch Tabanpour
2024-06-06 19:04:21 -07:00
committed by Copybara-Service
parent fb8bf206d9
commit ace0c8f0a3
11 changed files with 86 additions and 10 deletions
+9
View File
@@ -1233,6 +1233,13 @@ The full list of processing steps applied by the compiler to each mesh is as fol
faces at large angles relative to the average normal are excluded from the average. In this way, sharp edges (as in
cube edges) are not smoothed.
.. _asset-mesh-maxhullvert:
:at:`maxhullvert`: :at-val:`int, "-1"`
Maximum number of vertices in a mesh's convex hull. Currently this is implemented by asking qhull
`to teminate <http://www.qhull.org/html/qh-optt.htm#TAn>`__ after :at:`maxhullvert` vertices. The default
value of -1 means "unlimited". Positive values must be larger than 3.
.. _asset-mesh-vertex:
:at:`vertex`: :at-val:`real(3*nvert), optional`
@@ -7666,6 +7673,8 @@ if omitted.
.. _default-mesh-scale:
.. _default-mesh-maxhullvert:
:el-prefix:`default/` |-| **mesh** (?)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+3 -1
View File
@@ -103,6 +103,8 @@
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`refpos<asset-mesh-refpos>` | :ref:`refquat<asset-mesh-refquat>` | :ref:`scale<asset-mesh-scale>` | :ref:`smoothnormal<asset-mesh-smoothnormal>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`maxhullvert<asset-mesh-maxhullvert>` | | | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_2| mesh |br| |_2| |L| | | .. table:: |
| :ref:`plugin | \* | :class: mjcf-attributes |
@@ -1325,7 +1327,7 @@
| :ref:`mesh | ? | :class: mjcf-attributes |
| <default-mesh>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`scale<default-mesh-scale>` | | | | |
| | | | :ref:`scale<default-mesh-scale>` | :ref:`maxhullvert<default-mesh-maxhullvert>` | | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| default |br| |_| |L| | | .. table:: |
+9
View File
@@ -2,6 +2,15 @@
Changelog
=========
Upcoming version (not yet released)
-----------------------------------
General
^^^^^^^
1. Added :ref:`maxhullvert<asset-mesh-maxhullvert>`, the maximum number of vertices in a mesh's convex hull.
Version 3.1.6 (Jun 3, 2024)
---------------------------
+1
View File
@@ -446,6 +446,7 @@ typedef struct mjsMesh_ { // mesh specification
double refquat[4]; // reference orientation
double scale[3]; // rescale mesh
mjtByte smoothnormal; // do not exclude large-angle faces from normals
int maxhullvert; // maximum vertex count for the convex hull
mjFloatVec* uservert; // user vertex data
mjFloatVec* usernormal; // user normal data
mjFloatVec* usertexcoord; // user texcoord data
+1
View File
@@ -243,6 +243,7 @@ void mjs_defaultMesh(mjsMesh* mesh) {
memset(mesh, 0, sizeof(mjsMesh));
mesh->refquat[0] = 1;
mesh->scale[0] = mesh->scale[1] = mesh->scale[2] = 1;
mesh->maxhullvert = -1;
}
+11 -6
View File
@@ -50,8 +50,8 @@
#include <mujoco/mjmacro.h>
#include <mujoco/mjmodel.h>
#include <mujoco/mjtnum.h>
#include <mujoco/mjplugin.h>
#include <mujoco/mjtnum.h>
#include "engine/engine_crossplatform.h"
#include "engine/engine_io.h"
#include "engine/engine_plugin.h"
@@ -135,6 +135,7 @@ mjCMesh::mjCMesh(mjCModel* _model, mjCDef* _def) {
center_ = NULL;
graph_ = NULL;
needhull_ = false;
maxhullvert_ = -1;
invalidorientation_.first = -1;
invalidorientation_.second = -1;
validarea_ = true;
@@ -223,6 +224,7 @@ void mjCMesh::CopyFromSpec() {
facetexcoord_ = spec_facetexcoord_;
file = &file_;
content_type = &content_type_;
maxhullvert_ = spec.maxhullvert;
uservert = &vert_;
usernormal = &normal_;
userface = &face_;
@@ -1548,12 +1550,17 @@ double& mjCMesh::GetVolumeRef(mjtGeomInertia type) {
// make graph describing convex hull
void mjCMesh::MakeGraph(void) {
void mjCMesh::MakeGraph() {
int adr, ok, curlong, totlong, exitcode;
double* data;
facetT* facet, **facetp;
vertexT* vertex, *vertex1, **vertex1p;
char qhopt[10] = "qhull Qt";
std::string qhopt = "qhull Qt";
if (maxhullvert_ > -1) {
// qhull "TA" actually means "number of vertices added after the initial simplex"
qhopt += " TA" + std::to_string(maxhullvert_ - 4);
}
// graph not needed for small meshes
if (nvert() < 4) {
@@ -1585,7 +1592,7 @@ void mjCMesh::MakeGraph(void) {
qh->NOerrexit = false;
if (!exitcode) {
// actual init
qh_initflags(qh, qhopt);
qh_initflags(qh, const_cast<char*>(qhopt.c_str()));
qh_init_B(qh, data, nvert(), 3, False);
// construct convex hull
@@ -1742,8 +1749,6 @@ void mjCMesh::MakeGraph(void) {
}
}
// copy graph into face data
void mjCMesh::CopyGraph(void) {
// only if face data is missing
+1
View File
@@ -778,6 +778,7 @@ class mjCMesh_ : public mjCBase {
// size of mesh data to be copied into mjModel
int szgraph_; // size of graph data in ints
bool needhull_; // needs convex hull for collisions
int maxhullvert_; // max vertex count of convex hull
mjCBoundingVolumeHierarchy tree_; // bounding volume hierarchy
std::vector<double> face_aabb_; // bounding boxes of all faces
+9 -3
View File
@@ -145,7 +145,7 @@ const char* MJCF[nMJCF][mjXATTRNUM] = {
{"default", "R", "1", "class"},
{"<"},
{"mesh", "?", "1", "scale"},
{"mesh", "?", "2", "scale", "maxhullvert"},
{"material", "?", "10", "texture", "emission", "specular", "shininess",
"reflectance", "metallic", "roughness", "rgba", "texrepeat", "texuniform"},
{"joint", "?", "22", "type", "group", "pos", "axis", "springdamper",
@@ -221,8 +221,9 @@ const char* MJCF[nMJCF][mjXATTRNUM] = {
{"asset", "*", "0"},
{"<"},
{"mesh", "*", "12", "name", "class", "content_type", "file", "vertex", "normal",
"texcoord", "face", "refpos", "refquat", "scale", "smoothnormal"},
{"mesh", "*", "13", "name", "class", "content_type", "file", "vertex", "normal",
"texcoord", "face", "refpos", "refquat", "scale", "smoothnormal",
"maxhullvert"},
{"<"},
{"plugin", "*", "2", "plugin", "instance"},
{"<"},
@@ -1391,6 +1392,11 @@ void mjXReader::OneMesh(XMLElement* elem, mjsMesh* pmesh) {
pmesh->smoothnormal = (n==1);
}
if (ReadAttrInt(elem, "maxhullvert", &n)) {
if (n != 0 && n < 4) throw mjXError(elem, "maxhullvert must be larger than 3");
pmesh->maxhullvert = n;
}
// read user vertex data
if (ReadAttrTxt(elem, "vertex", text)) {
auto uservert = ReadAttrVec<float>(elem, "vertex");
+8
View File
@@ -0,0 +1,8 @@
<mujoco>
<asset>
<mesh file="torus.obj" maxhullvert="4"/>
</asset>
<worldbody>
<geom type="mesh" mesh="torus"/>
</worldbody>
</mujoco>
+11
View File
@@ -0,0 +1,11 @@
<mujoco>
<default>
<mesh maxhullvert="64"/>
</default>
<asset>
<mesh file="torus.obj"/>
</asset>
<worldbody>
<geom type="mesh" mesh="torus"/>
</worldbody>
</mujoco>
+23
View File
@@ -41,6 +41,10 @@ static const char* const kCubePath =
"user/testdata/cube.xml";
static const char* const kTorusPath =
"user/testdata/torus.xml";
static const char* const kTorusMaxhullVertPath =
"user/testdata/torus_maxhullvert.xml";
static const char* const kTorusDefaultMaxhullVertPath =
"user/testdata/torus_maxhullvert_default.xml";
static const char* const kTorusShellPath =
"user/testdata/torus_shell.xml";
static const char* const kConvexInertiaPath =
@@ -405,6 +409,25 @@ TEST_F(MjCMeshTest, TinyMeshLoads) {
mj_deleteModel(model);
}
// ------------- test max hull vert -------------------------------------------
TEST_F(MjCMeshTest, MaxHullVert) {
const std::string xml_path = GetTestDataFilePath(kTorusMaxhullVertPath);
std::array<char, 1024> error;
mjModel* model = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size());
ASSERT_GT(model->ngeom, 0);
ASSERT_EQ(model->mesh_graph[0], 4);
mj_deleteModel(model);
}
TEST_F(MjCMeshTest, MaxHullVertDefault) {
const std::string xml_path = GetTestDataFilePath(kTorusDefaultMaxhullVertPath);
std::array<char, 1024> error;
mjModel* model = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size());
ASSERT_GT(model->ngeom, 0);
ASSERT_EQ(model->mesh_graph[0], 64);
mj_deleteModel(model);
}
// ------------- test inline loading ------------------------------------------
TEST_F(MjCMeshTest, FaceNormalAutogenerated) {
static constexpr char xml[] = R"(