67 const int ptex_face_index,
70 const MDisps **r_displacement_grid,
76 const PolyCornerIndex *face_corner = &data->ptex_face_corner[ptex_face_index];
78 const int start_grid_index = face.
start() + face_corner->
corner;
80 if (face.size() == 4) {
81 float corner_u, corner_v;
83 *r_displacement_grid = &data->mdisps[start_grid_index + corner];
87 *r_displacement_grid = &data->mdisps[start_grid_index];
94 const int ptex_face_index,
96 const int corner_delta)
100 const PolyCornerIndex *face_corner = &data->ptex_face_corner[ptex_face_index];
102 const int effective_corner = (face.size() == 4) ? corner : face_corner->
corner;
103 const int next_corner = (effective_corner + corner_delta + face.size()) % face.size();
104 return &data->mdisps[face[next_corner]];
111 float r_tangent_D[3])
113 if (displacement_grid->
disps ==
nullptr) {
117 const int x = roundf(grid_u * (grid_size - 1));
118 const int y = roundf(grid_v * (grid_size - 1));
120 if (x == 0 && y == 0) {
136 float *r_ptex_face_u,
137 float *r_ptex_face_v)
139 if (num_corners == 4) {
148 const int num_corners,
149 const int ptex_face_index,
153 float r_tangent_matrix[3][3])
155 const bool is_quad = num_corners == 4;
156 const int quad_corner = is_quad ? corner : 0;
157 float dummy_P[3], dPdu[3], dPdv[3];
163 const MDisps *other_displacement_grid,
166 float r_tangent_D[3])
172 const MDisps *displacement_grid,
175 const int ptex_face_index,
176 const int corner_index,
179 const PolyCornerIndex *face_corner = &data->ptex_face_corner[ptex_face_index];
180 const int num_corners = data->faces[face_corner->
face_index].size();
187 float tangent_matrix[3][3];
189 data->subdiv, num_corners, ptex_face_index, corner_index, u,
v, tangent_matrix);
198 const int ptex_face_index,
200 const int corner_delta,
201 int *r_other_ptex_face_index,
202 int *r_other_corner_index)
204 const PolyCornerIndex *face_corner = &data->ptex_face_corner[ptex_face_index];
205 const int face_index = face_corner->
face_index;
206 const int num_corners = data->faces[face_corner->
face_index].size();
207 const bool is_quad = (num_corners == 4);
208 const int start_ptex_face_index = data->face_ptex_offset[face_index];
209 *r_other_corner_index = (corner + corner_delta + num_corners) % num_corners;
210 *r_other_ptex_face_index = is_quad ? start_ptex_face_index :
211 start_ptex_face_index + *r_other_corner_index;
216 const int ptex_face_index,
220 const int corner_delta,
226 displacement, ptex_face_index, corner, corner_delta);
227 int other_ptex_face_index, other_corner_index;
229 data, ptex_face_index, corner, corner_delta, &other_ptex_face_index, &other_corner_index);
233 other_displacement_grid,
236 other_ptex_face_index,
245 const int ptex_face_index,
253 const PolyCornerIndex *face_corner = &data->ptex_face_corner[ptex_face_index];
254 const int num_corners = data->faces[face_corner->
face_index].size();
255 for (
int corner_delta = 1; corner_delta < num_corners; corner_delta++) {
256 average_with_other(displacement, ptex_face_index, corner, 0.0f, 0.0f, corner_delta, r_D);
261 const int ptex_face_index,
271 const int ptex_face_index,
282 const int ptex_face_index,
288 switch (average_with) {
290 average_with_all(displacement, ptex_face_index, corner, grid_u, grid_v, r_D);
304 const int ptex_face_index,
308 const PolyCornerIndex *face_corner = &data->ptex_face_corner[ptex_face_index];
309 const int num_corners = data->faces[face_corner->
face_index].size();
310 const bool is_quad = (num_corners == 4);
312 float dummy_corner_u, dummy_corner_v;
316 return face_corner->
corner;
324 data->is_initialized =
true;
328 const int ptex_face_index,
338 const int grid_size = data->grid_size;
340 const MDisps *displacement_grid;
341 float grid_u, grid_v;
343 displacement, ptex_face_index, u,
v, &displacement_grid, &grid_u, &grid_v);
348 displacement_grid, grid_size, grid_u, grid_v, tangent_D);
350 float tangent_matrix[3][3];
370 int num_ptex_faces = 0;
372 for (
int face_index = 0; face_index < mesh->faces_num; face_index++) {
373 num_ptex_faces += (faces[face_index].size() == 4) ? 1 : faces[face_index].size();
375 return num_ptex_faces;
386 MEM_malloc_arrayN(num_ptex_faces,
sizeof(*data->ptex_face_corner),
"PTEX face corner"));
388 int ptex_face_index = 0;
390 for (
int face_index = 0; face_index < mesh->faces_num; face_index++) {
392 if (face.size() == 4) {
393 ptex_face_corner[ptex_face_index].
face_index = face_index;
394 ptex_face_corner[ptex_face_index].
corner = 0;
398 for (
int corner = 0; corner < face.size(); corner++) {
399 ptex_face_corner[ptex_face_index].
face_index = face_index;
400 ptex_face_corner[ptex_face_index].
corner = corner;
418 data->faces = mesh->faces();
421 data->is_initialized =
false;
442 Displacement *displacement = MEM_cnew<Displacement>(
"multires displacement");
444 "multires displacement data");
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.
ATTR_WARN_UNUSED_RESULT const BMVert * v
constexpr int64_t start() const
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
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 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
Displacement * displacement_evaluator