Skip to content

Commit

Permalink
No commit message
Browse files Browse the repository at this point in the history
  • Loading branch information
neodyme60 committed Sep 26, 2014
1 parent 3dbc6b9 commit e5f5f9b
Show file tree
Hide file tree
Showing 45 changed files with 1,037 additions and 294 deletions.
3 changes: 2 additions & 1 deletion aggregates/simple.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from core.aggregate import Aggregate


class Simple(Aggregate):

def __init__(self):
pass
Aggregate.__init__(self)
39 changes: 39 additions & 0 deletions application.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from PyQt4 import QtCore, QtGui
import numpy
import array
from core.film import Film


class Application(QtGui.QMainWindow):
def __init__(self, w: int, h: int, film: Film):
super(Application, self).__init__()
self.w = w
self.h = h
self.i = 0
self.film = film
self.initUI()

def updateData(self):
self.qimage = QtGui.QImage(self.film.data, self.w, self.h, QtGui.QImage.Format_RGB32)
self.pix = QtGui.QPixmap.fromImage(self.qimage)
self.myScaledPixmap = self.pix.scaled(self.imageLabel.size(), QtCore.Qt.KeepAspectRatio)
self.imageLabel.setPixmap(self.myScaledPixmap)
self.i += 1

def initUI(self):
self.statusBar().showMessage('Ready')

self.imageLabel = QtGui.QLabel('Zetcode', self)
self.imageLabel.setGeometry(QtCore.QRect(0, 0, self.w, self.h))
self.imageLabel.setBackgroundRole(QtGui.QPalette.Base)
self.imageLabel.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
self.imageLabel.setScaledContents(True)

# SET UP RECURRING EVENTS
self.timer = QtCore.QTimer()
self.timer.start(0.2)
self.connect(self.timer, QtCore.SIGNAL('timeout()'), self.updateData)

self.setGeometry(300, 300, self.w, self.h)
self.setWindowTitle('Absolute')
self.show()
12 changes: 6 additions & 6 deletions camera/perspective_camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
from core.film import Film
from core.camera_sample import CameraSample
from core.ray import Ray
from maths.config import INFINITY_F
from maths.config import infinity_max_f

class PerspectiveCamera(ProjectiveCamera):

def __init__(self, cam2world:Transform, sopen:float, sclose:float, lensr:float, focald:float, fov:float, film:Film):
super(ProjectiveCamera, self).__init__(cam2world, ProjectiveCamera(cam2world, Transform.create_perspective(fov, 1e-2, 1000.0)), sopen, sclose, lensr, focald, film)
self.dxCamera = (Point3d(1.0, 0.0 ,0.0) * self.rasterToCamera) - (Point3d(0.0, 0.0, 0.0) - self.rasterToCamera)
self.dyCamera = (Point3d(0.0, 1.0 ,0.0) * self.rasterToCamera) - (Point3d(0.0, 0.0, 0.0) - self.rasterToCamera)
def __init__(self, cam2world: Transform, sopen: float, sclose: float, lensr: float, focald: float, fov: float, film: Film):
ProjectiveCamera.__init__(self, cam2world, Transform.create_perspective(fov, 1e-2, 1000.0), sopen, sclose, lensr, focald, film)
self.dxCamera = (Point3d(1.0, 0.0 ,0.0) * self.rasterToCamera) - (Point3d(0.0, 0.0, 0.0) * self.rasterToCamera)
self.dyCamera = (Point3d(0.0, 1.0 ,0.0) * self.rasterToCamera) - (Point3d(0.0, 0.0, 0.0) * self.rasterToCamera)

def GenerateRay(self, sample:CameraSample, r: Ray):
point_camera = Point3d(sample.image_x, sample.image_y, 0.0) * self.rasterToCamera()
r = Ray(Point3d(0.0, 0.0, 0.0), point_camera, 0.0, INFINITY_F)
r = Ray(Point3d(0.0, 0.0, 0.0), point_camera, 0.0, infinity_max_f)
return r * self.camera_to_world
2 changes: 1 addition & 1 deletion core/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__author__ = 'nicolas'
1 change: 0 additions & 1 deletion core/aggregate.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from core.primitive import Primitive

__author__ = 'nicolas'

class Aggregate(Primitive):

Expand Down
103 changes: 103 additions & 0 deletions core/bbox.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
from core.ray import Ray
from maths.config import infinity_max_f, infinity_min_f
from maths.point3d import Point3d
from maths.vector3d import Vector3d


