Skip to content

Commit a0be19f

Browse files
ahcordechapulina
andauthored
Added Material pybind11 interface (#340)
Signed-off-by: Alejandro Hernández <ahcorde@gmail.com> Co-authored-by: Louise Poubel <louise@openrobotics.org>
1 parent bb43b30 commit a0be19f

6 files changed

Lines changed: 170 additions & 16 deletions

File tree

src/python/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ if (PYTHONLIBS_FOUND)
9595
GaussMarkovProcess_TEST
9696
Inertial_TEST
9797
MassMatrix3_TEST
98-
Material_TEST
9998
Matrix4_TEST
10099
OrientedBox_TEST
101100
PID_TEST

src/python_pybind11/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ if (${pybind11_FOUND})
1818
src/Color.cc
1919
src/Helpers.cc
2020
src/Kmeans.cc
21+
src/Material.cc
2122
src/Rand.cc
2223
src/RollingMean.cc
2324
src/SemanticVersion.cc
@@ -82,6 +83,7 @@ if (${pybind11_FOUND})
8283
Kmeans_TEST
8384
Line2_TEST
8485
Line3_TEST
86+
Material_TEST
8587
Matrix3_TEST
8688
MovingWindowFilter_TEST
8789
Pose3_TEST
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* Copyright (C) 2021 Open Source Robotics Foundation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
#include <limits>
18+
#include <map>
19+
#include <string>
20+
21+
#include "Material.hh"
22+
#include <ignition/math/Material.hh>
23+
#include <ignition/math/MaterialType.hh>
24+
25+
#include <pybind11/operators.h>
26+
#include <pybind11/stl_bind.h>
27+
28+
namespace ignition
29+
{
30+
namespace math
31+
{
32+
namespace python
33+
{
34+
void defineMathMaterial(py::module &m, const std::string &typestr)
35+
{
36+
37+
py::bind_map<std::map<
38+
ignition::math::MaterialType, ignition::math::Material>>
39+
(m, "MaterialMap");
40+
41+
using Class = ignition::math::Material;
42+
std::string pyclass_name = typestr;
43+
py::class_<Class> (m,
44+
pyclass_name.c_str(),
45+
py::buffer_protocol(),
46+
py::dynamic_attr())
47+
.def(py::init<>())
48+
.def(py::init<const ignition::math::MaterialType>())
49+
.def(py::init<const std::string&>())
50+
.def(py::init<const double>())
51+
.def(py::init<const Class&>())
52+
.def(py::self != py::self)
53+
.def(py::self == py::self)
54+
.def("predefined",
55+
&Class::Predefined,
56+
"Get all the built-in materials.")
57+
.def("set_to_nearest_density",
58+
&Class::SetToNearestDensity,
59+
py::arg("_value") = 0,
60+
py::arg("_epsilon") = std::numeric_limits<double>::max(),
61+
"Set this Material to the built-in Material with "
62+
"the nearest density value within _epsilon. If a built-in material "
63+
"could not be found, then this Material is not changed.")
64+
.def("type",
65+
&Class::Type,
66+
"Set the material's type. This will only set the type value. "
67+
"Other properties, such as density, will not be changed.")
68+
.def("set_type",
69+
&Class::SetType,
70+
"Set the material's type. This will only set the type value. "
71+
"Other properties, such as density, will not be changed.")
72+
.def("name",
73+
&Class::Name,
74+
"Get the name of the material. This will match the enum type "
75+
"names used in ::MaterialType, but in lowercase, if a built-in "
76+
"material is used.")
77+
.def("set_name",
78+
&Class::SetName,
79+
"Set the name of the material.")
80+
.def("set_density",
81+
&Class::SetDensity,
82+
"Set the name of the material.")
83+
.def("density", &Class::Density,
84+
"Set the density value of the material in kg/m^3.");
85+
86+
py::enum_<ignition::math::MaterialType>(m, "MaterialType")
87+
.value("STYROFOAM", ignition::math::MaterialType::STYROFOAM)
88+
.value("PINE", ignition::math::MaterialType::PINE)
89+
.value("WOOD", ignition::math::MaterialType::WOOD)
90+
.value("OAK", ignition::math::MaterialType::OAK)
91+
.value("PLASTIC", ignition::math::MaterialType::PLASTIC)
92+
.value("CONCRETE", ignition::math::MaterialType::CONCRETE)
93+
.value("ALUMINUM", ignition::math::MaterialType::ALUMINUM)
94+
.value("STEEL_ALLOY", ignition::math::MaterialType::STEEL_ALLOY)
95+
.value("STEEL_STAINLESS", ignition::math::MaterialType::STEEL_STAINLESS)
96+
.value("IRON", ignition::math::MaterialType::IRON)
97+
.value("BRASS", ignition::math::MaterialType::BRASS)
98+
.value("COPPER", ignition::math::MaterialType::COPPER)
99+
.value("TUNGSTEN", ignition::math::MaterialType::TUNGSTEN)
100+
.value("UNKNOWN_MATERIAL",
101+
ignition::math::MaterialType::UNKNOWN_MATERIAL)
102+
.export_values();
103+
}
104+
} // namespace python
105+
} // namespace math
106+
} // namespace ignition
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (C) 2021 Open Source Robotics Foundation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
18+
#ifndef IGNITION_MATH_PYTHON__MATERIAL_HH_
19+
#define IGNITION_MATH_PYTHON__MATERIAL_HH_
20+
21+
#include <pybind11/pybind11.h>
22+
#include <string>
23+
24+
namespace py = pybind11;
25+
26+
namespace ignition
27+
{
28+
namespace math
29+
{
30+
namespace python
31+
{
32+
/// Define a pybind11 wrapper for an ignition::math::Material
33+
/**
34+
* \param[in] module a pybind11 module to add the definition to
35+
* \param[in] typestr name of the type used by Python
36+
*/
37+
void defineMathMaterial(py::module &m, const std::string &typestr);
38+
} // namespace python
39+
} // namespace math
40+
} // namespace ignition
41+
42+
#endif // IGNITION_MATH_PYTHON__MATERIAL_HH_

src/python_pybind11/src/_ignition_math_pybind11.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "Kmeans.hh"
2222
#include "Line2.hh"
2323
#include "Line3.hh"
24+
#include "Material.hh"
2425
#include "Matrix3.hh"
2526
#include "MovingWindowFilter.hh"
2627
#include "Pose3.hh"
@@ -50,6 +51,8 @@ PYBIND11_MODULE(math, m)
5051

5152
ignition::math::python::defineMathKmeans(m, "Kmeans");
5253

54+
ignition::math::python::defineMathMaterial(m, "Material");
55+
5356
ignition::math::python::defineMathMovingWindowFilter<int>(
5457
m, "MovingWindowFilteri");
5558
ignition::math::python::defineMathMovingWindowFilter<double>(
Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,32 +26,34 @@ def test_init(self):
2626

2727
# Make sure that the number of elements in the MaterialType enum matches
2828
# the number of elements in the MaterialDensity::materials map.
29-
self.assertEqual(ignition.math.MaterialType_UNKNOWN_MATERIAL, len(mats))
29+
self.assertEqual(ignition.math.MaterialType.UNKNOWN_MATERIAL,
30+
ignition.math.MaterialType(len(mats)))
3031

3132
# Iterate over each element in the enum. Check the that enum value
3233
# matches the type value in the mats map.
33-
for i in range(ignition.math.MaterialType_UNKNOWN_MATERIAL):
34+
for i in range(ignition.math.MaterialType.UNKNOWN_MATERIAL):
3435
# Get the type of the material for MaterialType i.
35-
self.assertEqual(i, next(iter(mats.find(i)))[1].type())
36+
self.assertEqual(ignition.math.MaterialType(i),
37+
mats[ignition.math.MaterialType(i)].type())
3638

3739
# The name should not be empty
38-
self.assertTrue(next(iter(mats.find(i)))[1].name())
40+
self.assertTrue(mats[ignition.math.MaterialType(i)].name())
3941

4042
# The density should be less than the max double value and greater than
4143
# zero.
42-
self.assertLess(next(iter(mats.find(i)))[1].density(), sys.float_info.max)
43-
self.assertGreater(next(iter(mats.find(i)))[1].density(), 0.0)
44+
self.assertLess(mats[ignition.math.MaterialType(i)].density(), sys.float_info.max)
45+
self.assertGreater(mats[ignition.math.MaterialType(i)].density(), 0.0)
4446

45-
malicious = ignition.math.Material(42)
47+
malicious = ignition.math.Material(ignition.math.MaterialType(42))
4648
self.assertEqual(-1.0, malicious.density())
4749
self.assertEqual('', malicious.name())
4850

4951
byDensity = ignition.math.Material(42.2)
5052
self.assertEqual(42.2, byDensity.density())
51-
self.assertEqual(ignition.math.MaterialType_UNKNOWN_MATERIAL, byDensity.type())
53+
self.assertEqual(ignition.math.MaterialType.UNKNOWN_MATERIAL, byDensity.type())
5254

5355
def test_comparison(self):
54-
aluminum = ignition.math.Material(ignition.math.MaterialType_ALUMINUM)
56+
aluminum = ignition.math.Material(ignition.math.MaterialType.ALUMINUM)
5557

5658
modified = ignition.math.Material(aluminum)
5759
self.assertEqual(modified, aluminum)
@@ -62,14 +64,14 @@ def test_comparison(self):
6264
modified = ignition.math.Material(aluminum)
6365
self.assertEqual(modified, aluminum)
6466

65-
modified.set_type(ignition.math.MaterialType_PINE)
67+
modified.set_type(ignition.math.MaterialType.PINE)
6668
self.assertNotEqual(modified, aluminum)
6769

6870
def test_accessors(self):
6971

7072
mat = ignition.math.Material("Aluminum")
7173
mat1 = ignition.math.Material("aluminum")
72-
mat2 = ignition.math.Material(ignition.math.MaterialType_ALUMINUM)
74+
mat2 = ignition.math.Material(ignition.math.MaterialType.ALUMINUM)
7375
mat3 = ignition.math.Material(mat2)
7476

7577
self.assertAlmostEqual(2700.0, mat.density())
@@ -86,23 +88,23 @@ def test_accessors(self):
8688

8789
mat = ignition.math.Material("Notfoundium")
8890
self.assertGreater(0.0, mat.density())
89-
self.assertEqual(ignition.math.MaterialType_UNKNOWN_MATERIAL,
91+
self.assertEqual(ignition.math.MaterialType.UNKNOWN_MATERIAL,
9092
mat.type())
9193
self.assertFalse(mat.name())
9294

9395
material = ignition.math.Material()
9496
material.set_to_nearest_density(19300.0)
95-
self.assertEqual(ignition.math.MaterialType_TUNGSTEN, material.type())
97+
self.assertEqual(ignition.math.MaterialType.TUNGSTEN, material.type())
9698
self.assertAlmostEqual(19300.0, material.density())
9799

98100
material = ignition.math.Material()
99101
material.set_to_nearest_density(1001001.001, 1e-3)
100-
self.assertEqual(ignition.math.MaterialType_UNKNOWN_MATERIAL,
102+
self.assertEqual(ignition.math.MaterialType.UNKNOWN_MATERIAL,
101103
material.type())
102104
self.assertGreater(0.0, material.density())
103105
material = ignition.math.Material()
104106
material.set_to_nearest_density(1001001.001)
105-
self.assertEqual(ignition.math.MaterialType_TUNGSTEN, material.type())
107+
self.assertEqual(ignition.math.MaterialType.TUNGSTEN, material.type())
106108
self.assertAlmostEqual(19300, material.density())
107109

108110

0 commit comments

Comments
 (0)