Virtual Testbed
Ship dynamics simulator for extreme conditions
spline_surface.hh
1 #ifndef VTESTBED_GEOMETRY_SPLINE_SURFACE_HH
2 #define VTESTBED_GEOMETRY_SPLINE_SURFACE_HH
3 
4 #include <vtestbed/geometry/polyhedron.hh>
5 
6 namespace vtb {
7 
8  namespace geometry {
9 
10  template <class T, class Curve>
12 
13  public:
14  using curve_type = Curve;
15  using value_type = typename curve_type::value_type;
16  using reference = value_type&;
17  using const_reference = const value_type&;
19  using size_type = size_t;
20  using pointer = curve_type*;
21  using const_pointer = const curve_type*;
23 
24  private:
25  container_type _curves;
26 
27  public:
28 
29  inline explicit
30  Spline_surface(const container_type& curves):
31  _curves(curves) {}
32 
33  inline curve_type
34  operator()(T u) const {
36  points.reserve(this->_curves.size());
37  for (const auto& curve : this->_curves) {
38  points.emplace_back(curve(u));
39  }
40  return curve_type(points);
41  }
42 
43  inline value_type
44  operator()(T u, T v) const {
45  return this->operator()(u)(v);
46  }
47 
48  inline value_type
49  operator()(const Vertex<T,2>& v) const {
50  return this->operator()(v(0), v(1));
51  }
52 
53  inline size_type
54  size_v() const {
55  return this->_curves.size();
56  }
57 
58  inline size_type
59  max_size_u() const {
60  size_type max_s = 0;
61  for (const auto& s : this->_curves) {
62  size_type new_s = s.size();
63  if (new_s > max_s) { max_s = new_s; }
64  }
65  return max_s;
66  }
67 
68  inline const curve_type& operator[](size_type i) const { return this->_curves[i]; }
69  inline curve_type& operator[](size_type i) { return this->_curves[i]; }
70  inline size_type size() const { return this->_curves.size(); }
71  inline const_pointer begin() const { return this->_curves.data(); }
72  inline pointer begin() { return this->_curves.data(); }
73  inline const_pointer end() const { return this->_curves.data() + size(); }
74  inline pointer end() { return this->_curves.data() + size(); }
75 
76  inline Polyhedron<T,3>
77  polyhedron(size_type resolution_u, size_type resolution_v) const {
78  using vertex_array = typename polyhedron_type::vertex_array;
79  using face_array = typename polyhedron_type::face_array;
80  using index_type = typename vtb::geometry::Face<3>::value_type;
81  index_type nrows = this->_curves.size()*resolution_u;
82  index_type ncols = this->_curves.front().size()*resolution_v;
83  face_array faces;
84  vertex_array vertices;
85  vertices.reserve(ncols*nrows);
86  faces.reserve(ncols*nrows);
87  T du = T{1}/(nrows-1);
88  T dv = T{1}/(ncols-1);
89  for (index_type i=0; i<nrows; ++i) {
90  const auto& curve = (*this)(i*du);
91  for (index_type j=0; j<ncols; ++j) {
92  const auto& v2 = curve(j*dv);
93  vertices.emplace_back();
94  auto& v1 = vertices.back();
95  for (int i=0; i<3; ++i) {
96  v1(i) = v2(i);
97  }
98  }
99  }
100  for (index_type i=1; i<nrows; ++i) {
101  for (index_type j=1; j<ncols; ++j) {
102  auto i1 = ncols*(i-1) + (j-1);
103  auto i2 = ncols*(i-1) + j;
104  auto i3 = ncols*i + j;
105  auto i4 = ncols*i + (j-1);
106  faces.emplace_back(i1, i2, i3);
107  faces.emplace_back(i1, i3, i4);
108  }
109  }
110  polyhedron_type result(vertices, faces);
111  result.unique();
112  result.normalise();
113  return result;
114  }
115 
116  };
117 
118  }
119 
120 }
121 
122 #endif // vim:filetype=cpp
void unique()
Remove duplicate vertices and faces.
Main namespace.
Definition: convert.hh:9
void normalise()
Compute face and vertex normals in one loop.