Added support for GMSH22 surface loading
PiperOrigin-RevId: 629734063 Change-Id: I6a250b81de4e7c8f7520795bfe74a81d719dfb50
This commit is contained in:
committed by
Copybara-Service
parent
57b1dbac65
commit
131b1745db
@@ -3452,9 +3452,10 @@ saving the XML:
|
||||
.. _body-flexcomp-file:
|
||||
|
||||
:at:`file`: :at-val:`string, optional`
|
||||
The name of the file from which a **mesh** or a **gmsh** is loaded. For mesh, the file extentsion is used to
|
||||
determine the file format. Supported formats are the same as in :ref:`mesh assets<asset-mesh>`. For gmsh, the file is
|
||||
expected to be in GMSH format 4.1 or 2.2, ascii or binary, see :ref:`here<gmsh-file-docs>`.
|
||||
The name of the file from which a **surface** (triangular) or **volumetric** (tetrahedral) mesh is loaded. For
|
||||
surface meshes, the file extension is used to determine the file format. Supported formats are the same as in
|
||||
:ref:`mesh assets<asset-mesh>` and also including GMSH. Volumetric meshes are supported only in GMSH format.
|
||||
See :ref:`here<gmsh-file-docs>` for more information on GMSH files.
|
||||
|
||||
.. _body-flexcomp-rigid:
|
||||
|
||||
|
||||
+18
-17
@@ -24,39 +24,40 @@ General
|
||||
field.
|
||||
4. The type of the ``size`` argument of :ref:`mj_stackAllocNum` and :ref:`mj_stackAllocInt` was changed from ``int``
|
||||
to ``size_t``.
|
||||
5. Added support for gmsh format version 2.2 surface meshes in :ref:`flexcomp<body-flexcomp-file>`.
|
||||
|
||||
MJX
|
||||
^^^
|
||||
.. admonition:: Breaking API changes
|
||||
:class: attention
|
||||
|
||||
5. Removed deprecated ``mjx.device_get_into`` and ``mjx.device_put`` functions as they lack critical new
|
||||
6. Removed deprecated ``mjx.device_get_into`` and ``mjx.device_put`` functions as they lack critical new
|
||||
functionality.
|
||||
|
||||
**Migration:** Use ``mjx.get_data_into`` instead of ``mjx.device_get_into``, and ``mjx.put_data`` instead of
|
||||
``mjx.device_put``.
|
||||
|
||||
6. Added cylinder plane collisions.
|
||||
7. Added ``efc_type`` to ``mjx.Data`` and ``dim``, ``efc_address`` to ``mjx.Contact``.
|
||||
8. Added ``geom`` to ``mjx.Contact`` and marked ``geom1``, ``geom2`` deprecated.
|
||||
9. Added ``ne``, ``nf``, ``nl``, ``nefc``, and ``ncon`` to ``mjx.Data`` to match ``mujoco.MjData``.
|
||||
10. Given the above added fields, removed ``mjx.get_params``, ``mjx.ncon``, and ``mjx.count_constraints``.
|
||||
11. Changed the way meshes are organized on device to speed up collision detection when a mesh is replicated for many
|
||||
7. Added cylinder plane collisions.
|
||||
8. Added ``efc_type`` to ``mjx.Data`` and ``dim``, ``efc_address`` to ``mjx.Contact``.
|
||||
9. Added ``geom`` to ``mjx.Contact`` and marked ``geom1``, ``geom2`` deprecated.
|
||||
10. Added ``ne``, ``nf``, ``nl``, ``nefc``, and ``ncon`` to ``mjx.Data`` to match ``mujoco.MjData``.
|
||||
11. Given the above added fields, removed ``mjx.get_params``, ``mjx.ncon``, and ``mjx.count_constraints``.
|
||||
12. Changed the way meshes are organized on device to speed up collision detection when a mesh is replicated for many
|
||||
geoms.
|
||||
12. Fixed a bug where capsules might be ignored in broadphase colliision checking.
|
||||
13. Added cylinder collisions using SDFs.
|
||||
14. Added support for all :ref:`condim <coContact>`: 1, 3, 4, 6.
|
||||
15. Add support functions for ``id2name`` and ``name2id``, MJX versions of :ref:`mj_id2name` and :ref:`mj_name2id`.
|
||||
16. Added support for :ref:`gravcomp<body-gravcomp>` and :ref:`actuatorgravcomp<body-joint-actuatorgravcomp>`.
|
||||
17. Fixed a bug in ``mjx.ray`` for sometimes allowed negative distances for ray-mesh tests.
|
||||
13. Fixed a bug where capsules might be ignored in broadphase colliision checking.
|
||||
14. Added cylinder collisions using SDFs.
|
||||
15. Added support for all :ref:`condim <coContact>`: 1, 3, 4, 6.
|
||||
16. Add support functions for ``id2name`` and ``name2id``, MJX versions of :ref:`mj_id2name` and :ref:`mj_name2id`.
|
||||
17. Added support for :ref:`gravcomp<body-gravcomp>` and :ref:`actuatorgravcomp<body-joint-actuatorgravcomp>`.
|
||||
18. Fixed a bug in ``mjx.ray`` for sometimes allowed negative distances for ray-mesh tests.
|
||||
|
||||
Bug fixes
|
||||
^^^^^^^^^
|
||||
18. Defaults of lights were not being saved, now fixed.
|
||||
19. Prevent overwriting of frame names by body names when saving an XML. Bug introduced in 3.1.4.
|
||||
20. Fixed bug in Python binding of :ref:`mj_saveModel`: ``buffer`` argument was documented as optional but was actually
|
||||
19. Defaults of lights were not being saved, now fixed.
|
||||
20. Prevent overwriting of frame names by body names when saving an XML. Bug introduced in 3.1.4.
|
||||
21. Fixed bug in Python binding of :ref:`mj_saveModel`: ``buffer`` argument was documented as optional but was actually
|
||||
not optional.
|
||||
21. Fixed bug that prevented memory allocations larger than 2.15 GB.
|
||||
22. Fixed bug that prevented memory allocations larger than 2.15 GB.
|
||||
|
||||
|
||||
Version 3.1.4 (April 10th, 2024)
|
||||
|
||||
+54
-17
@@ -62,7 +62,7 @@ static void ReadStrFromBuffer(char* dest, const char* src, int maxlen) {
|
||||
std::strncpy(dest, src, maxlen);
|
||||
}
|
||||
|
||||
bool IsValidElementHeader22(const std::string& line) {
|
||||
bool IsValidElementOrNodeHeader22(const std::string& line) {
|
||||
// making sure characters are numbers
|
||||
for (char c : line) {
|
||||
if (!std::isdigit(c)) {
|
||||
@@ -1296,10 +1296,21 @@ void mjCFlexcomp::LoadGMSH41(char* buffer, int binary, int nodeend,
|
||||
// load GMSH format 2.2
|
||||
void mjCFlexcomp::LoadGMSH22(char* buffer, int binary, int nodeend,
|
||||
int nodebegin, int elemend, int elembegin) {
|
||||
// number of nodes
|
||||
size_t numNodes = 0;
|
||||
|
||||
// ascii nodes
|
||||
if (binary == 0) {
|
||||
// convert node char buffer to stringstream
|
||||
stringstream ss(std::string(buffer + nodebegin, nodeend - nodebegin));
|
||||
std::string line;
|
||||
|
||||
// checking header template
|
||||
std::getline(ss, line);
|
||||
if (!IsValidElementOrNodeHeader22(line)) {
|
||||
throw mjCError(NULL, "Invalid node header");
|
||||
}
|
||||
ss.seekg(-(line.size()+1), std::ios::cur);
|
||||
|
||||
// read header
|
||||
size_t maxNodeTag = 0;
|
||||
@@ -1307,7 +1318,7 @@ void mjCFlexcomp::LoadGMSH22(char* buffer, int binary, int nodeend,
|
||||
if (!ss.good()) {
|
||||
throw mjCError(NULL, "Error reading Nodes header");
|
||||
}
|
||||
size_t numNodes = maxNodeTag;
|
||||
numNodes = maxNodeTag;
|
||||
|
||||
if (numNodes < 0 || numNodes >= INT_MAX / 3) {
|
||||
throw mjCError(NULL, "Invalid number of nodes.");
|
||||
@@ -1349,7 +1360,7 @@ void mjCFlexcomp::LoadGMSH22(char* buffer, int binary, int nodeend,
|
||||
ReadStrFromBuffer(maxNodeTagChar, buffer + nodebegin, std::min(10, nodeend - nodebegin));
|
||||
size_t measuredHeaderSize = strnlen(maxNodeTagChar, 10) - 1;
|
||||
size_t maxNodeTag = std::stoi(maxNodeTagChar);
|
||||
size_t numNodes = maxNodeTag;
|
||||
numNodes = maxNodeTag;
|
||||
|
||||
// check number of nodes is a positive number
|
||||
if (numNodes < 0) {
|
||||
@@ -1396,7 +1407,7 @@ void mjCFlexcomp::LoadGMSH22(char* buffer, int binary, int nodeend,
|
||||
|
||||
// checking header template
|
||||
std::getline(ss, line);
|
||||
if (!IsValidElementHeader22(line)) {
|
||||
if (!IsValidElementOrNodeHeader22(line)) {
|
||||
throw mjCError(NULL, "Invalid elements header");
|
||||
}
|
||||
ss.seekg(-(line.size()+1), std::ios::cur);
|
||||
@@ -1404,7 +1415,7 @@ void mjCFlexcomp::LoadGMSH22(char* buffer, int binary, int nodeend,
|
||||
size_t maxElementTag = 0;
|
||||
ss >> maxElementTag;
|
||||
if (!ss.good()) {
|
||||
throw mjCError(NULL, "GetMaxElementTag::Error reading Elements header");
|
||||
throw mjCError(NULL, "Error reading Elements header");
|
||||
}
|
||||
size_t numElements = maxElementTag;
|
||||
|
||||
@@ -1419,18 +1430,30 @@ void mjCFlexcomp::LoadGMSH22(char* buffer, int binary, int nodeend,
|
||||
}
|
||||
|
||||
// reading first element's type
|
||||
int tag = 0, type = 0, numTags = 0;
|
||||
ss >> tag >> type >> numTags;
|
||||
int tag = 0, elementType = 0, numTags = 0;
|
||||
ss >> tag >> elementType >> numTags;
|
||||
if (!ss.good()) {
|
||||
throw mjCError(NULL, "Error reading Elements");
|
||||
}
|
||||
int numNodeTags = type;
|
||||
|
||||
size_t entityDim = 0;
|
||||
int numNodeTags = 0;
|
||||
// surface
|
||||
if (elementType == 2) {
|
||||
entityDim = 2;
|
||||
numNodeTags = 3;
|
||||
}
|
||||
// tetrahedral
|
||||
else if (elementType == 4) {
|
||||
entityDim = 3;
|
||||
numNodeTags = 4;
|
||||
}
|
||||
|
||||
if (numNodeTags < 1 || numNodeTags >4) {
|
||||
throw mjCError(NULL, "Invalid number of node tags");
|
||||
}
|
||||
|
||||
// setting entityDim
|
||||
size_t entityDim = numNodeTags - 1;
|
||||
def.spec.flex->dim = entityDim;
|
||||
|
||||
// read elements, discard all tags
|
||||
@@ -1438,7 +1461,7 @@ void mjCFlexcomp::LoadGMSH22(char* buffer, int binary, int nodeend,
|
||||
for (size_t i=0; i<numElements; i++) {
|
||||
int nodeTag = 0, physicalEntityTag = 0, elmentModelEntityTag = 0;
|
||||
if (i != 0) {
|
||||
ss >> tag >> type >> numTags;
|
||||
ss >> tag >> elementType >> numTags;
|
||||
if (!ss.good()) {
|
||||
throw mjCError(NULL, "Error reading Elements");
|
||||
}
|
||||
@@ -1454,7 +1477,7 @@ void mjCFlexcomp::LoadGMSH22(char* buffer, int binary, int nodeend,
|
||||
if (!ss.good()) {
|
||||
throw mjCError(NULL, "Error reading Elements");
|
||||
}
|
||||
if (nodeTag > numElements || nodeTag < 1) {
|
||||
if (nodeTag > numNodes || nodeTag < 1) {
|
||||
throw mjCError(NULL, "Invalid node tag");
|
||||
}
|
||||
element.push_back((int)(nodeTag-1));
|
||||
@@ -1464,7 +1487,7 @@ void mjCFlexcomp::LoadGMSH22(char* buffer, int binary, int nodeend,
|
||||
// binary elements
|
||||
else {
|
||||
// header size for gmshApp
|
||||
constexpr int elementHeaderSizeGmshApp = 6;
|
||||
constexpr int elementHeaderSizeGmshApp = 4;
|
||||
// header size for Ftetwild
|
||||
constexpr int elementHeaderSizeFtetwild = 17;
|
||||
// check header size
|
||||
@@ -1480,7 +1503,7 @@ void mjCFlexcomp::LoadGMSH22(char* buffer, int binary, int nodeend,
|
||||
int numElements = maxElementTag;
|
||||
int tag, numTags;
|
||||
int nodeTag;
|
||||
int numNodeTags;
|
||||
int elementType;
|
||||
|
||||
// check number of elements is a positive number
|
||||
if (numElements < 0) {
|
||||
@@ -1491,14 +1514,28 @@ void mjCFlexcomp::LoadGMSH22(char* buffer, int binary, int nodeend,
|
||||
int componentSize = sizeof(int);
|
||||
// element buffer
|
||||
const char* elementsBuffer = buffer + elembegin + measuredHeaderSize;
|
||||
ReadFromBuffer(&numNodeTags, elementsBuffer);
|
||||
ReadFromBuffer(&elementType, elementsBuffer);
|
||||
ReadFromBuffer(&numTags, elementsBuffer + componentSize*2);
|
||||
ReadFromBuffer(&tag, elementsBuffer + componentSize*3);
|
||||
|
||||
// tetrahedral has 4 node tags and surface has 3
|
||||
int numNodeTags = 0;
|
||||
size_t entityDim = 0;
|
||||
// surface
|
||||
if (elementType == 2) {
|
||||
entityDim = 2;
|
||||
numNodeTags = 3;
|
||||
}
|
||||
// tetrahedral
|
||||
else if (elementType == 4) {
|
||||
entityDim = 3;
|
||||
numNodeTags = 4;
|
||||
}
|
||||
|
||||
if (numNodeTags < 1 || numNodeTags >4) {
|
||||
throw mjCError(NULL, "Invalid number of node tags");
|
||||
}
|
||||
size_t entityDim = numNodeTags - 1;
|
||||
|
||||
def.spec.flex->dim = entityDim;
|
||||
|
||||
// element data(Ftetwild): tag and 4 nodeTag
|
||||
@@ -1534,7 +1571,7 @@ void mjCFlexcomp::LoadGMSH22(char* buffer, int binary, int nodeend,
|
||||
// read first element
|
||||
for (int k =0; k<numNodeTags; k++) {
|
||||
ReadFromBuffer(&nodeTag, elementsBuffer + componentSize*(6+k));
|
||||
if (nodeTag > numElements || nodeTag < 1) {
|
||||
if (nodeTag > numNodes || nodeTag < 1) {
|
||||
throw mjCError(NULL, "Invalid node tag");
|
||||
}
|
||||
element.push_back(nodeTag-1);
|
||||
@@ -1564,7 +1601,7 @@ void mjCFlexcomp::LoadGMSH22(char* buffer, int binary, int nodeend,
|
||||
for (int k = 0; k < numNodeTags; k++) {
|
||||
const char* nodeTagBuffer = elementsBuffer + componentSize*(4+k);
|
||||
ReadFromBuffer(&nodeTag, nodeTagBuffer);
|
||||
if (nodeTag > numElements || nodeTag < 1) {
|
||||
if (nodeTag > numNodes || nodeTag < 1) {
|
||||
throw mjCError(NULL, "Invalid node tag");
|
||||
}
|
||||
element.push_back(nodeTag-1);
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
$MeshFormat
|
||||
2.2 0 8
|
||||
$EndMeshFormat
|
||||
$Nodes
|
||||
14
|
||||
1 -0.5 -0.5 0
|
||||
2 0.5 -0.5 0
|
||||
3 0.5 0.5 0
|
||||
4 -0.5 0.5 0
|
||||
5 -0.5 -0.5 1
|
||||
6 0.5 -0.5 1
|
||||
7 0.5 0.5 1
|
||||
8 -0.5 0.5 1
|
||||
9 0 0 0
|
||||
10 0 -0.5 0.5
|
||||
11 0.5 0 0.5
|
||||
12 0 0.5 0.5
|
||||
13 -0.5 0 0.5
|
||||
14 0 0 1
|
||||
$EndNodes
|
||||
$Elements
|
||||
24
|
||||
1 2 2 0 1 9 4 3
|
||||
2 2 2 0 1 9 3 2
|
||||
3 2 2 0 1 9 1 4
|
||||
4 2 2 0 1 9 2 1
|
||||
5 2 2 0 1 2 10 1
|
||||
6 2 2 0 1 1 10 5
|
||||
7 2 2 0 1 6 10 2
|
||||
8 2 2 0 1 5 10 6
|
||||
9 2 2 0 1 3 11 2
|
||||
10 2 2 0 1 2 11 6
|
||||
11 2 2 0 1 7 11 3
|
||||
12 2 2 0 1 6 11 7
|
||||
13 2 2 0 1 4 12 3
|
||||
14 2 2 0 1 3 12 7
|
||||
15 2 2 0 1 8 12 4
|
||||
16 2 2 0 1 7 12 8
|
||||
17 2 2 0 1 1 13 4
|
||||
18 2 2 0 1 5 13 1
|
||||
19 2 2 0 1 4 13 8
|
||||
20 2 2 0 1 8 13 5
|
||||
21 2 2 0 1 5 6 14
|
||||
22 2 2 0 1 8 5 14
|
||||
23 2 2 0 1 6 7 14
|
||||
24 2 2 0 1 7 8 14
|
||||
$EndElements
|
||||
@@ -0,0 +1,26 @@
|
||||
<mujoco model="gmsh">
|
||||
<option timestep="0.01" integrator="implicitfast" solver="CG"/>
|
||||
|
||||
<asset>
|
||||
<texture type="skybox" builtin="gradient" rgb1=".3 .5 .7" rgb2="0 0 0" width="512" height="512"/>
|
||||
<texture name="grid" type="2d" builtin="checker" width="512" height="512" rgb1=".1 .2 .3" rgb2=".2 .3 .4"/>
|
||||
<material name="grid" texture="grid" texrepeat="1 1" texuniform="true" reflectance=".2"/>
|
||||
</asset>
|
||||
|
||||
<visual>
|
||||
<headlight diffuse="0.9 0.9 0.9" ambient="0.3 0.3 0.3" specular="0 0 0"/>
|
||||
<map force="0.1" zfar="30"/>
|
||||
<rgba haze="0.15 0.25 0.35 1"/>
|
||||
<quality shadowsize="4096"/>
|
||||
<global offwidth="800" offheight="800"/>
|
||||
</visual>
|
||||
|
||||
<worldbody>
|
||||
<geom name="floor" size="1 1 .05" type="plane" material="grid" condim="3"/>
|
||||
<light directional="false" diffuse=".2 .2 .2" specular="0 0 0" pos="0 0 5" dir="0 0 -1"/>
|
||||
<flexcomp name="cube" type="gmsh" dim="2" rgba=".8 .2 .2 1" radius="0.001" pos="0 0 0"
|
||||
mass="10" scale="1 1 1" file="cube_22_ascii_surf_gmshApp.msh">
|
||||
<edge equality="true"/>
|
||||
</flexcomp>
|
||||
</worldbody>
|
||||
</mujoco>
|
||||
Binary file not shown.
@@ -0,0 +1,26 @@
|
||||
<mujoco model="gmsh">
|
||||
<option timestep="0.01" integrator="implicitfast" solver="CG"/>
|
||||
|
||||
<asset>
|
||||
<texture type="skybox" builtin="gradient" rgb1=".3 .5 .7" rgb2="0 0 0" width="512" height="512"/>
|
||||
<texture name="grid" type="2d" builtin="checker" width="512" height="512" rgb1=".1 .2 .3" rgb2=".2 .3 .4"/>
|
||||
<material name="grid" texture="grid" texrepeat="1 1" texuniform="true" reflectance=".2"/>
|
||||
</asset>
|
||||
|
||||
<visual>
|
||||
<headlight diffuse="0.9 0.9 0.9" ambient="0.3 0.3 0.3" specular="0 0 0"/>
|
||||
<map force="0.1" zfar="30"/>
|
||||
<rgba haze="0.15 0.25 0.35 1"/>
|
||||
<quality shadowsize="4096"/>
|
||||
<global offwidth="800" offheight="800"/>
|
||||
</visual>
|
||||
|
||||
<worldbody>
|
||||
<geom name="floor" size="1 1 .05" type="plane" material="grid" condim="3"/>
|
||||
<light directional="false" diffuse=".2 .2 .2" specular="0 0 0" pos="0 0 5" dir="0 0 -1"/>
|
||||
<flexcomp name="cube" type="gmsh" dim="2" rgba=".8 .2 .2 1" radius="0.001" pos="0 0 0"
|
||||
mass="10" scale="1 1 1" file="cube_22_binary_surf_gmshApp.msh">
|
||||
<edge equality="true"/>
|
||||
</flexcomp>
|
||||
</worldbody>
|
||||
</mujoco>
|
||||
@@ -0,0 +1,67 @@
|
||||
$MeshFormat
|
||||
4.1 0 8
|
||||
$EndMeshFormat
|
||||
$Entities
|
||||
0 0 1 0
|
||||
1 -0.5 -0.5 0 0.5 0.5 1 0 0
|
||||
$EndEntities
|
||||
$Nodes
|
||||
1 14 1 14
|
||||
2 1 0 14
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
||||
11
|
||||
12
|
||||
13
|
||||
14
|
||||
-0.5 -0.5 0
|
||||
0.5 -0.5 0
|
||||
0.5 0.5 0
|
||||
-0.5 0.5 0
|
||||
-0.5 -0.5 1
|
||||
0.5 -0.5 1
|
||||
0.5 0.5 1
|
||||
-0.5 0.5 1
|
||||
0 0 0
|
||||
0 -0.5 0.5
|
||||
0.5 0 0.5
|
||||
0 0.5 0.5
|
||||
-0.5 0 0.5
|
||||
0 0 1
|
||||
$EndNodes
|
||||
$Elements
|
||||
1 24 1 24
|
||||
2 1 2 24
|
||||
1 9 4 3
|
||||
2 9 3 2
|
||||
3 9 1 4
|
||||
4 9 2 1
|
||||
5 2 10 1
|
||||
6 1 10 5
|
||||
7 6 10 2
|
||||
8 5 10 6
|
||||
9 3 11 2
|
||||
10 2 11 6
|
||||
11 7 11 3
|
||||
12 6 11 7
|
||||
13 4 12 3
|
||||
14 3 12 7
|
||||
15 8 12 4
|
||||
16 7 12 8
|
||||
17 1 13 4
|
||||
18 5 13 1
|
||||
19 4 13 8
|
||||
20 8 13 5
|
||||
21 5 6 14
|
||||
22 8 5 14
|
||||
23 6 7 14
|
||||
24 7 8 14
|
||||
$EndElements
|
||||
@@ -0,0 +1,26 @@
|
||||
<mujoco model="gmsh">
|
||||
<option timestep="0.01" integrator="implicitfast" solver="CG"/>
|
||||
|
||||
<asset>
|
||||
<texture type="skybox" builtin="gradient" rgb1=".3 .5 .7" rgb2="0 0 0" width="512" height="512"/>
|
||||
<texture name="grid" type="2d" builtin="checker" width="512" height="512" rgb1=".1 .2 .3" rgb2=".2 .3 .4"/>
|
||||
<material name="grid" texture="grid" texrepeat="1 1" texuniform="true" reflectance=".2"/>
|
||||
</asset>
|
||||
|
||||
<visual>
|
||||
<headlight diffuse="0.9 0.9 0.9" ambient="0.3 0.3 0.3" specular="0 0 0"/>
|
||||
<map force="0.1" zfar="30"/>
|
||||
<rgba haze="0.15 0.25 0.35 1"/>
|
||||
<quality shadowsize="4096"/>
|
||||
<global offwidth="800" offheight="800"/>
|
||||
</visual>
|
||||
|
||||
<worldbody>
|
||||
<geom name="floor" size="1 1 .05" type="plane" material="grid" condim="3"/>
|
||||
<light directional="false" diffuse=".2 .2 .2" specular="0 0 0" pos="0 0 5" dir="0 0 -1"/>
|
||||
<flexcomp name="cube" type="gmsh" dim="2" rgba=".8 .2 .2 1" radius="0.001" pos="0 0 0"
|
||||
mass="10" scale="1 1 1" file="cube_41_ascii_surf_gmshApp.msh">
|
||||
<edge equality="true"/>
|
||||
</flexcomp>
|
||||
</worldbody>
|
||||
</mujoco>
|
||||
Binary file not shown.
@@ -0,0 +1,26 @@
|
||||
<mujoco model="gmsh">
|
||||
<option timestep="0.01" integrator="implicitfast" solver="CG"/>
|
||||
|
||||
<asset>
|
||||
<texture type="skybox" builtin="gradient" rgb1=".3 .5 .7" rgb2="0 0 0" width="512" height="512"/>
|
||||
<texture name="grid" type="2d" builtin="checker" width="512" height="512" rgb1=".1 .2 .3" rgb2=".2 .3 .4"/>
|
||||
<material name="grid" texture="grid" texrepeat="1 1" texuniform="true" reflectance=".2"/>
|
||||
</asset>
|
||||
|
||||
<visual>
|
||||
<headlight diffuse="0.9 0.9 0.9" ambient="0.3 0.3 0.3" specular="0 0 0"/>
|
||||
<map force="0.1" zfar="30"/>
|
||||
<rgba haze="0.15 0.25 0.35 1"/>
|
||||
<quality shadowsize="4096"/>
|
||||
<global offwidth="800" offheight="800"/>
|
||||
</visual>
|
||||
|
||||
<worldbody>
|
||||
<geom name="floor" size="1 1 .05" type="plane" material="grid" condim="3"/>
|
||||
<light directional="false" diffuse=".2 .2 .2" specular="0 0 0" pos="0 0 5" dir="0 0 -1"/>
|
||||
<flexcomp name="cube" type="gmsh" dim="2" rgba=".8 .2 .2 1" radius="0.001" pos="0 0 0"
|
||||
mass="10" scale="1 1 1" file="cube_41_binary_surf_gmshApp.msh">
|
||||
<edge equality="true"/>
|
||||
</flexcomp>
|
||||
</worldbody>
|
||||
</mujoco>
|
||||
@@ -19,7 +19,7 @@
|
||||
<worldbody>
|
||||
<geom name="floor" size="20 20 .05" type="plane" material="grid" condim="3" />
|
||||
<light directional="false" diffuse=".2 .2 .2" specular="0 0 0" pos="0 0 5" dir="0 0 -1" />
|
||||
<flexcomp name="shark binary 2.2" type="gmsh" rgba=".8 .2 .2 1" radius="0.001" pos="0 0 4"
|
||||
<flexcomp name="shark binary 2.2" type="gmsh" dim="3" rgba=".8 .2 .2 1" radius="0.001" pos="0 0 4"
|
||||
mass="10" scale="1 1 1" file="shark_41_ascii_missing_node_index.msh">
|
||||
<edge equality="true" />
|
||||
</flexcomp>
|
||||
|
||||
@@ -8,7 +8,6 @@ $EndEntities
|
||||
$Nodes
|
||||
1 652 1 652
|
||||
3 0 0 652
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
|
||||
+108
-3
@@ -23,6 +23,8 @@
|
||||
#include <mujoco/mujoco.h>
|
||||
#include "test/fixture.h"
|
||||
|
||||
|
||||
|
||||
namespace mujoco {
|
||||
namespace {
|
||||
|
||||
@@ -32,6 +34,8 @@ using ::testing::HasSubstr;
|
||||
using UserFlexTest = MujocoTest;
|
||||
|
||||
|
||||
|
||||
|
||||
TEST_F(UserFlexTest, ParentMustHaveName) {
|
||||
static constexpr char xml[] = R"(
|
||||
<mujoco>
|
||||
@@ -255,6 +259,56 @@ TEST_F(UserFlexTest, LoadMSHBinaryGMSH_22_Success) {
|
||||
mj_deleteData(d);
|
||||
}
|
||||
|
||||
TEST_F(UserFlexTest, LoadMSHSurfaceBinaryGMSH_41_Success) {
|
||||
const std::string xml_path =
|
||||
GetTestDataFilePath("user/testdata/cube_41_binary_surf_gmshApp.xml");
|
||||
std::array<char, 1024> error;
|
||||
mjModel* m = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size());
|
||||
ASSERT_THAT(m, NotNull()) << error.data();
|
||||
mjData* d = mj_makeData(m);
|
||||
EXPECT_EQ(m->nflexvert, 14);
|
||||
EXPECT_EQ(m->nflexelem, 24);
|
||||
|
||||
// first node x y z
|
||||
EXPECT_EQ(m->flex_xvert0[0], -0.5 );
|
||||
EXPECT_EQ(m->flex_xvert0[1], -0.5 );
|
||||
EXPECT_EQ(m->flex_xvert0[2], 0 );
|
||||
|
||||
// first element
|
||||
EXPECT_EQ(m->flex_elem[0], 9-1 );
|
||||
EXPECT_EQ(m->flex_elem[1], 4-1 );
|
||||
EXPECT_EQ(m->flex_elem[2], 3-1 );
|
||||
|
||||
mj_step(m, d);
|
||||
mj_deleteModel(m);
|
||||
mj_deleteData(d);
|
||||
}
|
||||
|
||||
TEST_F(UserFlexTest, LoadMSHSurfaceBinaryGMSH_22_Success) {
|
||||
const std::string xml_path =
|
||||
GetTestDataFilePath("user/testdata/cube_22_binary_surf_gmshApp.xml");
|
||||
std::array<char, 1024> error;
|
||||
mjModel* m = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size());
|
||||
ASSERT_THAT(m, NotNull()) << error.data();
|
||||
mjData* d = mj_makeData(m);
|
||||
EXPECT_EQ(m->nflexvert, 14);
|
||||
EXPECT_EQ(m->nflexelem, 24);
|
||||
|
||||
// first node x y z
|
||||
EXPECT_EQ(m->flex_xvert0[0], -0.5 );
|
||||
EXPECT_EQ(m->flex_xvert0[1], -0.5 );
|
||||
EXPECT_EQ(m->flex_xvert0[2], 0 );
|
||||
|
||||
// first element
|
||||
EXPECT_EQ(m->flex_elem[0], 9-1 );
|
||||
EXPECT_EQ(m->flex_elem[1], 4-1 );
|
||||
EXPECT_EQ(m->flex_elem[2], 3-1 );
|
||||
|
||||
mj_step(m, d);
|
||||
mj_deleteModel(m);
|
||||
mj_deleteData(d);
|
||||
}
|
||||
|
||||
TEST_F(UserFlexTest, LoadMSHBinaryFTETWILD_22_Success) {
|
||||
const std::string xml_path =
|
||||
GetTestDataFilePath("user/testdata/shark_22_binary_fTetWild.xml");
|
||||
@@ -297,6 +351,56 @@ TEST_F(UserFlexTest, LoadMSHASCIIGMSH_22_Success) {
|
||||
mj_deleteData(d);
|
||||
}
|
||||
|
||||
TEST_F(UserFlexTest, LoadMSHSurfaceASCIIGMSH_41_Success) {
|
||||
const std::string xml_path =
|
||||
GetTestDataFilePath("user/testdata/cube_41_ascii_surf_gmshApp.xml");
|
||||
std::array<char, 1024> error;
|
||||
mjModel* m = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size());
|
||||
ASSERT_THAT(m, NotNull()) << error.data();
|
||||
mjData* d = mj_makeData(m);
|
||||
EXPECT_EQ(m->nflexvert, 14);
|
||||
EXPECT_EQ(m->nflexelem, 24);
|
||||
|
||||
// first node x y z
|
||||
EXPECT_EQ(m->flex_xvert0[0], -0.5 );
|
||||
EXPECT_EQ(m->flex_xvert0[1], -0.5 );
|
||||
EXPECT_EQ(m->flex_xvert0[2], 0 );
|
||||
|
||||
// first element
|
||||
EXPECT_EQ(m->flex_elem[0], 9-1 );
|
||||
EXPECT_EQ(m->flex_elem[1], 4-1 );
|
||||
EXPECT_EQ(m->flex_elem[2], 3-1 );
|
||||
|
||||
mj_step(m, d);
|
||||
mj_deleteModel(m);
|
||||
mj_deleteData(d);
|
||||
}
|
||||
|
||||
TEST_F(UserFlexTest, LoadMSHSurfaceASCIIGMSH_22_Success) {
|
||||
const std::string xml_path =
|
||||
GetTestDataFilePath("user/testdata/cube_22_ascii_surf_gmshApp.xml");
|
||||
std::array<char, 1024> error;
|
||||
mjModel* m = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size());
|
||||
ASSERT_THAT(m, NotNull()) << error.data();
|
||||
mjData* d = mj_makeData(m);
|
||||
EXPECT_EQ(m->nflexvert, 14);
|
||||
EXPECT_EQ(m->nflexelem, 24);
|
||||
|
||||
// first node x y z
|
||||
EXPECT_EQ(m->flex_xvert0[0], -0.5 );
|
||||
EXPECT_EQ(m->flex_xvert0[1], -0.5 );
|
||||
EXPECT_EQ(m->flex_xvert0[2], 0 );
|
||||
|
||||
// first element
|
||||
EXPECT_EQ(m->flex_elem[0], 9-1 );
|
||||
EXPECT_EQ(m->flex_elem[1], 4-1 );
|
||||
EXPECT_EQ(m->flex_elem[2], 3-1 );
|
||||
|
||||
mj_step(m, d);
|
||||
mj_deleteModel(m);
|
||||
mj_deleteData(d);
|
||||
}
|
||||
|
||||
TEST_F(UserFlexTest, LoadMSHASCIIFTETWILD_22_Success) {
|
||||
const std::string xml_path =
|
||||
GetTestDataFilePath("user/testdata/shark_22_ascii_fTetWild.xml");
|
||||
@@ -329,7 +433,7 @@ TEST_F(UserFlexTest, LoadMSHASCII_41_MissingNodeIndex_Fail) {
|
||||
std::array<char, 1024> error;
|
||||
mjModel* m = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size());
|
||||
EXPECT_THAT(error.data(), HasSubstr(
|
||||
"XML Error: Element size must be a multiple of dim+1"));
|
||||
"XML Error: Error: Node tags must be sequential"));
|
||||
mj_deleteModel(m);
|
||||
}
|
||||
|
||||
@@ -361,8 +465,9 @@ TEST_F(UserFlexTest, LoadMSHASCII_22_MissingNumNodes_Fail) {
|
||||
"user/testdata/malformed_shark_22_ascii_missing_num_nodes.xml");
|
||||
std::array<char, 1024> error;
|
||||
mjModel* m = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size());
|
||||
EXPECT_THAT(error.data(), HasSubstr(
|
||||
"XML Error: Element size must be a multiple of dim+1"));
|
||||
// TODO(mohammadhamid): Replace with an assertion about the error message. For
|
||||
// some reason, on Windows the error message is different on GH Actions
|
||||
EXPECT_THAT(m, IsNull());
|
||||
mj_deleteModel(m);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user