Antkeeper  0.0.1
brep-face.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Christopher J. Howard
3  *
4  * This file is part of Antkeeper source code.
5  *
6  * Antkeeper source code is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Antkeeper source code is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
22 #include <algorithm>
23 #include <vector>
24 
25 namespace geom {
26 
28 {
29  if (empty())
30  {
31  // List empty, initialize
32  m_head = loop;
33  loop->m_face_next = loop;
34  loop->m_face_previous = loop;
35  }
36  else
37  {
38  // Append loop
39  loop->m_face_next = m_head;
40  loop->m_face_previous = m_head->m_face_previous;
41  m_head->m_face_previous->m_face_next = loop;
42  m_head->m_face_previous = loop;
43  }
44 
45  ++m_size;
46 }
47 
49 {
50  loop->m_face_next = next;
51  loop->m_face_previous = next->m_face_previous;
52  next->m_face_previous->m_face_next = loop;
53  next->m_face_previous = loop;
54 
55  ++m_size;
56 }
57 
59 {
60  // Directly link next and previous loops
61  loop->m_face_next->m_face_previous = loop->m_face_previous;
62  loop->m_face_previous->m_face_next = loop->m_face_next;
63 
64  // If loop was the list head, update head
65  if (m_head == loop)
66  {
67  m_head = loop->m_face_next;
68  }
69 
70  --m_size;
71 }
72 
73 brep_face* brep_face_container::emplace_back(const std::span<brep_vertex*> vertices)
74 {
75  if (vertices.size() < 3)
76  {
77  return nullptr;
78  }
79 
80  // Find or make edges
81  std::vector<brep_edge*> edges(vertices.size());
82  std::size_t i = vertices.size() - 1;
83  for (std::size_t j = 0; j < vertices.size(); ++j)
84  {
85  edges[i] = m_mesh->edges().find(vertices[i], vertices[j]);
86  if (!edges[i])
87  {
88  edges[i] = m_mesh->edges().emplace_back(vertices[i], vertices[j]);
89  }
90 
91  i = j;
92  }
93 
94  // Allocate face
96  face->m_index = size() - 1;
97 
98  // Make face loops
99  for (std::size_t i = 0; i < vertices.size(); ++i)
100  {
101  brep_loop* loop = m_mesh->loops().emplace_back();
102 
103  loop->m_vertex = vertices[i];
104  loop->m_edge = edges[i];
105  loop->m_face = face;
106 
107  // Append loop to its edge's list of loops
108  loop->m_edge->m_loops.push_back(loop);
109 
110  // Append loop to its face's list of loops
111  face->m_loops.push_back(loop);
112  }
113 
114  return face;
115 };
116 
118 {
119  brep_loop* loop = face->loops().front();
120  do
121  {
122  // Remove loop from its edge's list of loops
123  loop->m_edge->m_loops.remove(loop);
124 
125  brep_loop* next_loop = loop->m_face_next;
126 
127  // Erase loop
128  m_mesh->loops().erase(loop);
129 
130  loop = next_loop;
131  }
132  while (loop != face->loops().front());
133 
134  // Erase face
136 }
137 
139 {
140  while (!empty())
141  {
142  erase(back());
143  }
144 }
145 
147 {
148  for (brep_loop* loop: face->loops())
149  {
150  // Swap order of loop vertices
151  loop->m_vertex = loop->edge()->vertices()[loop->edge()->vertices()[0] == loop->vertex()];
152 
153  // Swap pointers to next and previous face loops
154  std::swap(loop->m_face_next, loop->m_face_previous);
155  }
156 }
157 
158 } // namespace geom
brep_edge * emplace_back(brep_vertex *a, brep_vertex *b)
Appends a new edge to the end of the container.
Definition: brep-edge.cpp:62
brep_edge * find(brep_vertex *a, brep_vertex *b) const
Finds an edge bounded by vertices a and b (in any order).
Definition: brep-edge.cpp:105
void push_back(brep_loop *loop)
Appends a loop to the end of the list.
Definition: brep-edge.cpp:26
void remove(brep_loop *loop)
Removes an loop from the list.
Definition: brep-edge.cpp:47
constexpr std::size_t size() const noexcept
Returns the number of elements in the container.
virtual void erase(element_type *element)
Erases an element from the container.
constexpr bool empty() const noexcept
Returns true if the container is empty, false otherwise.
constexpr element_type * back() const noexcept
Returns the last element.
virtual element_type * emplace_back()
Appends a new element to the end of the container.
void clear() noexcept
Erases all faces and their loops.
Definition: brep-face.cpp:138
void erase(brep_face *face) override
Erases a face and all of its loops.
Definition: brep-face.cpp:117
void reverse(brep_face *face)
Reverses the direction of a face's bounding loops.
Definition: brep-face.cpp:146
brep_loop * front() const noexcept
Returns the first loop.
Definition: brep-face.hpp:120
constexpr bool empty() const noexcept
Returns true if the list is empty, false otherwise.
Definition: brep-face.hpp:196
void push_back(brep_loop *loop)
Appends a loop to the end of the list.
Definition: brep-face.cpp:27
void insert(brep_loop *next, brep_loop *loop)
Inserts a loop before a given loop.
Definition: brep-face.cpp:48
void remove(brep_loop *loop)
Removes an loop from the list.
Definition: brep-face.cpp:58
Portion of a shell bounded by loops.
Definition: brep-face.hpp:244
constexpr const brep_face_loop_list & loops() const noexcept
Returns the list of loops associated with this face.
Definition: brep-face.hpp:261
Connected boundary of a single face.
Definition: brep-loop.hpp:38
const brep_edge_container & edges() const noexcept
Returns the mesh edges.
Definition: brep-mesh.hpp:81
const brep_loop_container & loops() const noexcept
Returns the mesh loops.
Definition: brep-mesh.hpp:93
Geometric algorithms.