diff --git a/.idea/PathTracing.iml b/.idea/PathTracing.iml index 6711606..f58f256 100644 --- a/.idea/PathTracing.iml +++ b/.idea/PathTracing.iml @@ -2,7 +2,7 @@ - + diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..1cc4cad --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,17 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..3b31283 --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml index edf7f64..a36c67b 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -10,46 +10,41 @@ - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + ortho + image_height + windows + window + height + black + BLAC + 0.0, 0.0, 0.0 + BLACK + view + white + filename + light + up + focal + camera + cross + random + change to a + - - + + - + - - - - - + + + + + - - - + + + - - + + + + + + + + + + - + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + - - + + diff --git a/PyPath.py b/PyPath.py index 8fd497d..17dc3eb 100644 --- a/PyPath.py +++ b/PyPath.py @@ -7,25 +7,26 @@ #Modules from math import sqrt, cos, sin -from random import random, gauss +from random import random, gauss, randrange import array #for writing .ppm image file from winsound import Beep #for beep sound when complete from tkinter import * #for GUI +from main import prop_dict, obj_list #========================================# #==============CHANGE THESE==============# #Must be a string like the default below #and have .ppm extension as shown below -FILENAME = 'PyPath_Output.ppm' +FILENAME = prop_dict['output'] #Must be a string like the default below -DIRECTORY = 'C:\\Users\luish\ProgramasNovos\\' +DIRECTORY = './' # alterar de acordo com computador #==============CHANGE THESE==============# #========================================# #Constants EPSILON = 0.0001 HUGEVALUE = 1000000.0 #1 million -MAXDEPTH = 1 #max ray bounces +MAXDEPTH = 5 #max ray bounces PI = 3.1415926535897932384 TWO_PI = 6.2831853071795864769 INVERTED_PI = 0.3183098861837906912 @@ -146,7 +147,7 @@ def OrientedHemiDir(u1, u2, normal, exp): #Lambertian class BxDF: def __init__(self): - self.ke = BLACK #default, unless set with set_emission() + self.ke = RGBColour(prop_dict['ambient'], prop_dict['ambient'], prop_dict['ambient']) #default, unless set with set_emission() - change to ambient def set_emission(self, emission_colour): self.ke = emission_colour def get_emission(self): @@ -325,55 +326,57 @@ def __init__(self): self.primitives = [] #trace light path def trace_ray(self, ray, depth): - result = RGBColour(0.0, 0.0, 0.0) #black - t = HUGEVALUE - index = -1 #-1 means no hit - - if depth > MAXDEPTH: - return result - - #find closest hit object, its distance, hit_point and normal - #scan through primitives in scene, find closest - for i in range(0, len(self.primitives)): - #intersect returns tuple of (bool hit, distance, hit_point, normal) - hit_data = self.primitives[i].intersect(ray) - if hit_data[0] == True: #Hit - if hit_data[1] < t: #Distance - t = hit_data[1] - hit_point = hit_data[2] #hit_point - normal = hit_data[3] #normal - index = i #closest primitive index number - - if index == -1: #No Hit - return BLACK - - else: #Hit - wo = ray.d * -1.0 #outgoing (towards camera) - normal = orient_normal(normal, wo) #make normal point in correct direction - - #sample_f returns tuple (incoming direction, pdf) - shading_data = self.primitives[index].get_BxDF().sample_f(normal, wo) - wi = shading_data[0] #incoming direction - pdf = shading_data[1] #pdf - if pdf <= 0.0: - pdf = 1.0 - - f = self.primitives[index].get_BxDF().f(wi, wo, normal) - incoming_ray = Ray(hit_point, wi) #make incoming to follow - - #Russian Roulette - RR_prob = 0.66 - if depth > 2: - if(random() < RR_prob): #2/3 chance we stop here - return result + result = RGBColour(prop_dict['background'][0], prop_dict['background'][1], prop_dict['background'][2]) #black - change to background + t = HUGEVALUE + index = -1 #-1 means no hit + + if depth > MAXDEPTH: + return result + + #find closest hit object, its distance, hit_point and normal + #scan through primitives in scene, find closest + for i in range(0, len(self.primitives)): + #intersect returns tuple of (bool hit, distance, hit_point, normal) + hit_data = self.primitives[i].intersect(ray) + if hit_data[0] == True: #Hit + if hit_data[1] < t: #Distance + t = hit_data[1] + hit_point = hit_data[2] #hit_point + normal = hit_data[3] #normal + index = i #closest primitive index number + + if index == -1: #No Hit + return RGBColour(prop_dict['background'][0], prop_dict['background'][1], prop_dict['background'][2]) + + else: #Hit + wo = ray.d * -1.0 #outgoing (towards camera) + normal = orient_normal(normal, wo) #make normal point in correct direction + + #sample_f returns tuple (incoming direction, pdf) + shading_data = self.primitives[index].get_BxDF().sample_f(normal, wo) + wi = shading_data[0] #incoming direction + pdf = shading_data[1] #pdf + if pdf <= 0.0: + pdf = 1.0 + + f = self.primitives[index].get_BxDF().f(wi, wo, normal) + incoming_ray = Ray(hit_point, wi) #make incoming to follow + + + #Russian Roulette + RR_prob = 0.66 + if depth > 2: + if(random() < RR_prob): #2/3 chance we stop here + return result + + result = result + f.multiply(self.trace_ray(incoming_ray, depth + 1)) * Dot(wi, normal) / pdf + #result = (result + f.multiply(self.trace_ray(incoming_ray, depth + 1)) * Dot(wi, normal) / pdf)/2 + #Add emission + result = result + self.primitives[index].get_BxDF().get_emission() + result = result / RR_prob + return result #return final colour - result = result + f.multiply(self.trace_ray(incoming_ray, depth + 1)) * Dot(wi, normal) / pdf - #Add emission - result = result + self.primitives[index].get_BxDF().get_emission() - result = result / RR_prob - return result #return final colour - #add objects def add_primitive(self, primitive): self.primitives.append(primitive) @@ -477,13 +480,89 @@ def render(self, integrator): self.save_image(FILENAME) #FILENAME is define at top of source file #Play sound to signal a beep (For Windows) for i in range (1, 4): - Beep(i * 500, 250) + Beep(i * 500, 250) #-------------------------------------------------Main #Create Integrator path_tracer = PathTraceIntegrator() #Create Primitives w/ Materials #materials + +b = randrange(3) +b = 0 + +#Adicionando primeiro obj +for tFaces in obj_list[0].faces : + i = 0 + a = 0.0 + b = 0.0 + c = 0.0 + ve = [] + p = [] + q = [] + for x in obj_list[0].faces: + ve = (obj_list[0].faces[i]) + d = 0 + i = i+1 + for j in ve: + print(ve[d]) + if d == 0: + a = (obj_list[0].vertices[ve[d]-1]) + if d == 1: + b = (obj_list[0].vertices[ve[d]-1]) + if d == 2: + c = (obj_list[0].vertices[ve[d]-1]) + d = d+1 + p = a - b + q = a - c + a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x + n = p[1]*q[2] - p[2]*q[1], p[2]*q[0] - p[0]*q[2], p[0]*q[1] - p[1]*q[0] + white_emitt_plane = Lambertian(RGBColour(1.0, 1.0, 1.0)) # emitindo luz branca enquanto obj não está desenhado + white_emitt_plane.set_emission(RGBColour(1.0, 1.0, 1.0)) # emitindo luz branca enquanto obj não está desenhado + plane_2 = Plane(Vector3D(obj_list[0].vertices[0][0], obj_list[0].vertices[0][1], obj_list[0].vertices[0][2]), Vector3D(n[0], n[1], n[2])) + plane_2.set_BxDF(white_emitt_plane) # trocado de cinza para branco + path_tracer.add_primitive(plane_2) + + +red2_emit = Lambertian(RGBColour(0.7, 0.0, 0.0)) +red2_emit.set_emission(RGBColour(1.0, 0.0, 0.0)) +green_emit = Lambertian(RGBColour(0.0, 0.7, 0.0)) +green_emit.set_emission(RGBColour(0.0, 1.0, 0.0)) +floor_emit = Lambertian(RGBColour(0.7, 0.7, 0.7)) +floor_emit.set_emission(RGBColour(1.0, 1.0, 1.0)) +white_emitt_plane = Lambertian(RGBColour(1.0, 1.0, 1.0)) # emitindo luz branca enquanto obj não está desenhado +white_emitt_plane.set_emission(RGBColour(1.0, 1.0, 1.0)) # emitindo luz branca enquanto obj não está desenh + +if (b==0) : + + red2_emit = Lambertian(RGBColour(0.7, 0.0, 0.0)) + red2_emit.set_emission(RGBColour(1.0, 0.0, 0.0)) + green_emit = Lambertian(RGBColour(0.0, 0.7, 0.0)) + green_emit.set_emission(RGBColour(0.0, 1.0, 0.0)) + floor_emit = Lambertian(RGBColour(0.7, 0.7, 0.7)) + floor_emit.set_emission(RGBColour(1.0, 1.0, 1.0)) + + +if (b==1) : + + red2_emit = PerfectSpecular(RGBColour(0.0, 0.0, 0.0)) + red2_emit.set_emission(RGBColour(1.0, 0.0, 0.0)) + green_emit = PerfectSpecular(RGBColour(0.0, 0.0, 0.0)) + green_emit.set_emission(RGBColour(0.0, 1.0, 0.0)) + floor_emit = PerfectSpecular(RGBColour(0.0, 0.0, 0.0)) + floor_emit.set_emission(RGBColour(1.0, 1.0, 1.0)) + + +if (b==2) : + + red2_emit = GlossySpecular(RGBColour(0.0, 0.0, 0.0), 0) + red2_emit.set_emission(RGBColour(1.0, 0.0, 0.0), 0) + green_emit = GlossySpecular(RGBColour(0.0, 0.0, 0.0), 0) + green_emit.set_emission(RGBColour(0.0, 1.0, 0.0)) + floor_emit = GlossySpecular(RGBColour(0.0, 0.0, 0.7), 0) + floor_emit.set_emission(RGBColour(1.0, 1.0, 1.0)) + + gold_diff = Lambertian(RGBColour(1.0, 0.8, 0.3)) ground_diff = Lambertian(RGBColour(0.15, 0.15, 0.15)) red_emitt = Lambertian(RGBColour(3.0, 0.0, 0.0)) @@ -508,6 +587,7 @@ def render(self, integrator): path_tracer.add_primitive(sphere_3) #sphere 4 - mirror front sphere_4 = Sphere(Vector3D(4.0, -8.0, 20.0), 8.0) +#sphere_4 = Sphere(Vector3D(3.411, -3.8416, -16.59), 2.0) sphere_4.set_BxDF(glossy) path_tracer.add_primitive(sphere_4) #plane 1 - bottom ground @@ -515,17 +595,39 @@ def render(self, integrator): plane_1.set_BxDF(ground_diff) path_tracer.add_primitive(plane_1) #plane 2 - top light -plane_2 = Plane(Vector3D(0.0, 45.0, 0.0), Vector3D(0.0, -1.0, 0.0)) -plane_2.set_BxDF(grey_emitt_plane) -path_tracer.add_primitive(plane_2) +#plane_2 = Plane(Vector3D(0.0, 45.0, 0.0), Vector3D(0.0, -1.0, 0.0)) +#plane_2 = Plane(Vector3D(-0.91, 3.836, -23.324), Vector3D(0.0, -5.758479999999996, 0.0)) +#plane_2.set_BxDF(white_emitt_plane) # trocado de cinza para branco +#path_tracer.add_primitive(plane_2) + +plane_3 = Plane(Vector3D(-3.822, -3.8416, -16.59), Vector3D(124.237344, 0.0, 0.0)) +plane_3.set_BxDF(red2_emit) # esq +path_tracer.add_primitive(plane_3) +plane_4 = Plane(Vector3D(3.822, -3.8416, -32.76), Vector3D(-124.237344, 0.0, 0.0)) +plane_4.set_BxDF(green_emit) # dir +path_tracer.add_primitive(plane_4) +plane_5 = Plane(Vector3D(3.822, -3.8416, -16.59), Vector3D(0.0, 123.60347999999999, 0.0)) +plane_5.set_BxDF(floor_emit) # chao +path_tracer.add_primitive(plane_5) +plane_6 = Plane(Vector3D(-3.822, -3.8416, -32.76), Vector3D(0.0, 0.0, 58.730380800000006)) +plane_6.set_BxDF(floor_emit) # atras +path_tracer.add_primitive(plane_6) +plane_7 = Plane(Vector3D(3.822, 3.8416, -32.76), Vector3D(0.0, -123.60347999999999, 0.0)) +plane_7.set_BxDF(floor_emit) # chao +path_tracer.add_primitive(plane_7) + + #Create Camera -eye = Vector3D(-3.0, 0.0, 190.0) #higher z = more narrow view +eye = Vector3D(prop_dict['eye'][0], prop_dict['eye'][1], prop_dict['eye'][2]) #higher z = more narrow view +#eye = Vector3D(-3.0, 0.0, 190.0) # para testar focal = Vector3D(0.0, 0.0, 0.0) view_distance = 1000 #larger = more orthographic like up = Vector3D(0.0, 1.0, 0.0) +#height = int (prop_dict['size'][0]) +#width = int (prop_dict['size'][1]) height = 400 width = 400 -spp = 128 +spp = int (prop_dict['npaths']) cam = Camera(eye, focal, view_distance, up, height, width, spp) cam.render(path_tracer) #trace scene and save image diff --git a/__pycache__/PyPath.cpython-35.pyc b/__pycache__/PyPath.cpython-35.pyc new file mode 100644 index 0000000..d1f058b Binary files /dev/null and b/__pycache__/PyPath.cpython-35.pyc differ diff --git a/__pycache__/helper.cpython-35.pyc b/__pycache__/helper.cpython-35.pyc index 7086c5a..5b1d696 100644 Binary files a/__pycache__/helper.cpython-35.pyc and b/__pycache__/helper.cpython-35.pyc differ diff --git a/__pycache__/main.cpython-35.pyc b/__pycache__/main.cpython-35.pyc new file mode 100644 index 0000000..101c4e2 Binary files /dev/null and b/__pycache__/main.cpython-35.pyc differ diff --git a/__pycache__/objetos.cpython-35.pyc b/__pycache__/objetos.cpython-35.pyc index 49b342a..8a3ea30 100644 Binary files a/__pycache__/objetos.cpython-35.pyc and b/__pycache__/objetos.cpython-35.pyc differ diff --git a/cornell.pnm b/cornell.pnm new file mode 100644 index 0000000..f3eef2a Binary files /dev/null and b/cornell.pnm differ diff --git a/helper.py b/helper.py index 66e2e1c..bdb2f1d 100644 --- a/helper.py +++ b/helper.py @@ -75,7 +75,7 @@ def output(self,values): def __get_faces(self, name): faces = [] - f = open ('.\src\\' + name, 'r') + f = open ('./src//' + name, 'r') for line in f: # Pulando linhas em branco @@ -100,7 +100,7 @@ def __get_vertices(self, name): vertices = [] faces = [] - f = open ('.\src\\' + name, 'r') + f = open ('./src//' + name, 'r') for line in f: # Pulando linhas em branco @@ -137,4 +137,4 @@ def read(t, values): # Chamamos a função com nome read_ + tipo do valor a ser lido(object, light, eye...) func = getattr(read, t) result = func(values) - return result \ No newline at end of file + return result diff --git a/main.py b/main.py index 29027ae..25d7cf5 100644 --- a/main.py +++ b/main.py @@ -2,10 +2,11 @@ Responsavel por controlar o aplicativo """ from helper import read +from random import random, gauss, randrange print("Lendo Arquivos de configuração e Objetos") -file = ".\src\cornellroom.sdl" +file = "./src/cornellroom.sdl" obj_types_list = ['object','quad', 'light'] prop_types_list = ['eye', 'size', 'ortho', 'background', 'ambient', 'tonemapping', 'npaths', 'seed', 'output'] @@ -37,4 +38,37 @@ print("Lista de objetos: ", obj_list) print("Lista de propriedades: ", prop_dict) -# Inicializando objetos da cena \ No newline at end of file +print(obj_list[0].vertices) +i = 0 +a = 0.0 +b = 0.0 +c = 0.0 +ve = [] +p = [] +q = [] +for x in obj_list[5].faces: + print((obj_list[5].faces[i])) + ve = (obj_list[5].faces[i]) + d = 0 + i = i+1 + for j in ve: + print(ve[d]) + if d == 0: + a = (obj_list[5].vertices[ve[d]-1]) + if d == 1: + b = (obj_list[5].vertices[ve[d]-1]) + if d == 2: + c = (obj_list[5].vertices[ve[d]-1]) + d = d+1 + p = a - b + q = a - c + print(p) + print(q) + a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x + n = p[1]*q[2] - p[2]*q[1], p[2]*q[0] - p[0]*q[2], p[0]*q[1] - p[1]*q[0] + print(n) + b = randrange(3) + print(b) +print(obj_list[0].vertices[0][0]) +#print(str (obj_types_list['light'][0])) +# Inicializando objetos da cena diff --git a/src/cornellroom.sdl b/src/cornellroom.sdl index 59b6cca..467b55d 100644 --- a/src/cornellroom.sdl +++ b/src/cornellroom.sdl @@ -14,7 +14,7 @@ ambient 0.5 # Luz branca retangulo no centro do teto light luzcornell.obj 1.0 1.0 1.0 1.0 -npaths 10 +npaths 30 tonemapping 1.0 seed 9