Tatooine
pointset.h
Go to the documentation of this file.
1#ifndef TATOOINE_POINTSET_H
2#define TATOOINE_POINTSET_H
3//==============================================================================
4#include <tatooine/available_libraries.h>
8
9#include <boost/range/algorithm/find.hpp>
10#if TATOOINE_FLANN_AVAILABLE
11#include <flann/flann.hpp>
12#endif
13#include <tatooine/concepts.h>
14#include <tatooine/field.h>
15#include <tatooine/handle.h>
16#include <tatooine/polynomial.h>
17#include <tatooine/property.h>
18#include <tatooine/tensor.h>
22#include <tatooine/vtk_legacy.h>
23
24#include <fstream>
25#include <limits>
26#include <set>
27#include <vector>
28//==============================================================================
29namespace tatooine {
30//==============================================================================
31namespace detail::pointset {
32#if TATOOINE_CGAL_AVAILABLE
33template <floating_point Real, std::size_t NumDimensions, typename ValueType>
34struct natural_neighbor_coordinates_sampler;
35//------------------------------------------------------------------------------
36template <floating_point Real, std::size_t NumDimensions, typename ValueType,
37 typename Gradient>
38struct natural_neighbor_coordinates_sampler_with_gradients;
39#endif
40//==============================================================================
41#if TATOOINE_FLANN_AVAILABLE
42template <floating_point Real, std::size_t NumDimensions, typename ValueType,
43 invocable<Real> F>
44struct moving_least_squares_sampler;
45#endif
46//==============================================================================
47template <floating_point Real, std::size_t NumDimensions, typename ValueType>
48requires(flann_available())
49struct inverse_distance_weighting_sampler;
50//==============================================================================
51#if TATOOINE_BLAS_AND_LAPACK_AVAILABLE
52template <floating_point Real, std::size_t NumDimensions, typename ValueType,
53 invocable<Real> Kernel>
55//==============================================================================
56template <floating_point Real, std::size_t NumDimensions, typename ValueType,
57 typename GradientType>
59#endif
60//==============================================================================
61template <floating_point Real, std::size_t NumDimensions>
62struct vertex_container;
63//==============================================================================
64template <floating_point Real, std::size_t NumDimensions>
65struct const_vertex_container;
66} // namespace detail::pointset
67//==============================================================================
68template <floating_point Real, std::size_t NumDimensions>
69struct pointset {
70 // static constexpr std::size_t triangle_dims = 2;
71 // static constexpr std::size_t tetgen_dims = 3;
72 static constexpr auto num_dimensions() -> std::size_t {
73 return NumDimensions;
74 }
75 using real_type = Real;
79#if TATOOINE_FLANN_AVAILABLE || defined(TATOOINE_DOC_ONLY)
80 using flann_index_type = flann::Index<flann::L2<Real>>;
81#endif
82 //----------------------------------------------------------------------------
83 struct vertex_handle : handle<vertex_handle> {
85 using handle<vertex_handle>::operator=;
86 };
87 //----------------------------------------------------------------------------
90 //----------------------------------------------------------------------------
93 //----------------------------------------------------------------------------
95 template <typename T>
98 std::map<std::string, std::unique_ptr<vertex_property_type>>;
99 template <typename T>
102 T>;
103#if TATOOINE_CGAL_AVAILABLE
104 template <typename T>
107 NumDimensions, T>;
108 template <typename T, typename Gradient>
111 Real, NumDimensions, T, Gradient>;
112#endif
113 //============================================================================
114 protected:
115 std::vector<pos_type> m_vertex_position_data;
116
117 private:
118 std::set<vertex_handle> m_invalid_vertices;
120#if TATOOINE_FLANN_AVAILABLE || defined(TATOOINE_DOC_ONLY)
121 mutable std::unique_ptr<flann_index_type> m_kd_tree;
122 mutable std::mutex m_flann_mutex;
123#endif
124 //============================================================================
125 public:
126 pointset() = default;
127 ~pointset() = default;
128 //----------------------------------------------------------------------------
129 pointset(std::initializer_list<pos_type> &&vertices)
130 : m_vertex_position_data(std::move(vertices)) {}
131 //----------------------------------------------------------------------------
132 // #ifdef USE_TRIANGLE
133 // pointset(const triangle::io& io) {
134 // for (int i = 0; i < io.numberofpoints; ++i)
135 // insert_vertex(io.pointlist[i * 2], io.pointlist[i * 2 + 1]);
136 // }
137 // #endif
138
139 // template <typename = void>
140 // requires (NumDimensions == 3)
141 // pointset(const tetgenio& io) {
142 // for (int i = 0; i < io.numberofpoints; ++i)
143 // insert_vertex(io.pointlist[i * 3], io.pointlist[i * 3 + 1],
144 // io.pointlist[i * 3 + 2]);
145 // }
146 //----------------------------------------------------------------------------
147 pointset(pointset const &other)
150 vertex_properties().clear();
151 for (auto const &[name, prop] : other.vertex_properties())
152 vertex_properties().insert(std::pair{name, prop->clone()});
153 }
154 //----------------------------------------------------------------------------
155 pointset(pointset &&other) noexcept
156 : m_vertex_position_data(std::move(other.m_vertex_position_data)),
157 m_invalid_vertices(std::move(other.m_invalid_vertices)),
158 m_vertex_properties(std::move(other.m_vertex_properties)) {}
159 //----------------------------------------------------------------------------
160 explicit pointset(std::vector<pos_type> const &vertices)
162 //----------------------------------------------------------------------------
163 explicit pointset(std::vector<pos_type> &&vertices)
164 : m_vertex_position_data(std::move(vertices)) {}
165 //----------------------------------------------------------------------------
166 explicit pointset(filesystem::path const &path) { read(path); }
167 //----------------------------------------------------------------------------
168 auto operator=(pointset const &other) -> pointset & {
169 if (&other == this) {
170 return *this;
171 }
172 vertex_properties().clear();
173 m_vertex_position_data = other.m_vertex_position_data;
174 m_invalid_vertices = other.m_invalid_vertices;
175 for (auto const &[name, prop] : other.vertex_properties()) {
176 vertex_properties().emplace(name, prop->clone());
177 }
178 return *this;
179 }
180 //----------------------------------------------------------------------------
181 auto operator=(pointset &&other) noexcept -> pointset & = default;
182 //----------------------------------------------------------------------------
185 for (auto v : vertices()) {
186 aabb += at(v);
187 }
188 return aabb;
189 }
190 //----------------------------------------------------------------------------
191 auto vertex_properties() const -> auto const & { return m_vertex_properties; }
192 auto vertex_properties() -> auto & { return m_vertex_properties; }
193 //----------------------------------------------------------------------------
194 auto has_vertex_property(std::string const &name) const {
195 return vertex_properties().find(name) != vertex_properties().end();
196 }
197 //----------------------------------------------------------------------------
198 auto at(vertex_handle const v) -> auto & {
199 return m_vertex_position_data[v.index()];
200 }
201 auto at(vertex_handle const v) const -> auto const & {
202 return m_vertex_position_data[v.index()];
203 }
204 //----------------------------------------------------------------------------
205 auto vertex_at(vertex_handle const v) -> auto & {
206 assert(v.index() < m_vertex_position_data.size());
207 return m_vertex_position_data[v.index()];
208 }
209 auto vertex_at(vertex_handle const v) const -> auto const & {
210 assert(v.index() < m_vertex_position_data.size());
211 return m_vertex_position_data[v.index()];
212 }
213 //----------------------------------------------------------------------------
214 auto vertex_at(std::size_t const i) -> auto & {
215 assert(i < m_vertex_position_data.size());
216 return m_vertex_position_data[i];
217 }
218 auto vertex_at(std::size_t const i) const -> auto const & {
219 assert(i < m_vertex_position_data.size());
220 return m_vertex_position_data[i];
221 }
222 //----------------------------------------------------------------------------
223 auto operator[](vertex_handle const v) -> auto & { return at(v); }
224 auto operator[](vertex_handle const v) const -> auto const & { return at(v); }
225 //----------------------------------------------------------------------------
226 auto vertices() const { return const_vertex_container{this}; }
227 auto vertices() { return vertex_container{this}; }
228 //----------------------------------------------------------------------------
229 auto num_vertices() const {
230 return vertex_position_data().size() - invalid_vertices().size();
231 }
232 //----------------------------------------------------------------------------
233 auto num_vertex_properties() const { return vertex_properties().size(); }
234 //----------------------------------------------------------------------------
235 auto vertex_position_data() const -> auto const & {
237 }
238 //----------------------------------------------------------------------------
239 auto invalid_vertices() const -> auto const & { return m_invalid_vertices; }
240 //----------------------------------------------------------------------------
241 public:
243 auto insert_vertex(arithmetic auto const... ts)
244 requires(sizeof...(ts) == NumDimensions)
245 {
246 m_vertex_position_data.push_back(pos_type{static_cast<Real>(ts)...});
247 for (auto &[key, prop] : vertex_properties()) {
248 prop->push_back();
249 }
250#if TATOOINE_FLANN_AVAILABLE
251 {
252 auto lock = std::scoped_lock{m_flann_mutex};
253 if (m_kd_tree != nullptr) {
254 m_kd_tree->addPoints(flann::Matrix<Real>{
255 const_cast<Real *>(m_vertex_position_data.back().data()), 1,
256 num_dimensions()});
257 }
258 }
259#endif
261 }
262 //----------------------------------------------------------------------------
263 auto insert_vertex(pos_type const &v) {
264 m_vertex_position_data.push_back(v);
265 for (auto &[key, prop] : vertex_properties()) {
266 prop->push_back();
267 }
268#if TATOOINE_FLANN_AVAILABLE
269 {
270 auto lock = std::scoped_lock{m_flann_mutex};
271 if (m_kd_tree != nullptr) {
272 m_kd_tree->addPoints(flann::Matrix<Real>{
273 const_cast<Real *>(m_vertex_position_data.back().data()), 1,
274 num_dimensions()});
275 }
276 }
277#endif
279 }
280 //----------------------------------------------------------------------------
282 m_vertex_position_data.emplace_back(std::move(v));
283 for (auto &[key, prop] : vertex_properties()) {
284 prop->push_back();
285 }
286#if TATOOINE_FLANN_AVAILABLE
287 {
288 auto lock = std::scoped_lock{m_flann_mutex};
289 if (m_kd_tree != nullptr) {
290 m_kd_tree->addPoints(flann::Matrix<Real>{
291 const_cast<Real *>(m_vertex_position_data.back().data()), 1,
292 num_dimensions()});
293 }
294 }
295#endif
297 }
299 //----------------------------------------------------------------------------
301 auto tidy_up() {
302 // auto decrement_counter = std::size_t{};
303 // for (auto const v : invalid_vertices()) {
304 // m_vertex_position_data.erase(begin(m_vertex_position_data) +
305 // (v.index() - decrement_counter++));
306 // for (auto const& [key, prop] : vertex_properties()) {
307 // prop->erase(v.index());
308 // }
309 // }
310 auto cleaned_positions = std::vector<pos_type>{};
311 cleaned_positions.reserve(vertices().size());
312 auto invalid_it = begin(m_invalid_vertices);
313 auto i = std::size_t{};
314 for (auto const &pos : m_vertex_position_data) {
315 if (invalid_it != end(m_invalid_vertices) &&
316 *invalid_it == vertex_handle{i}) {
317 ++invalid_it;
318 } else {
319 cleaned_positions.push_back(pos);
320 }
321 ++i;
322 }
323 m_vertex_position_data = std::move(cleaned_positions);
324
325 for (auto &[name, prop] : m_vertex_properties) {
326 prop->clean(m_invalid_vertices);
327 }
328
329 m_invalid_vertices.clear();
330 }
331 //----------------------------------------------------------------------------
332 auto remove(vertex_handle const v) {
333 if (is_valid(v) &&
334 std::ranges::find(invalid_vertices(), v) == end(invalid_vertices())) {
335 m_invalid_vertices.insert(v);
336 }
337#if TATOOINE_FLANN_AVAILABLE
338 {
339 auto lock = std::scoped_lock{m_flann_mutex};
340 if (m_kd_tree != nullptr) {
341 m_kd_tree->removePoint(v.index());
342 }
343 }
344#endif
345 }
346 //----------------------------------------------------------------------------
347 constexpr auto is_valid(vertex_handle const v) const -> bool {
348 return v.is_valid() &&
349 std::ranges::find(invalid_vertices(), v) == end(invalid_vertices());
350 }
351
352 //----------------------------------------------------------------------------
355 m_vertex_position_data.shrink_to_fit();
356 invalid_vertices().clear();
357 for (auto &[key, val] : vertex_properties())
358 val->clear();
359 }
360 auto clear() { clear_vertices(); }
361 //============================================================================
362 template <invocable<pos_type> F>
363 auto sample_to_vertex_property(F &&f, std::string const &name) -> auto & {
364 return sample_to_vertex_property(std::forward<F>(f), name,
366 }
367 //============================================================================
368 template <invocable<pos_type> F>
369 auto sample_to_vertex_property(F &&f, std::string const &name,
371 -> auto & {
372 using T = std::invoke_result_t<F, pos_type>;
373 auto &prop = vertex_property<T>(name);
374 for (auto const v : vertices()) {
375 try {
376 prop[v] = f(at(v));
377 } catch (std::exception &) {
378 if constexpr (tensor_num_components<T> == 1) {
379 prop[v] = T{nan<T>()};
380 } else {
381 prop[v] = T::fill(nan<tatooine::value_type<T>>());
382 }
383 }
384 }
385 return prop;
386 }
387 //============================================================================
388 template <invocable<pos_type> F>
389 auto sample_to_vertex_property(F &&f, std::string const &name,
391 -> auto & {
392 using T = std::invoke_result_t<F, pos_type>;
393 auto &prop = vertex_property<T>(name);
394#pragma omp parallel for
395 for (auto const v : vertices()) {
396 try {
397 prop[v] = f(at(v));
398 } catch (std::exception &) {
399 if constexpr (tensor_num_components<T> == 1) {
400 prop[v] = T{nan<T>()};
401 } else {
402 prop[v] = T::fill(nan<tatooine::value_type<T>>());
403 }
404 }
405 }
406 return prop;
407 }
408 //----------------------------------------------------------------------------
409 auto join(this_type const &other) {
410 for (auto v : other.vertices()) {
411 insert_vertex(other[v]);
412 }
413 }
414 //----------------------------------------------------------------------------
415 auto find_duplicates(Real eps = 1e-6) {
416 std::vector<std::pair<vertex_handle, vertex_handle>> duplicates;
417 for (auto v0 = vertices().begin(); v0 != vertices().end(); ++v0)
418 for (auto v1 = next(v0); v1 != vertices().end(); ++v1)
419 if (approx_equal(at(v0), at(v1), eps)) duplicates.emplace_back(v0, v1);
420
421 return duplicates;
422 }
423 // #ifdef USE_TRIANGLE
424 //----------------------------------------------------------------------------
425 // template <typename = void>
426 // requires (NumDimensions == triangle_dims>>
427 // auto to_triangle_io() const {
428 // triangle::io in;
429 // std::size_t i = 0;
430 // in.pointlist = new triangle::Real[in.numberofpoints *
431 // triangle_dims]; for (auto v : vertices()) {
432 // for (std::size_t j = 0; j < triangle_dims; ++j) {
433 // in.pointlist[i++] = at(v)(j);
434 // }
435 // }
436 //
437 // return in;
438 // }
439 //
440 //--------------------------------------------------------------------------
441 // template <typename vertex_cont_t>
442 // requires (NumDimensions == triangle_dims)
443 // auto to_triangle_io(vertex_cont_t const& vertices) const {
444 // triangle::io in;
445 // std::size_t i = 0;
446 // in.numberofpoints = vertices().size();
447 // in.pointlist = new triangle::Real[in.numberofpoints *
448 // triangle_dims]; for (auto v : vertices()) {
449 // for (std::size_t j = 0; j < triangle_dims; ++j) {
450 // in.pointlist[i++] = at(v)(j);
451 // }
452 // }
453 //
454 // return in;
455 // }
456 // #endif
457
458 //----------------------------------------------------------------------------
459 // template <typename = void>
460 // requires (NumDimensions == tetgen_dims)
461 // void to_tetgen_io(tetgenio& in) const {
462 // std::size_t i = 0;
463 // in.numberofpoints = vertices().size();
464 // in.pointlist = new tetgen::Real[in.numberofpoints * tetgen_dims];
465 // in.pointmarkerlist = new int[in.numberofpoints];
466 // in.numberofpointattributes = 1;
467 // in.pointattributelist =
468 // new tetgen::Real[in.numberofpoints * in.numberofpointattributes];
469 // for (auto v : vertices()) {
470 // for (std::size_t j = 0; j < tetgen_dims; ++j) {
471 // in.pointlist[i * 3 + j] = at(v)(j);
472 // }
473 // in.pointmarkerlist[i] = i;
474 // in.pointattributelist[i] = v.index();
475 // ++i;
476 // }
477 // }
478
479 //----------------------------------------------------------------------------
481 // template <typename vertex_cont_t>
482 // auto to_tetgen_io(vertex_cont_t const& vertices) const {
483 // tetgenio io;
484 // std::size_t i = 0;
485 // io.numberofpoints = vertices.size();
486 // io.pointlist = new tetgen_real_type[io.numberofpoints * 3];
487 // for (auto v : vertices) {
488 // auto const& x = at(v);
489 // io.pointlist[i] = x(0);
490 // io.pointlist[i + 1] = x(1);
491 // io.pointlist[i + 2] = x(2);
492 // i += 2;
493 // }
494 //
495 // return io;
496 // }
497 //----------------------------------------------------------------------------
499 template <typename T>
500 auto vertex_property(std::string const &name) -> auto & {
501 if (auto it = vertex_properties().find(name);
502 it == end(vertex_properties())) {
503 return insert_vertex_property<T>(name);
504 } else {
505 if (typeid(T) != it->second->type()) {
506 throw std::runtime_error{
507 "type of property \"" + name + "\"(" +
508 boost::core::demangle(it->second->type().name()) +
509 ") does not match specified type " + type_name<T>() + "."};
510 }
511 return *dynamic_cast<typed_vertex_property_type<T> *>(
512 vertex_properties().at(name).get());
513 }
514 }
515 //----------------------------------------------------------------------------
516 template <typename T>
517 auto vertex_property(std::string const &name) const -> const auto & {
518 if (auto it = vertex_properties().find(name);
519 it == end(vertex_properties())) {
520 throw std::runtime_error{"property \"" + name + "\" not found"};
521 } else {
522 if (typeid(T) != it->second->type()) {
523 throw std::runtime_error{
524 "type of property \"" + name + "\"(" +
525 boost::core::demangle(it->second->type().name()) +
526 ") does not match specified type " + type_name<T>() + "."};
527 }
528 return *dynamic_cast<typed_vertex_property_type<T> *>(
529 vertex_properties().at(name).get());
530 }
531 }
532 //----------------------------------------------------------------------------
533 auto scalar_vertex_property(std::string const &name) const -> auto const & {
534 return vertex_property<tatooine::real_number>(name);
535 }
536 //----------------------------------------------------------------------------
537 auto scalar_vertex_property(std::string const &name) -> auto & {
538 return vertex_property<tatooine::real_number>(name);
539 }
540 //----------------------------------------------------------------------------
541 auto vec2_vertex_property(std::string const &name) const -> auto const & {
542 return vertex_property<vec2>(name);
543 }
544 //----------------------------------------------------------------------------
545 auto vec2_vertex_property(std::string const &name) -> auto & {
546 return vertex_property<vec2>(name);
547 }
548 //----------------------------------------------------------------------------
549 auto vec3_vertex_property(std::string const &name) const -> auto const & {
550 return vertex_property<vec3>(name);
551 }
552 //----------------------------------------------------------------------------
553 auto vec3_vertex_property(std::string const &name) -> auto & {
554 return vertex_property<vec3>(name);
555 }
556 //----------------------------------------------------------------------------
557 auto vec4_vertex_property(std::string const &name) const -> auto const & {
558 return vertex_property<vec4>(name);
559 }
560 //----------------------------------------------------------------------------
561 auto vec4_vertex_property(std::string const &name) -> auto & {
562 return vertex_property<vec4>(name);
563 }
564 //----------------------------------------------------------------------------
565 auto mat2_vertex_property(std::string const &name) const -> auto const & {
566 return vertex_property<mat2>(name);
567 }
568 //----------------------------------------------------------------------------
569 auto mat2_vertex_property(std::string const &name) -> auto & {
570 return vertex_property<mat2>(name);
571 }
572 //----------------------------------------------------------------------------
573 auto mat3_vertex_property(std::string const &name) const -> auto const & {
574 return vertex_property<mat3>(name);
575 }
576 //----------------------------------------------------------------------------
577 auto mat3_vertex_property(std::string const &name) -> auto & {
578 return vertex_property<mat3>(name);
579 }
580 //----------------------------------------------------------------------------
581 auto mat4_vertex_property(std::string const &name) const -> auto const & {
582 return vertex_property<mat4>(name);
583 }
584 //----------------------------------------------------------------------------
585 auto mat4_vertex_property(std::string const &name) -> auto & {
586 return vertex_property<mat4>(name);
587 }
588 //----------------------------------------------------------------------------
589 template <typename T>
590 auto insert_vertex_property(std::string const &name, T const &value = T{})
591 -> auto & {
592 auto [it, suc] = vertex_properties().insert(std::pair{
593 name, std::make_unique<typed_vertex_property_type<T>>(value)});
594 auto prop = dynamic_cast<typed_vertex_property_type<T> *>(it->second.get());
595 prop->resize(m_vertex_position_data.size());
596 return *prop;
597 }
598 //----------------------------------------------------------------------------
600 std::string const &name,
601 tatooine::real_number const value = tatooine::real_number{}) -> auto & {
602 return insert_vertex_property<tatooine::real_number>(name, value);
603 }
604 //----------------------------------------------------------------------------
606 std::string const &name, tatooine::vec2 const value = tatooine::vec2{})
607 -> auto & {
608 return insert_vertex_property<vec2>(name, value);
609 }
610 //----------------------------------------------------------------------------
612 std::string const &name, tatooine::vec3 const value = tatooine::vec3{})
613 -> auto & {
614 return insert_vertex_property<vec3>(name, value);
615 }
616 //----------------------------------------------------------------------------
618 std::string const &name, tatooine::vec4 const value = tatooine::vec4{})
619 -> auto & {
620 return insert_vertex_property<vec4>(name, value);
621 }
622 //----------------------------------------------------------------------------
624 std::string const &name, tatooine::mat2 const value = tatooine::mat2{})
625 -> auto & {
626 return insert_vertex_property<mat2>(name, value);
627 }
628 //----------------------------------------------------------------------------
630 std::string const &name, tatooine::mat3 const value = tatooine::mat3{})
631 -> auto & {
632 return insert_vertex_property<mat3>(name, value);
633 }
634 //----------------------------------------------------------------------------
636 std::string const &name, tatooine::mat4 const value = tatooine::mat4{})
637 -> auto & {
638 return insert_vertex_property<mat4>(name, value);
639 }
641 //----------------------------------------------------------------------------
643 auto write(filesystem::path const &path) const {
644 auto const ext = path.extension();
645 if constexpr (NumDimensions == 2 || NumDimensions == 3) {
646 if (ext == ".vtk") {
647 write_vtk(path);
648 return;
649 } else if (ext == ".vtp") {
650 write_vtp(path);
651 return;
652 }
653 }
654 throw std::runtime_error(
655 "Could not write pointset. Unknown file extension: \"" + ext.string() +
656 "\".");
657 }
658 //----------------------------------------------------------------------------
659 auto write_vtk(filesystem::path const &path,
660 std::string const &title = "Tatooine pointset") const -> void
661 requires(NumDimensions == 3 || NumDimensions == 2)
662 {
664 if (writer.is_open()) {
665 writer.set_title(title);
666 writer.write_header();
667 write_vertices_vtk(writer);
669 vec4d>(writer);
670 writer.close();
671 }
672 }
673 //----------------------------------------------------------------------------
674 private:
676 using namespace std::ranges;
677 if constexpr (NumDimensions == 2) {
678 auto three_dims = [](vec<Real, 2> const &v2) {
679 return vec<Real, 3>{v2(0), v2(1), 0};
680 };
681 auto v3s = std::vector<vec<Real, 3>>(vertices().size());
682 auto three_dimensional = views::transform(three_dims);
683 copy(m_vertex_position_data | three_dimensional, begin(v3s));
684 writer.write_points(v3s);
685 } else if constexpr (NumDimensions == 3) {
687 }
688
689 auto vertex_indices = std::vector<std::vector<std::size_t>>(
690 1, std::vector<std::size_t>(vertices().size()));
691 copy(views::iota(std::size_t(0), vertices().size()),
692 vertex_indices.front().begin());
693 writer.write_vertices(vertex_indices);
694 }
695 //----------------------------------------------------------------------------
696 template <typename T>
697 auto write_prop_vtk(vtk::legacy_file_writer &writer, std::string const &name,
698 typed_vertex_property_type<T> const &prop) const -> void {
699 writer.write_scalars(name, prop.internal_container());
700 }
701 //----------------------------------------------------------------------------
702 template <typename... Ts>
703 auto write_prop_vtk(vtk::legacy_file_writer &writer) const -> void {
704 if (!vertex_properties().empty()) {
705 writer.write_point_data(vertices().size());
706 }
707 for (const auto &p : m_vertex_properties) {
708 (
709 [&] {
710 auto const &[name, prop] = p;
711 if (prop->type() == typeid(Ts)) {
712 write_prop_vtk(writer, name, prop->template cast_to_typed<Ts>());
713 }
714 }(),
715 ...);
716 }
717 }
718 //----------------------------------------------------------------------------
719 public:
720 auto write_vtp(filesystem::path const &path) const {
721 auto file = std::ofstream{path, std::ios::binary};
722 if (!file.is_open()) {
723 throw std::runtime_error{"Could not write " + path.string()};
724 }
725 auto offset = std::size_t{};
726 using header_type = std::uint64_t;
727 using verts_connectivity_int_type = std::int64_t;
728 using verts_offset_int_type = verts_connectivity_int_type;
729 auto const num_bytes_points =
730 header_type(sizeof(Real) * 3 * vertices().size());
731 auto const num_bytes_verts_connectivity =
732 vertices().size() * sizeof(verts_connectivity_int_type);
733 auto const num_bytes_verts_offsets =
734 sizeof(verts_offset_int_type) * vertices().size();
735 file << "<VTKFile"
736 << " type=\"PolyData\""
737 << " version=\"1.0\""
738 << " byte_order=\"LittleEndian\""
739 << " header_type=\""
740 << vtk::xml::to_string(vtk::xml::to_data_type<header_type>())
741 << "\">\n"
742 << "<PolyData>\n"
743 << "<Piece"
744 << " NumberOfPoints=\"" << vertices().size() << "\""
745 << " NumberOfPolys=\"0\""
746 << " NumberOfVerts=\"" << vertices().size() << "\""
747 << " NumberOfLines=\"0\""
748 << " NumberOfStrips=\"0\""
749 << ">\n"
750 // Points
751 << "<Points>"
752 << "<DataArray"
753 << " format=\"appended\""
754 << " offset=\"" << offset << "\""
755 << " type=\"" << vtk::xml::to_string(vtk::xml::to_data_type<Real>())
756 << "\" NumberOfComponents=\"3\"/>"
757 << "</Points>\n";
758 offset += num_bytes_points + sizeof(header_type);
759 // Verts
760 file << "<Verts>\n"
761 // Verts - connectivity
762 << "<DataArray format=\"appended\" offset=\"" << offset << "\" type=\""
764 vtk::xml::to_data_type<verts_connectivity_int_type>())
765 << "\" Name=\"connectivity\"/>\n";
766 offset += num_bytes_verts_connectivity + sizeof(header_type);
767 // Verts - offsets
768 file << "<DataArray format=\"appended\" offset=\"" << offset << "\" type=\""
769 << vtk::xml::to_string(vtk::xml::to_data_type<verts_offset_int_type>())
770 << "\" Name=\"offsets\"/>\n";
771 offset += num_bytes_verts_offsets + sizeof(header_type);
772 file << "</Verts>\n";
773
774 {
775 // Writing vertex data to appended data section
776 file << "<PointData>\n";
777 for (auto const &[name, prop] : vertex_properties()) {
778 offset += write_vertex_property_data_array_vtp<float, header_type>(
779 name, prop, file, offset);
780 offset += write_vertex_property_data_array_vtp<vec2f, header_type>(
781 name, prop, file, offset);
782 offset += write_vertex_property_data_array_vtp<vec3f, header_type>(
783 name, prop, file, offset);
784 offset += write_vertex_property_data_array_vtp<vec4f, header_type>(
785 name, prop, file, offset);
786 offset += write_vertex_property_data_array_vtp<mat2f, header_type>(
787 name, prop, file, offset);
788 offset += write_vertex_property_data_array_vtp<mat3f, header_type>(
789 name, prop, file, offset);
790 offset += write_vertex_property_data_array_vtp<mat4f, header_type>(
791 name, prop, file, offset);
792 offset += write_vertex_property_data_array_vtp<double, header_type>(
793 name, prop, file, offset);
794 offset += write_vertex_property_data_array_vtp<vec2d, header_type>(
795 name, prop, file, offset);
796 offset += write_vertex_property_data_array_vtp<vec3d, header_type>(
797 name, prop, file, offset);
798 offset += write_vertex_property_data_array_vtp<vec4d, header_type>(
799 name, prop, file, offset);
800 offset += write_vertex_property_data_array_vtp<mat2d, header_type>(
801 name, prop, file, offset);
802 offset += write_vertex_property_data_array_vtp<mat3d, header_type>(
803 name, prop, file, offset);
804 offset += write_vertex_property_data_array_vtp<mat4d, header_type>(
805 name, prop, file, offset);
806 }
807 file << "</PointData>\n";
808 }
809 file << "</Piece>\n"
810 << "</PolyData>\n"
811 << "<AppendedData encoding=\"raw\">\n_";
812
813 using namespace std::ranges;
814 {
815 file.write(reinterpret_cast<char const *>(&num_bytes_points),
816 sizeof(header_type));
817 if constexpr (NumDimensions == 2) {
818 auto point_data = std::vector<vec<Real, 3>>(vertices().size());
819 auto position = [this](auto const v) -> auto &{ return at(v); };
820 constexpr auto to_3d = [](auto const &p) {
821 return vec{p.x(), p.y(), Real(0)};
822 };
823 copy(m_vertex_position_data | views::transform(to_3d),
824 begin(point_data));
825 file.write(reinterpret_cast<char const *>(point_data.data()),
826 num_bytes_points);
827 } else if constexpr (NumDimensions == 3) {
828 file.write(reinterpret_cast<char const *>(vertices().data()),
829 num_bytes_points);
830 }
831 }
832
833 // Writing verts connectivity data to appended data section
834 {
835 auto connectivity_data =
836 std::vector<verts_connectivity_int_type>(vertices().size());
837 copy(views::iota(verts_connectivity_int_type(0),
838 verts_connectivity_int_type(vertices().size())),
839 begin(connectivity_data));
840 file.write(reinterpret_cast<char const *>(&num_bytes_verts_connectivity),
841 sizeof(header_type));
842 file.write(reinterpret_cast<char const *>(connectivity_data.data()),
843 num_bytes_verts_connectivity);
844 }
845
846 // Writing verts offsets to appended data section
847 {
848 auto offsets = std::vector<verts_offset_int_type>(vertices().size(), 1);
849 for (std::size_t i = 1; i < size(offsets); ++i) {
850 offsets[i] += offsets[i - 1];
851 };
852 file.write(reinterpret_cast<char const *>(&num_bytes_verts_offsets),
853 sizeof(header_type));
854 file.write(reinterpret_cast<char const *>(offsets.data()),
855 num_bytes_verts_offsets);
856 }
857 for (auto const &[name, prop] : vertex_properties()) {
858 write_vertex_property_appended_data_vtp<float, header_type>(prop, file);
859 write_vertex_property_appended_data_vtp<vec2f, header_type>(prop, file);
860 write_vertex_property_appended_data_vtp<vec3f, header_type>(prop, file);
861 write_vertex_property_appended_data_vtp<vec4f, header_type>(prop, file);
862 write_vertex_property_appended_data_vtp<mat2f, header_type>(prop, file);
863 write_vertex_property_appended_data_vtp<mat3f, header_type>(prop, file);
864 write_vertex_property_appended_data_vtp<mat4f, header_type>(prop, file);
865 write_vertex_property_appended_data_vtp<double, header_type>(prop, file);
866 write_vertex_property_appended_data_vtp<vec2d, header_type>(prop, file);
867 write_vertex_property_appended_data_vtp<vec3d, header_type>(prop, file);
868 write_vertex_property_appended_data_vtp<vec4d, header_type>(prop, file);
869 write_vertex_property_appended_data_vtp<mat2d, header_type>(prop, file);
870 write_vertex_property_appended_data_vtp<mat3d, header_type>(prop, file);
871 write_vertex_property_appended_data_vtp<mat4d, header_type>(prop, file);
872 }
873 file << "\n</AppendedData>\n"
874 << "</VTKFile>";
875 }
876 //----------------------------------------------------------------------------
877 private:
878 //----------------------------------------------------------------------------
879 template <typename T, typename header_type>
880 auto write_vertex_property_data_array_vtp(auto const &name, auto const &prop,
881 auto &file, auto offset) const
882 -> std::size_t {
883 if (prop->type() == typeid(T)) {
884 if constexpr (tensor_rank<T> <= 1) {
885 file << "<DataArray"
886 << " Name=\"" << name << "\""
887 << " format=\"appended\""
888 << " offset=\"" << offset << "\""
889 << " type=\""
892 << "\" NumberOfComponents=\""
893 << tensor_num_components<T> << "\"/>\n";
894 return vertices().size() * sizeof(T) + sizeof(header_type);
895 } else if constexpr (tensor_rank<T> == 2) {
896 for (std::size_t i = 0; i < T::dimension(1); ++i) {
897 file << "<DataArray"
898 << " Name=\"" << name << "_col_" << i << "\""
899 << " format=\"appended\""
900 << " offset=\"" << offset << "\""
901 << " type=\""
904 << "\" NumberOfComponents=\"" << T::dimension(0) << "\"/>\n";
905 offset += vertices().size() * sizeof(tatooine::value_type<T>) *
906 tensor_dimension<T, 0> +
907 sizeof(header_type);
908 }
909 return vertices().size() * sizeof(tatooine::value_type<T>) *
910 tensor_num_components<T> +
911 sizeof(header_type) * tensor_dimension<T, 1>;
912 }
913 }
914 return 0;
915 }
916 //----------------------------------------------------------------------------
917 template <typename T, typename header_type>
919 auto &file) const {
920 if (prop->type() == typeid(T)) {
921 auto const &typed_prop = prop->template cast_to_typed<T>();
922 if constexpr (tensor_rank<T> <= 1) {
923 auto const num_bytes =
924 header_type(sizeof(tatooine::value_type<T>) *
925 tensor_num_components<T> * vertices().size());
926 file.write(reinterpret_cast<char const *>(&num_bytes),
927 sizeof(header_type));
928 file.write(reinterpret_cast<char const *>(typed_prop.data()),
929 num_bytes);
930 } else if constexpr (tensor_rank<T> == 2) {
931 auto const num_bytes = header_type(
932 sizeof(tatooine::value_type<T>) * tensor_num_components<T> *
933 vertices().size() / tensor_dimension<T, 0>);
934 for (std::size_t i = 0; i < tensor_dimension<T, 1>; ++i) {
935 file.write(reinterpret_cast<char const *>(&num_bytes),
936 sizeof(header_type));
937 for (auto const v : vertices()) {
938 auto data_begin = &typed_prop[v](0, i);
939 file.write(
940 reinterpret_cast<char const *>(data_begin),
941 sizeof(tatooine::value_type<T>) * tensor_dimension<T, 0>);
942 }
943 }
944 }
945 }
946 }
948 //----------------------------------------------------------------------------
950 public:
951 auto read(filesystem::path const &p) {
952 if (p.extension() == ".vtp") {
953 read_vtp(p);
954 }
955 }
956 //----------------------------------------------------------------------------
957 auto read_vtp(filesystem::path const &path) -> void
958 requires(NumDimensions == 2) || (NumDimensions == 3)
959 {
960 auto reader = vtk::xml::reader{path};
961 auto &poly_data = *reader.poly_data();
962
963 for (auto const &piece : poly_data.pieces) {
964 piece.points.visit_data([&](auto const &point_data) {
965 // always 3 components in vtk data array
966 for (std::size_t i = 0; i < point_data.size(); i += 3) {
967 if constexpr (num_dimensions() == 2) {
968 // just omit third component when reading to a 3d line
969 insert_vertex(point_data[i], point_data[i + 1]);
970 } else if constexpr (num_dimensions() == 3) {
971 insert_vertex(point_data[i], point_data[i + 1], point_data[i + 2]);
972 }
973 }
974 });
975 for (auto const &[name, prop] : piece.point_data) {
976 prop.visit_data([&]<typename T>(std::vector<T> const &data) {
977 auto v = vertex_handle{0};
978 if (prop.num_components() == 1) {
979 [[maybe_unused]] auto &prop = vertex_property<T>(name);
980 for (std::size_t i = 0; i < data.size(); ++i, ++v) {
981 prop[v] = data[i];
982 }
983 } else if (prop.num_components() == 2) {
984 [[maybe_unused]] auto &prop = vertex_property<vec<T, 2>>(name);
985 for (std::size_t i = 0; i < data.size(); i += 2, ++v) {
986 prop[v] = vec{data[i], data[i + 1]};
987 }
988 } else if (prop.num_components() == 3) {
989 auto &prop = vertex_property<vec<T, 3>>(name);
990 for (std::size_t i = 0; i < data.size(); i += 3, ++v) {
991 prop[v] = vec{data[i], data[i + 1], data[i + 2]};
992 }
993 } else if (prop.num_components() == 4) {
994 [[maybe_unused]] auto &prop = vertex_property<vec<T, 4>>(name);
995 for (std::size_t i = 0; i < data.size(); i += 4, ++v) {
996 prop[v] = vec{data[i], data[i + 1], data[i + 2], data[i + 3]};
997 }
998 }
999 });
1000 }
1001 }
1002 }
1004 //----------------------------------------------------------------------------
1005 public:
1006//----------------------------------------------------------------------------
1007#if TATOOINE_FLANN_AVAILABLE || defined(TATOOINE_DOC_ONLY)
1011 build_kd_tree();
1012 }
1014 auto lock = std::scoped_lock{m_flann_mutex};
1015 if (m_kd_tree != nullptr) {
1016 m_kd_tree->buildIndex();
1017 }
1018 }
1019 //----------------------------------------------------------------------------
1020 private:
1021 auto build_kd_tree() const -> auto & {
1022 auto lock = std::scoped_lock{m_flann_mutex};
1023 if (m_kd_tree == nullptr && vertices().size() > 0) {
1024 flann::Matrix<Real> dataset{
1025 const_cast<Real *>(m_vertex_position_data.front().data()),
1026 vertices().size(), num_dimensions()};
1027 m_kd_tree = std::make_unique<flann_index_type>(
1028 dataset, flann::KDTreeSingleIndexParams{});
1029 m_kd_tree->buildIndex();
1030 }
1031 return m_kd_tree;
1032 }
1033 //----------------------------------------------------------------------------
1034 public:
1035 //----------------------------------------------------------------------------
1036 auto invalidate_kd_tree() const {
1037 auto lock = std::scoped_lock{m_flann_mutex};
1038 m_kd_tree.reset();
1039 }
1040 //----------------------------------------------------------------------------
1041 auto nearest_neighbor(pos_type const &x) const {
1042 auto &h = build_kd_tree();
1043 if (h == nullptr) {
1044 return std::pair{vertex_handle::invalid(), Real(1) / Real(0)};
1045 }
1046 auto qm =
1047 flann::Matrix<Real>{const_cast<Real *>(x.data()), 1, num_dimensions()};
1048 auto indices = std::vector<std::vector<int>>{};
1049 auto distances = std::vector<std::vector<Real>>{};
1050 auto params = flann::SearchParams{};
1051 h->knnSearch(qm, indices, distances, 1, params);
1052 return std::pair{
1053 vertex_handle{static_cast<std::size_t>(indices.front().front())},
1054 distances.front().front()};
1055 }
1056 //----------------------------------------------------------------------------
1060 std::size_t const num_nearest_neighbors,
1061 flann::SearchParams const params = {}) const {
1062 auto &h = build_kd_tree();
1063 if (h == nullptr) {
1064 return std::pair{std::vector<int>{}, std::vector<Real>{}};
1065 }
1066 auto qm =
1067 flann::Matrix<Real>{const_cast<Real *>(x.data()), 1, num_dimensions()};
1068 auto indices = std::vector<std::vector<int>>{};
1069 auto distances = std::vector<std::vector<Real>>{};
1070 h->knnSearch(qm, indices, distances, num_nearest_neighbors, params);
1071 return std::pair{std::move(indices.front()), std::move(distances.front())};
1072 }
1073 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1075 std::size_t const num_nearest_neighbors) const {
1076 auto [indices, distances] = nearest_neighbors_raw(x, num_nearest_neighbors);
1077 auto handles = std::pair{std::vector<vertex_handle>(size(indices)),
1078 std::move(distances)};
1079 std::ranges::copy(indices | std::views::transform([](auto const i) {
1080 return vertex_handle{i};
1081 }),
1082 begin(handles.first));
1083 return handles;
1084 }
1085 //----------------------------------------------------------------------------
1088 auto nearest_neighbors_radius_raw(pos_type const &x, Real const radius,
1089 flann::SearchParams const params = {}) const
1090 -> std::pair<std::vector<int>, std::vector<Real>> {
1091 auto &h = build_kd_tree();
1092 if (h == nullptr) {
1093 return std::pair{std::vector<int>{}, std::vector<Real>{}};
1094 }
1095 flann::Matrix<Real> qm{const_cast<Real *>(x.data()), // NOLINT
1096 1, num_dimensions()};
1097 std::vector<std::vector<int>> indices;
1098 std::vector<std::vector<Real>> distances;
1099 {
1100 // auto lock = std::scoped_lock{m_flann_mutex};
1101 h->radiusSearch(qm, indices, distances, static_cast<float>(radius),
1102 params);
1103 }
1104 return {std::move(indices.front()), std::move(distances.front())};
1105 }
1106 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1107 auto nearest_neighbors_radius(pos_type const &x, Real const radius) const {
1108 auto const [indices, distances] = nearest_neighbors_radius_raw(x, radius);
1109 auto handles = std::pair{std::vector<vertex_handle>(size(indices)),
1110 std::move(distances)};
1111 std::ranges::copy(indices | std::views::transform([](auto const i) {
1112 return vertex_handle{i};
1113 }),
1114 begin(handles.first));
1115 return handles;
1116 }
1118#endif
1119 //============================================================================
1121 template <typename T>
1123 typed_vertex_property_type<T> const &prop, Real const radius = 1) const {
1124 return inverse_distance_weighting_sampler_type<T>{*this, prop, radius};
1125 }
1127//============================================================================
1128#if TATOOINE_FLANN_AVAILABLE
1140 template <typename T>
1142 Real const radius,
1143 invocable<real_type> auto &&weighting) const
1144 requires(NumDimensions == 3 || NumDimensions == 2)
1145 {
1147 real_type, num_dimensions(), T, std::decay_t<decltype(weighting)>>{
1148 *this, prop, radius, std::forward<decltype(weighting)>(weighting)};
1149 }
1150 //----------------------------------------------------------------------------
1162 template <typename T>
1164 Real const radius) const
1165 requires(NumDimensions == 3 || NumDimensions == 2)
1166 {
1168 prop, radius,
1169
1170 [](auto const d) {
1171 return 1 - 6 * d * d + 8 * d * d * d - 3 * d * d * d * d;
1172 }
1173
1174 //[](auto const d) {
1175 // return std::exp(-d * d);
1176 //}
1177 );
1178 }
1180#endif
1181//============================================================================
1182#if TATOOINE_BLAS_AND_LAPACK_AVAILABLE
1190 template <typename T>
1192 typed_vertex_property_type<T> const &prop) const {
1194 prop, [](auto const sqr_dist) { return gcem::sqrt(sqr_dist); });
1195 }
1196 //----------------------------------------------------------------------------
1204 template <typename T>
1206 typed_vertex_property_type<T> const &prop) const {
1207 return radial_basis_functions_sampler(prop, [](auto const sqr_dist) {
1208 return sqr_dist * gcem::sqrt(sqr_dist);
1209 });
1210 }
1211 //----------------------------------------------------------------------------
1219 template <typename T>
1221 typed_vertex_property_type<T> const &prop, Real const epsilon) const {
1222 return radial_basis_functions_sampler(prop, [epsilon](auto const sqr_dist) {
1223 return std::exp(-(epsilon * epsilon * sqr_dist));
1224 });
1225 }
1226 //----------------------------------------------------------------------------
1233 template <typename T>
1235 typed_vertex_property_type<T> const &prop) const {
1237 }
1238 //----------------------------------------------------------------------------
1243 template <typename T>
1245 invocable<Real> auto &&f) const {
1247 *this, prop, std::forward<decltype(f)>(f)};
1248 }
1249 //----------------------------------------------------------------------------
1252 template <typename T>
1254 typed_vertex_property_type<T> const &prop) const {
1256 }
1257 //----------------------------------------------------------------------------
1263 template <typename ValueType, typename GradientType>
1266 typed_vertex_property_type<GradientType> const &gradients) const {
1268 *this, values, gradients};
1269 }
1271#endif
1272//----------------------------------------------------------------------------
1273#if TATOOINE_CGAL_AVAILABLE
1275 template <typename T>
1277 typed_vertex_property_type<T> const &prop) const {
1279 }
1280 //----------------------------------------------------------------------------
1281 template <typename T, typename Gradient>
1284 typed_vertex_property_type<Gradient> const &gradients) const {
1286 Gradient>{
1287 *this, prop, gradients};
1288 }
1290#endif
1291 //----------------------------------------------------------------------------
1292 friend struct detail::pointset::vertex_container<Real, NumDimensions>;
1293 friend struct detail::pointset::const_vertex_container<Real, NumDimensions>;
1294};
1295//==============================================================================
1296template <std::size_t NumDimensions>
1302//==============================================================================
1303} // namespace tatooine
1304//==============================================================================
1307#if TATOOINE_CGAL_AVAILABLE
1310#endif
1311
1312#if TATOOINE_BLAS_AND_LAPACK_AVAILABLE
1315#endif
1317//==============================================================================
1318#endif
constexpr auto data() -> ValueType *
Definition: static_multidim_array.h:260
Definition: vtk_legacy.h:448
auto write_points(std::vector< std::array< Real, 2 > > const &points) -> void
Definition: vtk_legacy.h:637
auto write_vertices(std::vector< std::vector< std::size_t > > const &vertices) -> void
Definition: concepts.h:33
Definition: concepts.h:121
radial_basis_functions_sampler(tatooine::pointset< Real, NumDimensions > const &ps, typed_vector_property< typename tatooine::pointset< Real, NumDimensions >::vertex_handle, T >, Kernel &&kernel) -> radial_basis_functions_sampler< Real, NumDimensions, T, std::decay_t< Kernel > >
radial_basis_functions_sampler_with_gradients(tatooine::pointset< Real, NumDimensions > const &ps, typed_vector_property< typename tatooine::pointset< Real, NumDimensions >::vertex_handle, ValueType > const &, typed_vector_property< typename tatooine::pointset< Real, NumDimensions >::vertex_handle, GradientType > const &) -> radial_basis_functions_sampler_with_gradients< Real, NumDimensions, ValueType, GradientType >
static constexpr sequential_t sequential
Definition: tags.h:63
auto to_string(data_type const t) -> std::string_view
static auto constexpr to_data_type()
Definition: data_type.h:88
Definition: algorithm.h:6
VecF< 3 > vec3f
Definition: vec_typedefs.h:40
auto begin(Range &&range)
Definition: iterator_facade.h:318
typename value_type_impl< T >::type value_type
Definition: type_traits.h:280
auto end(Range &&range)
Definition: iterator_facade.h:322
auto constexpr thin_plate_spline_from_squared
Definition: thin_plate_spline.h:15
VecD< 3 > vec3d
Definition: vec_typedefs.h:51
axis_aligned_bounding_box< Real, NumDimensions > aabb
Definition: axis_aligned_bounding_box.h:553
VecD< 2 > vec2d
Definition: vec_typedefs.h:50
VecF< 4 > vec4f
Definition: vec_typedefs.h:41
constexpr auto approx_equal(T0 const &lhs, T1 const &rhs, common_type< tatooine::value_type< T0 >, tatooine::value_type< T1 > > eps=1e-6)
for comparison
Definition: tensor_utility.h:11
auto size(vec< ValueType, N > const &v)
Definition: vec.h:148
auto next(Iter iter)
Definition: iterator_facade.h:325
auto nan(const char *arg="")
Definition: nan.h:26
VecF< 2 > vec2f
Definition: vec_typedefs.h:39
Definition: axis_aligned_bounding_box.h:103
Definition: inverse_distance_weighting_sampler.h:10
Definition: moving_least_squares_samplerN.h:12
Definition: natural_neighbor_coordinates_sampler_with_gradients.h:19
Definition: natural_neighbor_coordinates_sampler.h:15
Definition: radial_basis_functions_sampler_with_gradients.h:100
Definition: radial_basis_functions_sampler.h:15
Definition: vertex_container.h:192
Definition: handle.h:14
auto index() const
Definition: handle.h:64
constexpr handle()
Definition: handle.h:24
Definition: mat.h:14
static constexpr auto invalid()
Definition: mesh.h:49
Definition: pointset.h:83
Definition: pointset.h:69
auto insert_vec2_vertex_property(std::string const &name, tatooine::vec2 const value=tatooine::vec2{}) -> auto &
Definition: pointset.h:605
auto vertex_properties() -> auto &
Definition: pointset.h:192
auto operator[](vertex_handle const v) -> auto &
Definition: pointset.h:223
auto operator=(pointset &&other) noexcept -> pointset &=default
auto mat2_vertex_property(std::string const &name) const -> auto const &
Definition: pointset.h:565
auto insert_vertex(pos_type const &v)
Definition: pointset.h:263
auto has_vertex_property(std::string const &name) const
Definition: pointset.h:194
auto build_kd_tree_index()
Definition: pointset.h:1013
auto scalar_vertex_property(std::string const &name) -> auto &
Definition: pointset.h:537
auto clear_vertices()
Definition: pointset.h:353
auto find_duplicates(Real eps=1e-6)
Definition: pointset.h:415
auto nearest_neighbors(pos_type const &x, std::size_t const num_nearest_neighbors) const
Definition: pointset.h:1074
auto insert_mat2_vertex_property(std::string const &name, tatooine::mat2 const value=tatooine::mat2{}) -> auto &
Definition: pointset.h:623
std::unique_ptr< flann_index_type > m_kd_tree
Definition: pointset.h:121
flann::Index< flann::L2< Real > > flann_index_type
Definition: pointset.h:80
auto write_vtp(filesystem::path const &path) const
Definition: pointset.h:720
pointset(std::initializer_list< pos_type > &&vertices)
Definition: pointset.h:129
auto scalar_vertex_property(std::string const &name) const -> auto const &
Definition: pointset.h:533
auto mat3_vertex_property(std::string const &name) -> auto &
Definition: pointset.h:577
auto insert_vertex_property(std::string const &name, T const &value=T{}) -> auto &
Definition: pointset.h:590
auto write_vtk(filesystem::path const &path, std::string const &title="Tatooine pointset") const -> void requires(NumDimensions==3||NumDimensions==2)
Definition: pointset.h:659
auto num_vertices() const
Definition: pointset.h:229
pointset< Real, NumDimensions > this_type
Definition: pointset.h:76
auto insert_vertex(arithmetic auto const ... ts)
Definition: pointset.h:243
auto nearest_neighbors_raw(pos_type const &x, std::size_t const num_nearest_neighbors, flann::SearchParams const params={}) const
Definition: pointset.h:1059
auto write_vertex_property_appended_data_vtp(auto const &prop, auto &file) const
Definition: pointset.h:918
auto operator=(pointset const &other) -> pointset &
Definition: pointset.h:168
auto vec4_vertex_property(std::string const &name) const -> auto const &
Definition: pointset.h:557
auto radial_basis_functions_sampler(typed_vertex_property_type< T > const &prop) const
Constructs a radial basis functions interpolator with thin plate spline kernel.
Definition: pointset.h:1253
auto moving_least_squares_sampler(typed_vertex_property_type< T > const &prop, Real const radius, invocable< real_type > auto &&weighting) const
Moving Least Squares Sampler.
Definition: pointset.h:1141
vertex_property_container_type m_vertex_properties
Definition: pointset.h:119
auto sample_to_vertex_property(F &&f, std::string const &name, execution_policy::sequential_t) -> auto &
Definition: pointset.h:369
auto vertices()
Definition: pointset.h:227
auto write(filesystem::path const &path) const
Definition: pointset.h:643
std::map< std::string, std::unique_ptr< vertex_property_type > > vertex_property_container_type
Definition: pointset.h:98
auto write_prop_vtk(vtk::legacy_file_writer &writer) const -> void
Definition: pointset.h:703
auto mat2_vertex_property(std::string const &name) -> auto &
Definition: pointset.h:569
auto at(vertex_handle const v) -> auto &
Definition: pointset.h:198
auto nearest_neighbors_radius_raw(pos_type const &x, Real const radius, flann::SearchParams const params={}) const -> std::pair< std::vector< int >, std::vector< Real > >
Definition: pointset.h:1088
auto radial_basis_functions_sampler_with_linear_kernel(typed_vertex_property_type< T > const &prop) const
Constructs a radial basis functions interpolator.
Definition: pointset.h:1191
auto vertex_property(std::string const &name) const -> const auto &
Definition: pointset.h:517
auto tidy_up()
tidies up invalid vertices
Definition: pointset.h:301
auto operator[](vertex_handle const v) const -> auto const &
Definition: pointset.h:224
auto at(vertex_handle const v) const -> auto const &
Definition: pointset.h:201
auto axis_aligned_bounding_box() const
Definition: pointset.h:183
auto mat3_vertex_property(std::string const &name) const -> auto const &
Definition: pointset.h:573
auto join(this_type const &other)
Definition: pointset.h:409
auto insert_scalar_vertex_property(std::string const &name, tatooine::real_number const value=tatooine::real_number{}) -> auto &
Definition: pointset.h:599
auto invalidate_kd_tree() const
Definition: pointset.h:1036
auto vertex_position_data() const -> auto const &
Definition: pointset.h:235
auto vec3_vertex_property(std::string const &name) const -> auto const &
Definition: pointset.h:549
auto read(filesystem::path const &p)
Definition: pointset.h:951
auto radial_basis_functions_sampler_with_gaussian_kernel(typed_vertex_property_type< T > const &prop, Real const epsilon) const
Constructs a radial basis functions interpolator.
Definition: pointset.h:1220
auto inverse_distance_weighting_sampler(typed_vertex_property_type< T > const &prop, Real const radius=1) const
Definition: pointset.h:1122
auto moving_least_squares_sampler(typed_vertex_property_type< T > const &prop, Real const radius) const
Moving Least Squares Sampler.
Definition: pointset.h:1163
auto radial_basis_functions_sampler(typed_vertex_property_type< T > const &prop, invocable< Real > auto &&f) const
Constructs a radial basis functions interpolator.
Definition: pointset.h:1244
auto vec2_vertex_property(std::string const &name) -> auto &
Definition: pointset.h:545
static constexpr auto num_dimensions() -> std::size_t
Definition: pointset.h:72
auto sample_to_vertex_property(F &&f, std::string const &name) -> auto &
Definition: pointset.h:363
auto write_vertex_property_data_array_vtp(auto const &name, auto const &prop, auto &file, auto offset) const -> std::size_t
Definition: pointset.h:880
auto radial_basis_functions_sampler_with_thin_plate_spline_kernel(typed_vertex_property_type< T > const &prop) const
Constructs a radial basis functions interpolator.
Definition: pointset.h:1234
auto insert_vertex(pos_type &&v)
Definition: pointset.h:281
pointset(pointset const &other)
Definition: pointset.h:147
auto nearest_neighbor(pos_type const &x) const
Definition: pointset.h:1041
auto invalid_vertices() const -> auto const &
Definition: pointset.h:239
std::set< vertex_handle > m_invalid_vertices
Definition: pointset.h:118
auto build_kd_tree() const -> auto &
Definition: pointset.h:1021
auto vertex_property(std::string const &name) -> auto &
using specified vertices of point_set
Definition: pointset.h:500
auto vec3_vertex_property(std::string const &name) -> auto &
Definition: pointset.h:553
pointset(std::vector< pos_type > &&vertices)
Definition: pointset.h:163
auto vertices() const
Definition: pointset.h:226
auto write_prop_vtk(vtk::legacy_file_writer &writer, std::string const &name, typed_vertex_property_type< T > const &prop) const -> void
Definition: pointset.h:697
vec< Real, NumDimensions > vec_type
Definition: pointset.h:77
std::mutex m_flann_mutex
Definition: pointset.h:122
auto radial_basis_functions_sampler(typed_vertex_property_type< ValueType > const &values, typed_vertex_property_type< GradientType > const &gradients) const
Constructs a radial basis functions interpolator that also takes the gradients of the property.
Definition: pointset.h:1264
constexpr auto is_valid(vertex_handle const v) const -> bool
Definition: pointset.h:347
auto natural_neighbor_coordinates_sampler(typed_vertex_property_type< T > const &prop) const
Definition: pointset.h:1276
auto clear()
Definition: pointset.h:360
Real real_type
Definition: pointset.h:75
auto vertex_at(vertex_handle const v) -> auto &
Definition: pointset.h:205
auto vec2_vertex_property(std::string const &name) const -> auto const &
Definition: pointset.h:541
auto nearest_neighbors_radius(pos_type const &x, Real const radius) const
Definition: pointset.h:1107
auto vertex_at(std::size_t const i) -> auto &
Definition: pointset.h:214
std::vector< pos_type > m_vertex_position_data
Definition: pointset.h:115
auto natural_neighbor_coordinates_sampler_with_gradients(typed_vertex_property_type< T > const &prop, typed_vertex_property_type< Gradient > const &gradients) const
Definition: pointset.h:1282
auto radial_basis_functions_sampler_with_cubic_kernel(typed_vertex_property_type< T > const &prop) const
Constructs a radial basis functions interpolator.
Definition: pointset.h:1205
auto vertex_at(vertex_handle const v) const -> auto const &
Definition: pointset.h:209
pointset(pointset &&other) noexcept
Definition: pointset.h:155
auto mat4_vertex_property(std::string const &name) -> auto &
Definition: pointset.h:585
pointset(filesystem::path const &path)
Definition: pointset.h:166
auto num_vertex_properties() const
Definition: pointset.h:233
auto insert_vec4_vertex_property(std::string const &name, tatooine::vec4 const value=tatooine::vec4{}) -> auto &
Definition: pointset.h:617
pointset(std::vector< pos_type > const &vertices)
Definition: pointset.h:160
auto insert_mat3_vertex_property(std::string const &name, tatooine::mat3 const value=tatooine::mat3{}) -> auto &
Definition: pointset.h:629
auto insert_mat4_vertex_property(std::string const &name, tatooine::mat4 const value=tatooine::mat4{}) -> auto &
Definition: pointset.h:635
auto insert_vec3_vertex_property(std::string const &name, tatooine::vec3 const value=tatooine::vec3{}) -> auto &
Definition: pointset.h:611
auto write_vertices_vtk(vtk::legacy_file_writer &writer) const
Definition: pointset.h:675
auto sample_to_vertex_property(F &&f, std::string const &name, execution_policy::parallel_t) -> auto &
Definition: pointset.h:389
auto read_vtp(filesystem::path const &path) -> void requires(NumDimensions==2)||(NumDimensions==3)
Definition: pointset.h:957
auto vertex_properties() const -> auto const &
Definition: pointset.h:191
auto vec4_vertex_property(std::string const &name) -> auto &
Definition: pointset.h:561
auto remove(vertex_handle const v)
Definition: pointset.h:332
auto mat4_vertex_property(std::string const &name) const -> auto const &
Definition: pointset.h:581
auto rebuild_kd_tree()
Definition: pointset.h:1009
auto vertex_at(std::size_t const i) const -> auto const &
Definition: pointset.h:218
Definition: property.h:66
Definition: property.h:16
Definition: reader.h:25