[Bf-blender-cvs] [3b132778dea] master: Multires: Support smooth shading when sculpting

Sergey Sharybin noreply at git.blender.org
Fri Feb 22 17:07:10 CET 2019


Commit: 3b132778deaac733baa78653685471e344b6b7c8
Author: Sergey Sharybin
Date:   Fri Feb 22 16:56:54 2019 +0100
Branches: master
https://developer.blender.org/rB3b132778deaac733baa78653685471e344b6b7c8

Multires: Support smooth shading when sculpting

On CCG side it is done similar to displacement, where we have
a dedicated functor which evaluates displacement. Might be seemed
as an overkill, but allows to decouple SubdivCCG from mesh entirely,
and maybe even free up coarse mesh in order to save some memory.

Some weak-looking aspect is the call to update normals from the
draw manager. Ideally, the manager will only draw what is already
evaluated. But it's a bit tricky to find a best place for this since
we avoid dependency graph updates during sculpt as much as possible.
The new code mimics the old code, this is how it was in 2.7.

Fix shading part of T58307.

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

M	source/blender/blenkernel/BKE_subdiv.h
M	source/blender/blenkernel/BKE_subdiv_ccg.h
M	source/blender/blenkernel/CMakeLists.txt
M	source/blender/blenkernel/intern/subdiv_ccg.c
M	source/blender/blenkernel/intern/subdiv_ccg_mask.c
A	source/blender/blenkernel/intern/subdiv_ccg_material.c
M	source/blender/draw/modes/sculpt_mode.c

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

diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h
index 4fddb3d5188..1ade8a0e44d 100644
--- a/source/blender/blenkernel/BKE_subdiv.h
+++ b/source/blender/blenkernel/BKE_subdiv.h
@@ -145,8 +145,7 @@ typedef struct SubdivDisplacement {
 typedef struct Subdiv {
 	/* Settings this subdivision surface is created for.
 	 *
-	 * It is read-only after assignment in BKE_subdiv_new_from_FOO().
-	 */
+	 * It is read-only after assignment in BKE_subdiv_new_from_FOO(). */
 	SubdivSettings settings;
 	/* Topology refiner includes all the glue logic to feed Blender side
 	 * topology to OpenSubdiv. It can be shared by both evaluator and GL mesh
@@ -162,7 +161,7 @@ typedef struct Subdiv {
 	/* Cached values, are not supposed to be accessed directly. */
 	struct {
 		/* Indexed by base face index, element indicates total number of ptex
-		 *faces created for preceding base faces. */
+		 * faces created for preceding base faces. */
 		int *face_ptex_offset;
 	} cache_;
 } Subdiv;
diff --git a/source/blender/blenkernel/BKE_subdiv_ccg.h b/source/blender/blenkernel/BKE_subdiv_ccg.h
index 804a5d0b500..822f4906bae 100644
--- a/source/blender/blenkernel/BKE_subdiv_ccg.h
+++ b/source/blender/blenkernel/BKE_subdiv_ccg.h
@@ -25,6 +25,7 @@
 #define __BKE_SUBDIV_CCG_H__
 
 #include "BKE_customdata.h"
+#include "BKE_DerivedMesh.h"
 #include "BLI_bitmap.h"
 #include "BLI_sys_types.h"
 
@@ -40,20 +41,41 @@ struct Subdiv;
  */
 
 /* Functor which evaluates mask value at a given (u, v) of given ptex face. */
-typedef struct SubdivCCGMask {
-	float (*eval_mask)(struct SubdivCCGMask *mask,
+typedef struct SubdivCCGMaskEvaluator {
+	float (*eval_mask)(struct SubdivCCGMaskEvaluator *mask_evaluator,
 	                   const int ptex_face_index,
 	                   const float u, const float v);
 
 	/* Free the data, not the evaluator itself. */
-	void (*free)(struct SubdivCCGMask *mask);
+	void (*free)(struct SubdivCCGMaskEvaluator *mask_evaluator);
 
 	void *user_data;
-} SubdivCCGMask;
+} SubdivCCGMaskEvaluator;
 
 /* Return true if mesh has mask and evaluator can be used. */
 bool BKE_subdiv_ccg_mask_init_from_paint(
-        SubdivCCGMask *mask_evaluator,
+        SubdivCCGMaskEvaluator *mask_evaluator,
+        const struct Mesh *mesh);
+
+/* =============================================================================
+ * Materials.
+ */
+
+/* Functor which evaluates material and flags of a given coarse face. */
+typedef struct SubdivCCGMaterialFlagsEvaluator {
+	DMFlagMat (*eval_material_flags)(
+	        struct SubdivCCGMaterialFlagsEvaluator *material_flags_evaluator,
+	        const int coarse_face_index);
+
+	/* Free the data, not the evaluator itself. */
+	void (*free)(
+	        struct SubdivCCGMaterialFlagsEvaluator *material_flags_evaluator);
+
+	void *user_data;
+} SubdivCCGMaterialFlagsEvaluator;
+
+void BKE_subdiv_ccg_material_flags_init_from_mesh(
+        SubdivCCGMaterialFlagsEvaluator *material_flags_evaluator,
         const struct Mesh *mesh);
 
 /* =============================================================================
@@ -196,7 +218,8 @@ typedef struct SubdivCCG {
 struct SubdivCCG *BKE_subdiv_to_ccg(
         struct Subdiv *subdiv,
         const SubdivToCCGSettings *settings,
-        SubdivCCGMask *mask_evaluator);
+        SubdivCCGMaskEvaluator *mask_evaluator,
+        SubdivCCGMaterialFlagsEvaluator *material_flags_evaluator);
 
 /* Destroy CCG representation of subdivision surface. */
 void BKE_subdiv_ccg_destroy(SubdivCCG *subdiv_ccg);
@@ -218,6 +241,11 @@ void BKE_subdiv_ccg_key_top_level(
 /* Recalculate all normals based on grid element coordinates. */
 void BKE_subdiv_ccg_recalc_normals(SubdivCCG *subdiv_ccg);
 
+/* Update normals of affected faces. */
+void BKE_subdiv_ccg_update_normals(SubdivCCG *subdiv_ccg,
+                                   struct CCGFace **effected_faces,
+                                   int num_effected_faces);
+
 /* Average grid coordinates and normals along the grid boundatries. */
 void BKE_subdiv_ccg_average_grids(SubdivCCG *subdiv_ccg);
 
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index b30acbcae24..e3afbc507bf 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -194,6 +194,7 @@ set(SRC
 	intern/subdiv.c
 	intern/subdiv_ccg.c
 	intern/subdiv_ccg_mask.c
+	intern/subdiv_ccg_material.c
 	intern/subdiv_converter.c
 	intern/subdiv_converter_mesh.c
 	intern/subdiv_displacement.c
diff --git a/source/blender/blenkernel/intern/subdiv_ccg.c b/source/blender/blenkernel/intern/subdiv_ccg.c
index bfcd4b8d52d..c35b38b4184 100644
--- a/source/blender/blenkernel/intern/subdiv_ccg.c
+++ b/source/blender/blenkernel/intern/subdiv_ccg.c
@@ -40,6 +40,19 @@
 
 #include "opensubdiv_topology_refiner_capi.h"
 
+/* =============================================================================
+ * Various forward declarations.
+ */
+
+static void subdiv_ccg_average_all_boundaries_and_corners(
+        SubdivCCG *subdiv_ccg,
+        CCGKey *key);
+
+static void subdiv_ccg_average_inner_face_grids(
+        SubdivCCG *subdiv_ccg,
+        CCGKey *key,
+        SubdivCCGFace *face);
+
 /* =============================================================================
  * Generally useful internal helpers.
  */
@@ -163,7 +176,8 @@ typedef struct CCGEvalGridsData {
 	SubdivCCG *subdiv_ccg;
 	Subdiv *subdiv;
 	int *face_ptex_offset;
-	SubdivCCGMask *mask_evaluator;
+	SubdivCCGMaskEvaluator *mask_evaluator;
+	SubdivCCGMaterialFlagsEvaluator *material_flags_evaluator;
 } CCGEvalGridsData;
 
 static void subdiv_ccg_eval_grid_element(
@@ -232,6 +246,10 @@ static void subdiv_ccg_eval_regular_grid(CCGEvalGridsData *data,
 		}
 		/* Assign grid's face. */
 		grid_faces[grid_index] = &faces[face_index];
+		/* Assign material flags. */
+		subdiv_ccg->grid_flag_mats[grid_index] =
+		        data->material_flags_evaluator->eval_material_flags(
+		                data->material_flags_evaluator, face_index);
 	}
 }
 
@@ -247,13 +265,13 @@ static void subdiv_ccg_eval_special_grid(CCGEvalGridsData *data,
 	const SubdivCCGFace *face = &faces[face_index];
 	for (int corner = 0; corner < face->num_grids; corner++) {
 		const int grid_index = face->start_grid_index + corner;
+		const int ptex_face_index =
+		        data->face_ptex_offset[face_index] + corner;
 		unsigned char *grid = (unsigned char *)subdiv_ccg->grids[grid_index];
 		for (int y = 0; y < grid_size; y++) {
 			const float u = 1.0f - ((float)y * grid_size_1_inv);
 			for (int x = 0; x < grid_size; x++) {
 				const float v = 1.0f - ((float)x * grid_size_1_inv);
-				const int ptex_face_index =
-				        data->face_ptex_offset[face_index] + corner;
 				const size_t grid_element_index = (size_t)y * grid_size + x;
 				const size_t grid_element_offset =
 				        grid_element_index * element_size;
@@ -265,6 +283,10 @@ static void subdiv_ccg_eval_special_grid(CCGEvalGridsData *data,
 		}
 		/* Assign grid's face. */
 		grid_faces[grid_index] = &faces[face_index];
+		/* Assign material flags. */
+		subdiv_ccg->grid_flag_mats[grid_index] =
+		        data->material_flags_evaluator->eval_material_flags(
+		                data->material_flags_evaluator, face_index);
 	}
 }
 
@@ -287,7 +309,8 @@ static void subdiv_ccg_eval_grids_task(
 static bool subdiv_ccg_evaluate_grids(
         SubdivCCG *subdiv_ccg,
         Subdiv *subdiv,
-        SubdivCCGMask *mask_evaluator)
+        SubdivCCGMaskEvaluator *mask_evaluator,
+        SubdivCCGMaterialFlagsEvaluator *material_flags_evaluator)
 {
 	OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
 	const int num_faces = topology_refiner->getNumFaces(topology_refiner);
@@ -297,6 +320,7 @@ static bool subdiv_ccg_evaluate_grids(
 	data.subdiv = subdiv;
 	data.face_ptex_offset = BKE_subdiv_face_ptex_offset_get(subdiv);
 	data.mask_evaluator = mask_evaluator;
+	data.material_flags_evaluator = material_flags_evaluator;
 	/* Threaded grids evaluation. */
 	ParallelRangeSettings parallel_range_settings;
 	BLI_parallel_range_settings_defaults(&parallel_range_settings);
@@ -591,7 +615,8 @@ static void subdiv_ccg_init_faces_neighborhood(SubdivCCG *subdiv_ccg)
 SubdivCCG *BKE_subdiv_to_ccg(
         Subdiv *subdiv,
         const SubdivToCCGSettings *settings,
-        SubdivCCGMask *mask_evaluator)
+        SubdivCCGMaskEvaluator *mask_evaluator,
+        SubdivCCGMaterialFlagsEvaluator *material_flags_evaluator)
 {
 	BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_CCG);
 	SubdivCCG *subdiv_ccg = MEM_callocN(sizeof(SubdivCCG), "subdiv ccg");
@@ -602,7 +627,8 @@ SubdivCCG *BKE_subdiv_to_ccg(
 	subdiv_ccg_alloc_elements(subdiv_ccg, subdiv);
 	subdiv_ccg_init_faces(subdiv_ccg);
 	subdiv_ccg_init_faces_neighborhood(subdiv_ccg);
-	if (!subdiv_ccg_evaluate_grids(subdiv_ccg, subdiv, mask_evaluator)) {
+	if (!subdiv_ccg_evaluate_grids(
+	        subdiv_ccg, subdiv, mask_evaluator, material_flags_evaluator)) {
 		BKE_subdiv_ccg_destroy(subdiv_ccg);
 		BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_CCG);
 		return NULL;
@@ -624,11 +650,17 @@ Mesh *BKE_subdiv_to_ccg_mesh(
 		}
 	}
 	BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_CCG);
-	SubdivCCGMask mask_evaluator;
+	SubdivCCGMaskEvaluator mask_evaluator;
 	bool has_mask = BKE_subdiv_ccg_mask_init_from_paint(
-        &mask_evaluator, coarse_mesh);
+	        &mask_evaluator, coarse_mesh);
+	SubdivCCGMaterialFlagsEvaluator material_flags_evaluator;
+	BKE_subdiv_ccg_material_flags_init_from_mesh(
+	        &material_flags_evaluator, coarse_mesh);
 	SubdivCCG *subdiv_ccg = BKE_subdiv_to_ccg(
-	    subdiv, settings, has_mask ? &mask_evaluator : NULL);
+	        subdiv,
+	        settings,
+	        has_mask ? &mask_evaluator : NULL,
+	        &material_flags_evaluator);
 	if (has_mask) {
 		mask_evaluator.free(&mask_evaluator);
 	}
@@ -723,12 +755,11 @@ typedef struct RecalcInnerNormalsTLSData {
  *
  * The result is stored in normals storage from TLS. */
 static void subdiv_ccg_recalc_inner_face_normals(
-        RecalcInnerNormalsData *data,
+        SubdivCCG *subdiv_ccg,
+        CCGKey *key,
         RecalcInnerNo

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list