Beispiel #1
0
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);
		}
	}
Beispiel #2
0
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;
}