|
|
- /*
- * Copyright (C) 2023 Christopher J. Howard
- *
- * This file is part of Antkeeper source code.
- *
- * Antkeeper source code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Antkeeper source code is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
- */
-
- #include <engine/geom/brep/brep-edge.hpp>
- #include <engine/geom/brep/brep-mesh.hpp>
- #include <algorithm>
-
- namespace geom {
-
- void brep_edge_loop_list::push_back(brep_loop* loop)
- {
- if (empty())
- {
- // List empty, initialize
- m_head = loop;
- loop->m_edge_next = loop;
- loop->m_edge_previous = loop;
- }
- else
- {
- // Append loop
- loop->m_edge_next = m_head;
- loop->m_edge_previous = m_head->m_edge_previous;
- m_head->m_edge_previous->m_edge_next = loop;
- m_head->m_edge_previous = loop;
- }
-
- ++m_size;
- }
-
- void brep_edge_loop_list::remove(brep_loop* loop)
- {
- // Directly link next and previous loops
- loop->m_edge_next->m_edge_previous = loop->m_edge_previous;
- loop->m_edge_previous->m_edge_next = loop->m_edge_next;
-
- // If loop was the list head, update head
- if (m_head == loop)
- {
- m_head = loop->m_edge_next;
- }
-
- --m_size;
- }
-
- brep_edge* brep_edge_container::emplace_back(brep_vertex* a, brep_vertex* b)
- {
- if (a == b)
- {
- return nullptr;
- }
-
- brep_edge* ab = brep_element_container<brep_edge>::emplace_back();
- ab->m_index = size() - 1;
- ab->m_vertices[0] = a;
- ab->m_vertices[1] = b;
-
- // Append edge AB to the edge lists of vertices A and B
- a->m_edges.push_back(ab);
- b->m_edges.push_back(ab);
-
- return ab;
- };
-
- void brep_edge_container::erase(brep_edge* edge)
- {
- // Kill all loops and faces bounded by this edge
- while (!edge->loops().empty())
- {
- m_mesh->faces().erase(edge->loops().back()->face());
- }
-
- // Remove this edge from its vertices' lists of edges
- edge->vertices().front()->m_edges.remove(edge);
- edge->vertices().back()->m_edges.remove(edge);
-
- // Erase edge
- brep_element_container<brep_edge>::erase(edge);
- }
-
- void brep_edge_container::clear() noexcept
- {
- while (!empty())
- {
- erase(back());
- }
- }
-
- brep_edge* brep_edge_container::find(brep_vertex* a, brep_vertex* b) const
- {
- if (!a->edges().empty() && !b->edges().empty() && a != b)
- {
- brep_edge* ea = a->edges().front();
- brep_edge* eb = b->edges().front();
- const std::size_t n = std::min<std::size_t>(a->edges().size(), b->edges().size());
- for (std::size_t i = 0; i < n; ++i)
- {
- if (ea->vertices()[1] == b || ea->vertices()[0] == b)
- {
- return ea;
- }
-
- if (eb->vertices()[1] == a || eb->vertices()[0] == a)
- {
- return eb;
- }
-
- ea = ea->m_vertex_next[ea->vertices()[1] == a];
- eb = eb->m_vertex_next[eb->vertices()[1] == b];
- }
- }
-
- return nullptr;
- }
-
- } // namespace geom
|