GCC Code Coverage Report


ernie/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
1 / 1
100.0%
Branches:
1 / 2
50.0%
Functions:
-
-%

io/ies.h
Line Branch Exec Source
1 // SPDX-License-Identifier: BSD-3-Clause
2 /// @file ies.h
3 /// @brief IES LM-63 photometric profiles of luminaires.
4 #pragma once
5
6 #include "ernie/export.h"
7
8 #include "ernie/util/glm.h"
9
10 #include <filesystem>
11 #include <string_view>
12 #include <vector>
13
14 namespace ernie {
15
16 /// @brief The axis an IES file's angles turn about.
17 /// In the luminaire's frame: x its length and 0 degree plane, y its
18 /// width, z up; it shines down -z.
19 enum class IesType {
20 /// Type C: about the vertical axis z. The vertical angle runs
21 /// from the nadir (0) to the zenith (180); the horizontal angle
22 /// turns around z from x towards y. Most luminaires.
23 C = 1,
24 /// Type B: about the width y (floodlights). The vertical angle
25 /// turns the plane through y, from the nadir towards x; the
26 /// horizontal angle leaves that plane, towards -y; both -90 to
27 /// 90.
28 B = 2,
29 /// Type A: about the length x (automotive lamps). The vertical
30 /// angle turns the plane through x, from the nadir towards y; the
31 /// horizontal angle leaves that plane, towards x.
32 A = 3,
33 };
34
35 /// @brief How a lamp's output changes as its luminaire tilts.
36 /// From TILT=INCLUDE or a tilt file; for lamps sensitive to burning
37 /// position, such as metal halide.
38
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
7 struct ERNIE_API IesTilt {
39 /// Lamp position: 1 vertical, 2 horizontal along x (0 degree
40 /// plane), 3 horizontal along y (90 degree plane); 0 for none.
41 int geometry = 0;
42 /// Tilt angles, in degrees, increasing.
43 std::vector<double> angles;
44 /// Candela multipliers at each angle.
45 std::vector<double> factors;
46
47 /// @brief The luminaire's tilt for the lamp's geometry.
48 /// Vertical lamps: the luminaire z's angle from vertical.
49 /// Horizontal lamps: the lamp axis's elevation.
50 /// @param x The luminaire's x axis in a z-up world (unit).
51 /// @param y The luminaire's y axis (unit).
52 /// @param z The luminaire's z axis (unit).
53 /// @return The tilt, in degrees.
54 double Angle(const glm::dvec3& x, const glm::dvec3& y, const glm::dvec3& z) const;
55
56 /// @brief The multiplier at a tilt.
57 /// Linear between the file's angles, held beyond; data up to 90
58 /// degrees mirrors past it.
59 /// @param degrees The tilt, in degrees.
60 /// @return The factor; 1 without tilt data.
61 double Factor(double degrees) const;
62 };
63
64 /// @brief A luminaire's luminous intensity from an IES LM-63 file.
65 /// Files may give a half, quadrant or one plane of a symmetric
66 /// luminaire; `Sample` mirrors them.
67 ///
68 /// References:
69 /// - IES LM-63-19, Approved Method: IES Standard File Format for the
70 /// Electronic Transfer of Photometric Data and Related Information,
71 /// Illuminating Engineering Society, 2019.
72 /// - I. Ashdown, "Parsing the IESNA LM-63 Photometric Data File",
73 /// 1998, http://lumen.iee.put.poznan.pl/kw/iesna.txt
74 /// - G. Ward, Radiance ies2rad, source.cal and tilt.cal (type B
75 /// coordinates and tilt angles),
76 /// https://github.com/NREL/Radiance/tree/master/src/cv
77 struct ERNIE_API IesProfile {
78 /// The photometric type.
79 IesType type = IesType::C;
80 /// Vertical angles, in degrees, increasing.
81 std::vector<double> vertical;
82 /// Horizontal angles, in degrees, increasing.
83 std::vector<double> horizontal;
84 /// Candela, `horizontal.size()` rows of `vertical.size()`, with
85 /// the file's multiplier and ballast factor applied.
86 std::vector<double> candela;
87 /// The tilt data.
88 IesTilt tilt;
89
90 /// @brief Intensity in a direction, bilinear between the file's
91 /// angles and mirrored by its symmetry.
92 /// @param theta Degrees from the nadir (-z).
93 /// @param phi Degrees around the nadir, from x towards y.
94 /// @return Candela; 0 outside the file's angles.
95 double Sample(double theta, double phi) const;
96
97 /// @return The luminous flux over the sphere, in lumens.
98 double Flux() const;
99
100 private:
101 /// Candela at the file's vertical angle `v` and horizontal angle
102 /// `h`, in its coordinates.
103 double Table(double v, double h) const;
104 };
105
106 /// @brief Parses LM-63 text, versions 1986 to 2019, types A, B, C.
107 /// @param text The file's contents.
108 /// @param directory Where a TILT=<file> is resolved.
109 /// @return The profile with its tilt data.
110 /// @throws std::invalid_argument If the text is not LM-63, has an
111 /// unknown type, or has angles out of order.
112 /// @throws std::runtime_error If a tilt file cannot be read.
113 ERNIE_API IesProfile ParseIes(std::string_view text, const std::filesystem::path& directory = {});
114
115 /// @brief Reads and parses an IES file; tilt files resolve beside it.
116 /// @param path The file.
117 /// @return The profile.
118 /// @throws std::runtime_error If it cannot be read.
119 ERNIE_API IesProfile ReadIes(const std::filesystem::path& path);
120
121 } // namespace ernie
122