82 if (levelSet ==
nullptr) {
84 "No level set was passed to CalculateNormalVectors.");
88 if (levelSet->getLevelSetWidth() < (maxValue * 4) + 1) {
89 VIENNACORE_LOG_WARNING(
"CalculateNormalVectors: Level set width must be "
91 std::to_string((maxValue * 4) + 1) +
92 ". Expanding level set to " +
93 std::to_string((maxValue * 4) + 1) +
".");
97 std::vector<std::vector<Vec3D<T>>> normalVectorsVector(
98 levelSet->getNumberOfSegments());
101 double pointsPerSegment =
102 double(2 * levelSet->getDomain().getNumberOfPoints()) /
103 double(levelSet->getLevelSetWidth());
105 auto grid = levelSet->getGrid();
108#pragma omp parallel num_threads(levelSet->getNumberOfSegments())
112 p = omp_get_thread_num();
115 auto &normalVectors = normalVectorsVector[p];
116 normalVectors.reserve(pointsPerSegment);
118 viennahrle::Index<D>
const startVector =
119 (p == 0) ? grid.getMinGridPoint()
120 : levelSet->getDomain().getSegmentation()[p - 1];
122 viennahrle::Index<D>
const endVector =
123 (p !=
static_cast<int>(levelSet->getNumberOfSegments() - 1))
124 ? levelSet->getDomain().getSegmentation()[p]
125 : grid.incrementIndices(grid.getMaxGridPoint());
127 for (viennahrle::ConstSparseStarIterator<
129 neighborIt(levelSet->getDomain(), startVector);
130 neighborIt.getIndices() < endVector; neighborIt.next()) {
132 auto ¢er = neighborIt.getCenter();
133 if (!center.isDefined()) {
135 }
else if (std::abs(center.getValue()) > maxValue) {
138 normalVectors.push_back(tmp);
145 for (
int i = 0; i <
D; i++) {
146 T pos = neighborIt.getNeighbor(i).getValue() - center.getValue();
147 T neg = center.getValue() - neighborIt.getNeighbor(i +
D).getValue();
148 n[i] = (pos + neg) * FINITE_DIFF_FACTOR;
149 denominator += n[i] * n[i];
152 denominator = std::sqrt(denominator);
153 if (std::abs(denominator) < EPSILON) {
154 VIENNACORE_LOG_WARNING(
155 "CalculateNormalVectors: Vector of length 0 at " +
156 neighborIt.getIndices().to_string());
157 for (
unsigned i = 0; i <
D; ++i)
160 for (
unsigned i = 0; i <
D; ++i) {
165 normalVectors.push_back(n);
170 unsigned numberOfNormals = 0;
171 for (
unsigned i = 0; i < levelSet->getNumberOfSegments(); ++i) {
172 numberOfNormals += normalVectorsVector[i].size();
174 normalVectorsVector[0].reserve(numberOfNormals);
176 for (
unsigned i = 1; i < levelSet->getNumberOfSegments(); ++i) {
177 normalVectorsVector[0].insert(normalVectorsVector[0].end(),
178 normalVectorsVector[i].begin(),
179 normalVectorsVector[i].end());
183 auto &pointData = levelSet->getPointData();
186 if (vectorDataPointer ==
nullptr) {
187 pointData.insertNextVectorData(normalVectorsVector[0],
191 *vectorDataPointer = std::move(normalVectorsVector[0]);