From 617e14f1954be455da70726971271b3d515c218b Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Fri, 30 Aug 2024 14:04:52 +0200 Subject: [PATCH] [EDF30834] : Finalization of Swig of recognition shape + python wrapping testing integration --- src/PyWrapping/CMakeLists.txt | 19 ++-- .../TestPyWrapGathered_medcoupling.py | 12 ++- src/PyWrapping/medcoupling.i | 13 +++ src/ShapeRecogn/Areas.cxx | 4 +- src/ShapeRecogn/PrimitiveType.cxx | 90 ++++++++++++++++++- src/ShapeRecogn/PrimitiveType.hxx | 84 ++++------------- src/ShapeRecogn/ShapeRecognMeshBuilder.cxx | 6 +- src/ShapeRecogn/Swig/ShapeRecognImpl.i | 25 ++++++ src/ShapeRecogn/Test/CMakeLists.txt | 15 +++- .../Test/CTestTestfileInstall.cmake | 19 ++-- src/ShapeRecogn/Test/TestShapeRecogn.py | 10 ++- 11 files changed, 197 insertions(+), 100 deletions(-) diff --git a/src/PyWrapping/CMakeLists.txt b/src/PyWrapping/CMakeLists.txt index c37d6780d..bb387825a 100644 --- a/src/PyWrapping/CMakeLists.txt +++ b/src/PyWrapping/CMakeLists.txt @@ -37,10 +37,6 @@ IF(MEDCOUPLING_USE_64BIT_IDS) STRING(APPEND SWIG_MODULE_medcoupling_EXTRA_FLAGS ";-DMEDCOUPLING_USE_64BIT_IDS") ENDIF(MEDCOUPLING_USE_64BIT_IDS) -IF(MEDCOUPLING_ENABLE_SHAPERECOGN) - LIST(APPEND SWIG_MODULE_medcoupling_EXTRA_FLAGS -DWITH_SHAPE_RECOGN) -ENDIF(MEDCOUPLING_ENABLE_SHAPERECOGN) - SET(medcoupling_SWIG_DPYS_FILES medcoupling.i) INCLUDE_DIRECTORIES( @@ -67,16 +63,23 @@ INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/../ParaMEDMEM ${CMAKE_CURRENT_SOURCE_DIR}/../ParaMEDMEM/MPIAccess ${CMAKE_CURRENT_SOURCE_DIR}/../ParaMEDMEM_Swig + ${CMAKE_CURRENT_SOURCE_DIR}/../ShapeRecogn + ${CMAKE_CURRENT_SOURCE_DIR}/../ShapeRecogn/Swig ${PROJECT_BINARY_DIR}/doc ) - -IF(WIN32 OR CYGWIN) + + IF(WIN32 OR CYGWIN) SET(medcoupling_LIB_dependancies ${PYTHON_LIBRARIES} ${PLATFORM_LIBS} medcouplingremapper medicoco) -ELSE(WIN32 OR CYGWIN) + ELSE(WIN32 OR CYGWIN) # ${PYTHON_LIBRARIES} not needed see https://www.python.org/dev/peps/pep-0513/#libpythonx-y-so-1 SET(medcoupling_LIB_dependancies ${PLATFORM_LIBS} medcouplingremapper medicoco) -ENDIF(WIN32 OR CYGWIN) + ENDIF(WIN32 OR CYGWIN) + IF(MEDCOUPLING_ENABLE_SHAPERECOGN) + LIST(APPEND SWIG_MODULE_medcoupling_EXTRA_FLAGS -DWITH_SHAPE_RECOGN) + LIST(APPEND medcoupling_LIB_dependancies shaperecogn) + ENDIF(MEDCOUPLING_ENABLE_SHAPERECOGN) + IF(NOT MEDCOUPLING_MICROMED) LIST(APPEND SWIG_MODULE_medcoupling_EXTRA_FLAGS -DWITH_MED_FILE) LIST(APPEND medcoupling_LIB_dependancies medloader) diff --git a/src/PyWrapping/TestPyWrapGathered_medcoupling.py b/src/PyWrapping/TestPyWrapGathered_medcoupling.py index 10ce28a1b..553fefc96 100644 --- a/src/PyWrapping/TestPyWrapGathered_medcoupling.py +++ b/src/PyWrapping/TestPyWrapGathered_medcoupling.py @@ -141,7 +141,17 @@ class medcouplingTest(unittest.TestCase): a,b,c=f3.getTime() self.assertEqual(b,10) ; self.assertEqual(c,13) ; self.assertAlmostEqual(a,10.75,14); pass - + + @unittest.skipUnless(HasShapeRecognitionExt(),"Requires Shape recognition extension activated") + def test6(self): + m = MEDCouplingCMesh() + arr = DataArrayDouble(5) ; arr.iota() + m.setCoords(arr,arr) + m = m.buildUnstructured() + m.simplexize(0) + m.changeSpaceDimension(3,0.) + srMesh = ShapeRecognMeshBuilder( m ) + rem = srMesh.recognize() def partitionerTesterHelper(self,algoSelected): arr=DataArrayDouble(10) ; arr.iota() diff --git a/src/PyWrapping/medcoupling.i b/src/PyWrapping/medcoupling.i index 29e2a82c7..ae66a385b 100644 --- a/src/PyWrapping/medcoupling.i +++ b/src/PyWrapping/medcoupling.i @@ -48,6 +48,10 @@ %include "ParaMEDMEMCommon.i" #endif +#ifdef WITH_SHAPE_RECOGN +%include "ShapeRecognCommon.i" +#endif + %constant const char __version__[]=MEDCOUPLING_GIT_SHA1; %constant const char __config_datetime__[]=MEDCOUPLING_CONFIG_DT; @@ -133,6 +137,15 @@ return false; #endif } + + bool HasShapeRecognitionExt() + { +#ifdef WITH_SHAPE_RECOGN + return true; +#else + return false; +#endif + } std::vector ActiveExtensions() { diff --git a/src/ShapeRecogn/Areas.cxx b/src/ShapeRecogn/Areas.cxx index 31d5d39bb..2cc82210f 100644 --- a/src/ShapeRecogn/Areas.cxx +++ b/src/ShapeRecogn/Areas.cxx @@ -128,12 +128,12 @@ PrimitiveType Areas::getPrimitiveType(mcIdType areaId) const std::string Areas::getPrimitiveTypeName(mcIdType areaId) const { - return convertPrimitiveToString(getPrimitiveType(areaId)); + return ConvertPrimitiveToString(getPrimitiveType(areaId)); } int Areas::getPrimitiveTypeInt(mcIdType areaId) const { - return convertPrimitiveToInt(getPrimitiveType(areaId)); + return ConvertPrimitiveToInt(getPrimitiveType(areaId)); } const std::vector &Areas::getNodeIds(mcIdType areaId) const diff --git a/src/ShapeRecogn/PrimitiveType.cxx b/src/ShapeRecogn/PrimitiveType.cxx index 28038fe35..d380e996b 100644 --- a/src/ShapeRecogn/PrimitiveType.cxx +++ b/src/ShapeRecogn/PrimitiveType.cxx @@ -22,9 +22,95 @@ #include #include -std::vector MEDCoupling::allManagedPrimitivesStr() +constexpr char PLANE_STR[] = "Plane"; +constexpr char SPHERE_STR[] = "Sphere"; +constexpr char CYLINDER_STR[] = "Cylinder"; +constexpr char CONE_STR[] = "Cone"; +constexpr char TORUS_STR[] = "Torus"; +constexpr char UNKNOWN_STR[] = "Unknown"; + +std::vector MEDCoupling::AllManagedPrimitives() +{ + return {PrimitiveType::Plane,PrimitiveType::Sphere,PrimitiveType::Cylinder,PrimitiveType::Cone,PrimitiveType::Torus,PrimitiveType::Unknown}; +} + +std::vector MEDCoupling::AllManagedPrimitivesStr() { + std::vector apt( AllManagedPrimitives() ); std::vector ret; - //std::copy(); + std::transform(apt.begin(),apt.end(),std::back_inserter(ret),[](PrimitiveType type) { return MEDCoupling::ConvertPrimitiveToString(type); } ); return ret; } + +std::string MEDCoupling::ConvertPrimitiveToString(MEDCoupling::PrimitiveType type) +{ + std::string typeName; + switch (type) + { + case PrimitiveType::Plane: + typeName = PLANE_STR; + break; + case PrimitiveType::Sphere: + typeName = SPHERE_STR; + break; + case PrimitiveType::Cylinder: + typeName = CYLINDER_STR; + break; + case PrimitiveType::Cone: + typeName = CONE_STR; + break; + case PrimitiveType::Torus: + typeName = TORUS_STR; + break; + case PrimitiveType::Unknown: + typeName = UNKNOWN_STR; + break; + default: + break; + } + return typeName; +}; + +MEDCoupling::PrimitiveType MEDCoupling::ConvertStringToPrimitive(const std::string& type) +{ + if( type == PLANE_STR ) + return PrimitiveType::Plane; + if( type == SPHERE_STR ) + return PrimitiveType::Sphere; + if( type == CYLINDER_STR ) + return PrimitiveType::Cylinder; + if( type == CONE_STR ) + return PrimitiveType::Cone; + if( type == TORUS_STR ) + return PrimitiveType::Torus; + if( type == UNKNOWN_STR ) + return PrimitiveType::Unknown; + return PrimitiveType::Unknown; +} + +int MEDCoupling::ConvertPrimitiveToInt(MEDCoupling::PrimitiveType type) +{ + int typeInt = 5; + switch (type) + { + case PrimitiveType::Plane: + typeInt = 0; + break; + case PrimitiveType::Sphere: + typeInt = 1; + break; + case PrimitiveType::Cylinder: + typeInt = 2; + break; + case PrimitiveType::Cone: + typeInt = 3; + break; + case PrimitiveType::Torus: + typeInt = 4; + break; + case PrimitiveType::Unknown: + default: + break; + } + return typeInt; +} diff --git a/src/ShapeRecogn/PrimitiveType.hxx b/src/ShapeRecogn/PrimitiveType.hxx index 8341c8af6..88f428932 100644 --- a/src/ShapeRecogn/PrimitiveType.hxx +++ b/src/ShapeRecogn/PrimitiveType.hxx @@ -21,79 +21,27 @@ #include #include +#include namespace MEDCoupling { - enum PrimitiveType - { - Plane = 0, - Sphere = 1, - Cylinder = 2, - Cone = 3, - Torus = 4, - Unknown = 5 - }; + enum class PrimitiveType : std::uint8_t + { + Plane = 0, + Sphere = 1, + Cylinder = 2, + Cone = 3, + Torus = 4, + Unknown = 5 + }; - inline std::vector allManagedPrimitives() - { - return {Plane,Sphere,Cylinder,Cone,Torus,Unknown}; - } + std::vector AllManagedPrimitives(); - std::vector allManagedPrimitivesStr(); + std::vector AllManagedPrimitivesStr(); - inline std::string convertPrimitiveToString(PrimitiveType type) - { - std::string typeName = ""; - switch (type) - { - case PrimitiveType::Plane: - typeName = "Plane"; - break; - case PrimitiveType::Sphere: - typeName = "Sphere"; - break; - case PrimitiveType::Cylinder: - typeName = "Cylinder"; - break; - case PrimitiveType::Cone: - typeName = "Cone"; - break; - case PrimitiveType::Torus: - typeName = "Torus"; - break; - case PrimitiveType::Unknown: - typeName = "Unknown"; - break; - default: - break; - } - return typeName; - }; + std::string ConvertPrimitiveToString(PrimitiveType type); + + PrimitiveType ConvertStringToPrimitive(const std::string& type); - inline int convertPrimitiveToInt(PrimitiveType type) - { - int typeInt = 5; - switch (type) - { - case PrimitiveType::Plane: - typeInt = 0; - break; - case PrimitiveType::Sphere: - typeInt = 1; - break; - case PrimitiveType::Cylinder: - typeInt = 2; - break; - case PrimitiveType::Cone: - typeInt = 3; - break; - case PrimitiveType::Torus: - typeInt = 4; - break; - case PrimitiveType::Unknown: - default: - break; - } - return typeInt; - }; + int ConvertPrimitiveToInt(PrimitiveType type); }; diff --git a/src/ShapeRecogn/ShapeRecognMeshBuilder.cxx b/src/ShapeRecogn/ShapeRecognMeshBuilder.cxx index fea8abe42..8b817eb2e 100644 --- a/src/ShapeRecogn/ShapeRecognMeshBuilder.cxx +++ b/src/ShapeRecogn/ShapeRecognMeshBuilder.cxx @@ -28,6 +28,7 @@ #include "MEDCouplingFieldInt32.hxx" #include +#include #include using namespace MEDCoupling; @@ -190,8 +191,9 @@ MEDCouplingFieldDouble *ShapeRecognMeshBuilder::buildNodeK2() const MEDCouplingFieldInt32 *ShapeRecognMeshBuilder::buildNodePrimitiveType() const { checkNodesBeforeBuildingField(); - const std::vector tmp( nodes->getPrimitiveType() ); - return buildField("Primitive Type (Node)", 1, {tmp.begin(),tmp.end()}, mesh); + std::vector tmp; + std::transform(nodes->getPrimitiveType().begin(),nodes->getPrimitiveType().end(),std::back_inserter(tmp),[](const PrimitiveType& elt){ return Int32(elt); }); + return buildField("Primitive Type (Node)", 1, tmp, mesh); } MEDCouplingFieldDouble *ShapeRecognMeshBuilder::buildNodeNormal() const diff --git a/src/ShapeRecogn/Swig/ShapeRecognImpl.i b/src/ShapeRecogn/Swig/ShapeRecognImpl.i index b1fdeab34..0d894c7ce 100644 --- a/src/ShapeRecogn/Swig/ShapeRecognImpl.i +++ b/src/ShapeRecogn/Swig/ShapeRecognImpl.i @@ -21,6 +21,8 @@ #include "ShapeRecognMesh.hxx" #include "ShapeRecognMeshBuilder.hxx" #include "Areas.hxx" + + #include %} %feature("unref") ShapeRecognMesh "$this->decrRef();" @@ -42,6 +44,13 @@ %newobject ShapeRecognMesh::getCenter; %newobject ShapeRecognMesh::getAxis; %newobject ShapeRecognMesh::getApex; +%newobject ShapeRecognMeshBuilder::buildNodeWeakDirections; +%newobject ShapeRecognMeshBuilder::buildNodeMainDirections; +%newobject ShapeRecognMeshBuilder::buildAreaAxisPoint; +%newobject ShapeRecognMeshBuilder::buildAreaAffinePoint; + +%rename (ConvertStringToPrimitive) ConvertStringToPrimitiveSwig; +%rename (ConvertPrimitiveToString) ConvertPrimitiveToStringSwig; class Areas { @@ -53,6 +62,7 @@ public: bool isEmpty(mcIdType areaId) const; size_t getNumberOfAreas() const; size_t getNumberOfNodes(mcIdType areaId) const; + int getPrimitiveType(mcIdType areaId) const; std::string getPrimitiveTypeName(mcIdType areaId) const; %extend { @@ -72,6 +82,21 @@ private: using namespace MEDCoupling; +std::vector AllManagedPrimitivesStr(); + +%inline +{ + std::string ConvertPrimitiveToStringSwig(int type) + { + return ConvertPrimitiveToString(static_cast(type)); + } + + int ConvertStringToPrimitiveSwig(const std::string& type) + { + return static_cast>( ConvertStringToPrimitive(type) ); + } +} + class ShapeRecognMesh : public RefCountObject { public: diff --git a/src/ShapeRecogn/Test/CMakeLists.txt b/src/ShapeRecogn/Test/CMakeLists.txt index 57247a660..a7df4179a 100644 --- a/src/ShapeRecogn/Test/CMakeLists.txt +++ b/src/ShapeRecogn/Test/CMakeLists.txt @@ -50,7 +50,10 @@ IF(NOT MEDCOUPLING_MICROMED) TARGET_LINK_LIBRARIES(${TESTSHAPE_RECOGN0} shaperecogn InterpKernelTestUtils medloader ${MEDFILE_C_LIBRARIES} ${HDF5_LIBRARIES} ${CPPUNIT_LIBRARIES} ${PLATFORM_LIBS}) INSTALL(TARGETS ${TESTSHAPE_RECOGN0} DESTINATION ${MEDCOUPLING_INSTALL_BINS}) + + #### Test section + SET(TEST_INSTALL_DIRECTORY ${MEDCOUPLING_INSTALL_TESTS}/ShapeRecogn) SET(BASE_TESTS ${TESTSHAPE_RECOGN0}) FOREACH(test ${BASE_TESTS}) @@ -58,13 +61,19 @@ IF(NOT MEDCOUPLING_MICROMED) COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${test}) SET_TESTS_PROPERTIES(${test} PROPERTIES ENVIRONMENT "${tests_env}") ENDFOREACH() + INSTALL(TARGETS ${TESTSHAPE_RECOGN0} DESTINATION ${TEST_INSTALL_DIRECTORY}) - # Application tests - SET(TEST_INSTALL_DIRECTORY ${MEDCOUPLING_INSTALL_TESTS}/ShapeRecogn) - INSTALL(TARGETS ${TESTSHAPE_RECOGN0} DESTINATION ${TEST_INSTALL_DIRECTORY}) + SET(TESTSHAPE_RECOGN1 "TestShapeRecogn.py") + SET(test ${TESTSHAPE_RECOGN1}) + SET(testname "TestShapeRecognPy") + ADD_TEST(NAME ${testname} COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/${test}) + SET_TESTS_PROPERTIES(${testname} PROPERTIES ENVIRONMENT "${tests_env}") + INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${TESTSHAPE_RECOGN1} DESTINATION ${TEST_INSTALL_DIRECTORY}) INSTALL(FILES CTestTestfileInstall.cmake DESTINATION ${TEST_INSTALL_DIRECTORY} RENAME CTestTestfile.cmake) + + #### End Test section ENDIF(NOT MEDCOUPLING_MICROMED) diff --git a/src/ShapeRecogn/Test/CTestTestfileInstall.cmake b/src/ShapeRecogn/Test/CTestTestfileInstall.cmake index b636c20a0..ae6f6c409 100644 --- a/src/ShapeRecogn/Test/CTestTestfileInstall.cmake +++ b/src/ShapeRecogn/Test/CTestTestfileInstall.cmake @@ -17,15 +17,12 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -SET(TEST_NAMES - TestShapeRecogn -) +SET(TEST_NAME "${COMPONENT_NAME}_ShapeRecogn") +ADD_TEST(${TEST_NAME} TestShapeRecogn) +SET_TESTS_PROPERTIES( ${TEST_NAME} PROPERTIES LABELS "${COMPONENT_NAME}" TIMEOUT ${TIMEOUT} ) -FOREACH(tfile ${TEST_NAMES}) - SET(TEST_NAME ${COMPONENT_NAME}_${tfile}) - ADD_TEST(${TEST_NAME} ${tfile}) - SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES - LABELS "${COMPONENT_NAME}" - TIMEOUT ${TIMEOUT} - ) -ENDFOREACH() +SET(tfile "TestShapeRecogn.py") +set(BASE_NAME "ShapeRecognPy") +SET(TEST_NAME ${COMPONENT_NAME}_${BASE_NAME}) +ADD_TEST(${TEST_NAME} python3 ${tfile}) +SET_TESTS_PROPERTIES( ${TEST_NAME} PROPERTIES LABELS "${COMPONENT_NAME}" TIMEOUT ${TIMEOUT} ) diff --git a/src/ShapeRecogn/Test/TestShapeRecogn.py b/src/ShapeRecogn/Test/TestShapeRecogn.py index 508fc4387..6d6142d96 100644 --- a/src/ShapeRecogn/Test/TestShapeRecogn.py +++ b/src/ShapeRecogn/Test/TestShapeRecogn.py @@ -50,16 +50,20 @@ class MEDCouplingIterativeStatisticsTest(unittest.TestCase): """ Direct translation of PlaneTest::testArea """ + self.assertEqual( sr.AllManagedPrimitivesStr() , ('Plane', 'Sphere', 'Cylinder', 'Cone', 'Torus', 'Unknown') ) fname = "ShapeRecognPlane.med" mesh = ml.ReadUMeshFromFile( getResourceFile( fname, 3 ),0) srMesh = sr.ShapeRecognMeshBuilder( mesh ) rem = srMesh.recognize() areas = srMesh.getAreas() - assert( areas.getNumberOfAreas() == 1 ) - assert( areas.getNumberOfNodes(0) == 36 ) + self.assertEqual( areas.getNumberOfAreas(), 1 ) + self.assertEqual( areas.getNumberOfNodes(0), 36 ) nodeIds = areas.getNodeIds(0) f = rem.getAreaPrimitiveType() - assert( areas.getPrimitiveTypeName(0) == "Plane") + self.assertEqual( areas.getPrimitiveType(0), 0) + self.assertEqual( areas.getPrimitiveTypeName(0), "Plane") + self.assertEqual( sr.ConvertStringToPrimitive("Plane"),0) + self.assertEqual( sr.ConvertPrimitiveToString(0),"Plane") f_normal = rem.getNodeNormal() affinePoint = srMesh.buildAreaAffinePoint().getArray()[ nodeIds[0] ] normal = f_normal.getArray()[ nodeIds[0] ] -- 2.39.2