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();
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;
}