16#include <lagrange/Mesh.h>
17#include <lagrange/MeshTrait.h>
18#include <lagrange/attributes/condense_indexed_attribute.h>
19#include <lagrange/common.h>
20#include <lagrange/compute_vertex_valence.h>
21#include <lagrange/legacy/inline.h>
22#include <lagrange/utils/assert.h>
23#include <lagrange/utils/range.h>
28template <
typename MeshType>
29void map_vertex_attribute_to_corner_attribute(
MeshType& mesh,
const std::string& attr_name)
31 static_assert(MeshTrait<MeshType>::is_mesh(),
"MeshType is not a mesh");
33 using Index =
typename MeshType::Index;
36 const Index num_facets = mesh.get_num_facets();
37 const Index vertex_per_facet = mesh.get_vertex_per_facet();
39 const auto& facets = mesh.get_facets();
40 auto vertex_attr = mesh.get_vertex_attribute_array(attr_name);
42 auto map_fn = [&](Eigen::Index ci, std::vector<std::pair<Eigen::Index, double>>& weights) {
45 safe_cast<Eigen::Index>(facets(ci / vertex_per_facet, ci % vertex_per_facet)),
48 auto corner_attr =
to_shared_ptr(vertex_attr->row_slice(num_facets * vertex_per_facet, map_fn));
50 if (!mesh.has_corner_attribute(attr_name)) {
51 mesh.add_corner_attribute(attr_name);
53 mesh.set_corner_attribute_array(attr_name, std::move(corner_attr));
56template <
typename MeshType>
57void map_facet_attribute_to_corner_attribute(
MeshType& mesh,
const std::string& attr_name)
59 static_assert(MeshTrait<MeshType>::is_mesh(),
"MeshType is not a mesh");
61 using Index =
typename MeshType::Index;
64 const Index num_facets = mesh.get_num_facets();
65 const Index vertex_per_facet = mesh.get_vertex_per_facet();
67 auto facet_attr = mesh.get_facet_attribute_array(attr_name);
69 auto map_fn = [&](Eigen::Index ci, std::vector<std::pair<Eigen::Index, double>>& weights) {
71 weights.emplace_back(safe_cast<Eigen::Index>(ci / vertex_per_facet), 1.0);
73 auto corner_attr =
to_shared_ptr(facet_attr->row_slice(num_facets * vertex_per_facet, map_fn));
75 if (!mesh.has_corner_attribute(attr_name)) {
76 mesh.add_corner_attribute(attr_name);
78 mesh.set_corner_attribute_array(attr_name, std::move(corner_attr));
81template <
typename MeshType>
82void map_corner_attribute_to_vertex_attribute(
MeshType& mesh,
const std::string& attr_name)
84 static_assert(MeshTrait<MeshType>::is_mesh(),
"MeshType is not a mesh");
86 using Index =
typename MeshType::Index;
89 const Index num_vertices = mesh.get_num_vertices();
90 const Index num_facets = mesh.get_num_facets();
91 const Index vertex_per_facet = mesh.get_vertex_per_facet();
93 const auto& facets = mesh.get_facets();
94 auto corner_attr = mesh.get_corner_attribute_array(attr_name);
96 if (!mesh.has_vertex_attribute(
"valence")) {
99 const auto& valence = mesh.get_vertex_attribute(
"valence");
102 std::vector<std::vector<std::pair<Eigen::Index, double>>> weights(num_vertices);
103 for (Index i = 0; i < num_facets; i++) {
104 for (Index j = 0; j < vertex_per_facet; j++) {
105 const double w = 1.0 / valence(facets(i, j), 0);
106 weights[facets(i, j)].emplace_back(i * vertex_per_facet + j, w);
110 auto mapping_fn = [&](Eigen::Index i, std::vector<std::pair<Eigen::Index, double>>& wts) {
114 auto vertex_attr =
to_shared_ptr(corner_attr->row_slice(num_vertices, mapping_fn));
116 if (!mesh.has_vertex_attribute(attr_name)) {
117 mesh.add_vertex_attribute(attr_name);
119 mesh.set_vertex_attribute_array(attr_name, std::move(vertex_attr));
122template <
typename MeshType>
123void map_corner_attribute_to_facet_attribute(
MeshType& mesh,
const std::string& attr_name)
125 static_assert(MeshTrait<MeshType>::is_mesh(),
"MeshType is not a mesh");
127 using Index =
typename MeshType::Index;
130 const Index num_facets = mesh.get_num_facets();
131 const Index vertex_per_facet = mesh.get_vertex_per_facet();
133 auto corner_attr = mesh.get_corner_attribute_array(attr_name);
135 auto mapping_fn = [&](Eigen::Index i, std::vector<std::pair<Eigen::Index, double>>& weights) {
137 for (
auto j :
range(vertex_per_facet)) {
138 weights.emplace_back(i * vertex_per_facet + j, 1.0 / vertex_per_facet);
142 auto facet_attr = corner_attr->row_slice(num_facets, mapping_fn);
144 if (!mesh.has_facet_attribute(attr_name)) {
145 mesh.add_facet_attribute(attr_name);
147 mesh.set_facet_attribute_array(attr_name, std::move(facet_attr));
150template <
typename MeshType>
151void map_vertex_attribute_to_indexed_attribute(
MeshType& mesh,
const std::string& attr_name)
153 static_assert(MeshTrait<MeshType>::is_mesh(),
"MeshType is not a mesh");
157 const auto& attr_values = mesh.get_vertex_attribute(attr_name);
158 const auto& attr_indices = mesh.get_facets();
160 if (!mesh.has_indexed_attribute(attr_name)) {
161 mesh.add_indexed_attribute(attr_name);
163 mesh.set_indexed_attribute(attr_name, attr_values, attr_indices);
164 condense_indexed_attribute(mesh, attr_name);
167template <
typename MeshType>
168void map_facet_attribute_to_indexed_attribute(
MeshType& mesh,
const std::string& attr_name)
170 static_assert(MeshTrait<MeshType>::is_mesh(),
"MeshType is not a mesh");
172 using IndexArray =
typename MeshType::IndexArray;
175 const auto num_facets = mesh.get_num_facets();
176 const auto vertex_per_facet = mesh.get_vertex_per_facet();
177 auto attr_values = mesh.get_facet_attribute(attr_name);
178 IndexArray attr_indices(num_facets, vertex_per_facet);
179 for (
auto i :
range(num_facets)) {
180 attr_indices.row(i).setConstant(i);
183 if (!mesh.has_indexed_attribute(attr_name)) {
184 mesh.add_indexed_attribute(attr_name);
186 mesh.import_indexed_attribute(attr_name, attr_values, attr_indices);
187 condense_indexed_attribute(mesh, attr_name);
190template <
typename MeshType>
191void map_corner_attribute_to_indexed_attribute(
MeshType& mesh,
const std::string& attr_name)
193 static_assert(MeshTrait<MeshType>::is_mesh(),
"MeshType is not a mesh");
195 using IndexArray =
typename MeshType::IndexArray;
198 const auto num_facets = mesh.get_num_facets();
199 const auto vertex_per_facet = mesh.get_vertex_per_facet();
200 auto attr_values = mesh.get_corner_attribute(attr_name);
201 IndexArray attr_indices(num_facets, vertex_per_facet);
202 for (
auto i :
range(num_facets)) {
203 for (
auto j :
range(vertex_per_facet)) {
204 attr_indices(i, j) = i * vertex_per_facet + j;
208 if (!mesh.has_indexed_attribute(attr_name)) {
209 mesh.add_indexed_attribute(attr_name);
211 mesh.import_indexed_attribute(attr_name, attr_values, attr_indices);
212 condense_indexed_attribute(mesh, attr_name);
215template <
typename MeshType>
216void map_indexed_attribute_to_vertex_attribute(
MeshType& mesh,
const std::string& attr_name)
218 static_assert(MeshTrait<MeshType>::is_mesh(),
"MeshType is not a mesh");
221 using AttributeArray =
typename MeshType::AttributeArray;
222 using Scalar =
typename MeshType::Scalar;
224 const auto entry = mesh.get_indexed_attribute(attr_name);
225 const auto& attr_values = std::get<0>(entry);
226 const auto& attr_indices = std::get<1>(entry);
228 const auto num_vertices = mesh.get_num_vertices();
229 const auto num_facets = mesh.get_num_facets();
230 const auto vertex_per_facet = mesh.get_vertex_per_facet();
231 const auto& facets = mesh.get_facets();
232 AttributeArray vertex_attr(num_vertices, attr_values.cols());
233 vertex_attr.setZero();
234 Eigen::Matrix<Scalar, Eigen::Dynamic, 1> valence(num_vertices);
236 for (
auto i :
range(num_facets)) {
237 for (
auto j :
range(vertex_per_facet)) {
238 vertex_attr.row(facets(i, j)) += attr_values.row(attr_indices(i, j));
239 valence[facets(i, j)] += 1;
242 vertex_attr.array().colwise() /= valence.array();
244 if (!mesh.has_vertex_attribute(attr_name)) {
245 mesh.add_vertex_attribute(attr_name);
247 mesh.import_vertex_attribute(attr_name, vertex_attr);
250template <
typename MeshType>
251void map_indexed_attribute_to_facet_attribute(
MeshType& mesh,
const std::string& attr_name)
253 static_assert(MeshTrait<MeshType>::is_mesh(),
"MeshType is not a mesh");
256 using AttributeArray =
typename MeshType::AttributeArray;
258 const auto entry = mesh.get_indexed_attribute(attr_name);
259 const auto& attr_values = std::get<0>(entry);
260 const auto& attr_indices = std::get<1>(entry);
262 const auto num_facets = mesh.get_num_facets();
263 const auto vertex_per_facet = mesh.get_vertex_per_facet();
264 AttributeArray facet_attr(num_facets, attr_values.cols());
265 facet_attr.setZero();
266 for (
auto i :
range(num_facets)) {
267 for (
auto j :
range(vertex_per_facet)) {
268 facet_attr.row(i) += attr_values.row(attr_indices(i, j)) / vertex_per_facet;
272 if (!mesh.has_facet_attribute(attr_name)) {
273 mesh.add_facet_attribute(attr_name);
275 mesh.import_facet_attribute(attr_name, facet_attr);
278template <
typename MeshType>
279void map_indexed_attribute_to_corner_attribute(
MeshType& mesh,
const std::string& attr_name)
281 static_assert(MeshTrait<MeshType>::is_mesh(),
"MeshType is not a mesh");
284 using AttributeArray =
typename MeshType::AttributeArray;
285 using Index =
typename MeshType::Index;
287 const auto entry = mesh.get_indexed_attribute(attr_name);
288 const auto& attr_values = std::get<0>(entry);
289 const auto& attr_indices = std::get<1>(entry);
291 const auto num_facets = mesh.get_num_facets();
292 const auto vertex_per_facet = mesh.get_vertex_per_facet();
293 AttributeArray corner_attr(num_facets * vertex_per_facet, attr_values.cols());
294 corner_attr.setZero();
295 for (
auto i :
range(num_facets)) {
296 for (
auto j :
range(vertex_per_facet)) {
297 if (attr_indices(i, j) != invalid<Index>()) {
298 corner_attr.row(i * vertex_per_facet + j) = attr_values.row(attr_indices(i, j));
303 if (!mesh.has_corner_attribute(attr_name)) {
304 mesh.add_corner_attribute(attr_name);
306 mesh.import_corner_attribute(attr_name, corner_attr);
AttributeId compute_vertex_valence(SurfaceMesh< Scalar, Index > &mesh, VertexValenceOptions options={})
Compute vertex valence.
Definition: compute_vertex_valence.cpp:25
#define la_runtime_assert(...)
Runtime assertion check.
Definition: assert.h:169
internal::Range< Index > range(Index end)
Returns an iterable object representing the range [0, end).
Definition: range.h:176
Main namespace for Lagrange.
Definition: AABBIGL.h:30
std::shared_ptr< T > to_shared_ptr(std::unique_ptr< T > &&ptr)
Helper for automatic type deduction for unique_ptr to shared_ptr conversion.
Definition: common.h:88