Branch data Line data Source code
1 : : #include "meshkit/AF2DfltRuleAppVisitor.hpp"
2 : :
3 : : // C++
4 : : #include <cmath>
5 : : #include <cstddef>
6 : :
7 : : // MeshKit
8 : : #include "meshkit/Error.hpp"
9 : :
10 : : const double AF2DfltRuleAppVisitor::eqTriAreaPerimSqRatio = sqrt(3.0) / 36.0;
11 : :
12 : 9981 : AF2DfltRuleAppVisitor::AF2DfltRuleAppVisitor() :
13 : 9981 : bestMetricVal(0), bestRuleApp(NULL)
14 : : {
15 : 9981 : }
16 : :
17 : 9981 : AF2DfltRuleAppVisitor::~AF2DfltRuleAppVisitor()
18 : : {
19 [ + + ]: 9981 : if (bestRuleApp != NULL)
20 : : {
21 [ + - ]: 6543 : delete bestRuleApp;
22 : : }
23 : 9981 : }
24 : :
25 : 0 : AF2DfltRuleAppVisitor::AF2DfltRuleAppVisitor(
26 : : const AF2DfltRuleAppVisitor & toCopy) :
27 : 0 : bestMetricVal(toCopy.bestMetricVal)
28 : : {
29 [ # # ]: 0 : if (toCopy.bestRuleApp != NULL)
30 : : {
31 [ # # ]: 0 : bestRuleApp = new AF2RuleApplication(*(toCopy.bestRuleApp));
32 : : }
33 : 0 : }
34 : :
35 : 0 : AF2DfltRuleAppVisitor& AF2DfltRuleAppVisitor::operator=(
36 : : const AF2DfltRuleAppVisitor & rhs)
37 : : {
38 : 0 : bestMetricVal = rhs.bestMetricVal;
39 : :
40 [ # # ]: 0 : if (bestRuleApp == NULL)
41 : : {
42 [ # # ]: 0 : if (rhs.bestRuleApp != NULL)
43 : : {
44 [ # # ]: 0 : bestRuleApp = new AF2RuleApplication(*(rhs.bestRuleApp));
45 : : }
46 : : }
47 : : else
48 : : {
49 : 0 : AF2RuleApplication* tempBestRuleApp = NULL;
50 [ # # ]: 0 : if (rhs.bestRuleApp != NULL)
51 : : {
52 [ # # ]: 0 : tempBestRuleApp = new AF2RuleApplication(*(rhs.bestRuleApp));
53 : : }
54 [ # # ]: 0 : delete bestRuleApp;
55 : 0 : bestRuleApp = tempBestRuleApp;
56 : : }
57 : :
58 : 0 : return *this;
59 : : }
60 : :
61 : 9981 : const AF2RuleApplication* AF2DfltRuleAppVisitor::getBestRuleApplication() const
62 : : {
63 : 9981 : return bestRuleApp;
64 : : }
65 : :
66 : 7452 : void AF2DfltRuleAppVisitor::visit(AF2RuleApplication const & ruleApp)
67 : : {
68 : 7452 : double metricVal = 0.0;
69 : :
70 : : // loop over the faces and take the worst face metric value
71 : : // as the rule metric value
72 [ + + ]: 36986 : for (unsigned int faceIndex = 0u;
73 : 18493 : faceIndex < ruleApp.getNumNewFaces(); ++faceIndex)
74 : : {
75 : 11041 : const AF2Polygon2D* facePtr = ruleApp.getNewFace(faceIndex);
76 : :
77 : : // verify that the face is a triangle
78 [ - + ]: 11041 : if (facePtr->getNumVertices() != 3u)
79 : : {
80 [ # # ]: 0 : MeshKit::Error badArg(MeshKit::MK_BAD_INPUT);
81 : : badArg.set_string(
82 [ # # ]: 0 : "AF2DfltRuleAppVisitor can visit only triangular faces.");
83 [ # # ]: 0 : throw badArg;
84 : : }
85 : :
86 : : // access the vertices of the triangle
87 : 11041 : const AF2Point2D* faceVtx0 = facePtr->getVertex(0u);
88 : 11041 : const AF2Point2D* faceVtx1 = facePtr->getVertex(1u);
89 : 11041 : const AF2Point2D* faceVtx2 = facePtr->getVertex(2u);
90 : :
91 : : // calculate the components of the vectors along triangle edges
92 : 11041 : double faceVec01X = faceVtx1->getX() - faceVtx0->getX();
93 : 11041 : double faceVec01Y = faceVtx1->getY() - faceVtx0->getY();
94 : 11041 : double faceVec02X = faceVtx2->getX() - faceVtx0->getX();
95 : 11041 : double faceVec02Y = faceVtx2->getY() - faceVtx0->getY();
96 : 11041 : double faceVec12X = faceVtx2->getX() - faceVtx1->getX();
97 : 11041 : double faceVec12Y = faceVtx2->getY() - faceVtx1->getY();
98 : :
99 : : // calculate the length of each edge from the vector
100 : 11041 : double sqLen = faceVec01X * faceVec01X + faceVec01Y * faceVec01Y;
101 : 11041 : double faceVec01Len = sqrt(sqLen);
102 : 11041 : sqLen = faceVec02X * faceVec02X + faceVec02Y * faceVec02Y;
103 : 11041 : double faceVec02Len = sqrt(sqLen);
104 : 11041 : sqLen = faceVec12X * faceVec12X + faceVec12Y * faceVec12Y;
105 : 11041 : double faceVec12Len = sqrt(sqLen);
106 : :
107 : : // caculate the perimeter and area
108 : 11041 : double facePerim = faceVec01Len + faceVec02Len + faceVec12Len;
109 : : double faceArea =
110 : 11041 : 0.5 * (faceVec01X * faceVec02Y - faceVec01Y * faceVec02X);
111 [ - + ]: 11041 : if (faceArea <= 0.0)
112 : : {
113 : : // the face is inverted, so this rule application is unacceptable
114 : 7452 : return;
115 : : }
116 : :
117 : : // calculate the face metric value
118 : 22082 : double faceMetricVal = 10.0 * (eqTriAreaPerimSqRatio *
119 : 22082 : facePerim * facePerim / faceArea - 1) + // shape error
120 : 33123 : 1.0/faceVec01Len + faceVec01Len +
121 : 33123 : 1.0/faceVec02Len + faceVec02Len +
122 : 22082 : 1.0/faceVec12Len + faceVec12Len - 6.0; // size error
123 : :
124 : : // update the rule metric value, if necessary
125 [ + + ]: 11041 : if (faceMetricVal > metricVal)
126 : : {
127 : 8570 : metricVal = faceMetricVal;
128 : : }
129 : : }
130 : :
131 : : // update the best rule application if this is the only rule application
132 : : // or is a "measurable" improvement over the previous best
133 [ + + ]: 7452 : if (bestRuleApp == NULL)
134 : : {
135 [ + - ]: 6543 : bestRuleApp = new AF2RuleApplication(ruleApp);
136 : 6543 : bestMetricVal = metricVal;
137 : : }
138 [ + + ]: 909 : else if (metricVal < 0.99*bestMetricVal)
139 : : {
140 : 106 : *bestRuleApp = ruleApp;
141 : 106 : bestMetricVal = metricVal;
142 : : }
143 : : }
|