[Bf-blender-cvs] [3fbdcefa174] blender2.8: Subdiv: Initial implementation of CCG

Sergey Sharybin noreply at git.blender.org
Tue Sep 11 16:37:58 CEST 2018


Commit: 3fbdcefa174dd85972b7b63c0955e3a8d42f6943
Author: Sergey Sharybin
Date:   Thu Sep 6 17:06:17 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB3fbdcefa174dd85972b7b63c0955e3a8d42f6943

Subdiv: Initial implementation of CCG

Attempts to substitude CCGDM with an OpenSubdiv based structure
which has less abstraction levels. The missing part in this
substitude is a face pointers which old CCGDM/multires code was
using to stitch faces (averaging boundaries).

Another curial bit missing: "reshaping" of multires CD_MDISPS
to the state of new PBVH grids.

The new code is only available when OpenSubdiv modifier is
enabled (WITH_OPENSUBDIV_MODIFIER=ON) and with debug value of
128. This is so this WIP code is not interfering with current
production machines in the studio.

Reviewers: brecht

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D3685

===================================================================

M	source/blender/blenkernel/BKE_paint.h
M	source/blender/blenkernel/BKE_subdiv.h
M	source/blender/blenkernel/BKE_subdiv_ccg.h
M	source/blender/blenkernel/intern/mesh_runtime.c
M	source/blender/blenkernel/intern/paint.c
M	source/blender/blenkernel/intern/subdiv_ccg.c
M	source/blender/blenkernel/intern/subdiv_stats.c
M	source/blender/editors/sculpt_paint/paint_hide.c
M	source/blender/makesdna/DNA_mesh_types.h
M	source/blender/modifiers/intern/MOD_multires.c
M	source/blender/modifiers/intern/MOD_subsurf.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index c440a634c9f..ade23a2a9ca 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -261,7 +261,7 @@ int BKE_sculpt_mask_layers_ensure(struct Object *ob,
                                   struct MultiresModifierData *mmd);
 void BKE_sculpt_toolsettings_data_ensure(struct Scene *scene);
 
-struct PBVH *BKE_sculpt_object_pbvh_ensure(struct Object *ob, struct Mesh *me_eval_deform);
+struct PBVH *BKE_sculpt_object_pbvh_ensure(struct Depsgraph *depsgraph, struct Object *ob);
 
 enum {
 	SCULPT_MASK_LAYER_CALC_VERT = (1 << 0),
diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h
index 4ebb5d1ac66..09fcce369d4 100644
--- a/source/blender/blenkernel/BKE_subdiv.h
+++ b/source/blender/blenkernel/BKE_subdiv.h
@@ -66,6 +66,8 @@ typedef enum eSubdivStatsValue {
 	SUBDIV_STATS_SUBDIV_TO_MESH_GEOMETRY,
 	SUBDIV_STATS_EVALUATOR_CREATE,
 	SUBDIV_STATS_EVALUATOR_REFINE,
+	SUBDIV_STATS_SUBDIV_TO_CCG,
+	SUBDIV_STATS_SUBDIV_TO_CCG_ELEMENTS,
 
 	NUM_SUBDIV_STATS_VALUES,
 } eSubdivStatsValue;
@@ -86,6 +88,10 @@ typedef struct SubdivStats {
 			double evaluator_creation_time;
 			/* Time spent on evaluator->refine(). */
 			double evaluator_refine_time;
+			/* Total time spent on whole CCG creation. */
+			double subdiv_to_ccg_time;
+			/* Time spent on CCG elements evaluation/initialization. */
+			double subdiv_to_ccg_elements_time;
 		};
 		double values_[NUM_SUBDIV_STATS_VALUES];
 	};
diff --git a/source/blender/blenkernel/BKE_subdiv_ccg.h b/source/blender/blenkernel/BKE_subdiv_ccg.h
index b1acf43ad25..8f8a605d309 100644
--- a/source/blender/blenkernel/BKE_subdiv_ccg.h
+++ b/source/blender/blenkernel/BKE_subdiv_ccg.h
@@ -33,10 +33,12 @@
 #define __BKE_SUBDIV_CCG_H__
 
 #include "BKE_customdata.h"
+#include "BLI_bitmap.h"
 #include "BLI_sys_types.h"
 
 struct CCGElem;
 struct CCGKey;
+struct DMFlagMat;
 struct Mesh;
 struct Subdiv;
 
