[Bf-blender-cvs] [a355110] opensubdiv-modifier: OpenSubdiv: Continue working on skipping CCG creation

Sergey Sharybin noreply at git.blender.org
Thu Jul 16 12:56:09 CEST 2015


Commit: a35511069408d53651d39a64ee1ca5b0d583aa7a
Author: Sergey Sharybin
Date:   Wed Jul 15 20:21:23 2015 +0200
Branches: opensubdiv-modifier
https://developer.blender.org/rBa35511069408d53651d39a64ee1ca5b0d583aa7a

OpenSubdiv: Continue working on skipping CCG creation

Synchronize topology refiner directly from derived mesh and skip CCG geometry
creation in that case.

Gets rid of annoying derived mesh pointer in the CCGSubSurf structure, but needs
to add some information for coarse vertices positions.

Drawing code is totally removed now, no partitioning or material setting happens,
this code needs to be adopted to the case of missing CCG geometry. Maybe this
will require having some extra arrays in the CCGSubSurf structure, but generally
memory usage will still be much less than the previous integration.

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

M	source/blender/blenkernel/intern/CCGSubSurf.c
M	source/blender/blenkernel/intern/CCGSubSurf.h
M	source/blender/blenkernel/intern/CCGSubSurf_intern.h
M	source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
M	source/blender/blenkernel/intern/subsurf_ccg.c

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

diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c
index 2725b66..9f09212 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -306,7 +306,7 @@ CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc, int subdivLevels, CCGAllocatorIFC *a
 #ifdef WITH_OPENSUBDIV
 		ss->osd_evaluator = NULL;
 		ss->osd_mesh = NULL;
-		ss->osd_topology_changed = false;
+		ss->osd_topology_refiner = NULL;
 		ss->osd_mesh_invalid = false;
 		ss->osd_coords_invalid = false;
 		ss->osd_vao = 0;
@@ -316,7 +316,8 @@ CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc, int subdivLevels, CCGAllocatorIFC *a
 		ss->osd_subsurf_uv = 0;
 		ss->osd_uv_index = -1;
 		ss->osd_next_face_index = 0;
-		ss->dm = NULL;
+		ss->osd_coarse_positions = NULL;
+		ss->osd_num_coarse_positions = 0;
 #endif
 
 		return ss;
@@ -338,10 +339,11 @@ void ccgSubSurf_free(CCGSubSurf *ss)
 	if (ss->osd_vao != 0) {
 		glDeleteVertexArrays(1, &ss->osd_vao);
 	}
