]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Add build methods for retrieving the fields of the Areas and Nodes
authorEl Hadi Moussi <moussi@phimeca.com>
Thu, 8 Aug 2024 15:39:55 +0000 (17:39 +0200)
committerEl Hadi Moussi <moussi@phimeca.com>
Thu, 8 Aug 2024 15:39:55 +0000 (17:39 +0200)
src/ShapeRecogn/ShapeRecognMesh.cxx
src/ShapeRecogn/ShapeRecognMesh.hxx
src/ShapeRecogn/Swig/ShapeRecognMesh.i

index 27572d9eda8fa49f676fd8a18e79db3370ed50cd..d5910e949600c05d7055b8ad9446e5a372a617eb 100644 (file)
@@ -15,73 +15,13 @@ ShapeRecognMesh::ShapeRecognMesh(const std::string &fileName)
 
 ShapeRecognMesh::~ShapeRecognMesh()
 {
-    if (areas != 0)
+    if (areas != nullptr)
         delete areas;
-    if (nodes != 0)
+    if (nodes != nullptr)
         delete nodes;
     mesh->decrRef();
 }
 
-const Nodes *ShapeRecognMesh::getNodes() const
-{
-    return nodes;
-}
-
-MEDCouplingFieldDouble *ShapeRecognMesh::buildAffinePointField() const
-{
-    const std::vector<mcIdType> &areaIdByNodes = areas->getAreaIdByNodes();
-    MEDCouplingFieldDouble *field = MEDCouplingFieldDouble::New(
-        ON_NODES);
-    field->setName("area_affine_point");
-    field->setMesh(mesh);
-    DataArrayDouble *values = DataArrayDouble::New();
-    values->setName("area_affine_point");
-    values->alloc(nodes->getNbNodes(), 3);
-    values->setInfoOnComponent(0, "X");
-    values->setInfoOnComponent(1, "Y");
-    values->setInfoOnComponent(2, "Z");
-    for (mcIdType nodeId = 0; nodeId < (mcIdType)areaIdByNodes.size(); ++nodeId)
-    {
-        std::array<double, 3> affinePoint = areas->getAffinePoint(areaIdByNodes[nodeId]);
-        values->setIJ(nodeId, 0, affinePoint[0]);
-        values->setIJ(nodeId, 1, affinePoint[1]);
-        values->setIJ(nodeId, 2, affinePoint[2]);
-    }
-    field->setArray(values);
-    values->decrRef();
-    return field;
-}
-
-MEDCouplingFieldDouble *ShapeRecognMesh::buildNormalField() const
-{
-    const std::vector<mcIdType> &areaIdByNodes = areas->getAreaIdByNodes();
-    MEDCouplingFieldDouble *field = MEDCouplingFieldDouble::New(
-        ON_NODES);
-    field->setName("area_normal");
-    field->setMesh(mesh);
-    DataArrayDouble *values = DataArrayDouble::New();
-    values->setName("area_normal");
-    values->alloc(nodes->getNbNodes(), 3);
-    values->setInfoOnComponent(0, "X");
-    values->setInfoOnComponent(1, "Y");
-    values->setInfoOnComponent(2, "Z");
-    for (mcIdType nodeId = 0; nodeId < (mcIdType)areaIdByNodes.size(); ++nodeId)
-    {
-        std::array<double, 3> normal = areas->getNormal(areaIdByNodes[nodeId]);
-        values->setIJ(nodeId, 0, normal[0]);
-        values->setIJ(nodeId, 1, normal[1]);
-        values->setIJ(nodeId, 2, normal[2]);
-    }
-    field->setArray(values);
-    values->decrRef();
-    return field;
-}
-
-const Areas *ShapeRecognMesh::getAreas() const
-{
-    return areas;
-}
-
 void ShapeRecognMesh::recognize()
 {
     mesh->incrRef();
@@ -92,104 +32,261 @@ void ShapeRecognMesh::recognize()
     areasBuilder.expand();
     areasBuilder.rebuild();
     areas = areasBuilder.getAreas();
-    // for (mcIdType areaId = 0; areaId < areas->getNumberOfAreas(); ++areaId)
-    // {
-    //     std::cout << "area ("
-    //               << areaId
-    //               << ") : "
-    //               << areas->getPrimitiveTypeName(areaId)
-    //               << ", " << areas->getNumberOfNodes(areaId) << " "
-    //               << "[";
-    //     // for (mcIdType nodeId : areas->getNodeIds(areaId))
-    //     // {
-    //     //     std::cout << nodeId << ",";
-    //     // }
-    //     std::cout << "]\n";
-    // }
-}
-
-void ShapeRecognMesh::recognize(const std::string &outputFile)
+}
+
+void ShapeRecognMesh::recognize(const std::string &outputFile, bool writeFromScratch)
 {
     recognize();
     // Nodes
     // - k1
-    MEDCouplingFieldDouble *fieldNodeK1 = MEDCouplingFieldDouble::New(
-        ON_NODES);
-    fieldNodeK1->setName("node_k1");
-    fieldNodeK1->setMesh(mesh);
-    DataArrayDouble *nodeK1 = DataArrayDouble::New();
-    nodeK1->setName("node_k1");
-    nodeK1->alloc(nodes->getNbNodes(), 1);
-    for (mcIdType nodeId = 0; nodeId < nodes->getNbNodes(); ++nodeId)
-        nodeK1->setIJ(nodeId, 0, nodes->getK1(nodeId));
-    fieldNodeK1->setArray(nodeK1);
-    nodeK1->decrRef();
-    WriteField(outputFile, fieldNodeK1, true);
+    MEDCouplingFieldDouble *fieldNodeK1 = buildNodeK1();
+    WriteField(outputFile, fieldNodeK1, writeFromScratch);
     fieldNodeK1->decrRef();
     // - k2
-    MEDCouplingFieldDouble *fieldNodeK2 = MEDCouplingFieldDouble::New(
-        ON_NODES);
-    fieldNodeK2->setName("node_k2");
-    fieldNodeK2->setMesh(mesh);
-    DataArrayDouble *nodeK2 = DataArrayDouble::New();
-    nodeK2->setName("node_k2");
-    nodeK2->alloc(nodes->getNbNodes(), 1);
-    for (mcIdType nodeId = 0; nodeId < nodes->getNbNodes(); ++nodeId)
-        nodeK2->setIJ(nodeId, 0, nodes->getK2(nodeId));
-    fieldNodeK2->setArray(nodeK2);
-    nodeK2->decrRef();
+    MEDCouplingFieldDouble *fieldNodeK2 = buildNodeK2();
     WriteField(outputFile, fieldNodeK2, false);
     fieldNodeK2->decrRef();
     // - primitive types
-    MEDCouplingFieldDouble *fieldNodePrimitiveTypes = MEDCouplingFieldDouble::New(
-        ON_NODES);
-    fieldNodePrimitiveTypes->setName("node_primitive_types");
-    fieldNodePrimitiveTypes->setMesh(mesh);
-    DataArrayDouble *nodePrimitiveTypes = DataArrayDouble::New();
-    nodePrimitiveTypes->setName("node_primitive_types");
-    nodePrimitiveTypes->alloc(nodes->getNbNodes(), 1);
-    for (mcIdType nodeId = 0; nodeId < nodes->getNbNodes(); ++nodeId)
-        nodePrimitiveTypes->setIJ(nodeId, 0, (double)convertPrimitiveToInt(nodes->getPrimitiveType(nodeId)));
-    fieldNodePrimitiveTypes->setArray(nodePrimitiveTypes);
-    nodePrimitiveTypes->decrRef();
-    WriteField(outputFile, fieldNodePrimitiveTypes, false);
-    fieldNodePrimitiveTypes->decrRef();
+    MEDCouplingFieldDouble *fieldNodePrimitiveType = buildNodePrimitiveType();
+    WriteField(outputFile, fieldNodePrimitiveType, false);
+    fieldNodePrimitiveType->decrRef();
+    // - Normal
+    MEDCouplingFieldDouble *fieldNodeNormal = buildNodeNormal();
+    WriteField(outputFile, fieldNodeNormal, false);
+    fieldNodeNormal->decrRef();
     // Areas
+    // - Area Id
+    MEDCouplingFieldDouble *fieldAreaId = buildAreaId();
+    WriteField(outputFile, fieldAreaId, false);
+    fieldAreaId->decrRef();
+    // - Primitive Types
+    MEDCouplingFieldDouble *fieldAreaPrimitiveType = buildAreaPrimitiveType();
+    WriteField(outputFile, fieldAreaPrimitiveType, false);
+    fieldAreaPrimitiveType->decrRef();
+    // - Normal
+    auto fieldAreaNormal = buildAreaNormal();
+    WriteField(outputFile, fieldAreaNormal, false);
+    fieldAreaNormal->decrRef();
+    // - Minor Radius
+    MEDCouplingFieldDouble *fieldAreaMinorRadius = buildMinorRadius();
+    WriteField(outputFile, fieldAreaMinorRadius, false);
+    fieldAreaMinorRadius->decrRef();
+    // - Radius
+    MEDCouplingFieldDouble *fieldAreaRadius = buildRadius();
+    WriteField(outputFile, fieldAreaRadius, false);
+    fieldAreaRadius->decrRef();
+    // - Angle
+    MEDCouplingFieldDouble *fieldAreaAngle = buildAngle();
+    WriteField(outputFile, fieldAreaAngle, false);
+    fieldAreaAngle->decrRef();
+    // - Center
+    MEDCouplingFieldDouble *fieldAreaCenter = buildCenter();
+    WriteField(outputFile, fieldAreaCenter, false);
+    fieldAreaCenter->decrRef();
+    // - Axis
+    MEDCouplingFieldDouble *fieldAreaAxis = buildAxis();
+    WriteField(outputFile, fieldAreaAxis, false);
+    fieldAreaAxis->decrRef();
+    // - Apex
+    MEDCouplingFieldDouble *fieldAreaApex = buildApex();
+    WriteField(outputFile, fieldAreaApex, false);
+    fieldAreaApex->decrRef();
+}
+
+const Nodes *ShapeRecognMesh::getNodes() const
+{
+    return nodes;
+}
+
+const Areas *ShapeRecognMesh::getAreas() const
+{
+    return areas;
+}
+
+MEDCouplingFieldDouble *ShapeRecognMesh::buildNodeK1() const
+{
+    if (nodes == nullptr)
+        throw INTERP_KERNEL::Exception("recognize must be called before building any fields");
+    return buildField("K1 (Node)", 1, nodes->getK1());
+}
+
+MEDCouplingFieldDouble *ShapeRecognMesh::buildNodeK2() const
+{
+    if (nodes == nullptr)
+        throw INTERP_KERNEL::Exception("recognize must be called before building any fields");
+    return buildField("K2 (Node)", 1, nodes->getK2());
+}
+
+MEDCouplingFieldDouble *ShapeRecognMesh::buildNodePrimitiveType() const
+{
+    if (nodes == nullptr)
+        throw INTERP_KERNEL::Exception("recognize must be called before building any fields");
+    return buildField("Primitive Type (Node)", 1, nodes->getPrimitiveType());
+}
+
+MEDCouplingFieldDouble *ShapeRecognMesh::buildNodeNormal() const
+{
+    if (nodes == nullptr)
+        throw INTERP_KERNEL::Exception("recognize must be called before building any fields");
+    return buildField("Normal (Node)", 3, nodes->getNormals());
+}
+
+MEDCouplingFieldDouble *ShapeRecognMesh::buildAreaId() const
+{
+    if (areas == nullptr)
+        throw INTERP_KERNEL::Exception("recognize must be called before building any fields");
+    return buildField("Area Id", 1, areas->getAreaIdByNodes());
+}
+
+MEDCouplingFieldDouble *ShapeRecognMesh::buildAreaPrimitiveType() const
+{
+    if (areas == nullptr)
+        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);
+}
+
+MEDCouplingFieldDouble *ShapeRecognMesh::buildAreaNormal() const
+{
+    if (areas == nullptr)
+        throw INTERP_KERNEL::Exception("recognize must be called before building any fields");
+    double *values = buildArea3DArray([](Areas *areas, mcIdType areaId) -> const std::array<double, 3> &
+                                      { return areas->getNormal(areaId); });
+    return buildField("Normal (Area)", 3, values);
+}
+
+MEDCouplingFieldDouble *ShapeRecognMesh::buildMinorRadius() const
+{
+    if (areas == nullptr)
+        throw INTERP_KERNEL::Exception("recognize must be called before building any fields");
+    double *values = buildAreaArray([](Areas *areas, mcIdType areaId) -> double
+                                    { return areas->getMinorRadius(areaId); });
+    return buildField("Minor Radius (Area)", 1, values);
+}
+
+MEDCouplingFieldDouble *ShapeRecognMesh::buildRadius() const
+{
+    if (areas == nullptr)
+        throw INTERP_KERNEL::Exception("recognize must be called before building any fields");
+    double *values = buildAreaArray([](Areas *areas, mcIdType areaId) -> double
+                                    { return areas->getRadius(areaId); });
+    return buildField("Radius (Area)", 1, values);
+}
+
+MEDCouplingFieldDouble *ShapeRecognMesh::buildAngle() const
+{
+    if (areas == nullptr)
+        throw INTERP_KERNEL::Exception("recognize must be called before building any fields");
+    double *values = buildAreaArray([](Areas *areas, mcIdType areaId) -> double
+                                    { return areas->getAngle(areaId); });
+    return buildField("Angle (Area)", 1, values);
+}
+
+MEDCouplingFieldDouble *ShapeRecognMesh::buildCenter() const
+{
+    if (areas == nullptr)
+        throw INTERP_KERNEL::Exception("recognize must be called before building any fields");
+    double *values = buildArea3DArray([](Areas *areas, mcIdType areaId) -> const std::array<double, 3> &
+                                      { return areas->getCenter(areaId); });
+    return buildField("Normal (Area)", 3, values);
+}
+
+MEDCouplingFieldDouble *ShapeRecognMesh::buildAxis() const
+{
+    if (areas == nullptr)
+        throw INTERP_KERNEL::Exception("recognize must be called before building any fields");
+    double *values = buildArea3DArray([](Areas *areas, mcIdType areaId) -> const std::array<double, 3> &
+                                      { return areas->getAxis(areaId); });
+    return buildField("Axis (Area)", 3, values);
+}
+
+MEDCouplingFieldDouble *ShapeRecognMesh::buildApex() const
+{
+    if (areas == nullptr)
+        throw INTERP_KERNEL::Exception("recognize must be called before building any fields");
+    double *values = buildArea3DArray([](Areas *areas, mcIdType areaId) -> const std::array<double, 3> &
+                                      { return areas->getApex(areaId); });
+    return buildField("Axis (Area)", 3, values);
+}
+
+template <typename T>
+MEDCouplingFieldDouble *ShapeRecognMesh::buildField(
+    const std::string &name,
+    size_t nbOfCompo,
+    const std::vector<T> &values) const
+{
+    DataArrayDouble *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 *ShapeRecognMesh::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 *ShapeRecognMesh::buildField(
+    const std::string &name,
+    size_t nbOfCompo,
+    DataArrayDouble *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);
+    data->decrRef();
+    return field;
+}
+
+double *ShapeRecognMesh::buildArea3DArray(
+    const std::array<double, 3> &(*areaFunc)(Areas *, mcIdType)) const
+{
+    double *values = new double[3 * nodes->getNbNodes()];
     const std::vector<mcIdType> &areaIdByNodes = areas->getAreaIdByNodes();
-    // - area id
-    MEDCouplingFieldDouble *fieldAreaIds = MEDCouplingFieldDouble::New(
-        ON_NODES);
-    fieldAreaIds->setName("area_ids");
-    fieldAreaIds->setMesh(mesh);
-    DataArrayDouble *areaIds = DataArrayDouble::New();
-    areaIds->setName("area_ids");
-    areaIds->alloc(nodes->getNbNodes(), 1);
-    for (mcIdType nodeId = 0; nodeId < (mcIdType)areaIdByNodes.size(); ++nodeId)
-        areaIds->setIJ(nodeId, 0, (double)areaIdByNodes[nodeId]);
-    fieldAreaIds->setArray(areaIds);
-    areaIds->decrRef();
-    WriteField(outputFile, fieldAreaIds, false);
-    fieldAreaIds->decrRef();
-    // - primitive types
-    MEDCouplingFieldDouble *fieldAreaPrimitiveTypes = MEDCouplingFieldDouble::New(
-        ON_NODES);
-    fieldAreaPrimitiveTypes->setName("area_primitive_types");
-    fieldAreaPrimitiveTypes->setMesh(mesh);
-    DataArrayDouble *areaPrimitiveTypes = DataArrayDouble::New();
-    areaPrimitiveTypes->setName("area_primitive_types");
-    areaPrimitiveTypes->alloc(nodes->getNbNodes(), 1);
-    for (mcIdType nodeId = 0; nodeId < (mcIdType)areaIdByNodes.size(); ++nodeId)
-        areaPrimitiveTypes->setIJ(nodeId, 0, (double)areas->getPrimitiveTypeInt(areaIdByNodes[nodeId]));
-    fieldAreaPrimitiveTypes->setArray(areaPrimitiveTypes);
-    areaPrimitiveTypes->decrRef();
-    WriteField(outputFile, fieldAreaPrimitiveTypes, false);
-    fieldAreaPrimitiveTypes->decrRef();
-    // - normal
-    auto fieldNormal = buildNormalField();
-    WriteField(outputFile, fieldNormal, false);
-    fieldNormal->decrRef();
-    // - affine point
-    auto fieldAffinePoint = buildAffinePointField();
-    WriteField(outputFile, fieldAffinePoint, false);
-    fieldAffinePoint->decrRef();
+    for (size_t nodeId = 0; nodeId < areaIdByNodes.size(); ++nodeId)
+    {
+        mcIdType areaId = areaIdByNodes[nodeId];
+        if (areaId != -1)
+        {
+            const std::array<double, 3> &areaValues = areaFunc(areas, areaId);
+            values[3 * nodeId] = areaValues[0];
+            values[3 * nodeId + 1] = areaValues[1];
+            values[3 * nodeId + 2] = areaValues[2];
+        }
+    }
+    return values;
+}
+
+double *ShapeRecognMesh::buildAreaArray(double (*areaFunc)(Areas *, mcIdType)) const
+{
+    const std::vector<mcIdType> &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, areaId);
+    }
+    return values;
 }
