foo
[meshfrac] / src / frac.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include "frac.h"
4 #include "dynarr.h"
5
6 static void destroy_cell(struct frac_cell *cell);
7 static int build_cell(struct fracture *frac, int cellidx);
8
9 int frac_init(struct fracture *frac)
10 {
11         frac->mesh = 0;
12
13         if(!(frac->cells = dynarr_alloc(0, sizeof *frac->cells))) {
14                 return -1;
15         }
16         return 0;
17 }
18
19 void frac_destroy(struct fracture *frac)
20 {
21         int i, num;
22
23         if(!frac) return;
24
25         if(frac->cells) {
26                 num = dynarr_size(frac->cells);
27                 for(i=0; i<num; i++) {
28                         destroy_cell(frac->cells + i);
29                 }
30                 dynarr_free(frac->cells);
31         }
32 }
33
34 static void destroy_cell(struct frac_cell *cell)
35 {
36         if(!cell) return;
37
38         cmesh_free(cell->mesh);
39         dynarr_free(cell->planes);
40 }
41
42 void frac_mesh(struct fracture *frac, const struct cmesh *m)
43 {
44         frac->mesh = (struct cmesh*)m;
45 }
46
47 int frac_point(struct fracture *frac, float x, float y, float z)
48 {
49         struct frac_cell cell;
50         struct frac_cell *tmp;
51
52         cgm_vcons(&cell.pt, x, y, z);
53         if(!(cell.mesh = cmesh_alloc())) {
54                 return -1;
55         }
56         if(!(cell.planes = dynarr_alloc(0, sizeof *cell.planes))) {
57                 cmesh_free(cell.mesh);
58                 return -1;
59         }
60         if(!(tmp = dynarr_push(frac->cells, &cell))) {
61                 cmesh_free(cell.mesh);
62                 dynarr_free(cell.planes);
63                 return -1;
64         }
65         frac->cells = tmp;
66         return 0;
67 }
68
69 int frac_num_cells(struct fracture *frac)
70 {
71         return dynarr_size(frac->cells);
72 }
73
74 /* --- step 1: generate a bunch of points (or let the user add them manually) */
75
76 int frac_gen_points(struct fracture *frac, int num)
77 {
78         int i;
79         float x, y, z;
80         cgm_vec3 bbmin, bbmax, delta;
81
82         if(!frac || !frac->mesh) return -1;
83         if(!cmesh_poly_count(frac->mesh)) {
84                 return -1;
85         }
86
87         cmesh_aabbox(frac->mesh, &bbmin, &bbmax);
88         delta = bbmax;
89         cgm_vsub(&delta, &bbmin);
90
91         for(i=0; i<num; i++) {
92                 x = (float)rand() / RAND_MAX * delta.x + bbmin.x;
93                 y = (float)rand() / RAND_MAX * delta.y + bbmin.y;
94                 z = (float)rand() / RAND_MAX * delta.z + bbmin.z;
95
96                 if(frac_point(frac, x, y, z) == -1) {
97                         return -1;
98                 }
99         }
100         return 0;
101 }
102
103
104 /* --- step 2: construct voronoi cells bounded by planes */
105
106 int frac_build_cells(struct fracture *frac)
107 {
108         int i;
109
110         for(i=0; i<dynarr_size(frac->cells); i++) {
111                 if(build_cell(frac, i) == -1) {
112                         return -1;
113                 }
114         }
115
116         return -1;
117 }
118
119 static int build_cell(struct fracture *frac, int cellidx)
120 {
121         int i, j, num;
122         struct plane plane, *pptr;
123         struct frac_cell *cell = frac->cells + cellidx;
124
125         num = dynarr_size(frac->cells);
126         for(i=0; i<num; i++) {
127                 if(i == cellidx) continue;
128                 midplane(&plane, &cell->pt, &frac->cells[i].pt);
129                 if(!(pptr = dynarr_push(cell->planes, &plane))) {
130                         return -1;
131                 }
132                 cell->planes = pptr;
133         }
134
135         /* clip all planes against each other to end up with a convex cell */
136         num = dynarr_size(cell->planes);
137         for(i=0; i<num; i++) {
138                 for(j=0; j<num; j++) {
139                         if(i == j) continue;
140
141                         clip_poly...
142                 }
143         }
144 }
145
146 int frac_build_shell(struct fracture *frac)
147 {
148         return -1;
149 }
150
151 int frac_build_walls(struct fracture *frac)
152 {
153         return -1;
154 }
155
156 int frac_build(struct fracture *frac)
157 {
158         if(frac_build_cells(frac) == -1) {
159                 return -1;
160         }
161         if(frac_build_shell(frac) == -1) {
162                 return -1;
163         }
164         if(frac_build_walls(frac) == -1) {
165                 return -1;
166         }
167         return 0;
168 }