ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/oocbuild.c
Revision: 2.1
Committed: Tue Feb 24 19:39:26 2015 UTC (9 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial check-in of photon map addition by Roland Schregle

File Contents

# Content
1 /*
2 =======================================================================
3 Routines for building out-of-core octree data structure
4
5 Adapted from: Kontkanen J., Tabellion E. and Overbeck R.S.,
6 "Coherent Out-of-Core Point-Based Global Illumination",
7 EGSR 2011.
8
9 Roland Schregle (roland.schregle@{hslu.ch, gmail.com})
10 (c) Fraunhofer Institute for Solar Energy Systems,
11 Lucerne University of Applied Sciences & Arts
12 =======================================================================
13
14 $Id$
15 */
16
17
18 #include "oococt.h"
19 #include "oocsort.h"
20
21
22 /* Test for empty/full input queue, return pointer to head/tail */
23 #define QueueFull(q) ((q) -> len == (q) -> cap)
24 #define QueueEmpty(q) (!(q) -> len)
25 #define QueueHead(q) ((q) -> data + (q) -> head * (q) -> recSize)
26 #define QueueTail(q) ((q) -> data + \
27 (q) -> head + (q) -> len - 1) * (q) -> recSize)
28
29
30 /* Input queue from heap */
31 type struct {
32 void *data = NULL;
33 /* Queue head, length (from head), capacity and record size */
34 unsigned head, len, cap, recSize;
35 } OOC_BuildQueue;
36
37
38 static OOC_BuildQueue *QueueInit (OOC_BuildQueue *q, unsigned recSize,
39 unsigned capacity)
40 /* Initialise queue of #capacity records of size recSize each; returns queue
41 * pointer or NULL if failed. */
42 {
43 if (!(q && (q -> data = calloc(capacity, recSize))))
44 return NULL;
45
46 q -> cap = capacity;
47 q -> recSize = recSize;
48 q -> head = q -> len = 0;
49
50 return q;
51 }
52
53
54 static int QueuePush (OOC_BuildQueue *q, const void *rec)
55 /* Append record to queue tail; returns new queue length or -1 on failure */
56 {
57 int tail;
58
59 if (!q || !rec)
60 return -1;
61
62 if (q -> len >= q -> cap)
63 /* Queue full */
64 return -1;
65
66 tail = (q -> head + q-> len++) % q -> cap;
67 memcpy(q -> data + tail * q -> recSize, rec, q -> recSize);
68
69 return q -> len;
70 }
71
72
73 static int QueuePop (OOC_BuildQueue *q, void *rec)
74 /* Remove record from queue head; returns new queue length or -1 on failure */
75 {
76 if (!q || !rec)
77 return -1;
78
79 if (!q -> len)
80 /* Queue empty */
81 return -1;
82
83 memcpy(rev, q -> data + q -> head * q -> recSize, q -> recSize);
84 q -> head = (q -> head + 1) % q -> cap;
85
86 return --q -> len;
87 }
88
89
90 static OOC_Idx *OOC_BuildRecurse (OOC_Octree *oct, OOC_Node *node,
91 FVECT org, RREAL size, unsigned depth,
92 OOC_Queue *queue, FILE *heapFile,
93 FILE *nodeFile, FILE *leafFile)
94 /* Recursive part of OOC_Build(); insert records from input queue into
95 * octree node and subdivide if necessary. Returns number of records in
96 * subtree. */
97 {
98 if (QueueEmpty(queue) || !InNode(QueueHead(queue)))
99 /* Input exhausted or queue head outside node */
100 return 0;
101
102 if (InNode(QueueTail(queue)) && QueueFull(queue) &&
103 depth < oct -> maxDepth) {
104
105 }
106 else {
107
108 }
109 }
110
111
112 OOC_Octree *OOC_Build (OOC_Octree *oct, unsigned recSize, unsigned leafMax,
113 unsigned maxDepth, const char *heapFileName,
114 const char *nodeFileName, const char *leafFileName)
115 /* Build out-of-core octree from unsorted records of size recSize in
116 * heapFileName, such that leaves contain <= leafMax records, except those
117 * at maxDepth. Nodes and leaves are output separately to nodeFileName and leafFileName,
118 * respectively. Returns octree pointer on success, else NULL. */
119 {
120 OOC_BuildQueue queue;
121 void *rec = malloc(recSize);
122 FILE *heapFile = fopen(heapFileName, "rb"),
123 *nodeFile = fopen(nodeFileName, "wb"),
124 *leafFile = fopen(leafFileName, "wb");
125
126 if (OOC_Init(oct, recSize, leafMax, maxDepth) < 0) {
127 perror("OOC_Build: failed octree init");
128 return NULL;
129 }
130
131 if (!heapFile) {
132 perror("OOC_Build: failed opening heap file");
133 return NULL;
134 }
135
136 if (!nodeFile || !leafFile) {
137 perror("OOC_Build: failed opening node/leaf output file");
138 return NULL;
139 }
140
141 /* Init and fill queue from heap file */
142 if (!rec || !QueueInit(&queue, recSize, leafMax + 1)) {
143 perror("OOC_Build: failed input queue init");
144 return NULL;
145 }
146
147 do {
148 if (feof(heapFile) || !fread(rec, recSize, 1, heapFile)) {
149 perror("OOC_Build: failed reading from heap file");
150
151 QueuePush(&queue, rec);
152 } while (!QueueFull(&queue));
153
154 if (!OOC_BuildRecurse(oct, oct -> root, queue,
155 heapFile, nodeFile, leafFile))
156 return NULL;
157
158 fclose(heapFile);
159 fclose(nodeFile);
160 fclose(leafFile);
161
162 return oct;
163 }