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 for
69 for (unsigned p = 0; p < domain.getNumberOfSegments(); ++p) {
70
71 const viennahrle::Index<D> startVector =
72 (p == 0) ? grid.getMinGridPoint() : domain.getSegmentation()[p - 1];
73
74 const viennahrle::Index<D> endVector =
75 (p != static_cast<int>(domain.getNumberOfSegments() - 1))
76 ? domain.getSegmentation()[p]
77 : grid.incrementIndices(grid.getMaxGridPoint());
78
79 for (viennahrle::SparseIterator<hrleDomainType> it(domain, startVector);
80 it.getStartIndices() < endVector; ++it) {
81
82 if (!it.isDefined())
83 continue;
84
85 // Starting position of the point
86 Vec3D<T> currentPos{};
87 for (int i = 0; i < D; ++i) {
88 currentPos[i] = it.getStartIndices(i);
89 }
90
91 // Start tracing the ray
92 T minLevelSetValue = it.getValue(); // Starting level set value
93 Vec3D<T> rayPos = currentPos;
94
95 // Step once to skip immediate neighbor
96 for (int i = 0; i < D; ++i)
97 rayPos[i] += dir[i];
98
99 bool visibility = true;
100
101 while (true) {
102 // Update the ray position
103 for (int i = 0; i < D; ++i)
104 rayPos[i] += dir[i];
105
106 // Determine the nearest grid cell (round to nearest index)
107 viennahrle::Index<D> nearestCell;
108 for (int i = 0; i < D; ++i)
109 nearestCell[i] = static_cast<viennahrle::IndexType>(rayPos[i]);
110
111 // Check if the nearest cell is within bounds
112 bool outOfBounds = false;
113 for (int i = 0; i < D; ++i) {
114 if (nearestCell[i] < minDefinedPoint[i] ||
115 nearestCell[i] > maxDefinedPoint[i]) {
116 outOfBounds = true;
117 break;
118 }
119 }
120
121 if (outOfBounds)
122 break; // Ray is outside the grid
123
124 // Access the level set value at the nearest cell
125 T value =
126 viennahrle::SparseIterator<hrleDomainType>(domain, nearestCell)
127 .getValue();
128
129 // Update the minimum value encountered
130 if (value < minLevelSetValue) {
131 visibility = false;
132 break;
133 }
134 }
135
136 // Update visibility for this point
137 visibilities[it.getPointId()] = visibility ? 1.0 : 0.0;
138 }
139 }
140 }
141
142 int unassignedCount = 0;
143 for (size_t i = 0; i < visibilities.size(); ++i) {
144 if (visibilities[i] < 0) {
145 std::cerr << "Unassigned visibility at point ID: " << i << std::endl;
146 ++unassignedCount;
147 }
148 }
149 if (unassignedCount > 0) {
150 std::cerr << "[Error] Total unassigned points: " << unassignedCount
151 << std::endl;
152 }
153
154 auto &pointData = levelSet->getPointData();
155 // delete if already exists
156 if (int i = pointData.getScalarDataIndex(visibilitiesLabel); i != -1) {
157 pointData.eraseScalarData(i);
158 }
159 pointData.insertNextScalarData(visibilities, visibilitiesLabel);
160 }
161};
162
163} // namespace viennals
constexpr int D
Definition Epitaxy.cpp:12
double T
Definition Epitaxy.cpp:13
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:27
viennahrle::Domain< T, D > DomainType
Definition lsDomain.hpp:32
Definition lsAdvect.hpp:41