Source code for photonmap.Reader.ReadRADGeo

from photonmap.Common.Math import *
from openalea.plantgl.all import * 


import re

#Objectif of this module is read the geometry of each object of fichier RAD

[docs] def cylinder_vertices(start, end, rayon): """ Generate the geometry of a cylinder Parameters ---------- start: Vec3 The center of the first circle of cylinder end: Vec3 The center of the second circle of cylinder rayon: float The radius of these two circles Returns ------- A array of vertices of an cylinder """ vert = [] direction = end - start direction.normalize() horizontal = crossVector(direction, Vector3(0,0,1)) v1 = end + rayon * horizontal v2 = start + rayon * horizontal v3 = start - rayon * horizontal v4 = end - rayon * horizontal vert.append((v1[0], v1[1], v1[2])) vert.append((v2[0], v2[1], v2[2])) vert.append((v3[0], v3[1], v3[2])) vert.append((v4[0], v4[1], v4[2])) return vert
[docs] def read_rad(file: str, scale_factor: int, invert_normals: bool): """ Parse a radiance file (https://radsite.lbl.gov/radiance/framed.html) to a make a plantGL Scene Parameters ---------- file: str the rad filename scale_factor: int The size of geometries. The vertices of geometries is recalculated by dividing their coordinates by this value invert_normals: bool whether to invert the normals or not. Returns ------- A plantGL Scene. """ with open(file, "r") as f: lines = f.readlines() materials = {} shapes = {} sc = Scene() i = 0 for _ in range(len(lines)): i += 1 if i >= len(lines): break elif lines[i].startswith("#"): continue elif lines[i].startswith("void"): # material li = lines[i].split(None) type = li[1] name = li[2].strip("\n") # print("material name: " + str(name)) if materials.get(name) is None: if type == "plastic": li = lines[i + 4].split(None) color = Color3( denormalize(float(li[0])), denormalize(float(li[1])), denormalize(float(li[2])), ) spec = Color3( denormalize(float(li[3])), denormalize(float(li[3])), denormalize(float(li[3])), ) roughness = float(li[4]) mat = { "name": name, "type": type, "color": color, "spec": spec, "roughness": roughness, } materials[name] = mat i += 5 elif type == "metal": li = lines[i + 4].split(None) color = Color3( denormalize(float(li[0])), denormalize(float(li[1])), denormalize(float(li[2])), ) spec = Color3( denormalize(float(li[3])), denormalize(float(li[3])), denormalize(float(li[3])), ) roughness = float(li[4]) mat = { "name": name, "type": type, "color": color, "spec": spec, "roughness": roughness, } materials[name] = mat i += 5 elif type == "trans": li = lines[i + 4].split(None) color = Color3( denormalize(float(li[0])), denormalize(float(li[1])), denormalize(float(li[2])), ) spec = Color3( denormalize(float(li[3])), denormalize(float(li[3])), denormalize(float(li[3])), ) roughness = float(li[4]) trans = float(li[5]) tspec = float(li[6]) mat = { "name": name, "type": type, "color": color, "spec": spec, "roughness": roughness, "trans": trans, "tspec": tspec, } materials[name] = mat i += 5 elif type == "light": li = lines[i + 4].split(None) color = Color3( denormalize(float(li[0])), denormalize(float(li[1])), denormalize(float(li[2])), ) mat = {"name": name, "type": type, "color": color} materials[name] = mat i += 5 else: keys = materials.keys() for k in keys: if lines[i].startswith(k): li = lines[i].split(None) material = li[0] type = li[1] name = li[2].strip("\n") if type == "point_light" or type == "point": i += 1 vert = [] l = re.split(r"\s+|;+", lines[i]) vert.append( ( float(l[0]) / scale_factor, float(l[1]) / scale_factor, float(l[2]) / scale_factor, ) ) shapes[name] = { "vertices": vert, "type": type, "size": 1, "material": material, } else: i += 3 vert = [] size = int(lines[i]) tmp = i + 1 nbCoords = int(size / 3) if type == "cylinder": l = re.split(r"\s+|;+", lines[i + 1]) l2 = re.split(r"\s+|;+", lines[i + 2]) l3 = re.split(r"\s+|;+", lines[i + 3]) r = float(l3[0]) / scale_factor x, y, z = ( float(l[0]) / scale_factor, float(l[1]) / scale_factor, float(l[2]) / scale_factor, ) x2, y2, z2 = ( float(l2[0]) / scale_factor, float(l2[1]) / scale_factor, float(l2[2]) / scale_factor, ) vert = cylinder_vertices(Vector3(x,y,z), Vector3(x2,y2,z2), 0) # vert.append((x + r, y + r, z + r)) # vert.append((x - r, y - r, z - r)) # vert.append((x2 + r, y2 + r, z2 + r)) # vert.append((x2 - r, y2 - r, z2 - r)) shapes[name] = { "vertices": vert, "type": type, "size": len(vert), "material": material, } i += 3 elif type == "cone": l = re.split(r"\s+|;+", lines[i + 1]) l2 = re.split(r"\s+|;+", lines[i + 2]) l3 = re.split(r"\s+|;+", lines[i + 3]) r = float(l3[0]) / scale_factor r2 = float(l3[1]) / scale_factor x, y, z = ( float(l[0]) / scale_factor, float(l[1]) / scale_factor, float(l[2]) / scale_factor, ) x2, y2, z2 = ( float(l2[0]) / scale_factor, float(l2[1]) / scale_factor, float(l2[2]) / scale_factor, ) ratio = r / r2 pos = [x, y, z] newCone = Frustum() newCone.taper = 1.0 + ratio newCone.height = z2 * 10 - z * 10 ts = Tesselator() newCone.apply(ts) mesh = ts.result maxi = 0 for i in range(0, mesh.indexListSize()): index = mesh.indexAt(i) typeF = mesh.faceSize(i) for j in range(0, typeF): if index[j] > maxi: maxi = index[j] for u in range(0, maxi + 1): mvector = mesh.pointAt(u) mesh.pointList[u] = ( mvector[0] / 10 + pos[0], mvector[1] / 10 + pos[1], mvector[2] / 10 + pos[2], ) shapes[name] = { "vertices": vert, "type": type, "size": len(vert), "material": material, "mesh": mesh, } i += 3 else: for j in range(tmp, tmp + nbCoords): l = re.split(r"\s+|;+", lines[j]) vert.append( ( float(l[0]) / scale_factor, float(l[1]) / scale_factor, float(l[2]) / scale_factor, ) ) i = j shapes[name] = { "vertices": vert, "type": type, "size": size, "material": material, } for sh, val in shapes.items(): mat_key = val["material"] mat = materials[mat_key] vert = val["vertices"] s = Shape() nbCoords = int(val["size"] / 3) if val.get("mesh") is not None: print("mesh detected") s.name = sh s.geometry = val["mesh"] if mat["type"] == "light": s.name += str(vert[0]) s.appearance = Material( name=name, ambient=Color3(mat["color"]), emission=Color3(mat["color"]), ) elif mat["type"] == "trans": s.appearance = Material( name=mat["name"], ambient=Color3(mat["color"]), specular=Color3(mat["spec"]), shininess=1 - mat["roughness"], transparency=mat["trans"], ) else: if Color3(mat["spec"]) == Color3(0, 0, 0): s.appearance = Material( name=mat["name"], ambient=Color3(mat["color"]), shininess=1 - mat["roughness"], ) else: s.appearance = Material( name=mat["name"], ambient=Color3(mat["color"]), specular=Color3(mat["spec"]), shininess=1 - mat["roughness"], ) s.appearance.name = mat["name"] sc.add(s) elif nbCoords % 3 == 0: ts = TriangleSet(vert) i = 0 indList = [] if nbCoords == 9: ind = Index3(i, i + 1, i + 2) indList.append(ind) ind = Index3(i, i + 2, i + 3) indList.append(ind) ind = Index3(i, i + 3, i + 4) indList.append(ind) ind = Index3(i, i + 4, i + 5) indList.append(ind) ind = Index3(i, i + 5, i + 6) indList.append(ind) ind = Index3(i, i + 6, i + 7) indList.append(ind) ind = Index3(i, i + 7, i + 8) indList.append(ind) else: while i < nbCoords: if invert_normals: ind = Index3(i, i + 2, i + 1) else: ind = Index3(i, i + 1, i + 2) indList.append(ind) i += 3 ts.indexList = Index3Array(indList) ts.computeNormalList() s.geometry = ts s.name = sh if mat["type"] == "light": s.name += str(vert[0]) s.appearance = Material( name=name, ambient=Color3(mat["color"]), emission=Color3(mat["color"]), ) elif mat["type"] == "trans": s.appearance = Material( name=mat["name"], ambient=Color3(mat["color"]), specular=Color3(mat["spec"]), shininess=1 - mat["roughness"], transparency=mat["trans"], ) else: if Color3(mat["spec"]) == Color3(0, 0, 0): s.appearance = Material( name=mat["name"], ambient=Color3(mat["color"]), shininess=1 - mat["roughness"], ) else: s.appearance = Material( name=mat["name"], ambient=Color3(mat["color"]), specular=Color3(mat["spec"]), shininess=1 - mat["roughness"], ) s.appearance.name = mat["name"] sc.add(s) else: #triangulate quad ts = TriangleSet(vert) i = 0 indList = [] while i < nbCoords: if invert_normals: ind = Index3(i, i + 2, i + 1) ind2 = Index3(i, i + 3, i + 2) else: ind = Index3(i, i + 1, i + 2) ind2 = Index3(i, i + 2, i + 3) indList.append(ind) indList.append(ind2) i += 4 ts.indexList = Index3Array(indList) ts.computeNormalList() s.geometry = ts s.name = sh if mat["type"] == "light": s.appearance = Material( name=mat["name"], ambient=Color3(mat["color"]), emission=Color3(mat["color"]), ) elif mat["type"] == "trans": s.appearance = Material( name=mat["name"], ambient=Color3(mat["color"]), specular=Color3(mat["spec"]), shininess=1 - mat["roughness"], transparency=mat["trans"], ) else: if Color3(mat["spec"]) == Color3(0, 0, 0): s.appearance = Material( name=mat["name"], ambient=Color3(mat["color"]), shininess=1 - mat["roughness"], ) else: s.appearance = Material( name=mat["name"], ambient=Color3(mat["color"]), specular=Color3(mat["spec"]), shininess=1 - mat["roughness"], ) s.appearance.name = mat["name"] sc.add(s) save_name = file.split(".")[0] + ".obj" sc.save(save_name) return sc