Skip to content

Commit 54c14a0

Browse files
authored
Merge branch 'main' into scpeters/line2_template_api
2 parents 9c8dfe4 + 268039c commit 54c14a0

7 files changed

Lines changed: 160 additions & 29 deletions

File tree

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
name: Bazel repeat flaky tests
2+
on:
3+
schedule:
4+
# GitHub caches are purged after 7 days of inactivity, so
5+
# running twice a week helps protect the bazel cache
6+
# Run at 16:00 UTC, Monday and Friday
7+
- cron: '0 16 * * 1,5'
8+
9+
jobs:
10+
repeat-flaky-tests:
11+
uses: ./.github/workflows/bazel_repeat_tests.yml
12+
with:
13+
flaky: 1
14+
runs_per_test: 10
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
name: Bazel repeat non-flaky tests
2+
on:
3+
schedule:
4+
# GitHub caches are purged after 7 days of inactivity, so
5+
# running twice a week helps protect the bazel cache
6+
# Run at 17:00 UTC, Monday and Friday
7+
- cron: '0 17 * * 1,5'
8+
9+
jobs:
10+
repeat-non-flaky-tests:
11+
uses: ./.github/workflows/bazel_repeat_tests.yml
12+
with:
13+
flaky: 0
14+
runs_per_test: 10
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Bazel repeat tests
2+
on:
3+
workflow_call:
4+
inputs: &shared_inputs
5+
flaky:
6+
description: "0 to execute non-flaky tests, 1 to execute flaky tests"
7+
default: 0
8+
required: false
9+
type: string
10+
runs_per_test:
11+
description: "Number of times to repeat each test"
12+
default: 10
13+
required: false
14+
type: string
15+
workflow_dispatch:
16+
inputs: *shared_inputs
17+
18+
jobs:
19+
repeat-tests:
20+
uses: bazel-contrib/.github/.github/workflows/bazel.yaml@v7.7.0
21+
with:
22+
folders: |
23+
[
24+
"."
25+
]
26+
exclude: |
27+
[
28+
{"folder": ".", "bzlmodEnabled": false}
29+
]
30+
exclude_windows: true
31+
bazel_test_command: |
32+
# Exit with success code 0 if no targets match the query
33+
# `grep -q '^' fails if the query output is empty
34+
bazel query "attr(flaky, ${{ inputs.flaky }}, tests(//...))" \
35+
| grep -q '^' || exit 0
36+
bazel test --runs_per_test=${{ inputs.runs_per_test }} \
37+
--test_output=errors \
38+
$(bazel query "attr(flaky, ${{ inputs.flaky }}, tests(//...))")

