Blender  V3.3
mesh_topology.cc
Go to the documentation of this file.
1 // Copyright 2020 Blender Foundation. All rights reserved.
2 //
3 // This program is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU General Public License
5 // as published by the Free Software Foundation; either version 2
6 // of the License, or (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software Foundation,
15 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 //
17 // Author: Sergey Sharybin
18 
20 
21 #include <cassert>
22 
23 namespace blender {
24 namespace opensubdiv {
25 
26 MeshTopology::MeshTopology() : num_vertices_(0), num_edges_(0), num_faces_(0)
27 {
28 }
29 
31 {
32 }
33 
35 // Vertices.
36 
37 void MeshTopology::setNumVertices(int num_vertices)
38 {
39  num_vertices_ = num_vertices;
40 }
41 
43 {
44  return num_vertices_;
45 }
46 
47 void MeshTopology::setVertexSharpness(int vertex_index, float sharpness)
48 {
49  assert(vertex_index >= 0);
50  assert(vertex_index < getNumVertices());
51 
52  ensureVertexTagsSize(vertex_index + 1);
53 
54  vertex_tags_[vertex_index].sharpness = sharpness;
55 }
56 
57 float MeshTopology::getVertexSharpness(int vertex_index) const
58 {
59  assert(vertex_index >= 0);
60  assert(vertex_index < getNumVertices());
61 
62  if (vertex_index >= vertex_tags_.size()) {
63  // Sharpness for the vertex was never provided.
64  return 0.0f;
65  }
66 
67  return vertex_tags_[vertex_index].sharpness;
68 }
69 
70 void MeshTopology::ensureVertexTagsSize(int num_vertices)
71 {
72  if (vertex_tags_.size() < num_vertices) {
73  vertex_tags_.resize(num_vertices);
74  }
75 }
76 
78 // Edges.
79 
80 void MeshTopology::setNumEdges(int num_edges)
81 {
82  num_edges_ = num_edges;
83 }
84 
86 {
87  return num_edges_;
88 }
89 
90 void MeshTopology::setEdgeVertexIndices(int edge_index, int v1, int v2)
91 {
92  assert(edge_index >= 0);
93  assert(edge_index < getNumEdges());
94 
95  assert(v1 >= 0);
96  assert(v1 < getNumVertices());
97 
98  assert(v2 >= 0);
99  assert(v2 < getNumVertices());
100 
101  ensureNumEdgesAtLeast(edge_index + 1);
102 
103  Edge &edge = edges_[edge_index];
104  edge.v1 = v1;
105  edge.v2 = v2;
106 }
107 
108 void MeshTopology::getEdgeVertexIndices(int edge_index, int *v1, int *v2) const
109 {
110  assert(edge_index >= 0);
111  assert(edge_index < getNumEdges());
112 
113  if (edge_index >= edges_.size()) {
114  *v1 = -1;
115  *v2 = -1;
116  return;
117  }
118 
119  const Edge &edge = edges_[edge_index];
120  *v1 = edge.v1;
121  *v2 = edge.v2;
122 }
123 
124 bool MeshTopology::isEdgeEqual(int edge_index, int expected_v1, int expected_v2) const
125 {
126  assert(edge_index >= 0);
127  assert(edge_index < getNumEdges());
128 
129  if (edge_index >= edges_.size()) {
130  return false;
131  }
132 
133  const Edge &edge = edges_[edge_index];
134  return edge.v1 == expected_v1 && edge.v2 == expected_v2;
135 }
136 
137 void MeshTopology::setEdgeSharpness(int edge_index, float sharpness)
138 {
139  assert(edge_index >= 0);
140  assert(edge_index < getNumEdges());
141 
142  if (sharpness < 1e-6f) {
143  return;
144  }
145 
146  ensureEdgeTagsSize(edge_index + 1);
147 
148  edge_tags_[edge_index].sharpness = sharpness;
149 }
150 
151 float MeshTopology::getEdgeSharpness(int edge_index) const
152 {
153  assert(edge_index >= 0);
154 
155  if (edge_index >= edge_tags_.size()) {
156  // NOTE: It's possible that full topology is not known and that there was
157  // never sharpness assigned to any of the edges.
158  return 0.0f;
159  }
160 
161  return edge_tags_[edge_index].sharpness;
162 }
163 
165 {
166  if (edges_.size() < num_edges) {
167  edges_.resize(num_edges);
168  }
169 }
170 
172 {
173  if (edge_tags_.size() < num_edges) {
174  edge_tags_.resize(num_edges);
175  }
176 }
177 
179 // Faces.
180 
181 void MeshTopology::setNumFaces(int num_faces)
182 {
183  num_faces_ = num_faces;
184 
185  // NOTE: Extra element to store fake face past the last real one to make it
186  // possible to calculate number of vertices in the last face.
187  faces_first_vertex_index_.resize(num_faces + 1, 0);
188 }
189 
191 {
192  return num_faces_;
193 }
194 
195 void MeshTopology::setNumFaceVertices(int face_index, int num_face_vertices)
196 {
197  assert(face_index >= 0);
198  assert(face_index < getNumFaces());
199 
200  faces_first_vertex_index_[face_index + 1] = faces_first_vertex_index_[face_index] +
201  num_face_vertices;
202 }
203 
204 int MeshTopology::getNumFaceVertices(int face_index) const
205 {
206  assert(face_index >= 0);
207  assert(face_index < getNumFaces());
208 
209  return faces_first_vertex_index_[face_index + 1] - faces_first_vertex_index_[face_index];
210 }
211 
213  int num_face_vertex_indices,
214  const int *face_vertex_indices)
215 {
216  assert(face_index >= 0);
217  assert(face_index < getNumFaces());
218  assert(num_face_vertex_indices == getNumFaceVertices(face_index));
219 
220  int *face_vertex_indices_storage = getFaceVertexIndicesStorage(face_index);
221  memcpy(face_vertex_indices_storage, face_vertex_indices, sizeof(int) * num_face_vertex_indices);
222 }
223 
225  int num_expected_face_vertex_indices,
226  const int *expected_face_vertex_indices) const
227 {
228  assert(face_index >= 0);
229  assert(face_index < getNumFaces());
230 
231  if (getNumFaceVertices(face_index) != num_expected_face_vertex_indices) {
232  return false;
233  }
234 
235  const int *face_vertex_indices_storage = getFaceVertexIndicesStorage(face_index);
236  return memcmp(face_vertex_indices_storage,
237  expected_face_vertex_indices,
238  sizeof(int) * num_expected_face_vertex_indices) == 0;
239 }
240 
242  const vector<int> &expected_face_vertex_indices) const
243 {
245  face_index, expected_face_vertex_indices.size(), expected_face_vertex_indices.data());
246 }
247 
249 {
250  const MeshTopology *const_this = this;
251  return const_cast<int *>(const_this->getFaceVertexIndicesStorage(face_index));
252 }
253 const int *MeshTopology::getFaceVertexIndicesStorage(int face_index) const
254 {
255  assert(face_index >= 0);
256  assert(face_index < getNumFaces());
257 
258  const int offset = faces_first_vertex_index_[face_index];
259  return face_vertex_indices_.data() + offset;
260 }
261 
263 // Pipeline related.
264 
266 {
267  if (!faces_first_vertex_index_.empty()) {
269  }
270 }
271 
272 } // namespace opensubdiv
273 } // namespace blender
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
ATTR_WARN_UNUSED_RESULT const BMVert * v2
int * getFaceVertexIndicesStorage(int face_index)
void ensureNumEdgesAtLeast(int num_edges)
void ensureVertexTagsSize(int num_vertices)
void getEdgeVertexIndices(int edge_index, int *v1, int *v2) const
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)
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)
vector< VertexTag > vertex_tags_
float getVertexSharpness(int vertex_index) const
void setNumFaceVertices(int face_index, int num_face_vertices)
int num_vertices_
Definition: eval_output.h:179
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset