91 std::string
const& name,
bool const on_top,
92 bool const copy_material_ids,
93 std::optional<int>
const layer_id)
95 INFO(
"Extracting top surface of mesh '{:s}' ... ", mesh.
getName());
96 double const flag = on_top ? -1.0 : 1.0;
97 Eigen::Vector3d
const dir({0, 0, flag});
98 double const angle(90);
99 std::unique_ptr<MeshLib::Mesh> sfc_mesh(
nullptr);
101 auto const prop_name =
107 mesh, dir, angle, prop_name));
111 sfc_mesh = (on_top) ? std::make_unique<MeshLib::Mesh>(mesh)
112 : std::unique_ptr<MeshLib::Mesh>(
116 sfc_mesh->getProperties().createNewPropertyVector<std::size_t>(
118 sfc_mesh->getNumberOfNodes(), 1);
121 pv->assign(ranges::views::iota(0u, sfc_mesh->getNumberOfNodes()));
125 ERR(
"Could not create and initialize property '{}'.", prop_name);
132 std::vector<MeshLib::Node*> subsfc_nodes =
134 std::vector<MeshLib::Element*> subsfc_elements =
137 std::size_t
const n_subsfc_nodes(subsfc_nodes.size());
139 std::vector<MeshLib::Node*>
const& sfc_nodes(sfc_mesh->getNodes());
140 std::size_t
const n_sfc_nodes(sfc_nodes.size());
142 if (!sfc_mesh->getProperties().existsPropertyVector<std::size_t>(prop_name))
144 ERR(
"Need subsurface node ids, but the property '{:s}' is not "
150 auto const*
const node_id_pv =
151 sfc_mesh->getProperties().getPropertyVector<std::size_t>(prop_name);
154 std::map<std::size_t, std::size_t> subsfc_sfc_id_map;
155 for (std::size_t k(0); k < n_sfc_nodes; ++k)
157 std::size_t
const subsfc_id((*node_id_pv)[k]);
158 std::size_t
const sfc_id(k + n_subsfc_nodes);
159 subsfc_sfc_id_map.insert(std::make_pair(subsfc_id, sfc_id));
162 node[0], node[1], node[2] - (flag * thickness), sfc_id));
166 std::vector<MeshLib::Element*>
const& sfc_elements(sfc_mesh->getElements());
167 std::size_t
const n_sfc_elements(sfc_elements.size());
168 for (std::size_t k(0); k < n_sfc_elements; ++k)
171 subsfc_nodes, *sfc_elements[k], *node_id_pv, subsfc_sfc_id_map));
174 auto new_mesh =
new MeshLib::Mesh(name, subsfc_nodes, subsfc_elements,
179 ERR(
"Could not copy the property 'MaterialIDs' since the original mesh "
180 "does not contain such a property.");
183 auto const*
const materials =
186 auto*
const new_materials =
187 new_mesh->getProperties().createNewPropertyVector<
int>(
191 ERR(
"Can not set material properties for new layer");
195 int next_material_id = 0;
197 if (materials !=
nullptr)
199 next_material_id = *ranges::max_element(*materials) + 1;
202 auto initial_values =
203 materials ? ranges::any_view<int const>{*materials}
204 : ranges::views::repeat_n(layer_id.value_or(next_material_id),
207 auto additional_values = [&]() -> ranges::any_view<int const>
209 if (copy_material_ids &&
210 sfc_mesh->getProperties().existsPropertyVector<
int>(
"MaterialIDs"))
212 return ranges::any_view<int const>{
213 *sfc_mesh->getProperties().getPropertyVector<
int>(
218 int const new_layer_id = layer_id.value_or(next_material_id);
219 auto const n_new_props =
221 return ranges::views::repeat_n(new_layer_id, n_new_props);
225 new_materials->assign(ranges::views::common(
226 ranges::views::concat(initial_values, additional_values)));