include/gz/math/Line3.hh

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ namespace gz::math
4848
/// \param[in] _y1 Y coordinate of the start point.
4949
/// \param[in] _x2 X coordinate of the end point.
5050
/// \param[in] _y2 Y coordinate of the end point.
51-
public: Line3(const double _x1, const double _y1,
52-
const double _x2, const double _y2)
51+
public: Line3(const T _x1, const T _y1,
52+
const T _x2, const T _y2)
5353
{
5454
this->Set(_x1, _y1, _x2, _y2);
5555
}
@@ -61,9 +61,9 @@ namespace gz::math
6161
/// \param[in] _x2 X coordinate of the end point.
6262
/// \param[in] _y2 Y coordinate of the end point.
6363
/// \param[in] _z2 Z coordinate of the end point.
64-
public: Line3(const double _x1, const double _y1,
65-
const double _z1, const double _x2,
66-
const double _y2, const double _z2)
64+
public: Line3(const T _x1, const T _y1,
65+
const T _z1, const T _x2,
66+
const T _y2, const T _z2)
6767
{
6868
this->Set(_x1, _y1, _z1, _x2, _y2, _z2);
6969
}
@@ -100,9 +100,9 @@ namespace gz::math
100100
/// \param[in] _y2 Y coordinate of the end point.
101101
/// \param[in] _z Z coordinate of both points,
102102
/// by default _z is set to 0.
103-
public: void Set(const double _x1, const double _y1,
104-
const double _x2, const double _y2,
105-
const double _z = 0)
103+
public: void Set(const T _x1, const T _y1,
104+
const T _x2, const T _y2,
105+
const T _z = 0)
106106
{
107107
this->pts[0].Set(_x1, _y1, _z);
108108
this->pts[1].Set(_x2, _y2, _z);
@@ -115,9 +115,9 @@ namespace gz::math
115115
/// \param[in] _x2 X coordinate of the end point.
116116
/// \param[in] _y2 Y coordinate of the end point.
117117
/// \param[in] _z2 Z coordinate of the end point.
118-
public: void Set(const double _x1, const double _y1,
119-
const double _z1, const double _x2,
120-
const double _y2, const double _z2)
118+
public: void Set(const T _x1, const T _y1,
119+
const T _z1, const T _x2,
120+
const T _y2, const T _z2)
121121
{
122122
this->pts[0].Set(_x1, _y1, _z1);
123123
this->pts[1].Set(_x2, _y2, _z2);
@@ -134,7 +134,7 @@ namespace gz::math
134134
/// \return The length of the line.
135135
public: T Length() const
136136
{
137-
return this->pts[0].Distance(this->pts[1]);
137+
return static_cast<T>(this->pts[0].Distance(this->pts[1]));
138138
}
139139

140140
/// \brief Get the shortest line between this line and the
@@ -214,7 +214,8 @@ namespace gz::math
214214
double mua = clamp(numer / denom, 0.0, 1.0);
215215
double mub = clamp((d1343 + d4321 * mua) / d4343, 0.0, 1.0);
216216

217-
_result.Set(this->pts[0] + (p21 * mua), _line[0] + (p43 * mub));
217+
_result.Set(this->pts[0] + (p21 * static_cast<T>(mua)),
218+
_line[0] + (p43 * static_cast<T>(mub)));
218219

219220
return true;
220221
}
@@ -229,13 +230,13 @@ namespace gz::math
229230
auto ptTo1 = _pt - this->pts[1];
230231

231232
// Point is projected beyond pt0 or the line has length 0
232-
if (ptTo0.Dot(line) <= 0.0)
233+
if (ptTo0.Dot(line) <= static_cast<T>(0))
233234
{
234235
return ptTo0.Length();
235236
}
236237

237238
// Point is projected beyond pt1
238-
if (ptTo1.Dot(line) >= 0.0)
239+
if (ptTo1.Dot(line) >= static_cast<T>(0))
239240
{
240241
return ptTo1.Length();
241242
}
@@ -341,18 +342,19 @@ namespace gz::math
341342
public: bool Within(const math::Vector3<T> &_pt,
342343
double _epsilon = 1e-6) const
343344
{
345+
auto eps = static_cast<T>(_epsilon);
344346
return _pt.X() <= std::max(this->pts[0].X(),
345-
this->pts[1].X()) + _epsilon &&
347+
this->pts[1].X()) + eps &&
346348
_pt.X() >= std::min(this->pts[0].X(),
347-
this->pts[1].X()) - _epsilon &&
349+
this->pts[1].X()) - eps &&
348350
_pt.Y() <= std::max(this->pts[0].Y(),
349-
this->pts[1].Y()) + _epsilon &&
351+
this->pts[1].Y()) + eps &&
350352
_pt.Y() >= std::min(this->pts[0].Y(),
351-
this->pts[1].Y()) - _epsilon &&
353+
this->pts[1].Y()) - eps &&
352354
_pt.Z() <= std::max(this->pts[0].Z(),
353-
this->pts[1].Z()) + _epsilon &&
355+
this->pts[1].Z()) + eps &&
354356
_pt.Z() >= std::min(this->pts[0].Z(),
355-
this->pts[1].Z()) - _epsilon;
357+
this->pts[1].Z()) - eps;
356358
}
357359

358360
/// \brief Equality operator.

