Skip to content

Commit 9fb328f

Browse files
authored
Merge pull request #1672 from LLNL/feature/spainhour/sampling_shaper_memoization
Enhance CurvedPolygon so WN memoization works with sampling shaper
2 parents a22a833 + f3eadb8 commit 9fb328f

19 files changed

+804
-371
lines changed

src/axom/core/numerics/quadrature.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ namespace numerics
2323
/*!
2424
* \class QuadratureRule
2525
*
26-
* \brief Stores a fixed array of 1D quadrature points and weights
26+
* \brief Stores fixed views to arrays of 1D quadrature points and weights
2727
*/
2828
class QuadratureRule
2929
{

src/axom/primal/geometry/BezierCurve.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,9 @@ class BezierCurve
221221
/// Returns the order of the Bezier Curve
222222
int getOrder() const { return static_cast<int>(m_controlPoints.size()) - 1; }
223223

224+
/// Returns the number of control points of the Bezier Curve
225+
int getNumControlPoints() const { return static_cast<int>(m_controlPoints.size()); }
226+
224227
/// Clears the list of control points, make nonrational
225228
void clear()
226229
{
@@ -256,6 +259,9 @@ class BezierCurve
256259
/// Retrieves the control point at index \a idx
257260
const PointType& operator[](int idx) const { return m_controlPoints[idx]; }
258261

262+
const PointType& getInitPoint() const { return m_controlPoints[0]; }
263+
const PointType& getEndPoint() const { return m_controlPoints[m_controlPoints.size() - 1]; }
264+
259265
/// Returns a copy of the Bezier curve's control points
260266
CoordsVec getControlPoints() const { return m_controlPoints; }
261267

src/axom/primal/geometry/CurvedPolygon.hpp

Lines changed: 99 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,64 @@
1818
#include "axom/primal/geometry/Point.hpp"
1919
#include "axom/primal/geometry/Vector.hpp"
2020
#include "axom/primal/geometry/BezierCurve.hpp"
21+
#include "axom/primal/geometry/NURBSCurve.hpp"
2122
#include "axom/primal/geometry/BoundingBox.hpp"
2223

24+
// For NURBSCurveGWNCache objects
25+
#include "axom/primal/operators/detail/winding_number_3d_memoization.hpp"
26+
2327
#include <vector>
2428
#include <ostream>
2529

2630
namespace axom
2731
{
2832
namespace primal
2933
{
30-
// Forward declare the templated classes and operator functions
34+
namespace internal
35+
{
36+
///@{
37+
/// \name Boilerplate to deduce the numeric type from the curve object
38+
template <typename U>
39+
struct get_numeric_type;
40+
3141
template <typename T, int NDIMS>
42+
struct get_numeric_type<BezierCurve<T, NDIMS>>
43+
{
44+
using type = T;
45+
};
46+
47+
template <typename T, int NDIMS>
48+
struct get_numeric_type<NURBSCurve<T, NDIMS>>
49+
{
50+
using type = T;
51+
};
52+
53+
template <typename T>
54+
struct get_numeric_type<detail::NURBSCurveGWNCache<T>>
55+
{
56+
using type = T;
57+
};
58+
///@}
59+
60+
///@{
61+
/// \name Boilerplate for a compile-time flag for the cached object
62+
template <typename U>
63+
struct has_cached_data : std::false_type
64+
{ };
65+
66+
template <typename T>
67+
struct has_cached_data<detail::NURBSCurveGWNCache<T>> : std::true_type
68+
{ };
69+
///@}
70+
} // namespace internal
71+
72+
// Forward declare the templated classes and operator functions
73+
template <typename CurveType>
3274
class CurvedPolygon;
3375

3476
/*! \brief Overloaded output operator for polygons */
35-
template <typename T, int NDIMS>
36-
std::ostream& operator<<(std::ostream& os, const CurvedPolygon<T, NDIMS>& poly);
77+
template <typename CurveType>
78+
std::ostream& operator<<(std::ostream& os, const CurvedPolygon<CurveType>& poly);
3779

3880
/*!
3981
* \class CurvedPolygon
@@ -44,15 +86,15 @@ std::ostream& operator<<(std::ostream& os, const CurvedPolygon<T, NDIMS>& poly);
4486
* \note The component curves should be ordered in a counter clockwise
4587
* orientation with respect to the polygon's normal vector
4688
*/
47-
template <typename T, int NDIMS>
89+
template <typename CurveType>
4890
class CurvedPolygon
4991
{
5092
public:
51-
using PointType = Point<T, NDIMS>;
52-
using VectorType = Vector<T, NDIMS>;
53-
using NumArrayType = axom::NumericArray<T, NDIMS>;
54-
using BezierCurveType = BezierCurve<T, NDIMS>;
55-
using BoundingBoxType = typename BezierCurveType::BoundingBoxType;
93+
using T = typename internal::get_numeric_type<CurveType>::type;
94+
95+
using PointType = typename CurveType::PointType;
96+
using VectorType = typename CurveType::VectorType;
97+
using BoundingBoxType = typename CurveType::BoundingBoxType;
5698

5799
public:
58100
/// Default constructor for an empty polygon
@@ -73,20 +115,30 @@ class CurvedPolygon
73115
m_edges.resize(nEdges);
74116
}
75117

76-
/// Constructor from an array of \a nEdges curves
77-
CurvedPolygon(BezierCurveType* curves, int nEdges)
118+
/*!
119+
* \brief Copy constructor for another curve type
120+
*/
121+
template <typename OtherCurveType>
122+
CurvedPolygon(const CurvedPolygon<OtherCurveType>& other_poly)
78123
{
79-
SLIC_ASSERT(curves != nullptr);
80-
SLIC_ASSERT(nEdges >= 1);
81-
82-
m_edges.reserve(nEdges);
83-
84-
for(int e = 0; e < nEdges; ++e)
124+
m_edges.resize(other_poly.numEdges());
125+
for(int e = 0; e < other_poly.numEdges(); ++e)
85126
{
86-
this->addEdge(curves[e]);
127+
m_edges[e] = CurveType(other_poly[e]);
87128
}
88129
}
89130

131+
///! \brief Constructor for CurvedPolygon from an ArrayView of curves
132+
CurvedPolygon(axom::ArrayView<const CurveType> curves) : m_edges(curves) { }
133+
134+
///! \brief Constructor from a c-style array of \a nEdges curves
135+
CurvedPolygon(const CurveType* curves, int nEdges)
136+
: CurvedPolygon(axom::ArrayView<const CurveType>(curves, nEdges))
137+
{ }
138+
139+
///! \brief Constructor from a Axom array of curves
140+
CurvedPolygon(const axom::Array<CurveType>& curves) : CurvedPolygon(curves.view()) { }
141+
90142
/// Clears the list of edges
91143
void clear() { m_edges.clear(); }
92144

@@ -105,36 +157,43 @@ class CurvedPolygon
105157
m_edges.resize(ngon);
106158
}
107159

108-
/// Appends a BezierCurve to the list of edges
109-
void addEdge(const BezierCurveType& c1) { m_edges.push_back(c1); }
160+
/// Appends a curve to the list of edges
161+
void addEdge(const CurveType& c1) { m_edges.push_back(c1); }
162+
163+
/// Consumes then appends a curve to the list of edges
164+
void addEdge(CurveType&& c1) { m_edges.push_back(std::move(c1)); }
110165

111166
/// Splits an edge "in place"
112167
void splitEdge(int idx, T t)
113168
{
114-
SLIC_ASSERT(idx < static_cast<int>(m_edges.size()));
169+
SLIC_ASSERT(idx >= 0 && idx < static_cast<int>(m_edges.size()));
170+
AXOM_STATIC_ASSERT_MSG(!internal::has_cached_data<CurveType>::value,
171+
"splitEdge cannot be called on objects with associated cache data");
115172

173+
m_edges.reserve(numEdges() + 1);
116174
m_edges.insert(m_edges.begin() + idx + 1, 1, m_edges[idx]);
117175
auto& csplit = m_edges[idx];
118176
csplit.split(t, m_edges[idx], m_edges[idx + 1]);
119177
}
120178

121-
axom::Array<BezierCurve<T, NDIMS>> getEdges() const { return m_edges; }
122-
179+
axom::Array<CurveType> getEdges() const { return m_edges; }
123180
/// @}
124181

125-
/*! Retrieves the Bezier Curve at index idx */
126-
BezierCurveType& operator[](int idx) { return m_edges[idx]; }
127-
/*! Retrieves the vertex at index idx */
128-
const BezierCurveType& operator[](int idx) const { return m_edges[idx]; }
182+
/*! Retrieves the curve at index idx */
183+
CurveType& operator[](int idx) { return m_edges[idx]; }
184+
/*! Retrieves the curve at index idx */
185+
const CurveType& operator[](int idx) const { return m_edges[idx]; }
129186

130187
/// Tests equality of two CurvedPolygons
131-
friend inline bool operator==(const CurvedPolygon<T, NDIMS>& lhs, const CurvedPolygon<T, NDIMS>& rhs)
188+
friend inline bool operator==(const CurvedPolygon<CurveType>& lhs,
189+
const CurvedPolygon<CurveType>& rhs)
132190
{
133191
return lhs.m_edges == rhs.m_edges;
134192
}
135193

136194
/// Tests inequality of two CurvedPolygons
137-
friend inline bool operator!=(const CurvedPolygon<T, NDIMS>& lhs, const CurvedPolygon<T, NDIMS>& rhs)
195+
friend inline bool operator!=(const CurvedPolygon<CurveType>& lhs,
196+
const CurvedPolygon<CurveType>& rhs)
138197
{
139198
return !(lhs == rhs);
140199
}
@@ -149,7 +208,7 @@ class CurvedPolygon
149208
{
150209
const int sz = numEdges();
151210

152-
os << "{" << sz << "-sided Bezier polygon:";
211+
os << "{" << sz << "-sided curved polygon:";
153212
for(int i = 0; i < sz - 1; ++i)
154213
{
155214
os << m_edges[i] << ",";
@@ -177,17 +236,16 @@ class CurvedPolygon
177236
const int nEdges = numEdges();
178237

179238
// initial basic check: no edges, or one edge or linear or quadratic order cannot be closed
180-
if(nEdges < 1 || (nEdges == 1 && m_edges[0].getOrder() <= 2))
239+
if(nEdges < 1 || (nEdges == 1 && m_edges[0].getNumControlPoints() <= 2))
181240
{
182241
return false;
183242
}
184243

185244
// foreach edge: check last vertex of previous edge against first vertex of current edge
186245
for(int cur = 0, prev = nEdges - 1; cur < nEdges; prev = cur++)
187246
{
188-
const auto ord = m_edges[prev].getOrder();
189-
const auto& lastPrev = m_edges[prev][ord];
190-
const auto& firstCur = m_edges[cur][0];
247+
const auto& lastPrev = m_edges[prev].getEndPoint();
248+
const auto& firstCur = m_edges[cur].getInitPoint();
191249
if(!isNearlyEqual(squared_distance(lastPrev, firstCur), 0., sq_tol))
192250
{
193251
return false;
@@ -200,6 +258,10 @@ class CurvedPolygon
200258
/// \brief Reverses orientation of a CurvedPolygon
201259
void reverseOrientation()
202260
{
261+
AXOM_STATIC_ASSERT_MSG(
262+
!internal::has_cached_data<CurveType>::value,
263+
"reverseOrientation cannot be called on objects with associated cache data");
264+
203265
const int ngon = numEdges();
204266
const int mid = ngon >> 1;
205267
const bool isOdd = (ngon & 1) != 0;
@@ -233,14 +295,14 @@ class CurvedPolygon
233295
}
234296

235297
private:
236-
axom::Array<BezierCurve<T, NDIMS>> m_edges;
298+
axom::Array<CurveType> m_edges;
237299
};
238300

239301
//------------------------------------------------------------------------------
240302
/// Free functions implementing Polygon's operators
241303
//------------------------------------------------------------------------------
242-
template <typename T, int NDIMS>
243-
std::ostream& operator<<(std::ostream& os, const CurvedPolygon<T, NDIMS>& poly)
304+
template <typename CurveType>
305+
std::ostream& operator<<(std::ostream& os, const CurvedPolygon<CurveType>& poly)
244306
{
245307
poly.print(os);
246308
return os;

src/axom/primal/geometry/NURBSCurve.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,9 @@ class NURBSCurve
621621
*/
622622
const PointType& operator[](int idx) const { return m_controlPoints[idx]; }
623623

624+
const PointType& getInitPoint() const { return m_controlPoints[0]; }
625+
const PointType& getEndPoint() const { return m_controlPoints[m_controlPoints.size() - 1]; }
626+
624627
/// \brief Returns a copy of the NURBS curve's control points
625628
CoordsVec getControlPoints() const { return m_controlPoints; }
626629

src/axom/primal/operators/compute_moments.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ primal::Point<T, 2> sector_centroid(const primal::BezierCurve<T, 2>& curve)
9595

9696
/// \brief Returns the area enclosed by the CurvedPolygon
9797
template <typename T>
98-
T area(const primal::CurvedPolygon<T, 2>& poly, double tol = 1e-8)
98+
T area(const primal::CurvedPolygon<BezierCurve<T, 2>>& poly, double tol = 1e-8)
9999
{
100100
const int ngon = poly.numEdges();
101101
T A = 0.0;
@@ -119,7 +119,7 @@ T area(const primal::CurvedPolygon<T, 2>& poly, double tol = 1e-8)
119119

120120
/// \brief Returns the centroid of the CurvedPolygon
121121
template <typename T>
122-
primal::Point<T, 2> centroid(const primal::CurvedPolygon<T, 2>& poly, double tol = 1e-8)
122+
primal::Point<T, 2> centroid(const primal::CurvedPolygon<BezierCurve<T, 2>>& poly, double tol = 1e-8)
123123
{
124124
using PointType = primal::Point<T, 2>;
125125

0 commit comments

Comments
 (0)