83 if (levelSet ==
nullptr) {
85 .addError(
"No level set was passed to CalculateNormalVectors.")
90 if (levelSet->getLevelSetWidth() < (maxValue * 4) + 1) {
92 .addWarning(
"CalculateNormalVectors: Level set width must be "
94 std::to_string((maxValue * 4) + 1) +
95 ". Expanding level set to " +
96 std::to_string((maxValue * 4) + 1) +
".")
101 std::vector<std::vector<Vec3D<T>>> normalVectorsVector(
102 levelSet->getNumberOfSegments());
105 double pointsPerSegment =
106 double(2 * levelSet->getDomain().getNumberOfPoints()) /
107 double(levelSet->getLevelSetWidth());
109 auto grid = levelSet->getGrid();
112#pragma omp parallel num_threads(levelSet->getNumberOfSegments())
116 p = omp_get_thread_num();
119 auto &normalVectors = normalVectorsVector[p];
120 normalVectors.reserve(pointsPerSegment);
122 viennahrle::Index<D>
const startVector =
123 (p == 0) ? grid.getMinGridPoint()
124 : levelSet->getDomain().getSegmentation()[p - 1];
126 viennahrle::Index<D>
const endVector =
127 (p !=
static_cast<int>(levelSet->getNumberOfSegments() - 1))
128 ? levelSet->getDomain().getSegmentation()[p]
129 : grid.incrementIndices(grid.getMaxGridPoint());
131 for (viennahrle::ConstSparseStarIterator<
133 neighborIt(levelSet->getDomain(), startVector);
134 neighborIt.getIndices() < endVector; neighborIt.next()) {
136 auto ¢er = neighborIt.getCenter();
137 if (!center.isDefined()) {
139 }
else if (std::abs(center.getValue()) > maxValue) {
142 normalVectors.push_back(tmp);
149 for (
int i = 0; i <
D; i++) {
150 T pos = neighborIt.getNeighbor(i).getValue() - center.getValue();
151 T neg = center.getValue() - neighborIt.getNeighbor(i +
D).getValue();
152 n[i] = (pos + neg) * FINITE_DIFF_FACTOR;
153 denominator += n[i] * n[i];
156 denominator = std::sqrt(denominator);
157 if (std::abs(denominator) < EPSILON) {
158 Logger::getInstance()
159 .addWarning(
"CalculateNormalVectors: Vector of length 0 at " +
160 neighborIt.getIndices().to_string())
162 for (
unsigned i = 0; i <
D; ++i)
165 for (
unsigned i = 0; i <
D; ++i) {
170 normalVectors.push_back(n);
175 unsigned numberOfNormals = 0;
176 for (
unsigned i = 0; i < levelSet->getNumberOfSegments(); ++i) {
177 numberOfNormals += normalVectorsVector[i].size();
179 normalVectorsVector[0].reserve(numberOfNormals);
181 for (
unsigned i = 1; i < levelSet->getNumberOfSegments(); ++i) {
182 normalVectorsVector[0].insert(normalVectorsVector[0].end(),
183 normalVectorsVector[i].begin(),
184 normalVectorsVector[i].end());
188 auto &pointData = levelSet->getPointData();
191 if (vectorDataPointer ==
nullptr) {
192 pointData.insertNextVectorData(normalVectorsVector[0],
196 *vectorDataPointer = std::move(normalVectorsVector[0]);