index 2d4fcfa90ed1d69b43eae4cad1f3346813528a38..fd508b0cd81c87e14f407490239eabd216fa864b 100644 (file)
@@ -23,6 +23,7 @@
 #include <string>
 
 #include "MEDCouplingUMesh.hxx"
+#include "MEDCouplingFieldDouble.hxx"
 
 namespace MEDCoupling
 {
@@ -35,18 +36,48 @@ namespace MEDCoupling
         ShapeRecognMesh(const std::string &fileName);
         ~ShapeRecognMesh();
 
-        const Areas *getAreas() const;
         const Nodes *getNodes() const;
-        MEDCouplingFieldDouble *buildAffinePointField() const;
-        MEDCouplingFieldDouble *buildNormalField() const;
+        const Areas *getAreas() const;
 
         void recognize();
-        void recognize(const std::string &outputFile);
+        void recognize(const std::string &outputFile, bool writeFromScratch = true);
+
+        // Node properties
+        MEDCoupling::MEDCouplingFieldDouble *buildNodeK1() const;
+        MEDCoupling::MEDCouplingFieldDouble *buildNodeK2() const;
+        MEDCoupling::MEDCouplingFieldDouble *buildNodePrimitiveType() const;
+        MEDCoupling::MEDCouplingFieldDouble *buildNodeNormal() const;
+
+        // Area properties
+        MEDCoupling::MEDCouplingFieldDouble *buildAreaId() const;
+        MEDCoupling::MEDCouplingFieldDouble *buildAreaPrimitiveType() const;
+        MEDCoupling::MEDCouplingFieldDouble *buildAreaNormal() const;
+        MEDCoupling::MEDCouplingFieldDouble *buildMinorRadius() const;
+        MEDCoupling::MEDCouplingFieldDouble *buildRadius() const;
+        MEDCoupling::MEDCouplingFieldDouble *buildAngle() const;
+        MEDCoupling::MEDCouplingFieldDouble *buildCenter() const;
+        MEDCoupling::MEDCouplingFieldDouble *buildAxis() const;
+        MEDCoupling::MEDCouplingFieldDouble *buildApex() const;
 
     private:
+        template <typename T>
+        MEDCouplingFieldDouble *buildField(
+            const std::string &name,
+            size_t nbOfCompo,
+            const std::vector<T> &values) const;
+        MEDCouplingFieldDouble *buildField(
+            const std::string &name,
+            size_t nbOfCompo,
+            double *values) const;
+        MEDCouplingFieldDouble *buildField(
+            const std::string &name,
+            size_t nbOfCompo,
+            DataArrayDouble *values) const;
+        double *buildArea3DArray(const std::array<double, 3> &(*areaFunc)(Areas *, mcIdType)) const;
+        double *buildAreaArray(double (*areaFunc)(Areas *, mcIdType)) const;
         const MEDCouplingUMesh *mesh;
-        Nodes *nodes = 0;
-        Areas *areas = 0;
+        Nodes *nodes = nullptr;
+        Areas *areas = nullptr;
     };
 };
 
index 699b3264be5db74432d2de68d959a912829e2a36..06a7948b8c35f408202fbd7a7ec137279ded79bb 100644 (file)
@@ -2,14 +2,11 @@
 
 %include "std_string.i"
 
-
 %{
 #include "ShapeRecognMesh.hxx"
+using namespace MEDCoupling;
 %}
 
-%ignore getAreas() const; 
-%ignore getNodes() const; 
-%ignore buildNormalField() const; 
-%ignore buildAffinePointField() const; 
-%ignore recognize(); 
+%ignore getAreas() const;
+%ignore getNodes() const;
 %include "ShapeRecognMesh.hxx"