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