Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 53 additions & 44 deletions cpp/spherical_volume_rendering_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

namespace svr {

namespace {
constexpr double DOUBLE_MAX = std::numeric_limits<double>::max();

// The type corresponding to the voxel(s) with the minimum tMax value for a
Expand Down Expand Up @@ -107,22 +108,22 @@ inline int calculateAngularVoxelIDFromPoints(

// Returns true if the "step" taken from the current voxel ID remains in
// the grid bounds.
inline bool inBoundsAzimuthal(const SphericalVoxelGrid &grid,
const int step,
const int azi_voxel) noexcept {
const double radian = (azi_voxel + 1)*grid.deltaPhi();
inline bool inBoundsAzimuthal(const SphericalVoxelGrid &grid, const int step,
const int azi_voxel) noexcept {
const double radian = (azi_voxel + 1) * grid.deltaPhi();
const double angval = radian - std::abs(step * grid.deltaPhi());
return angval <= grid.sphereMaxBoundAzi() && angval >= grid.sphereMinBoundAzi() ;
return angval <= grid.sphereMaxBoundAzi() &&
angval >= grid.sphereMinBoundAzi();
}

// Returns true if the "step" taken from the current voxel ID remains in
// the grid bounds.
inline bool inBoundsPolar(const SphericalVoxelGrid &grid,
const int step,
const int pol_voxel) noexcept {
const double radian = (pol_voxel + 1)*grid.deltaTheta();
inline bool inBoundsPolar(const SphericalVoxelGrid &grid, const int step,
const int pol_voxel) noexcept {
const double radian = (pol_voxel + 1) * grid.deltaTheta();
const double angval = radian - std::abs(step * grid.deltaTheta());
return angval <= grid.sphereMaxBoundPolar() && angval >= grid.sphereMinBoundPolar() ;
return angval <= grid.sphereMaxBoundPolar() &&
angval >= grid.sphereMinBoundPolar();
}

// Initializes an angular voxel ID. For polar initialization, *_2 represents
Expand Down Expand Up @@ -244,7 +245,6 @@ HitParameters angularHit(
t_max = ray_segment.intersectionTimeAt(b, ray);
}
}

const bool t_t_max_eq = svr::isEqual(t, t_max);
const bool t_max_within_bounds = t < t_max && !t_t_max_eq && t_max < max_t;
const bool t_t_min_eq = svr::isEqual(t, t_min);
Expand Down Expand Up @@ -373,7 +373,7 @@ inline HitParameters azimuthalHit(const Ray &ray,
// 6. tMaxR, tMaxPhi equal intersection.
// 7. tMaxTheta, tMaxPhi equal intersection.
// For each case, the following must hold: t < tMax < max_t
// For reference in shorthand naming:
// For reference, uses the following shortform naming:
// RP = Radial - Polar
// RA = Radial - Azimuthal
// PA = Polar - Azimuthal
Expand All @@ -398,10 +398,12 @@ inline VoxelIntersectionType minimumIntersection(

// Initialize an array of values representing the points of intersection between
// the lines corresponding to voxel boundaries and a given radial voxel in the
// XY plane and XZ plane. Here, P_* represents these points with a given radius
// 'current_radius'. The case where the number of polar voxels is equal to the
// number of azimuthal voxels is also checked to reduce the number of
// trigonometric and floating point calculations.
// XY plane and XZ plane. Here, P_* represents these points with a given radius.
//
// The calculations used for P_polar are:
// P1 = current_radius * trig_value.cosine + sphere_center.x()
// P2 = current_radius * trig_value.sine + sphere_center.y()
// Similar for P_azimuthal, but uses Z-axis instead of Y-axis.
inline void initializeVoxelBoundarySegments(
std::vector<svr::LineSegment> &P_polar,
std::vector<svr::LineSegment> &P_azimuthal, bool ray_origin_is_outside_grid,
Expand All @@ -411,22 +413,6 @@ inline void initializeVoxelBoundarySegments(
P_azimuthal = grid.pMaxAzimuthal();
return;
}
if (grid.numPolarSections() == grid.numAzimuthalSections()) {
std::transform(
grid.polarTrigValues().cbegin(), grid.polarTrigValues().cend(),
P_polar.begin(), P_azimuthal.begin(),
[current_radius, &grid](const TrigonometricValues &tv,
LineSegment &polar_LS) -> LineSegment {
const double px_value =
current_radius * tv.cosine + grid.sphereCenter().x();
const double current_radius_times_sin = current_radius * tv.sine;
polar_LS = {.P1 = px_value,
.P2 = current_radius_times_sin + grid.sphereCenter().y()};
return {.P1 = px_value,
.P2 = current_radius_times_sin + grid.sphereCenter().z()};
});
return;
}
std::transform(
grid.polarTrigValues().cbegin(), grid.polarTrigValues().cend(),
P_polar.begin(),
Expand All @@ -443,6 +429,8 @@ inline void initializeVoxelBoundarySegments(
});
}

} // namespace

std::vector<svr::SphericalVoxel> walkSphericalVolume(
const Ray &ray, const svr::SphericalVoxelGrid &grid,
double max_t) noexcept {
Expand Down Expand Up @@ -529,16 +517,13 @@ std::vector<svr::SphericalVoxel> walkSphericalVolume(
current_polar_voxel, t, max_t);
const auto azimuthal = azimuthalHit(ray, grid, ray_segment, collinear_times,
current_azimuthal_voxel, t, max_t);

if (current_radial_voxel + radial.tStep == 0 ||
(radial.tMax == DOUBLE_MAX && polar.tMax == DOUBLE_MAX &&
azimuthal.tMax == DOUBLE_MAX)) {
voxels.back().exit_t = t_ray_exit;
voxels.back().exit_t = t_ray_exit;
return voxels;
}
const bool in_azi_bounds =
inBoundsAzimuthal(grid,azimuthal.tStep,current_azimuthal_voxel);
const bool in_polar_bounds =
inBoundsPolar(grid,polar.tStep,current_polar_voxel);
const auto voxel_intersection =
minimumIntersection(radial, polar, azimuthal);
switch (voxel_intersection) {
Expand All @@ -549,37 +534,56 @@ std::vector<svr::SphericalVoxel> walkSphericalVolume(
}
case Polar: {
t = polar.tMax;
if (!in_polar_bounds) return voxels;
if (!inBoundsPolar(grid, polar.tStep, current_polar_voxel)) {
voxels.back().exit_t = t_ray_exit;
return voxels;
}
current_polar_voxel =
(current_polar_voxel + polar.tStep) % grid.numPolarSections();
break;
}
case Azimuthal: {
if (!in_azi_bounds) return voxels;
if (!inBoundsAzimuthal(grid, azimuthal.tStep,
current_azimuthal_voxel)) {
voxels.back().exit_t = t_ray_exit;
return voxels;
}
t = azimuthal.tMax;
current_azimuthal_voxel = (current_azimuthal_voxel + azimuthal.tStep) %
grid.numAzimuthalSections();
break;
}
case RadialPolar: {
t = radial.tMax;
if (!in_polar_bounds) return voxels;
if (!inBoundsPolar(grid, polar.tStep, current_polar_voxel)) {
voxels.back().exit_t = t_ray_exit;
return voxels;
}
current_radial_voxel += radial.tStep;
current_polar_voxel =
(current_polar_voxel + polar.tStep) % grid.numPolarSections();
break;
}
case RadialAzimuthal: {
t = radial.tMax;
if (!in_azi_bounds) return voxels;
if (!inBoundsAzimuthal(grid, azimuthal.tStep,
current_azimuthal_voxel)) {
voxels.back().exit_t = t_ray_exit;
return voxels;
}
current_radial_voxel += radial.tStep;
current_azimuthal_voxel = (current_azimuthal_voxel + azimuthal.tStep) %
grid.numAzimuthalSections();
break;
}
case PolarAzimuthal: {
t = polar.tMax;
if (!in_azi_bounds) return voxels;
if (!inBoundsAzimuthal(grid, azimuthal.tStep,
current_azimuthal_voxel) ||
!(inBoundsPolar(grid, polar.tStep, current_polar_voxel))) {
voxels.back().exit_t = t_ray_exit;
return voxels;
}
current_polar_voxel =
(current_polar_voxel + polar.tStep) % grid.numPolarSections();
current_azimuthal_voxel = (current_azimuthal_voxel + azimuthal.tStep) %
Expand All @@ -588,7 +592,12 @@ std::vector<svr::SphericalVoxel> walkSphericalVolume(
}
case RadialPolarAzimuthal: {
t = radial.tMax;
if (!in_azi_bounds) return voxels;
if (!inBoundsAzimuthal(grid, azimuthal.tStep,
current_azimuthal_voxel) ||
!(inBoundsPolar(grid, polar.tStep, current_polar_voxel))) {
voxels.back().exit_t = t_ray_exit;
return voxels;
}
current_radial_voxel += radial.tStep;
current_polar_voxel =
(current_polar_voxel + polar.tStep) % grid.numPolarSections();
Expand Down Expand Up @@ -632,4 +641,4 @@ std::vector<svr::SphericalVoxel> walkSphericalVolume(
}
// LCOV_EXCL_STOP

} // namespace svr
} // namespace svr
4 changes: 3 additions & 1 deletion cpp/spherical_volume_rendering_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ struct SphericalVoxel {
int radial;
int polar;
int azimuthal;

// Entrance and exit time into the given voxel.
double enter_t;
double exit_t;
};
Expand All @@ -40,4 +42,4 @@ std::vector<SphericalVoxel> walkSphericalVolume(

} // namespace svr

#endif // SPHERICAL_VOLUME_RENDERING_SPHERICALVOLUMERENDERINGUTIL_H
#endif // SPHERICAL_VOLUME_RENDERING_SPHERICALVOLUMERENDERINGUTIL_H
Loading