[Bf-blender-cvs] [f7ea465] opensubdiv-modifier: OpenSubdiv: Experiments with CPU face-varying interpolation

Sergey Sharybin noreply at git.blender.org
Thu Jul 16 16:15:25 CEST 2015


Commit: f7ea465af280c531babf09a1b567f5dc3eb1bfb7
Author: Sergey Sharybin
Date:   Thu Jul 16 16:09:04 2015 +0200
Branches: opensubdiv-modifier
https://developer.blender.org/rBf7ea465af280c531babf09a1b567f5dc3eb1bfb7

OpenSubdiv: Experiments with CPU face-varying interpolation

It's kind of a failure actually because face-varying interpolation is not
supported yet by limit evalaution API, meaning we can't really do CPU side
UV map evaluation.

This commit lays down some basis of the work for future and finished vertex
varying evalaution which was used here for some quick tests.

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

M	intern/opensubdiv/opensubdiv_capi.h
M	intern/opensubdiv/opensubdiv_evaluator_capi.cc
M	source/blender/blenkernel/intern/CCGSubSurf.h
M	source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
M	source/blender/blenkernel/intern/subsurf_ccg.c

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

diff --git a/intern/opensubdiv/opensubdiv_capi.h b/intern/opensubdiv/opensubdiv_capi.h
index bafeaaf..770bd58 100644
--- a/intern/opensubdiv/opensubdiv_capi.h
+++ b/intern/opensubdiv/opensubdiv_capi.h
@@ -104,7 +104,6 @@ void openSubdiv_setEvaluatorCoarsePositions(OpenSubdiv_EvaluatorDescr *evaluator
                                             int start_vert,
                                             int num_vert);
 
-/* TODO(sergey): Currently optimized for UVs. */
 void openSubdiv_setEvaluatorVaryingData(OpenSubdiv_EvaluatorDescr *evaluator_descr,
                                         float *varying_data,
                                         int start_vert,
@@ -117,6 +116,11 @@ void openSubdiv_evaluateLimit(OpenSubdiv_EvaluatorDescr *evaluator_descr,
                               float dPdu[3],
                               float dPdv[3]);
 
+void openSubdiv_evaluateVarying(OpenSubdiv_EvaluatorDescr *evaluator_descr,
+                               int osd_face_index,
+                               float face_u, float face_v,
+                               float varying[3]);
+
 /* ** Actual drawing ** */
 
 /* Initialize all the invariants which stays the same for every single path,
diff --git a/intern/opensubdiv/opensubdiv_evaluator_capi.cc b/intern/opensubdiv/opensubdiv_evaluator_capi.cc
index a041c96..7efdebf 100644
--- a/intern/opensubdiv/opensubdiv_evaluator_capi.cc
+++ b/intern/opensubdiv/opensubdiv_evaluator_capi.cc
@@ -283,7 +283,8 @@ public:
 		}
 	}
 
-	void EvalPatchesVarying(PatchCoord& patch_coord) {
+	void EvalPatchVarying(PatchCoord& patch_coord,
+	                      float varying[3]) {
 		StackAllocatedBuffer<3, 1> varying_data;
 		BufferDescriptor varying_desc(0, 3, 3);
 		SinglePatchCoordBuffer patch_coord_buffer(patch_coord);
@@ -294,10 +295,12 @@ public:
 			                                         device_context_);
 
 		EVALUATOR::EvalPatches(src_varying_data_, src_varying_desc_,
-		                       varying_data, varying_desc,
+		                       &varying_data, varying_desc,
 		                       patch_coord_buffer.GetNumVertices(),
-		                       patch_coord_buffer,
+		                       &patch_coord_buffer,
 		                       patch_table_, eval_instance, device_context_);
+		float *refined_varying = varying_data.BindCpuBuffer();
+		memcpy(varying, refined_varying, sizeof(float) * 3);
 	}
 private:
 	SRC_VERTEX_BUFFER *src_data_;
@@ -453,6 +456,8 @@ void openSubdiv_setEvaluatorVaryingData(OpenSubdiv_EvaluatorDescr *evaluator_des
 {
 	/* TODO(sergey): Add sanity check on indices. */
 	evaluator_descr->eval_output->UpdateVaryingData(varying_data, start_vert, num_verts);
+	/* TODO(sergey): Get rid of this ASAP. */
+	evaluator_descr->eval_output->Refine();
 }
 
 void openSubdiv_evaluateLimit(OpenSubdiv_EvaluatorDescr *evaluator_descr,
@@ -476,3 +481,15 @@ void openSubdiv_evaluateLimit(OpenSubdiv_EvaluatorDescr *evaluator_descr,
 		evaluator_descr->eval_output->EvalPatchCoord(patch_coord, P);
 	}
 }
