Exemplo n.º 1
0
void TriContourGenerator::find_boundary_lines(Contour& contour,
                                              const double& level)
{
    // Traverse boundaries to find starting points for all contour lines that
    // intersect the boundaries.  For each starting point found, follow the
    // line to its end before continuing.
    const Triangulation& triang = get_triangulation();
    const Boundaries& boundaries = get_boundaries();
    for (Boundaries::const_iterator it = boundaries.begin();
            it != boundaries.end(); ++it) {
        const Boundary& boundary = *it;
        bool startAbove, endAbove = false;
        for (Boundary::const_iterator itb = boundary.begin();
                itb != boundary.end(); ++itb) {
            if (itb == boundary.begin())
                startAbove = get_z(triang.get_triangle_point(*itb)) >= level;
            else
                startAbove = endAbove;
            endAbove = get_z(triang.get_triangle_point(itb->tri,
                                                       (itb->edge+1)%3)) >= level;
            if (startAbove && !endAbove) {
                // This boundary edge is the start point for a contour line,
                // so follow the line.
                contour.push_back(ContourLine());
                ContourLine& contour_line = contour.back();
                TriEdge tri_edge = *itb;
                follow_interior(contour_line, tri_edge, true, level, false);
            }
        }
    }
}
Exemplo n.º 2
0
void TriContourGenerator::clear_visited_flags(bool include_boundaries)
{
    // Clear _interiorVisited.
    std::fill(_interior_visited.begin(), _interior_visited.end(), false);

    if (include_boundaries) {
        if (_boundaries_visited.empty()) {
            const Boundaries& boundaries = get_boundaries();

            // Initialise _boundaries_visited.
            _boundaries_visited.reserve(boundaries.size());
            for (Boundaries::const_iterator it = boundaries.begin();
                    it != boundaries.end(); ++it)
                _boundaries_visited.push_back(BoundaryVisited(it->size()));

            // Initialise _boundaries_used.
            _boundaries_used = BoundariesUsed(boundaries.size());
        }

        // Clear _boundaries_visited.
        for (BoundariesVisited::iterator it = _boundaries_visited.begin();
                it != _boundaries_visited.end(); ++it)
            std::fill(it->begin(), it->end(), false);

        // Clear _boundaries_used.
        std::fill(_boundaries_used.begin(), _boundaries_used.end(), false);
    }
}
Exemplo n.º 3
0
void Triangulation::get_boundary_edge(const TriEdge& triEdge,
                                      int& boundary,
                                      int& edge) const
{
    get_boundaries();  // Ensure _tri_edge_to_boundary_map has been created.
    TriEdgeToBoundaryMap::const_iterator it =
        _tri_edge_to_boundary_map.find(triEdge);
    assert(it != _tri_edge_to_boundary_map.end() &&
           "TriEdge is not on a boundary");
    boundary = it->second.boundary;
    edge = it->second.edge;
}
Exemplo n.º 4
0
void Triangulation::write_boundaries() const
{
    const Boundaries& bs = get_boundaries();
    std::cout << "Number of boundaries: " << bs.size() << std::endl;
    for (Boundaries::const_iterator it = bs.begin(); it != bs.end(); ++it) {
        const Boundary& b = *it;
        std::cout << "  Boundary of " << b.size() << " points: ";
        for (Boundary::const_iterator itb = b.begin(); itb != b.end(); ++itb) {
            std::cout << *itb << ", ";
        }
        std::cout << std::endl;
    }
}
Exemplo n.º 5
0
bool TriContourGenerator::follow_boundary(ContourLine& contour_line,
                                          TriEdge& tri_edge,
                                          const double& lower_level,
                                          const double& upper_level,
                                          bool on_upper)
{
    const Triangulation& triang = get_triangulation();
    const Boundaries& boundaries = get_boundaries();

    // Have TriEdge to start at, need equivalent boundary edge.
    int boundary, edge;
    triang.get_boundary_edge(tri_edge, boundary, edge);
    _boundaries_used[boundary] = true;

    bool stop = false;
    bool first_edge = true;
    double z_start, z_end = 0;
    while (!stop)
    {
        assert(!_boundaries_visited[boundary][edge] && "Boundary already visited");
        _boundaries_visited[boundary][edge] = true;

        // z values of start and end points of boundary edge.
        if (first_edge)
            z_start = get_z(triang.get_triangle_point(tri_edge));
        else
            z_start = z_end;
        z_end = get_z(triang.get_triangle_point(tri_edge.tri,
                                                (tri_edge.edge+1)%3));

        if (z_end > z_start) {  // z increasing.
            if (!(!on_upper && first_edge) &&
                z_end >= lower_level && z_start < lower_level) {
                stop = true;
                on_upper = false;
            } else if (z_end >= upper_level && z_start < upper_level) {
                stop = true;
                on_upper = true;
            }
        } else {  // z decreasing.
            if (!(on_upper && first_edge) &&
                z_start >= upper_level && z_end < upper_level) {
                stop = true;
                on_upper = true;
            } else if (z_start >= lower_level && z_end < lower_level) {
                stop = true;
                on_upper = false;
            }
        }

        first_edge = false;

        if (!stop) {
            // Move to next boundary edge, adding point to contour line.
            edge = (edge+1) % (int)boundaries[boundary].size();
            tri_edge = boundaries[boundary][edge];
            contour_line.push_back(triang.get_point_coords(
                                       triang.get_triangle_point(tri_edge)));
        }
    }

    return on_upper;
}
Exemplo n.º 6
0
void TriContourGenerator::find_boundary_lines_filled(Contour& contour,
                                                     const double& lower_level,
                                                     const double& upper_level)
{
    // Traverse boundaries to find starting points for all contour lines that
    // intersect the boundaries.  For each starting point found, follow the
    // line to its end before continuing.
    const Triangulation& triang = get_triangulation();
    const Boundaries& boundaries = get_boundaries();
    for (Boundaries::size_type i = 0; i < boundaries.size(); ++i) {
        const Boundary& boundary = boundaries[i];
        for (Boundary::size_type j = 0; j < boundary.size(); ++j) {
            if (!_boundaries_visited[i][j]) {
                // z values of start and end of this boundary edge.
                double z_start = get_z(triang.get_triangle_point(boundary[j]));
                double z_end = get_z(triang.get_triangle_point(
                                   boundary[j].tri, (boundary[j].edge+1)%3));

                // Does this boundary edge's z increase through upper level
                // and/or decrease through lower level?
                bool incr_upper = (z_start < upper_level && z_end >= upper_level);
                bool decr_lower = (z_start >= lower_level && z_end < lower_level);

                if (decr_lower || incr_upper) {
                    // Start point for contour line, so follow it.
                    contour.push_back(ContourLine());
                    ContourLine& contour_line = contour.back();
                    TriEdge start_tri_edge = boundary[j];
                    TriEdge tri_edge = start_tri_edge;

                    // Traverse interior and boundaries until return to start.
                    bool on_upper = incr_upper;
                    do {
                        follow_interior(contour_line, tri_edge, true,
                            on_upper ? upper_level : lower_level, on_upper);
                        on_upper = follow_boundary(contour_line, tri_edge,
                                       lower_level, upper_level, on_upper);
                    } while (tri_edge != start_tri_edge);

                    // Filled contour lines must not have same first and last
                    // points.
                    if (contour_line.size() > 1 &&
                            contour_line.front() == contour_line.back())
                        contour_line.pop_back();
                }
            }
        }
    }

    // Add full boundaries that lie between the lower and upper levels.  These
    // are boundaries that have not been touched by an internal contour line
    // which are stored in _boundaries_used.
    for (Boundaries::size_type i = 0; i < boundaries.size(); ++i) {
        if (!_boundaries_used[i]) {
            const Boundary& boundary = boundaries[i];
            double z = get_z(triang.get_triangle_point(boundary[0]));
            if (z >= lower_level && z < upper_level) {
                contour.push_back(ContourLine());
                ContourLine& contour_line = contour.back();
                for (Boundary::size_type j = 0; j < boundary.size(); ++j)
                    contour_line.push_back(triang.get_point_coords(
                                      triang.get_triangle_point(boundary[j])));
            }
        }
    }
}
// Core subdivision iteration loop
struct Mesh_Info *
iterate(struct rt_bot_internal *bot, struct Mesh_Info *prev_mesh)
{
    std::map<size_t, std::vector<size_t> >::iterator f_it;
    std::vector<size_t>::iterator l_it;

    struct Mesh_Info *starting_mesh;
    if (!prev_mesh) {
	starting_mesh = new Mesh_Info;
	mesh_info_init(bot, starting_mesh);
    } else {
	starting_mesh = prev_mesh;
    }
    struct Mesh_Info *mesh = new Mesh_Info;

    mesh->iteration_cnt = starting_mesh->iteration_cnt + 1;

    find_q_pts(starting_mesh);

    std::set<std::pair<size_t, size_t> > old_edges;
    std::set<std::pair<size_t, size_t> >::iterator e_it;
    get_all_edges(starting_mesh, &old_edges);

    std::set<std::pair<size_t, size_t> > outer_edges;
    std::set<size_t > outer_pts;
    std::set<size_t > outer_faces;
    get_boundaries(starting_mesh, &outer_pts, &outer_edges, &outer_faces);

    std::cout << "outer pt count: " << outer_pts.size() << "\n";
    std::cout << "outer edge count: " << outer_edges.size() << "\n";
    std::cout << "outer face count: " << outer_faces.size() << "\n";

    // Relax old points here
    for (size_t pcnt = 0; pcnt < (size_t)starting_mesh->points_p0.Count(); pcnt++) {
	mesh->points_p0.Append(*starting_mesh->points_p0.At((int)pcnt));
	mesh->iteration_of_insert[pcnt] = starting_mesh->iteration_of_insert[pcnt];
    }

    for (f_it = starting_mesh->face_pts.begin(); f_it != starting_mesh->face_pts.end(); f_it++) {
	mesh->points_p0.Append(starting_mesh->points_q[(int)(*f_it).first]);
	mesh->iteration_of_insert[mesh->points_p0.Count()-1] = mesh->iteration_cnt;
	starting_mesh->index_in_next[(*f_it).first] = mesh->points_p0.Count()-1;
    }

    // Use the old faces to guide the insertion of the new.
    size_t face_cnt = 0;
    for (f_it = starting_mesh->face_pts.begin(); f_it != starting_mesh->face_pts.end(); f_it++) {
	std::set<std::pair<size_t, size_t> > face_old_edges;

	size_t q0 = starting_mesh->index_in_next[(*f_it).first];
	l_it = (*f_it).second.begin();

	face_old_edges.insert(std::make_pair((*l_it), (*(l_it+1))));
	face_old_edges.insert(std::make_pair((*(l_it+1)), (*(l_it+2))));
	face_old_edges.insert(std::make_pair((*(l_it+2)), (*l_it)));

	for (e_it = face_old_edges.begin(); e_it != face_old_edges.end(); e_it++) {
	    std::pair<size_t, size_t> edge = mk_edge((*e_it).first, (*e_it).second);

	    if (old_edges.find(edge) != old_edges.end()) {
		if (outer_edges.find(edge) == outer_edges.end()) {

		    std::set<size_t> curr_faces = starting_mesh->edges_to_faces[edge];

		    curr_faces.erase((*f_it).first);
		    size_t q1 = starting_mesh->index_in_next[*curr_faces.begin()];

                    if (outer_faces.find(q0) != outer_faces.end() && outer_faces.find(q1) != outer_faces.end()) {
			std::cout << "Got two edge faces\n";
                    }

		    mesh_add_face((*e_it).first, q1, q0, face_cnt, mesh);
		    face_cnt++;
		    mesh_add_face((*e_it).second, q0, q1, face_cnt, mesh);
		    face_cnt++;
		    old_edges.erase(edge);
		} else {
		    if (mesh->iteration_cnt % 2 == 0) {
			std::cout << "second iteration: " << q0 << "\n";
		    } else {
			mesh_add_face((*e_it).first, (*e_it).second, q0, face_cnt, mesh);
			face_cnt++;
			old_edges.erase(edge);
		    }
		}
	    }
	}
    }

    delete starting_mesh;
    return mesh;
}