2#include <kernel/geometry/mesh_part.hpp>
3#include <kernel/geometry/atlas/bezier.hpp>
4#include <kernel/adjacency/graph.hpp>
7namespace FEAT::Geometry::Intern
10 template<
typename Shape_>
21 static std::unique_ptr<Atlas::ChartBase<MeshType>> meshpart_to_bezier(
const MeshType& mesh,
const MeshPartType& meshpart)
24 if constexpr(dim == 2)
27 const auto& edge_to_vert = mesh.template get_index_set<1, 0>();
28 const auto& face_to_edge = mesh.template get_index_set<2, 1>();
29 const auto& face_to_vert = mesh.template get_index_set<2, 0>();
33 const auto& target_set = meshpart.template get_target_set<1>();
36 std::for_each(is_target.begin(), is_target.end(), [](
Index& a){a = Index(0);});
37 for(
Index k = 0; k < target_set.get_num_entities(); ++k)
39 is_target[target_set[k]] =
Index(1);
42 XASSERTM(target_set.get_num_entities() > 0u,
"Trying to create bezier chart from non 1d meshpart");
44 std::vector<Tiny::Vector<DataType, dim>> vtx_line;
45 vtx_line.reserve(target_set.get_num_entities()+1);
47 bool not_closed =
false;
48 Index cur_edge = target_set[0];
53 for(
int k = 0; k < edge_to_vert.get_num_indices(); ++k)
55 Index cur_vert = edge_to_vert[target_set[0]][k];
56 bool is_boundary =
true;
57 for(
Index l = dom_ptr[cur_vert]; l < dom_ptr[cur_vert+1]; ++l)
59 if(img_ptr[l] != cur_edge && is_target[img_ptr[l]] ==
Index(1))
69 if(prev_vert == ~
Index(0))
71 prev_vert = edge_to_vert[target_set[0]][0];
74 const Index start_edge = target_set[0];
75 vtx_line.push_back(vtx_set[prev_vert]);
84 for(
int k = 0; k < edge_to_vert.get_num_indices(); ++k)
86 if(edge_to_vert[cur_edge][k] != prev_vert)
88 cur_vert = edge_to_vert[cur_edge][k];
93 vtx_line.push_back(vtx_set[cur_vert]);
96 if(orientation != ~
Index(0))
99 auto mid_e = DataType(0.5) * (vtx_set[cur_vert] + vtx_set[prev_vert]);
107 if(orientation != ~
Index(0))
111 for(
int k = 0; k < index_tuple.num_indices; ++k)
113 mid_c.axpy(DataType(1)/DataType(index_tuple.num_indices), vtx_set[index_tuple[k]]);
116 const auto outer_normal = mid_e - mid_c;
117 const auto line_segment = vtx_set[cur_vert] - vtx_set[prev_vert];
124 if(orientation ==
Index(2)) orientation = new_orient;
125 XASSERTM(orientation == new_orient,
"Non orientable");
132 for(
Index l = dom_ptr[cur_vert]; l < dom_ptr[cur_vert+1]; ++l)
134 if(img_ptr[l] != cur_edge && is_target[img_ptr[l]] ==
Index(1))
136 next_edge = img_ptr[l];
140 if(next_edge == ~
Index(0))
146 if(next_edge == start_edge)
151 cur_edge = next_edge;
152 prev_vert = cur_vert;
155 std::unique_ptr<Atlas::Bezier<MeshType>> bezier = std::make_unique<Atlas::Bezier<MeshType>>(!not_closed, orientation ==
Index(0) ? 1 : -1);
156 for(
Index k = 0; k < vtx_line.size(); ++k)
158 bezier->push_vertex(vtx_line[k]);
167 XABORTM(
"Bezier chart only valid in 2d");
170 return std::unique_ptr<Atlas::ChartBase<MeshType>>{
nullptr};
#define XABORTM(msg)
Abortion macro definition with custom message.
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Adjacency Graph implementation.
Index * get_domain_ptr()
Returns the domain pointer array.
Index * get_image_idx()
Returns the image node index array.
Index degree(Index domain_node) const
Returns the degree of a domain node.
Class template for partial meshes.
Tiny Vector class template.
@ injectify_transpose
Render-Injectified-Transpose mode.
CUDA_HOST_DEVICE T_ dot(const T_ &a, const T_ &b)
Computes the dot-product of two scalars.
std::uint64_t Index
Index data type.