From: Anthony Geay Date: Fri, 30 Aug 2024 06:40:18 +0000 (+0200) Subject: [EDF30834] : Templatization + python wrapping X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=f3b2265a16754558b8b1eb80bab70e33329931f9;p=tools%2Fmedcoupling.git [EDF30834] : Templatization + python wrapping --- diff --git a/src/ShapeRecogn/Areas.cxx b/src/ShapeRecogn/Areas.cxx index 6f2f155a3..31d5d39bb 100644 --- a/src/ShapeRecogn/Areas.cxx +++ b/src/ShapeRecogn/Areas.cxx @@ -64,7 +64,7 @@ void Areas::removeArea(mcIdType areaId) void Areas::addNode(mcIdType areaId, mcIdType nodeId) { removeNode(nodeId); - areaIdByNodes[nodeId] = areaId; + areaIdByNodes[nodeId] = FromIdType(areaId); Area &area = areas[areaId]; area.nodeIds.push_back(nodeId); size_t nbNodes = area.nodeIds.size(); @@ -238,7 +238,7 @@ void Areas::cleanArea(mcIdType areaId, mcIdType newAreaId = -1) { Area &area = areas[areaId]; for (mcIdType nodeId : area.nodeIds) - areaIdByNodes[nodeId] = newAreaId; + areaIdByNodes[nodeId] = FromIdType( newAreaId ); area.primitive = PrimitiveType::Unknown; area.k1 = 0.0; area.k2 = 0.0; @@ -498,7 +498,7 @@ void Areas::computeTorusProperties(mcIdType areaId) area.center[i] = xc * base2d[i] + yc * base2d[3 + i] + meanMajorRadiusNodes[i]; } -const std::vector &Areas::getAreaIdByNodes() const +const std::vector &Areas::getAreaIdByNodes() const { return areaIdByNodes; } diff --git a/src/ShapeRecogn/Areas.hxx b/src/ShapeRecogn/Areas.hxx index 912b4e680..8e3158a56 100644 --- a/src/ShapeRecogn/Areas.hxx +++ b/src/ShapeRecogn/Areas.hxx @@ -59,7 +59,7 @@ namespace MEDCoupling void cleanInvalidNodeAreas(); mcIdType getAreaId(mcIdType nodeId) const; - const std::vector &getAreaIdByNodes() const; + const std::vector &getAreaIdByNodes() const; bool isEmpty(mcIdType areaId) const; size_t getNumberOfAreas() const; @@ -100,6 +100,6 @@ namespace MEDCoupling std::vector areas; const Nodes *nodes; - std::vector areaIdByNodes; + std::vector areaIdByNodes; }; } diff --git a/src/ShapeRecogn/ShapeRecognMesh.cxx b/src/ShapeRecogn/ShapeRecognMesh.cxx index 9cd4bc7c2..61b664d09 100644 --- a/src/ShapeRecogn/ShapeRecognMesh.cxx +++ b/src/ShapeRecogn/ShapeRecognMesh.cxx @@ -68,7 +68,7 @@ const MEDCouplingFieldDouble *ShapeRecognMesh::getNodeK2() const return nodeK2; } -const MEDCouplingFieldDouble *ShapeRecognMesh::getNodePrimitiveType() const +const MEDCouplingFieldInt32 *ShapeRecognMesh::getNodePrimitiveType() const { return nodePrimitiveType; } @@ -78,12 +78,12 @@ const MEDCouplingFieldDouble *ShapeRecognMesh::getNodeNormal() const return nodeNormal; } -const MEDCouplingFieldDouble *ShapeRecognMesh::getAreaId() const +const MEDCouplingFieldInt32 *ShapeRecognMesh::getAreaId() const { return areaId; } -const MEDCouplingFieldDouble *ShapeRecognMesh::getAreaPrimitiveType() const +const MEDCouplingFieldInt32 *ShapeRecognMesh::getAreaPrimitiveType() const { return areaPrimitiveType; } diff --git a/src/ShapeRecogn/ShapeRecognMesh.hxx b/src/ShapeRecogn/ShapeRecognMesh.hxx index 63252a0ac..deb44962b 100644 --- a/src/ShapeRecogn/ShapeRecognMesh.hxx +++ b/src/ShapeRecogn/ShapeRecognMesh.hxx @@ -22,6 +22,7 @@ #include #include "MEDCouplingUMesh.hxx" +#include "MEDCouplingFieldInt32.hxx" #include "MEDCouplingFieldDouble.hxx" #include "MEDCouplingRefCountObject.hxx" @@ -39,12 +40,12 @@ namespace MEDCoupling // Node properties const MEDCouplingFieldDouble *getNodeK1() const; const MEDCouplingFieldDouble *getNodeK2() const; - const MEDCouplingFieldDouble *getNodePrimitiveType() const; + const MEDCouplingFieldInt32 *getNodePrimitiveType() const; const MEDCouplingFieldDouble *getNodeNormal() const; // Area properties - const MEDCouplingFieldDouble *getAreaId() const; - const MEDCouplingFieldDouble *getAreaPrimitiveType() const; + const MEDCouplingFieldInt32 *getAreaId() const; + const MEDCouplingFieldInt32 *getAreaPrimitiveType() const; const MEDCouplingFieldDouble *getAreaNormal() const; const MEDCouplingFieldDouble *getMinorRadius() const; const MEDCouplingFieldDouble *getRadius() const; @@ -60,10 +61,10 @@ namespace MEDCoupling private: MCAuto nodeK1; MCAuto nodeK2; - MCAuto nodePrimitiveType; + MCAuto nodePrimitiveType; MCAuto nodeNormal; - MCAuto areaId; - MCAuto areaPrimitiveType; + MCAuto areaId; + MCAuto areaPrimitiveType; MCAuto areaNormal; MCAuto minorRadius; MCAuto radius; diff --git a/src/ShapeRecogn/ShapeRecognMeshBuilder.cxx b/src/ShapeRecogn/ShapeRecognMeshBuilder.cxx index fe0e7b2b0..6f1434065 100644 --- a/src/ShapeRecogn/ShapeRecognMeshBuilder.cxx +++ b/src/ShapeRecogn/ShapeRecognMeshBuilder.cxx @@ -22,7 +22,10 @@ #include "NodesBuilder.hxx" #include "AreasBuilder.hxx" #include "ShapeRecognMesh.hxx" + #include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingFieldInt64.hxx" +#include "MEDCouplingFieldInt32.hxx" using namespace MEDCoupling; @@ -82,169 +85,192 @@ const Areas *ShapeRecognMeshBuilder::getAreas() const return areas.get(); } -MEDCouplingFieldDouble *ShapeRecognMeshBuilder::buildNodeK1() const +void ShapeRecognMeshBuilder::checkNodesBeforeBuildingField() const { if ( ! nodes.get() ) throw INTERP_KERNEL::Exception("recognize must be called before building any fields"); - return buildField("K1 (Node)", 1, nodes->getK1()); } -MEDCouplingFieldDouble *ShapeRecognMeshBuilder::buildNodeK2() const +void ShapeRecognMeshBuilder::checkAreasBeforeBuildingField() const { - if ( ! nodes.get() ) + if ( ! areas.get() ) throw INTERP_KERNEL::Exception("recognize must be called before building any fields"); - return buildField("K2 (Node)", 1, nodes->getK2()); } -MEDCouplingFieldDouble *ShapeRecognMeshBuilder::buildNodePrimitiveType() const +template +typename Traits::FieldType *buildField( + const std::string &name, + MCAuto::ArrayType> data, + const MEDCouplingUMesh *mesh) { - if ( ! nodes.get() ) - throw INTERP_KERNEL::Exception("recognize must be called before building any fields"); - return buildField("Primitive Type (Node)", 1, nodes->getPrimitiveType()); + using ZeField = typename Traits::FieldType; + ZeField *field = ZeField::New(ON_NODES); + mcIdType nbNodes = data->getNumberOfTuples(); + size_t nbOfCompo = data->getNumberOfComponents(); + field->setName(name); + field->setMesh(mesh); + if (nbOfCompo == 3) + { + data->setInfoOnComponent(0, "X"); + data->setInfoOnComponent(1, "Y"); + data->setInfoOnComponent(2, "Z"); + } + field->setArray(data); + return field; +} + +template +typename Traits::FieldType *buildField( + const std::string &name, + size_t nbOfCompo, + const std::vector &values, + const MEDCouplingUMesh *mesh) +{ + using ZeArray = typename Traits::ArrayType; + mcIdType nbNodes = mesh->getNumberOfNodes(); + MCAuto data( ZeArray::New() ); + data->setName(name); + data->alloc(nbNodes, nbOfCompo); + std::copy(values.begin(), values.end(), data->getPointer()); + data->declareAsNew(); + return buildField(name, data, mesh); +} + +template +typename Traits::FieldType *buildField( + const std::string &name, + size_t nbOfCompo, + T *values, + const MEDCouplingUMesh *mesh) +{ + using ZeArray = typename Traits::ArrayType; + mcIdType nbNodes = mesh->getNumberOfNodes(); + ZeArray *data = ZeArray::New(); + data->setName(name); + data->useArray( + values, + true, + MEDCoupling::DeallocType::CPP_DEALLOC, + nbNodes, + nbOfCompo); + return buildField(name, data, mesh); +} + +template +T *buildAreaArrayT(Areas *areas, Nodes *nodes, std::function areaFunc) +{ + const std::vector &areaIdByNodes = areas->getAreaIdByNodes(); + T *values = new T[nodes->getNbNodes()]; + for (size_t nodeId = 0; nodeId < areaIdByNodes.size(); ++nodeId) + { + Int32 areaId = areaIdByNodes[nodeId]; + if (areaId != -1) + values[nodeId] = areaFunc(areas, areaId); + } + return values; +} + +MEDCouplingFieldDouble *ShapeRecognMeshBuilder::buildNodeK1() const +{ + checkNodesBeforeBuildingField(); + return buildField("K1 (Node)", 1, nodes->getK1(), mesh); +} + +MEDCouplingFieldDouble *ShapeRecognMeshBuilder::buildNodeK2() const +{ + checkNodesBeforeBuildingField(); + return buildField("K2 (Node)", 1, nodes->getK2(), mesh); +} + +MEDCouplingFieldInt32 *ShapeRecognMeshBuilder::buildNodePrimitiveType() const +{ + checkNodesBeforeBuildingField(); + return nullptr;//buildField("Primitive Type (Node)", 1, nodes->getPrimitiveType(), mesh); } MEDCouplingFieldDouble *ShapeRecognMeshBuilder::buildNodeNormal() const { - if ( ! nodes.get() ) - throw INTERP_KERNEL::Exception("recognize must be called before building any fields"); - return buildField("Normal (Node)", 3, nodes->getNormals()); + checkNodesBeforeBuildingField(); + return buildField("Normal (Node)", 3, nodes->getNormals(), mesh); } -MEDCouplingFieldDouble *ShapeRecognMeshBuilder::buildAreaId() const +MEDCouplingFieldInt32 *ShapeRecognMeshBuilder::buildAreaId() const { - if ( ! areas.get() ) - throw INTERP_KERNEL::Exception("recognize must be called before building any fields"); - return buildField("Area Id", 1, areas->getAreaIdByNodes()); + checkAreasBeforeBuildingField(); + return buildField("Area Id", 1, areas->getAreaIdByNodes(), mesh); } -MEDCouplingFieldDouble *ShapeRecognMeshBuilder::buildAreaPrimitiveType() const +MEDCouplingFieldInt32 *ShapeRecognMeshBuilder::buildAreaPrimitiveType() const { - if ( ! areas.get() ) - throw INTERP_KERNEL::Exception("recognize must be called before building any fields"); - double *values = buildAreaArray([](Areas *areas, mcIdType areaId) -> double - { return (double)areas->getPrimitiveType(areaId); }); - return buildField("Primitive Type (Area)", 1, values); + checkAreasBeforeBuildingField(); + std::int32_t *values = buildAreaArrayT(areas.get(),nodes.get(),[](Areas *areas, mcIdType areaId) -> std::int32_t + { return (std::int32_t)areas->getPrimitiveType(areaId); }); + return buildField("Primitive Type (Area)", 1, values, mesh); } MEDCouplingFieldDouble *ShapeRecognMeshBuilder::buildAreaNormal() const { - if ( ! areas.get() ) - throw INTERP_KERNEL::Exception("recognize must be called before building any fields"); + checkAreasBeforeBuildingField(); double *values = buildArea3DArray([](Areas *areas, mcIdType areaId) -> const std::array & { return areas->getNormal(areaId); }); - return buildField("Normal (Area)", 3, values); + return buildField("Normal (Area)", 3, values, mesh); } MEDCouplingFieldDouble *ShapeRecognMeshBuilder::buildMinorRadius() const { - if ( ! areas.get() ) - throw INTERP_KERNEL::Exception("recognize must be called before building any fields"); + checkAreasBeforeBuildingField(); double *values = buildAreaArray([](Areas *areas, mcIdType areaId) -> double { return areas->getMinorRadius(areaId); }); - return buildField("Minor Radius (Area)", 1, values); + return buildField("Minor Radius (Area)", 1, values, mesh); } MEDCouplingFieldDouble *ShapeRecognMeshBuilder::buildRadius() const { - if ( ! areas.get() ) - throw INTERP_KERNEL::Exception("recognize must be called before building any fields"); + checkAreasBeforeBuildingField(); double *values = buildAreaArray([](Areas *areas, mcIdType areaId) -> double { return areas->getRadius(areaId); }); - return buildField("Radius (Area)", 1, values); + return buildField("Radius (Area)", 1, values, mesh); } MEDCouplingFieldDouble *ShapeRecognMeshBuilder::buildAngle() const { - if ( ! areas.get() ) - throw INTERP_KERNEL::Exception("recognize must be called before building any fields"); + checkAreasBeforeBuildingField(); double *values = buildAreaArray([](Areas *areas, mcIdType areaId) -> double { return areas->getAngle(areaId); }); - return buildField("Angle (Area)", 1, values); + return buildField("Angle (Area)", 1, values, mesh); } MEDCouplingFieldDouble *ShapeRecognMeshBuilder::buildCenter() const { - if ( ! areas.get() ) - throw INTERP_KERNEL::Exception("recognize must be called before building any fields"); + checkAreasBeforeBuildingField(); double *values = buildArea3DArray([](Areas *areas, mcIdType areaId) -> const std::array & { return areas->getCenter(areaId); }); - return buildField("Center (Area)", 3, values); + return buildField("Center (Area)", 3, values, mesh); } MEDCouplingFieldDouble *ShapeRecognMeshBuilder::buildAxis() const { - if ( ! areas.get() ) - throw INTERP_KERNEL::Exception("recognize must be called before building any fields"); + checkAreasBeforeBuildingField(); double *values = buildArea3DArray([](Areas *areas, mcIdType areaId) -> const std::array & { return areas->getAxis(areaId); }); - return buildField("Axis (Area)", 3, values); + return buildField("Axis (Area)", 3, values, mesh); } MEDCouplingFieldDouble *ShapeRecognMeshBuilder::buildApex() const { - if ( ! areas.get() ) - throw INTERP_KERNEL::Exception("recognize must be called before building any fields"); + checkAreasBeforeBuildingField(); double *values = buildArea3DArray([](Areas *areas, mcIdType areaId) -> const std::array & { return areas->getApex(areaId); }); - return buildField("Apex (Area)", 3, values); -} - -template -MEDCouplingFieldDouble *ShapeRecognMeshBuilder::buildField( - const std::string &name, - size_t nbOfCompo, - const std::vector &values) const -{ - MCAuto data( DataArrayDouble::New() ); - data->setName(name); - data->alloc(nodes->getNbNodes(), nbOfCompo); - std::copy(values.begin(), values.end(), data->getPointer()); - data->declareAsNew(); - return buildField(name, nbOfCompo, data); -} - -MEDCouplingFieldDouble *ShapeRecognMeshBuilder::buildField( - const std::string &name, - size_t nbOfCompo, - double *values) const -{ - DataArrayDouble *data = DataArrayDouble::New(); - data->setName(name); - data->useArray( - values, - true, - MEDCoupling::DeallocType::CPP_DEALLOC, - nodes->getNbNodes(), - nbOfCompo); - return buildField(name, nbOfCompo, data); -} - -MEDCouplingFieldDouble *ShapeRecognMeshBuilder::buildField( - const std::string &name, - size_t nbOfCompo, - MCAuto data) const -{ - MEDCouplingFieldDouble *field = MEDCouplingFieldDouble::New(ON_NODES); - field->setName(name); - field->setMesh(mesh); - if (nbOfCompo == 3) - { - data->setInfoOnComponent(0, "X"); - data->setInfoOnComponent(1, "Y"); - data->setInfoOnComponent(2, "Z"); - } - field->setArray(data); - return field; + return buildField("Apex (Area)", 3, values, mesh); } -double *ShapeRecognMeshBuilder::buildArea3DArray( - const std::array &(*areaFunc)(Areas *, mcIdType)) const +double *ShapeRecognMeshBuilder::buildArea3DArray(std::function &(Areas *, Int32)> areaFunc) const { double *values = new double[3 * nodes->getNbNodes()]; - const std::vector &areaIdByNodes = areas->getAreaIdByNodes(); + const std::vector &areaIdByNodes = areas->getAreaIdByNodes(); for (size_t nodeId = 0; nodeId < areaIdByNodes.size(); ++nodeId) { - mcIdType areaId = areaIdByNodes[nodeId]; + Int32 areaId = areaIdByNodes[nodeId]; if (areaId != -1) { const std::array &areaValues = areaFunc(areas.get(), areaId); @@ -256,15 +282,7 @@ double *ShapeRecognMeshBuilder::buildArea3DArray( return values; } -double *ShapeRecognMeshBuilder::buildAreaArray(double (*areaFunc)(Areas *, mcIdType)) const +double *ShapeRecognMeshBuilder::buildAreaArray(std::function areaFunc) const { - const std::vector &areaIdByNodes = areas->getAreaIdByNodes(); - double *values = new double[nodes->getNbNodes()]; - for (size_t nodeId = 0; nodeId < areaIdByNodes.size(); ++nodeId) - { - mcIdType areaId = areaIdByNodes[nodeId]; - if (areaId != -1) - values[nodeId] = areaFunc(areas.get(), areaId); - } - return values; + return buildAreaArrayT(areas.get(), nodes.get(), areaFunc ); } diff --git a/src/ShapeRecogn/ShapeRecognMeshBuilder.hxx b/src/ShapeRecogn/ShapeRecognMeshBuilder.hxx index af7b53476..051fdf65a 100644 --- a/src/ShapeRecogn/ShapeRecognMeshBuilder.hxx +++ b/src/ShapeRecogn/ShapeRecognMeshBuilder.hxx @@ -22,15 +22,19 @@ #include #include "MEDCouplingUMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" #include "Nodes.hxx" #include "Areas.hxx" #include +#include namespace MEDCoupling { + class MEDCouplingFieldInt32; + class MEDCouplingFieldInt64; + class MEDCouplingFieldDouble; + class ShapeRecognMesh; class ShapeRecognMeshBuilder @@ -49,12 +53,12 @@ namespace MEDCoupling // Node properties MEDCoupling::MEDCouplingFieldDouble *buildNodeK1() const; MEDCoupling::MEDCouplingFieldDouble *buildNodeK2() const; - MEDCoupling::MEDCouplingFieldDouble *buildNodePrimitiveType() const; + MEDCoupling::MEDCouplingFieldInt32 *buildNodePrimitiveType() const; MEDCoupling::MEDCouplingFieldDouble *buildNodeNormal() const; // Area properties - MEDCoupling::MEDCouplingFieldDouble *buildAreaId() const; - MEDCoupling::MEDCouplingFieldDouble *buildAreaPrimitiveType() const; + MEDCoupling::MEDCouplingFieldInt32 *buildAreaId() const; + MEDCoupling::MEDCouplingFieldInt32 *buildAreaPrimitiveType() const; MEDCoupling::MEDCouplingFieldDouble *buildAreaNormal() const; MEDCoupling::MEDCouplingFieldDouble *buildMinorRadius() const; MEDCoupling::MEDCouplingFieldDouble *buildRadius() const; @@ -63,22 +67,11 @@ namespace MEDCoupling MEDCoupling::MEDCouplingFieldDouble *buildAxis() const; MEDCoupling::MEDCouplingFieldDouble *buildApex() const; - template - MEDCouplingFieldDouble *buildField( - const std::string &name, - size_t nbOfCompo, - const std::vector &values) const; - MEDCouplingFieldDouble *buildField( - const std::string &name, - size_t nbOfCompo, - double *values) const; - MEDCouplingFieldDouble *buildField( - const std::string &name, - size_t nbOfCompo, - MCAuto values) const; - double *buildArea3DArray(const std::array &(*areaFunc)(Areas *, mcIdType)) const; - double *buildAreaArray(double (*areaFunc)(Areas *, mcIdType)) const; + double *buildArea3DArray(std::function &(Areas *, Int32)> areaFunc) const; + double *buildAreaArray(std::function areaFunc) const; void assign(MCAuto< MEDCouplingUMesh > mesh); + void checkNodesBeforeBuildingField() const; + void checkAreasBeforeBuildingField() const; private: MCConstAuto< MEDCouplingUMesh > mesh; std::unique_ptr nodes; diff --git a/src/ShapeRecogn/Swig/ShapeRecognCommon.i b/src/ShapeRecogn/Swig/ShapeRecognCommon.i index 5362e77bd..66e959206 100644 --- a/src/ShapeRecogn/Swig/ShapeRecognCommon.i +++ b/src/ShapeRecogn/Swig/ShapeRecognCommon.i @@ -29,10 +29,6 @@ using namespace MEDCoupling; using namespace INTERP_KERNEL; %} -%template(ivec) std::vector; -%template(dvec) std::vector; -%template(svec) std::vector; - #ifdef WITH_NUMPY %init %{ import_array(); %} #endif diff --git a/src/ShapeRecogn/Swig/ShapeRecognImpl.i b/src/ShapeRecogn/Swig/ShapeRecognImpl.i index c09a23315..677bdb2eb 100644 --- a/src/ShapeRecogn/Swig/ShapeRecognImpl.i +++ b/src/ShapeRecogn/Swig/ShapeRecognImpl.i @@ -47,6 +47,11 @@ public: double getMinorRadius(mcIdType areaId) const; double getRadius(mcIdType areaId) const; double getAngle(mcIdType areaId) const; + // + bool isEmpty(mcIdType areaId) const; + size_t getNumberOfAreas() const; + size_t getNumberOfNodes(mcIdType areaId) const; + std::string getPrimitiveTypeName(mcIdType areaId) const; /*const std::array &getNormal(mcIdType areaId) const; const std::array &getCenter(mcIdType areaId) const; const std::array &getAxis(mcIdType areaId) const; @@ -58,6 +63,8 @@ private: ~Areas(); }; +using namespace MEDCoupling; + class ShapeRecognMesh : public RefCountObject { public: @@ -163,19 +170,13 @@ private: class ShapeRecognMeshBuilder { public: - ShapeRecognMeshBuilder(MEDCouplingUMesh *mesh); + ShapeRecognMeshBuilder(MEDCoupling::MEDCouplingUMesh *mesh); ~ShapeRecognMeshBuilder(); //const Nodes *getNodes() const; const Areas *getAreas() const; %extend { - ShapeRecognMeshBuilder(MEDCouplingUMesh *mesh) - { - - - } - ShapeRecognMesh *recognize() { MCAuto ret = self->recognize();