Ejemplo n.º 1
0
void tri_grid::split_triangles(int max_pts, int max_levs)
{
	std::cout << "# Splitting triangles" << std::endl;
	// loop through each base triangle and split until the number of points
	// contained in the triangle is less than or equal to max_pts
	for (unsigned int tri=0; tri<triangles.size(); tri++)
	{
		// check first whether it should be split or not
		if (triangles[tri]->get_root()->get_data()->get_number_of_indices() > max_pts)		
			split_triangle(triangles[tri]->get_root(), max_pts, max_levs);	// NB - this function is recursive
	}
}
Ejemplo n.º 2
0
/**
 * @brief EpsTrimesh::split_on_sphere_center_and_tangent
 * @param tid
 */
DANI_INLINE
void EpsTrimesh::split_on_sphere_tangent(const uint tid)
{
    Sphere *sphere = &t_epsilons.at(tid);

    if (sphere->tangent_pos == TANGENT_UNKNOWN)
        return;

    if (sphere->radius == 0.0)
        return;

    if (sphere->center_pos != CENTERED_ON_VERTEX)
        assert(false);

    uint vid = UINT_MAX;

    // center
    if (sphere->tangent_pos == TANGENT_ON_EDGE)
    {
        std::cout << ">>>>Sphere associated to triangle " << tid << " is tangent on edge .. splitting .. " << std::endl;

        vid = split_edge(sphere->tangent_id, sphere->tangent);

        for (uint tt : adj_vtx2tri(vid))
            t_epsilons.at(tt).center_tri.first = tt;
    }
    else
    if (sphere->tangent_pos == TANGENT_ON_TRIANGLE)
    {
        std::cout << ">>>>Sphere associated to triangle " << tid << " is tangent on triangle .. splitting .. " << std::endl;

        vid = split_triangle(sphere->tangent_tri.first, sphere->tangent);

        for (uint tt : adj_vtx2tri(vid))
            t_epsilons.at(tt).center_tri.first = tt;
    }
    else
    if (sphere->tangent_pos == TANGENT_ON_VERTEX)
    {
        std::cout << ">>>>Sphere associated to triangle " << tid << " is tangent on vertex. " << std::endl;
    }

    // Recursive

    if (vid != UINT_MAX)
    {
        for (uint tt=0; tt < num_triangles(); tt++)
        {
            if (t_epsilons.at(tt).tangent_pos == TANGENT_ON_EDGE &&
                    std::find(adj_vtx2edg(vid).begin(), adj_vtx2edg(vid).end(), t_epsilons.at(tt).tangent_id) != adj_vtx2edg(vid).end())
                split_on_sphere_tangent(tt);
            else
            if (t_epsilons.at(tt).tangent_pos == TANGENT_ON_TRIANGLE &&
                    std::find(adj_vtx2tri(vid).begin(), adj_vtx2tri(vid).end(), t_epsilons.at(tt).tangent_tri.first) != adj_vtx2tri(vid).end())
                split_on_sphere_tangent(tt);
        }
    }

    return;

}
Ejemplo n.º 3
0
void tri_grid::split_triangle(QT_TRI_NODE* triangle, int max_pts, int max_levs)
{
	// split the triangle indicated by PTI (parent triangle index) into four
	// new triangles and insert the 3 new force points into the point cloud 
	// and the triangle definition into the HTMA containing the references to 
	// the force points
	int iM[3];		// indices to new points in the point cloud
	for (int i=0; i<3; i++)
	{
		int j = i<2 ? i+1 : 0;
		// get the two points of the current triangle edge and create a mid point
		force_point MP = (PC[(*(triangle->get_data()))[i]] + PC[(*(triangle->get_data()))[j]]) * 0.5;
		// normalise the mid point
		MP *= 1.0 / MP.mag();
		// add to the point cloud
		iM[i] = PC_ADD_SPLIT(MP);
	}
	// new points have been created - now add the four new triangles
	indexed_force_tri_3D* ift = triangle->get_data();
	// get the current label
	LABEL c_label = ift->get_label();
	// calculate the multiplier
	long int mp = (long int)(pow(10, c_label.max_level+2));
	triangle->add_child(indexed_force_tri_3D(&PC, (*ift)[0],     iM[0], iM[2], LABEL(c_label.label+1*mp, c_label.max_level+1)));
	triangle->add_child(indexed_force_tri_3D(&PC,     iM[0], (*ift)[1], iM[1], LABEL(c_label.label+2*mp, c_label.max_level+1)));
	triangle->add_child(indexed_force_tri_3D(&PC,     iM[1], (*ift)[2], iM[2], LABEL(c_label.label+3*mp, c_label.max_level+1)));
	triangle->add_child(indexed_force_tri_3D(&PC,     iM[0],     iM[1], iM[2], LABEL(c_label.label+4*mp, c_label.max_level+1)));
	// check whether the triangles should contain one of the indexed points
	const std::list<grid_index>* grid_index_list = triangle->get_data()->get_grid_indices();
	for (std::list<grid_index>::const_iterator gii = grid_index_list->begin();
		 gii != grid_index_list->end(); gii++)
	{
		// get the actual triangle from the quad tree
		// check for point inclusion of current grid index
		bool pit = false;
		for (int i=0; i<4; i++)
		{
			// need to check each child triangle
			indexed_force_tri_3D* child_tri = triangle->get_child(i)->get_data();
			if (point_in_tri(&(gii->cart_coord), child_tri))
			{
				child_tri->add_index(gii->i, gii->j, gii->cart_coord);
				pit = true;
			}
		}
		// if not added then add to nearest
		FP_TYPE min_dist = 1e10;
		int min_tri_idx = -1;
		if (not pit)
		{
			for (int i=0; i<4; i++)
			{
				// calculate distance between point and centroid
				indexed_force_tri_3D* child_tri = triangle->get_child(i)->get_data();
				FP_TYPE dist = (child_tri->centroid() - gii->cart_coord).mag();
				if (dist < min_dist)
					min_tri_idx = i;
			}
			// add to the child tri the point is nearest to
			triangle->get_child(min_tri_idx)->get_data()->add_index(gii->i, gii->j, gii->cart_coord);
		}
	}
	
	// check whether each child should be split again
	for (int i=0; i<4; i++)
	{
		if ((triangle->get_child(i)->get_data()->get_number_of_indices() > max_pts ||
			// this ensures that any (for example level 7) levels with triangles in a previous level still get split
			 triangle->get_level() > max_levs-3) &&
			 triangle->get_level() < (max_levs-1))
			// recursive split
			split_triangle(triangle->get_child(i), max_pts, max_levs);
	}
}
Ejemplo n.º 4
0
/**
 * @brief EpsTrimesh::split_on_sphere_center_and_tangent
 * @param tid
 */
