67 const int ptex_face_index,
70 const MDisps **r_displacement_grid,
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)
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]];
113 if (displacement_grid.
disps ==
nullptr) {
114 r_tangent_D =
float3(0.0f);
117 const int x =
roundf(grid_u * (grid_size - 1));
118 const int y =
roundf(grid_v * (grid_size - 1));
119 r_tangent_D = displacement_grid.
disps[
y * grid_size +
x];
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,
155 const bool is_quad = num_corners == 4;
156 const int quad_corner = is_quad ? corner : 0;
165 const MDisps &other_displacement_grid,
174 const MDisps &displacement_grid,
177 const int ptex_face_index,
178 const int corner_index,
182 const int num_corners =
data.faces[face_corner.
face_index].size();
191 *
data.subdiv, num_corners, ptex_face_index, corner_index, u,
v, tangent_matrix);
200 const int ptex_face_index,
202 const int corner_delta,
203 int &r_other_ptex_face_index,
204 int &r_other_corner_index)
207 const int face_index = face_corner.
face_index;
208 const int num_corners =
data.faces[face_corner.
face_index].size();
209 const bool is_quad = (num_corners == 4);
210 const int start_ptex_face_index =
data.face_ptex_offset[face_index];
211 r_other_corner_index = (corner + corner_delta + num_corners) % num_corners;
212 r_other_ptex_face_index = is_quad ? start_ptex_face_index :
213 start_ptex_face_index + r_other_corner_index;
218 const int ptex_face_index,
222 const int corner_delta,
228 displacement, ptex_face_index, corner, corner_delta);
229 int other_ptex_face_index, other_corner_index;
231 data, ptex_face_index, corner, corner_delta, other_ptex_face_index, other_corner_index);
235 other_displacement_grid,
238 other_ptex_face_index,
247 const int ptex_face_index,
256 const int num_corners =
data.faces[face_corner.
face_index].size();
257 for (
int corner_delta = 1; corner_delta < num_corners; corner_delta++) {
258 average_with_other(displacement, ptex_face_index, corner, 0.0f, 0.0f, corner_delta, r_D);
263 const int ptex_face_index,
273 const int ptex_face_index,
284 const int ptex_face_index,
290 switch (average_with) {
292 average_with_all(displacement, ptex_face_index, corner, grid_u, grid_v, r_D);
306 const int ptex_face_index,
311 const int num_corners =
data.faces[face_corner.
face_index].size();
312 const bool is_quad = (num_corners == 4);
314 float dummy_corner_u, dummy_corner_v;
318 return face_corner.
corner;
326 data.is_initialized =
true;
330 const int ptex_face_index,
340 const int grid_size =
data.grid_size;
342 const MDisps *displacement_grid;
343 float grid_u, grid_v;
345 *displacement, ptex_face_index, u,
v, &displacement_grid, grid_u, grid_v);
350 *displacement_grid, grid_size, grid_u, grid_v, tangent_D);
358 average_displacement(*displacement, average_with, ptex_face_index, corner, grid_u, grid_v, r_D);
372 int num_ptex_faces = 0;
374 for (
int face_index = 0; face_index <
mesh.faces_num; face_index++) {
375 num_ptex_faces += (
faces[face_index].size() == 4) ? 1 :
faces[face_index].size();
377 return num_ptex_faces;
386 data.ptex_face_corner.reinitialize(num_ptex_faces);
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;
421 data.is_initialized =
false;
445 displacement->
user_data = MEM_new<MultiresDisplacementData>(
"multires displacement data");
449 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(blender::float3x3 &tangent_matrix, const blender::float3 &dPdu, const blender::float3 &dPdv, int corner)
void multiresModifier_ensure_external_read(Mesh *mesh, const MultiresModifierData *mmd)
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)
static void average_read_displacement_tangent(const MultiresDisplacementData &data, const MDisps &other_displacement_grid, const float grid_u, const float grid_v, float3 &r_tangent_D)
static void average_with_next(const Displacement &displacement, const int ptex_face_index, const int corner, const float grid_u, const float, float3 &r_D)
BLI_INLINE AverageWith read_displacement_grid(const MDisps &displacement_grid, const int grid_size, const float grid_u, const float grid_v, float3 &r_tangent_D)
static void average_with_other(const Displacement &displacement, const int ptex_face_index, const int corner, const float grid_u, const float grid_v, const int corner_delta, float3 &r_D)
static void average_with_prev(const Displacement &displacement, const int ptex_face_index, const int corner, const float, const float grid_v, float3 &r_D)
BLI_INLINE void rotate_grid_to_quad(int corner, float grid_u, float grid_v, float *r_quad_u, float *r_quad_v)
void displacement_attach_from_multires(Subdiv *subdiv, const Mesh *mesh, const MultiresModifierData *mmd)
static void average_read_displacement_object(const MultiresDisplacementData &data, const MDisps &displacement_grid, const float grid_u, const float grid_v, const int ptex_face_index, const int corner_index, float3 &r_D)
static int count_num_ptex_faces(const Mesh &mesh)
BLI_INLINE void grid_uv_to_ptex_face_uv(float grid_u, float grid_v, float *r_ptex_u, float *r_ptex_v)
static void displacement_data_init_mapping(Displacement &displacement, const Mesh &mesh)
static void average_get_other_ptex_and_corner(const 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)
void displacement_detach(Subdiv *subdiv)
static void average_displacement(const Displacement &displacement, const AverageWith average_with, const int ptex_face_index, const int corner, const float grid_u, const float grid_v, float3 &r_D)
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)
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, float3x3 &r_tangent_matrix)
BLI_INLINE int rotate_quad_to_corner(float quad_u, float quad_v, float *r_corner_u, float *r_corner_v)
void eval_limit_point_and_derivatives(Subdiv *subdiv, int ptex_face_index, float u, float v, float3 &r_P, float3 &r_dPdu, float3 &r_dPdv)
static void displacement_init_functions(Displacement *displacement)
void eval_displacement(Subdiv *subdiv, int ptex_face_index, float u, float v, const float3 &dPdu, const float3 &dPdv, float3 &r_D)
static void initialize(Displacement *displacement)
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 int displacement_get_grid_and_coord(const Displacement &displacement, const int ptex_face_index, const float u, const float v, const MDisps **r_displacement_grid, float &r_grid_u, float &r_grid_v)
static void free_displacement(Displacement *displacement)
static void displacement_init_data(Displacement &displacement, Subdiv &subdiv, const Mesh &mesh, const MultiresModifierData &mmd)
static void average_with_all(const Displacement &displacement, const int ptex_face_index, const int corner, const float, const float, float3 &r_D)
static int displacement_get_face_corner(const MultiresDisplacementData &data, const int ptex_face_index, const float u, const float v)
static const MDisps * displacement_get_other_grid(const Displacement &displacement, const int ptex_face_index, const int corner, const int corner_delta)
Span< int > face_ptex_offset_get(Subdiv *subdiv)
VecBase< T, 3 > transform_direction(const MatBase< T, 3, 3 > &mat, const VecBase< T, 3 > &direction)
MatBase< float, 3, 3 > float3x3
VecBase< float, 3 > float3
void(* eval_displacement)(Displacement *displacement, int ptex_face_index, float u, float v, const float3 &dPdu, const float3 &dPdv, float3 &r_D)
void(* free)(Displacement *displacement)
void(* initialize)(Displacement *displacement)
OffsetIndices< int > faces
const MultiresModifierData * mmd
Array< PolyCornerIndex > ptex_face_corner
Span< int > face_ptex_offset