Skip to content

Commit

Permalink
Added Python wrapper to ConvexDecomposition (#1398)
Browse files Browse the repository at this point in the history
Signed-off-by: Alejandro Hernández Cordero <ahcorde@gmail.com>
Co-authored-by: Ian Chen <ichen@openrobotics.org>
  • Loading branch information
ahcorde and iche033 authored Apr 9, 2024
1 parent e9dd811 commit c8fbdbe
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 1 deletion.
1 change: 1 addition & 0 deletions python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ pybind11_add_module(${BINDINGS_MODULE_NAME} MODULE
src/sdf/pyCamera.cc
src/sdf/pyCapsule.cc
src/sdf/pyCollision.cc
src/sdf/pyConvexDecomposition.cc
src/sdf/pyCylinder.cc
src/sdf/pyElement.cc
src/sdf/pyEllipsoid.cc
Expand Down
2 changes: 2 additions & 0 deletions python/src/sdf/_gz_sdformat_pybind11.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "pyCamera.hh"
#include "pyCapsule.hh"
#include "pyCollision.hh"
#include "pyConvexDecomposition.hh"
#include "pyCylinder.hh"
#include "pyElement.hh"
#include "pyEllipsoid.hh"
Expand Down Expand Up @@ -85,6 +86,7 @@ PYBIND11_MODULE(BINDINGS_MODULE_NAME, m) {
sdf::python::defineCamera(m);
sdf::python::defineCapsule(m);
sdf::python::defineCollision(m);
sdf::python::defineConvexDecomposition(m);
sdf::python::defineContact(m);
sdf::python::defineCylinder(m);
// PrintConfig has to be defined before Param and Element because it's used as
Expand Down
50 changes: 50 additions & 0 deletions python/src/sdf/pyConvexDecomposition.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (C) 2024 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "pyMesh.hh"

#include <pybind11/pybind11.h>

#include "sdf/ParserConfig.hh"
#include "sdf/Mesh.hh"

using namespace pybind11::literals;

namespace sdf
{
// Inline bracket to help doxygen filtering.
inline namespace SDF_VERSION_NAMESPACE {
namespace python
{
/////////////////////////////////////////////////
void defineConvexDecomposition(pybind11::object module)
{
pybind11::class_<sdf::ConvexDecomposition>(module, "ConvexDecomposition")
.def(pybind11::init<>())
.def("max_convex_hulls", &sdf::ConvexDecomposition::MaxConvexHulls,
"Get the maximum number of convex hulls that can be generated.")
.def("set_max_convex_hulls", &sdf::ConvexDecomposition::SetMaxConvexHulls,
"Set the maximum number of convex hulls that can be generated.")
.def("__copy__", [](const sdf::ConvexDecomposition &self) {
return sdf::ConvexDecomposition(self);
})
.def("__deepcopy__", [](const sdf::ConvexDecomposition &self, pybind11::dict) {
return sdf::ConvexDecomposition(self);
}, "memo"_a);
}
} // namespace python
} // namespace SDF_VERSION_NAMESPACE
} // namespace sdf
41 changes: 41 additions & 0 deletions python/src/sdf/pyConvexDecomposition.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (C) 2024 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef SDFORMAT_PYTHON_CONVEX_DECOMPOSITION_HH_
#define SDFORMAT_PYTHON_CONVEX_DECOMPOSITION_HH_

#include <pybind11/pybind11.h>

#include "sdf/Mesh.hh"

#include "sdf/config.hh"

namespace sdf
{
// Inline bracket to help doxygen filtering.
inline namespace SDF_VERSION_NAMESPACE {
namespace python
{
/// Define a pybind11 wrapper for an sdf::ConvexDecomposition
/**
* \param[in] module a pybind11 module to add the definition to
*/
void defineConvexDecomposition(pybind11::object module);
} // namespace python
} // namespace SDF_VERSION_NAMESPACE
} // namespace sdf

#endif // SDFORMAT_PYTHON_CONVEX_DECOMPOSITION_HH_
22 changes: 22 additions & 0 deletions python/src/sdf/pyMesh.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,23 @@ void defineMesh(pybind11::object module)
pybind11::class_<sdf::Mesh>(module, "Mesh")
.def(pybind11::init<>())
.def(pybind11::init<sdf::Mesh>())
.def("optimization", &sdf::Mesh::Optimization,
"Get the mesh's optimization method.")
.def("optimization_str", &sdf::Mesh::OptimizationStr,
"Get the mesh's optimization method")
.def("set_optimization",
pybind11::overload_cast<sdf::MeshOptimization>(
&sdf::Mesh::SetOptimization),
"Set the mesh optimization method.")
.def("set_optimization",
pybind11::overload_cast<const std::string &>(
&sdf::Mesh::SetOptimization),
"Set the mesh optimization method.")
.def("convex_decomposition", &sdf::Mesh::ConvexDecomposition,
pybind11::return_value_policy::reference_internal,
"Get the associated ConvexDecomposition object")
.def("set_convex_decomposition", &sdf::Mesh::SetConvexDecomposition,
"Set the associated ConvexDecomposition object.")
.def("uri", &sdf::Mesh::Uri,
"Get the mesh's URI.")
.def("set_uri", &sdf::Mesh::SetUri,
Expand Down Expand Up @@ -67,6 +84,11 @@ void defineMesh(pybind11::object module)
.def("__deepcopy__", [](const sdf::Mesh &self, pybind11::dict) {
return sdf::Mesh(self);
}, "memo"_a);

pybind11::enum_<sdf::MeshOptimization>(module, "MeshOptimization")
.value("NONE", sdf::MeshOptimization::NONE)
.value("CONVEX_HULL", sdf::MeshOptimization::CONVEX_HULL)
.value("CONVEX_DECOMPOSITION", sdf::MeshOptimization::CONVEX_DECOMPOSITION);
}
} // namespace python
} // namespace SDF_VERSION_NAMESPACE
Expand Down
44 changes: 43 additions & 1 deletion python/test/pyMesh_TEST.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
# limitations under the License.

import copy
from gz_test_deps.sdformat import Mesh
from gz_test_deps.sdformat import Mesh, ConvexDecomposition
from gz_test_deps.math import Vector3d
import gz_test_deps.sdformat as sdf
import unittest


Expand All @@ -23,6 +24,9 @@ class MeshTEST(unittest.TestCase):
def test_default_construction(self):
mesh = Mesh()

self.assertEqual("", mesh.optimization_str())
self.assertEqual(sdf.MeshOptimization.NONE, mesh.optimization())
self.assertEqual(None, mesh.convex_decomposition())
self.assertEqual("", mesh.file_path())
self.assertEqual("", mesh.uri())
self.assertEqual("", mesh.submesh())
Expand All @@ -32,19 +36,29 @@ def test_default_construction(self):

def test_assigment(self):
mesh = Mesh()
self.assertTrue(mesh.set_optimization("convex_decomposition"))
mesh.set_uri("banana")
mesh.set_submesh("watermelon")
mesh.set_center_submesh(True)
mesh.set_scale(Vector3d(0.5, 0.6, 0.7))
mesh.set_file_path("/pear")

convexDecomp = ConvexDecomposition()
convexDecomp.set_max_convex_hulls(10)
mesh.set_convex_decomposition(convexDecomp)

mesh2 = mesh
self.assertEqual("convex_decomposition", mesh2.optimization_str())
self.assertEqual(sdf.MeshOptimization.CONVEX_DECOMPOSITION, mesh2.optimization())
self.assertEqual("banana", mesh2.uri())
self.assertEqual("watermelon", mesh2.submesh())
self.assertEqual(Vector3d(0.5, 0.6, 0.7), mesh2.scale())
self.assertTrue(mesh2.center_submesh())
self.assertEqual("/pear", mesh2.file_path())

convexDecomp2 = mesh2.convex_decomposition()
self.assertEqual(10, convexDecomp2.max_convex_hulls())

mesh.set_file_path("/apple")
self.assertEqual("/apple", mesh2.file_path())

Expand All @@ -63,19 +77,29 @@ def test_assigment(self):

def test_deepcopy_construction(self):
mesh = Mesh()
self.assertTrue(mesh.set_optimization("convex_decomposition"))
mesh.set_uri("banana")
mesh.set_submesh("watermelon")
mesh.set_center_submesh(True)
mesh.set_scale(Vector3d(0.5, 0.6, 0.7))
mesh.set_file_path("/pear")

convexDecomp = ConvexDecomposition()
convexDecomp.set_max_convex_hulls(10)
mesh.set_convex_decomposition(convexDecomp)

mesh2 = copy.deepcopy(mesh)
self.assertEqual("convex_decomposition", mesh2.optimization_str())
self.assertEqual(sdf.MeshOptimization.CONVEX_DECOMPOSITION, mesh2.optimization())
self.assertEqual("banana", mesh2.uri())
self.assertEqual("watermelon", mesh2.submesh())
self.assertEqual(Vector3d(0.5, 0.6, 0.7), mesh2.scale())
self.assertTrue(mesh2.center_submesh())
self.assertEqual("/pear", mesh2.file_path())

convexDecomp2 = mesh2.convex_decomposition()
self.assertEqual(10, convexDecomp2.max_convex_hulls())

mesh.set_file_path("/apple")
mesh.set_scale(Vector3d(0.3, 0.2, 0.4))
mesh.set_center_submesh(False)
Expand All @@ -92,6 +116,24 @@ def test_deepcopy_construction(self):
def test_set(self):
mesh = Mesh()

self.assertEqual("", mesh.optimization_str())
self.assertTrue(mesh.set_optimization("convex_hull"))
self.assertEqual("convex_hull", mesh.optimization_str())
self.assertEqual(sdf.MeshOptimization.CONVEX_HULL, mesh.optimization())
mesh.set_optimization(sdf.MeshOptimization.CONVEX_DECOMPOSITION)
self.assertEqual("convex_decomposition", mesh.optimization_str())
self.assertEqual(sdf.MeshOptimization.CONVEX_DECOMPOSITION, mesh.optimization())

self.assertFalse(mesh.set_optimization("invalid"))
mesh.set_optimization(sdf.MeshOptimization(99))
self.assertEqual(sdf.MeshOptimization(99), mesh.optimization())
self.assertEqual("", mesh.optimization_str())

convexDecomp = ConvexDecomposition()
convexDecomp.set_max_convex_hulls(10)
mesh.set_convex_decomposition(convexDecomp)
self.assertEqual(10, mesh.convex_decomposition().max_convex_hulls())

self.assertEqual("", mesh.uri())
mesh.set_uri("http://myuri.com")
self.assertEqual("http://myuri.com", mesh.uri())
Expand Down

0 comments on commit c8fbdbe

Please sign in to comment.