Blender  V2.93
subdiv_eval.c
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 #include "BKE_subdiv_eval.h"
25 
26 #include "DNA_mesh_types.h"
27 #include "DNA_meshdata_types.h"
28 
29 #include "BLI_bitmap.h"
30 #include "BLI_math_vector.h"
31 #include "BLI_utildefines.h"
32 
33 #include "BKE_customdata.h"
34 #include "BKE_subdiv.h"
35 
36 #include "MEM_guardedalloc.h"
37 
40 
42 {
44  if (subdiv->topology_refiner == NULL) {
45  /* Happens on input mesh with just loose geometry,
46  * or when OpenSubdiv is disabled */
47  return false;
48  }
49  if (subdiv->evaluator == NULL) {
53  if (subdiv->evaluator == NULL) {
54  return false;
55  }
56  }
57  else {
58  /* TODO(sergey): Check for topology change. */
59  }
61  return true;
62 }
63 
64 static void set_coarse_positions(Subdiv *subdiv,
65  const Mesh *mesh,
66  const float (*coarse_vertex_cos)[3])
67 {
68  const MVert *mvert = mesh->mvert;
69  const MLoop *mloop = mesh->mloop;
70  const MPoly *mpoly = mesh->mpoly;
71  /* Mark vertices which needs new coordinates. */
72  /* TODO(sergey): This is annoying to calculate this on every update,
73  * maybe it's better to cache this mapping. Or make it possible to have
74  * OpenSubdiv's vertices match mesh ones? */
75  BLI_bitmap *vertex_used_map = BLI_BITMAP_NEW(mesh->totvert, "vert used map");
76  for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) {
77  const MPoly *poly = &mpoly[poly_index];
78  for (int corner = 0; corner < poly->totloop; corner++) {
79  const MLoop *loop = &mloop[poly->loopstart + corner];
80  BLI_BITMAP_ENABLE(vertex_used_map, loop->v);
81  }
82  }
83  for (int vertex_index = 0, manifold_vertex_index = 0; vertex_index < mesh->totvert;
84  vertex_index++) {
85  if (!BLI_BITMAP_TEST_BOOL(vertex_used_map, vertex_index)) {
86  continue;
87  }
88  const float *vertex_co;
89  if (coarse_vertex_cos != NULL) {
90  vertex_co = coarse_vertex_cos[vertex_index];
91  }
92  else {
93  const MVert *vertex = &mvert[vertex_index];
94  vertex_co = vertex->co;
95  }
96  subdiv->evaluator->setCoarsePositions(subdiv->evaluator, vertex_co, manifold_vertex_index, 1);
97  manifold_vertex_index++;
98  }
99  MEM_freeN(vertex_used_map);
100 }
101 
103  const MLoopUV *mloopuv,
104  const int layer_index)
105 {
106  OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
107  OpenSubdiv_Evaluator *evaluator = subdiv->evaluator;
108  const int num_faces = topology_refiner->getNumFaces(topology_refiner);
109  const MLoopUV *mluv = mloopuv;
110  /* TODO(sergey): OpenSubdiv's C-API converter can change winding of
111  * loops of a face, need to watch for that, to prevent wrong UVs assigned.
112  */
113  for (int face_index = 0; face_index < num_faces; face_index++) {
114  const int num_face_vertices = topology_refiner->getNumFaceVertices(topology_refiner,
115  face_index);
116  const int *uv_indices = topology_refiner->getFaceFVarValueIndices(
117  topology_refiner, face_index, layer_index);
118  for (int vertex_index = 0; vertex_index < num_face_vertices; vertex_index++, mluv++) {
119  evaluator->setFaceVaryingData(evaluator, layer_index, mluv->uv, uv_indices[vertex_index], 1);
120  }
121  }
122 }
123 
125  const Mesh *mesh,
126  const float (*coarse_vertex_cos)[3])
127 {
128  if (!BKE_subdiv_eval_begin(subdiv)) {
129  return false;
130  }
131  return BKE_subdiv_eval_refine_from_mesh(subdiv, mesh, coarse_vertex_cos);
132 }
133 
135  const Mesh *mesh,
136  const float (*coarse_vertex_cos)[3])
137 {
138  if (subdiv->evaluator == NULL) {
139  /* NOTE: This situation is supposed to be handled by begin(). */
140  BLI_assert(!"Is not supposed to happen");
141  return false;
142  }
143  /* Set coordinates of base mesh vertices. */
144  set_coarse_positions(subdiv, mesh, coarse_vertex_cos);
145  /* Set face-varyign data to UV maps. */
146  const int num_uv_layers = CustomData_number_of_layers(&mesh->ldata, CD_MLOOPUV);
147  for (int layer_index = 0; layer_index < num_uv_layers; layer_index++) {
148  const MLoopUV *mloopuv = CustomData_get_layer_n(&mesh->ldata, CD_MLOOPUV, layer_index);
149  set_face_varying_data_from_uv(subdiv, mloopuv, layer_index);
150  }
151  /* Update evaluator to the new coarse geometry. */
153  subdiv->evaluator->refine(subdiv->evaluator);
155  return true;
156 }
157 
159 {
160  if (subdiv->displacement_evaluator == NULL) {
161  return;
162  }
163  if (subdiv->displacement_evaluator->initialize == NULL) {
164  return;
165  }
167 }
168 
169 /* ========================== Single point queries ========================== */
170 
172  Subdiv *subdiv, const int ptex_face_index, const float u, const float v, float r_P[3])
173 {
174  BKE_subdiv_eval_limit_point_and_derivatives(subdiv, ptex_face_index, u, v, r_P, NULL, NULL);
175 }
176 
178  const int ptex_face_index,
179  const float u,
180  const float v,
181  float r_P[3],
182  float r_dPdu[3],
183  float r_dPdv[3])
184 {
185  subdiv->evaluator->evaluateLimit(subdiv->evaluator, ptex_face_index, u, v, r_P, r_dPdu, r_dPdv);
186 
187  /* NOTE: In a very rare occasions derivatives are evaluated to zeros or are exactly equal.
188  * This happens, for example, in single vertex on Suzannne's nose (where two quads have 2 common
189  * edges).
190  *
191  * This makes tangent space displacement (such as multires) impossible to be used in those
192  * vertices, so those needs to be addressed in one way or another.
193  *
194  * Simplest thing to do: step inside of the face a little bit, where there is known patch at
195  * which there must be proper derivatives. This might break continuity of normals, but is better
196  * that giving totally unusable derivatives. */
197 
198  if (r_dPdu != NULL && r_dPdv != NULL) {
199  if ((is_zero_v3(r_dPdu) || is_zero_v3(r_dPdv)) || equals_v3v3(r_dPdu, r_dPdv)) {
200  subdiv->evaluator->evaluateLimit(subdiv->evaluator,
201  ptex_face_index,
202  u * 0.999f + 0.0005f,
203  v * 0.999f + 0.0005f,
204  r_P,
205  r_dPdu,
206  r_dPdv);
207  }
208  }
209 }
210 
212  const int ptex_face_index,
213  const float u,
214  const float v,
215  float r_P[3],
216  float r_N[3])
217 {
218  float dPdu[3], dPdv[3];
219  BKE_subdiv_eval_limit_point_and_derivatives(subdiv, ptex_face_index, u, v, r_P, dPdu, dPdv);
220  cross_v3_v3v3(r_N, dPdu, dPdv);
221  normalize_v3(r_N);
222 }
223 
225  const int ptex_face_index,
226  const float u,
227  const float v,
228  float r_P[3],
229  short r_N[3])
230 {
231  float N_float[3];
232  BKE_subdiv_eval_limit_point_and_normal(subdiv, ptex_face_index, u, v, r_P, N_float);
233  normal_float_to_short_v3(r_N, N_float);
234 }
235 
237  const int face_varying_channel,
238  const int ptex_face_index,
239  const float u,
240  const float v,
241  float r_face_varying[2])
242 {
244  subdiv->evaluator, face_varying_channel, ptex_face_index, u, v, r_face_varying);
245 }
246 
248  const int ptex_face_index,
249  const float u,
250  const float v,
251  const float dPdu[3],
252  const float dPdv[3],
253  float r_D[3])
254 {
255  if (subdiv->displacement_evaluator == NULL) {
256  zero_v3(r_D);
257  return;
258  }
260  subdiv->displacement_evaluator, ptex_face_index, u, v, dPdu, dPdv, r_D);
261 }
262 
264  Subdiv *subdiv, const int ptex_face_index, const float u, const float v, float r_P[3])
265 {
266  if (subdiv->displacement_evaluator) {
267  float dPdu[3], dPdv[3], D[3];
268  BKE_subdiv_eval_limit_point_and_derivatives(subdiv, ptex_face_index, u, v, r_P, dPdu, dPdv);
269  BKE_subdiv_eval_displacement(subdiv, ptex_face_index, u, v, dPdu, dPdv, D);
270  add_v3_v3(r_P, D);
271  }
272  else {
273  BKE_subdiv_eval_limit_point(subdiv, ptex_face_index, u, v, r_P);
274  }
275 }
276 
277 /* =================== Patch queries at given resolution =================== */
278 
279 /* Move buffer forward by a given number of bytes. */
280 static void buffer_apply_offset(void **buffer, const int offset)
281 {
282  *buffer = ((unsigned char *)*buffer) + offset;
283 }
284 
285 /* Write given number of floats to the beginning of given buffer. */
286 static void buffer_write_float_value(void **buffer, const float *values_buffer, int num_values)
287 {
288  memcpy(*buffer, values_buffer, sizeof(float) * num_values);
289 }
290 
291 /* Similar to above, just operates with short values. */
292 static void buffer_write_short_value(void **buffer, const short *values_buffer, int num_values)
293 {
294  memcpy(*buffer, values_buffer, sizeof(short) * num_values);
295 }
296 
298  const int ptex_face_index,
299  const int resolution,
300  void *buffer,
301  const int offset,
302  const int stride)
303 {
304  buffer_apply_offset(&buffer, offset);
305  const float inv_resolution_1 = 1.0f / (float)(resolution - 1);
306  for (int y = 0; y < resolution; y++) {
307  const float v = y * inv_resolution_1;
308  for (int x = 0; x < resolution; x++) {
309  const float u = x * inv_resolution_1;
310  BKE_subdiv_eval_limit_point(subdiv, ptex_face_index, u, v, buffer);
312  }
313  }
314 }
315 
317  const int ptex_face_index,
318  const int resolution,
319  void *point_buffer,
320  const int point_offset,
321  const int point_stride,
322  void *du_buffer,
323  const int du_offset,
324  const int du_stride,
325  void *dv_buffer,
326  const int dv_offset,
327  const int dv_stride)
328 {
329  buffer_apply_offset(&point_buffer, point_offset);
330  buffer_apply_offset(&du_buffer, du_offset);
331  buffer_apply_offset(&dv_buffer, dv_offset);
332  const float inv_resolution_1 = 1.0f / (float)(resolution - 1);
333  for (int y = 0; y < resolution; y++) {
334  const float v = y * inv_resolution_1;
335  for (int x = 0; x < resolution; x++) {
336  const float u = x * inv_resolution_1;
338  subdiv, ptex_face_index, u, v, point_buffer, du_buffer, dv_buffer);
339  buffer_apply_offset(&point_buffer, point_stride);
340  buffer_apply_offset(&du_buffer, du_stride);
341  buffer_apply_offset(&dv_buffer, dv_stride);
342  }
343  }
344 }
345 
347  const int ptex_face_index,
348  const int resolution,
349  void *point_buffer,
350  const int point_offset,
351  const int point_stride,
352  void *normal_buffer,
353  const int normal_offset,
354  const int normal_stride)
355 {
356  buffer_apply_offset(&point_buffer, point_offset);
357  buffer_apply_offset(&normal_buffer, normal_offset);
358  const float inv_resolution_1 = 1.0f / (float)(resolution - 1);
359  for (int y = 0; y < resolution; y++) {
360  const float v = y * inv_resolution_1;
361  for (int x = 0; x < resolution; x++) {
362  const float u = x * inv_resolution_1;
363  float normal[3];
364  BKE_subdiv_eval_limit_point_and_normal(subdiv, ptex_face_index, u, v, point_buffer, normal);
365  buffer_write_float_value(&normal_buffer, normal, 3);
366  buffer_apply_offset(&point_buffer, point_stride);
367  buffer_apply_offset(&normal_buffer, normal_stride);
368  }
369  }
370 }
371 
373  const int ptex_face_index,
374  const int resolution,
375  void *point_buffer,
376  const int point_offset,
377  const int point_stride,
378  void *normal_buffer,
379  const int normal_offset,
380  const int normal_stride)
381 {
382  buffer_apply_offset(&point_buffer, point_offset);
383  buffer_apply_offset(&normal_buffer, normal_offset);
384  const float inv_resolution_1 = 1.0f / (float)(resolution - 1);
385  for (int y = 0; y < resolution; y++) {
386  const float v = y * inv_resolution_1;
387  for (int x = 0; x < resolution; x++) {
388  const float u = x * inv_resolution_1;
389  short normal[3];
391  subdiv, ptex_face_index, u, v, point_buffer, normal);
392  buffer_write_short_value(&normal_buffer, normal, 3);
393  buffer_apply_offset(&point_buffer, point_stride);
394  buffer_apply_offset(&normal_buffer, normal_stride);
395  }
396  }
397 }
typedef float(TangentPoint)[2]
CustomData interface, see also DNA_customdata_types.h.
int CustomData_number_of_layers(const struct CustomData *data, int type)
void * CustomData_get_layer_n(const struct CustomData *data, int type, int n)
@ SUBDIV_STATS_EVALUATOR_REFINE
Definition: BKE_subdiv.h:96
@ SUBDIV_STATS_EVALUATOR_CREATE
Definition: BKE_subdiv.h:95
void BKE_subdiv_stats_end(SubdivStats *stats, eSubdivStatsValue value)
Definition: subdiv_stats.c:47
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
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define BLI_BITMAP_ENABLE(_bitmap, _index)
Definition: BLI_bitmap.h:78
#define BLI_BITMAP_TEST_BOOL(_bitmap, _index)
Definition: BLI_bitmap.h:73
#define BLI_BITMAP_NEW(_tot, _alloc_string)
Definition: BLI_bitmap.h:50
unsigned int BLI_bitmap
Definition: BLI_bitmap.h:32
MINLINE void normal_float_to_short_v3(short r[3], const float n[3])
MINLINE float normalize_v3(float r[3])
MINLINE bool is_zero_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE bool equals_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
@ CD_MLOOPUV
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei stride
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v
OpenSubdiv_Evaluator * openSubdiv_createEvaluatorFromTopologyRefiner(OpenSubdiv_TopologyRefiner *topology_refiner)
IconTextureDrawCall normal
__kernel void ccl_constant KernelData ccl_global void ccl_global char ccl_global int ccl_global char ccl_global unsigned int ccl_global float * buffer
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
unsigned int v
float co[3]
struct CustomData pdata ldata
struct MVert * mvert
int totvert
struct MLoop * mloop
int totpoly
struct MPoly * mpoly
void(* setCoarsePositions)(struct OpenSubdiv_Evaluator *evaluator, const float *positions, const int start_vertex_index, const int num_vertices)
void(* evaluateLimit)(struct OpenSubdiv_Evaluator *evaluator, const int ptex_face_index, float face_u, float face_v, float P[3], float dPdu[3], float dPdv[3])
void(* setFaceVaryingData)(struct OpenSubdiv_Evaluator *evaluator, const int face_varying_channel, const float *face_varying_data, const int start_vertex_index, const int num_vertices)
void(* evaluateFaceVarying)(struct OpenSubdiv_Evaluator *evaluator, const int face_varying_channel, const int ptex_face_index, float face_u, float face_v, float face_varying[2])
void(* refine)(struct OpenSubdiv_Evaluator *evaluator)
int(* getNumFaceVertices)(const struct OpenSubdiv_TopologyRefiner *topology_refiner, const int face_index)
const int *(* getFaceFVarValueIndices)(const struct OpenSubdiv_TopologyRefiner *topology_refiner, const int face_index, const int channel)
int(* getNumFaces)(const struct OpenSubdiv_TopologyRefiner *topology_refiner)
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
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
void BKE_subdiv_eval_limit_point(Subdiv *subdiv, const int ptex_face_index, const float u, const float v, float r_P[3])
Definition: subdiv_eval.c:171
void BKE_subdiv_eval_init_displacement(Subdiv *subdiv)
Definition: subdiv_eval.c:158
void BKE_subdiv_eval_displacement(Subdiv *subdiv, const int ptex_face_index, const float u, const float v, const float dPdu[3], const float dPdv[3], float r_D[3])
Definition: subdiv_eval.c:247
void BKE_subdiv_eval_limit_patch_resolution_point(Subdiv *subdiv, const int ptex_face_index, const int resolution, void *buffer, const int offset, const int stride)
Definition: subdiv_eval.c:297
bool BKE_subdiv_eval_begin_from_mesh(Subdiv *subdiv, const Mesh *mesh, const float(*coarse_vertex_cos)[3])
Definition: subdiv_eval.c:124
void BKE_subdiv_eval_face_varying(Subdiv *subdiv, const int face_varying_channel, const int ptex_face_index, const float u, const float v, float r_face_varying[2])
Definition: subdiv_eval.c:236
bool BKE_subdiv_eval_refine_from_mesh(Subdiv *subdiv, const Mesh *mesh, const float(*coarse_vertex_cos)[3])
Definition: subdiv_eval.c:134
void BKE_subdiv_eval_final_point(Subdiv *subdiv, const int ptex_face_index, const float u, const float v, float r_P[3])
Definition: subdiv_eval.c:263
void BKE_subdiv_eval_limit_point_and_short_normal(Subdiv *subdiv, const int ptex_face_index, const float u, const float v, float r_P[3], short r_N[3])
Definition: subdiv_eval.c:224
void BKE_subdiv_eval_limit_point_and_normal(Subdiv *subdiv, const int ptex_face_index, const float u, const float v, float r_P[3], float r_N[3])
Definition: subdiv_eval.c:211
bool BKE_subdiv_eval_begin(Subdiv *subdiv)
Definition: subdiv_eval.c:41
static void buffer_write_float_value(void **buffer, const float *values_buffer, int num_values)
Definition: subdiv_eval.c:286
void BKE_subdiv_eval_limit_patch_resolution_point_and_derivatives(Subdiv *subdiv, const int ptex_face_index, const int resolution, void *point_buffer, const int point_offset, const int point_stride, void *du_buffer, const int du_offset, const int du_stride, void *dv_buffer, const int dv_offset, const int dv_stride)
Definition: subdiv_eval.c:316
void BKE_subdiv_eval_limit_patch_resolution_point_and_normal(Subdiv *subdiv, const int ptex_face_index, const int resolution, void *point_buffer, const int point_offset, const int point_stride, void *normal_buffer, const int normal_offset, const int normal_stride)
Definition: subdiv_eval.c:346
static void set_coarse_positions(Subdiv *subdiv, const Mesh *mesh, const float(*coarse_vertex_cos)[3])
Definition: subdiv_eval.c:64
static void set_face_varying_data_from_uv(Subdiv *subdiv, const MLoopUV *mloopuv, const int layer_index)
Definition: subdiv_eval.c:102
void BKE_subdiv_eval_limit_point_and_derivatives(Subdiv *subdiv, const int ptex_face_index, const float u, const float v, float r_P[3], float r_dPdu[3], float r_dPdv[3])
Definition: subdiv_eval.c:177
void BKE_subdiv_eval_limit_patch_resolution_point_and_short_normal(Subdiv *subdiv, const int ptex_face_index, const int resolution, void *point_buffer, const int point_offset, const int point_stride, void *normal_buffer, const int normal_offset, const int normal_stride)
Definition: subdiv_eval.c:372
static void buffer_write_short_value(void **buffer, const short *values_buffer, int num_values)
Definition: subdiv_eval.c:292
static void buffer_apply_offset(void **buffer, const int offset)
Definition: subdiv_eval.c:280
BLI_INLINE float D(const float *data, const int res[3], int x, int y, int z)
Definition: voxel.c:29