diff --git a/Gui/DataView/MshQualitySelection.ui b/Gui/DataView/MshQualitySelection.ui index d082f66f6f32f99ae798acb28692800d047fe152..6007c249ecd866ede84bda0bb164a84f5c80af95 100644 --- a/Gui/DataView/MshQualitySelection.ui +++ b/Gui/DataView/MshQualitySelection.ui @@ -48,6 +48,13 @@ </property> </widget> </item> + <item> + <widget class="QRadioButton" name="choiceRadius"> + <property name="text"> + <string>Radius to Shortest Edge Ratio</string> + </property> + </widget> + </item> </layout> </widget> </item> diff --git a/Gui/DataView/MshQualitySelectionDialog.cpp b/Gui/DataView/MshQualitySelectionDialog.cpp index 4885d7d85bcaa3b624ce52e93902f70d684e3c7c..f6d8e7ecdb2c0d765a2ae4fe5747f1127f3fa508 100644 --- a/Gui/DataView/MshQualitySelectionDialog.cpp +++ b/Gui/DataView/MshQualitySelectionDialog.cpp @@ -30,20 +30,22 @@ MshQualitySelectionDialog::~MshQualitySelectionDialog() /// Instructions if the OK-Button has been pressed. void MshQualitySelectionDialog::accept() { - MeshQualityType t; - if (this->choiceEdges->isChecked()) - t = MeshQualityType::EDGERATIO; - else if (this->choiceArea->isChecked()) - t = MeshQualityType::AREA; - else if (this->choiceVolume->isChecked()) - t = MeshQualityType::VOLUME; - else if (this->choiceAngles->isChecked()) - t = MeshQualityType::EQUIANGLESKEW; - else - t = MeshQualityType::INVALID; + MeshQualityType t; + if (this->choiceEdges->isChecked()) + t = MeshQualityType::EDGERATIO; + else if (this->choiceArea->isChecked()) + t = MeshQualityType::AREA; + else if (this->choiceVolume->isChecked()) + t = MeshQualityType::VOLUME; + else if (this->choiceAngles->isChecked()) + t = MeshQualityType::EQUIANGLESKEW; + else if (this->choiceRadius->isChecked()) + t = MeshQualityType::RADIUSEDGERATIO; + else + t = MeshQualityType::INVALID; - emit measureSelected(_msh, t); - this->done(QDialog::Accepted); + emit measureSelected(_msh, t); + this->done(QDialog::Accepted); } /// Instructions if the Cancel-Button has been pressed. diff --git a/Gui/VtkVis/VtkVisPipeline.cpp b/Gui/VtkVis/VtkVisPipeline.cpp index dc490fcd69ee668e5e88907ca4a0a3012dcbe1ad..3b5a38ac72f0bb9145f74f79ce7b53687048cba4 100644 --- a/Gui/VtkVis/VtkVisPipeline.cpp +++ b/Gui/VtkVis/VtkVisPipeline.cpp @@ -28,6 +28,7 @@ #include "MeshQuality/AreaMetric.h" #include "MeshQuality/VolumeMetric.h" #include "MeshQuality/EdgeRatioMetric.h" +#include "MeshQuality/RadiusEdgeRatioMetric.h" #include "MshItem.h" #include "MshModel.h" #include "StationTreeModel.h" @@ -462,13 +463,15 @@ void VtkVisPipeline::checkMeshQuality(VtkMeshSource* source, MeshQualityType t) const MeshLib::Mesh* mesh = source->GetMesh(); MeshLib::ElementQualityMetric* quality_tester (nullptr); if (t == MeshQualityType::EDGERATIO) - quality_tester = new MeshLib::EdgeRatioMetric(mesh); + quality_tester = new MeshLib::EdgeRatioMetric(*mesh); else if (t == MeshQualityType::AREA) - quality_tester = new MeshLib::AreaMetric(mesh); + quality_tester = new MeshLib::AreaMetric(*mesh); else if (t == MeshQualityType::VOLUME) - quality_tester = new MeshLib::VolumeMetric(mesh); + quality_tester = new MeshLib::VolumeMetric(*mesh); else if (t == MeshQualityType::EQUIANGLESKEW) - quality_tester = new MeshLib::AngleSkewMetric(mesh); + quality_tester = new MeshLib::AngleSkewMetric(*mesh); + else if (t == MeshQualityType::RADIUSEDGERATIO) + quality_tester = new MeshLib::RadiusEdgeRatioMetric(*mesh); else { ERR("VtkVisPipeline::checkMeshQuality(): Unknown MeshQualityType."); diff --git a/MeshLib/MeshEnums.cpp b/MeshLib/MeshEnums.cpp index 910b4c5a05bfd6ae8ed60e8debc15ea17743c959..73f7bf6913f260a8228c98c909f49fce1fe22512 100644 --- a/MeshLib/MeshEnums.cpp +++ b/MeshLib/MeshEnums.cpp @@ -54,14 +54,16 @@ MeshElemType String2MeshElemType(const std::string &s) const std::string MeshQualityType2String(const MeshQualityType t) { - if (t == MeshQualityType::AREA) - return "Area"; - if (t == MeshQualityType::EDGERATIO) - return "EdgeRatio"; - if (t == MeshQualityType::EQUIANGLESKEW) - return "EquiAngleSkew"; - if (t == MeshQualityType::VOLUME) - return "Volume"; - return "none"; + if (t == MeshQualityType::AREA) + return "Area"; + if (t == MeshQualityType::EDGERATIO) + return "EdgeRatio"; + if (t == MeshQualityType::EQUIANGLESKEW) + return "EquiAngleSkew"; + if (t == MeshQualityType::RADIUSEDGERATIO) + return "RadiusEdgeRatio"; + if (t == MeshQualityType::VOLUME) + return "Volume"; + return "none"; } diff --git a/MeshLib/MeshEnums.h b/MeshLib/MeshEnums.h index 3bf5caecdd9e841227a55e74193e17ea46d0a468..ac63a453835f15d296a6da6b948b896c2573b920 100644 --- a/MeshLib/MeshEnums.h +++ b/MeshLib/MeshEnums.h @@ -61,11 +61,12 @@ enum class CellType */ enum class MeshQualityType { - INVALID = 0, - AREA, - VOLUME, - EDGERATIO, - EQUIANGLESKEW + INVALID = 0, + AREA, + VOLUME, + EDGERATIO, + EQUIANGLESKEW, + RADIUSEDGERATIO }; /// Given a MeshElemType this returns the appropriate string. diff --git a/MeshLib/MeshQuality/AngleSkewMetric.cpp b/MeshLib/MeshQuality/AngleSkewMetric.cpp index fb6dc802bb8e44a2e40eeb66741d9c523ff9efc0..2c14f59bcc5deb46a4828a1fc5095954145c0274 100644 --- a/MeshLib/MeshQuality/AngleSkewMetric.cpp +++ b/MeshLib/MeshQuality/AngleSkewMetric.cpp @@ -29,7 +29,7 @@ namespace MeshLib { -AngleSkewMetric::AngleSkewMetric(Mesh const* const mesh) : +AngleSkewMetric::AngleSkewMetric(Mesh const& mesh) : ElementQualityMetric(mesh), M_PI_THIRD (M_PI / 3.0), TWICE_M_PI (2 * M_PI) {} @@ -38,13 +38,13 @@ AngleSkewMetric::~AngleSkewMetric() void AngleSkewMetric::calculateQuality () { - const std::vector<MeshLib::Element*>& elements(_mesh->getElements()); - const size_t nElements (_mesh->getNElements()); + const std::vector<MeshLib::Element*>& elements(_mesh.getElements()); + const size_t nElements (_mesh.getNElements()); for (size_t k(0); k < nElements; k++) { - const Element* elem (elements[k]); - switch (elem->getGeomType()) + Element const& elem (*elements[k]); + switch (elem.getGeomType()) { case MeshElemType::LINE: _element_quality_metric[k] = -1.0; @@ -70,11 +70,11 @@ void AngleSkewMetric::calculateQuality () } } -double AngleSkewMetric::checkTriangle (Element const* const elem) const +double AngleSkewMetric::checkTriangle (Element const& elem) const { - double const* const node0 (elem->getNode(0)->getCoords()); - double const* const node1 (elem->getNode(1)->getCoords()); - double const* const node2 (elem->getNode(2)->getCoords()); + double const* const node0 (elem.getNode(0)->getCoords()); + double const* const node1 (elem.getNode(1)->getCoords()); + double const* const node2 (elem.getNode(2)->getCoords()); double min_angle (M_PI_2), max_angle (0.0); getMinMaxAngleFromTriangle (node0, node1, node2, min_angle, max_angle); @@ -84,12 +84,12 @@ double AngleSkewMetric::checkTriangle (Element const* const elem) const (M_PI_THIRD - min_angle) / (M_PI_THIRD)); } -double AngleSkewMetric::checkQuad (Element const* const elem) const +double AngleSkewMetric::checkQuad (Element const& elem) const { - double const* const node0 (elem->getNode(0)->getCoords()); - double const* const node1 (elem->getNode(1)->getCoords()); - double const* const node2 (elem->getNode(2)->getCoords()); - double const* const node3 (elem->getNode(3)->getCoords()); + double const* const node0 (elem.getNode(0)->getCoords()); + double const* const node1 (elem.getNode(1)->getCoords()); + double const* const node2 (elem.getNode(2)->getCoords()); + double const* const node3 (elem.getNode(3)->getCoords()); double min_angle (TWICE_M_PI); double max_angle (0.0); @@ -100,12 +100,12 @@ double AngleSkewMetric::checkQuad (Element const* const elem) const std::max((max_angle - M_PI_2) / (M_PI - M_PI_2), (M_PI_2 - min_angle) / (M_PI_2)); } -double AngleSkewMetric::checkTetrahedron (Element const* const elem) const +double AngleSkewMetric::checkTetrahedron (Element const& elem) const { - double const* const node0 (elem->getNode(0)->getCoords()); - double const* const node1 (elem->getNode(1)->getCoords()); - double const* const node2 (elem->getNode(2)->getCoords()); - double const* const node3 (elem->getNode(3)->getCoords()); + double const* const node0 (elem.getNode(0)->getCoords()); + double const* const node1 (elem.getNode(1)->getCoords()); + double const* const node2 (elem.getNode(2)->getCoords()); + double const* const node3 (elem.getNode(3)->getCoords()); double min_angle (M_PI_2); double max_angle (0.0); @@ -123,16 +123,16 @@ double AngleSkewMetric::checkTetrahedron (Element const* const elem) const (M_PI_THIRD - min_angle) / (M_PI_THIRD)); } -double AngleSkewMetric::checkHexahedron (Element const* const elem) const +double AngleSkewMetric::checkHexahedron (Element const& elem) const { - double const* const node0 (elem->getNode(0)->getCoords()); - double const* const node1 (elem->getNode(1)->getCoords()); - double const* const node2 (elem->getNode(2)->getCoords()); - double const* const node3 (elem->getNode(3)->getCoords()); - double const* const node4 (elem->getNode(4)->getCoords()); - double const* const node5 (elem->getNode(5)->getCoords()); - double const* const node6 (elem->getNode(6)->getCoords()); - double const* const node7 (elem->getNode(7)->getCoords()); + double const* const node0 (elem.getNode(0)->getCoords()); + double const* const node1 (elem.getNode(1)->getCoords()); + double const* const node2 (elem.getNode(2)->getCoords()); + double const* const node3 (elem.getNode(3)->getCoords()); + double const* const node4 (elem.getNode(4)->getCoords()); + double const* const node5 (elem.getNode(5)->getCoords()); + double const* const node6 (elem.getNode(6)->getCoords()); + double const* const node7 (elem.getNode(7)->getCoords()); double min_angle (2 * M_PI); double max_angle (0.0); @@ -154,14 +154,14 @@ double AngleSkewMetric::checkHexahedron (Element const* const elem) const std::max((max_angle - M_PI_2) / (M_PI - M_PI_2), (M_PI_2 - min_angle) / (M_PI_2)); } -double AngleSkewMetric::checkPrism (Element const* const elem) const +double AngleSkewMetric::checkPrism (Element const& elem) const { - double const* const node0 (elem->getNode(0)->getCoords()); - double const* const node1 (elem->getNode(1)->getCoords()); - double const* const node2 (elem->getNode(2)->getCoords()); - double const* const node3 (elem->getNode(3)->getCoords()); - double const* const node4 (elem->getNode(4)->getCoords()); - double const* const node5 (elem->getNode(5)->getCoords()); + double const* const node0 (elem.getNode(0)->getCoords()); + double const* const node1 (elem.getNode(1)->getCoords()); + double const* const node2 (elem.getNode(2)->getCoords()); + double const* const node3 (elem.getNode(3)->getCoords()); + double const* const node4 (elem.getNode(4)->getCoords()); + double const* const node5 (elem.getNode(5)->getCoords()); double min_angle_tri (2 * M_PI); double max_angle_tri (0.0); diff --git a/MeshLib/MeshQuality/AngleSkewMetric.h b/MeshLib/MeshQuality/AngleSkewMetric.h index bdf023b54bb52351752b0d94b007a715024d8282..5cdaddee899ea4f402e3b05ca4da3e8077136e1e 100644 --- a/MeshLib/MeshQuality/AngleSkewMetric.h +++ b/MeshLib/MeshQuality/AngleSkewMetric.h @@ -26,17 +26,17 @@ namespace MeshLib class AngleSkewMetric : public ElementQualityMetric { public: - AngleSkewMetric(Mesh const* const mesh); + AngleSkewMetric(Mesh const& mesh); virtual ~AngleSkewMetric(); virtual void calculateQuality (); private: - double checkTriangle(Element const* const elem) const; - double checkQuad(Element const* const elem) const; - double checkTetrahedron(Element const* const elem) const; - double checkHexahedron(Element const* const elem) const; - double checkPrism (Element const* const elem) const; + double checkTriangle(Element const& elem) const; + double checkQuad(Element const& elem) const; + double checkTetrahedron(Element const& elem) const; + double checkHexahedron(Element const& elem) const; + double checkPrism (Element const& elem) const; void getMinMaxAngleFromQuad(double const* const n0, double const* const n1, double const* const n2, double const* const n3, double &min_angle, diff --git a/MeshLib/MeshQuality/AreaMetric.cpp b/MeshLib/MeshQuality/AreaMetric.cpp index 6dc6fb6b6b5485187147af9cb239e102c3463a1e..f1094d3f274172c52540b4d0b66b8fd8691edafc 100644 --- a/MeshLib/MeshQuality/AreaMetric.cpp +++ b/MeshLib/MeshQuality/AreaMetric.cpp @@ -18,36 +18,36 @@ namespace MeshLib { -AreaMetric::AreaMetric(Mesh const* const mesh) +AreaMetric::AreaMetric(Mesh const& mesh) : ElementQualityMetric(mesh) {} void AreaMetric::calculateQuality() { - const std::vector<MeshLib::Element*> &elements(_mesh->getElements()); + const std::vector<MeshLib::Element*> &elements(_mesh.getElements()); const size_t nElems(elements.size()); for (size_t k(0); k < nElems; k++) { double area(std::numeric_limits<double>::max()); - const Element* elem (elements[k]); + Element const& elem (*elements[k]); - if (elem->getDimension() == 1) + if (elem.getDimension() == 1) { _element_quality_metric[k] = -1.0; continue; } - else if (elem->getDimension() == 2) + else if (elem.getDimension() == 2) { - area = elem->getContent(); + area = elem.getContent(); if (area < sqrt(fabs(std::numeric_limits<double>::epsilon()))) errorMsg(elem, k); } else { - size_t nFaces(elem->getNFaces()); + size_t nFaces(elem.getNFaces()); for (size_t i = 0; i < nFaces; i++) { - const double sub_area (elem->getFace(i)->getContent()); + const double sub_area (elem.getFace(i)->getContent()); if (sub_area < sqrt(fabs(std::numeric_limits<double>::epsilon()))) errorMsg(elem, k); diff --git a/MeshLib/MeshQuality/AreaMetric.h b/MeshLib/MeshQuality/AreaMetric.h index 334b318551e0e89e4e77aa74b9ade546c0371045..5e80686672c7375a41570845dbf39bd0cc66d435 100644 --- a/MeshLib/MeshQuality/AreaMetric.h +++ b/MeshLib/MeshQuality/AreaMetric.h @@ -26,7 +26,7 @@ namespace MeshLib class AreaMetric : public ElementQualityMetric { public: - AreaMetric(Mesh const* const mesh); + AreaMetric(Mesh const& mesh); virtual ~AreaMetric() {} virtual void calculateQuality (); diff --git a/MeshLib/MeshQuality/EdgeRatioMetric.cpp b/MeshLib/MeshQuality/EdgeRatioMetric.cpp index 7c2cb981430f634e0fefc2fa8c01540870668129..5471020dc976e173fb7f2de03d639054db421d67 100644 --- a/MeshLib/MeshQuality/EdgeRatioMetric.cpp +++ b/MeshLib/MeshQuality/EdgeRatioMetric.cpp @@ -18,7 +18,7 @@ namespace MeshLib { -EdgeRatioMetric::EdgeRatioMetric(Mesh const* const mesh) : +EdgeRatioMetric::EdgeRatioMetric(Mesh const& mesh) : ElementQualityMetric(mesh) { } @@ -26,63 +26,63 @@ EdgeRatioMetric::EdgeRatioMetric(Mesh const* const mesh) : void EdgeRatioMetric::calculateQuality() { // get all elements of mesh - const std::vector<MeshLib::Element*>& elements(_mesh->getElements()); - const size_t nElements (_mesh->getNElements()); + const std::vector<MeshLib::Element*>& elements(_mesh.getElements()); + const size_t nElements (_mesh.getNElements()); for (size_t k(0); k < nElements; k++) { - const Element* elem (elements[k]); - switch (elem->getGeomType()) + Element const& elem (*elements[k]); + switch (elem.getGeomType()) { case MeshElemType::LINE: _element_quality_metric[k] = 1.0; break; case MeshElemType::TRIANGLE: { - _element_quality_metric[k] = checkTriangle(elem->getNode(0), elem->getNode(1), elem->getNode(2)); + _element_quality_metric[k] = checkTriangle(*elem.getNode(0), *elem.getNode(1), *elem.getNode(2)); break; } case MeshElemType::QUAD: { - _element_quality_metric[k] = checkQuad(elem->getNode(0), elem->getNode(1), elem->getNode(2), elem->getNode(3)); + _element_quality_metric[k] = checkQuad(*elem.getNode(0), *elem.getNode(1), *elem.getNode(2), *elem.getNode(3)); break; } case MeshElemType::TETRAHEDRON: { - _element_quality_metric[k] = checkTetrahedron(elem->getNode(0), elem->getNode(1), elem->getNode(2), elem->getNode(3)); + _element_quality_metric[k] = checkTetrahedron(*elem.getNode(0), *elem.getNode(1), *elem.getNode(2), *elem.getNode(3)); break; } case MeshElemType::PRISM: { std::vector<const GeoLib::Point*> pnts; for (size_t j(0); j < 6; j++) - pnts.push_back(elem->getNode(j)); + pnts.push_back(elem.getNode(j)); _element_quality_metric[k] = checkPrism(pnts); break; } case MeshElemType::PYRAMID: { std::vector<const GeoLib::Point*> pnts; for (size_t j(0); j < 5; j++) - pnts.push_back(elem->getNode(j)); + pnts.push_back(elem.getNode(j)); _element_quality_metric[k] = checkPyramid(pnts); break; } case MeshElemType::HEXAHEDRON: { std::vector<const GeoLib::Point*> pnts; for (size_t j(0); j < 8; j++) - pnts.push_back(elem->getNode(j)); + pnts.push_back(elem.getNode(j)); _element_quality_metric[k] = checkHexahedron(pnts); break; } default: ERR ("MeshQualityShortestLongestRatio::check () check for element type %s not implemented.", - MeshElemType2String(elem->getGeomType()).c_str()); + MeshElemType2String(elem.getGeomType()).c_str()); } } } -double EdgeRatioMetric::checkTriangle (GeoLib::Point const* const a, - GeoLib::Point const* const b, - GeoLib::Point const* const c) const +double EdgeRatioMetric::checkTriangle (GeoLib::Point const& a, + GeoLib::Point const& b, + GeoLib::Point const& c) const { - double len0 (sqrt(MathLib::sqrDist (*b,*a))); - double len1 (sqrt(MathLib::sqrDist (*b,*c))); - double len2 (sqrt(MathLib::sqrDist (*a,*c))); + double len0 (sqrt(MathLib::sqrDist (b,a))); + double len1 (sqrt(MathLib::sqrDist (b,c))); + double len2 (sqrt(MathLib::sqrDist (a,c))); if (len0 < len1 && len0 < len2) { @@ -110,15 +110,15 @@ double EdgeRatioMetric::checkTriangle (GeoLib::Point const* const a, } } -double EdgeRatioMetric::checkQuad (GeoLib::Point const* const a, - GeoLib::Point const* const b, - GeoLib::Point const* const c, - GeoLib::Point const* const d) const +double EdgeRatioMetric::checkQuad (GeoLib::Point const& a, + GeoLib::Point const& b, + GeoLib::Point const& c, + GeoLib::Point const& d) const { - double sqr_lengths[4] = {MathLib::sqrDist (*b,*a), - MathLib::sqrDist (*c,*b), - MathLib::sqrDist (*d,*c), - MathLib::sqrDist (*a,*d)}; + double sqr_lengths[4] = {MathLib::sqrDist (b,a), + MathLib::sqrDist (c,b), + MathLib::sqrDist (d,c), + MathLib::sqrDist (a,d)}; // sort lengths - since this is a very small array we use bubble sort for (size_t i(0); i < 4; i++) @@ -129,14 +129,14 @@ double EdgeRatioMetric::checkQuad (GeoLib::Point const* const a, return sqrt(sqr_lengths[0]) / sqrt(sqr_lengths[3]); } -double EdgeRatioMetric::checkTetrahedron (GeoLib::Point const* const a, - GeoLib::Point const* const b, - GeoLib::Point const* const c, - GeoLib::Point const* const d) const +double EdgeRatioMetric::checkTetrahedron (GeoLib::Point const& a, + GeoLib::Point const& b, + GeoLib::Point const& c, + GeoLib::Point const& d) const { - double sqr_lengths[6] = {MathLib::sqrDist (*b,*a), MathLib::sqrDist (*c,*b), - MathLib::sqrDist (*c,*a), MathLib::sqrDist (*a,*d), - MathLib::sqrDist (*b,*d), MathLib::sqrDist (*c,*d)}; + double sqr_lengths[6] = {MathLib::sqrDist (b,a), MathLib::sqrDist (c,b), + MathLib::sqrDist (c,a), MathLib::sqrDist (a,d), + MathLib::sqrDist (b,d), MathLib::sqrDist (c,d)}; // sort lengths - since this is a very small array we use bubble sort for (size_t i(0); i < 6; i++) @@ -147,7 +147,7 @@ double EdgeRatioMetric::checkTetrahedron (GeoLib::Point const* const a, return sqrt(sqr_lengths[0]) / sqrt(sqr_lengths[5]); } -double EdgeRatioMetric::checkPrism (std::vector<const GeoLib::Point*> const & pnts) const +double EdgeRatioMetric::checkPrism (std::vector<const GeoLib::Point*> const& pnts) const { double sqr_lengths[9] = {MathLib::sqrDist (*pnts[0],*pnts[1]), MathLib::sqrDist (*pnts[1],*pnts[2]), @@ -168,7 +168,7 @@ double EdgeRatioMetric::checkPrism (std::vector<const GeoLib::Point*> const & pn return sqrt(sqr_lengths[0]) / sqrt(sqr_lengths[8]); } -double EdgeRatioMetric::checkPyramid (std::vector<const GeoLib::Point*> const & pnts) const +double EdgeRatioMetric::checkPyramid (std::vector<const GeoLib::Point*> const &pnts) const { double sqr_lengths[8] = {MathLib::sqrDist (*pnts[0],*pnts[1]), MathLib::sqrDist (*pnts[1],*pnts[2]), diff --git a/MeshLib/MeshQuality/EdgeRatioMetric.h b/MeshLib/MeshQuality/EdgeRatioMetric.h index 45b2148820c1e880ebe449fb2108407a3d0e497f..b6c321da4886d7067e37b2e43427d5d46092f08c 100644 --- a/MeshLib/MeshQuality/EdgeRatioMetric.h +++ b/MeshLib/MeshQuality/EdgeRatioMetric.h @@ -27,26 +27,26 @@ namespace MeshLib class EdgeRatioMetric : public ElementQualityMetric { public: - EdgeRatioMetric(Mesh const* const mesh); + EdgeRatioMetric(Mesh const& mesh); virtual ~EdgeRatioMetric () {} virtual void calculateQuality (); private: - double checkTriangle (GeoLib::Point const* const a, - GeoLib::Point const* const b, - GeoLib::Point const* const c) const; - double checkQuad (GeoLib::Point const* const a, - GeoLib::Point const* const b, - GeoLib::Point const* const c, - GeoLib::Point const* const d) const; - double checkTetrahedron (GeoLib::Point const* const a, - GeoLib::Point const* const b, - GeoLib::Point const* const c, - GeoLib::Point const* const d) const; - double checkPrism (std::vector<const GeoLib::Point*> const & pnts) const; - double checkPyramid (std::vector<const GeoLib::Point*> const & pnts) const; - double checkHexahedron (std::vector<const GeoLib::Point*> const & pnts) const; + double checkTriangle (GeoLib::Point const& a, + GeoLib::Point const& b, + GeoLib::Point const& c) const; + double checkQuad (GeoLib::Point const& a, + GeoLib::Point const& b, + GeoLib::Point const& c, + GeoLib::Point const& d) const; + double checkTetrahedron (GeoLib::Point const& a, + GeoLib::Point const& b, + GeoLib::Point const& c, + GeoLib::Point const& d) const; + double checkPrism (std::vector<const GeoLib::Point*> const& pnts) const; + double checkPyramid (std::vector<const GeoLib::Point*> const& pnts) const; + double checkHexahedron (std::vector<const GeoLib::Point*> const& pnts) const; }; } diff --git a/MeshLib/MeshQuality/ElementQualityMetric.cpp b/MeshLib/MeshQuality/ElementQualityMetric.cpp index 53842242af653224635a4b7a602690a02853f20c..119215908bb0f0e1800d049d9971c2114530a6c3 100644 --- a/MeshLib/MeshQuality/ElementQualityMetric.cpp +++ b/MeshLib/MeshQuality/ElementQualityMetric.cpp @@ -20,30 +20,29 @@ namespace MeshLib { -ElementQualityMetric::ElementQualityMetric(Mesh const* const mesh) : +ElementQualityMetric::ElementQualityMetric(Mesh const& mesh) : _min (std::numeric_limits<double>::max()), _max (0), _mesh (mesh) { - if (_mesh) - _element_quality_metric.resize (_mesh->getNElements(), -1.0); + _element_quality_metric.resize (_mesh.getNElements(), -1.0); } BaseLib::Histogram<double> ElementQualityMetric::getHistogram (size_t nclasses) const { if (nclasses == 0) { // simple suggestion: number of classes with Sturges criterion - nclasses = static_cast<size_t>(1 + 3.3 * log (static_cast<float>((_mesh->getNElements())))); + nclasses = static_cast<size_t>(1 + 3.3 * log (static_cast<float>((_mesh.getNElements())))); } return BaseLib::Histogram<double>(getElementQuality(), nclasses, true); } -void ElementQualityMetric::errorMsg (const Element* elem, size_t idx) const +void ElementQualityMetric::errorMsg (Element const& elem, size_t idx) const { ERR ("Error in MeshQualityChecker::check() - Calculated value of element is below double precision minimum."); - ERR ("Points of %s-Element %d: ", MeshElemType2String(elem->getGeomType()).c_str(), idx); - for (size_t i(0); i < elem->getNNodes(); i++) + ERR ("Points of %s-Element %d: ", MeshElemType2String(elem.getGeomType()).c_str(), idx); + for (size_t i(0); i < elem.getNNodes(); i++) { - const double* coords = elem->getNode(i)->getCoords(); + const double* coords = elem.getNode(i)->getCoords(); ERR ("\t Node %d: (%f, %f, %f)", i, coords[0], coords[1], coords[2]); } } diff --git a/MeshLib/MeshQuality/ElementQualityMetric.h b/MeshLib/MeshQuality/ElementQualityMetric.h index 3629e45abdcbf026ca369dd8afe6f53c7628ac33..584eb223a6830c9ac2947dc4bac912ff71dd5a94 100644 --- a/MeshLib/MeshQuality/ElementQualityMetric.h +++ b/MeshLib/MeshQuality/ElementQualityMetric.h @@ -35,7 +35,7 @@ namespace MeshLib class ElementQualityMetric { public: - ElementQualityMetric(Mesh const* const mesh); + ElementQualityMetric(Mesh const& mesh); virtual ~ElementQualityMetric () {} @@ -51,11 +51,11 @@ public: virtual BaseLib::Histogram<double> getHistogram (std::size_t nclasses = 0) const; protected: - void errorMsg (const Element* elem, std::size_t idx) const; + void errorMsg (Element const& elem, std::size_t idx) const; double _min; double _max; - Mesh const* const _mesh; + Mesh const& _mesh; std::vector<double> _element_quality_metric; }; } diff --git a/MeshLib/MeshQuality/RadiusEdgeRatioMetric.cpp b/MeshLib/MeshQuality/RadiusEdgeRatioMetric.cpp new file mode 100644 index 0000000000000000000000000000000000000000..752c3ef60d66d5ad9e2f9e52fa678bcc9c625efb --- /dev/null +++ b/MeshLib/MeshQuality/RadiusEdgeRatioMetric.cpp @@ -0,0 +1,45 @@ +/** + * \file RadiusEdgeRatioMetric.cpp + * \author Karsten Rink + * \date 2014-09-02 + * \brief Implementation of the RadiusEdgeRadioMetric class. + * + * \copyright + * Copyright (c) 2012-2014, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + */ + +#include "RadiusEdgeRatioMetric.h" + +#include "Node.h" +#include "MinimalBoundingSphere.h" + +namespace MeshLib +{ + +RadiusEdgeRatioMetric::RadiusEdgeRatioMetric(Mesh const& mesh) +: ElementQualityMetric(mesh) +{} + +void RadiusEdgeRatioMetric::calculateQuality () +{ + std::vector<MeshLib::Element*> const& elements(_mesh.getElements()); + size_t const nElements (_mesh.getNElements()); + for (size_t k(0); k < nElements; k++) + { + Element const& elem (*elements[k]); + std::size_t const n_nodes (elem.getNNodes()); + MeshLib::Node* const*const nodes = elem.getNodes(); + std::vector<GeoLib::Point*> pnts(n_nodes); + std::copy_n(elem.getNodes(), n_nodes, pnts.begin()); + GeoLib::MinimalBoundingSphere const s(pnts); + double min, max; + elem.computeSqrEdgeLengthRange(min, max); + _element_quality_metric[k] = sqrt(min)/(2*s.getRadius()); + } +} + +} // end namespace MeshLib diff --git a/MeshLib/MeshQuality/RadiusEdgeRatioMetric.h b/MeshLib/MeshQuality/RadiusEdgeRatioMetric.h new file mode 100644 index 0000000000000000000000000000000000000000..90c79aa7ca4a51d4367022078ea5ab11ce64ece9 --- /dev/null +++ b/MeshLib/MeshQuality/RadiusEdgeRatioMetric.h @@ -0,0 +1,37 @@ +/** + * \file RadiusEdgeRatioMetric.h + * \author Karsten Rink + * \date 2014-09-02 + * \brief Definition of the RadiusEdgeRatioMetric class. + * + * \copyright + * Copyright (c) 2012-2014, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + */ + +#ifndef RADIUSEDGERATIOMETRIC_H_ +#define RADIUSEDGERATIOMETRIC_H_ + +#include "ElementQualityMetric.h" + +namespace MeshLib +{ + +/** + * Calculates the quality of mesh elements based on the ratio between + * radius of the smallest enclosing sphere and the shortest element edge + */ +class RadiusEdgeRatioMetric : public ElementQualityMetric +{ +public: + RadiusEdgeRatioMetric(Mesh const& mesh); + virtual ~RadiusEdgeRatioMetric() {}; + + virtual void calculateQuality (); +}; +} + +#endif /* RADIUSEDGERATIOMETRIC_H_ */ diff --git a/MeshLib/MeshQuality/VolumeMetric.cpp b/MeshLib/MeshQuality/VolumeMetric.cpp index d090fa201ec59686d31b663727b49345d02b0bb5..07ae817eb0f6cbafe8ff5248a2d84ffb44b5420f 100644 --- a/MeshLib/MeshQuality/VolumeMetric.cpp +++ b/MeshLib/MeshQuality/VolumeMetric.cpp @@ -20,28 +20,28 @@ namespace MeshLib { -VolumeMetric::VolumeMetric(Mesh const* const mesh) : +VolumeMetric::VolumeMetric(Mesh const& mesh) : ElementQualityMetric(mesh) { } void VolumeMetric::calculateQuality() { // get all elements of mesh - const std::vector<MeshLib::Element*>& elements(_mesh->getElements()); + const std::vector<MeshLib::Element*>& elements(_mesh.getElements()); size_t error_count(0); - size_t nElements (_mesh->getNElements()); + size_t nElements (_mesh.getNElements()); for (size_t k(0); k < nElements; k++) { - const Element* elem (elements[k]); - if (elem->getDimension()<3) + Element const& elem (*elements[k]); + if (elem.getDimension()<3) { _element_quality_metric[k] = 0.0; continue; } - double volume (elem->getContent()); + double volume (elem.getContent()); if (volume > _max) _max = volume; if (volume < sqrt(fabs(std::numeric_limits<double>::epsilon()))) { diff --git a/MeshLib/MeshQuality/VolumeMetric.h b/MeshLib/MeshQuality/VolumeMetric.h index f9a9bb28259ef45f0b66c3c155b6c5c6593a811f..0c0a75b9a1c7a75e8d64c97bc7587322216af47e 100644 --- a/MeshLib/MeshQuality/VolumeMetric.h +++ b/MeshLib/MeshQuality/VolumeMetric.h @@ -26,7 +26,7 @@ namespace MeshLib class VolumeMetric : public ElementQualityMetric { public: - VolumeMetric(Mesh const* const mesh); + VolumeMetric(Mesh const& mesh); virtual ~VolumeMetric() {} virtual void calculateQuality ();