Created
February 14, 2022 14:00
-
-
Save kergalym/6358a8a983b3b220a0b21f08854259ac to your computer and use it in GitHub Desktop.
code fragment from RP v1 IESLoader.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def _loadIESProfile(self, name, filename): | |
""" Internal method to load an ies profile. Adapted from | |
https://gist.githubusercontent.com/AngryLoki/4364512/raw/ies2cycles.py """ | |
# self.debug("Loading ies profile", filename, "as",len(self.profileNames)) | |
profileMultiplier = 1.0 | |
# Open the IES file | |
with open(filename, 'r', encoding="utf-8", errors="ignore") as handle: | |
content = handle.read() | |
content.encode('utf-8') | |
# Extract and check version string | |
versionString, content = content.split('\n', 1) | |
versionString = versionString.strip() | |
if versionString in self.IESVersionTable: | |
version = self.IESVersionTable[versionString] | |
else: | |
self.warn("No supported IES version found:",versionString) | |
version = None | |
# Extract IES properties | |
keywords = dict() | |
while content and not content.startswith('TILT='): | |
key, content = content.split('\n', 1) | |
if key.startswith('['): | |
endbracket = key.find(']') | |
if endbracket != -1: | |
keywords[key[1:endbracket]] = key[endbracket + 1:].strip() | |
# After all properties, the tile keyword should follow | |
keyword, content = content.split('\n', 1) | |
if not keyword.startswith('TILT'): | |
self.warn("TILT keyword not found") | |
return False | |
# Strip data | |
fileData = content.replace(',', ' ').split() | |
# Property 0 is the amount of lamps | |
numLamps = int(fileData[0]) | |
if numLamps != 1: | |
self.warn("Only 1 lamp is supported,", numLamps, "found:",name) | |
# Extract further properties | |
lumensPerLamp = float(fileData[1]) | |
candelaMultiplier = float(fileData[2]) | |
numVerticalAngles = int(fileData[3]) | |
numHorizontalAngles = int(fileData[4]) | |
# Check if everything went right so far | |
if not numVerticalAngles or not numHorizontalAngles: | |
self.error("Error during property extract") | |
return False | |
# Extract further properties | |
photometricType = int(fileData[5]) | |
unitType = int(fileData[6]) | |
# Determine the unit type, either feet or meters | |
if unitType not in [1, 2]: | |
self.warn("Unkown unity type:", unitType) | |
# Extract data size | |
width, length, height = map(float, fileData[7:10]) | |
ballastFactor = float(fileData[10]) | |
futureUse = float(fileData[11]) | |
if futureUse != 1.0: | |
self.warn("Invalid future use field") | |
inputWatts = float(fileData[12]) | |
# Extract the actual data | |
verticalAngles = [float(s) for s in fileData[13:13 + numVerticalAngles]] | |
horizontalAngles = [float(s) for s in fileData[13 + numVerticalAngles: | |
13 + numVerticalAngles + numHorizontalAngles]] | |
# Determine the vertical light cone type. There are 90 and 180 degree cone types. | |
if verticalAngles[0] == 0 and verticalAngles[-1] == 90: | |
lampConeType = 'TYPE90' | |
elif verticalAngles[0] == 0 and verticalAngles[-1] == 180: | |
lampConeType = 'TYPE180' | |
else: | |
self.warn("Unsupported angles: ", verticalAngles[0], "-", verticalAngles[-1]) | |
lampConeType = 'TYPE180' | |
# Determine the horizontal light cone type | |
if len(horizontalAngles) == 1 or abs(horizontalAngles[0] - horizontalAngles[-1]) == 360: | |
lampHorizontalConeType = 'TYPE360' | |
elif abs(horizontalAngles[0] - horizontalAngles[-1]) == 180: | |
lampHorizontalConeType = 'TYPE180' | |
elif abs(horizontalAngles[0] - horizontalAngles[-1]) == 90: | |
lampHorizontalConeType = 'TYPE90' | |
else: | |
self.warn("Unsupported horizontal angles: ", horizontalAngles[0], "-", horizontalAngles[-1]) | |
lampHorizontalConeType = 'TYPE360' | |
# Read the candela values | |
offset = 13 + len(verticalAngles) + len(horizontalAngles) | |
candelaIndex = len(verticalAngles) * len(horizontalAngles) | |
candelaValues = [float(s) for s in fileData[offset:offset + candelaIndex]] | |
# Convert the 1d candela array to 2d array | |
candela2D = list(zip(*[iter(candelaValues)] * len(verticalAngles))) | |
# Compute the fallof gradient | |
lampGradientData = [x / verticalAngles[-1] for x in verticalAngles] | |
# Compute the radial gradient | |
radialGradientData = [sum(x) / len(x) for x in zip(*candela2D)] | |
radialGradientDataMax = max(radialGradientData) | |
# Normalize the radial gradient by dividing by the maximum value | |
radialGradientData = [val / radialGradientDataMax for val in radialGradientData] | |
# Finally register the profile | |
self._storeIESProfile(name, radialGradientData, lampGradientData) | |
return True |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment