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