From 34ec716352a96fa967a8fa656fec3cad8b2e4a99 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 1 Nov 2018 11:06:00 +0100 Subject: Subdiv: Cleanup, deduplicate some code --- source/blender/blenkernel/BKE_subdiv.h | 17 +++++++ .../blender/blenkernel/intern/multires_reshape.c | 56 +++++++++------------- source/blender/blenkernel/intern/subdiv_ccg.c | 19 ++------ source/blender/blenkernel/intern/subdiv_ccg_mask.c | 17 ++----- .../intern/subdiv_displacement_multires.c | 16 ++----- source/blender/blenkernel/intern/subdiv_inline.h | 48 +++++++++++++++++++ 6 files changed, 97 insertions(+), 76 deletions(-) create mode 100644 source/blender/blenkernel/intern/subdiv_inline.h (limited to 'source') diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h index 06d57062b59..715f82fac55 100644 --- a/source/blender/blenkernel/BKE_subdiv.h +++ b/source/blender/blenkernel/BKE_subdiv.h @@ -32,6 +32,7 @@ #ifndef __BKE_SUBDIV_H__ #define __BKE_SUBDIV_H__ +#include "BLI_compiler_compat.h" #include "BLI_sys_types.h" struct Mesh; @@ -208,4 +209,20 @@ void BKE_subdiv_displacement_detach(Subdiv *subdiv); int *BKE_subdiv_face_ptex_offset_get(Subdiv *subdiv); +/* ============================= VARIOUS HELPERS ============================ */ + +/* For a given (ptex_u, ptex_v) within a ptex face get corresponding + * (grid_u, grid_v) within a grid. + */ +BLI_INLINE void BKE_subdiv_ptex_face_uv_to_grid_uv( + const float ptex_u, const float ptex_v, + float *r_grid_u, float *r_grid_v); + +/* For a given subdivision level (which is NOT refinement level) get size of + * CCG grid (number of grid points on a side). + */ +BLI_INLINE int BKE_subdiv_grid_size_from_level(const int level); + #endif /* __BKE_SUBDIV_H__ */ + +#include "intern/subdiv_inline.h" diff --git a/source/blender/blenkernel/intern/multires_reshape.c b/source/blender/blenkernel/intern/multires_reshape.c index b14010f3a90..ddbd6e45626 100644 --- a/source/blender/blenkernel/intern/multires_reshape.c +++ b/source/blender/blenkernel/intern/multires_reshape.c @@ -53,16 +53,6 @@ /* TODO(sergey): De-duplicate with subdiv_displacement_multires.c. */ -/* Coordinates within grid has different convention from PTex coordinates. - * This function converts the latter ones to former. - */ -BLI_INLINE void ptex_uv_to_grid_uv(const float ptex_u, const float ptex_v, - float *r_grid_u, float *r_grid_v) -{ - *r_grid_u = 1.0f - ptex_v; - *r_grid_v = 1.0f - ptex_u; -} - /* Simplified version of mdisp_rot_face_to_crn, only handles quad and * works in normalized coordinates. * @@ -159,8 +149,7 @@ typedef struct MultiresReshapeContext { static void multires_reshape_allocate_displacement_grid( MDisps *displacement_grid, const int level) { - /* TODO(sergey): Use grid_size_for_level_get() somehow. */ - const int grid_size = (1 << (level - 1)) + 1; + const int grid_size = BKE_subdiv_grid_size_from_level(level); const int grid_area = grid_size * grid_size; float (*disps)[3] = MEM_calloc_arrayN( grid_area, 3 * sizeof(float), "multires disps"); @@ -199,8 +188,7 @@ static void multires_reshape_ensure_mask_grids(Mesh *mesh, const int grid_level) return; } const int num_grids = mesh->totloop; - /* TODO(sergey): Use grid_size_for_level_get() somehow. */ - const int grid_size = (1 << (grid_level - 1)) + 1; + const int grid_size = BKE_subdiv_grid_size_from_level(grid_level); const int grid_area = grid_size * grid_size; for (int grid_index = 0; grid_index < num_grids; grid_index++) { GridPaintMask *grid_paint_mask = &grid_paint_masks[grid_index]; @@ -361,11 +349,12 @@ static void multires_reshape_vertex_from_final_data( face_corner = rotate_quad_to_corner(u, v, &corner_u, &corner_v); grid_corner = face_corner; grid_index = loop_index + face_corner; - ptex_uv_to_grid_uv(corner_u, corner_v, &grid_u, &grid_v); + BKE_subdiv_ptex_face_uv_to_grid_uv( + corner_u, corner_v, &grid_u, &grid_v); } else { grid_index = loop_index; - ptex_uv_to_grid_uv(u, v, &grid_u, &grid_v); + 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) { @@ -450,9 +439,8 @@ static void multires_reshape_propagate_prepare( data->reshape_level = reshape_level; data->top_level = top_level; data->num_grids = num_grids; - /* TODO(sergey): use grid_size_for_level_get(). */ - data->reshape_grid_size = (1 << (reshape_level - 1)) + 1; - data->top_grid_size = (1 << (top_level - 1)) + 1; + data->reshape_grid_size = BKE_subdiv_grid_size_from_level(reshape_level); + data->top_grid_size = BKE_subdiv_grid_size_from_level(top_level); data->old_displacement_grids = old_mdisps; data->new_displacement_grids = mdisps; data->grid_paint_mask = @@ -664,17 +652,18 @@ static void multires_reshape_propagate(MultiresPropagateData *data) static void multires_reshape_propagate_free(MultiresPropagateData *data) { - if (data->old_displacement_grids != NULL) { - const int num_grids = data->num_grids; - MDisps *old_mdisps = data->old_displacement_grids; - for (int grid_index = 0; grid_index < num_grids; grid_index++) { - MDisps *old_displacement_grid = &old_mdisps[grid_index]; - if (old_displacement_grid->disps) { - MEM_freeN(old_displacement_grid->disps); - } + if (data->old_displacement_grids == NULL) { + return; + } + const int num_grids = data->num_grids; + MDisps *old_mdisps = data->old_displacement_grids; + for (int grid_index = 0; grid_index < num_grids; grid_index++) { + MDisps *old_displacement_grid = &old_mdisps[grid_index]; + if (old_displacement_grid->disps) { + MEM_freeN(old_displacement_grid->disps); } - MEM_freeN(data->old_displacement_grids); } + MEM_freeN(data->old_displacement_grids); } /* ============================================================================= @@ -819,8 +808,7 @@ static bool multires_reshape_from_vertcos( .coarse_mesh = coarse_mesh, .mdisps = mdisps, .grid_paint_mask = NULL, - /* TODO(sergey): Use grid_size_for_level_get */ - .grid_size = (1 << (top_level - 1)) + 1, + .grid_size = BKE_subdiv_grid_size_from_level(top_level), .level = top_level, }, .deformed_verts = deformed_verts, @@ -993,7 +981,8 @@ static void reshape_from_ccg_regular_face(ReshapeFromCCGTaskData *data, float grid_u, grid_v; const int face_corner = rotate_quad_to_corner( u, v, &corner_u, &corner_v); - ptex_uv_to_grid_uv(corner_u, corner_v, &grid_u, &grid_v); + BKE_subdiv_ptex_face_uv_to_grid_uv( + corner_u, corner_v, &grid_u, &grid_v); /*const*/ CCGElem *grid = grids[coarse_poly->loopstart + face_corner]; /*const*/ CCGElem *grid_element = CCG_grid_elem( @@ -1036,7 +1025,7 @@ static void reshape_from_ccg_special_face(ReshapeFromCCGTaskData *data, for (int x = 0; x < resolution; x++) { const float u = x * resolution_1_inv; float grid_u, grid_v; - ptex_uv_to_grid_uv(u, v, &grid_u, &grid_v); + BKE_subdiv_ptex_face_uv_to_grid_uv(u, v, &grid_u, &grid_v); /*const*/ CCGElem *grid = grids[coarse_poly->loopstart + corner]; /*const*/ CCGElem *grid_element = CCG_grid_elem( @@ -1111,8 +1100,7 @@ bool multiresModifier_reshapeFromCCG( .coarse_mesh = coarse_mesh, .mdisps = mdisps, .grid_paint_mask = grid_paint_mask, - /* TODO(sergey): Use grid_size_for_level_get */ - .grid_size = (1 << (top_level - 1)) + 1, + .grid_size = BKE_subdiv_grid_size_from_level(top_level), .level = top_level}, .face_ptex_offset = BKE_subdiv_face_ptex_offset_get(subdiv), .key = &key, diff --git a/source/blender/blenkernel/intern/subdiv_ccg.c b/source/blender/blenkernel/intern/subdiv_ccg.c index a386b7bb2d3..e488b1129fc 100644 --- a/source/blender/blenkernel/intern/subdiv_ccg.c +++ b/source/blender/blenkernel/intern/subdiv_ccg.c @@ -50,17 +50,6 @@ * Generally useful internal helpers. */ -/* For a given subdivision level (NOT the refinement level) get resolution - * of grid. - */ -static int grid_size_for_level_get(const SubdivCCG *subdiv_ccg, int level) -{ - BLI_assert(level >= 1); - BLI_assert(level <= subdiv_ccg->level); - UNUSED_VARS_NDEBUG(subdiv_ccg); - return (1 << (level - 1)) + 1; -} - /* Number of floats in per-vertex elements. */ static int num_element_float_get(const SubdivCCG *subdiv_ccg) { @@ -139,8 +128,7 @@ static void subdiv_ccg_alloc_elements(SubdivCCG *subdiv_ccg, Subdiv *subdiv) /* Allocate memory for surface grids. */ const int num_faces = topology_refiner->getNumFaces(topology_refiner); const int num_grids = topology_refiner_count_face_corners(topology_refiner); - const int grid_size = grid_size_for_level_get( - subdiv_ccg, subdiv_ccg->level); + const int grid_size = BKE_subdiv_grid_size_from_level(subdiv_ccg->level); const int grid_area = grid_size * grid_size; subdiv_ccg->num_grids = num_grids; subdiv_ccg->grids = @@ -644,8 +632,7 @@ SubdivCCG *BKE_subdiv_to_ccg( SubdivCCG *subdiv_ccg = MEM_callocN(sizeof(SubdivCCG), "subdiv ccg"); subdiv_ccg->subdiv = subdiv; subdiv_ccg->level = bitscan_forward_i(settings->resolution - 1); - subdiv_ccg->grid_size = - grid_size_for_level_get(subdiv_ccg, subdiv_ccg->level); + subdiv_ccg->grid_size = BKE_subdiv_grid_size_from_level(subdiv_ccg->level); subdiv_ccg_init_layers(subdiv_ccg, settings); subdiv_ccg_alloc_elements(subdiv_ccg, subdiv); subdiv_ccg_init_faces(subdiv_ccg); @@ -736,7 +723,7 @@ void BKE_subdiv_ccg_key(CCGKey *key, const SubdivCCG *subdiv_ccg, int level) { key->level = level; key->elem_size = element_size_bytes_get(subdiv_ccg); - key->grid_size = grid_size_for_level_get(subdiv_ccg, level); + key->grid_size = BKE_subdiv_grid_size_from_level(level); key->grid_area = key->grid_size * key->grid_size; key->grid_bytes = key->elem_size * key->grid_area; diff --git a/source/blender/blenkernel/intern/subdiv_ccg_mask.c b/source/blender/blenkernel/intern/subdiv_ccg_mask.c index 27f996a68bb..9cd7ed0a962 100644 --- a/source/blender/blenkernel/intern/subdiv_ccg_mask.c +++ b/source/blender/blenkernel/intern/subdiv_ccg_mask.c @@ -38,6 +38,7 @@ #include "BLI_math_vector.h" #include "BKE_customdata.h" +#include "BKE_subdiv.h" #include "MEM_guardedalloc.h" @@ -59,16 +60,6 @@ typedef struct GridPaintMaskData { PolyCornerIndex *ptex_poly_corner; } GridPaintMaskData; -/* Coordinates within grid has different convention from PTex coordinates. - * This function converts the latter ones to former. - */ -BLI_INLINE void ptex_uv_to_grid_uv(const float ptex_u, const float ptex_v, - float *r_grid_u, float *r_grid_v) -{ - *r_grid_u = 1.0f - ptex_v; - *r_grid_v = 1.0f - ptex_u; -} - /* Simplified version of mdisp_rot_face_to_crn, only handles quad and * works in normalized coordinates. * @@ -119,12 +110,12 @@ static int mask_get_grid_and_coord( corner = rotate_quad_to_corner(u, v, &corner_u, &corner_v); *r_mask_grid = &data->grid_paint_mask[start_grid_index + corner]; - ptex_uv_to_grid_uv(corner_u, corner_v, grid_u, grid_v); + BKE_subdiv_ptex_face_uv_to_grid_uv(corner_u, corner_v, grid_u, grid_v); } else { *r_mask_grid = &data->grid_paint_mask[start_grid_index]; - ptex_uv_to_grid_uv(u, v, grid_u, grid_v); + BKE_subdiv_ptex_face_uv_to_grid_uv(u, v, grid_u, grid_v); } return corner; } @@ -135,7 +126,7 @@ BLI_INLINE float read_mask_grid(const GridPaintMask *mask_grid, if (mask_grid->data == NULL) { return 0; } - const int grid_size = (1 << (mask_grid->level - 1)) + 1; + const int grid_size = BKE_subdiv_grid_size_from_level(mask_grid->level); const int x = (grid_u * (grid_size - 1) + 0.5f); const int y = (grid_v * (grid_size - 1) + 0.5f); return mask_grid->data[y * grid_size + x]; diff --git a/source/blender/blenkernel/intern/subdiv_displacement_multires.c b/source/blender/blenkernel/intern/subdiv_displacement_multires.c index 7d2053129b3..aea02c5f9c9 100644 --- a/source/blender/blenkernel/intern/subdiv_displacement_multires.c +++ b/source/blender/blenkernel/intern/subdiv_displacement_multires.c @@ -69,16 +69,6 @@ typedef enum eAverageWith { AVERAGE_WITH_NEXT, } eAverageWith; -/* Coordinates within grid has different convention from PTex coordinates. - * This function converts the latter ones to former. - */ -BLI_INLINE void ptex_uv_to_grid_uv(const float ptex_u, const float ptex_v, - float *r_grid_u, float *r_grid_v) -{ - *r_grid_u = 1.0f - ptex_v; - *r_grid_v = 1.0f - ptex_u; -} - /* Simplified version of mdisp_rot_face_to_crn, only handles quad and * works in normalized coordinates. * @@ -128,11 +118,11 @@ static int displacement_get_grid_and_coord( float corner_u, corner_v; corner = rotate_quad_to_corner(u, v, &corner_u, &corner_v); *r_displacement_grid = &data->mdisps[start_grid_index + corner]; - ptex_uv_to_grid_uv(corner_u, corner_v, grid_u, grid_v); + BKE_subdiv_ptex_face_uv_to_grid_uv(corner_u, corner_v, grid_u, grid_v); } else { *r_displacement_grid = &data->mdisps[start_grid_index]; - ptex_uv_to_grid_uv(u, v, grid_u, grid_v); + BKE_subdiv_ptex_face_uv_to_grid_uv(u, v, grid_u, grid_v); } return corner; } @@ -401,7 +391,7 @@ static void displacement_init_data(SubdivDisplacement *displacement, const MultiresModifierData *mmd) { MultiresDisplacementData *data = displacement->user_data; - data->grid_size = (1 << (mmd->totlvl - 1)) + 1; + data->grid_size = BKE_subdiv_grid_size_from_level(mmd->totlvl); data->mpoly = mesh->mpoly; data->mdisps = CustomData_get_layer(&mesh->ldata, CD_MDISPS); displacement_data_init_mapping(displacement, mesh); diff --git a/source/blender/blenkernel/intern/subdiv_inline.h b/source/blender/blenkernel/intern/subdiv_inline.h new file mode 100644 index 00000000000..c9e924ced82 --- /dev/null +++ b/source/blender/blenkernel/intern/subdiv_inline.h @@ -0,0 +1,48 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2018 by Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenkernel/intern/subdiv_inline.h + * \ingroup bke + */ + +#ifndef __BKE_SUBDIV_INLINE_H__ +#define __BKE_SUBDIV_INLINE_H__ + +#include "BKE_subdiv.h" + +BLI_INLINE void BKE_subdiv_ptex_face_uv_to_grid_uv( + const float ptex_u, const float ptex_v, + float *r_grid_u, float *r_grid_v) +{ + *r_grid_u = 1.0f - ptex_v; + *r_grid_v = 1.0f - ptex_u; +} + +BLI_INLINE int BKE_subdiv_grid_size_from_level(const int level) +{ + return (1 << (level - 1)) + 1; +} + +#endif /* __BKE_SUBDIV_INLINE_H__ */ -- cgit v1.2.3