static int build_cell(struct fracture *frac, int cellidx)
{
- int i, j, num;
- struct plane plane, *pptr;
+ int i, j, num, clipres;
+ struct plane plane;
struct frac_cell *cell = frac->cells + cellidx;
+ struct poly poly, clipped, *polys, *pptr;
+ float bsize;
+
+ if(!(polys = dynarr_alloc(0, sizeof *polys))) {
+ return -1;
+ }
+
+ cmesh_bsphere(frac->mesh, 0, &bsize);
+ size *= 2;
num = dynarr_size(frac->cells);
for(i=0; i<num; i++) {
if(i == cellidx) continue;
midplane(&plane, &cell->pt, &frac->cells[i].pt);
- if(!(pptr = dynarr_push(cell->planes, &plane))) {
+ plane_poly(&plane, &poly, bsize);
+ if(!(pptr = dynarr_push(polys, &poly))) {
return -1;
}
- cell->planes = pptr;
+ polys = pptr;
}
+ num = dynarr_size(polys);
+ valid_planes = alloca(num * sizeof *valid_planes);
+ memset(valid_planes, 0xff, num * sizeof *valid_planes);
+
/* clip all planes against each other to end up with a convex cell */
- num = dynarr_size(cell->planes);
+ cell->num_polys = num;
for(i=0; i<num; i++) {
for(j=0; j<num; j++) {
- if(i == j) continue;
+ if(i == j || !valid_planes[j]) {
+ continue;
+ }
+
+ /* clip plane polygon i with plane j */
+ poly_plane(polys + j, &plane);
+ init_poly(&clipped);
+ if((clipres = clip_poly(&clipped, polys + i, &plane)) < 0) {
+ /* completely clipped, mark it for removal */
+ valid_planes[i] = 0;
+ cell->num_polys--;
+ break;
+ }
+ }
+ }
- clip_poly...
+ if(!(cell->polys = malloc(cell->num_polys * sizeof *cell->polys))) {
+ return -1;
+ }
+ pptr = cell->polys;
+ for(i=0; i<num; i++) {
+ if(valid_planes[i]) {
+ assert(pptr - cell->polys < cell->num_polys);
+ *pptr++ = polys[i];
+ } else {
+ destroy_poly(polys + i);
}
}
+ darr_free(polys);
+ return 0;
}
int frac_build_shell(struct fracture *frac)
float ray_plane(const cgm_ray *ray, const struct plane *plane);
float ray_poly(const cgm_ray *ray, const struct poly *poly);
+int init_poly(struct poly *p);
+void destroy_poly(struct poly *p);
int clip_poly(struct poly *pout, const struct poly *pin, const struct plane *plane);
#endif /* GEOM_H_ */