Blender  V3.3
BKE_subdiv.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2018 Blender Foundation. All rights reserved. */
3 
8 #pragma once
9 
10 #include "BLI_compiler_compat.h"
11 #include "BLI_sys_types.h"
12 
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16 
17 struct Mesh;
22 struct Subdiv;
23 
25  /* Do not interpolate boundaries. */
27  /* Sharpen edges. */
29  /* sharpen edges and corners, */
32 
41 
42 typedef struct SubdivSettings {
43  /* Simple subdivision corresponds to "Simple" option in the interface. When it's enabled the
44  * subdivided mesh is not "smoothed": new vertices are added uniformly on the existing surface.
45  *
46  * On an OpenSubdiv implementation level this translates to a subdivision scheme:
47  * when is_simple is true OSD_SCHEME_BILINEAR is used, otherwise OSD_SCHEME_CATMARK. */
48  bool is_simple;
49 
50  /* This refers to an adaptive isolation when creating patches for the subdivided surface.
51  *
52  * When is set to false (aka uniform subdivision) fixed depth of isolation is used, which
53  * allows to iteratively add more subdivisions (uniform subdivision level 2 = uniform subdivision
54  * level 1 + uniform subdivision level 1). Uniform subdivisions will progressively go to a limit
55  * surface.
56  *
57  * Adaptive isolation generates patches at a limit surface (aka as if infinite number of uniform
58  * subdivisions have been applied). This setting allows to have matches normal and tangent space
59  * the same independent of number of subdivisions set in modifier settings. */
61 
62  /* Corresponds to Quality option in modifier settings: higher values means the final surface
63  * will be more accurately represented by patches.
64  *
65  * On an OpenSubdiv implementation level this is an isolation level. */
66  int level;
67 
69 
73 
74 /* NOTE: Order of enumerators MUST match order of values in SubdivStats. */
75 typedef enum eSubdivStatsValue {
84 
87 
88 typedef struct SubdivStats {
89  union {
90  struct {
91  /* Time spend on creating topology refiner, which includes time
92  * spend on conversion from Blender data to OpenSubdiv data, and
93  * time spend on topology orientation on OpenSubdiv C-API side. */
95  /* Total time spent in BKE_subdiv_to_mesh(). */
97  /* Geometry (MVert and co) creation time during SUBDIV_TYO_MESH. */
99  /* Time spent on evaluator creation from topology refiner. */
101  /* Time spent on evaluator->refine(). */
103  /* Total time spent on whole CCG creation. */
105  /* Time spent on CCG elements evaluation/initialization. */
107  /* Time spent on CCG elements evaluation/initialization. */
109  };
111  };
112 
113  /* Per-value timestamp on when corresponding BKE_subdiv_stats_begin() was
114  * called. */
117 
118 /* Functor which evaluates displacement at a given (u, v) of given ptex face. */
119 typedef struct SubdivDisplacement {
120  /* Initialize displacement evaluator.
121  *
122  * Is called right before evaluation is actually needed. This allows to do
123  * some lazy initialization, like allocate evaluator from a main thread but
124  * then do actual evaluation from background job. */
125  void (*initialize)(struct SubdivDisplacement *displacement);
126 
127  /* Return displacement which is to be added to the original coordinate.
128  *
129  * NOTE: This function is supposed to return "continuous" displacement for
130  * each pf PTex faces created for special (non-quad) polygon. This means,
131  * if displacement is stored on per-corner manner (like MDisps for multires)
132  * this is up the displacement implementation to average boundaries of the
133  * displacement grids if needed.
134  *
135  * Averaging of displacement for vertices created for over coarse vertices
136  * and edges is done by subdiv code. */
137  void (*eval_displacement)(struct SubdivDisplacement *displacement,
138  int ptex_face_index,
139  float u,
140  float v,
141  const float dPdu[3],
142  const float dPdv[3],
143  float r_D[3]);
144 
145  /* Free the data, not the evaluator itself. */
146  void (*free)(struct SubdivDisplacement *displacement);
147 
148  void *user_data;
150 
151 /* This structure contains everything needed to construct subdivided surface.
152  * It does not specify storage, memory layout or anything else.
153  * It is possible to create different storage's (like, grid based CPU side
154  * buffers, GPU subdivision mesh, CPU side fully qualified mesh) from the same
155  * Subdiv structure. */
156 typedef struct Subdiv {
157  /* Settings this subdivision surface is created for.
158  *
159  * It is read-only after assignment in BKE_subdiv_new_from_FOO(). */
161  /* Topology refiner includes all the glue logic to feed Blender side
162  * topology to OpenSubdiv. It can be shared by both evaluator and GL mesh
163  * drawer. */
165  /* CPU side evaluator. */
167  /* Optional displacement evaluator. */
169  /* Statistics for debugging. */
171 
172  /* Cached values, are not supposed to be accessed directly. */
173  struct {
174  /* Indexed by base face index, element indicates total number of ptex
175  * faces created for preceding base faces. This also stores the final
176  * ptex offset (the total number of PTex faces) at the end of the array
177  * so that algorithms can compute the number of ptex faces for a given
178  * face by computing the delta with the offset for the next face without
179  * using a separate data structure, e.g.:
180  *
181  * const int num_face_ptex_faces = face_ptex_offset[i + 1] - face_ptex_offset[i];
182  *
183  * In total this array has a size of `num base faces + 1`.
184  */
188 
189 /* --------------------------------------------------------------------
190  * Module.
191  */
192 
193 /* (De)initialize the entire subdivision surface module. */
194 void BKE_subdiv_init(void);
195 void BKE_subdiv_exit(void);
196 
197 /* --------------------------------------------------------------------
198  * Conversion helpers.
199  */
200 
201 /* NOTE: uv_smooth is eSubsurfUVSmooth. */
203 
205  int boundary_smooth);
206 
207 /* --------------------------------------------------------------------
208  * Statistics.
209  */
210 
212 
215 
217 
218 void BKE_subdiv_stats_print(const SubdivStats *stats);
219 
220 /* --------------------------------------------------------------------
221  * Settings.
222  */
223 
224 bool BKE_subdiv_settings_equal(const SubdivSettings *settings_a, const SubdivSettings *settings_b);
225 
226 /* --------------------------------------------------------------------
227  * Construction.
228  */
229 
230 /* Construct new subdivision surface descriptor, from scratch, using given
231  * settings and topology. */
233  struct OpenSubdiv_Converter *converter);
234 Subdiv *BKE_subdiv_new_from_mesh(const SubdivSettings *settings, const struct Mesh *mesh);
235 
236 /* Similar to above, but will not re-create descriptor if it was created for the
237  * same settings and topology.
238  * If settings or topology did change, the existing descriptor is freed and a
239  * new one is created from scratch.
240  *
241  * NOTE: It is allowed to pass NULL as an existing subdivision surface
242  * descriptor. This will create a new descriptor without any extra checks.
243  */
245  const SubdivSettings *settings,
246  struct OpenSubdiv_Converter *converter);
248  const SubdivSettings *settings,
249  const struct Mesh *mesh);
250 
251 void BKE_subdiv_free(Subdiv *subdiv);
252 
253 /* --------------------------------------------------------------------
254  * Displacement API.
255  */
256 
258  struct Mesh *mesh,
259  const struct MultiresModifierData *mmd);
260 
262 
263 /* --------------------------------------------------------------------
264  * Topology helpers.
265  */
266 
267 /* For each element in the array, this stores the total number of ptex faces up to that element,
268  * with the total number of ptex faces being the last element in the array. The array is of length
269  * `base face count + 1`. */
271 
272 /* --------------------------------------------------------------------
273  * PTex faces and grids.
274  */
275 
276 /* For a given (ptex_u, ptex_v) within a ptex face get corresponding
277  * (grid_u, grid_v) within a grid. */
279  float ptex_v,
280  float *r_grid_u,
281  float *r_grid_v);
282 
283 /* Inverse of above. */
285  float grid_v,
286  float *r_ptex_u,
287  float *r_ptex_v);
288 
289 /* For a given subdivision level (which is NOT refinement level) get size of
290  * CCG grid (number of grid points on a side).
291  */
293 
294 /* Simplified version of mdisp_rot_face_to_crn, only handles quad and
295  * works in normalized coordinates.
296  *
297  * NOTE: Output coordinates are in ptex coordinates. */
299  float quad_v,
300  float *r_corner_u,
301  float *r_corner_v);
302 
303 /* Converts (u, v) coordinate from within a grid to a quad coordinate in
304  * normalized ptex coordinates. */
306  int corner, float grid_u, float grid_v, float *r_quad_u, float *r_quad_v);
307 
308 /* Convert Blender edge crease value to OpenSubdiv sharpness. */
309 BLI_INLINE float BKE_subdiv_crease_to_sharpness_f(float edge_crease);
310 BLI_INLINE float BKE_subdiv_crease_to_sharpness_char(char edge_crease);
311 
312 #ifdef __cplusplus
313 }
314 #endif
315 
316 #include "intern/subdiv_inline.h"
BLI_INLINE void BKE_subdiv_ptex_face_uv_to_grid_uv(float ptex_u, float ptex_v, float *r_grid_u, float *r_grid_v)
Definition: subdiv_inline.h:15
void BKE_subdiv_stats_init(SubdivStats *stats)
Definition: subdiv_stats.c:14
eSubdivStatsValue
Definition: BKE_subdiv.h:75
@ SUBDIV_STATS_SUBDIV_TO_CCG_ELEMENTS
Definition: BKE_subdiv.h:82
@ SUBDIV_STATS_EVALUATOR_REFINE
Definition: BKE_subdiv.h:80
@ SUBDIV_STATS_TOPOLOGY_REFINER_CREATION_TIME
Definition: BKE_subdiv.h:76
@ NUM_SUBDIV_STATS_VALUES
Definition: BKE_subdiv.h:85
@ SUBDIV_STATS_EVALUATOR_CREATE
Definition: BKE_subdiv.h:79
@ SUBDIV_STATS_SUBDIV_TO_MESH_GEOMETRY
Definition: BKE_subdiv.h:78
@ SUBDIV_STATS_SUBDIV_TO_MESH
Definition: BKE_subdiv.h:77
@ SUBDIV_STATS_SUBDIV_TO_CCG
Definition: BKE_subdiv.h:81
@ SUBDIV_STATS_TOPOLOGY_COMPARE
Definition: BKE_subdiv.h:83
void BKE_subdiv_stats_end(SubdivStats *stats, eSubdivStatsValue value)
Definition: subdiv_stats.c:31
BLI_INLINE int BKE_subdiv_grid_size_from_level(int level)
Definition: subdiv_inline.h:33
BLI_INLINE float BKE_subdiv_crease_to_sharpness_f(float edge_crease)
Definition: subdiv_inline.h:90
struct SubdivDisplacement SubdivDisplacement
BLI_INLINE void BKE_subdiv_rotate_grid_to_quad(int corner, float grid_u, float grid_v, float *r_quad_u, float *r_quad_v)
Definition: subdiv_inline.h:68
bool BKE_subdiv_settings_equal(const SubdivSettings *settings_a, const SubdivSettings *settings_b)
Definition: subdiv.c:83
void BKE_subdiv_stats_reset(SubdivStats *stats, eSubdivStatsValue value)
Definition: subdiv_stats.c:36
void BKE_subdiv_stats_begin(SubdivStats *stats, eSubdivStatsValue value)
Definition: subdiv_stats.c:26
eSubdivVtxBoundaryInterpolation BKE_subdiv_vtx_boundary_interpolation_from_subsurf(int boundary_smooth)
Definition: subdiv.c:66
void BKE_subdiv_free(Subdiv *subdiv)
Definition: subdiv.c:184
eSubdivFVarLinearInterpolation
Definition: BKE_subdiv.h:33
@ SUBDIV_FVAR_LINEAR_INTERPOLATION_ALL
Definition: BKE_subdiv.h:39
@ SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY
Definition: BKE_subdiv.h:35
@ SUBDIV_FVAR_LINEAR_INTERPOLATION_BOUNDARIES
Definition: BKE_subdiv.h:38
@ SUBDIV_FVAR_LINEAR_INTERPOLATION_NONE
Definition: BKE_subdiv.h:34
@ SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_AND_JUNCTIONS
Definition: BKE_subdiv.h:36
@ SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_JUNCTIONS_AND_CONCAVE
Definition: BKE_subdiv.h:37
void BKE_subdiv_displacement_attach_from_multires(Subdiv *subdiv, struct Mesh *mesh, const struct MultiresModifierData *mmd)
Subdiv * BKE_subdiv_update_from_converter(Subdiv *subdiv, const SubdivSettings *settings, struct OpenSubdiv_Converter *converter)
Definition: subdiv.c:141
BLI_INLINE void BKE_subdiv_grid_uv_to_ptex_face_uv(float grid_u, float grid_v, float *r_ptex_u, float *r_ptex_v)
Definition: subdiv_inline.h:24
Subdiv * BKE_subdiv_update_from_mesh(Subdiv *subdiv, const SubdivSettings *settings, const struct Mesh *mesh)
Subdiv * BKE_subdiv_new_from_mesh(const SubdivSettings *settings, const struct Mesh *mesh)
struct Subdiv Subdiv
int * BKE_subdiv_face_ptex_offset_get(Subdiv *subdiv)
Definition: subdiv.c:209
void BKE_subdiv_init(void)
Definition: subdiv.c:32
BLI_INLINE int BKE_subdiv_rotate_quad_to_corner(float quad_u, float quad_v, float *r_corner_u, float *r_corner_v)
Definition: subdiv_inline.h:38
eSubdivVtxBoundaryInterpolation
Definition: BKE_subdiv.h:24
@ SUBDIV_VTX_BOUNDARY_EDGE_AND_CORNER
Definition: BKE_subdiv.h:30
@ SUBDIV_VTX_BOUNDARY_NONE
Definition: BKE_subdiv.h:26
@ SUBDIV_VTX_BOUNDARY_EDGE_ONLY
Definition: BKE_subdiv.h:28
void BKE_subdiv_displacement_detach(Subdiv *subdiv)
struct SubdivSettings SubdivSettings
void BKE_subdiv_exit(void)
Definition: subdiv.c:37
eSubdivFVarLinearInterpolation BKE_subdiv_fvar_interpolation_from_uv_smooth(int uv_smooth)
Definition: subdiv.c:46
struct SubdivStats SubdivStats
Subdiv * BKE_subdiv_new_from_converter(const SubdivSettings *settings, struct OpenSubdiv_Converter *converter)
Definition: subdiv.c:98
void BKE_subdiv_stats_print(const SubdivStats *stats)
Definition: subdiv_stats.c:41
BLI_INLINE float BKE_subdiv_crease_to_sharpness_char(char edge_crease)
Definition: subdiv_inline.h:95
#define BLI_INLINE
ATTR_WARN_UNUSED_RESULT const BMVert * v
SyclQueue void void size_t num_bytes void
void(* initialize)(struct SubdivDisplacement *displacement)
Definition: BKE_subdiv.h:125
void(* eval_displacement)(struct SubdivDisplacement *displacement, int ptex_face_index, float u, float v, const float dPdu[3], const float dPdv[3], float r_D[3])
Definition: BKE_subdiv.h:137
void(* free)(struct SubdivDisplacement *displacement)
Definition: BKE_subdiv.h:146
bool is_adaptive
Definition: BKE_subdiv.h:60
eSubdivFVarLinearInterpolation fvar_linear_interpolation
Definition: BKE_subdiv.h:71
bool use_creases
Definition: BKE_subdiv.h:68
eSubdivVtxBoundaryInterpolation vtx_boundary_interpolation
Definition: BKE_subdiv.h:70
double topology_compare_time
Definition: BKE_subdiv.h:108
double topology_refiner_creation_time
Definition: BKE_subdiv.h:94
double begin_timestamp_[NUM_SUBDIV_STATS_VALUES]
Definition: BKE_subdiv.h:115
double values_[NUM_SUBDIV_STATS_VALUES]
Definition: BKE_subdiv.h:110
double subdiv_to_mesh_time
Definition: BKE_subdiv.h:96
double evaluator_refine_time
Definition: BKE_subdiv.h:102
double subdiv_to_ccg_time
Definition: BKE_subdiv.h:104
double subdiv_to_ccg_elements_time
Definition: BKE_subdiv.h:106
double subdiv_to_mesh_geometry_time
Definition: BKE_subdiv.h:98
double evaluator_creation_time
Definition: BKE_subdiv.h:100
SubdivSettings settings
Definition: BKE_subdiv.h:160
struct Subdiv::@68 cache_
SubdivStats stats
Definition: BKE_subdiv.h:170
struct SubdivDisplacement * displacement_evaluator
Definition: BKE_subdiv.h:168
struct OpenSubdiv_TopologyRefiner * topology_refiner
Definition: BKE_subdiv.h:164
struct OpenSubdiv_Evaluator * evaluator
Definition: BKE_subdiv.h:166
int * face_ptex_offset
Definition: BKE_subdiv.h:185