@@ -67,7 +69,12 @@ typedef struct SubdivCCG {
 	 * corresponding to face-corners of coarse mesh, each grid has
 	 * grid_size^2 elements.
 	 */
+	/* Indexed by a grid index, points to a grid data which is stored in
+	 * grids_storage.
+	 */
 	struct CCGElem **grids;
+	/* Flat array of all grids' data. */
+	unsigned char *grids_storage;
 	int num_grids;
 	/* Loose edges, each array element contains grid_size elements
 	 * corresponding to vertices created by subdividing coarse edges.
@@ -91,6 +98,9 @@ typedef struct SubdivCCG {
 	int normal_offset;
 	int mask_offset;
 
+	struct DMFlagMat *grid_flag_mats;
+	BLI_bitmap **grid_hidden;
+
 	/* TODO(sergey): Consider adding some accessors to a "decoded" geometry,
 	 * to make integration with draw manager and such easy.
 	 */
@@ -106,9 +116,18 @@ struct SubdivCCG *BKE_subdiv_to_ccg(
         const SubdivToCCGSettings *settings,
         const struct Mesh *coarse_mesh);
 
+
 /* Destroy CCG representation of subdivision surface. */
 void BKE_subdiv_ccg_destroy(SubdivCCG *subdiv_ccg);
 
+/* Helper function, creates Mesh structure which is properly setup to use
+ * grids.
+ */
+struct Mesh *BKE_subdiv_to_ccg_mesh(
+        struct Subdiv *subdiv,
+        const SubdivToCCGSettings *settings,
+        const struct Mesh *coarse_mesh);
+
 /* 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);
diff --git a/source/blender/blenkernel/intern/mesh_runtime.c b/source/blender/blenkernel/intern/mesh_runtime.c
index 60699589a77..51dd9a9ea3a 100644
--- a/source/blender/blenkernel/intern/mesh_runtime.c
+++ b/source/blender/blenkernel/intern/mesh_runtime.c
@@ -43,6 +43,7 @@
 #include "BKE_bvhutils.h"
 #include "BKE_mesh.h"
 #include "BKE_mesh_runtime.h"
+#include "BKE_subdiv_ccg.h"
 
 /* -------------------------------------------------------------------- */
 /** \name Mesh Runtime Struct Utils
@@ -196,6 +197,11 @@ void BKE_mesh_runtime_clear_geometry(Mesh *mesh)
 {
 	bvhcache_free(&mesh->runtime.bvh_cache);
 	MEM_SAFE_FREE(mesh->runtime.looptris.array);
+	/* TODO(sergey): Does this really belong here? */
+	if (mesh->runtime.subsurf_ccg != NULL) {
+		BKE_subdiv_ccg_destroy(mesh->runtime.subsurf_ccg);
+		mesh->runtime.subsurf_ccg = NULL;
+	}
 }
 
 /** \} */
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 12cdb4586c1..edea8784715 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -55,6 +55,7 @@
 
 #include "BKE_animsys.h"
 #include "BKE_brush.h"
+#include "BKE_ccg.h"
 #include "BKE_colortools.h"
 #include "BKE_deform.h"
 #include "BKE_main.h"
@@ -72,6 +73,7 @@
 #include "BKE_object.h"
 #include "BKE_paint.h"
 #include "BKE_pbvh.h"
+#include "BKE_subdiv_ccg.h"
 #include "BKE_subsurf.h"
 
 #include "DEG_depsgraph.h"
@@ -910,7 +912,6 @@ void BKE_sculpt_update_mesh_elements(
 	ss->kb = (mmd == NULL) ? BKE_keyblock_from_object(ob) : NULL;
 
 	Mesh *me_eval = mesh_get_eval_final(depsgraph, scene, ob, CD_MASK_BAREMESH);
-	Mesh *me_eval_deform = mesh_get_eval_deform(depsgraph, scene, ob, CD_MASK_BAREMESH);
 
 	/* VWPaint require mesh info for loop lookup, so require sculpt mode here */
 	if (mmd && ob->mode & OB_MODE_SCULPT) {
@@ -931,7 +932,7 @@ void BKE_sculpt_update_mesh_elements(
 		ss->vmask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK);
 	}
 
-	PBVH *pbvh = BKE_sculpt_object_pbvh_ensure(ob, me_eval_deform);
+	PBVH *pbvh = BKE_sculpt_object_pbvh_ensure(depsgraph, ob);
 	BLI_assert(pbvh == ss->pbvh);
 	UNUSED_VARS_NDEBUG(pbvh);
 	MEM_SAFE_FREE(ss->pmap);
@@ -1139,7 +1140,7 @@ static PBVH *build_pbvh_for_dynamic_topology(Object *ob)
 	return pbvh;
 }
 