-	if (ss->dm != NULL) {
-		ss->dm->needsFree = 1;
-		ss->dm->release(ss->dm);
+	if (ss->osd_coarse_positions != NULL) {
+		MEM_freeN(ss->osd_coarse_positions);
 	}
+	/* TODO(sergey): This is not valid when viewport is not visible. */
+	BLI_assert(ss->osd_topology_refiner == NULL);
 #endif
 
 	if (ss->syncState) {
@@ -402,7 +404,9 @@ CCGError ccgSubSurf_setSubdivisionLevels(CCGSubSurf *ss, int subdivisionLevels)
 		return eCCGError_InvalidValue;
 	}
 	else if (subdivisionLevels != ss->subdivLevels) {
-		ss->osd_topology_changed = true;
+#ifdef WITH_OPENSUBDIV
+		ss->osd_mesh_invalid = true;
+#endif
 		ss->numGrids = 0;
 		ss->subdivLevels = subdivisionLevels;
 		ccg_ehash_free(ss->vMap, (EHEntryFreeFP) _vert_free, ss);
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.h b/source/blender/blenkernel/intern/CCGSubSurf.h
index 0fa9215..59f8a56 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf.h
@@ -195,14 +195,14 @@ void				ccgFaceIterator_next		(CCGFaceIterator *fi);
  * of the prepare routine.
  */
 struct DerivedMesh;
-void ccgSubSurf_setDerivedMesh(CCGSubSurf *ss, struct DerivedMesh *dm);
+void ccgSubSurf_prepareTopologyRefiner(CCGSubSurf *ss,
+                                       struct DerivedMesh *dm);
 bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss, bool use_osd_glsl);
 void ccgSubSurf_drawGLMesh(CCGSubSurf *ss, bool fill_quads,
                            int start_partition, int num_partitions);
 void ccgSubSurf_setSkipGrids(CCGSubSurf *ss, bool skip_grids);
 bool ccgSubSurf_needGrids(CCGSubSurf *ss);
 
-struct DerivedMesh;
 void ccgSubSurf_setUVCoordsFromDM(CCGSubSurf *ss,
                                   struct DerivedMesh *dm,
                                   bool subdivide_uvs);
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_intern.h b/source/blender/blenkernel/intern/CCGSubSurf_intern.h
index 1e5965c..874e50b 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf_intern.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf_intern.h
@@ -207,7 +207,7 @@ struct CCGSubSurf {
 #ifdef WITH_OPENSUBDIV
 	struct OpenSubdiv_EvaluatorDescr *osd_evaluator;
 	struct OpenSubdiv_GLMesh *osd_mesh;
-	bool osd_topology_changed;
+	struct OpenSubdiv_TopologyRefinerDescr *osd_topology_refiner;  /* Only used at synchronization stage. */
 	bool osd_mesh_invalid, osd_coords_invalid;
 	unsigned int osd_vao;
 	bool skip_grids;
@@ -218,7 +218,8 @@ struct CCGSubSurf {
 	int osd_uv_index;
 	int osd_next_face_index;
 
-	struct DerivedMesh *dm;
+	float (*osd_coarse_positions)[3];
+	int osd_num_coarse_positions;
 #endif
 };
 
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
index 312351c..2420bf8 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
@@ -44,6 +44,7 @@
 
 #define OSD_LOG if (false) printf
 
+#if 0
 static bool ccgSubSurf_checkDMTopologyChanged(DerivedMesh *dm, DerivedMesh *dm2)
 {
 	const int num_verts = dm->getNumVerts(dm);
@@ -76,54 +77,15 @@ static bool ccgSubSurf_checkDMTopologyChanged(DerivedMesh *dm, DerivedMesh *dm2)
 	/* TODO(sergey): Check whether crease changed. */
 	return false;
 }
-
-void ccgSubSurf_setDerivedMesh(CCGSubSurf *ss, DerivedMesh *dm)
-{
-	if (ss->dm != NULL) {
-		if (ccgSubSurf_checkDMTopologyChanged(ss->dm, dm)) {
-			ss->osd_topology_changed = true;
-		}
-		ss->dm->needsFree = 1;
-		ss->dm->release(ss->dm);
-	}
-	ss->dm = dm;
-}
+#endif
 
 static void ccgSubSurf__updateGLMeshCoords(CCGSubSurf *ss)
 {
-	/* TODO(sergey): This is rather a duplicated work to gather all
-	 * the basis coordinates in an array. It also needed to update
-	 * evaluator and we somehow should optimize this to positions
-	 * are not being packed into an array at draw time.
-	 */
-	float (*positions)[3];
-	int vertDataSize = ss->meshIFC.vertDataSize;
-	int normalDataOffset = ss->normalDataOffset;
-	int num_basis_verts = ss->vMap->numEntries;
-	int i;
-
 	BLI_assert(ss->meshIFC.numLayers == 3);
-
-	positions = MEM_callocN(2 * sizeof(*positions) * num_basis_verts,
-	                        "OpenSubdiv coarse points");
-#pragma omp parallel for
-	for (i = 0; i < ss->vMap->curSize; i++) {
-		CCGVert *v = (CCGVert *) ss->vMap->buckets[i];
-		for (; v; v = v->next) {
-			float *co = VERT_getCo(v, 0);
-			float *no = VERT_getNo(v, 0);
-			BLI_assert(v->osd_index < ss->vMap->numEntries);
-			VertDataCopy(positions[v->osd_index * 2], co, ss);
-			VertDataCopy(positions[v->osd_index * 2 + 1], no, ss);
-		}
-	}
-
 	openSubdiv_osdGLMeshUpdateVertexBuffer(ss->osd_mesh,
-	                                       (float *) positions,
+	                                       (float *) ss->osd_coarse_positions,
 	                                       0,
-	                                       num_basis_verts);
-
-	MEM_freeN(positions);
+	                                       ss->osd_num_coarse_positions);
 }
 
 bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss, bool use_osd_glsl)