+
+void openSubdiv_evaluateVarying(OpenSubdiv_EvaluatorDescr *evaluator_descr,
+                               int osd_face_index,
+                               float face_u, float face_v,
+                               float varying[3])
+{
+	assert((face_u >= 0.0f) && (face_u <= 1.0f) && (face_v >= 0.0f) && (face_v <= 1.0f));
+	const PatchTable::PatchHandle *handle =
+	        evaluator_descr->patch_map->FindPatch(osd_face_index, face_u, face_v);
+	PatchCoord patch_coord(*handle, face_u, face_v);
+	evaluator_descr->eval_output->EvalPatchVarying(patch_coord, varying);
+}
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.h b/source/blender/blenkernel/intern/CCGSubSurf.h
index 6669298..23f7e71 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf.h
@@ -215,13 +215,25 @@ bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss, bool use_osd_glsl);
 void ccgSubSurf_drawGLMesh(CCGSubSurf *ss, bool fill_quads,
                            int start_partition, int num_partitions);
 
+/* Controls whether CCG are needed (Cmeaning CPU evaluation) or fully GPU compute
+ * and draw is allowed.
+ */
 void ccgSubSurf_setSkipGrids(CCGSubSurf *ss, bool skip_grids);
-
 bool ccgSubSurf_needGrids(CCGSubSurf *ss);
 
-void ccgSubSurf_setUVCoordsFromDM(CCGSubSurf *ss,
-                                  struct DerivedMesh *dm,
-                                  bool subdivide_uvs);
+/* Set evaluator's face varying data from UV coordinates.
+ * Used for CPU evaluation.
+ */
+void ccgSubSurf_evaluatorSetFVarUV(CCGSubSurf *ss,
+                                   struct DerivedMesh *dm,
+                                   int layer_index);
+
+/* TODO(sergey): Temporary call to test things. */
+void ccgSubSurf_evaluatorFVarUV(CCGSubSurf *ss,
+                                int face_index, int S,
+                                float grid_u, float grid_v,
+                                float uv[2]);
+
 #endif
 
 #endif  /* __CCGSUBSURF_H__ */
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
index 4026e05..e6227f6 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
@@ -362,72 +362,41 @@ BLI_INLINE void ccgSubSurf__mapEdgeToFace(int S,
 	}
 }
 
