forked from LeenkxTeam/LNXSDK
		
	
		
			
				
	
	
		
			174 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			174 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# Using IES profiles from http://www.derekjenson.com/3d-blog/ies-light-profiles
 | 
						|
# IES parser based on:
 | 
						|
# https://github.com/tobspr/RenderPipeline
 | 
						|
# Copyright (c) 2014-2016 tobspr <tobias.springer1@gmail.com>
 | 
						|
# Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
						|
# of this software and associated documentation files (the "Software"), to deal
 | 
						|
# in the Software without restriction, including without limitation the rights
 | 
						|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
						|
# copies of the Software, and to permit persons to whom the Software is
 | 
						|
# furnished to do so, subject to the following conditions:
 | 
						|
 | 
						|
# The above copyright notice and this permission notice shall be included in
 | 
						|
# all copies or substantial portions of the Software.
 | 
						|
 | 
						|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
						|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
						|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
						|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
						|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
						|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
						|
# THE SOFTWARE.
 | 
						|
 | 
						|
import re
 | 
						|
import os
 | 
						|
import math
 | 
						|
import bpy
 | 
						|
import random
 | 
						|
 | 
						|
def load(filepath):
 | 
						|
    global _vertical_angles
 | 
						|
    global _horizontal_angles
 | 
						|
    global _candela_values
 | 
						|
    KEYWORD_REGEX = re.compile(r"\[([A-Za-z0-8_-]+)\](.*)")
 | 
						|
 | 
						|
    PROFILES = [
 | 
						|
        "IESNA:LM-63-1986",
 | 
						|
        "IESNA:LM-63-1991",
 | 
						|
        "IESNA91",
 | 
						|
        "IESNA:LM-63-1995",
 | 
						|
        "IESNA:LM-63-2002",
 | 
						|
        "ERCO Leuchten GmbH  BY: ERCO/LUM650/8701",
 | 
						|
        "ERCO Leuchten GmbH"
 | 
						|
    ]
 | 
						|
 | 
						|
    with open(filepath, "r") as handle:
 | 
						|
        lines = handle.readlines()
 | 
						|
 | 
						|
    lines = [i.strip() for i in lines]
 | 
						|
 | 
						|
    # Parse version header
 | 
						|
    first_line = lines.pop(0)
 | 
						|
    if first_line not in PROFILES:
 | 
						|
        raise "Unsupported Profile: " + first_line
 | 
						|
 | 
						|
    # Extracts the keywords
 | 
						|
    keywords = {}
 | 
						|
    while lines:
 | 
						|
        line = lines.pop(0)
 | 
						|
        if not line.startswith("["):
 | 
						|
            if line != "TILT=NONE":
 | 
						|
                continue
 | 
						|
            lines.insert(0, line)
 | 
						|
            break
 | 
						|
        else:
 | 
						|
            match = KEYWORD_REGEX.match(line)
 | 
						|
            if match:
 | 
						|
                key, val = match.group(1, 2)
 | 
						|
                keywords[key.strip()] = val.strip()
 | 
						|
            else:
 | 
						|
                raise "Invalid keyword line: " + line
 | 
						|
 | 
						|
    # Next line should be TILT=NONE according to the spec
 | 
						|
    if lines.pop(0) != "TILT=NONE":
 | 
						|
        raise "Expected TILT=NONE line, but none found!"
 | 
						|
 | 
						|
    # From now on, lines do not matter anymore, instead everything is space seperated
 | 
						|
    new_parts = (' '.join(lines)).replace(",", " ").split()
 | 
						|
 | 
						|
    def read_int():
 | 
						|
        return int(new_parts.pop(0))
 | 
						|
 | 
						|
    def read_float():
 | 
						|
        return float(new_parts.pop(0))
 | 
						|
 | 
						|
    # Amount of Lamps
 | 
						|
    if read_int() != 1:
 | 
						|
        raise "Only 1 Lamp supported!"
 | 
						|
 | 
						|
    # Extract various properties
 | 
						|
    lumen_per_lamp = read_float()
 | 
						|
    candela_multiplier = read_float()
 | 
						|
    num_vertical_angles = read_int()
 | 
						|
    num_horizontal_angles = read_int()
 | 
						|
 | 
						|
    if num_vertical_angles < 1 or num_horizontal_angles < 1:
 | 
						|
        raise "Invalid of vertical/horizontal angles!"
 | 
						|
 | 
						|
    photometric_type = read_int()
 | 
						|
    unit_type = read_int()
 | 
						|
 | 
						|
    # Check for a correct unit type, should be 1 for meters and 2 for feet
 | 
						|
    if unit_type not in [1, 2]:
 | 
						|
        raise "Invalid unit type"
 | 
						|
 | 
						|
    width = read_float()
 | 
						|
    length = read_float()
 | 
						|
    height = read_float()
 | 
						|
    ballast_factor = read_float()
 | 
						|
    future_use = read_float()
 | 
						|
    input_watts = read_float()
 | 
						|
 | 
						|
    _vertical_angles = [read_float() for i in range(num_vertical_angles)]
 | 
						|
    _horizontal_angles = [read_float() for i in range(num_horizontal_angles)]
 | 
						|
 | 
						|
    _candela_values = []
 | 
						|
    candela_scale = 0.0
 | 
						|
 | 
						|
    for i in range(num_horizontal_angles):
 | 
						|
        vertical_data = [read_float() for i in range(num_vertical_angles)]
 | 
						|
        candela_scale = max(candela_scale, max(vertical_data))
 | 
						|
        _candela_values += vertical_data
 | 
						|
 | 
						|
    # Rescale values, divide by maximum
 | 
						|
    _candela_values = [i / candela_scale for i in _candela_values]
 | 
						|
    generate_texture()
 | 
						|
 | 
						|