@@ -160,16 +122,13 @@ bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss, bool use_osd_glsl)
 	}
 
 	if (ss->osd_mesh == NULL) {
-		OpenSubdiv_Converter converter;
-		OpenSubdiv_TopologyRefinerDescr *topology_refiner;
-		ccgSubSurf_converter_setup_from_derivedmesh(ss, ss->dm, &converter);
-		topology_refiner = openSubdiv_createTopologyRefinerDescr(&converter);
 		ss->osd_mesh = openSubdiv_createOsdGLMeshFromTopologyRefiner(
-		        topology_refiner,
+		        ss->osd_topology_refiner,
 		        compute_type,
 		        ss->subdivLevels,
 		        OPENSUBDIV_SCHEME_CATMARK,  /* TODO(sergey): Deprecated argument. */
 		        ss->osd_subsurf_uv);
+		ss->osd_topology_refiner = NULL;
 
 		if (UNLIKELY(ss->osd_mesh == NULL)) {
 			/* Most likely compute device is not available. */
@@ -360,8 +319,8 @@ static bool check_topology_changed(CCGSubSurf *ss)
 	if (ss->osd_compute != U.opensubdiv_compute_type) {
 		return true;
 	}
-
-	return ss->osd_topology_changed;
+	/* TODO(sergey): Do proper check here. */
+	return false;
 }
 
 static bool opensubdiv_createEvaluator(CCGSubSurf *ss)
@@ -806,6 +765,52 @@ static void opensubdiv_evaluateGrids(CCGSubSurf *ss)
 	}
 }
 
+void ccgSubSurf_prepareTopologyRefiner(CCGSubSurf *ss,
+                                       DerivedMesh *dm)
+{
+	if (ss->osd_mesh == NULL || ss->osd_mesh_invalid) {
+		OpenSubdiv_Converter converter;
+		ccgSubSurf_converter_setup_from_derivedmesh(ss, dm, &converter);
+		/* TODO(sergey): Remove possibly previously allocated refiner. */
+		ss->osd_topology_refiner = openSubdiv_createTopologyRefinerDescr(&converter);
+	}
+
+	/* Update number of grids, needed for thinhs liek final faces
+	 * counter, used by display drawing.
+	 */
+	{
+		const int num_polys = dm->getNumPolys(dm);
+		const MPoly *mpoly = dm->getPolyArray(dm);
+		int poly;
+		ss->numGrids = 0;
+		for (poly = 0; poly < num_polys; ++poly) {
+			ss->numGrids += mpoly[poly].totloop;
+		}
+	}
+
+	{
+		const int num_verts = dm->getNumVerts(dm);
+		const MVert *mvert = dm->getVertArray(dm);
+		int vert;
+		if (ss->osd_coarse_positions != NULL &&
+		    num_verts != ss->osd_num_coarse_positions)
+		{
+			MEM_freeN(ss->osd_coarse_positions);
+			ss->osd_coarse_positions = NULL;
+		}
+		if (ss->osd_coarse_positions == NULL) {
+			ss->osd_coarse_positions = MEM_mallocN(sizeof(float) * 6 * num_verts, "osd coarse positions");
+		}
+		for (vert = 0; vert < num_verts; vert++) {
+			copy_v3_v3(ss->osd_coarse_positions[vert * 2 + 0], mvert[vert].co);
+			/* TODO(sergey): Support proper normals here. */
+			zero_v3(ss->osd_coarse_positions[vert * 2 + 1]);
+		}
+		ss->osd_num_coarse_positions = num_verts;
+		ss->osd_coords_invalid = true;
+	}
+}
+
 void ccgSubSurf__sync_opensubdiv(CCGSubSurf *ss)
 {
 	BLI_assert(ss->meshIFC.numLayers == 2 || ss->meshIFC.numLayers == 3);
@@ -831,7 +836,6 @@ void ccgSubSurf__sync_opensubdiv(CCGSubSurf *ss)
 				ss->osd_mesh_invalid = true;
 			}
 			ss->osd_uvs_invalid = true;
-			ss->osd_topology_changed = false;
 			ss->osd_compute = U.opensubdiv_compute_type;
 		}
 		opensubdiv_updateCoarseNormals(ss);
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index d7ebd1b..348a37e 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -675,6 +675,14 @@ static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss,
 #endif
 }
 
+#ifdef WITH_OPENSUBDIV
+static void ss_sync_osd_from_derivedmesh(CCGSubSurf *ss,
+                                         DerivedMesh *dm)
+{
+	ccgSubSurf_prepareTopologyRefiner(ss, dm);
+}
+#endif  /* WITH_OPENSUBDIV */
+
 static void ss_sync_from_derivedmesh(CCGSubSurf *ss,
                                      DerivedMesh *dm,
                                      float (*vertexCos)[3],
@@ -682,7 +690,8 @@ static void ss_sync_from_derivedmesh(CCGSubSurf *ss,
 {
 #ifdef WITH_OPENSUBDIV
 	if (!ccgSubSurf_needGrids(ss)) {
-		abort();
+		/* TODO(sergey): Use vertex coordinates and flat subdiv flag. */
+		ss_sync_osd_from_derivedmesh(ss, dm);
 	}
 	else
 #endif
@@ -2291,64 +2300,11 @@ static void ccgDM_drawFaces

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list