GCC Code Coverage Report


Directory: ./
File: openvdb/openvdb/math/Proximity.cc
Date: 2022-07-25 17:40:05
Exec Total Coverage
Lines: 31 52 59.6%
Functions: 1 2 50.0%
Branches: 32 48 66.7%

Line Branch Exec Source
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3
4 #include "Proximity.h"
5
6 namespace openvdb {
7 OPENVDB_USE_VERSION_NAMESPACE
8 namespace OPENVDB_VERSION_NAME {
9 namespace math {
10
11
12 OPENVDB_API Vec3d
13
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14078652 times.
14078652 closestPointOnTriangleToPoint(
14 const Vec3d& a, const Vec3d& b, const Vec3d& c, const Vec3d& p, Vec3d& uvw)
15 {
16 uvw.setZero();
17
18 // degenerate triangle, singular
19
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 14078652 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
14078652 if ((isApproxEqual(a, b) && isApproxEqual(a, c))) {
20 uvw[0] = 1.0;
21 return a;
22 }
23
24 Vec3d ab = b - a, ac = c - a, ap = p - a;
25 double d1 = ab.dot(ap), d2 = ac.dot(ap);
26
27 // degenerate triangle edges
28
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14078652 times.
14078652 if (isApproxEqual(a, b)) {
29
30 double t = 0.0;
31 Vec3d cp = closestPointOnSegmentToPoint(a, c, p, t);
32
33 uvw[0] = 1.0 - t;
34 uvw[2] = t;
35
36 return cp;
37
38
2/4
✓ Branch 0 taken 14078652 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14078652 times.
✗ Branch 3 not taken.
14078652 } else if (isApproxEqual(a, c) || isApproxEqual(b, c)) {
39
40 double t = 0.0;
41 Vec3d cp = closestPointOnSegmentToPoint(a, b, p, t);
42 uvw[0] = 1.0 - t;
43 uvw[1] = t;
44 return cp;
45 }
46
47
4/4
✓ Branch 0 taken 1240067 times.
✓ Branch 1 taken 12838585 times.
✓ Branch 2 taken 624700 times.
✓ Branch 3 taken 615367 times.
14078652 if (d1 <= 0.0 && d2 <= 0.0) {
48 624700 uvw[0] = 1.0;
49 624700 return a; // barycentric coordinates (1,0,0)
50 }
51
52 // Check if P in vertex region outside B
53 Vec3d bp = p - b;
54 double d3 = ab.dot(bp), d4 = ac.dot(bp);
55
4/4
✓ Branch 0 taken 1545659 times.
✓ Branch 1 taken 11908293 times.
✓ Branch 2 taken 561357 times.
✓ Branch 3 taken 984302 times.
13453952 if (d3 >= 0.0 && d4 <= d3) {
56 561357 uvw[1] = 1.0;
57 561357 return b; // barycentric coordinates (0,1,0)
58 }
59
60 // Check if P in edge region of AB, if so return projection of P onto AB
61 12892595 double vc = d1 * d4 - d3 * d2;
62
6/6
✓ Branch 0 taken 3231847 times.
✓ Branch 1 taken 9660748 times.
✓ Branch 2 taken 3230917 times.
✓ Branch 3 taken 930 times.
✓ Branch 4 taken 3227276 times.
✓ Branch 5 taken 3641 times.
12892595 if (vc <= 0.0 && d1 >= 0.0 && d3 <= 0.0) {
63 3227276 uvw[1] = d1 / (d1 - d3);
64 3227276 uvw[0] = 1.0 - uvw[1];
65 return a + uvw[1] * ab; // barycentric coordinates (1-v,v,0)
66 }
67
68 // Check if P in vertex region outside C
69 Vec3d cp = p - c;
70 double d5 = ab.dot(cp), d6 = ac.dot(cp);
71
4/4
✓ Branch 0 taken 1311578 times.
✓ Branch 1 taken 8353741 times.
✓ Branch 2 taken 556072 times.
✓ Branch 3 taken 755506 times.
9665319 if (d6 >= 0.0 && d5 <= d6) {
72 556072 uvw[2] = 1.0;
73 556072 return c; // barycentric coordinates (0,0,1)
74 }
75
76 // Check if P in edge region of AC, if so return projection of P onto AC
77 9109247 double vb = d5 * d2 - d1 * d6;
78
5/6
✓ Branch 0 taken 3082602 times.
✓ Branch 1 taken 6026645 times.
✓ Branch 2 taken 3082602 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3077765 times.
✓ Branch 5 taken 4837 times.
9109247 if (vb <= 0.0 && d2 >= 0.0 && d6 <= 0.0) {
79 3077765 uvw[2] = d2 / (d2 - d6);
80 3077765 uvw[0] = 1.0 - uvw[2];
81 return a + uvw[2] * ac; // barycentric coordinates (1-w,0,w)
82 }
83
84 // Check if P in edge region of BC, if so return projection of P onto BC
85 6031482 double va = d3*d6 - d5*d4;
86
4/6
✓ Branch 0 taken 1581664 times.
✓ Branch 1 taken 4449818 times.
✓ Branch 2 taken 1581664 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1581664 times.
✗ Branch 5 not taken.
6031482 if (va <= 0.0 && (d4 - d3) >= 0.0 && (d5 - d6) >= 0.0) {
87 1581664 uvw[2] = (d4 - d3) / ((d4 - d3) + (d5 - d6));
88 1581664 uvw[1] = 1.0 - uvw[2];
89 1581664 return b + uvw[2] * (c - b); // barycentric coordinates (0,1-w,w)
90 }
91
92 // P inside face region. Compute Q through its barycentric coordinates (u,v,w)
93 4449818 double denom = 1.0 / (va + vb + vc);
94 4449818 uvw[2] = vc * denom;
95 4449818 uvw[1] = vb * denom;
96 4449818 uvw[0] = 1.0 - uvw[1] - uvw[2];
97
98 4449818 return a + ab*uvw[1] + ac*uvw[2]; // = u*a + v*b + w*c , u= va*denom = 1.0-v-w
99 }
100
101
102 OPENVDB_API Vec3d
103 closestPointOnSegmentToPoint(const Vec3d& a, const Vec3d& b, const Vec3d& p, double& t)
104 {
105 Vec3d ab = b - a;
106 t = (p - a).dot(ab);
107
108 if (t <= 0.0) {
109 // c projects outside the [a,b] interval, on the a side.
110 t = 0.0;
111 return a;
112 } else {
113
114 // always nonnegative since denom = ||ab||^2
115 double denom = ab.dot(ab);
116
117 if (t >= denom) {
118 // c projects outside the [a,b] interval, on the b side.
119 t = 1.0;
120 return b;
121 } else {
122 // c projects inside the [a,b] interval.
123 t = t / denom;
124 return a + (ab * t);
125 }
126 }
127 }
128
129 } // namespace math
130 } // namespace OPENVDB_VERSION_NAME
131 } // namespace openvdb
132