NodesBuilder.cxx
Areas.cxx
AreasBuilder.cxx
+ ShapeRecognMeshBuilder.cxx
ShapeRecognMesh.cxx
)
return PrimitiveType::Unknown;
}
+PrimitiveType NodesBuilder::findPrimitiveType2(double k1, double k2, double kdiff0, double kis0) const
+{
+ double epsilon2 = pow(EPSILON_PRIMITIVE, 2);
+ double diffCurvature = fabs(k1 - k2);
+ double gaussianCurvature = k1 * k2;
+ double meanCurvature = (k1 + k2) / 2.0;
+ if (fabs(k1) < EPSILON_PRIMITIVE &&
+ fabs(k2) < EPSILON_PRIMITIVE &&
+ gaussianCurvature < epsilon2 &&
+ meanCurvature < EPSILON_PRIMITIVE)
+ return PrimitiveType::Plane;
+ else if (diffCurvature < EPSILON_PRIMITIVE && k1 > EPSILON_PRIMITIVE && k2 > EPSILON_PRIMITIVE)
+ return PrimitiveType::Sphere;
+ else if (
+ (fabs(k1) > EPSILON_PRIMITIVE && fabs(k2) < EPSILON_PRIMITIVE) ||
+ (fabs(k1) < EPSILON_PRIMITIVE && fabs(k2) > EPSILON_PRIMITIVE))
+ return PrimitiveType::Cylinder;
+ else if (
+ std::signbit(k1) != std::signbit(k2) ||
+ (fabs(k1) < EPSILON_PRIMITIVE && fabs(k2) < EPSILON_PRIMITIVE))
+ return PrimitiveType::Torus;
+ else
+ return PrimitiveType::Unknown;
+}
+
std::vector<double> NodesBuilder::computeNormalCurvatureCoefficients(
const std::vector<double> &discreteCurvatures,
const std::vector<double> &tangents,
void computeCurvatures(double tol = 0.000001);
void computeCurvatures(mcIdType nodeId, double tol);
PrimitiveType findPrimitiveType(double k1, double k2, double kdiff0, double kis0) const;
+ PrimitiveType findPrimitiveType2(double k1, double k2, double kdiff0, double kis0) const;
std::vector<double> computeNormalCurvatureCoefficients(
const std::vector<double> &discreteCurvatures,
const std::vector<double> &tangents,
#include "ShapeRecognMesh.hxx"
-#include "NodesBuilder.hxx"
-#include "AreasBuilder.hxx"
#include "MEDLoader.hxx"
-#include "MEDCouplingFieldDouble.hxx"
using namespace MEDCoupling;
-ShapeRecognMesh::ShapeRecognMesh(const std::string &fileName, int meshDimRelToMax)
+ShapeRecognMesh::ShapeRecognMesh()
+ : nodeK1(0), nodeK2(0), nodePrimitiveType(0),
+ nodeNormal(0), areaId(0), areaPrimitiveType(0),
+ areaNormal(0), minorRadius(0), radius(0),
+ angle(0), center(0), axis(0), apex(0)
{
- mesh = ReadUMeshFromFile(fileName, meshDimRelToMax);
- if (mesh->getMeshDimension() != 2)
- throw INTERP_KERNEL::Exception("Expect a mesh with a dimension equal to 2");
- if (mesh->getNumberOfCellsWithType(INTERP_KERNEL::NORM_TRI3) != mesh->getNumberOfCells())
- throw INTERP_KERNEL::Exception("Expect a mesh containing exclusively triangular cells");
}
-
ShapeRecognMesh::~ShapeRecognMesh()
{
- if (areas != nullptr)
- delete areas;
- if (nodes != nullptr)
- delete nodes;
- mesh->decrRef();
+ nodeK1->decrRef();
+ nodeK2->decrRef();
+ nodePrimitiveType->decrRef();
+ nodeNormal->decrRef();
+ areaId->decrRef();
+ areaPrimitiveType->decrRef();
+ areaNormal->decrRef();
+ minorRadius->decrRef();
+ radius->decrRef();
+ angle->decrRef();
+ center->decrRef();
+ axis->decrRef();
+ apex->decrRef();
+}
+
+std::size_t ShapeRecognMesh::getHeapMemorySizeWithoutChildren() const
+{
+ return 0;
+}
+
+std::vector<const BigMemoryObject *> ShapeRecognMesh::getDirectChildrenWithNull() const
+{
+ std::vector<const BigMemoryObject *> ret;
+ ret.push_back(nodeK1);
+ ret.push_back(nodeK2);
+ ret.push_back(nodePrimitiveType);
+ ret.push_back(nodeNormal);
+ ret.push_back(areaId);
+ ret.push_back(areaPrimitiveType);
+ ret.push_back(areaNormal);
+ ret.push_back(minorRadius);
+ ret.push_back(radius);
+ ret.push_back(angle);
+ ret.push_back(center);
+ ret.push_back(axis);
+ ret.push_back(apex);
+ return ret;
}
-void ShapeRecognMesh::recognize()
+ShapeRecognMesh *ShapeRecognMesh::New()
{
- mesh->incrRef();
- NodesBuilder nodesBuilder(mesh);
- nodes = nodesBuilder.build();
- AreasBuilder areasBuilder(nodes);
- areasBuilder.build();
- areas = areasBuilder.getAreas();
+ return new ShapeRecognMesh;
}
-void ShapeRecognMesh::recognize(const std::string &outputFile, bool writeFromScratch)
+void ShapeRecognMesh::save(const std::string &outputFile, bool writeFromScratch) const
{
- recognize();
// Nodes
// - k1
- MEDCouplingFieldDouble *fieldNodeK1 = buildNodeK1();
- WriteField(outputFile, fieldNodeK1, writeFromScratch);
- fieldNodeK1->decrRef();
+ WriteField(outputFile, nodeK1, writeFromScratch);
// - k2
- MEDCouplingFieldDouble *fieldNodeK2 = buildNodeK2();
- WriteField(outputFile, fieldNodeK2, false);
- fieldNodeK2->decrRef();
+ WriteField(outputFile, nodeK2, false);
// - primitive types
- MEDCouplingFieldDouble *fieldNodePrimitiveType = buildNodePrimitiveType();
- WriteField(outputFile, fieldNodePrimitiveType, false);
- fieldNodePrimitiveType->decrRef();
+ WriteField(outputFile, nodePrimitiveType, false);
// - Normal
- MEDCouplingFieldDouble *fieldNodeNormal = buildNodeNormal();
- WriteField(outputFile, fieldNodeNormal, false);
- fieldNodeNormal->decrRef();
+ WriteField(outputFile, nodeNormal, false);
// Areas
// - Area Id
- MEDCouplingFieldDouble *fieldAreaId = buildAreaId();
- WriteField(outputFile, fieldAreaId, false);
- fieldAreaId->decrRef();
+ WriteField(outputFile, areaId, false);
// - Primitive Types
- MEDCouplingFieldDouble *fieldAreaPrimitiveType = buildAreaPrimitiveType();
- WriteField(outputFile, fieldAreaPrimitiveType, false);
- fieldAreaPrimitiveType->decrRef();
+ WriteField(outputFile, areaPrimitiveType, false);
// - Normal
- auto fieldAreaNormal = buildAreaNormal();
- WriteField(outputFile, fieldAreaNormal, false);
- fieldAreaNormal->decrRef();
+ WriteField(outputFile, areaNormal, false);
// - Minor Radius
- MEDCouplingFieldDouble *fieldAreaMinorRadius = buildMinorRadius();
- WriteField(outputFile, fieldAreaMinorRadius, false);
- fieldAreaMinorRadius->decrRef();
+ WriteField(outputFile, minorRadius, false);
// - Radius
- MEDCouplingFieldDouble *fieldAreaRadius = buildRadius();
- WriteField(outputFile, fieldAreaRadius, false);
- fieldAreaRadius->decrRef();
+ WriteField(outputFile, radius, false);
// - Angle
- MEDCouplingFieldDouble *fieldAreaAngle = buildAngle();
- WriteField(outputFile, fieldAreaAngle, false);
- fieldAreaAngle->decrRef();
+ WriteField(outputFile, angle, false);
// - Center
- MEDCouplingFieldDouble *fieldAreaCenter = buildCenter();
- WriteField(outputFile, fieldAreaCenter, false);
- fieldAreaCenter->decrRef();
+ WriteField(outputFile, center, false);
// - Axis
- MEDCouplingFieldDouble *fieldAreaAxis = buildAxis();
- WriteField(outputFile, fieldAreaAxis, false);
- fieldAreaAxis->decrRef();
+ WriteField(outputFile, axis, false);
// - 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());
+ WriteField(outputFile, apex, false);
}
-MEDCouplingFieldDouble *ShapeRecognMesh::buildAreaPrimitiveType() const
+MEDCouplingFieldDouble *ShapeRecognMesh::getNodeK1() 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);
+ return nodeK1;
}
-MEDCouplingFieldDouble *ShapeRecognMesh::buildAreaNormal() const
+MEDCouplingFieldDouble *ShapeRecognMesh::getNodeK2() 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);
+ return nodeK2;
}
-MEDCouplingFieldDouble *ShapeRecognMesh::buildMinorRadius() const
+MEDCouplingFieldDouble *ShapeRecognMesh::getNodePrimitiveType() 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);
+ return nodePrimitiveType;
}
-MEDCouplingFieldDouble *ShapeRecognMesh::buildRadius() const
+MEDCouplingFieldDouble *ShapeRecognMesh::getNodeNormal() 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);
+ return nodeNormal;
}
-MEDCouplingFieldDouble *ShapeRecognMesh::buildAngle() const
+MEDCouplingFieldDouble *ShapeRecognMesh::getAreaId() 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);
+ return areaId;
}
-MEDCouplingFieldDouble *ShapeRecognMesh::buildCenter() const
+MEDCouplingFieldDouble *ShapeRecognMesh::getAreaPrimitiveType() 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("Center (Area)", 3, values);
+ return areaPrimitiveType;
}
-MEDCouplingFieldDouble *ShapeRecognMesh::buildAxis() const
+MEDCouplingFieldDouble *ShapeRecognMesh::getAreaNormal() 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);
+ return areaNormal;
}
-MEDCouplingFieldDouble *ShapeRecognMesh::buildApex() const
+MEDCouplingFieldDouble *ShapeRecognMesh::getMinorRadius() 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("Apex (Area)", 3, values);
+ return minorRadius;
}
-template <typename T>
-MEDCouplingFieldDouble *ShapeRecognMesh::buildField(
- const std::string &name,
- size_t nbOfCompo,
- const std::vector<T> &values) const
+MEDCouplingFieldDouble *ShapeRecognMesh::getRadius() 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);
+ return radius;
}
-MEDCouplingFieldDouble *ShapeRecognMesh::buildField(
- const std::string &name,
- size_t nbOfCompo,
- double *values) const
+MEDCouplingFieldDouble *ShapeRecognMesh::getAngle() const
{
- DataArrayDouble *data = DataArrayDouble::New();
- data->setName(name);
- data->useArray(
- values,
- true,
- MEDCoupling::DeallocType::CPP_DEALLOC,
- nodes->getNbNodes(),
- nbOfCompo);
- return buildField(name, nbOfCompo, data);
+ return angle;
}
-MEDCouplingFieldDouble *ShapeRecognMesh::buildField(
- const std::string &name,
- size_t nbOfCompo,
- DataArrayDouble *data) const
+MEDCouplingFieldDouble *ShapeRecognMesh::getCenter() 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;
+ return center;
}
-double *ShapeRecognMesh::buildArea3DArray(
- const std::array<double, 3> &(*areaFunc)(Areas *, mcIdType)) const
+MEDCouplingFieldDouble *ShapeRecognMesh::getAxis() const
{
- double *values = new double[3 * nodes->getNbNodes()];
- const std::vector<mcIdType> &areaIdByNodes = areas->getAreaIdByNodes();
- 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;
+ return axis;
}
-double *ShapeRecognMesh::buildAreaArray(double (*areaFunc)(Areas *, mcIdType)) const
+MEDCouplingFieldDouble *ShapeRecognMesh::getApex() 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;
+ return apex;
}
#include "MEDCouplingUMesh.hxx"
#include "MEDCouplingFieldDouble.hxx"
+#include "MEDCouplingRefCountObject.hxx"
namespace MEDCoupling
{
- class Nodes;
- class Areas;
-
- class ShapeRecognMesh
+ class ShapeRecognMesh : public RefCountObject
{
- public:
- ShapeRecognMesh(const std::string &fileName, int meshDimRelToMax = 0);
- ~ShapeRecognMesh();
+ friend class ShapeRecognMeshBuilder;
- const Nodes *getNodes() const;
- const Areas *getAreas() const;
+ public:
+ static ShapeRecognMesh *New();
+ std::size_t getHeapMemorySizeWithoutChildren() const;
+ std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const;
- void recognize();
- void recognize(const std::string &outputFile, bool writeFromScratch = true);
+ void save(const std::string &outputFile, bool writeFromScratch = true) const;
// Node properties
- MEDCoupling::MEDCouplingFieldDouble *buildNodeK1() const;
- MEDCoupling::MEDCouplingFieldDouble *buildNodeK2() const;
- MEDCoupling::MEDCouplingFieldDouble *buildNodePrimitiveType() const;
- MEDCoupling::MEDCouplingFieldDouble *buildNodeNormal() const;
+ MEDCoupling::MEDCouplingFieldDouble *getNodeK1() const;
+ MEDCoupling::MEDCouplingFieldDouble *getNodeK2() const;
+ MEDCoupling::MEDCouplingFieldDouble *getNodePrimitiveType() const;
+ MEDCoupling::MEDCouplingFieldDouble *getNodeNormal() 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;
+ MEDCoupling::MEDCouplingFieldDouble *getAreaId() const;
+ MEDCoupling::MEDCouplingFieldDouble *getAreaPrimitiveType() const;
+ MEDCoupling::MEDCouplingFieldDouble *getAreaNormal() const;
+ MEDCoupling::MEDCouplingFieldDouble *getMinorRadius() const;
+ MEDCoupling::MEDCouplingFieldDouble *getRadius() const;
+ MEDCoupling::MEDCouplingFieldDouble *getAngle() const;
+ MEDCoupling::MEDCouplingFieldDouble *getCenter() const;
+ MEDCoupling::MEDCouplingFieldDouble *getAxis() const;
+ MEDCoupling::MEDCouplingFieldDouble *getApex() 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;
+ protected:
+ ShapeRecognMesh();
+ ~ShapeRecognMesh();
- const MEDCouplingUMesh *mesh;
- Nodes *nodes = nullptr;
- Areas *areas = nullptr;
+ private:
+ MEDCoupling::MEDCouplingFieldDouble *nodeK1;
+ MEDCoupling::MEDCouplingFieldDouble *nodeK2;
+ MEDCoupling::MEDCouplingFieldDouble *nodePrimitiveType;
+ MEDCoupling::MEDCouplingFieldDouble *nodeNormal;
+ MEDCoupling::MEDCouplingFieldDouble *areaId;
+ MEDCoupling::MEDCouplingFieldDouble *areaPrimitiveType;
+ MEDCoupling::MEDCouplingFieldDouble *areaNormal;
+ MEDCoupling::MEDCouplingFieldDouble *minorRadius;
+ MEDCoupling::MEDCouplingFieldDouble *radius;
+ MEDCoupling::MEDCouplingFieldDouble *angle;
+ MEDCoupling::MEDCouplingFieldDouble *center;
+ MEDCoupling::MEDCouplingFieldDouble *axis;
+ MEDCoupling::MEDCouplingFieldDouble *apex;
};
};
--- /dev/null
+#include "ShapeRecognMeshBuilder.hxx"
+
+#include "NodesBuilder.hxx"
+#include "AreasBuilder.hxx"
+#include "MEDLoader.hxx"
+#include "ShapeRecognMesh.hxx"
+#include "MEDCouplingFieldDouble.hxx"
+
+using namespace MEDCoupling;
+
+ShapeRecognMeshBuilder::ShapeRecognMeshBuilder(const std::string &fileName, int meshDimRelToMax)
+{
+ mesh = ReadUMeshFromFile(fileName, meshDimRelToMax);
+ if (mesh->getMeshDimension() != 2)
+ throw INTERP_KERNEL::Exception("Expect a mesh with a dimension equal to 2");
+ if (mesh->getNumberOfCellsWithType(INTERP_KERNEL::NORM_TRI3) != mesh->getNumberOfCells())
+ throw INTERP_KERNEL::Exception("Expect a mesh containing exclusively triangular cells");
+}
+
+ShapeRecognMeshBuilder::~ShapeRecognMeshBuilder()
+{
+ if (areas != nullptr)
+ delete areas;
+ if (nodes != nullptr)
+ delete nodes;
+ mesh->decrRef();
+}
+
+ShapeRecognMesh *ShapeRecognMeshBuilder::recognize()
+{
+ mesh->incrRef();
+ NodesBuilder nodesBuilder(mesh);
+ nodes = nodesBuilder.build();
+ AreasBuilder areasBuilder(nodes);
+ areasBuilder.build();
+ areas = areasBuilder.getAreas();
+ MCAuto<ShapeRecognMesh> recognMesh = ShapeRecognMesh::New();
+ recognMesh->nodeK1 = buildNodeK1();
+ recognMesh->nodeK2 = buildNodeK2();
+ recognMesh->nodePrimitiveType = buildNodePrimitiveType();
+ recognMesh->nodeNormal = buildNodeNormal();
+ recognMesh->areaId = buildAreaId();
+ recognMesh->areaPrimitiveType = buildAreaPrimitiveType();
+ recognMesh->areaNormal = buildAreaNormal();
+ recognMesh->minorRadius = buildMinorRadius();
+ recognMesh->radius = buildRadius();
+ recognMesh->angle = buildAngle();
+ recognMesh->center = buildCenter();
+ recognMesh->axis = buildAxis();
+ recognMesh->apex = buildApex();
+ return recognMesh.retn();
+}
+
+const Nodes *ShapeRecognMeshBuilder::getNodes() const
+{
+ return nodes;
+}
+
+const Areas *ShapeRecognMeshBuilder::getAreas() const
+{
+ return areas;
+}
+
+MEDCouplingFieldDouble *ShapeRecognMeshBuilder::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 *ShapeRecognMeshBuilder::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 *ShapeRecognMeshBuilder::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 *ShapeRecognMeshBuilder::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 *ShapeRecognMeshBuilder::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 *ShapeRecognMeshBuilder::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 *ShapeRecognMeshBuilder::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 *ShapeRecognMeshBuilder::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 *ShapeRecognMeshBuilder::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 *ShapeRecognMeshBuilder::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 *ShapeRecognMeshBuilder::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("Center (Area)", 3, values);
+}
+
+MEDCouplingFieldDouble *ShapeRecognMeshBuilder::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 *ShapeRecognMeshBuilder::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("Apex (Area)", 3, values);
+}
+
+template <typename T>
+MEDCouplingFieldDouble *ShapeRecognMeshBuilder::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 *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,
+ 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 *ShapeRecognMeshBuilder::buildArea3DArray(
+ const std::array<double, 3> &(*areaFunc)(Areas *, mcIdType)) const
+{
+ double *values = new double[3 * nodes->getNbNodes()];
+ const std::vector<mcIdType> &areaIdByNodes = areas->getAreaIdByNodes();
+ 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 *ShapeRecognMeshBuilder::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;
+}
--- /dev/null
+// Copyright (C) 2007-2024 CEA, EDF
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef __SHAPERECOGNMESHBUILDER_HXX__
+#define __SHAPERECOGNMESHBUILDER_HXX__
+
+#include <string>
+
+#include "MEDCouplingUMesh.hxx"
+#include "MEDCouplingFieldDouble.hxx"
+
+namespace MEDCoupling
+{
+ class Nodes;
+ class Areas;
+ class ShapeRecognMesh;
+
+ class ShapeRecognMeshBuilder
+ {
+ public:
+ ShapeRecognMeshBuilder(const std::string &fileName, int meshDimRelToMax = 0);
+ ~ShapeRecognMeshBuilder();
+
+ const Nodes *getNodes() const;
+ const Areas *getAreas() const;
+
+ ShapeRecognMesh *recognize();
+
+ private:
+ // 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;
+
+ 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 = nullptr;
+ Areas *areas = nullptr;
+ };
+};
+
+#endif // __SHAPERECOGNMESHBUILDER_HXX__
%{
#include "ShapeRecognMesh.hxx"
+#include "ShapeRecognMeshBuilder.hxx"
using namespace MEDCoupling;
%}
%ignore getAreas() const;
%ignore getNodes() const;
%include "ShapeRecognMesh.hxx"
+%include "ShapeRecognMeshBuilder.hxx"
#include "ConeTest.hxx"
-#include "ShapeRecognMesh.hxx"
+#include "ShapeRecognMeshBuilder.hxx"
#include "Areas.hxx"
#include "MathOps.hxx"
#include "TestInterpKernelUtils.hxx" // getResourceFile()
void ConeTest::setUp()
{
std::string file = INTERP_TEST::getResourceFile("ShapeRecognCone.med", 3);
- srMesh = new ShapeRecognMesh(file);
+ srMesh = new ShapeRecognMeshBuilder(file);
srMesh->recognize();
areas = srMesh->getAreas();
}
namespace MEDCoupling
{
- class ShapeRecognMesh;
+ class ShapeRecognMeshBuilder;
class Areas;
class ConeTest : public CppUnit::TestFixture
void testThirdArea();
private:
- ShapeRecognMesh *srMesh = 0;
+ ShapeRecognMeshBuilder *srMesh = 0;
const Areas *areas;
};
};
#include "CylinderTest.hxx"
-#include "ShapeRecognMesh.hxx"
+#include "ShapeRecognMeshBuilder.hxx"
#include "Areas.hxx"
#include "MathOps.hxx"
#include "TestInterpKernelUtils.hxx" // getResourceFile()
void CylinderTest::setUp()
{
std::string file = INTERP_TEST::getResourceFile("ShapeRecognCylinder.med", 3);
- srMesh = new ShapeRecognMesh(file);
+ srMesh = new ShapeRecognMeshBuilder(file);
srMesh->recognize();
areas = srMesh->getAreas();
}
namespace MEDCoupling
{
- class ShapeRecognMesh;
+ class ShapeRecognMeshBuilder;
class Areas;
class CylinderTest : public CppUnit::TestFixture
void testThirdArea();
private:
- ShapeRecognMesh *srMesh = 0;
+ ShapeRecognMeshBuilder *srMesh = 0;
const Areas *areas;
};
};
#include "PlaneTest.hxx"
-#include "ShapeRecognMesh.hxx"
+#include "ShapeRecognMeshBuilder.hxx"
#include "Areas.hxx"
#include "MathOps.hxx"
#include "TestInterpKernelUtils.hxx" // getResourceFile()
void PlaneTest::setUp()
{
std::string file = INTERP_TEST::getResourceFile("ShapeRecognPlane.med", 3);
- srMesh = new ShapeRecognMesh(file);
+ srMesh = new ShapeRecognMeshBuilder(file);
srMesh->recognize();
areas = srMesh->getAreas();
}
namespace MEDCoupling
{
- class ShapeRecognMesh;
+ class ShapeRecognMeshBuilder;
class Areas;
class PlaneTest : public CppUnit::TestFixture
void testArea();
private:
- ShapeRecognMesh *srMesh = 0;
+ ShapeRecognMeshBuilder *srMesh = 0;
const Areas *areas;
};
};
#include "SphereTest.hxx"
-#include "ShapeRecognMesh.hxx"
+#include "ShapeRecognMeshBuilder.hxx"
#include "Areas.hxx"
#include "MathOps.hxx"
#include "TestInterpKernelUtils.hxx" // getResourceFile()
void SphereTest::setUp()
{
std::string file = INTERP_TEST::getResourceFile("ShapeRecognSphere.med", 3);
- srMesh = new ShapeRecognMesh(file);
+ srMesh = new ShapeRecognMeshBuilder(file);
srMesh->recognize();
areas = srMesh->getAreas();
}
namespace MEDCoupling
{
- class ShapeRecognMesh;
+ class ShapeRecognMeshBuilder;
class Areas;
class SphereTest : public CppUnit::TestFixture
void testArea();
private:
- ShapeRecognMesh *srMesh = 0;
+ ShapeRecognMeshBuilder *srMesh = 0;
const Areas *areas;
};
};
#include "TorusTest.hxx"
-#include "ShapeRecognMesh.hxx"
+#include "ShapeRecognMeshBuilder.hxx"
#include "Areas.hxx"
#include "MathOps.hxx"
#include "TestInterpKernelUtils.hxx" // getResourceFile()
void TorusTest::setUp()
{
std::string file = INTERP_TEST::getResourceFile("ShapeRecognTorus.med", 3);
- srMesh = new ShapeRecognMesh(file);
+ srMesh = new ShapeRecognMeshBuilder(file);
srMesh->recognize();
areas = srMesh->getAreas();
}
namespace MEDCoupling
{
- class ShapeRecognMesh;
+ class ShapeRecognMeshBuilder;
class Areas;
class TorusTest : public CppUnit::TestFixture
void testArea();
private:
- ShapeRecognMesh *srMesh = 0;
+ ShapeRecognMeshBuilder *srMesh = 0;
const Areas *areas;
};
};