class BoundingBox:
def __init__(self, pMin: Point3d(infinity_max_f, infinity_max_f, infinity_max_f),
pMax: Point3d(infinity_min_f, infinity_min_f, infinity_min_f)):
self.pMin = pMin
self.pMax = pMax

@staticmethod
def create_from_point3d(p: Point3d):
return BoundingBox(p, p)

@staticmethod
def create_from_two_point3d(p_min: Point3d, p_max: Point3d):
return BoundingBox(p_min, p_max)

def get_is_overlapped(self, b) -> bool:
x = (self.pMax.x >= b.pMin.x) and (self.pMin.x <= b.pMax.x)
y = (self.pMax.y >= b.pMin.y) and (self.pMin.y <= b.pMax.y)
z = (self.pMax.z >= b.pMin.z) and (self.pMin.z <= b.pMax.z)
return x and y and z

def get_union_point3d(self, p: Point3d):
p_min = Point3d(min(self.pMin.x, p.x), min(self.pMin.y, p.y), min(self.pMin.z, p.z))
p_max = Point3d(max(self.pMax.x, p.x), max(self.pMax.y, p.y), max(self.pMax.z, p.z))
return BoundingBox.create_from_two_point3d(p_min, p_max)

def get_union_bbox(self, b):
p_min = Point3d(min(self.pMin.x, b.pMin.x), min(self.pMin.y, b.pMin.y), min(self.pMin.z, b.pMin.z))
p_max = Point3d(max(self.pMax.x, b.pMax.x), max(self.pMax.y, b.pMax.y), max(self.pMax.z, b.pMax.z))
return BoundingBox.create_from_two_point3d(p_min, p_max)

def get_is_point_inside(self, p: Point3d) -> bool:
return (
p.x >= self.pMin.x and p.x <= self.pMax.x and p.y >= self.pMin.y and p.y <= self.pMax.y and p.z >= self.pMin.z and p.z <= self.pMax.z)

def expand(self, delta: float):
self.pMin -= Vector3d(delta, delta, delta)
self.pMax += Vector3d(delta, delta, delta)

def get_surface_area(self) -> float:
d = self.pMax - self.pMin
return 2.0 * (d.x * d.y + d.x * d.z + d.y * d.z)

def get_volume(self) -> float:
d = self.pMax - self.pMin
return d.x * d.y * d.z

def get_maximum_extent(self) -> int:
diag = self.pMax - self.pMin
if diag.x > diag.y and diag.x > diag.z:
return 0
elif diag.y > diag.z:
return 1
else:
return 2

def get_offset(self, p: Point3d) -> Point3d:
return p - self.pMin / (self.pMax - self.pMin)

def __eq__(self, other):
if type(other) is not BoundingBox:
return NotImplemented

if self.pMax == other.pMax and self.pMin == other.pMin:
return True
return False

def __ne__(self, other):
return not self.__eq__(other)

def __le__(self, other):
raise NotImplemented

def __gt__(self, other):
raise NotImplemented

def __ge__(self, other):
raise NotImplemented

def get_intersect(self, r: Ray) -> (float, float):
t0 = r.min_t
t1 = r.max_t
for i in range(3):
# Update interval for _i_th bounding box slab
inv_direction = 1.0 / r.direction[i]
t_near = (self.pMin[i] - r.origin[i]) * inv_direction
t_far = (self.pMax[i] - r.origin[i]) * inv_direction

# Update parametric interval from slab intersection $t$s
if t_near > t_far:
t_near, t_far = t_far, t_near
if t_near > t0:
t0 = t_near
if t_far < t1:
t1 = t_far
if t0 > t1:
return None, None
return t0, t1
132 changes: 132 additions & 0 deletions core/buckets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
from enum import Enum
import random


class BucketOrderSortType(Enum):
Row = 0
Column = 1
Diagonal = 2
Spiral = 3
Hilbert = 4
Random = 5

class BucketOrder:
def __init__(self, width: int, height: int, sort_order: BucketOrderSortType):
self.buckets_orders = []
self.width = width
self.height = height
self.sort_order = sort_order

@staticmethod
def create(width: int, height: int, sort_order: BucketOrderSortType):
if sort_order == BucketOrderSortType.Row:
return RowBucketOrder(width, height)
elif sort_order == BucketOrderSortType.Random:
return RandomBucketOrder(width, height)
elif sort_order == BucketOrderSortType.Hilbert:
return HilbertBucketOrder(width, height)
elif sort_order == BucketOrderSortType.Diagonal:
return DiagonalBucketOrder(width, height)
else:
return RandomBucketOrder(width, height)