DANI_INLINE
uint EpsTrimesh::split_on_sphere_center(const uint tid)
{
    Sphere *sphere = &t_epsilons.at(tid);

    if (sphere->center_pos == CENTERED_UNKNOWN)
        return UINT_MAX;

    if (sphere->radius == 0.0 || sphere->radius == FLT_MAX)
        return UINT_MAX;

    uint vid = UINT_MAX;

    // center
    if (sphere->center_pos == CENTERED_ON_EDGE)
    {
        //std::cout << "Sphere associated to triangle " << tid << " is centered on edge .. splitting .. " << std::endl;

        //vid = split_edge(sphere->center_id, sphere->center);
        vid = UINT_MAX;
    }
    else
    if (sphere->center_pos == CENTERED_ON_TRIANGLE)
    {
        //std::cout << "Sphere associated to triangle " << tid << " is centered on triangle .. splitting .. " << std::endl;

        vid = split_triangle(tid, sphere->center);
    }
    else
    if (sphere->center_pos == CENTERED_ON_VERTEX)
    {
        //std::cout << "Sphere associated to triangle " << tid << " is centered on vertex. " << std::endl;
        vid = sphere->center_id;
    }

//    if (vid != UINT_MAX)
//    {
//        for (uint tt : adj_vtx2tri(vid))
//        {
//            t_epsilons.at(tt).center_tri.first = tt;

//            t_epsilons.at(tt).center_pos = CENTERED_ON_VERTEX;
//            t_epsilons.at(tt).center_id = vid;
//        }
//    }

//    // Recursive

//    if (vid != UINT_MAX)
//    {
//        std::vector<int> ppoo = adj_vtx2tri(vid);

//        for (int tt : ppoo)
//        {
//            split_on_sphere_center(tt);
//        }
//    }

    return vid;

}