OpenSubdiv: Avoid crashes when GPU subsurf is tried to be used on CPU
authorSergey Sharybin <sergey.vfx@gmail.com>
Mon, 3 Aug 2015 14:44:46 +0000 (16:44 +0200)
committerSergey Sharybin <sergey.vfx@gmail.com>
Mon, 3 Aug 2015 14:44:46 +0000 (16:44 +0200)
The issue was caused by CCG code being confused by number of geometry returned
by utility functions in the case of the skipped grids.

Made it so that code is always only working with CCG data and handled drawing
code in a bit special way now.

This solves such crashes as i.e. snapping.

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

index b78c3c77aa4ada39f068411f0e6cd7229814e689..d952e68696e83bbb5939eab1b2b0577dcd276f22 100644 (file)
@@ -1191,39 +1191,15 @@ CCGError ccgSubSurf_stitchFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF, in
 
 int ccgSubSurf_getNumVerts(const CCGSubSurf *ss)
 {
-#ifdef WITH_OPENSUBDIV
-       if (ss->skip_grids) {
-               return ccgSubSurf__getNumOsdBaseVerts(ss);
-       }
-       else
-#endif
-       {
-               return ss->vMap->numEntries;
-       }
+       return ss->vMap->numEntries;
 }
 int ccgSubSurf_getNumEdges(const CCGSubSurf *ss)
 {
-#ifdef WITH_OPENSUBDIV
-       if (ss->skip_grids) {
-               return ccgSubSurf__getNumOsdBaseEdges(ss);
-       }
-       else
-#endif
-       {
-               return ss->eMap->numEntries;
-       }
+       return ss->eMap->numEntries;
 }
 int ccgSubSurf_getNumFaces(const CCGSubSurf *ss)
 {
-#ifdef WITH_OPENSUBDIV
-       if (ss->skip_grids) {
-               return ccgSubSurf__getNumOsdBaseFaces(ss);
-       }
-       else
-#endif
-       {
-               return ss->fMap->numEntries;
-       }
+       return ss->fMap->numEntries;
 }
 
 CCGVert *ccgSubSurf_getVert(CCGSubSurf *ss, CCGVertHDL v)
index d80bdcdb7fcdc5866a25768aa45c8b164046b950..95ea91461f8fdd45c87df0680981fb1e3468d1d0 100644 (file)
@@ -303,10 +303,6 @@ void ccgSubSurf__sync_legacy(CCGSubSurf *ss);
 
 void ccgSubSurf__sync_opensubdiv(CCGSubSurf *ss);
 
-int ccgSubSurf__getNumOsdBaseVerts(const CCGSubSurf *ss);
-int ccgSubSurf__getNumOsdBaseEdges(const CCGSubSurf *ss);
-int ccgSubSurf__getNumOsdBaseFaces(const CCGSubSurf *ss);
-
 /* * CCGSubSurf_opensubdiv_converter.c * */
 
 struct OpenSubdiv_Converter;
index c6c8f14dd2c77c4eb04f9f44b659181348a00c14..c7526521963e75d0dff4b8b030417695577beb3e 100644 (file)
@@ -863,46 +863,4 @@ void ccgSubSurf__sync_opensubdiv(CCGSubSurf *ss)
 #endif
 }
 
-static const OpenSubdiv_TopologyRefinerDescr *get_effective_refiner(
-        const CCGSubSurf *ss)
-{
-       if (ss->osd_topology_refiner != NULL) {
-               return ss->osd_topology_refiner;
-       }
-       if (ss->osd_mesh != NULL) {
-               return openSubdiv_getGLMeshTopologyRefiner(ss->osd_mesh);
-       }
-       return 0;
-}
-
-int ccgSubSurf__getNumOsdBaseVerts(const CCGSubSurf *ss)
-{
-       const OpenSubdiv_TopologyRefinerDescr *topology_refiner =
-               get_effective_refiner(ss);
-       if (topology_refiner == NULL) {
-               return 0;
-       }
-       return openSubdiv_topologyRefinerGetNumVerts(topology_refiner);
-}
-
-int ccgSubSurf__getNumOsdBaseEdges(const CCGSubSurf *ss)
-{
-       const OpenSubdiv_TopologyRefinerDescr *topology_refiner =
-               get_effective_refiner(ss);
-       if (topology_refiner == NULL) {
-               return 0;
-       }
-       return openSubdiv_topologyRefinerGetNumEdges(topology_refiner);
-}
-
-int ccgSubSurf__getNumOsdBaseFaces(const CCGSubSurf *ss)
-{
-       const OpenSubdiv_TopologyRefinerDescr *topology_refiner =
-               get_effective_refiner(ss);
-       if (topology_refiner == NULL) {
-               return 0;
-       }
-       return openSubdiv_topologyRefinerGetNumFaces(topology_refiner);
-}
-
 #endif  /* WITH_OPENSUBDIV */
index 71e14eba6904e834d8052a5168164eaec87e53f9..cfc9c32e81ec1691d5ee0be4c2fa1afc6bf5bb9a 100644 (file)
@@ -4551,13 +4551,20 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
                                          DerivedMesh *dm,
                                          bool use_gpu_backend)
 {
+#ifdef WITH_OPENSUBDIV
+       const int totedge = dm->getNumEdges(dm);
+       const int totface = dm->getNumPolys(dm);
+#else
        const int totedge = ccgSubSurf_getNumEdges(ss);
        const int totface = ccgSubSurf_getNumFaces(ss);
+#endif
        CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
        int numTex, numCol;
        int hasPCol, hasOrigSpace;
 
        if (use_gpu_backend == false) {
+               BLI_assert(totedge == ccgSubSurf_getNumEdges(ss));
+               BLI_assert(totface == ccgSubSurf_getNumFaces(ss));
                DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM,
                                 ccgSubSurf_getNumFinalVerts(ss),
                                 ccgSubSurf_getNumFinalEdges(ss),