def generate_texture():
 | 
						|
    tex = bpy.data.images.new("iestexture", width=128, height=128, float_buffer=True) # R16
 | 
						|
    resolution_vertical = 128
 | 
						|
    resolution_horizontal = 128
 | 
						|
 | 
						|
    for vert in range(resolution_vertical):
 | 
						|
        for horiz in range(resolution_horizontal):
 | 
						|
            vert_angle = vert / (resolution_vertical - 1.0)
 | 
						|
            vert_angle = math.cos(vert_angle * math.pi) * 90.0 + 90.0
 | 
						|
            horiz_angle = horiz / (resolution_horizontal - 1.0) * 360.0
 | 
						|
            candela = get_candela_value(vert_angle, horiz_angle)
 | 
						|
            x = vert
 | 
						|
            y = horiz
 | 
						|
            i = x + y * resolution_horizontal
 | 
						|
            tex.pixels[i * 4] = candela
 | 
						|
            tex.pixels[i * 4 + 1] = candela
 | 
						|
            tex.pixels[i * 4 + 2] = candela
 | 
						|
            tex.pixels[i * 4 + 3] = 1.0
 | 
						|
 | 
						|
def get_candela_value(vertical_angle, horizontal_angle):
 | 
						|
    # Assume a dataset without horizontal angles
 | 
						|
    return get_vertical_candela_value(0, vertical_angle)
 | 
						|
 | 
						|
def get_vertical_candela_value(horizontal_angle_idx, vertical_angle):
 | 
						|
    if vertical_angle < 0.0:
 | 
						|
        return 0.0
 | 
						|
 | 
						|
    if vertical_angle > _vertical_angles[len(_vertical_angles) - 1]:
 | 
						|
        return 0.0
 | 
						|
 | 
						|
    for vertical_index in range(1, len(_vertical_angles)):
 | 
						|
        curr_angle = _vertical_angles[vertical_index]
 | 
						|
        if curr_angle > vertical_angle:
 | 
						|
            prev_angle = _vertical_angles[vertical_index - 1]
 | 
						|
            prev_value = get_candela_value_from_index(vertical_index - 1, horizontal_angle_idx)
 | 
						|
            curr_value = get_candela_value_from_index(vertical_index, horizontal_angle_idx)
 | 
						|
            lerp = (vertical_angle - prev_angle) / (curr_angle - prev_angle)
 | 
						|
            assert lerp >= 0.0 and lerp <= 1.0
 | 
						|
            return curr_value * lerp + prev_value * (1.0 - lerp)
 | 
						|
    return 0.0
 | 
						|
 | 
						|
def get_candela_value_from_index(vertical_angle_idx, horizontal_angle_idx):
 | 
						|
    index = vertical_angle_idx + horizontal_angle_idx * len(_vertical_angles)
 | 
						|
    return _candela_values[index]
 | 
						|
 | 
						|
filepath = "/Users/onek8/Desktop/ies/JellyFish.ies"
 | 
						|
load(filepath)
 |