-static PBVH *build_regular_mesh_pbvh(Object *ob, Mesh *me_eval_deform)
+static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform)
 {
 	Mesh *me = BKE_object_get_original_mesh(ob);
 	const int looptris_num = poly_to_tri_count(me->totpoly, me->totloop);
@@ -1174,7 +1175,24 @@ static PBVH *build_regular_mesh_pbvh(Object *ob, Mesh *me_eval_deform)
 	return pbvh;
 }
 
-PBVH *BKE_sculpt_object_pbvh_ensure(Object *ob, Mesh *me_eval_deform)
+static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg)
+{
+	CCGKey key;
+	BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
+	PBVH *pbvh = BKE_pbvh_new();
+	BKE_pbvh_build_grids(
+	        pbvh,
+	        subdiv_ccg->grids, subdiv_ccg->num_grids,
+	        &key,
+	        NULL,
+	        subdiv_ccg->grid_flag_mats,
+	        subdiv_ccg->grid_hidden);
+	pbvh_show_diffuse_color_set(pbvh, ob->sculpt->show_diffuse_color);
+	pbvh_show_mask_set(pbvh, ob->sculpt->show_mask);
+	return pbvh;
+}
+
+PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
 {
 	if (ob == NULL || ob->sculpt == NULL) {
 		return NULL;
@@ -1189,8 +1207,17 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Object *ob, Mesh *me_eval_deform)
 		/* Sculpting on a BMesh (dynamic-topology) gets a special PBVH. */
 		pbvh = build_pbvh_for_dynamic_topology(ob);
 	}
-	else if (ob->type == OB_MESH) {
-		pbvh = build_regular_mesh_pbvh(ob, me_eval_deform);
+	else {
+		Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
+		Mesh *mesh_eval = object_eval->data;
+		if (mesh_eval->runtime.subsurf_ccg != NULL) {
+			pbvh = build_pbvh_from_ccg(ob, mesh_eval->runtime.subsurf_ccg);
+		}
+		else if (ob->type == OB_MESH) {
+			Mesh *me_eval_deform = mesh_get_eval_deform(
+			        depsgraph, DEG_get_evaluated_scene(depsgraph), ob, CD_MASK_BAREMESH);
+			pbvh = build_pbvh_from_regular_mesh(ob, me_eval_deform);
+		}
 	}
 
 	ob->sculpt->pbvh = pbvh;
diff --git a/source/blender/blenkernel/intern/subdiv_ccg.c b/source/blender/blenkernel/intern/subdiv_ccg.c
index d1769c5324d..33785c09936 100644
--- a/source/blender/blenkernel/intern/subdiv_ccg.c
+++ b/source/blender/blenkernel/intern/subdiv_ccg.c
@@ -34,15 +34,74 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "BLI_math_bits.h"
+#include "BLI_task.h"
+
+#include "BKE_DerivedMesh.h"
 #include "BKE_ccg.h"
+#include "BKE_mesh.h"
 #include "BKE_subdiv.h"
+#include "BKE_subdiv_eval.h"
+
+/* =============================================================================
+ * 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)
+{
+	/* 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 num_floats;
+}
+
+/* Per-vertex element size in bytes. */
+static int element_size_bytes_get(const SubdivCCG *subdiv_ccg)
+{
+	return sizeof(float) * num_element_float_get(subdiv_ccg);
+}
+
+/* =============================================================================
+ * Internal helpers for CCG creation.
+ */
 
 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. */
+	/* 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;
+	}
+	/* Normals.
+	 *
+	 * NOTE: Keep them at the end, matching old CCGDM. Doesn't really matter
+	 * here, but some other area might in theory depend memory layout.
+	 */
 	if (settings->need_normal) {
 		subdiv_ccg->has_normal = true;
 		subdiv_ccg->normal_offset = layer_offset;
@@ -52,65 +111,264 @@ static void subdiv_ccg_init_layers(SubdivCCG *subdiv_ccg,
 		subdiv_ccg->has_normal = false;
 		subdiv_ccg->normal_offset = -1;
 	}
-	/* Mask. */
-	if (settings->need_mask) {
-		subdiv_ccg->has_mask = true;
-	

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list