Ejemplo n.º 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);
		}
	}
Ejemplo n.º 2
0
void create_one_cusp(
    Triangulation   *manifold,
    Tetrahedron     *tet,
    Boolean         is_finite,
    VertexIndex     v,
    int             cusp_index)
{
    Cusp        *cusp;
    IdealVertex *queue;
    int         queue_first,
                queue_last;
    Tetrahedron *tet1,
                *nbr;
    VertexIndex v1,
                nbr_v;
    FaceIndex   f;

    /*
     *  Create the cusp, add it to the list, and set
     *  the is_finite and index fields.
     */

    cusp = NEW_STRUCT(Cusp);
    initialize_cusp(cusp);
    INSERT_BEFORE(cusp, &manifold->cusp_list_end);
    cusp->is_finite = is_finite;
    cusp->index     = cusp_index;

    /*
     *  We don't set the topology, is_complete, m, l, holonomy,
     *  cusp_shape or shape_precision fields.
     *
     *  For "real" cusps the calling routine may
     *
     *      (1) call peripheral_curves() to set the cusp->topology,
     *
     *      (2) keep the default values of cusp->is_complete,
     *          cusp->m and cusp->l as set by initialize_cusp(), and
     *
     *      (3) let the holonomy and cusp_shape be computed automatically
     *          when hyperbolic structure is computed.
     *
     *  Alternatively, the calling routine may set these fields in other
     *  ways, as it sees fit.
     *
     *  If we were called by create_fake_cusps(), then the above fields
     *  are all irrelevant and ignored.
     */

    /*
     *  Set the tet->cusp field at all vertices incident to the new cusp.
     */

    /*
     *  Allocate space for a queue of pointers to the IdealVertices.
     *  Each IdealVertex will appear on the queue at most once, so an
     *  array of length 4 * manifold->num_tetrahedra will suffice.
     */
    queue = NEW_ARRAY(4 * manifold->num_tetrahedra, IdealVertex);

    /*
     *  Set the cusp of the given IdealVertex...
     */
    tet->cusp[v] = cusp;

    /*
     *  ...and put it on the queue.
     */
    queue_first = 0;
    queue_last  = 0;
    queue[0].tet = tet;
    queue[0].v   = v;

    /*
     *  Start processing the queue.
     */
    do
    {
        /*
         *  Pull an IdealVertex off the front of the queue.
         */
        tet1 = queue[queue_first].tet;
        v1   = queue[queue_first].v;
        queue_first++;

        /*
         *  Look at the three neighboring IdealVertices.
         */
        for (f = 0; f < 4; f++)
        {
            if (f == v1)
                continue;

            nbr   = tet1->neighbor[f];
            nbr_v = EVALUATE(tet1->gluing[f], v1);

            /*
             *  If the neighbor's cusp hasn't been set...
             */
            if (nbr->cusp[nbr_v] == NULL)
            {
                /*
                 *  ...set it...
                 */
                nbr->cusp[nbr_v] = cusp;

                /*
                 *  ...and add it to the end of the queue.
                 */
                ++queue_last;
                queue[queue_last].tet   = nbr;
                queue[queue_last].v     = nbr_v;
            }
        }
    }
    while (queue_first <= queue_last);

    /*
     *  Free the memory used for the queue.
     */
    my_free(queue);
}