/* See {hedge.h}. */ /* Copyright (C) 2023 Jorge Stolfi, UNICAMP */ /* Last edited on 2023-10-01 13:23:02 by stolfi */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #define valloc(n, T) \ ((T*)notnull(calloc((n), sizeof(T)), "no mem")) hedge_t *hedge_new(int32_t nf_alloc, int32_t ne_alloc, int32_t nv_alloc) { hedge_t *H = valloc(1, hedge_t); H->F = hedge_face_vec_new(nf_alloc); H->nf = 0; H->A = hedge_arc_vec_new(2*ne_alloc); H->na = 0; H->V = hedge_vert_vec_new(nv_alloc); H->nv = 0; return H; } hedge_face_t *hedge_add_face(hedge_t *H, double X, double Y, double Z, bool_t show) { hedge_face_t *f = valloc(1, hedge_face_t); f->ctr = (r3_t){{ X, Y, Z }}; f->side = NULL; f->show = show; f->id = H->nf; hedge_face_vec_expand(&(H->F), H->nf); H->F.e[H->nf]= f; H->nf++; return f; } hedge_vert_t *hedge_add_vert(hedge_t *H, double X, double Y, double Z, bool_t show) { hedge_vert_t *v = valloc(1, hedge_vert_t); v->pos = (r3_t){{ X, Y, Z }}; v->out = NULL; v->show = show; v->id = H->nv; hedge_vert_vec_expand(&(H->V), H->nv); H->V.e[H->nv]= v; H->nv++; return v; } hedge_arc_t *hedge_add_edge ( hedge_t *H, hedge_vert_t *org, hedge_vert_t *dst, hedge_face_t *left, hedge_face_t *right, double bend ) { hedge_arc_t *a = valloc(1, hedge_arc_t); a->org = org; a->left = left; a->next = NULL; a->bend = +bend + 2.0; a->id = H->na; left->side = a; org->out = a; hedge_arc_t *b = valloc(1, hedge_arc_t); b->org = dst; b->left = right; b->next = NULL; b->bend = -bend + 2.0; b->id = H->na + 1; right->side = b; dst->out = b; a->twin = b; b->twin = a; hedge_arc_vec_expand(&(H->A), H->na+1); H->A.e[H->na]= a; H->A.e[H->na+1]= b; H->na += 2; return a; } void hedge_set_next(hedge_arc_t *a, hedge_arc_t *b) { demand(a->next == NULL, "{next} already defined"); a->next = b; hedge_face_t *f = a->left; demand(f != NULL, "{left} is still {NULL}"); demand(f == b->left, "{left} pointers don't match"); demand(f->side != NULL, "{side} is still {NULL}");; } void hedge_check_topology(hedge_t *H) { /* Consistency of arc {twin}: */ fprintf(stderr, "checking arcs...\n"); for (int32_t ka = 0; ka < H->na; ka++) { hedge_arc_t *a = H->A.e[ka]; demand(a != NULL, "{NULL} in face table"); hedge_arc_t *b = a->twin; demand(b != NULL, "{NULL} in {twin} pointer"); demand(a != b, "arc is own {twin}"); demand(b->twin != NULL, "{NULL} in {twin} pointer of twin"); demand(b->twin == a, "bad {twin} of twin"); /* !!! Must check also the 1-manifold condition for edges !!! */ } /* Consistency of face {side} and arc {next}: */ fprintf(stderr, "checking faces...\n"); for (int32_t kf = 0; kf < H->nf; kf++) { hedge_face_t *f = H->F.e[kf]; demand(f != NULL, "{NULL} in face table"); hedge_arc_t *a = f->side; demand(a != NULL, "{NULL} in {side} pointer"); do { demand(a->left == f, "bad {left} pointer"); demand(a->next != NULL, "{NULL} in {next} pointer"); a = a->next; } while (a != f->side); } /* Consistency of vertex {out} and arc {turn}: */ fprintf(stderr, "checking vertices...\n"); for (int32_t kv = 0; kv < H->nv; kv++) { hedge_vert_t *v = H->V.e[kv]; demand(v != NULL, "{NULL} in face table"); hedge_arc_t *a = v->out; demand(a != NULL, "{NULL} in {out} pointer"); do { demand(a->org == v, "bad {org} pointer"); a = a->twin->next; } while (a != v->out); } } vec_typeimpl(hedge_face_vec_t, hedge_face_vec, hedge_face_t*); vec_typeimpl(hedge_arc_vec_t, hedge_arc_vec, hedge_arc_t*); vec_typeimpl(hedge_vert_vec_t, hedge_vert_vec, hedge_vert_t*);