Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2018-09-04 17:16:01 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2018-09-06 12:32:21 +0300
commit79e8805a9e880cba15d5f19dd4345b7c462c884c (patch)
treee829c7617ce08650504000671f43bd735d9c8cc4
parent8a3adaa48568382c1d0e67fabb8ec3d07b94dd42 (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.
-rw-r--r--source/blender/blenkernel/BKE_subdiv_ccg.h118
-rw-r--r--source/blender/blenkernel/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/intern/subdiv_ccg.c127
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);
+}