ViennaLS
Loading...
Searching...
No Matches
lsCalculateCurvatures.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <hrleCartesianPlaneIterator.hpp>
5#include <lsDomain.hpp>
6#include <lsExpand.hpp>
7
8#include <vcLogger.hpp>
9#include <vcSmartPointer.hpp>
10
11namespace viennals {
12
13using namespace viennacore;
14
20
21// Calculates the Mean Curvature and/or Gaussian Curvature (3D)
22// for the passed lsDomain for all points with level set values <= 0.5. The
23// result is saved in the lsDomain.
24template <class T, int D> class CalculateCurvatures {
25 SmartPointer<Domain<T, D>> levelSet = nullptr;
26 T maxValue = 0.5;
28
29public:
30 static constexpr char meanCurvatureLabel[] = "MeanCurvatures";
31 static constexpr char gaussianCurvatureLabel[] = "GaussianCurvatures";
32
34
35 CalculateCurvatures(SmartPointer<Domain<T, D>> passedLevelSet)
36 : levelSet(passedLevelSet) {}
37
38 CalculateCurvatures(SmartPointer<Domain<T, D>> passedLevelSet,
39 CurvatureEnum method)
40 : levelSet(passedLevelSet), type(method) {}
41
42 void setLevelSet(SmartPointer<Domain<T, D>> passedLevelSet) {
43 levelSet = passedLevelSet;
44 }
45
47 // in 2D there is only one option so ignore
48 if constexpr (D == 3) {
49 type = passedType;
50 } else {
51 if (passedType != type) {
52 VIENNACORE_LOG_WARNING(
53 "CalculateCurvatures: Could not set curvature type because 2D "
54 "only supports mean curvature.");
55 }
56 }
57 }
58
59 void setMaxValue(const T passedMaxValue) { maxValue = passedMaxValue; }
60
61 void apply() {
62 if (levelSet == nullptr) {
63 VIENNACORE_LOG_ERROR("No level set was passed to CalculateCurvatures.");
64 return;
65 }
66
67 // need second neighbours
68 if (unsigned minWidth = std::ceil((maxValue * 8) + 1);
69 levelSet->getLevelSetWidth() < minWidth) {
70 VIENNACORE_LOG_WARNING("CalculateCurvatures: Level set width must be "
71 "at least " +
72 std::to_string(minWidth) +
73 ". Expanding level set to " +
74 std::to_string(minWidth) + ".");
75 Expand<T, D>(levelSet, minWidth).apply();
76 }
77
78 std::vector<std::vector<T>> meanCurvaturesVector(
79 levelSet->getNumberOfSegments());
80 std::vector<std::vector<T>> gaussCurvaturesVector(
81 levelSet->getNumberOfSegments());
82
83 auto grid = levelSet->getGrid();
84 const bool calculateMean =
87 const bool calculateGauss =
90
92#pragma omp parallel num_threads(levelSet->getNumberOfSegments())
93 {
94 int p = 0;
95#ifdef _OPENMP
96 p = omp_get_thread_num();
97#endif
98
99 auto &meanCurvatures = meanCurvaturesVector[p];
100 auto &gaussCurvatures = gaussCurvaturesVector[p];
101
102 if (calculateMean) {
103 meanCurvatures.reserve(
104 levelSet->getDomain().getDomainSegment(p).getNumberOfPoints());
105 }
106 if (calculateGauss) {
107 gaussCurvatures.reserve(
108 levelSet->getDomain().getDomainSegment(p).getNumberOfPoints());
109 }
110
111 viennahrle::Index<D> const startVector =
112 (p == 0) ? grid.getMinGridPoint()
113 : levelSet->getDomain().getSegmentation()[p - 1];
114
115 viennahrle::Index<D> const endVector =
116 (p != static_cast<int>(levelSet->getNumberOfSegments() - 1))
117 ? levelSet->getDomain().getSegmentation()[p]
118 : grid.incrementIndices(grid.getMaxGridPoint());
119
120 for (viennahrle::CartesianPlaneIterator<typename Domain<T, D>::DomainType>
121 neighborIt(levelSet->getDomain(), startVector);
122 neighborIt.getIndices() < endVector; neighborIt.next()) {
123
124 auto &center = neighborIt.getCenter();
125 if (!center.isDefined()) {
126 continue;
127 } else if (std::abs(center.getValue()) > maxValue) {
128 if (calculateMean)
129 meanCurvatures.push_back(0.);
130 if (calculateGauss)
131 gaussCurvatures.push_back(0.);
132 continue;
133 }
134
135 // calculate curvatures
136 if (calculateMean) {
137 meanCurvatures.push_back(lsInternal::meanCurvature(neighborIt));
138 }
139 if (calculateGauss) {
140 gaussCurvatures.push_back(lsInternal::gaussianCurvature(neighborIt));
141 }
142 }
143 }
144
145 // put all curvature values in the correct ordering
146 if (calculateMean) {
147 unsigned numberOfCurvatures = 0;
148 for (unsigned i = 0; i < levelSet->getNumberOfSegments(); ++i) {
149 numberOfCurvatures += meanCurvaturesVector[i].size();
150 }
151 meanCurvaturesVector[0].reserve(numberOfCurvatures);
152
153 for (unsigned i = 1; i < levelSet->getNumberOfSegments(); ++i) {
154 meanCurvaturesVector[0].insert(meanCurvaturesVector[0].end(),
155 meanCurvaturesVector[i].begin(),
156 meanCurvaturesVector[i].end());
157 }
158 }
159
160 if (calculateGauss) {
161 unsigned numberOfCurvatures = 0;
162 for (unsigned i = 0; i < levelSet->getNumberOfSegments(); ++i) {
163 numberOfCurvatures += gaussCurvaturesVector[i].size();
164 }
165 gaussCurvaturesVector[0].reserve(numberOfCurvatures);
166
167 for (unsigned i = 1; i < levelSet->getNumberOfSegments(); ++i) {
168 gaussCurvaturesVector[0].insert(gaussCurvaturesVector[0].end(),
169 gaussCurvaturesVector[i].begin(),
170 gaussCurvaturesVector[i].end());
171 }
172 }
173
174 // insert into pointData of levelSet
175 if (calculateMean) {
176 auto &pointData = levelSet->getPointData();
177 auto scalarDataPointer =
178 pointData.getScalarData(meanCurvatureLabel, true);
179 // if it does not exist, insert new normals vector
180 if (scalarDataPointer == nullptr) {
181 pointData.insertNextScalarData(meanCurvaturesVector[0],
183 } else {
184 // if it does exist, just swap the old with the new values
185 *scalarDataPointer = std::move(meanCurvaturesVector[0]);
186 }
187 }
188
189 if (calculateGauss) {
190 auto &pointData = levelSet->getPointData();
191 auto scalarDataPointer =
192 pointData.getScalarData(gaussianCurvatureLabel, true);
193 // if it does not exist, insert new normals vector
194 if (scalarDataPointer == nullptr) {
195 pointData.insertNextScalarData(gaussCurvaturesVector[0],
197 } else {
198 // if it does exist, just swap the old with the new values
199 *scalarDataPointer = std::move(gaussCurvaturesVector[0]);
200 }
201 }
202 }
203};
204
205} // namespace viennals
constexpr int D
Definition Epitaxy.cpp:11
double T
Definition Epitaxy.cpp:12
void setCurvatureType(CurvatureEnum passedType)
Definition lsCalculateCurvatures.hpp:46
void setMaxValue(const T passedMaxValue)
Definition lsCalculateCurvatures.hpp:59
static constexpr char meanCurvatureLabel[]
Definition lsCalculateCurvatures.hpp:30
CalculateCurvatures(SmartPointer< Domain< T, D > > passedLevelSet, CurvatureEnum method)
Definition lsCalculateCurvatures.hpp:38
void apply()
Definition lsCalculateCurvatures.hpp:61
static constexpr char gaussianCurvatureLabel[]
Definition lsCalculateCurvatures.hpp:31
CalculateCurvatures(SmartPointer< Domain< T, D > > passedLevelSet)
Definition lsCalculateCurvatures.hpp:35
void setLevelSet(SmartPointer< Domain< T, D > > passedLevelSet)
Definition lsCalculateCurvatures.hpp:42
Class containing all information about the level set, including the dimensions of the domain,...
Definition lsDomain.hpp:27
viennahrle::Domain< T, D > DomainType
Definition lsDomain.hpp:32
Expands the levelSet to the specified number of layers. The largest value in the levelset is thus wid...
Definition lsExpand.hpp:17
void apply()
Apply the expansion to the specified width.
Definition lsExpand.hpp:44
T gaussianCurvature(It &it, bool bigStencil=false)
Calculates the Gaussian Curvature of the level set function from a suitable hrle iterator....
Definition lsCurvatureFormulas.hpp:181
T meanCurvature(It &it, bool bigStencil=false)
Calculates the Mean Curvature of the level set function from a suitable hrle iterator....
Definition lsCurvatureFormulas.hpp:161
Definition lsAdvect.hpp:37
CurvatureEnum
Definition lsCalculateCurvatures.hpp:15
@ GAUSSIAN_CURVATURE
Definition lsCalculateCurvatures.hpp:17
@ MEAN_AND_GAUSSIAN_CURVATURE
Definition lsCalculateCurvatures.hpp:18
@ MEAN_CURVATURE
Definition lsCalculateCurvatures.hpp:16