66 const int ptex_face_index,
69 const MDisps **r_displacement_grid,
77 const int start_grid_index = face.
start() + face_corner->
corner;
79 if (face.
size() == 4) {
80 float corner_u, corner_v;
82 *r_displacement_grid = &
data->mdisps[start_grid_index + corner];
86 *r_displacement_grid = &
data->mdisps[start_grid_index];
93 const int ptex_face_index,
95 const int corner_delta)
101 const int effective_corner = (face.
size() == 4) ? corner : face_corner->
corner;
102 const int next_corner = (effective_corner + corner_delta + face.
size()) % face.
size();
103 return &
data->mdisps[face[next_corner]];
110 float r_tangent_D[3])
112 if (displacement_grid->
disps ==
nullptr) {
116 const int x = roundf(grid_u * (grid_size - 1));
117 const int y = roundf(grid_v * (grid_size - 1));
119 if (
x == 0 &&
y == 0) {
135 float *r_ptex_face_u,
136 float *r_ptex_face_v)
138 if (num_corners == 4) {
147 const int num_corners,
148 const int ptex_face_index,
152 float r_tangent_matrix[3][3])
154 const bool is_quad = num_corners == 4;
155 const int quad_corner = is_quad ? corner : 0;
156 float dummy_P[3], dPdu[3], dPdv[3];
162 const MDisps *other_displacement_grid,
165 float r_tangent_D[3])
171 const MDisps *displacement_grid,
174 const int ptex_face_index,
175 const int corner_index,
179 const int num_corners =
data->faces[face_corner->
face_index].size();
186 float tangent_matrix[3][3];
188 data->subdiv, num_corners, ptex_face_index, corner_index, u,
v, tangent_matrix);
197 const int ptex_face_index,
199 const int corner_delta,
200 int *r_other_ptex_face_index,
201 int *r_other_corner_index)
204 const int face_index = face_corner->
face_index;
205 const int num_corners =
data->faces[face_corner->
face_index].size();
206 const bool is_quad = (num_corners == 4);
207 const int start_ptex_face_index =
data->face_ptex_offset[face_index];
208 *r_other_corner_index = (corner + corner_delta + num_corners) % num_corners;
209 *r_other_ptex_face_index = is_quad ? start_ptex_face_index :
210 start_ptex_face_index + *r_other_corner_index;
215 const int ptex_face_index,
219 const int corner_delta,
225 displacement, ptex_face_index, corner, corner_delta);
226 int other_ptex_face_index, other_corner_index;
228 data, ptex_face_index, corner, corner_delta, &other_ptex_face_index, &other_corner_index);
232 other_displacement_grid,
235 other_ptex_face_index,
244 const int ptex_face_index,
253 const int num_corners =
data->faces[face_corner->
face_index].size();
254 for (
int corner_delta = 1; corner_delta < num_corners; corner_delta++) {
255 average_with_other(displacement, ptex_face_index, corner, 0.0f, 0.0f, corner_delta, r_D);
260 const int ptex_face_index,
270 const int ptex_face_index,
281 const int ptex_face_index,
287 switch (average_with) {
289 average_with_all(displacement, ptex_face_index, corner, grid_u, grid_v, r_D);
303 const int ptex_face_index,
308 const int num_corners =
data->faces[face_corner->
face_index].size();
309 const bool is_quad = (num_corners == 4);
311 float dummy_corner_u, dummy_corner_v;
315 return face_corner->
corner;
323 data->is_initialized =
true;
327 const int ptex_face_index,
337 const int grid_size =
data->grid_size;
339 const MDisps *displacement_grid;
340 float grid_u, grid_v;
342 displacement, ptex_face_index, u,
v, &displacement_grid, &grid_u, &grid_v);
347 displacement_grid, grid_size, grid_u, grid_v, tangent_D);
349 float tangent_matrix[3][3];
369 int num_ptex_faces = 0;
371 for (
int face_index = 0; face_index <
mesh->faces_num; face_index++) {
372 num_ptex_faces += (
faces[face_index].size() == 4) ? 1 :
faces[face_index].size();
374 return num_ptex_faces;
387 int ptex_face_index = 0;
389 for (
int face_index = 0; face_index <
mesh->faces_num; face_index++) {
391 if (face.
size() == 4) {
392 ptex_face_corner[ptex_face_index].
face_index = face_index;
393 ptex_face_corner[ptex_face_index].
corner = 0;
397 for (
int corner = 0; corner < face.
size(); corner++) {
398 ptex_face_corner[ptex_face_index].
face_index = face_index;
399 ptex_face_corner[ptex_face_index].
corner = corner;
420 data->is_initialized =
false;
442 displacement->
user_data = MEM_new<MultiresDisplacementData>(
"multires displacement data");
446 subdiv->displacement_evaluator = displacement;
CustomData interface, see also DNA_customdata_types.h.
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
BLI_INLINE void BKE_multires_construct_tangent_matrix(float tangent_matrix[3][3], const float dPdu[3], const float dPdv[3], int corner)
void multiresModifier_ensure_external_read(Mesh *mesh, const MultiresModifierData *mmd)
void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
Read Guarded memory(de)allocation.
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert * v
constexpr int64_t size() const
constexpr int64_t start() const
void * MEM_callocN(size_t len, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
void displacement_attach_from_multires(Subdiv *subdiv, Mesh *mesh, const MultiresModifierData *mmd)
static void average_with_prev(Displacement *displacement, const int ptex_face_index, const int corner, const float, const float grid_v, float r_D[3])
static void average_convert_grid_coord_to_ptex(const int num_corners, const int corner, const float grid_u, const float grid_v, float *r_ptex_face_u, float *r_ptex_face_v)
static void average_read_displacement_object(MultiresDisplacementData *data, const MDisps *displacement_grid, const float grid_u, const float grid_v, const int ptex_face_index, const int corner_index, float r_D[3])
static void average_construct_tangent_matrix(Subdiv *subdiv, const int num_corners, const int ptex_face_index, const int corner, const float u, const float v, float r_tangent_matrix[3][3])
static void average_displacement(Displacement *displacement, eAverageWith average_with, const int ptex_face_index, const int corner, const float grid_u, const float grid_v, float r_D[3])
static void displacement_init_data(Displacement *displacement, Subdiv *subdiv, Mesh *mesh, const MultiresModifierData *mmd)
static void average_with_other(Displacement *displacement, const int ptex_face_index, const int corner, const float grid_u, const float grid_v, const int corner_delta, float r_D[3])
static const MDisps * displacement_get_other_grid(Displacement *displacement, const int ptex_face_index, const int corner, const int corner_delta)
BLI_INLINE void rotate_grid_to_quad(int corner, float grid_u, float grid_v, float *r_quad_u, float *r_quad_v)
static void average_read_displacement_tangent(MultiresDisplacementData *data, const MDisps *other_displacement_grid, const float grid_u, const float grid_v, float r_tangent_D[3])
void eval_displacement(Subdiv *subdiv, int ptex_face_index, float u, float v, const float dPdu[3], const float dPdv[3], float r_D[3])
void eval_limit_point_and_derivatives(Subdiv *subdiv, int ptex_face_index, float u, float v, float r_P[3], float r_dPdu[3], float r_dPdv[3])
static int displacement_get_grid_and_coord(Displacement *displacement, const int ptex_face_index, const float u, const float v, const MDisps **r_displacement_grid, float *grid_u, float *grid_v)
BLI_INLINE void grid_uv_to_ptex_face_uv(float grid_u, float grid_v, float *r_ptex_u, float *r_ptex_v)
void displacement_detach(Subdiv *subdiv)
BLI_INLINE void ptex_face_uv_to_grid_uv(float ptex_u, float ptex_v, float *r_grid_u, float *r_grid_v)
BLI_INLINE int grid_size_from_level(int level)
BLI_INLINE int rotate_quad_to_corner(float quad_u, float quad_v, float *r_corner_u, float *r_corner_v)
static void average_get_other_ptex_and_corner(MultiresDisplacementData *data, const int ptex_face_index, const int corner, const int corner_delta, int *r_other_ptex_face_index, int *r_other_corner_index)
BLI_INLINE eAverageWith read_displacement_grid(const MDisps *displacement_grid, const int grid_size, const float grid_u, const float grid_v, float r_tangent_D[3])
static void displacement_init_functions(Displacement *displacement)
int * face_ptex_offset_get(Subdiv *subdiv)
static void initialize(Displacement *displacement)
static void free_displacement(Displacement *displacement)
static void displacement_data_init_mapping(Displacement *displacement, const Mesh *mesh)
static int displacement_get_face_corner(MultiresDisplacementData *data, const int ptex_face_index, const float u, const float v)
static int count_num_ptex_faces(const Mesh *mesh)
static void average_with_all(Displacement *displacement, const int ptex_face_index, const int corner, const float, const float, float r_D[3])
static void average_with_next(Displacement *displacement, const int ptex_face_index, const int corner, const float grid_u, const float, float r_D[3])
void(* free)(Displacement *displacement)
void(* eval_displacement)(Displacement *displacement, int ptex_face_index, float u, float v, const float dPdu[3], const float dPdv[3], float r_D[3])
void(* initialize)(Displacement *displacement)
PolyCornerIndex * ptex_face_corner
OffsetIndices< int > faces
const MultiresModifierData * mmd