ViennaLS
Loading...
Searching...
No Matches
lsCalculateVisibilities.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <hrleSparseIterator.hpp>
4#include <lsDomain.hpp>
5#include <vcVectorType.hpp>
6
7namespace viennals {
8using namespace viennacore;
9
10template <class T, int D> class CalculateVisibilities {
11 using hrleDomainType = typename Domain<T, D>::DomainType;
12
13 SmartPointer<Domain<T, D>> levelSet;
14 Vec3D<T> direction;
15 const T epsilon = static_cast<T>(1e-6);
16 const std::string visibilitiesLabel;
17
18public:
19 CalculateVisibilities(const SmartPointer<Domain<T, D>> &passedLevelSet,
20 const Vec3D<T> &passedDirection,
21 std::string label = "Visibilities")
22 : levelSet(passedLevelSet), direction(passedDirection),
23 visibilitiesLabel(std::move(label)) {}
24
25 void apply() {
26 auto &domain = levelSet->getDomain();
27 auto &grid = levelSet->getGrid();
28
29 // Invert the vector
30 auto dir = Normalize(Inv(direction));
31 std::vector<T> visibilities(domain.getNumberOfPoints(), static_cast<T>(-1));
32
33 // Check if the direction vector has a component in the simulation
34 // dimensions
35 T dirNorm = 0;
36 for (int i = 0; i < D; ++i) {
37 dirNorm += dir[i] * dir[i];
38 }
39
40 if (dirNorm < epsilon) {
41 std::fill(visibilities.begin(), visibilities.end(), static_cast<T>(1.0));
42 } else {
43 // *** Determine extents of domain ***
44 Vec3D<T> minDefinedPoint{};
45 Vec3D<T> maxDefinedPoint{};
46 // Initialize with extreme values
47 for (int i = 0; i < D; ++i) {
48 minDefinedPoint[i] = std::numeric_limits<T>::max();
49 maxDefinedPoint[i] = std::numeric_limits<T>::lowest();
50 }
51 // Iterate through all defined points in the domain
52 for (viennahrle::SparseIterator<hrleDomainType> it(domain);
53 !it.isFinished(); it.next()) {
54 if (!it.isDefined())
55 continue; // Skip undefined points
56
57 // Get the coordinate of the current point
58 auto point = it.getStartIndices();
59 for (int i = 0; i < D; ++i) {
60 // Compare to update min and max defined points
61 T coord = point[i]; // * grid.getGridDelta();
62 minDefinedPoint[i] = std::min(minDefinedPoint[i], coord);
63 maxDefinedPoint[i] = std::max(maxDefinedPoint[i], coord);
64 }
65 }
66 //****************************
67
68#pragma omp parallel num_threads(levelSet->getNumberOfSegments())
69 {
70 int p = 0;
71#ifdef _OPENMP
72 p = omp_get_thread_num();
73#endif
74
75 const viennahrle::Index<D> startVector =
76 (p == 0) ? grid.getMinGridPoint() : domain.getSegmentation()[p - 1];
77
78 const viennahrle::Index<D> endVector =
79 (p != static_cast<int>(domain.getNumberOfSegments() - 1))
80 ? domain.getSegmentation()[p]
81 : grid.incrementIndices(grid.getMaxGridPoint());
82
83 for (viennahrle::SparseIterator<hrleDomainType> it(domain, startVector);
84 it.getStartIndices() < endVector; ++it) {
85
86 if (!it.isDefined())
87 continue;
88
89 // Starting position of the point
90 Vec3D<T> currentPos{};
91 for (int i = 0; i < D; ++i) {
92 currentPos[i] = it.getStartIndices(i);
93 }
94
95 // Start tracing the ray
96 T minLevelSetValue = it.getValue(); // Starting level set value
97 Vec3D<T> rayPos = currentPos;
98
99 // Step once to skip immediate neighbor
100 for (int i = 0; i < D; ++i)
101 rayPos[i] += dir[i];
102
103 bool visibility = true;
104
105 while (true) {
106 // Update the ray position
107 for (int i = 0; i < D; ++i)
108 rayPos[i] += dir[i];
109
110 // Determine the nearest grid cell (round to nearest index)
111 viennahrle::Index<D> nearestCell;
112 for (int i = 0; i < D; ++i)
113 nearestCell[i] = static_cast<viennahrle::IndexType>(rayPos[i]);
114
115 // Check if the nearest cell is within bounds
116 bool outOfBounds = false;
117 for (int i = 0; i < D; ++i) {
118 if (nearestCell[i] < minDefinedPoint[i] ||
119 nearestCell[i] > maxDefinedPoint[i]) {
120 outOfBounds = true;
121 break;
122 }
123 }
124
125 if (outOfBounds)
126 break; // Ray is outside the grid
127
128 // Access the level set value at the nearest cell
129 T value =
130 viennahrle::SparseIterator<hrleDomainType>(domain, nearestCell)
131 .getValue();
132
133 // Update the minimum value encountered
134 if (value < minLevelSetValue) {
135 visibility = false;
136 break;
137 }
138 }
139
140 // Update visibility for this point
141 visibilities[it.getPointId()] = visibility ? 1.0 : 0.0;
142 }
143 }
144 }
145
146 int unassignedCount = 0;
147 for (size_t i = 0; i < visibilities.size(); ++i) {
148 if (visibilities[i] < 0) {
149 std::cerr << "Unassigned visibility at point ID: " << i << std::endl;
150 ++unassignedCount;
151 }
152 }
153 if (unassignedCount > 0) {
154 std::cerr << "[Error] Total unassigned points: " << unassignedCount
155 << std::endl;
156 }
157
158 auto &pointData = levelSet->getPointData();
159 // delete if already exists
160 if (int i = pointData.getScalarDataIndex(visibilitiesLabel); i != -1) {
161 pointData.eraseScalarData(i);
162 }
163 pointData.insertNextScalarData(visibilities, visibilitiesLabel);
164 }
165};
166
167} // namespace viennals
constexpr int D
Definition Epitaxy.cpp:11
double T
Definition Epitaxy.cpp:12
CalculateVisibilities(const SmartPointer< Domain< T, D > > &passedLevelSet, const Vec3D< T > &passedDirection, std::string label="Visibilities")
Definition lsCalculateVisibilities.hpp:19
void apply()
Definition lsCalculateVisibilities.hpp:25
Class containing all information about the level set, including the dimensions of the domain,...
Definition lsDomain.hpp:28
viennahrle::Domain< T, D > DomainType
Definition lsDomain.hpp:33
Definition lsAdvect.hpp:41