#include "NodesBuilder.hxx"
#include "AreasBuilder.hxx"
#include "ShapeRecognMesh.hxx"
+
#include "MEDCouplingFieldDouble.hxx"
+#include "MEDCouplingFieldInt64.hxx"
+#include "MEDCouplingFieldInt32.hxx"
using namespace MEDCoupling;
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 T>
+typename Traits<T>::FieldType *buildField(
+ const std::string &name,
+ MCAuto<typename Traits<T>::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<T>::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 T>
+typename Traits<T>::FieldType *buildField(
+ const std::string &name,
+ size_t nbOfCompo,
+ const std::vector<T> &values,
+ const MEDCouplingUMesh *mesh)
+{
+ using ZeArray = typename Traits<T>::ArrayType;
+ mcIdType nbNodes = mesh->getNumberOfNodes();
+ MCAuto<ZeArray> data( ZeArray::New() );
+ data->setName(name);
+ data->alloc(nbNodes, nbOfCompo);
+ std::copy(values.begin(), values.end(), data->getPointer());
+ data->declareAsNew();
+ return buildField<T>(name, data, mesh);
+}
+
+template <typename T>
+typename Traits<T>::FieldType *buildField(
+ const std::string &name,
+ size_t nbOfCompo,
+ T *values,
+ const MEDCouplingUMesh *mesh)
+{
+ using ZeArray = typename Traits<T>::ArrayType;
+ mcIdType nbNodes = mesh->getNumberOfNodes();
+ ZeArray *data = ZeArray::New();
+ data->setName(name);
+ data->useArray(
+ values,
+ true,
+ MEDCoupling::DeallocType::CPP_DEALLOC,
+ nbNodes,
+ nbOfCompo);
+ return buildField<T>(name, data, mesh);
+}
+
+template<class T>
+T *buildAreaArrayT(Areas *areas, Nodes *nodes, std::function<T(Areas *, mcIdType)> areaFunc)
+{
+ const std::vector<Int32> &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<double>("K1 (Node)", 1, nodes->getK1(), mesh);
+}
+
+MEDCouplingFieldDouble *ShapeRecognMeshBuilder::buildNodeK2() const
+{
+ checkNodesBeforeBuildingField();
+ return buildField<double>("K2 (Node)", 1, nodes->getK2(), mesh);
+}
+
+MEDCouplingFieldInt32 *ShapeRecognMeshBuilder::buildNodePrimitiveType() const
+{
+ checkNodesBeforeBuildingField();
+ return nullptr;//buildField<Int32>("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<double>("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<Int32>("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<std::int32_t>(areas.get(),nodes.get(),[](Areas *areas, mcIdType areaId) -> std::int32_t
+ { return (std::int32_t)areas->getPrimitiveType(areaId); });
+ return buildField<Int32>("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<double, 3> &
{ return areas->getNormal(areaId); });
- return buildField("Normal (Area)", 3, values);
+ return buildField<double>("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<double>("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<double>("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<double>("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<double, 3> &
{ return areas->getCenter(areaId); });
- return buildField("Center (Area)", 3, values);
+ return buildField<double>("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<double, 3> &
{ return areas->getAxis(areaId); });
- return buildField("Axis (Area)", 3, values);
+ return buildField<double>("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<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
-{
- MCAuto<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,
- MCAuto<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);
- return field;
+ return buildField<double>("Apex (Area)", 3, values, mesh);
}
-double *ShapeRecognMeshBuilder::buildArea3DArray(
- const std::array<double, 3> &(*areaFunc)(Areas *, mcIdType)) const
+double *ShapeRecognMeshBuilder::buildArea3DArray(std::function<const std::array<double, 3> &(Areas *, Int32)> areaFunc) const
{
double *values = new double[3 * nodes->getNbNodes()];
- const std::vector<mcIdType> &areaIdByNodes = areas->getAreaIdByNodes();
+ const std::vector<Int32> &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<double, 3> &areaValues = areaFunc(areas.get(), areaId);
return values;
}
-double *ShapeRecognMeshBuilder::buildAreaArray(double (*areaFunc)(Areas *, mcIdType)) const
+double *ShapeRecognMeshBuilder::buildAreaArray(std::function<double(Areas *, Int32)> areaFunc) 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.get(), areaId);
- }
- return values;
+ return buildAreaArrayT<double>(areas.get(), nodes.get(), areaFunc );
}