class BucketOrderInfo:
def __init__(self, bucket_order_type: BucketOrderSortType, width: int, height: int):
self.bucket_order_type = bucket_order_type
self.width = width
self.height = height


class RowBucketOrder(BucketOrder):
def __init__(self, width: int, height: int):

BucketOrder.__init__(self, width, height, BucketOrderSortType.Row)

for i in range(self.height * self.width):
by = i // self.width
bx = i % self.width
if (by & 1) == 1:
bx = self.width - 1 - bx
self.buckets_orders.append(bx + by * self.width)


class RandomBucketOrder(BucketOrder):
def __init__(self, width: int, height: int):

BucketOrder.__init__(self, width, height, BucketOrderSortType.Random)

for i in range(self.height * self.width):
by = i // self.width
bx = i % self.width
if (by & 1) == 1:
bx = self.width - 1 - bx
self.buckets_orders.append(bx + by * self.width)

random.shuffle(self.buckets_orders)


class DiagonalBucketOrder(BucketOrder):
def __init__(self, width: int, height: int):

BucketOrder.__init__(self, width, height, BucketOrderSortType.Random)

x = y = 0
nx = 1
ny = 0
for i in range(self.height * self.width):
self.buckets_orders.append(x + y * self.width)

while True:
if y == ny:
y = 0
x = nx
ny += 1
nx += 1
else:
x -= 1
y += 1
if not ((y >= height or x >= width) and i != (width * height - 1)):
break


class HilbertBucketOrder(BucketOrder):

def __init__(self, width: int, height: int):
BucketOrder.__init__(self, width, height, BucketOrderSortType.Random)
hi = hn = 0
while ((1 << hn) < width or (1 << hn) < height) and hn < 16:
hn += 1
hnn = 1 << (2 * hn)
n = width * height
for i in range(n):
hx = 0
hy = 0
while True:
s = hi
s |= 0x55555555 << (2 * hn)
sr = (s >> 1) & 0x55555555
cs = ((s & 0x55555555) + sr) ^ 0x55555555
cs ^= cs >> 2
cs ^= cs >> 4
cs ^= cs >> 8
cs ^= cs >> 16
swap = cs & 0x55555555
comp = (cs >> 1) & 0x55555555
t = (s & swap) ^ comp
s = s ^ sr ^ t ^ (t << 1)
s &= (1 << 2 * hn) - 1
t = (s ^ (s >> 1)) & 0x22222222
s = s ^ t ^ (t << 1)
t = (s ^ (s >> 2)) & 0x0C0C0C0C
s = s ^ t ^ (t << 2)
t = (s ^ (s >> 4)) & 0x00F000F0
s = s ^ t ^ (t << 4)
t = (s ^ (s >> 8)) & 0x0000FF00
s = s ^ t ^ (t << 8)
hx = s >> 16
hy = s & 0xFFFF
hi += 1
if not ((hx >= width or hy >= height or hx < 0 or hy < 0) and hi < hnn):
break
self.buckets_orders.append(hx + hy * width)
2 changes: 1 addition & 1 deletion core/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def __init__(self, cam2world:float, shutterOpen:float, sutterClose:float, film:F
self.film = film
self.camera_to_world = cam2world
self.shutterOpen = shutterOpen
self.sutterClose = sutterClose
self.shutterClose = sutterClose

def GenerateRay(self, sample:CameraSample, r: Ray):
pass
8 changes: 5 additions & 3 deletions core/film.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
__author__ = 'nicolas'
import numpy


class Film:

def __init__(self, width, height):
self.width = width
self.height = height
self.data = [int]* (width*height)

self.data = numpy.random.random(width * height )*255
self.data=numpy.reshape(self.data,(width, height))
self.data=numpy.require(self.data, dtype = numpy.uint)

def generate_ray(self):
raise Exception("Must be implemented")
2 changes: 0 additions & 2 deletions core/geometric_primitive.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
from core.primitive import Primitive

__author__ = 'nicolas'


class GeometricPrimitive(Primitive):
def __init__(self):
Expand Down
1 change: 0 additions & 1 deletion core/intersection.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from maths.point3d import Point3d
from maths.vector3d import Vector3d

__author__ = 'nicolas'

class Intersection:

Expand Down
Loading

0 comments on commit e5f5f9b

Please sign in to comment.