src/Line3_TEST.cc

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ using namespace gz;
2525
/////////////////////////////////////////////////
2626
TEST(Line3Test, Constructor)
2727
{
28+
math::Line3d lineDefault;
29+
EXPECT_EQ(lineDefault[0], math::Vector3d::Zero);
30+
EXPECT_EQ(lineDefault[1], math::Vector3d::Zero);
31+
2832
math::Line3d lineA(0, 0, 10, 10);
2933
EXPECT_DOUBLE_EQ(lineA[0].X(), 0.0);
3034
EXPECT_DOUBLE_EQ(lineA[0].Y(), 0.0);
@@ -88,6 +92,10 @@ TEST(Line3Test, Set)
8892
EXPECT_DOUBLE_EQ(lineA[1].X(), 5.0);
8993
EXPECT_DOUBLE_EQ(lineA[1].Y(), 6.0);
9094
EXPECT_DOUBLE_EQ(lineA[1].Z(), 7.0);
95+
96+
lineA.Set(math::Vector3d(20, 21, 22), math::Vector3d(23, 24, 25));
97+
EXPECT_EQ(lineA[0], math::Vector3d(20, 21, 22));
98+
EXPECT_EQ(lineA[1], math::Vector3d(23, 24, 25));
9199
}
92100

93101
/////////////////////////////////////////////////
@@ -344,6 +352,17 @@ TEST(Line3Test, Intersect)
344352

345353
EXPECT_TRUE(line.Intersect(math::Line3d(0, -1, 0, 0, 0.1, 0)));
346354
EXPECT_TRUE(line.Intersect(math::Line3d(0, 1, 0, 0, 1.1, 0)));
355+
356+
// Parallel non-overlapping lines
357+
EXPECT_FALSE(line.Intersect(math::Line3d(0, 2, 0, 0, 3, 0)));
358+
EXPECT_FALSE(line.Intersect(math::Line3d(0, 2, 0, 0, 3, 0), pt));
359+
360+
// Parallel overlapping line where _line[0] is within this line
361+
EXPECT_TRUE(line.Intersect(math::Line3d(0, 0.5, 0, 0, 2, 0), pt));
362+
EXPECT_EQ(pt, math::Vector3d(0, 0.5, 0));
363+
364+
// Skew non-intersecting lines
365+
EXPECT_FALSE(line.Intersect(math::Line3d(1, 0, 1, 1, 1, 1), pt));
347366
}
348367

349368
/////////////////////////////////////////////////
@@ -371,3 +390,17 @@ TEST(Line3Test, Coplanar)
371390
EXPECT_FALSE(line.Coplanar(math::Line3d(1, 0, 0, 1, 1, 1)));
372391
EXPECT_FALSE(line.Coplanar(math::Line3d(1, 0, 1, 2, 0, 0)));
373392
}
393+
394+
/////////////////////////////////////////////////
395+
TEST(Line3Test, TemplateTypes)
396+
{
397+
math::Line3i lineI(0, 0, 0, 10, 10, 10);
398+
EXPECT_EQ(lineI[0], math::Vector3i(0, 0, 0));
399+
EXPECT_EQ(lineI[1], math::Vector3i(10, 10, 10));
400+
401+
math::Line3f lineF(0.0f, 0.0f, 0.0f, 10.0f, 10.0f, 10.0f);
402+
EXPECT_FLOAT_EQ(lineF[0].X(), 0.0f);
403+
EXPECT_FLOAT_EQ(lineF[1].Y(), 10.0f);
404+
EXPECT_NEAR(lineF.Length(), 17.320508f, 1e-4f);
405+
}
406+

