Blender V4.5
BKE_subdiv_ccg.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2018 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#pragma once
10
11#include <memory>
12
13#include "BLI_array.hh"
15#include "BLI_bit_span_ops.hh"
16#include "BLI_index_mask_fwd.hh"
17#include "BLI_offset_indices.hh"
18#include "BLI_span.hh"
19#include "BLI_utility_mixins.hh"
20#include "BLI_vector.hh"
21
22#include "BKE_ccg.hh"
23
24struct Mesh;
25namespace blender::bke::subdiv {
26struct Subdiv;
27}
28
29/* --------------------------------------------------------------------
30 * Masks.
31 */
32
33/* Functor which evaluates mask value at a given (u, v) of given ptex face. */
35 float (*eval_mask)(SubdivCCGMaskEvaluator *mask_evaluator,
36 int ptex_face_index,
37 float u,
38 float v);
39
40 /* Free the data, not the evaluator itself. */
41 void (*free)(SubdivCCGMaskEvaluator *mask_evaluator);
42
43 void *user_data;
44};
45
46/* Return true if mesh has mask and evaluator can be used. */
47bool BKE_subdiv_ccg_mask_init_from_paint(SubdivCCGMaskEvaluator *mask_evaluator, const Mesh *mesh);
48
49/* --------------------------------------------------------------------
50 * SubdivCCG.
51 */
52
54 /* Resolution at which regular ptex (created for quad face) are being
55 * evaluated. This defines how many vertices final mesh will have: every
56 * regular ptex has resolution^2 vertices. Special (irregular, or ptex
57 * created for a corner of non-quad face) will have resolution of
58 * `resolution - 1`. */
60 /* Denotes which extra layers to be added to CCG elements. */
63};
64
66 /* Index of the grid within SubdivCCG::grids array. */
68
69 /* Coordinate within the grid. */
70 short x, y;
71
72 /* Returns the coordinate for the index in an array sized to contain all grid vertices (including
73 * duplicates). */
74 static SubdivCCGCoord from_index(const CCGKey &key, int index)
75 {
76 const int grid_index = index / key.grid_area;
77 const int index_in_grid = index - grid_index * key.grid_area;
78
79 SubdivCCGCoord coord{};
80 coord.grid_index = grid_index;
81 coord.x = index_in_grid % key.grid_size;
82 coord.y = index_in_grid / key.grid_size;
83
84 return coord;
85 }
86
87 /* Returns the index for the coordinate in an array sized to contain all grid vertices (including
88 * duplicates). */
89 int to_index(const CCGKey &key) const
90 {
91 return key.grid_area * this->grid_index +
93 }
94};
95
96/* Definition of an edge which is adjacent to at least one of the faces. */
99 /* Indexed by adjacent face index, then by point index on the edge.
100 * points to a coordinate into the grids. */
102};
103
104/* Definition of a vertex which is adjacent to at least one of the faces. */
107 /* Indexed by adjacent face index, points to a coordinate in the grids. */
109};
110
111/* Representation of subdivision surface which uses CCG grids. */
113 /* This is a subdivision surface this CCG was created for.
114 *
115 * TODO(sergey): Make sure the whole descriptor is valid, including all the
116 * displacement attached to the surface. */
118 /* A level at which geometry was subdivided. This is what defines grid
119 * resolution. It is NOT the topology refinement level. */
120 int level = -1;
121 /* Resolution of grid. All grids have matching resolution, and resolution
122 * is same as ptex created for non-quad faces. */
123 int grid_size = -1;
125 int grid_area = -1;
127 int grids_num = -1;
137
138 /* Faces from which grids are emitted. Owned by base mesh. */
140 /* The face in #faces for each grid. Owned by base mesh (See #Mesh::corner_to_face_map()). */
142
143 /* Edges which are adjacent to faces.
144 * Used for faster grid stitching, at the cost of extra memory.
145 */
147
148 /* Vertices which are adjacent to faces
149 * Used for faster grid stitching, at the cost of extra memory.
150 */
152
155
156 /* TODO(sergey): Consider adding some accessors to a "decoded" geometry,
157 * to make integration with draw manager and such easy.
158 */
159
160 /* TODO(sergey): Consider adding CD layers here, so we can draw final mesh
161 * from grids, and have UVs and such work.
162 */
163
164 /* Integration with sculpting. */
165 /* TODO(sergey): Is this really best way to go? Kind of annoying to have
166 * such use-related flags in a more or less generic structure. */
167 struct {
168 /* Corresponds to MULTIRES_COORDS_MODIFIED. */
169 bool coords = false;
170 /* Corresponds to MULTIRES_HIDDEN_MODIFIED. */
171 bool hidden = false;
173
174 /* Cached values, are not supposed to be accessed directly. */
175 struct {
176 /* Indexed by face, indicates index of the first grid which corresponds to the face. */
179
180 ~SubdivCCG();
181};
182
183/* Create CCG representation of subdivision surface.
184 *
185 * NOTE: CCG stores dense vertices in a grid-like storage. There is no edges or
186 * faces information's for the high-poly surface.
187 *
188 * NOTE: Subdiv is expected to be refined and ready for evaluation.
189 * NOTE: CCG becomes an owner of subdiv.
190 *
191 * TODO(sergey): Allow some user-counter or more explicit control over who owns
192 * the Subdiv. The goal should be to allow viewport GL Mesh and CCG to share
193 * same Subsurf without conflicts. */
194std::unique_ptr<SubdivCCG> BKE_subdiv_to_ccg(blender::bke::subdiv::Subdiv &subdiv,
195 const SubdivToCCGSettings &settings,
196 const Mesh &coarse_mesh,
197 SubdivCCGMaskEvaluator *mask_evaluator);
198
199/* Helper function, creates Mesh structure which is properly setup to use
200 * grids.
201 */
203 const SubdivToCCGSettings &settings,
204 const Mesh &coarse_mesh);
205
206/* Create a key for accessing grid elements at a given level. */
207CCGKey BKE_subdiv_ccg_key(const SubdivCCG &subdiv_ccg, int level);
209
210/* Recalculate all normals based on grid element coordinates. */
212
213/* Update normals of affected faces. */
215
216/* Average grid coordinates and normals along the grid boundaries. */
218
219/* Similar to above, but only updates given faces. */
221 const blender::IndexMask &face_mask);
222
223/* Get geometry counters at the current subdivision level. */
224void BKE_subdiv_ccg_topology_counters(const SubdivCCG &subdiv_ccg,
225 int &r_num_vertices,
226 int &r_num_edges,
227 int &r_num_faces,
228 int &r_num_loops);
229
234
236 {
237 return this->coords.as_span().drop_back(num_duplicates);
238 }
239
241 {
242 return this->coords.as_span().take_back(num_duplicates);
243 }
244};
245
246void BKE_subdiv_ccg_print_coord(const char *message, const SubdivCCGCoord &coord);
247bool BKE_subdiv_ccg_check_coord_valid(const SubdivCCG &subdiv_ccg, const SubdivCCGCoord &coord);
248
249/* CCG element neighbors.
250 *
251 * Neighbors are considered:
252 *
253 * - For an inner elements of a grid other elements which are sharing same row or column (4
254 * neighbor elements in total).
255 *
256 * - For the corner element a single neighboring element on every adjacent edge, single from
257 * every grid.
258 *
259 * - For the boundary element two neighbor elements on the boundary (from same grid) and one
260 * element inside of every neighboring grid. */
261
262/* Get actual neighbors of the given coordinate.
263 *
264 * If include_duplicates is true, vertices in other grids that match
265 * the current vertex are added at the end of the coords array. */
266void BKE_subdiv_ccg_neighbor_coords_get(const SubdivCCG &subdiv_ccg,
267 const SubdivCCGCoord &coord,
268 bool include_duplicates,
269 SubdivCCGNeighbors &r_neighbors);
270
271inline int BKE_subdiv_ccg_grid_to_face_index(const SubdivCCG &subdiv_ccg, const int grid_index)
272{
273 return subdiv_ccg.grid_to_face_map[grid_index];
274}
275
276void BKE_subdiv_ccg_eval_limit_point(const SubdivCCG &subdiv_ccg,
277 const SubdivCCGCoord &coord,
278 float r_point[3]);
280 const CCGKey &key,
281 int grid_index,
282 blender::MutableSpan<blender::float3> r_limit_positions);
283
289
290/* Returns if a grid coordinates is adjacent to a coarse mesh edge, vertex or nothing. If it is
291 * adjacent to an edge, r_v1 and r_v2 will be set to the two vertices of that edge. If it is
292 * adjacent to a vertex, r_v1 and r_v2 will be the index of that vertex. */
294 const SubdivCCG &subdiv_ccg,
295 const SubdivCCGCoord &coord,
296 blender::Span<int> corner_verts,
298 int &r_v1,
299 int &r_v2);
300
301/* Determines if a given grid coordinate is on a coarse mesh boundary. */
303 blender::Span<int> corner_verts,
304 blender::BitSpan boundary_verts,
305 const SubdivCCG &subdiv_ccg,
306 SubdivCCGCoord coord);
307
308/* Get array which is indexed by face index and contains index of a first grid of the face.
309 *
310 * The "ensure" version allocates the mapping if it's not known yet and stores it in the subdiv_ccg
311 * descriptor. This function is NOT safe for threading.
312 *
313 * The "get" version simply returns cached array. */
315const int *BKE_subdiv_ccg_start_face_grid_index_get(const SubdivCCG &subdiv_ccg);
316
319
320template<typename Fn>
322 const blender::BitGroupVector<> &grid_hidden,
323 const int grid,
324 const Fn &fn)
325{
326 if (grid_hidden.is_empty()) {
327 for (const int i : blender::IndexRange(key.grid_area)) {
328 fn(i);
329 }
330 }
331 else {
332 blender::bits::foreach_0_index(grid_hidden[grid], fn);
333 }
334}
335
337
339inline IndexRange grid_range(const int grid_area, const int grid)
340{
341 return IndexRange(grid * grid_area, grid_area);
342}
343inline IndexRange grid_range(const CCGKey &key, const int grid)
344{
345 return grid_range(key.grid_area, grid);
346}
347
349inline IndexRange face_range(const OffsetIndices<int> faces, const int grid_area, const int face)
350{
351 const IndexRange corners = faces[face];
352 return IndexRange(corners.start() * grid_area, corners.size() * grid_area);
353}
354inline IndexRange face_range(const OffsetIndices<int> faces, const CCGKey &key, const int face)
355{
356 return face_range(faces, key.grid_area, face);
357}
358
360inline int grid_xy_to_vert(const CCGKey &key, const int grid, const int x, const int y)
361{
362 return key.grid_area * grid + CCG_grid_xy_to_index(key.grid_size, x, y);
363}
364
365} // namespace blender::bke::ccg
int CCG_grid_xy_to_index(const int grid_size, const int x, const int y)
Definition BKE_ccg.hh:77
bool BKE_subdiv_ccg_coord_is_mesh_boundary(blender::OffsetIndices< int > faces, blender::Span< int > corner_verts, blender::BitSpan boundary_verts, const SubdivCCG &subdiv_ccg, SubdivCCGCoord coord)
int BKE_subdiv_ccg_grid_to_face_index(const SubdivCCG &subdiv_ccg, const int grid_index)
blender::Vector< SubdivCCGCoord, 256 > SubdivCCGNeighborCoords
const int * BKE_subdiv_ccg_start_face_grid_index_get(const SubdivCCG &subdiv_ccg)
const int * BKE_subdiv_ccg_start_face_grid_index_ensure(SubdivCCG &subdiv_ccg)
void BKE_subdiv_ccg_recalc_normals(SubdivCCG &subdiv_ccg)
void BKE_subdiv_ccg_eval_limit_positions(const SubdivCCG &subdiv_ccg, const CCGKey &key, int grid_index, blender::MutableSpan< blender::float3 > r_limit_positions)
CCGKey BKE_subdiv_ccg_key_top_level(const SubdivCCG &subdiv_ccg)
void BKE_subdiv_ccg_eval_limit_point(const SubdivCCG &subdiv_ccg, const SubdivCCGCoord &coord, float r_point[3])
CCGKey BKE_subdiv_ccg_key(const SubdivCCG &subdiv_ccg, int level)
blender::BitGroupVector & BKE_subdiv_ccg_grid_hidden_ensure(SubdivCCG &subdiv_ccg)
bool BKE_subdiv_ccg_mask_init_from_paint(SubdivCCGMaskEvaluator *mask_evaluator, const Mesh *mesh)
void BKE_subdiv_ccg_print_coord(const char *message, const SubdivCCGCoord &coord)
void BKE_subdiv_ccg_update_normals(SubdivCCG &subdiv_ccg, const blender::IndexMask &face_mask)
SubdivCCGAdjacencyType
@ SUBDIV_CCG_ADJACENT_EDGE
@ SUBDIV_CCG_ADJACENT_VERTEX
@ SUBDIV_CCG_ADJACENT_NONE
void BKE_subdiv_ccg_average_stitch_faces(SubdivCCG &subdiv_ccg, const blender::IndexMask &face_mask)
Mesh * BKE_subdiv_to_ccg_mesh(blender::bke::subdiv::Subdiv &subdiv, const SubdivToCCGSettings &settings, const Mesh &coarse_mesh)
bool BKE_subdiv_ccg_check_coord_valid(const SubdivCCG &subdiv_ccg, const SubdivCCGCoord &coord)
void BKE_subdiv_ccg_topology_counters(const SubdivCCG &subdiv_ccg, int &r_num_vertices, int &r_num_edges, int &r_num_faces, int &r_num_loops)
void BKE_subdiv_ccg_foreach_visible_grid_vert(const CCGKey &key, const blender::BitGroupVector<> &grid_hidden, const int grid, const Fn &fn)
SubdivCCGAdjacencyType BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(const SubdivCCG &subdiv_ccg, const SubdivCCGCoord &coord, blender::Span< int > corner_verts, blender::OffsetIndices< int > faces, int &r_v1, int &r_v2)
void BKE_subdiv_ccg_average_grids(SubdivCCG &subdiv_ccg)
void BKE_subdiv_ccg_neighbor_coords_get(const SubdivCCG &subdiv_ccg, const SubdivCCGCoord &coord, bool include_duplicates, SubdivCCGNeighbors &r_neighbors)
std::unique_ptr< SubdivCCG > BKE_subdiv_to_ccg(blender::bke::subdiv::Subdiv &subdiv, const SubdivToCCGSettings &settings, const Mesh &coarse_mesh, SubdivCCGMaskEvaluator *mask_evaluator)
void BKE_subdiv_ccg_grid_hidden_free(SubdivCCG &subdiv_ccg)
ATTR_WARN_UNUSED_RESULT const BMVert * v
Span< T > as_span() const
#define this
static char faces[256]
void foreach_0_index(const BitSpanT &data, Fn &&fn)
IndexRange face_range(const OffsetIndices< int > faces, const int grid_area, const int face)
IndexRange grid_range(const int grid_area, const int grid)
int grid_xy_to_vert(const CCGKey &key, const int grid, const int x, const int y)
int grid_size
Definition BKE_ccg.hh:33
int grid_area
Definition BKE_ccg.hh:35
SubdivCCGCoord ** boundary_coords
SubdivCCGCoord * corner_coords
int to_index(const CCGKey &key) const
static SubdivCCGCoord from_index(const CCGKey &key, int index)
float(* eval_mask)(SubdivCCGMaskEvaluator *mask_evaluator, int ptex_face_index, float u, float v)
void(* free)(SubdivCCGMaskEvaluator *mask_evaluator)
SubdivCCGNeighborCoords coords
blender::Span< SubdivCCGCoord > duplicates() const
blender::Span< SubdivCCGCoord > unique() const
struct SubdivCCG::@215250027323141210226117165130145372352306247373 dirty
blender::Array< blender::float3 > normals
blender::BitGroupVector grid_hidden
blender::Array< float > masks
blender::Array< SubdivCCGAdjacentVertex > adjacent_verts
blender::bke::subdiv::Subdiv * subdiv
blender::Array< int > start_face_grid_index
struct SubdivCCG::@163163141032115270172315130137161051014031350057 cache_
blender::OffsetIndices< int > faces
blender::Array< SubdivCCGAdjacentEdge > adjacent_edges
blender::Span< int > grid_to_face_map
blender::Array< blender::float3 > positions
i
Definition text_draw.cc:230