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