src/python_pybind11/src/Line3.hh

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,10 @@ void helpDefineMathLine3(py::module &m, const std::string &typestr)
6060
.def(py::init<const gz::math::Vector3<T>&,
6161
const gz::math::Vector3<T>&>(),
6262
"Constructor")
63-
.def(py::init<const double, const double, const double, const double>(),
63+
.def(py::init<const T, const T, const T, const T>(),
6464
"2D Constructor where Z coordinates are 0")
65-
.def(py::init<const double, const double, const double, const double,
66-
const double, const double>(),
65+
.def(py::init<const T, const T, const T, const T,
66+
const T, const T>(),
6767
"Constructor")
6868
.def(py::self != py::self)
6969
.def(py::self == py::self)
@@ -78,15 +78,15 @@ void helpDefineMathLine3(py::module &m, const std::string &typestr)
7878
&Class::SetB,
7979
"Set the end point of the line segment")
8080
.def("set",
81-
py::overload_cast<const double, const double, const double,
82-
const double, const double>(&Class::Set),
81+
py::overload_cast<const T, const T, const T,
82+
const T, const T>(&Class::Set),
8383
py::arg("_x1"), py::arg("_y1"), py::arg("_x2"),
84-
py::arg("_y2"), py::arg("_z") = 0,
84+
py::arg("_y2"), py::arg("_z") = static_cast<T>(0),
8585
"Set the start and end point of the line segment, assuming that "
8686
"both points have the same height.")
8787
.def("set",
88-
py::overload_cast<const double, const double, const double,
89-
const double, const double, const double>(
88+
py::overload_cast<const T, const T, const T,
89+
const T, const T, const T>(
9090
&Class::Set),
9191
"Set the start and end point of the line segment")
9292
.def("direction",

src/python_pybind11/test/Line3_TEST.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@
1515
import math
1616
import unittest
1717
from gz.math import Line3d
18+
from gz.math import Line3f
19+
from gz.math import Line3i
1820
from gz.math import Vector3d
21+
from gz.math import Vector3f
22+
from gz.math import Vector3i
1923

2024

2125
class TestLine3d(unittest.TestCase):
@@ -80,6 +84,10 @@ def test_set(self):
8084
self.assertAlmostEqual(line_a[1].y(), 6.0)
8185
self.assertAlmostEqual(line_a[1].z(), 7.0)
8286

87+
line_a.set(Vector3d(20, 21, 22), Vector3d(23, 24, 25))
88+
self.assertEqual(line_a[0], Vector3d(20, 21, 22))
89+
self.assertEqual(line_a[1], Vector3d(23, 24, 25))
90+
8391
def test_length(self):
8492
line_a = Line3d(0, 0, 0, 10, 10, 10)
8593
self.assertAlmostEqual(line_a.length(), math.sqrt(300), delta=1e-10)
@@ -225,6 +233,17 @@ def test_interesct(self):
225233
self.assertTrue(line.intersect(Line3d(0, -1, 0, 0, 0.1, 0)))
226234
self.assertTrue(line.intersect(Line3d(0, 1, 0, 0, 1.1, 0)))
227235

236+
# Parallel non-overlapping lines
237+
self.assertFalse(line.intersect(Line3d(0, 2, 0, 0, 3, 0)))
238+
self.assertFalse(line.intersect(Line3d(0, 2, 0, 0, 3, 0), pt))
239+
240+
# Parallel overlapping line where _line[0] is within this line
241+
self.assertTrue(line.intersect(Line3d(0, 0.5, 0, 0, 2, 0), pt))
242+
self.assertEqual(pt, Vector3d(0, 0.5, 0))
243+
244+
# Skew non-intersecting lines
245+
self.assertFalse(line.intersect(Line3d(1, 0, 1, 1, 1, 1), pt))
246+
228247
def test_parallel(self):
229248
line = Line3d(0, 0, 0, 0, 1, 0)
230249
self.assertTrue(line.parallel(Line3d(1, 0, 0, 1, 1, 0)))
@@ -245,6 +264,17 @@ def test_coplanar(self):
245264
self.assertFalse(line.coplanar(Line3d(1, 0, 0, 1, 1, 1)))
246265
self.assertFalse(line.coplanar(Line3d(1, 0, 1, 2, 0, 0)))
247266

267+
def test_template_types(self):
268+
line_i = Line3i(0, 0, 0, 10, 10, 10)
269+
self.assertEqual(line_i[0], Vector3i(0, 0, 0))
270+
self.assertEqual(line_i[1], Vector3i(10, 10, 10))
271+
272+
line_f = Line3f(0.0, 0.0, 0.0, 10.0, 10.0, 10.0)
273+
self.assertAlmostEqual(line_f[0].x(), 0.0)
274+
self.assertAlmostEqual(line_f[1].y(), 10.0)
275+
self.assertAlmostEqual(line_f.length(), 17.320508, delta=1e-4)
276+
248277

249278
if __name__ == '__main__':
250279
unittest.main()
280+

0 commit comments

Comments
 (0)