Blender V4.3
mesh_topology.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2020 Blender Foundation
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later
4 *
5 * Author: Sergey Sharybin. */
6
8
9#include <cassert>
10
11namespace blender::opensubdiv {
12
13MeshTopology::MeshTopology() : num_vertices_(0), num_edges_(0), num_faces_(0) {}
14
16
18// Vertices.
19
20void MeshTopology::setNumVertices(int num_vertices)
21{
22 num_vertices_ = num_vertices;
23}
24
26{
27 return num_vertices_;
28}
29
30void MeshTopology::setVertexSharpness(int vertex_index, float sharpness)
31{
32 assert(vertex_index >= 0);
33 assert(vertex_index < getNumVertices());
34
35 ensureVertexTagsSize(vertex_index + 1);
36
37 vertex_tags_[vertex_index].sharpness = sharpness;
38}
39
40float MeshTopology::getVertexSharpness(int vertex_index) const
41{
42 assert(vertex_index >= 0);
43 assert(vertex_index < getNumVertices());
44
45 if (vertex_index >= vertex_tags_.size()) {
46 // Sharpness for the vertex was never provided.
47 return 0.0f;
48 }
49
50 return vertex_tags_[vertex_index].sharpness;
51}
52
54{
55 if (vertex_tags_.size() < num_vertices) {
56 vertex_tags_.resize(num_vertices);
57 }
58}
59
61// Edges.
62
63void MeshTopology::setNumEdges(int num_edges)
64{
65 num_edges_ = num_edges;
66}
67
69{
70 return num_edges_;
71}
72
73void MeshTopology::setEdgeVertexIndices(int edge_index, int v1, int v2)
74{
75 assert(edge_index >= 0);
76 assert(edge_index < getNumEdges());
77
78 assert(v1 >= 0);
79 assert(v1 < getNumVertices());
80
81 assert(v2 >= 0);
82 assert(v2 < getNumVertices());
83
84 ensureNumEdgesAtLeast(edge_index + 1);
85
86 Edge &edge = edges_[edge_index];
87 edge.v1 = v1;
88 edge.v2 = v2;
89}
90
91void MeshTopology::getEdgeVertexIndices(int edge_index, int *v1, int *v2) const
92{
93 assert(edge_index >= 0);
94 assert(edge_index < getNumEdges());
95
96 if (edge_index >= edges_.size()) {
97 *v1 = -1;
98 *v2 = -1;
99 return;
100 }
101
102 const Edge &edge = edges_[edge_index];
103 *v1 = edge.v1;
104 *v2 = edge.v2;
105}
106
107bool MeshTopology::isEdgeEqual(int edge_index, int expected_v1, int expected_v2) const
108{
109 assert(edge_index >= 0);
110 assert(edge_index < getNumEdges());
111
112 if (edge_index >= edges_.size()) {
113 return false;
114 }
115
116 const Edge &edge = edges_[edge_index];
117 return edge.v1 == expected_v1 && edge.v2 == expected_v2;
118}
119
120void MeshTopology::setEdgeSharpness(int edge_index, float sharpness)
121{
122 assert(edge_index >= 0);
123 assert(edge_index < getNumEdges());
124
125 if (sharpness < 1e-6f) {
126 return;
127 }
128
129 ensureEdgeTagsSize(edge_index + 1);
130
131 edge_tags_[edge_index].sharpness = sharpness;
132}
133
134float MeshTopology::getEdgeSharpness(int edge_index) const
135{
136 assert(edge_index >= 0);
137
138 if (edge_index >= edge_tags_.size()) {
139 // NOTE: It's possible that full topology is not known and that there was
140 // never sharpness assigned to any of the edges.
141 return 0.0f;
142 }
143
144 return edge_tags_[edge_index].sharpness;
145}
146
148{
149 if (edges_.size() < num_edges) {
150 edges_.resize(num_edges);
151 }
152}
153
155{
156 if (edge_tags_.size() < num_edges) {
157 edge_tags_.resize(num_edges);
158 }
159}
160
162// Faces.
163
164void MeshTopology::setNumFaces(int num_faces)
165{
166 num_faces_ = num_faces;
167
168 // NOTE: Extra element to store fake face past the last real one to make it
169 // possible to calculate number of vertices in the last face.
170 faces_first_vertex_index_.resize(num_faces + 1, 0);
171}
172
174{
175 return num_faces_;
176}
177
178void MeshTopology::setNumFaceVertices(int face_index, int num_face_vertices)
179{
180 assert(face_index >= 0);
181 assert(face_index < getNumFaces());
182
183 faces_first_vertex_index_[face_index + 1] = faces_first_vertex_index_[face_index] +
184 num_face_vertices;
185}
186
187int MeshTopology::getNumFaceVertices(int face_index) const
188{
189 assert(face_index >= 0);
190 assert(face_index < getNumFaces());
191
192 return faces_first_vertex_index_[face_index + 1] - faces_first_vertex_index_[face_index];
193}
194
196 int num_face_vertex_indices,
197 const int *face_vertex_indices)
198{
199 assert(face_index >= 0);
200 assert(face_index < getNumFaces());
201 assert(num_face_vertex_indices == getNumFaceVertices(face_index));
202
203 int *face_vertex_indices_storage = getFaceVertexIndicesStorage(face_index);
204 memcpy(face_vertex_indices_storage, face_vertex_indices, sizeof(int) * num_face_vertex_indices);
205}
206
208 int num_expected_face_vertex_indices,
209 const int *expected_face_vertex_indices) const
210{
211 assert(face_index >= 0);
212 assert(face_index < getNumFaces());
213
214 if (getNumFaceVertices(face_index) != num_expected_face_vertex_indices) {
215 return false;
216 }
217
218 const int *face_vertex_indices_storage = getFaceVertexIndicesStorage(face_index);
219 return memcmp(face_vertex_indices_storage,
220 expected_face_vertex_indices,
221 sizeof(int) * num_expected_face_vertex_indices) == 0;
222}
223
225 int face_index, const std::vector<int> &expected_face_vertex_indices) const
226{
228 face_index, expected_face_vertex_indices.size(), expected_face_vertex_indices.data());
229}
230
232{
233 const MeshTopology *const_this = this;
234 return const_cast<int *>(const_this->getFaceVertexIndicesStorage(face_index));
235}
236const int *MeshTopology::getFaceVertexIndicesStorage(int face_index) const
237{
238 assert(face_index >= 0);
239 assert(face_index < getNumFaces());
240
241 const int offset = faces_first_vertex_index_[face_index];
242 return face_vertex_indices_.data() + offset;
243}
244
246// Pipeline related.
247
254
255} // namespace blender::opensubdiv
ATTR_WARN_UNUSED_RESULT const BMVert * v2
int * getFaceVertexIndicesStorage(int face_index)
std::vector< int > faces_first_vertex_index_
void ensureNumEdgesAtLeast(int num_edges)
void ensureVertexTagsSize(int num_vertices)
void getEdgeVertexIndices(int edge_index, int *v1, int *v2) const
std::vector< VertexTag > vertex_tags_
void setEdgeSharpness(int edge_index, float sharpness)
bool isEdgeEqual(int edge_index, int expected_v1, int expected_v2) const
float getEdgeSharpness(int edge_index) const
void setNumVertices(int num_vertices)
std::vector< int > face_vertex_indices_
void setFaceVertexIndices(int face_index, int num_face_vertex_indices, const int *face_vertex_indices)
void ensureEdgeTagsSize(int num_edges)
void setVertexSharpness(int vertex_index, float sharpness)
int getNumFaceVertices(int face_index) const
bool isFaceVertexIndicesEqual(int face_index, int num_expected_face_vertex_indices, const int *expected_face_vertex_indices) const
void setEdgeVertexIndices(int edge_index, int v1, int v2)
float getVertexSharpness(int vertex_index) const
std::vector< EdgeTag > edge_tags_
void setNumFaceVertices(int face_index, int num_face_vertices)