Skip to content

Instantly share code, notes, and snippets.

@kergalym
Created February 14, 2022 14:00
Show Gist options
  • Save kergalym/6358a8a983b3b220a0b21f08854259ac to your computer and use it in GitHub Desktop.
Save kergalym/6358a8a983b3b220a0b21f08854259ac to your computer and use it in GitHub Desktop.
code fragment from RP v1 IESLoader.py
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