Blender V4.3
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
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_sys_types.h"
20#include "BLI_utility_mixins.hh"
21#include "BLI_vector.hh"
22
23#include "BKE_ccg.hh"
24
25struct Mesh;
26namespace blender::bke::subdiv {
27struct Subdiv;
28}
29
30/* --------------------------------------------------------------------
31 * Masks.
32 */
33
34/* Functor which evaluates mask value at a given (u, v) of given ptex face. */
37 int ptex_face_index,
38 float u,
39 float v);
40
41 /* Free the data, not the evaluator itself. */
42 void (*free)(SubdivCCGMaskEvaluator *mask_evaluator);
43
44 void *user_data;
45};
46
47/* Return true if mesh has mask and evaluator can be used. */
48bool BKE_subdiv_ccg_mask_init_from_paint(SubdivCCGMaskEvaluator *mask_evaluator, const Mesh *mesh);
49
50/* --------------------------------------------------------------------
51 * SubdivCCG.
52 */
53
55 /* Resolution at which regular ptex (created for quad face) are being
56 * evaluated. This defines how many vertices final mesh will have: every
57 * regular ptex has resolution^2 vertices. Special (irregular, or ptex
58 * created for a corner of non-quad face) will have resolution of
59 * `resolution - 1`. */
61 /* Denotes which extra layers to be added to CCG elements. */
64};
65
67 /* Index of the grid within SubdivCCG::grids array. */
69
70 /* Coordinate within the grid. */
71 short x, y;
72
73 /* Returns the coordinate for the index in an array sized to contain all grid vertices (including
74 * duplicates). */
75 inline static SubdivCCGCoord from_index(const CCGKey &key, int index)
76 {
77 const int grid_index = index / key.grid_area;
78 const int index_in_grid = index - grid_index * key.grid_area;
79
80 SubdivCCGCoord coord{};
81 coord.grid_index = grid_index;
82 coord.x = index_in_grid % key.grid_size;
83 coord.y = index_in_grid / key.grid_size;
84
85 return coord;
86 }
87
88 /* Returns the index for the coordinate in an array sized to contain all grid vertices (including
89 * duplicates). */
90 int to_index(const CCGKey &key) const
91 {
92 return key.grid_area * this->grid_index +
93 CCG_grid_xy_to_index(key.grid_size, this->x, this->y);
94 }
95};
96
97/* Definition of an edge which is adjacent to at least one of the faces. */
100 /* Indexed by adjacent face index, then by point index on the edge.
101 * points to a coordinate into the grids. */
103};
104
105/* Definition of a vertex which is adjacent to at least one of the faces. */
108 /* Indexed by adjacent face index, points to a coordinate in the grids. */
110};
111
112/* Representation of subdivision surface which uses CCG grids. */
114 /* This is a subdivision surface this CCG was created for.
115 *
116 * TODO(sergey): Make sure the whole descriptor is valid, including all the
117 * displacement attached to the surface. */
119 /* A level at which geometry was subdivided. This is what defines grid
120 * resolution. It is NOT the topology refinement level. */
121 int level = -1;
122 /* Resolution of grid. All grids have matching resolution, and resolution
123 * is same as ptex created for non-quad faces. */
124 int grid_size = -1;
126 int grid_area = -1;
128 int grids_num = -1;
138
139 /* Faces from which grids are emitted. Owned by base mesh. */
141 /* The face in #faces for each grid. Owned by base mesh (See #Mesh::corner_to_face_map()). */
143
144 /* Edges which are adjacent to faces.
145 * Used for faster grid stitching, at the cost of extra memory.
146 */
148
149 /* Vertices which are adjacent to faces
150 * Used for faster grid stitching, at the cost of extra memory.
151 */
153
156
157 /* TODO(sergey): Consider adding some accessors to a "decoded" geometry,
158 * to make integration with draw manager and such easy.
159 */
160
161 /* TODO(sergey): Consider adding CD layers here, so we can draw final mesh
162 * from grids, and have UVs and such work.
163 */
164
165 /* Integration with sculpting. */
166 /* TODO(sergey): Is this really best way to go? Kind of annoying to have
167 * such use-related flags in a more or less generic structure. */
168 struct {
169 /* Corresponds to MULTIRES_COORDS_MODIFIED. */
170 bool coords = false;
171 /* Corresponds to MULTIRES_HIDDEN_MODIFIED. */
172 bool hidden = false;
174
175 /* Cached values, are not supposed to be accessed directly. */
176 struct {
177 /* Indexed by face, indicates index of the first grid which corresponds to the face. */
180
181 ~SubdivCCG();
182};
183
184/* Create CCG representation of subdivision surface.
185 *
186 * NOTE: CCG stores dense vertices in a grid-like storage. There is no edges or
187 * faces information's for the high-poly surface.
188 *
189 * NOTE: Subdiv is expected to be refined and ready for evaluation.
190 * NOTE: CCG becomes an owner of subdiv.
191 *
192 * TODO(sergey): Allow some user-counter or more explicit control over who owns
193 * the Subdiv. The goal should be to allow viewport GL Mesh and CCG to share
194 * same Subsurf without conflicts. */
195std::unique_ptr<SubdivCCG> BKE_subdiv_to_ccg(blender::bke::subdiv::Subdiv &subdiv,
196 const SubdivToCCGSettings &settings,
197 const Mesh &coarse_mesh,
198 SubdivCCGMaskEvaluator *mask_evaluator);
199
200/* Helper function, creates Mesh structure which is properly setup to use
201 * grids.
202 */
204 const SubdivToCCGSettings &settings,
205 const Mesh &coarse_mesh);
206
207/* Create a key for accessing grid elements at a given level. */
208CCGKey BKE_subdiv_ccg_key(const SubdivCCG &subdiv_ccg, int level);
210
211/* Recalculate all normals based on grid element coordinates. */
213
214/* Update normals of affected faces. */
216
217/* Average grid coordinates and normals along the grid boundaries. */
219
220/* Similar to above, but only updates given faces. */
222 const blender::IndexMask &face_mask);
223
224/* Get geometry counters at the current subdivision level. */
225void BKE_subdiv_ccg_topology_counters(const SubdivCCG &subdiv_ccg,
226 int &r_num_vertices,
227 int &r_num_edges,
228 int &r_num_faces,
229 int &r_num_loops);
230
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)
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
draw_view in_light_buf[] float
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)
blender::Span< SubdivCCGCoord > duplicates() const
blender::Vector< SubdivCCGCoord, 256 > coords
blender::Span< SubdivCCGCoord > unique() const
blender::Array< blender::float3 > normals
blender::BitGroupVector grid_hidden
blender::Array< float > masks
struct SubdivCCG::@65 cache_
blender::Array< SubdivCCGAdjacentVertex > adjacent_verts
blender::bke::subdiv::Subdiv * subdiv
blender::Array< int > start_face_grid_index
struct SubdivCCG::@64 dirty
blender::OffsetIndices< int > faces
blender::Array< SubdivCCGAdjacentEdge > adjacent_edges
blender::Span< int > grid_to_face_map
blender::Array< blender::float3 > positions