diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-09-04 17:16:01 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-09-06 12:32:21 +0300 |
commit | 79e8805a9e880cba15d5f19dd4345b7c462c884c (patch) | |
tree | e829c7617ce08650504000671f43bd735d9c8cc4 /source/blender | |
parent | 8a3adaa48568382c1d0e67fabb8ec3d07b94dd42 (diff) |
Subdiv: Some ground work for CCG support
Nothing really interesting, just starting laying down API which
seems to be a decent substitute to CCGDM, without requiring too
much work be done in sculpting area.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_subdiv_ccg.h | 118 | ||||
-rw-r--r-- | source/blender/blenkernel/CMakeLists.txt | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subdiv_ccg.c | 127 |
3 files changed, 247 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_subdiv_ccg.h b/source/blender/blenkernel/BKE_subdiv_ccg.h new file mode 100644 index 00000000000..b1acf43ad25 --- /dev/null +++ b/source/blender/blenkernel/BKE_subdiv_ccg.h @@ -0,0 +1,118 @@ +/* + * ***** 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 BKE_subdiv_ccg.h + * \ingroup bke + * \since July 2018 + * \author Sergey Sharybin + */ + +#ifndef __BKE_SUBDIV_CCG_H__ +#define __BKE_SUBDIV_CCG_H__ + +#include "BKE_customdata.h" +#include "BLI_sys_types.h" + +struct CCGElem; +struct CCGKey; +struct Mesh; +struct Subdiv; + +typedef struct SubdivToCCGSettings { + /* Resolution at which regular ptex (created for quad polygon) are being + * evaluated. This defines how many vertices final mesh will have: every + * regular ptex has resolution^2 vertices. Special (irregular, or ptex + * crated for a corner of non-quad polygon) will have resolution of + * `resolution - 1`. + */ + int resolution; + /* Denotes which extra layers to be added to CCG elements. */ + bool need_normal; + bool need_mask; +} SubdivToCCGSettings; + +/* Representation of subdivision surface which uses CCG grids. */ +typedef struct SubdivCCG { + /* A level at which geometry was subdivided. This is what defines grid + * resolution. It is NOT the topology refinement level. + */ + int level; + /* Resolution of grid. All grids have matching resolution, and resolution + * is same as ptex created for non-quad polygons. + */ + int grid_size; + /* Grids represent limit surface, with displacement applied. Grids are + * corresponding to face-corners of coarse mesh, each grid has + * grid_size^2 elements. + */ + struct CCGElem **grids; + int num_grids; + /* Loose edges, each array element contains grid_size elements + * corresponding to vertices created by subdividing coarse edges. + */ + struct CCGElem **edges; + int num_edges; + /* Loose vertices. Every element corresponds to a loose vertex from a coarse + * mesh, every coarse loose vertex corresponds to a single sundivided + * element. + */ + struct CCGElem *vertices; + int num_vertices; + /* Denotes which layers present in the elements. + * + * Grids always has coordinates, followed by extra layers which are set to + * truth here. + */ + bool has_normal; + bool has_mask; + /* Offsets of corresponding data layers in the elements. */ + int normal_offset; + int mask_offset; + + /* TODO(sergey): Consider adding some accessors to a "decoded" geometry, + * to make integration with draw manager and such easy. + */ + + /* TODO(sergey): Consider adding CD layers here, so we can draw final mesh + * from grids, and have UVs and such work. + */ +} SubdivCCG; + +/* Create real hi-res CCG from subdivision. */ +struct SubdivCCG *BKE_subdiv_to_ccg( + struct Subdiv *subdiv, + const SubdivToCCGSettings *settings, + const struct Mesh *coarse_mesh); + +/* Destroy CCG representation of subdivision surface. */ +void BKE_subdiv_ccg_destroy(SubdivCCG *subdiv_ccg); + +/* Create a key for accessing grid elements at a given level. */ +void BKE_subdiv_ccg_key( + struct CCGKey *key, const SubdivCCG *subdiv_ccg, int level); +void BKE_subdiv_ccg_key_top_level( + struct CCGKey *key, const SubdivCCG *subdiv_ccg); + +#endif /* __BKE_SUBDIV_CCG_H__ */ diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index deb2cb3bac5..85c9a2de4d7 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -194,6 +194,7 @@ set(SRC intern/speaker.c intern/studiolight.c intern/subdiv.c + intern/subdiv_ccg.c intern/subdiv_converter.c intern/subdiv_converter_mesh.c intern/subdiv_displacement.c @@ -325,6 +326,7 @@ set(SRC BKE_speaker.h BKE_studiolight.h BKE_subdiv.h + BKE_subdiv_ccg.h BKE_subdiv_eval.h BKE_subdiv_foreach.h BKE_subdiv_mesh.h diff --git a/source/blender/blenkernel/intern/subdiv_ccg.c b/source/blender/blenkernel/intern/subdiv_ccg.c new file mode 100644 index 00000000000..647869dca7e --- /dev/null +++ b/source/blender/blenkernel/intern/subdiv_ccg.c @@ -0,0 +1,127 @@ +/* + * ***** 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_ccg.c + * \ingroup bke + */ + +#include "BKE_subdiv_ccg.h" + +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" + +#include "MEM_guardedalloc.h" + +#include "BKE_ccg.h" +#include "BKE_subdiv.h" + +static void subdiv_ccg_init_layers(SubdivCCG *subdiv_ccg, + const SubdivToCCGSettings *settings) +{ + /* CCG always contains coordinates. Rest of layers are coming after them. */ + int layer_offset = sizeof(float) * 3; + /* Normals. */ + if (settings->need_normal) { + subdiv_ccg->has_normal = true; + subdiv_ccg->normal_offset = layer_offset; + layer_offset += sizeof(float) * 3; + } + else { + subdiv_ccg->has_normal = false; + subdiv_ccg->normal_offset = -1; + } + /* Mask. */ + if (settings->need_mask) { + subdiv_ccg->has_mask = true; + subdiv_ccg->mask_offset = layer_offset; + layer_offset += sizeof(float); + } + else { + subdiv_ccg->has_mask = false; + subdiv_ccg->mask_offset = -1; + } +} + +static int grid_size_for_level_get(const SubdivCCG *subdiv_ccg, int level) +{ + BLI_assert(level >= 1); + BLI_assert(level <= subdiv_ccg->level); + return (1 << (level - 1)) + 1; +} + +/* Per-vertex element size in bytes. */ +static int element_size_get(const SubdivCCG *subdiv_ccg) +{ + /* We always have 3 floats for coordinate. */ + int num_floats = 3; + if (subdiv_ccg->has_normal) { + num_floats += 3; + } + if (subdiv_ccg->has_mask) { + num_floats += 1; + } + return sizeof(float) * num_floats; +} + +SubdivCCG *BKE_subdiv_to_ccg( + Subdiv *UNUSED(subdiv), + const SubdivToCCGSettings *settings, + const Mesh *UNUSED(coarse_mesh)) +{ + SubdivCCG *subdiv_ccg = MEM_callocN(sizeof(SubdivCCG *), "subdiv ccg"); + subdiv_ccg->level = settings->resolution >> 1; + subdiv_ccg->grid_size = + grid_size_for_level_get(subdiv_ccg, subdiv_ccg->level); + subdiv_ccg_init_layers(subdiv_ccg, settings); + return NULL; +} + +void BKE_subdiv_ccg_destroy(SubdivCCG *subdiv_ccg) +{ + MEM_SAFE_FREE(subdiv_ccg->grids); + MEM_SAFE_FREE(subdiv_ccg->edges); + MEM_SAFE_FREE(subdiv_ccg->vertices); + MEM_freeN(subdiv_ccg); +} + +void BKE_subdiv_ccg_key(CCGKey *key, const SubdivCCG *subdiv_ccg, int level) +{ + key->level = level; + key->elem_size = element_size_get(subdiv_ccg); + key->grid_size = grid_size_for_level_get(subdiv_ccg, level); + key->grid_area = key->grid_size * key->grid_size; + key->grid_bytes = key->elem_size * key->grid_area; + + key->normal_offset = subdiv_ccg->normal_offset; + key->mask_offset = subdiv_ccg->mask_offset; + + key->has_normals = subdiv_ccg->has_normal; + key->has_mask = subdiv_ccg->has_mask; +} + +void BKE_subdiv_ccg_key_top_level(CCGKey *key, const SubdivCCG *subdiv_ccg) +{ + BKE_subdiv_ccg_key(key, subdiv_ccg, subdiv_ccg->level); +} |