[Bf-blender-cvs] [02f86482b4e] master: Multires: Simplify reshaping code
Sergey Sharybin
noreply at git.blender.org
Fri Jan 18 12:30:27 CET 2019
Commit: 02f86482b4e528f4cee106983c0c6ef81b0ca3e3
Author: Sergey Sharybin
Date: Thu Jan 17 12:06:26 2019 +0100
Branches: master
https://developer.blender.org/rB02f86482b4e528f4cee106983c0c6ef81b0ca3e3
Multires: Simplify reshaping code
The idea is to run reshaping for every boundary vertex
of a grid rather than trying to copy boundary grid
elements.
While this is somewhat slower, this avoids all this
tangent flipping magic, which tempts to be rather tricky
and fragile.
===================================================================
M source/blender/blenkernel/BKE_multires.h
M source/blender/blenkernel/intern/multires_reshape.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h
index 7cefda3330d..f246522fffe 100644
--- a/source/blender/blenkernel/BKE_multires.h
+++ b/source/blender/blenkernel/BKE_multires.h
@@ -155,8 +155,10 @@ void BKE_multires_subdiv_mesh_settings_init(
/* For a given partial derivatives of a ptex face get tangent matrix for
* displacement.
- * Corner needs to be known to properly "rotate" partial derivatives.
- */
+ *
+ * Corner needs to be known to properly "rotate" partial derivatives when the
+ * matrix is being constructed for quad. For non-quad the corner is to be set
+ * to 0. */
BLI_INLINE void BKE_multires_construct_tangent_matrix(
float tangent_matrix[3][3],
const float dPdu[3],
diff --git a/source/blender/blenkernel/intern/multires_reshape.c b/source/blender/blenkernel/intern/multires_reshape.c
index 96f5e9b6b01..6fd9176dbcb 100644
--- a/source/blender/blenkernel/intern/multires_reshape.c
+++ b/source/blender/blenkernel/intern/multires_reshape.c
@@ -143,119 +143,63 @@ static void multires_reshape_ensure_grids(Mesh *mesh, const int grid_level)
multires_reshape_ensure_mask_grids(mesh, grid_level);
}
-static void multires_reshape_vertex_copy_to_next(
- MultiresReshapeContext *ctx,
+/* Convert normalized coordinate within a grid to a normalized coordinate within
+ * a ptex face. */
+static void multires_reshape_grid_coord_to_ptex(
const MPoly *coarse_poly,
- const int current_corner,
- const MDisps *current_displacement_grid,
- const GridPaintMask *current_mask_grid,
- const int current_grid_x, const int current_grid_y)
+ const int corner, const float corner_u, const float corner_v,
+ float *r_ptex_face_u, float *r_ptex_face_v)
{
- const int grid_size = ctx->top_grid_size;
- const int next_current_corner = (current_corner + 1) % coarse_poly->totloop;
- const int next_grid_x = 0;
- const int next_grid_y = current_grid_x;
- const int current_index = current_grid_y * grid_size + current_grid_x;
- const int next_index = next_grid_y * grid_size + next_grid_x;
- /* Copy displacement. */
- MDisps *next_displacement_grid = &ctx->mdisps[
- coarse_poly->loopstart + next_current_corner];
- float *next_displacement = next_displacement_grid->disps[next_index];
- copy_v3_v3(next_displacement,
- current_displacement_grid->disps[current_index]);
- SWAP(float, next_displacement[0], next_displacement[1]);
- next_displacement[0] = -next_displacement[0];
- /* Copy mask, if exists. */
- if (current_mask_grid != NULL) {
- GridPaintMask *next_mask_grid = &ctx->grid_paint_mask[
- coarse_poly->loopstart + next_current_corner];
- next_mask_grid->data[next_index] =
- current_mask_grid->data[current_index];
+ if (coarse_poly->totloop == 4) {
+ float grid_u, grid_v;
+ BKE_subdiv_ptex_face_uv_to_grid_uv(
+ corner_u, corner_v, &grid_u, &grid_v);
+ BKE_subdiv_rotate_grid_to_quad(corner, grid_u, grid_v,
+ r_ptex_face_u, r_ptex_face_v);
+ }
+ else {
+ *r_ptex_face_u = corner_u;
+ *r_ptex_face_v = corner_v;
}
}
-static void multires_reshape_vertex_copy_to_prev(
- MultiresReshapeContext *ctx,
+/* NOTE: The tangent vectors are measured in ptex face normalized coordinates,
+ * which is different from grid tangent. */
+static void multires_reshape_sample_surface(
+ Subdiv *subdiv,
const MPoly *coarse_poly,
- const int current_corner,
- const MDisps *current_displacement_grid,
- const GridPaintMask *current_mask_grid,
- const int current_grid_x, const int current_grid_y)
+ const int corner, const float corner_u, const float corner_v,
+ const int ptex_face_index,
+ float r_P[3], float r_dPdu[3], float r_dPdv[3])
{
- const int grid_size = ctx->top_grid_size;
- const int prev_current_corner =
- (current_corner - 1 + coarse_poly->totloop) % coarse_poly->totloop;
- const int prev_grid_x = current_grid_y;
- const int prev_grid_y = 0;
- const int current_index = current_grid_y * grid_size + current_grid_x;
- const int prev_index = prev_grid_y * grid_size + prev_grid_x;
- /* Copy displacement. */
- MDisps *prev_displacement_grid = &ctx->mdisps[
- coarse_poly->loopstart + prev_current_corner];
- float *prev_displacement = prev_displacement_grid->disps[prev_index];
- copy_v3_v3(prev_displacement,
- current_displacement_grid->disps[current_index]);
- SWAP(float, prev_displacement[0], prev_displacement[1]);
- prev_displacement[1] = -prev_displacement[1];
- /* Copy mask, if exists. */
- if (current_mask_grid != NULL) {
- GridPaintMask *prev_mask_grid = &ctx->grid_paint_mask[
- coarse_poly->loopstart + prev_current_corner];
- prev_mask_grid->data[prev_index] =
- current_mask_grid->data[current_index];
- }
+ float ptex_face_u, ptex_face_v;
+ multires_reshape_grid_coord_to_ptex(coarse_poly, corner, corner_u, corner_v,
+ &ptex_face_u, &ptex_face_v);
+ BKE_subdiv_eval_limit_point_and_derivatives(
+ subdiv,
+ ptex_face_index, ptex_face_u, ptex_face_v,
+ r_P, r_dPdu, r_dPdv);
}
-static void copy_boundary_displacement(
- MultiresReshapeContext *ctx,
+static void multires_reshape_tangent_matrix_for_corner(
const MPoly *coarse_poly,
- const int corner,
- const int grid_x, const int grid_y,
- const MDisps *displacement_grid,
- const GridPaintMask *mask_grid)
+ const int coarse_corner,
+ const float dPdu[3], const float dPdv[3],
+ float r_tangent_matrix[3][3])
{
- if (grid_x == 0 && grid_y == 0) {
- for (int i = 0; i < coarse_poly->totloop; i++) {
- const int current_face_corner =
- (corner + i) % coarse_poly->totloop;
- const int grid_index = coarse_poly->loopstart + current_face_corner;
- MDisps *current_displacement_grid = &ctx->mdisps[grid_index];
- GridPaintMask *current_mask_grid =
- mask_grid != NULL ? &ctx->grid_paint_mask[grid_index]
- : NULL;
- multires_reshape_vertex_copy_to_next(
- ctx,
- coarse_poly,
- current_face_corner,
- current_displacement_grid,
- current_mask_grid,
- 0, 0);
- }
- }
- else if (grid_x == 0) {
- multires_reshape_vertex_copy_to_prev(
- ctx,
- coarse_poly,
- corner,
- displacement_grid,
- mask_grid,
- grid_x, grid_y);
- }
- else if (grid_y == 0) {
- multires_reshape_vertex_copy_to_next(
- ctx,
- coarse_poly,
- corner,
- displacement_grid,
- mask_grid,
- grid_x, grid_y);
- }
+ /* For a quad faces we would need to flip the tangent, since they will use
+ * use different coordinates within displacement grid comparent to ptex
+ * face. */
+ const bool is_quad = (coarse_poly->totloop == 4);
+ const int tangent_corner = is_quad ? coarse_corner : 0;
+ BKE_multires_construct_tangent_matrix(
+ r_tangent_matrix, dPdu, dPdv, tangent_corner);
}
static void multires_reshape_vertex_from_final_data(
MultiresReshapeContext *ctx,
const int ptex_face_index,
- const float u, const float v,
+ const float corner_u, const float corner_v,
const int coarse_poly_index,
const int coarse_corner,
const float final_P[3], const float final_mask)
@@ -268,62 +212,39 @@ static void multires_reshape_vertex_from_final_data(
const int loop_index = coarse_poly->loopstart + coarse_corner;
/* Evaluate limit surface. */
float P[3], dPdu[3], dPdv[3];
- BKE_subdiv_eval_limit_point_and_derivatives(
- subdiv, ptex_face_index, u, v, P, dPdu, dPdv);
- /* Get coordinate and corner configuration. */
- float grid_u, grid_v;
- MDisps *displacement_grid;
- GridPaintMask *grid_paint_mask = NULL;
- int face_corner = coarse_corner;
- int grid_corner = 0;
- int grid_index;
- if (coarse_poly->totloop == 4) {
- float corner_u, corner_v;
- face_corner = BKE_subdiv_rotate_quad_to_corner(
- u, v, &corner_u, &corner_v);
- grid_corner = face_corner;
- grid_index = loop_index + face_corner;
- BKE_subdiv_ptex_face_uv_to_grid_uv(
- corner_u, corner_v, &grid_u, &grid_v);
- }
- else {
- grid_index = loop_index;
- BKE_subdiv_ptex_face_uv_to_grid_uv(u, v, &grid_u, &grid_v);
- }
- displacement_grid = &ctx->mdisps[grid_index];
- if (ctx->grid_paint_mask != NULL) {
- grid_paint_mask = &ctx->grid_paint_mask[grid_index];
- BLI_assert(grid_paint_mask->level == displacement_grid->level);
- }
+ multires_reshape_sample_surface(
+ subdiv,
+ coarse_poly,
+ coarse_corner, corner_u, corner_v,
+ ptex_face_index,
+ P, dPdu, dPdv);
+ /* Construct tangent matrix which matches orientation of the current
+ * displacement grid. */
+ float tangent_matrix[3][3], inv_tangent_matrix[3][3];
+ multires_reshape_tangent_matrix_for_corner(coarse_poly, coarse_corner,
+ dPdu, dPdv,
+ tangent_matrix);
+ invert_m3_m3(inv_tangent_matrix, tangent_matrix);
/* Convert object coordinate to a tangent space of displacement grid. */
float D[3];
sub_v3_v3v3(D, final_P, P);
- float tangent_matrix[3][3];
- BKE_multires_construct_tangent_matrix(
- tangent_matrix, dPdu, dPdv, grid_corner);
- float inv_tangent_matrix[3][3];
- invert_m3_m3(inv_tangent_matrix, tangent_matrix);
float tangent_D[3];
mul_v3_m3v3(tangent_D, inv_tangent_matrix, D);
- /* Write tangent displacement. */
+ /* Calculate index of element within the grid. */
+ float grid_u, grid_v;
+ BKE_subdiv_ptex_face_uv_to_grid_uv(corner_u, corner_v, &grid_u, &grid_v);
const int grid_x = (grid_u * (grid_size - 1) + 0.5f);
const int grid_y = (grid_v * (grid_size - 1) + 0.5f);
const int index = grid_y * grid_size + grid_x;
+ /* Write tangent displacement. */
+ MDisps *displacement_grid = &ctx->mdisps[loop_index];
copy_v3_v3(displacement_grid->disps[index], tangent_D);
/* Write mask grid. */
- if (grid_paint_mask != NULL) {
+ if (ctx->grid_paint_mask != NULL) {
+ GridPaintMask *grid
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list