Blender V5.0
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/* -------------------------------------------------------------------- */
32
36 int ptex_face_index,
37 float u,
38 float v);
39
41 void (*free)(SubdivCCGMaskEvaluator *mask_evaluator);
42
43 void *user_data;
44};
45
47bool BKE_subdiv_ccg_mask_init_from_paint(SubdivCCGMaskEvaluator *mask_evaluator, const Mesh *mesh);
48
50
51/* -------------------------------------------------------------------- */
54
68
72
74 short x, y;
75
80 static SubdivCCGCoord from_index(const CCGKey &key, int index)
81 {
82 const int grid_index = index / key.grid_area;
83 const int index_in_grid = index - grid_index * key.grid_area;
84
85 SubdivCCGCoord coord{};
86 coord.grid_index = grid_index;
87 coord.x = index_in_grid % key.grid_size;
88 coord.y = index_in_grid / key.grid_size;
89
90 return coord;
91 }
92
97 int to_index(const CCGKey &key) const
98 {
99 return key.grid_area * this->grid_index +
100 CCG_grid_xy_to_index(key.grid_size, this->x, this->y);
101 }
102};
103
112
118
132 int level = -1;
137 int grid_size = -1;
139 int grid_area = -1;
141 int grids_num = -1;
151
156
167
177
180
181 /* TODO(sergey): Consider adding some accessors to a "decoded" geometry,
182 * to make integration with draw manager and such easy.
183 */
184
185 /* TODO(sergey): Consider adding CD layers here, so we can draw final mesh
186 * from grids, and have UVs and such work.
187 */
188
189 /* Integration with sculpting. */
190 /* TODO(sergey): Is this really best way to go? Kind of annoying to have
191 * such use-related flags in a more or less generic structure. */
192 struct {
194 bool coords = false;
196 bool hidden = false;
198
199 ~SubdivCCG();
200};
201
215std::unique_ptr<SubdivCCG> BKE_subdiv_to_ccg(blender::bke::subdiv::Subdiv &subdiv,
216 const SubdivToCCGSettings &settings,
217 const Mesh &coarse_mesh,
218 SubdivCCGMaskEvaluator *mask_evaluator = nullptr);
219
225 const SubdivToCCGSettings &settings,
226 const Mesh &coarse_mesh);
227
229CCGKey BKE_subdiv_ccg_key(const SubdivCCG &subdiv_ccg, int level);
231
234
237
240
243 const blender::IndexMask &face_mask);
244
246void BKE_subdiv_ccg_topology_counters(const SubdivCCG &subdiv_ccg,
247 int &r_num_vertices,
248 int &r_num_edges,
249 int &r_num_faces,
250 int &r_num_loops);
251
256
258 {
259 return this->coords.as_span().drop_back(num_duplicates);
260 }
261
263 {
264 return this->coords.as_span().take_back(num_duplicates);
265 }
266};
267
268void BKE_subdiv_ccg_print_coord(const char *message, const SubdivCCGCoord &coord);
269bool BKE_subdiv_ccg_check_coord_valid(const SubdivCCG &subdiv_ccg, const SubdivCCGCoord &coord);
270
271/* CCG element neighbors.
272 *
273 * Neighbors are considered:
274 *
275 * - For an inner elements of a grid other elements which are sharing same row or column (4
276 * neighbor elements in total).
277 *
278 * - For the corner element a single neighboring element on every adjacent edge, single from
279 * every grid.
280 *
281 * - For the boundary element two neighbor elements on the boundary (from same grid) and one
282 * element inside of every neighboring grid. */
283
290void BKE_subdiv_ccg_neighbor_coords_get(const SubdivCCG &subdiv_ccg,
291 const SubdivCCGCoord &coord,
292 bool include_duplicates,
293 SubdivCCGNeighbors &r_neighbors);
294
295inline int BKE_subdiv_ccg_grid_to_face_index(const SubdivCCG &subdiv_ccg, const int grid_index)
296{
297 return subdiv_ccg.grid_to_face_map[grid_index];
298}
299
301 const CCGKey &key,
302 int grid_index,
303 blender::MutableSpan<blender::float3> r_limit_positions);
304
305enum class SubdivCCGAdjacencyType : int8_t {
309};
310
317 const SubdivCCG &subdiv_ccg,
318 const SubdivCCGCoord &coord,
319 blender::Span<int> corner_verts,
321 int &r_v1,
322 int &r_v2);
323
326 blender::Span<int> corner_verts,
327 blender::BitSpan boundary_verts,
328 const SubdivCCG &subdiv_ccg,
329 SubdivCCGCoord coord);
330
333
334template<typename Fn>
336 const blender::BitGroupVector<> &grid_hidden,
337 const int grid,
338 const Fn &fn)
339{
340 if (grid_hidden.is_empty()) {
341 for (const int i : blender::IndexRange(key.grid_area)) {
342 fn(i);
343 }
344 }
345 else {
346 blender::bits::foreach_0_index(grid_hidden[grid], fn);
347 }
348}
349
351
353inline IndexRange grid_range(const int grid_area, const int grid)
354{
355 return IndexRange(grid * grid_area, grid_area);
356}
357inline IndexRange grid_range(const CCGKey &key, const int grid)
358{
359 return grid_range(key.grid_area, grid);
360}
361
363inline IndexRange face_range(const OffsetIndices<int> faces, const int grid_area, const int face)
364{
365 const IndexRange corners = faces[face];
366 return IndexRange(corners.start() * grid_area, corners.size() * grid_area);
367}
368inline IndexRange face_range(const OffsetIndices<int> faces, const CCGKey &key, const int face)
369{
370 return face_range(faces, key.grid_area, face);
371}
372
374inline int grid_xy_to_vert(const CCGKey &key, const int grid, const int x, const int y)
375{
376 return key.grid_area * grid + CCG_grid_xy_to_index(key.grid_size, x, y);
377}
378
379} // namespace blender::bke::ccg
380
int CCG_grid_xy_to_index(const int grid_size, const int x, const int y)
Definition BKE_ccg.hh:73
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)
SubdivCCGAdjacencyType
blender::Vector< SubdivCCGCoord, 256 > SubdivCCGNeighborCoords
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)
std::unique_ptr< SubdivCCG > BKE_subdiv_to_ccg(blender::bke::subdiv::Subdiv &subdiv, const SubdivToCCGSettings &settings, const Mesh &coarse_mesh, SubdivCCGMaskEvaluator *mask_evaluator=nullptr)
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)
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)
void BKE_subdiv_ccg_grid_hidden_free(SubdivCCG &subdiv_ccg)
ATTR_WARN_UNUSED_RESULT const BMVert * v
Span< T > as_span() const
nullptr float
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
blender::Vector< blender::Array< SubdivCCGCoord > > boundary_coords
blender::Vector< 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
blender::Array< blender::float3 > normals
blender::BitGroupVector grid_hidden
blender::Array< float > masks
blender::Array< SubdivCCGAdjacentVertex > adjacent_verts
blender::bke::subdiv::Subdiv * subdiv
blender::OffsetIndices< int > faces
blender::Array< SubdivCCGAdjacentEdge > adjacent_edges
blender::Span< int > grid_to_face_map
blender::Array< blender::float3 > positions
struct SubdivCCG::@013326174356303061066227044362260371376134015325 dirty
i
Definition text_draw.cc:230