2#include <wmtk/SurfaceTagAttributes.h>
6#include <wmtk/io/ComponentIO.hpp>
7#include <wmtk/io/DataWriter.hpp>
10inline MeshData geometry_data(
const MatrixXd& V,
const MatrixXi& C, CellType type)
13 data.V = DataMatrix<double>::Zero(V.rows(), 3);
14 data.V.leftCols(V.cols()) = V;
15 data.cells[type].connectivity = C.cast<int64_t>();
19template <
typename Vertex,
typename Cell>
21geometry_data(
const std::vector<Vertex>& vertices,
const std::vector<Cell>& cells, CellType type)
24 data.V = DataMatrix<double>::Zero(vertices.size(), 3);
25 for (
size_t i = 0; i < vertices.size(); ++i)
26 for (
int j = 0; j < vertices[i].size(); ++j) data.V(i, j) = vertices[i][j];
27 auto& C = data.cells[type].connectivity;
28 C.resize(cells.size(), cell_size(type));
29 for (
size_t i = 0; i < cells.size(); ++i)
30 for (
int j = 0; j < C.cols(); ++j) C(i, j) = cells[i][j];
34template <
typename Po
int>
36 const std::vector<std::array<Point, 2>>& segments,
37 const std::vector<Point>& anchors)
39 std::map<std::array<double, 3>, int64_t> rows;
41 std::vector<std::array<double, 3>> vertices;
42 auto vertex = [&](
const Point& p) {
43 std::array<double, 3> key{{0, 0, 0}};
44 for (
int i = 0; i < p.size(); ++i) key[i] = p[i];
45 auto [it, added] = rows.emplace(key, rows.size());
46 if (added) vertices.push_back(key);
49 auto& E = data.cells[CellType::Edge].connectivity;
50 E.resize(segments.size(), 2);
51 for (
size_t i = 0; i < segments.size(); ++i) {
52 E(i, 0) = vertex(segments[i][0]);
53 E(i, 1) = vertex(segments[i][1]);
55 auto& P = data.cells[CellType::Point].connectivity;
56 P.resize(anchors.size(), 1);
57 for (
size_t i = 0; i < anchors.size(); ++i) P(i, 0) = vertex(anchors[i]);
58 data.V.resize(vertices.size(), 3);
59 for (
size_t i = 0; i < vertices.size(); ++i)
60 for (
int j = 0; j < 3; ++j) data.V(i, j) = vertices[i][j];
64template <
typename Mesh,
typename TupleRange,
typename Tags>
65void collect_tags(Mesh& mesh, MeshMap& outputs, CellType type,
const TupleRange& cells, Tags tags)
68 auto& block = outputs.at(
"mesh").cells[type];
69 if (block.connectivity.cols() != cell_size(type)) block.connectivity.resize(0, cell_size(type));
72 std::set<std::string> named, labelled;
73 for (
const auto& [
id, name] : mesh.m_tag_id_to_name) named.insert(name);
74 std::vector<std::string> labels;
75 for (
size_t j = 0; j < mesh.m_tags_count; ++j) {
76 const auto it = mesh.m_tag_id_to_name.find(j);
77 const bool unnamed = it == mesh.m_tag_id_to_name.end();
78 std::string label = unnamed ?
"tag_" + std::to_string(j) : it->second;
79 while (labelled.count(label) || (unnamed && named.count(label))) label +=
"_";
80 labelled.insert(label);
81 labels.push_back(label);
83 DataMatrix<uint8_t> values = DataMatrix<uint8_t>::Zero(cells.size(), labels.size());
84 for (
size_t i = 0; i < cells.size(); ++i)
85 for (
size_t j = 0; j < labels.size(); ++j) values(i, j) = tags(cells[i]).count(j) ? 1 : 0;
87 for (
size_t j = 0; j < labels.size(); ++j) {
88 block.attributes.erase(labels[j]);
89 block.attributes.erase(
"tag_" + std::to_string(j));
93 if (std::find(labels.begin(), labels.end(),
"ambient") == labels.end()) {
94 const auto empty = (values.template cast<int>().rowwise().sum().array() == 0).eval();
95 if (labels.empty() || empty.any()) {
96 values.conservativeResize(Eigen::NoChange, values.cols() + 1);
97 values.col(values.cols() - 1) = empty.template cast<uint8_t>();
98 labels.push_back(
"ambient");
101 block.attributes[
"tags"] = {std::move(values), std::move(labels)};
107template <
typename Mesh>
108void collect_face_tags(
const Mesh& mesh, MeshMap& outputs,
const std::vector<std::string>& names)
110 if (names.empty())
return;
111 std::vector<int64_t> row(mesh.vert_capacity(), -1);
113 for (
const auto& v : mesh.get_vertices()) row[v.vid(mesh)] = n++;
114 std::vector<std::array<int64_t, 3>> faces;
115 std::vector<InputSet> sets;
118 : (InputSet(1) << names.size()) - 1;
119 for (
const auto& f : mesh.get_faces()) {
120 const auto& attr = mesh.m_face_attribute[f.fid(mesh)];
122 const InputSet set = attr.input_set() & mask;
123 if (set == 0)
continue;
124 auto vids = mesh.get_face_vids(f);
125 std::sort(vids.begin(), vids.end());
126 if (attr.orientation_along(vids) < 0) std::swap(vids[1], vids[2]);
127 faces.push_back({{row[vids[0]], row[vids[1]], row[vids[2]]}});
130 auto& block = outputs.at(
"mesh").cells[CellType::Triangle];
131 block.connectivity.resize(faces.size(), 3);
132 DataMatrix<uint8_t> member = DataMatrix<uint8_t>::Zero(faces.size(), names.size());
133 for (
size_t i = 0; i < faces.size(); ++i) {
134 for (
int k = 0; k < 3; ++k) block.connectivity(i, k) = faces[i][k];
135 for (
size_t j = 0; j < names.size(); ++j) member(i, j) = (sets[i] >> j) & 1;
137 block.attributes[
"tags"] = {std::move(member), names};
static constexpr int max_inputs
One input per bit of InputSet: the width is set there, and only there.
Definition SurfaceTagAttributes.h:130