/* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ tb_void_t gb_tessellator_triangulation_make(gb_tessellator_impl_t* impl) { // check tb_assert_abort(impl && impl->mesh); // the new face must be inserted to the head of faces tb_assert_abort(gb_mesh_face_order(impl->mesh) == GB_MESH_ORDER_INSERT_HEAD); // the iterator tb_iterator_ref_t iterator = gb_mesh_face_itor(impl->mesh); tb_assert_abort(iterator); // done tb_size_t itor = tb_iterator_head(iterator); tb_size_t tail = tb_iterator_tail(iterator); gb_mesh_face_ref_t face = tb_null; while (itor != tail) { // the face face = (gb_mesh_face_ref_t)tb_iterator_item(iterator, itor); tb_assert_abort(face); /* the next face * * @note we don't process the new faces at the head */ itor = tb_iterator_next(iterator, itor); // the face is inside? if (gb_tessellator_face_inside(face)) { // make triangulation for the face region gb_tessellator_triangulation_make_face(impl, face); } } #ifdef __gb_debug__ // check mesh gb_mesh_check(impl->mesh); #endif }
static tb_void_t gb_tessellator_listener(gb_mesh_event_ref_t event) { // check tb_assert(event); // done switch (event->type) { case GB_MESH_EVENT_FACE_SPLIT: { // the org and dst face gb_mesh_face_ref_t face_org = (gb_mesh_face_ref_t)event->org; gb_mesh_face_ref_t face_dst = (gb_mesh_face_ref_t)event->dst; /* split(face_org) => (face_org, face_dst) * * the new face will inherit the inside attribute of the old face */ gb_tessellator_face_inside_set(face_dst, gb_tessellator_face_inside(face_org)); } break; case GB_MESH_EVENT_EDGE_SPLIT: { // the org and dst edge gb_mesh_edge_ref_t edge_org = (gb_mesh_edge_ref_t)event->org; gb_mesh_edge_ref_t edge_dst = (gb_mesh_edge_ref_t)event->dst; /* split(edge_org) => (edge_org, edge_dst) * * the new edge will inherit the winding attribute of the old edge */ gb_tessellator_edge_winding_set(edge_dst, gb_tessellator_edge_winding(edge_org)); gb_tessellator_edge_winding_set(gb_mesh_edge_sym(edge_dst), gb_tessellator_edge_winding(gb_mesh_edge_sym(edge_org))); } break; default: tb_assertf(0, "unknown listener event: %lx", event->type); break; } }