void data_to_triangulation( TriangulationData *data, Triangulation **manifold_ptr) { /* * We assume the UI has done some basic error checking * on the data, so we don't repeat it here. */ Triangulation *manifold; Tetrahedron **tet_array; Cusp **cusp_array; Boolean cusps_are_given; int i, j, k, l, m; Boolean all_peripheral_curves_are_zero, finite_vertices_are_present; /* * Initialize *manifold_ptr to NULL. * We'll do all our work with manifold, and then copy * manifold to *manifold_ptr at the very end. */ *manifold_ptr = NULL; /* * Allocate and initialize the Triangulation structure. */ manifold = NEW_STRUCT(Triangulation); initialize_triangulation(manifold); /* * Allocate and copy the name. */ manifold->name = NEW_ARRAY(strlen(data->name) + 1, char); strcpy(manifold->name, data->name); /* * Set up the global information. * * The hyperbolic structure is included in the file only for * human readers; here we recompute it from scratch. */ manifold->num_tetrahedra = data->num_tetrahedra; manifold->solution_type[complete] = not_attempted; manifold->solution_type[ filled ] = not_attempted; manifold->orientability = data->orientability; manifold->num_or_cusps = data->num_or_cusps; manifold->num_nonor_cusps = data->num_nonor_cusps; manifold->num_cusps = manifold->num_or_cusps + manifold->num_nonor_cusps; /* * Allocate the Tetrahedra. * Keep pointers to them on a temporary array, so we can * find them by their indices. */ tet_array = NEW_ARRAY(manifold->num_tetrahedra, Tetrahedron *); for (i = 0; i < manifold->num_tetrahedra; i++) { tet_array[i] = NEW_STRUCT(Tetrahedron); initialize_tetrahedron(tet_array[i]); INSERT_BEFORE(tet_array[i], &manifold->tet_list_end); } /* * If num_or_cusps or num_nonor_cusps is nonzero, allocate the Cusps. * Keep pointers to them on temporary arrays, so we can find them * by their indices. * Otherwise we will create arbitrary Cusps later. */ cusps_are_given = (data->num_or_cusps != 0) || (data->num_nonor_cusps != 0); if (cusps_are_given == TRUE) { cusp_array = NEW_ARRAY(manifold->num_cusps, Cusp *); for (i = 0; i < manifold->num_cusps; i++) { cusp_array[i] = NEW_STRUCT(Cusp); initialize_cusp(cusp_array[i]); INSERT_BEFORE(cusp_array[i], &manifold->cusp_list_end); } }
static Triangulation *try_Dirichlet_to_triangulation( WEPolyhedron *polyhedron) { /* * Implement Plan A as described above. */ Triangulation *triangulation; WEEdge *edge, *nbr_edge, *mate_edge; WEEdgeEnd end; WEEdgeSide side; Tetrahedron *new_tet; FaceIndex f; /* * Don't attempt to triangulate an orbifold. */ if (singular_set_is_empty(polyhedron) == FALSE) return NULL; /* * Set up the Triangulation. */ triangulation = NEW_STRUCT(Triangulation); initialize_triangulation(triangulation); /* * Allocate and copy the name. */ triangulation->name = NEW_ARRAY(strlen(DEFAULT_NAME) + 1, char); strcpy(triangulation->name, DEFAULT_NAME); /* * Allocate the Tetrahedra. */ triangulation->num_tetrahedra = 4 * polyhedron->num_edges; for (edge = polyhedron->edge_list_begin.next; edge != &polyhedron->edge_list_end; edge = edge->next) for (end = 0; end < 2; end++) /* = tail, tip */ for (side = 0; side < 2; side++) /* = left, right */ { new_tet = NEW_STRUCT(Tetrahedron); initialize_tetrahedron(new_tet); INSERT_BEFORE(new_tet, &triangulation->tet_list_end); edge->tet[end][side] = new_tet; } /* * Initialize neighbors. */ for (edge = polyhedron->edge_list_begin.next; edge != &polyhedron->edge_list_end; edge = edge->next) for (end = 0; end < 2; end++) /* = tail, tip */ for (side = 0; side < 2; side++) /* = left, right */ { /* * Neighbor[0] is associated to this same WEEdge. * It lies on the same side (left or right), but * at the opposite end (tail or tip). */ edge->tet[end][side]->neighbor[0] = edge->tet[!end][side]; /* * Neighbor[1] lies on the same face of the Dirichlet * domain, but at the "next side" of that face. */ nbr_edge = edge->e[end][side]; if (nbr_edge->v[!end] == edge->v[end]) /* edge and nbr_edge point in the same direction */ edge->tet[end][side]->neighbor[1] = nbr_edge->tet[!end][side]; else if (nbr_edge->v[end] == edge->v[end]) /* edge and nbr_edge point in opposite directions */ edge->tet[end][side]->neighbor[1] = nbr_edge->tet[end][!side]; else uFatalError("Dirichlet_to_triangulation", "Dirichlet_conversion"); /* * Neighbor[2] is associated to this same WEEdge. * It lies at the same end (tail or tip), but * on the opposite side (left or right). */ edge->tet[end][side]->neighbor[2] = edge->tet[end][!side]; /* * Neighbor[3] lies on this face's "mate" elsewhere * on the Dirichlet domain. */ mate_edge = edge->neighbor[side]; edge->tet[end][side]->neighbor[3] = mate_edge->tet [edge->preserves_direction[side] ? end : !end ] [edge->preserves_sides[side] ? side : !side]; } /* * Initialize all gluings to the identity. */ for (edge = polyhedron->edge_list_begin.next; edge != &polyhedron->edge_list_end; edge = edge->next) for (end = 0; end < 2; end++) /* = tail, tip */ for (side = 0; side < 2; side++) /* = left, right */ for (f = 0; f < 4; f++) edge->tet[end][side]->gluing[f] = IDENTITY_PERMUTATION; /* * Set up the EdgeClasses. */ create_edge_classes(triangulation); orient_edge_classes(triangulation); /* * Attempt to orient the manifold. */ orient(triangulation); /* * Set up the Cusps, including "fake cusps" for the finite vertices. * Then locate and remove the fake cusps. If the manifold is closed, * drill out an arbitrary curve to express it as a Dehn filling. * Finally, determine the topology of each cusp (torus or Klein bottle) * and count them. */ create_cusps(triangulation); mark_fake_cusps(triangulation); peripheral_curves(triangulation); remove_finite_vertices(triangulation); count_cusps(triangulation); /* * Try to compute a hyperbolic structure, first for the unfilled * manifold, and then for the closed manifold if appropriate. */ find_complete_hyperbolic_structure(triangulation); do_Dehn_filling(triangulation); /* * If the manifold is hyperbolic, install a shortest basis on each cusp. */ if ( triangulation->solution_type[complete] == geometric_solution || triangulation->solution_type[complete] == nongeometric_solution) install_shortest_bases(triangulation); /* * All done! */ return triangulation; }