[Bf-blender-cvs] [b69cbe7d875] master: Fix T60124: Multires modifier not reading data from external files

Sergey Sharybin noreply at git.blender.org
Fri Jan 4 16:00:23 CET 2019


Commit: b69cbe7d8759e604e34d81a9ddc90d8167751f33
Author: Sergey Sharybin
Date:   Fri Jan 4 15:57:44 2019 +0100
Branches: master
https://developer.blender.org/rBb69cbe7d8759e604e34d81a9ddc90d8167751f33

Fix T60124: Multires modifier not reading data from external files

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

M	source/blender/blenkernel/BKE_subdiv.h
M	source/blender/blenkernel/BKE_subdiv_eval.h
M	source/blender/blenkernel/intern/subdiv_displacement_multires.c
M	source/blender/blenkernel/intern/subdiv_eval.c

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

diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h
index 0a09d3528b4..70572d30819 100644
--- a/source/blender/blenkernel/BKE_subdiv.h
+++ b/source/blender/blenkernel/BKE_subdiv.h
@@ -88,8 +88,7 @@ typedef struct SubdivStats {
 		struct {
 			/* Time spend on creating topology refiner, which includes time
 			 * spend on conversion from Blender data to OpenSubdiv data, and
-			 * time spend on topology orientation on OpenSubdiv C-API side.
-			 */
+			 * time spend on topology orientation on OpenSubdiv C-API side. */
 			double topology_refiner_creation_time;
 			/* Total time spent in BKE_subdiv_to_mesh(). */
 			double subdiv_to_mesh_time;
@@ -108,13 +107,19 @@ typedef struct SubdivStats {
 	};
 
 	/* Per-value timestamp on when corresponding BKE_subdiv_stats_begin() was
-	 * called.
-	 */
+	 * called. */
 	double begin_timestamp_[NUM_SUBDIV_STATS_VALUES];
 } SubdivStats;
 
 /* Functor which evaluates dispalcement at a given (u, v) of given ptex face. */
 typedef struct SubdivDisplacement {
+	/* Initialize displacement evaluator.
+	 *
+	 * Is called right before evaluation is actually needed. This allows to do
+	 * some lazy initialization, like allocate evaluator from a main thread but
+	 * then do actual evaluation from background job. */
+	void (*initialize)(struct SubdivDisplacement *displacement);
+
 	/* Return displacement which is to be added to the original coordinate.
 	 *
 	 * NOTE: This function is supposed to return "continuous" displacement for
@@ -124,8 +129,7 @@ typedef struct SubdivDisplacement {
 	 * displacement grids if needed.
 	 *
 	 * Averaging of displacement for vertices created for over coarse vertices
-	 * and edges is done by subdiv code.
-	 */
+	 * and edges is done by subdiv code. */
 	void (*eval_displacement)(struct SubdivDisplacement *displacement,
 	                          const int ptex_face_index,
 	                          const float u, const float v,
@@ -142,8 +146,7 @@ typedef struct SubdivDisplacement {
  * It does not specify storage, memory layout or anything else.
  * It is possible to create different storages (like, grid based CPU side
  * buffers, GPU subdivision mesh, CPU side fully qualified mesh) from the same
- * Subdiv structure.
- */
+ * Subdiv structure. */
 typedef struct Subdiv {
 	/* Settings this subdivision surface is created for.
 	 *
@@ -152,8 +155,7 @@ typedef struct Subdiv {
 	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
-	 * drawer.
-	 */
+	 * drawer. */
 	struct OpenSubdiv_TopologyRefiner *topology_refiner;
 	/* CPU side evaluator. */
 	struct OpenSubdiv_Evaluator *evaluator;
@@ -200,7 +202,7 @@ void BKE_subdiv_free(Subdiv *subdiv);
 
 void BKE_subdiv_displacement_attach_from_multires(
         Subdiv *subdiv,
-        const struct Mesh *mesh,
+        struct Mesh *mesh,
         const struct MultiresModifierData *mmd);
 
 void BKE_subdiv_displacement_detach(Subdiv *subdiv);
@@ -212,8 +214,7 @@ 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.
- */
+ * (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);
@@ -226,8 +227,7 @@ BLI_INLINE int BKE_subdiv_grid_size_from_level(const int level);
 /* Simplified version of mdisp_rot_face_to_crn, only handles quad and
  * works in normalized coordinates.
  *
- * NOTE: Output coordinates are in ptex coordinates.
- */
+ * NOTE: Output coordinates are in ptex coordinates. */
 BLI_INLINE int BKE_subdiv_rotate_quad_to_corner(
         const float u, const float v,
         float *r_u, float *r_v);
diff --git a/source/blender/blenkernel/BKE_subdiv_eval.h b/source/blender/blenkernel/BKE_subdiv_eval.h
index 0ea5c978e62..b743c759ace 100644
--- a/source/blender/blenkernel/BKE_subdiv_eval.h
+++ b/source/blender/blenkernel/BKE_subdiv_eval.h
@@ -42,6 +42,12 @@ bool BKE_subdiv_eval_begin(struct Subdiv *subdiv);
 bool BKE_subdiv_eval_update_from_mesh(struct Subdiv *subdiv,
                                       const struct Mesh *mesh);
 
+/* Makes sure displacement evaluator is initialized.
+ *
+ * NOTE: This function must be called once before evaluating displacement or
+ * final surface position. */
+void BKE_subdiv_eval_init_displacement(struct Subdiv *subdiv);
+
 /* Single point queries. */
 
 void BKE_subdiv_eval_limit_point(
@@ -77,8 +83,7 @@ void BKE_subdiv_eval_face_varying(
  * TODO(sergey): This is currently used together with
  * BKE_subdiv_eval_final_point() which cas easily evaluate derivatives.
  * Would be nice to have dispalcement evaluation function which does not require
- * knowing derivatives ahead of a time.
- */
+ * knowing derivatives ahead of a time. */
 void BKE_subdiv_eval_displacement(
         struct Subdiv *subdiv,
         const int ptex_face_index,
@@ -96,8 +101,7 @@ void BKE_subdiv_eval_final_point(
  *
  * Will evaluate patch at uniformly distributed (u, v) coordinates on a grid
  * of given resolution, producing resolution^2 evaluation points. The order
- * goes as u in rows, v in columns.
- */
+ * goes as u in rows, v in columns. */
 
 void BKE_subdiv_eval_limit_patch_resolution_point(
         struct Subdiv *subdiv,
diff --git a/source/blender/blenkernel/intern/subdiv_displacement_multires.c b/source/blender/blenkernel/intern/subdiv_displacement_multires.c
index 5744ac3ca0d..d6865e1826f 100644
--- a/source/blender/blenkernel/intern/subdiv_displacement_multires.c
+++ b/source/blender/blenkernel/intern/subdiv_displacement_multires.c
@@ -49,20 +49,23 @@ typedef struct PolyCornerIndex {
 
 typedef struct MultiresDisplacementData {
 	int grid_size;
+	/* Mesh is used to read external displacement. */
+	Mesh *mesh;
 	const MPoly *mpoly;
 	const MDisps *mdisps;
 	/* Indexed by ptex face index, contains polygon/corner which corresponds
 	 * to it.
 	 *
 	 * NOTE: For quad polygon this is an index of first corner only, since
-	 * there we only have one ptex.
-	 */
+	 * there we only have one ptex. */
 	PolyCornerIndex *ptex_poly_corner;
+	/* Sanity check, is used in debug builds.
+	 * Controls that initialize() was called prior to eval_displacement(). */
+	bool is_initialized;
 } MultiresDisplacementData;
 
 /* Denotes which grid to use to average value of the displacement read from the
- * grid which corresponds to the ptex face.
- */
+ * grid which corresponds to the ptex face. */
 typedef enum eAverageWith {
 	AVERAGE_WITH_NONE,
 	AVERAGE_WITH_ALL,
@@ -238,6 +241,16 @@ static void average_displacement(SubdivDisplacement *displacement,
 	}
 }
 
+static void initialize(SubdivDisplacement *displacement)
+{
+	MultiresDisplacementData *data = displacement->user_data;
+	Mesh *mesh = data->mesh;
+	/* Make sure external displacement is read. */
+	CustomData_external_read(
+	    &mesh->ldata, &mesh->id, CD_MASK_MDISPS, mesh->totloop);
+	data->is_initialized = true;
+}
+
 static void eval_displacement(SubdivDisplacement *displacement,
                               const int ptex_face_index,
                               const float u, const float v,
@@ -245,6 +258,7 @@ static void eval_displacement(SubdivDisplacement *displacement,
                               float r_D[3])
 {
 	MultiresDisplacementData *data = displacement->user_data;
+	BLI_assert(data->is_initialized);
 	const int grid_size = data->grid_size;
 	/* Get displacement in tangent space. */
 	const MDisps *displacement_grid;
@@ -254,8 +268,7 @@ static void eval_displacement(SubdivDisplacement *displacement,
 	                                             &displacement_grid,
 	                                             &grid_u, &grid_v);
 	/* Read displacement from the current displacement grid and see if any
-	 * averaging is needed.
-	 */
+	 * averaging is needed. */
 	float tangent_D[3];
 	eAverageWith average_with =
 	        read_displacement_grid(displacement_grid, grid_size,
@@ -279,8 +292,7 @@ static void free_displacement(SubdivDisplacement *displacement)
 }
 
 /* TODO(sergey): This seems to be generally used information, which almost
- * worth adding to a subdiv itself, with possible cache of the value.
- */
+ * worth adding to a subdiv itself, with possible cache of the value. */
 static int count_num_ptex_faces(const Mesh *mesh)
 {
 	int num_ptex_faces = 0;
@@ -323,25 +335,28 @@ static void displacement_data_init_mapping(SubdivDisplacement *displacement,
 }
 
 static void displacement_init_data(SubdivDisplacement *displacement,
-                                   const Mesh *mesh,
+                                   Mesh *mesh,
                                    const MultiresModifierData *mmd)
 {
 	MultiresDisplacementData *data = displacement->user_data;
 	data->grid_size = BKE_subdiv_grid_size_from_level(mmd->totlvl);
+	data->mesh = mesh;
 	data->mpoly = mesh->mpoly;
 	data->mdisps = CustomData_get_layer(&mesh->ldata, CD_MDISPS);
+	data->is_initialized = false;
 	displacement_data_init_mapping(displacement, mesh);
 }
 
 static void displacement_init_functions(SubdivDisplacement *displacement)
 {
+	displacement->initialize = initialize;
 	displacement->eval_displacement = eval_displacement;
 	displacement->free = free_displacement;
 }
 
 void BKE_subdiv_displacement_attach_from_multires(
         Subdiv *subdiv,
-        const Mesh *mesh,
+        Mesh *mesh,
         const MultiresModifierData *mmd)
 {
 	/* Make sure we don't have previously assigned displacement. */
diff --git a/source/blender/blenkernel/intern/subdiv_eval.c b/source/blender/blenkernel/intern/subdiv_eval.c
index f4a9e1a95fd..7043edc7fc9 100644
--- a/source/blender/blenkernel/intern/subdiv_eval.c
+++ b/source/blender/blenkernel/intern/subdiv_eval.c
@@ -64,6 +64,7 @@ bool BKE_subdiv_eval_begin(Subdiv *subdiv)
 	else {
 		/* TODO(sergey): Check for topology change. */
 	}
+	BKE_subdiv_eval_init_displacement(subdiv);
 	return true;
 }
 
@@ -159,6 +160,17 @@ bool BKE_subdiv_eval_update_from_mesh(Subdiv *sub

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list