diff --git a/CMake/SofaPython3Tools.cmake b/CMake/SofaPython3Tools.cmake index 8e784ddf..d3302db2 100644 --- a/CMake/SofaPython3Tools.cmake +++ b/CMake/SofaPython3Tools.cmake @@ -48,17 +48,23 @@ function(SP3_add_python_package) cmake_parse_arguments(A "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + set(OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${SP3_PYTHON_PACKAGES_DIRECTORY}/${A_TARGET_DIRECTORY}) + if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + set(OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${SP3_PYTHON_PACKAGES_DIRECTORY}/${A_TARGET_DIRECTORY}) + endif() + + file(GLOB_RECURSE files RELATIVE ${A_SOURCE_DIRECTORY} ${A_SOURCE_DIRECTORY}/*) foreach(file_relative_path ${files}) set(file_absolute_path ${A_SOURCE_DIRECTORY}/${file_relative_path}) configure_file( ${file_absolute_path} - ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${SP3_PYTHON_PACKAGES_DIRECTORY}/${A_TARGET_DIRECTORY}/${file_relative_path} + ${OUTPUT_DIRECTORY}/${file_relative_path} @ONLY ) get_filename_component(relative_directory ${file_relative_path} DIRECTORY) install( - FILES "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${SP3_PYTHON_PACKAGES_DIRECTORY}/${A_TARGET_DIRECTORY}/${file_relative_path}" + FILES "${OUTPUT_DIRECTORY}/${file_relative_path}" DESTINATION "${LIBRARY_OUTPUT_DIRECTORY}/${SP3_PYTHON_PACKAGES_DIRECTORY}/${A_TARGET_DIRECTORY}/${relative_directory}" ) endforeach() @@ -117,7 +123,7 @@ function(SP3_add_python_module) find_package(pybind11 CONFIG QUIET REQUIRED) - pybind11_add_module(${A_TARGET} SHARED "${A_SOURCES}") + pybind11_add_module(${A_TARGET} SHARED NO_EXTRAS "${A_SOURCES}") add_library(SofaPython3::${A_TARGET} ALIAS ${A_TARGET}) target_include_directories(${A_TARGET} @@ -131,10 +137,8 @@ function(SP3_add_python_module) if (NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") target_compile_options(${A_TARGET} PRIVATE -Dregister=) - target_compile_options(${A_TARGET} PRIVATE -fvisibility=hidden) endif() - target_link_libraries(${A_TARGET} PUBLIC pybind11::module) target_link_libraries(${A_TARGET} PUBLIC "${A_DEPENDS}") set_target_properties( diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e2f8370..aee9d14b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,6 +73,9 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) +# Enable use of folder for IDE like VS +set_property(GLOBAL PROPERTY USE_FOLDERS ON) + # Set the minimum python version to 3.7 set(PYBIND11_PYTHON_VERSION 3.7) diff --git a/bindings/CMakeLists.txt b/bindings/CMakeLists.txt index b5067f78..c1a588c8 100644 --- a/bindings/CMakeLists.txt +++ b/bindings/CMakeLists.txt @@ -1,10 +1,10 @@ project(Bindings) -add_subdirectory(Sofa) -add_subdirectory(SofaRuntime) -add_subdirectory(SofaGui) -add_subdirectory(SofaTypes) -add_subdirectory(Modules) +set(BINDINGS_MODULE_LIST Sofa SofaRuntime SofaGui SofaTypes Modules) + +foreach(bindings_module ${BINDINGS_MODULE_LIST}) + add_subdirectory(${bindings_module}) +endforeach() if (SP3_WITH_SOFAEXPORTER) add_subdirectory(SofaExporter) @@ -13,12 +13,13 @@ endif() add_library(${PROJECT_NAME} INTERFACE) add_library(SofaPython3::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) -target_link_libraries(${PROJECT_NAME} INTERFACE ${PROJECT_NAME}.Modules) -target_link_libraries(${PROJECT_NAME} INTERFACE ${PROJECT_NAME}.Sofa) -target_link_libraries(${PROJECT_NAME} INTERFACE ${PROJECT_NAME}.SofaExporter) -target_link_libraries(${PROJECT_NAME} INTERFACE ${PROJECT_NAME}.SofaGui) -target_link_libraries(${PROJECT_NAME} INTERFACE ${PROJECT_NAME}.SofaRuntime) -target_link_libraries(${PROJECT_NAME} INTERFACE ${PROJECT_NAME}.SofaTypes) +foreach(bindings_module ${BINDINGS_MODULE_LIST}) + target_link_libraries(${PROJECT_NAME} INTERFACE ${PROJECT_NAME}.${bindings_module}) +endforeach() + +if (SP3_WITH_SOFAEXPORTER) + target_link_libraries(${PROJECT_NAME} INTERFACE ${PROJECT_NAME}.SofaExporter) +endif() configure_package_config_file( "${CMAKE_CURRENT_SOURCE_DIR}/BindingsConfig.cmake.in" diff --git a/bindings/Modules/CMakeLists.txt b/bindings/Modules/CMakeLists.txt index ea31381c..dd75a919 100644 --- a/bindings/Modules/CMakeLists.txt +++ b/bindings/Modules/CMakeLists.txt @@ -1,9 +1,18 @@ project(Bindings.Modules) -add_subdirectory(src/SofaPython3/SofaBaseTopology) +set(MODULEBINDINGS_MODULE_LIST SofaBaseTopology) + +foreach(modulebindings_module ${MODULEBINDINGS_MODULE_LIST}) + add_subdirectory(src/SofaPython3/${modulebindings_module}) +endforeach() + add_library(${PROJECT_NAME} INTERFACE) add_library(SofaPython3::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) -target_link_libraries(${PROJECT_NAME} INTERFACE ${PROJECT_NAME}.SofaBaseTopology) +foreach(modulebindings_module ${MODULEBINDINGS_MODULE_LIST}) + target_link_libraries(${PROJECT_NAME} INTERFACE ${PROJECT_NAME}.${modulebindings_module}) + set_target_properties(${PROJECT_NAME}.${modulebindings_module} PROPERTIES FOLDER "Bindings/Modules") +endforeach() + install(TARGETS ${PROJECT_NAME} EXPORT BindingsTargets) \ No newline at end of file diff --git a/bindings/Sofa/CMakeLists.txt b/bindings/Sofa/CMakeLists.txt index 77a15719..669f8edb 100644 --- a/bindings/Sofa/CMakeLists.txt +++ b/bindings/Sofa/CMakeLists.txt @@ -1,10 +1,10 @@ project(Bindings.Sofa) -add_subdirectory(src/SofaPython3/Sofa/Core) -add_subdirectory(src/SofaPython3/Sofa/Components) -add_subdirectory(src/SofaPython3/Sofa/Helper) -add_subdirectory(src/SofaPython3/Sofa/Simulation) -add_subdirectory(src/SofaPython3/Sofa/Types) +set(SOFABINDINGS_MODULE_LIST Core Components Helper Simulation Types) + +foreach(sofabindings_module ${SOFABINDINGS_MODULE_LIST}) + add_subdirectory(src/SofaPython3/Sofa/${sofabindings_module}) +endforeach() SP3_add_python_package( SOURCE_DIRECTORY @@ -16,11 +16,9 @@ SP3_add_python_package( add_library(${PROJECT_NAME} INTERFACE) add_library(SofaPython3::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) -target_link_libraries(${PROJECT_NAME} INTERFACE ${PROJECT_NAME}.Core) -target_link_libraries(${PROJECT_NAME} INTERFACE ${PROJECT_NAME}.Components) -target_link_libraries(${PROJECT_NAME} INTERFACE ${PROJECT_NAME}.Helper) -target_link_libraries(${PROJECT_NAME} INTERFACE ${PROJECT_NAME}.Simulation) -target_link_libraries(${PROJECT_NAME} INTERFACE ${PROJECT_NAME}.Types) +foreach(sofabindings_module ${SOFABINDINGS_MODULE_LIST}) + target_link_libraries(${PROJECT_NAME} INTERFACE ${PROJECT_NAME}.${sofabindings_module}) +endforeach() install(TARGETS ${PROJECT_NAME} EXPORT BindingsTargets) diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base.h b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base.h index ccfdf2e0..ced532ad 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base.h +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base.h @@ -34,145 +34,12 @@ along with sofaqtquick. If not, see . namespace sofapython3 { -/** - * This is the main pybind11 type holder that will manage the underlying reference counter of the SOFA C++ objects. It - * should be used when creating bindings for a C++ class that inherits sofa::core::objectmodel::Base. - * - * \note There is a problem in pybind11 which sometime does a kind of slicing between the python object and its bound - * C++ object. This usually happens when instantiating a virtual (trampoline) class in python that then calls the - * new operator in the pybind11::init() and return the newly created object. Python will sometime destroy the - * initial object before the C++ one is created. We go around this by keeping here a reference to the initial - * python object, hence incrementing its reference counter by one. - * - * See https://github.com/pybind/pybind11/issues/1546 for more details. - * @tparam T - */ - template -struct py_shared_ptr : public sofa::core::sptr { - using Base = sofa::core::sptr; - using Base::Base; - - py_shared_ptr(const sofa::core::sptr & sptr) : Base(sptr) {} - - py_shared_ptr(const sofa::core::sptr & sptr, T * ptr) : Base(ptr) {} - - py_shared_ptr(const py_shared_ptr & py_ptr) : Base(py_ptr) { - p_object = py_ptr.p_object; - } - - py_shared_ptr(py_shared_ptr & py_ptr) : Base(py_ptr) { - p_object = py_ptr.p_object; - } - - void set_object(const pybind11::object & o) { - p_object = o; - } - -private: - pybind11::object p_object; -}; +using py_shared_ptr = sofa::core::sptr; } // namespace sofapython3 -// Type caster for SP3 and SOFA holders -namespace pybind11::detail { -/** - * This is an alias type caster that converts sofa::core::sptr to sofapython3::py_shared_ptr. - * It is needed for when bound C++ function returns sofa::core::sptr instead of py_shared_ptr while the holder - * type was set to the latter. - * @tparam T - */ -template -class type_caster> { - -PYBIND11_TYPE_CASTER (sofa::core::sptr , _("sofa::core::sptr")); - - using BaseCaster = copyable_holder_caster>; - - bool load (pybind11::handle src, bool b) - { - // First make sure the py::object is an instanced of sofapython3::py_shared_ptr - BaseCaster bc; - bool success = bc.load (src, b); - if (!success) { - return false; - } - - // Convert the holder_caster to a sofapython3::py_shared_ptr instance - auto base_ptr = static_cast> (bc); - - // Take ownership of the py::object - auto h = BaseCaster::cast(base_ptr, return_value_policy(), handle()); - auto py_obj = reinterpret_borrow(h); - - // Save a copy into the holder so that it doesn't get deleted and thereby creating slicing - base_ptr.set_object(py_obj); - - // Set the value to the ptr - value = sofa::core::sptr (base_ptr); - return true; - } - - static handle cast (sofa::core::sptr sp, - return_value_policy rvp, - handle h) - { - return BaseCaster::cast (sp, rvp, h); - } -}; - -template -struct always_construct_holder> : always_construct_holder { }; - -/** - * Main type caster that converts python objects to C++ sofapython3::py_shared_ptr objects, and the inverse. - * To avoid slicing (see sofapython3::py_shared_ptr), it will preserve the initial python object when the initial - * python -> C++ conversion happens. - * @tparam T - */ -template -class type_caster> { - -PYBIND11_TYPE_CASTER (sofapython3::py_shared_ptr , _("sofapython3::py_shared_ptr")); - - using BaseCaster = copyable_holder_caster>; - - bool load (pybind11::handle src, bool b) - { - // First make sure the py::object is an instanced of sofapython3::py_shared_ptr - BaseCaster bc; - bool success = bc.load (src, b); - if (!success) { - return false; - } - - // Convert the holder_caster to a sofapython3::py_shared_ptr instance - auto base_ptr = static_cast> (bc); - - // Take ownership of the py::object - auto h = BaseCaster::cast(base_ptr, return_value_policy(), handle()); - auto py_obj = reinterpret_borrow(h); - - // Save a copy into the holder so that it doesn't get deleted and thereby creating slicing - base_ptr.set_object(py_obj); - - // Set the value to the ptr - value = base_ptr; - return true; - } - - static handle cast (sofapython3::py_shared_ptr sp, - return_value_policy rvp, - handle h) - { - return BaseCaster::cast (sp, rvp, h); - } -}; - -template -struct is_holder_type> : std::true_type {}; -} +PYBIND11_DECLARE_HOLDER_TYPE(T, sofapython3::py_shared_ptr, true) namespace sofapython3 { diff --git a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Node.cpp b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Node.cpp index ac5e1349..7f44387f 100644 --- a/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Node.cpp +++ b/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Node.cpp @@ -150,12 +150,11 @@ py_shared_ptr __init__(const std::string& name) { /// Method: init (beware this is not the python __init__, this is sofa's init()) void init(Node& self) { self.init(ExecParams::defaultInstance()); } -py::object addObject(Node& self, const py::object & object) +py::object addObject(Node& self, BaseObject * object) { try { - auto base_object = py::cast>(object); - if (self.addObject(base_object)) - return object; + if (self.addObject(object)) + return PythonFactory::toPython(object); } catch (...) { throw py::type_error("Trying to add an object that isn't derived from sofa::core::objectmodel::BaseObject."); } @@ -483,7 +482,7 @@ void moduleAddNode(py::module &m) { p.def("init", &init, sofapython3::doc::sofa::core::Node::initSofa ); p.def("add", &addKwargs, sofapython3::doc::sofa::core::Node::addKwargs); p.def("addObject", &addObjectKwargs, sofapython3::doc::sofa::core::Node::addObjectKwargs); - p.def("addObject", &addObject, sofapython3::doc::sofa::core::Node::addObject); + p.def("addObject", &addObject, sofapython3::doc::sofa::core::Node::addObject, py::keep_alive<0, 2>()); p.def("createObject", &createObject, sofapython3::doc::sofa::core::Node::createObject); p.def("addChild", &addChildKwargs, sofapython3::doc::sofa::core::Node::addChildKwargs); p.def("addChild", &addChild, sofapython3::doc::sofa::core::Node::addChild); diff --git a/bindings/Sofa/tests/CMakeLists.txt b/bindings/Sofa/tests/CMakeLists.txt index 17b052d1..eef73a1a 100644 --- a/bindings/Sofa/tests/CMakeLists.txt +++ b/bindings/Sofa/tests/CMakeLists.txt @@ -39,6 +39,7 @@ enable_testing() add_executable(${PROJECT_NAME} ${SOURCE_FILES} ${HEADER_FILES} ${PYTHON_FILES}) target_link_libraries(${PROJECT_NAME} SofaGTestMain SofaHelper SofaPython3::Plugin SofaPython3::Bindings.Sofa SofaPython3::Bindings.SofaTypes SofaPython3::Bindings.SofaRuntime) target_compile_definitions(${PROJECT_NAME} PRIVATE "PYTHON_TESTFILES_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/\"") +set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER "Bindings/Tests") set(RPATH "$ORIGIN/../lib") if (APPLE) @@ -54,20 +55,19 @@ set_target_properties( add_test(NAME ${PROJECT_NAME} COMMAND ${PROJECT_NAME}) -SP3_configure_directory(${CMAKE_CURRENT_SOURCE_DIR}/Components ${CMAKE_BINARY_DIR}/${RUNTIME_OUTPUT_DIRECTORY}/Components) -install(DIRECTORY ${CMAKE_BINARY_DIR}/${RUNTIME_OUTPUT_DIRECTORY}/Components DESTINATION ${RUNTIME_OUTPUT_DIRECTORY}) - -SP3_configure_directory(${CMAKE_CURRENT_SOURCE_DIR}/Core ${CMAKE_BINARY_DIR}/${RUNTIME_OUTPUT_DIRECTORY}/Core) -install(DIRECTORY ${CMAKE_BINARY_DIR}/${RUNTIME_OUTPUT_DIRECTORY}/Core DESTINATION ${RUNTIME_OUTPUT_DIRECTORY}) - -SP3_configure_directory(${CMAKE_CURRENT_SOURCE_DIR}/Helper ${CMAKE_BINARY_DIR}/${RUNTIME_OUTPUT_DIRECTORY}/Helper) -install(DIRECTORY ${CMAKE_BINARY_DIR}/${RUNTIME_OUTPUT_DIRECTORY}/Helper DESTINATION ${RUNTIME_OUTPUT_DIRECTORY}) - -SP3_configure_directory(${CMAKE_CURRENT_SOURCE_DIR}/Simulation ${CMAKE_BINARY_DIR}/${RUNTIME_OUTPUT_DIRECTORY}/Simulation) -install(DIRECTORY ${CMAKE_BINARY_DIR}/${RUNTIME_OUTPUT_DIRECTORY}/Simulation DESTINATION ${RUNTIME_OUTPUT_DIRECTORY}) - -SP3_configure_directory(${CMAKE_CURRENT_SOURCE_DIR}/Types ${CMAKE_BINARY_DIR}/${RUNTIME_OUTPUT_DIRECTORY}/Types) -install(DIRECTORY ${CMAKE_BINARY_DIR}/${RUNTIME_OUTPUT_DIRECTORY}/Types DESTINATION ${RUNTIME_OUTPUT_DIRECTORY}) +set(DIR_BINDING_LIST Components Core Helper Simulation Types) +get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +foreach(dir_binding ${DIR_BINDING_LIST}) + if (_isMultiConfig) # MSVC + foreach(config_type ${CMAKE_CONFIGURATION_TYPES}) + SP3_configure_directory(${CMAKE_CURRENT_SOURCE_DIR}/${dir_binding} ${CMAKE_BINARY_DIR}/${RUNTIME_OUTPUT_DIRECTORY}/${config_type}/${dir_binding}) + install(DIRECTORY ${CMAKE_BINARY_DIR}/${RUNTIME_OUTPUT_DIRECTORY}/${config_type}/${dir_binding} DESTINATION ${RUNTIME_OUTPUT_DIRECTORY}) + endforeach() + else() + SP3_configure_directory(${CMAKE_CURRENT_SOURCE_DIR}/${dir_binding} ${CMAKE_BINARY_DIR}/${RUNTIME_OUTPUT_DIRECTORY}/${dir_binding}) + install(DIRECTORY ${CMAKE_BINARY_DIR}/${RUNTIME_OUTPUT_DIRECTORY}/${dir_binding} DESTINATION ${RUNTIME_OUTPUT_DIRECTORY}) + endif() +endforeach() install( TARGETS ${PROJECT_NAME} diff --git a/bindings/Sofa/tests/Core/ForceField.py b/bindings/Sofa/tests/Core/ForceField.py index c2d6e67d..bc9fd550 100644 --- a/bindings/Sofa/tests/Core/ForceField.py +++ b/bindings/Sofa/tests/Core/ForceField.py @@ -42,6 +42,7 @@ def createParticle(node, node_name, use_implicit_scheme, use_iterative_solver): def rssffScene(use_implicit_scheme=True, use_iterative_solver=True): SofaRuntime.importPlugin("SofaSparseSolver") SofaRuntime.importPlugin("SofaExplicitOdeSolver") + SofaRuntime.importPlugin("SofaImplicitOdeSolver") node = Sofa.Core.Node("root") node.gravity = [0, -10, 0] createParticle(node, "particle", use_implicit_scheme, use_iterative_solver) diff --git a/bindings/Sofa/tests/Helper/FileRepository.py b/bindings/Sofa/tests/Helper/FileRepository.py index 5dae7d5c..80092336 100644 --- a/bindings/Sofa/tests/Helper/FileRepository.py +++ b/bindings/Sofa/tests/Helper/FileRepository.py @@ -3,54 +3,56 @@ import Sofa import Sofa.Helper import unittest -import tempfile import os +from pathlib import Path +from tempfile import gettempdir class Test(unittest.TestCase): def __init__(self, methodName): unittest.TestCase.__init__(self, methodName) - self.temp_dir1 = tempfile.TemporaryDirectory(suffix="Test", prefix="FileRepository") - self.temp_file1 = open(os.path.join(self.temp_dir1.name, "a_simple_test_file_1.txt"), "w") - self.temp_dir2 = tempfile.TemporaryDirectory(suffix="Test", prefix="FileRepository") - self.temp_file2 = open(os.path.join(self.temp_dir2.name, "a_simple_test_file_2.txt"), "w") + # First temporary directory + self.temp_dir1 = os.path.join(gettempdir(), f'FileRepository_{hash(os.times())}_test_1') + os.makedirs(self.temp_dir1, exist_ok=True) + self.temp_file1 = open(os.path.join(self.temp_dir1, "a_simple_test_file_1.txt"), "w") - os.environ['FILEREPOSITORYTEST'] = self.temp_dir1.name + # Second temporary directory + self.temp_dir2 = os.path.join(gettempdir(), f'FileRepository_{hash(os.times())}_test_2') + os.makedirs(self.temp_dir2, exist_ok=True) + self.temp_file2 = open(os.path.join(self.temp_dir2, "a_simple_test_file_2.txt"), "w") + + self.repository = Sofa.Helper.System.FileRepository() + + def test_environment(self): + os.environ['FILEREPOSITORYTEST'] = self.temp_dir1 self.repository = Sofa.Helper.System.FileRepository("FILEREPOSITORYTEST") - self.assertEqual(self.repository.getPaths(), [self.temp_dir1.name]) + + self.assertEqual([Path(p) for p in self.repository.getPaths()], [Path(self.temp_dir1)]) self.repository.clear() self.assertEqual(self.repository.getPaths(), []) def test_add_remove_directories(self): - self.repository.addFirstPath(self.temp_dir1.name) - self.repository.addFirstPath(self.temp_dir2.name) - self.assertEqual(self.repository.getPaths(), [self.temp_dir2.name, self.temp_dir1.name]) + self.repository.addFirstPath(self.temp_dir1) + self.repository.addFirstPath(self.temp_dir2) + self.assertEqual([Path(p) for p in self.repository.getPaths()], [Path(self.temp_dir2), Path(self.temp_dir1)]) - self.repository.removePath(self.temp_dir2.name) - self.assertEqual(self.repository.getPaths(), [self.temp_dir1.name]) + self.repository.removePath(str(Path(self.temp_dir2).as_posix())) + self.assertEqual([Path(p) for p in self.repository.getPaths()], [Path(self.temp_dir1)]) - self.repository.addLastPath(self.temp_dir2.name) - self.assertEqual(self.repository.getPaths(), [self.temp_dir1.name, self.temp_dir2.name]) + self.repository.addLastPath(self.temp_dir2) + self.assertEqual([Path(p) for p in self.repository.getPaths()], [Path(self.temp_dir1), Path(self.temp_dir2)]) self.repository.clear() def test_find_file(self): - self.repository.addFirstPath(self.temp_dir1.name) + self.repository.addFirstPath(self.temp_dir1) self.assertTrue(self.repository.findFile("a_simple_test_file_1.txt")) - self.repository.addFirstPath(self.temp_dir2.name) + self.repository.addFirstPath(self.temp_dir2) self.assertTrue(self.repository.findFile("a_simple_test_file_2.txt")) - self.assertEqual(self.repository.getFile("a_simple_test_file_1.txt"), os.path.join(self.temp_dir1.name, "a_simple_test_file_1.txt")) - self.assertEqual(self.repository.getFile("a_simple_test_file_2.txt"), os.path.join(self.temp_dir2.name, "a_simple_test_file_2.txt")) + self.assertEqual(Path(self.repository.getFile("a_simple_test_file_1.txt")), Path(os.path.join(self.temp_dir1, "a_simple_test_file_1.txt"))) + self.assertEqual(Path(self.repository.getFile("a_simple_test_file_2.txt")), Path(os.path.join(self.temp_dir2, "a_simple_test_file_2.txt"))) self.repository.clear() - -def runTests(): - suite = unittest.TestLoader().loadTestsFromTestCase(Test) - return unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful() - - -def createScene(rootNode): - runTests() diff --git a/bindings/Sofa/tests/Simulation/Simulation.py b/bindings/Sofa/tests/Simulation/Simulation.py index 3e9f86b1..f189b391 100644 --- a/bindings/Sofa/tests/Simulation/Simulation.py +++ b/bindings/Sofa/tests/Simulation/Simulation.py @@ -5,6 +5,7 @@ import Sofa.Types import Sofa.Simulation import tempfile +import os class Test(unittest.TestCase): def test_load(self): @@ -17,11 +18,11 @@ def test_load(self): """ - tf = tempfile.NamedTemporaryFile(mode="w+t", suffix=".scn") - tf.file.write(scene) - tf.file.flush() - tt = open(tf.name) + tf = tempfile.NamedTemporaryFile(mode="w+t", suffix=".scn", delete=False) + tf.write(scene) + tf.flush() node = Sofa.Simulation.load(tf.name) self.assertNotEqual(node, None) self.assertEqual(node.name.value, "rootNode") + os.remove(tf.name) diff --git a/bindings/SofaExporter/src/SofaExporter/Binding_STLExporter.cpp b/bindings/SofaExporter/src/SofaExporter/Binding_STLExporter.cpp index 90201cea..d5a69e95 100644 --- a/bindings/SofaExporter/src/SofaExporter/Binding_STLExporter.cpp +++ b/bindings/SofaExporter/src/SofaExporter/Binding_STLExporter.cpp @@ -25,15 +25,20 @@ along with sofaqtquick. If not, see . - thierry.gaugry@inria.fr ********************************************************************/ +#include #include #include #include +#include +#include using sofa::component::exporter::STLExporter; -namespace sofapython3 -{ +/// Makes an alias for the pybind11 namespace to increase readability. +namespace py { using namespace pybind11; } + +namespace sofapython3 { void moduleAddSTLExporter(py::module &m) { @@ -43,7 +48,7 @@ void moduleAddSTLExporter(py::module &m) return py::cast(dynamic_cast(object)); }); - py::class_> p(m, "STLExporter"); + py::class_> p(m, "STLExporter"); p.def("write", &STLExporter::write, sofapython3::doc::SofaExporter::STLExporter::write::docstring); } diff --git a/bindings/SofaExporter/src/SofaExporter/Binding_STLExporter.h b/bindings/SofaExporter/src/SofaExporter/Binding_STLExporter.h index 0585cc94..44f34aa8 100644 --- a/bindings/SofaExporter/src/SofaExporter/Binding_STLExporter.h +++ b/bindings/SofaExporter/src/SofaExporter/Binding_STLExporter.h @@ -29,17 +29,8 @@ along with sofaqtquick. If not, see . #include -#include -#include +namespace sofapython3 { -template class pybind11::class_>; - - -namespace sofapython3 -{ - -void moduleAddSTLExporter(py::module &m); +void moduleAddSTLExporter(pybind11::module &m); } /// namespace sofapython3 diff --git a/bindings/SofaRuntime/tests/CMakeLists.txt b/bindings/SofaRuntime/tests/CMakeLists.txt index ead89246..24eb3405 100644 --- a/bindings/SofaRuntime/tests/CMakeLists.txt +++ b/bindings/SofaRuntime/tests/CMakeLists.txt @@ -15,6 +15,7 @@ enable_testing() add_executable(${PROJECT_NAME} ${SOURCE_FILES} ${PYTHON_FILES}) target_link_libraries(${PROJECT_NAME} SofaGTestMain SofaHelper SofaPython3::Plugin SofaPython3::Bindings.Sofa.Core) target_compile_definitions(${PROJECT_NAME} PRIVATE "PYTHON_TESTFILES_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}\"") +set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER "Bindings/Tests") set(RPATH "$ORIGIN/../lib") if (APPLE) diff --git a/bindings/SofaTypes/tests/CMakeLists.txt b/bindings/SofaTypes/tests/CMakeLists.txt index 9be101f4..4799cdda 100644 --- a/bindings/SofaTypes/tests/CMakeLists.txt +++ b/bindings/SofaTypes/tests/CMakeLists.txt @@ -15,6 +15,7 @@ enable_testing() add_executable(${PROJECT_NAME} ${SOURCE_FILES} ${PYTHON_FILES}) target_link_libraries(${PROJECT_NAME} SofaGTestMain SofaHelper SofaPython3::Plugin) target_compile_definitions(${PROJECT_NAME} PRIVATE "PYTHON_TESTFILES_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/pyfiles/\"") +set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER "Bindings/Tests") set(RPATH "$ORIGIN/../lib") if (APPLE)