Lagrange
eval_as_attribute.h
1/*
2 * Copyright 2020 Adobe. All rights reserved.
3 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may obtain a copy
5 * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software distributed under
8 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 * OF ANY KIND, either express or implied. See the License for the specific language
10 * governing permissions and limitations under the License.
11 */
12#pragma once
13
14#include <lagrange/Mesh.h>
15#include <lagrange/MeshTrait.h>
16#include <lagrange/legacy/inline.h>
17#include <lagrange/utils/range.h>
18#include <tbb/parallel_for.h>
19
20#include <functional>
21#include <string>
22
27namespace lagrange {
28LAGRANGE_LEGACY_INLINE
29namespace legacy {
30
31template <typename MeshType>
32void eval_as_vertex_attribute(
33 MeshType& mesh,
34 const std::string& attribute_name,
35 const std::function<typename MeshType::Scalar(typename MeshType::Index v_idx)>& func,
36 bool parallel = true)
37{
38 static_assert(MeshTrait<MeshType>::is_mesh(), "Input type is not Mesh");
39
40 using AttributeArray = typename MeshType::AttributeArray;
41 using Index = typename MeshType::Index;
42
43 const auto num_vertices = mesh.get_num_vertices();
44 AttributeArray attr(num_vertices, 1);
45
46 if (parallel) {
47 tbb::parallel_for(
48 tbb::blocked_range<Index>(0, num_vertices),
49 [&](const tbb::blocked_range<Index>& tbb_range) {
50 for (auto v_idx = tbb_range.begin(); v_idx != tbb_range.end(); ++v_idx) {
51 attr(v_idx, 0) = func(v_idx);
52 };
53 });
54 } else {
55 for (auto v_idx : range(num_vertices)) {
56 attr(v_idx, 0) = func(v_idx);
57 }
58 }
59 if (!mesh.has_vertex_attribute(attribute_name)) {
60 mesh.add_vertex_attribute(attribute_name);
61 }
62 mesh.import_vertex_attribute(attribute_name, attr);
63}
64
65template <typename MeshType>
66void eval_as_vertex_attribute(
67 MeshType& mesh,
68 const std::string& attribute_name,
69 const std::function<typename MeshType::Scalar(const typename MeshType::VertexType& V)>& func,
70 bool parallel = true)
71{
72 static_assert(MeshTrait<MeshType>::is_mesh(), "Input type is not Mesh");
73
74 using Index = typename MeshType::Index;
75
76 const auto& V = mesh.get_vertices();
77 return eval_as_vertex_attribute(
78 mesh,
79 attribute_name,
80 [&V, &func](Index v_idx) { return func(V.row(v_idx)); },
81 parallel);
82}
83
84template <typename MeshType>
85void eval_as_vertex_attribute(
86 MeshType& mesh,
87 const std::string& attribute_name,
88 const std::function<typename MeshType::Scalar(
89 typename MeshType::Scalar x,
90 typename MeshType::Scalar y,
91 typename MeshType::Scalar z)>& func,
92 bool parallel = true)
93{
94 static_assert(MeshTrait<MeshType>::is_mesh(), "Input type is not Mesh");
95
96 using Index = typename MeshType::Index;
97
98 const auto& V = mesh.get_vertices();
99 return eval_as_vertex_attribute(
100 mesh,
101 attribute_name,
102 [&V, &func](Index v_idx) { return func(V(v_idx, 0), V(v_idx, 1), V(v_idx, 2)); },
103 parallel);
104}
105
106template <typename MeshType>
107void eval_as_facet_attribute(
108 MeshType& mesh,
109 const std::string& attribute_name,
110 const std::function<typename MeshType::Scalar(typename MeshType::Index f_idx)>& func,
111 bool parallel = true)
112{
113 static_assert(MeshTrait<MeshType>::is_mesh(), "Input type is not Mesh");
114
115 using AttributeArray = typename MeshType::AttributeArray;
116 using Index = typename MeshType::Index;
117
118 const auto num_facets = mesh.get_num_facets();
119 AttributeArray attr(num_facets, 1);
120
121 if (parallel) {
122 tbb::parallel_for(
123 tbb::blocked_range<Index>(0, num_facets),
124 [&](const tbb::blocked_range<Index>& tbb_range) {
125 for (auto f_idx = tbb_range.begin(); f_idx != tbb_range.end(); ++f_idx) {
126 attr(f_idx, 0) = func(f_idx);
127 };
128 });
129 } else {
130 for (auto f_idx : range(num_facets)) {
131 attr(f_idx, 0) = func(f_idx);
132 }
133 }
134
135 if (!mesh.has_facet_attribute(attribute_name)) {
136 mesh.add_facet_attribute(attribute_name);
137 }
138 mesh.import_facet_attribute(attribute_name, attr);
139}
140
141template <typename MeshType>
142void eval_as_edge_attribute_new(
143 MeshType& mesh,
144 const std::string& attribute_name,
145 const std::function<typename MeshType::Scalar(typename MeshType::Index e_idx)>& func,
146 bool parallel = true)
147{
148 static_assert(MeshTrait<MeshType>::is_mesh(), "Input type is not Mesh");
149
150 using AttributeArray = typename MeshType::AttributeArray;
151 using Index = typename MeshType::Index;
152
153 const auto num_edges = mesh.get_num_edges();
154 AttributeArray attr(num_edges, 1);
155
156 if (parallel) {
157 tbb::parallel_for(
158 tbb::blocked_range<Index>(0, num_edges),
159 [&](const tbb::blocked_range<Index>& tbb_range) {
160 for (auto e_idx = tbb_range.begin(); e_idx != tbb_range.end(); ++e_idx) {
161 attr(e_idx, 0) = func(e_idx);
162 };
163 });
164 } else {
165 for (auto e_idx : range(num_edges)) {
166 attr(e_idx, 0) = func(e_idx);
167 }
168 }
169
170 if (!mesh.has_edge_attribute(attribute_name)) {
171 mesh.add_edge_attribute(attribute_name);
172 }
173 mesh.import_edge_attribute(attribute_name, attr);
174}
175
176} // namespace legacy
177} // namespace lagrange
Definition: Mesh.h:48
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