-void ccgSubSurf_setUVCoordsFromDM(CCGSubSurf *ss,
-                                  DerivedMesh *dm,
-                                  bool subdivide_uvs)
+void ccgSubSurf_evaluatorSetFVarUV(CCGSubSurf *ss,
+                                   DerivedMesh *dm,
+                                   int layer_index)
 {
-	CustomData *loop_data = &dm->loopData;
-	int /*layer,*/ num_layer = CustomData_number_of_layers(loop_data, CD_MLOOPUV);
-	bool mpoly_allocated;
-	MPoly *mpoly;
-
-	ss->osd_uv_index = CustomData_get_active_layer(&dm->loopData,
-	                                               CD_MLOOPUV);
-
-	if (subdivide_uvs != ss->osd_subsurf_uv) {
-		ss->osd_uvs_invalid = true;
-	}
-
-	if (num_layer == 0 || !ss->osd_uvs_invalid) {
-		return;
-	}
-
-	ss->osd_uvs_invalid = false;
-	ss->osd_subsurf_uv = subdivide_uvs;
-	if (ss->osd_mesh) {
-		ss->osd_mesh_invalid = true;
-	}
-
-	mpoly = DM_get_poly_array(dm, &mpoly_allocated);
-
-	/* TODO(sergey): Need proper port. */
-#if 0
-	openSubdiv_evaluatorFVDataClear(ss->osd_evaluator);
-
-	for (layer = 0; layer < num_layer; ++layer) {
-		openSubdiv_evaluatorFVNamePush(ss->osd_evaluator, "u");
-		openSubdiv_evaluatorFVNamePush(ss->osd_evaluator, "v");
-	}
-
-	{
-		int i;
-		for (i = 0; i < ss->fMap->curSize; ++i) {
-			CCGFace *face = (CCGFace *) ss->fMap->buckets[i];
-			for (; face; face = face->next) {
-				int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(face));
-				MPoly *mp = &mpoly[index];
-				int S;
-				for (S = 0; S < face->numVerts; ++S) {
-					for (layer = 0; layer < num_layer; ++layer) {
-						MLoopUV *mloopuv = CustomData_get_layer_n(loop_data,
-						                                          CD_MLOOPUV,
-						                                          layer);
-
-						MLoopUV *loopuv = &mloopuv[mp->loopstart + S];
-						openSubdiv_evaluatorFVDataPush(ss->osd_evaluator,
-						                               loopuv->uv[0]);
-						openSubdiv_evaluatorFVDataPush(ss->osd_evaluator,
-						                               loopuv->uv[1]);
-					}
-				}
-			}
+	MPoly *mpoly = dm->getPolyArray(dm);
+	MLoopUV *mloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, layer_index);
+	int num_polys = dm->getNumPolys(dm);
+	int index, poly;
+	BLI_assert(ss->osd_evaluator != NULL);
+	for (poly = 0, index = 0; poly < num_polys; poly++) {
+		int loop;
+		MPoly *mp = &mpoly[poly];
+		for (loop = 0; loop < mp->totloop; loop++, index++) {
+			MLoopUV *mluv = &mloopuv[loop + mp->loopstart];
+			(void)mluv;
+			/* TODO(sergey): Send mluv->uv to the evaluator's face varying
+			 * buffer.
+			 */
 		}
 	}
-#endif
+}
 
-	if (mpoly_allocated) {
-		MEM_freeN(mpoly);
-	}
+void ccgSubSurf_evaluatorFVarUV(CCGSubSurf *ss,
+                                int face_index, int S,
+                                float grid_u, float grid_v,
+                                float uv[2])
+{
+	float face_u, face_v;
+	ccgSubSurf__mapGridToFace(S,
+	                          grid_u, grid_v,
+	                          &face_u, &face_v);
+	(void)ss;
+	(void)face_index;
+	/* TODO(sergey): Evaluate face varying coordinate. */
+	zero_v2(uv);
 }
 
 static bool opensubdiv_createEvaluator(CCGSubSurf *ss)
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index fcf5fc4..553c899 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -269,6 +269,7 @@ static int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edg
 	}
 }
 
+#ifndef WITH_OPENSUBDIV
 static void get_face_uv_map_vert(UvVertMap *vmap, struct MPoly *mpoly, struct MLoop *ml, int fi, CCGVertHDL *fverts)
 {
 	UvMapVert *v, *nv;
@@ -410,7 +411,96 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm,
 
 	return 1;
 }
+#endif  /* WITH_OPENSUBDIV */
+
+#ifdef WITH_OPENSUBDIV
+static void set_subsurf_ccg_uv(CCGSubSurf *ss,
+                               DerivedMesh *dm,
+                               DerivedMesh *result,
+                               int layer_index)
+{
+	CCGFace **faceMap;
+	MTFace *tf;
+	MLoopUV *mluv;
+	CCGFaceIterator fi;
+	int index, gridSize, gridFaces, totface, x, y, S;
+	MLoopUV *dmloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, layer_index);
+	/* need to update both CD_MTFACE & CD_MLOOPUV, hrmf, we could get away with
+	 * just tface except applying the modifier then looses subsurf UV */
+	MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, layer_index);
+	MLoopUV *mloopuv = CustomData_get_layer_n(&result->loopData, CD_MLOOPUV, layer_index);
+
+	if (dmloopuv == NULL || (tface == NULL && mloopuv == NULL)) {
+		return;
+	}
+
+	ccgSubSurf_evaluatorSetFVarUV(ss, dm, layer_index);
+
+	/* get some info from CCGSubSurf */
+	totface = ccgSubSurf_getNumFaces(ss);
+

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list