46 if (levelSet ==
nullptr) {
48 .addError(
"No level set was passed to CalculateNormalVectors.")
52 if (levelSet->getLevelSetWidth() < (maxValue * 4) + 1) {
54 .addWarning(
"CalculateNormalVectors: Level set width must be "
56 std::to_string((maxValue * 4) + 1) +
57 ". Expanding level set to " +
58 std::to_string((maxValue * 4) + 1) +
".")
63 std::vector<std::vector<Vec3D<T>>> normalVectorsVector(
64 levelSet->getNumberOfSegments());
65 double pointsPerSegment =
66 double(2 * levelSet->getDomain().getNumberOfPoints()) /
67 double(levelSet->getLevelSetWidth());
69 auto grid = levelSet->getGrid();
72#pragma omp parallel num_threads(levelSet->getNumberOfSegments())
76 p = omp_get_thread_num();
79 auto &normalVectors = normalVectorsVector[p];
80 normalVectors.reserve(pointsPerSegment);
82 viennahrle::Index<D>
const startVector =
83 (p == 0) ? grid.getMinGridPoint()
84 : levelSet->getDomain().getSegmentation()[p - 1];
86 viennahrle::Index<D>
const endVector =
87 (p !=
static_cast<int>(levelSet->getNumberOfSegments() - 1))
88 ? levelSet->getDomain().getSegmentation()[p]
89 : grid.incrementIndices(grid.getMaxGridPoint());
91 for (viennahrle::ConstSparseStarIterator<
93 neighborIt(levelSet->getDomain(), startVector);
94 neighborIt.getIndices() < endVector; neighborIt.next()) {
96 auto ¢er = neighborIt.getCenter();
97 if (!center.isDefined()) {
99 }
else if (std::abs(center.getValue()) > maxValue) {
102 normalVectors.push_back(tmp);
109 for (
int i = 0; i <
D; i++) {
110 T pos = neighborIt.getNeighbor(i).getValue() - center.getValue();
111 T neg = center.getValue() - neighborIt.getNeighbor(i +
D).getValue();
112 n[i] = (pos + neg) * 0.5;
113 denominator += n[i] * n[i];
116 denominator = std::sqrt(denominator);
117 if (std::abs(denominator) < 1e-12) {
118 Logger::getInstance()
119 .addWarning(
"CalculateNormalVectors: Vector of length 0 at " +
120 neighborIt.getIndices().to_string())
122 for (
unsigned i = 0; i <
D; ++i)
125 for (
unsigned i = 0; i <
D; ++i) {
130 normalVectors.push_back(n);
135 unsigned numberOfNormals = 0;
136 for (
unsigned i = 0; i < levelSet->getNumberOfSegments(); ++i) {
137 numberOfNormals += normalVectorsVector[i].size();
139 normalVectorsVector[0].reserve(numberOfNormals);
141 for (
unsigned i = 1; i < levelSet->getNumberOfSegments(); ++i) {
142 normalVectorsVector[0].insert(normalVectorsVector[0].end(),
143 normalVectorsVector[i].begin(),
144 normalVectorsVector[i].end());
148 auto &pointData = levelSet->getPointData();
151 if (vectorDataPointer ==
nullptr) {
152 pointData.insertNextVectorData(normalVectorsVector[0],
156 *vectorDataPointer = std::move(normalVectorsVector[0]);