ASCOT5
Loading...
Searching...
No Matches
octree.c
Go to the documentation of this file.
1
19#include <stdlib.h>
20#include "ascot5.h"
21#include "octree.h"
22#include "list.h"
23#include "wall/wall_3d.h"
24
46void octree_create(octree_node** node, real x_min, real x_max, real y_min,
47 real y_max, real z_min, real z_max, int depth) {
48 octree_node* n = (octree_node*) malloc(sizeof(octree_node));
49 (*node) = n;
50 real epsilon = 1e-6;
51 n->bb1[0] = x_min - epsilon;
52 n->bb2[0] = x_max + epsilon;
53 n->bb1[1] = y_min - epsilon;
54 n->bb2[1] = y_max + epsilon;
55 n->bb1[2] = z_min - epsilon;
56 n->bb2[2] = z_max + epsilon;
57 real x = (x_max + x_min) / 2;
58 real y = (y_max + y_min) / 2;
59 real z = (z_max + z_min) / 2;
60 if(depth > 1) {
61 octree_create(&(n->n000), x_min, x, y_min, y, z_min, z, depth-1);
62 octree_create(&(n->n100), x, x_max, y_min, y, z_min, z, depth-1);
63 octree_create(&(n->n010), x_min, x, y, y_max, z_min, z, depth-1);
64 octree_create(&(n->n110), x, x_max, y, y_max, z_min, z, depth-1);
65 octree_create(&(n->n001), x_min, x, y_min, y, z, z_max, depth-1);
66 octree_create(&(n->n101), x, x_max, y_min, y, z, z_max, depth-1);
67 octree_create(&(n->n011), x_min, x, y, y_max, z, z_max, depth-1);
68 octree_create(&(n->n111), x, x_max, y, y_max, z, z_max, depth-1);
69 n->list = NULL;
70 }
71 else {
72 n->n000 = NULL;
73 n->n100 = NULL;
74 n->n010 = NULL;
75 n->n110 = NULL;
76 n->n001 = NULL;
77 n->n101 = NULL;
78 n->n011 = NULL;
79 n->n111 = NULL;
80 list_int_create(&(n->list));
81 }
82}
83
92 if((*node)->n000 != NULL) {
93 octree_free( &((*node)->n000) );
94 octree_free( &((*node)->n100) );
95 octree_free( &((*node)->n010) );
96 octree_free( &((*node)->n110) );
97 octree_free( &((*node)->n001) );
98 octree_free( &((*node)->n101) );
99 octree_free( &((*node)->n011) );
100 octree_free( &((*node)->n111) );
101 }
102 else {
103 list_int_free( &((*node)->list) );
104 }
105 free(*node);
106 *node = NULL;
107}
108
123void octree_add(octree_node* node, real t1[3], real t2[3], real t3[3], int id) {
124 if(node->n000 == NULL) {
125 /* leaf node, add the triangle to the list */
126 list_int_add(node->list, id);
127 }
128 else {
129 if(wall_3d_tri_in_cube(t1, t2, t3, node->n000->bb1, node->n000->bb2)>0)
130 octree_add(node->n000, t1, t2, t3, id);
131 if(wall_3d_tri_in_cube(t1, t2, t3, node->n100->bb1, node->n100->bb2)>0)
132 octree_add(node->n100, t1, t2, t3, id);
133 if(wall_3d_tri_in_cube(t1, t2, t3, node->n010->bb1, node->n010->bb2)>0)
134 octree_add(node->n010, t1, t2, t3, id);
135 if(wall_3d_tri_in_cube(t1, t2, t3, node->n110->bb1, node->n110->bb2)>0)
136 octree_add(node->n110, t1, t2, t3, id);
137 if(wall_3d_tri_in_cube(t1, t2, t3, node->n001->bb1, node->n001->bb2)>0)
138 octree_add(node->n001, t1, t2, t3, id);
139 if(wall_3d_tri_in_cube(t1, t2, t3, node->n101->bb1, node->n101->bb2)>0)
140 octree_add(node->n101, t1, t2, t3, id);
141 if(wall_3d_tri_in_cube(t1, t2, t3, node->n011->bb1, node->n011->bb2)>0)
142 octree_add(node->n011, t1, t2, t3, id);
143 if(wall_3d_tri_in_cube(t1, t2, t3, node->n111->bb1, node->n111->bb2)>0)
144 octree_add(node->n111, t1, t2, t3, id);
145 }
146}
147
165 if(node->n000 == NULL) {
166 return node->list;
167 }
168 else {
169 real x = (node->bb1[0] + node->bb2[0]) / 2;
170 real y = (node->bb1[1] + node->bb2[1]) / 2;
171 real z = (node->bb1[2] + node->bb2[2]) / 2;
172
173 if(p[0] < x && p[1] < y && p[2] < z)
174 return octree_get(node->n000, p);
175 if(p[0] > x && p[1] < y && p[2] < z)
176 return octree_get(node->n100, p);
177 if(p[0] < x && p[1] > y && p[2] < z)
178 return octree_get(node->n010, p);
179 if(p[0] > x && p[1] > y && p[2] < z)
180 return octree_get(node->n110, p);
181 if(p[0] < x && p[1] < y && p[2] > z)
182 return octree_get(node->n001, p);
183 if(p[0] > x && p[1] < y && p[2] > z)
184 return octree_get(node->n101, p);
185 if(p[0] < x && p[1] > y && p[2] > z)
186 return octree_get(node->n011, p);
187 if(p[0] > x && p[1] > y && p[2] > z)
188 return octree_get(node->n111, p);
189 }
190
191 /* We should not ever get here but this
192 supresses compiler warnings. */
193 return NULL;
194}
Main header file for ASCOT5.
double real
Definition ascot5.h:85
void list_int_create(list_int_node **list)
Create an empty list.
Definition list.c:16
void list_int_free(list_int_node **list)
Deallocate this list and all lists it is linked to.
Definition list.c:28
void list_int_add(list_int_node *list, int data)
Add new node to the end of the chain.
Definition list.c:48
Header file for list.c.
void octree_add(octree_node *node, real t1[3], real t2[3], real t3[3], int id)
Add triangle to the node(s) it belongs to.
Definition octree.c:123
void octree_free(octree_node **node)
Free octree node and all its child nodes.
Definition octree.c:91
void octree_create(octree_node **node, real x_min, real x_max, real y_min, real y_max, real z_min, real z_max, int depth)
Create octree of given depth.
Definition octree.c:46
list_int_node * octree_get(octree_node *node, real p[3])
Get that leaf node's linked list the given coordinate belongs to.
Definition octree.c:164
Header file for octree.c.
Linked list node that stores int data.
Definition list.h:12
Struct representing single octree node.
Definition octree.h:17
struct octree_node * n100
Definition octree.h:19
struct octree_node * n111
Definition octree.h:25
struct octree_node * n101
Definition octree.h:23
struct octree_node * n110
Definition octree.h:21
struct octree_node * n010
Definition octree.h:20
struct octree_node * n000
Definition octree.h:18
struct octree_node * n001
Definition octree.h:22
struct octree_node * n011
Definition octree.h:24
list_int_node * list
Definition octree.h:28
real bb2[3]
Definition octree.h:27
real bb1[3]
Definition octree.h:26
int wall_3d_tri_in_cube(real t1[3], real t2[3], real t3[3], real bb1[3], real bb2[3])
Check if any part of a triangle is inside a box.
Definition wall_3d.c:464
Header file for wall_3d.c.