Subdiv: Cleanup, deduplicate some code
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
MEM_freeN(data->old_displacement_grids);
|
||||
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);
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
|
||||
48
source/blender/blenkernel/intern/subdiv_inline.h
Normal file
48
source/blender/blenkernel/intern/subdiv_inline.h
Normal file
@@ -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__ */
|
||||
Reference in New Issue
Block a user