Fixed bug #21348, Hide selection in Edit Mode not working with some modifiers (VBOs)
authorNicholas Bishop <nicholasbishop@gmail.com>
Fri, 11 Jun 2010 07:57:43 +0000 (07:57 +0000)
committerNicholas Bishop <nicholasbishop@gmail.com>
Fri, 11 Jun 2010 07:57:43 +0000 (07:57 +0000)
Was actually a couple bugs:
* VBO bug was that hidden faces weren't being skipped correctly. Fixed that and rewrote this bit of VBO drawing code more clearly (less duplication, less unecessary state, and comments even)
* Second bug was that CCGDerivedMesh wasn't outputing ORIGINDEX data for faces. (it's not doing it for edges or verts either, but I don't know that we need it to.) At any rate, we do need this data for faces so that additional DerivedMeshes on top of subsurf know what faces in the editmesh are hidden.

source/blender/blenkernel/intern/cdderivedmesh.c
source/blender/blenkernel/intern/subsurf_ccg.c

index cadf5f375b5cb90240d8dce4b7804c0d63c985fd..80f39531b349184bedf9366872074444abcf79dc 100644 (file)
@@ -853,47 +853,41 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
                }
        }
        else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
-               int state = 1;
-               int prevstate = 1;
                int prevstart = 0;
                GPU_vertex_setup(dm);
                GPU_normal_setup(dm);
                if( useColors && mc )
                        GPU_color_setup(dm);
                if( !GPU_buffer_legacy(dm) ) {
+                       int tottri = dm->drawObject->nelements/3;
                        glShadeModel(GL_SMOOTH);
-                       for( i = 0; i < dm->drawObject->nelements/3; i++ ) {
+
+                       for( i = 0; i < tottri; i++ ) {
                                int actualFace = dm->drawObject->faceRemap[i];
                                int drawSmooth = (mf[actualFace].flag & ME_SMOOTH);
-                               int dontdraw = 0;
+                               int draw = 1;
+
                                if(index) {
                                        orig = index[actualFace];
                                        if(setDrawOptions && orig == ORIGINDEX_NONE)
-                                               dontdraw = 1;
+                                               draw = 0;
                                }
                                else
                                        orig = actualFace;
-                               if( dontdraw ) {
-                                       state = 0;
-                               }
-                               else {
-                                       if(!setDrawOptions || setDrawOptions(userData, orig, &drawSmooth)) {
-                                               state = 1;
-                                       }
-                                       else {
-                                               state = 0;
-                                       }
-                               }
-                               if( prevstate != state && prevstate == 1 ) {
-                                       if( i-prevstart > 0 ) {
-                                               glDrawArrays(GL_TRIANGLES,prevstart*3,(i-prevstart)*3);
-                                       }
-                                       prevstart = i;
+
+                               if(setDrawOptions && !setDrawOptions(userData, orig, &drawSmooth))
+                                       draw = 0;
+
+                               /* Goal is to draw as long of a contiguous triangle
+                                  array as possible, so draw when we hit either an
+                                  invisible triangle or at the end of the array */
+                               if(!draw || i == tottri - 1) {
+                                       if(prevstart != i)
+                                               /* Add one to the length (via `draw')
+                                                  if we're drawing at the end of the array */
+                                               glDrawArrays(GL_TRIANGLES,prevstart*3, (i-prevstart+draw)*3);
+                                       prevstart = i + 1;
                                }
-                               prevstate = state;
-                       }
-                       if(state==1) {
-                               glDrawArrays(GL_TRIANGLES,prevstart*3,dm->drawObject->nelements-prevstart*3);
                        }
                        glShadeModel(GL_FLAT);
                }
index 53206bb3970c8a9032f5631e4863f62801fb43ff..0d7738353df55a31fd17a10c3faa968b7cc9854a 100644 (file)
@@ -2328,6 +2328,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
        int gridInternalEdges;
        MEdge *medge = NULL;
        MFace *mface = NULL;
+       int *orig_indices;
        FaceVertWeight *qweight, *tweight;
 
        DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM,
@@ -2437,6 +2438,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
 
        faceFlags = ccgdm->faceFlags = MEM_callocN(sizeof(char)*2*totface, "faceFlags");
 
+       orig_indices = (int*)ccgdm->dm.getFaceDataArray(&ccgdm->dm, CD_ORIGINDEX);
        for(index = 0; index < totface; ++index) {
                CCGFace *f = ccgdm->faceMap[index].face;
                int numVerts = ccgSubSurf_getFaceNumVerts(f);
@@ -2450,6 +2452,9 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
                ccgdm->faceMap[index].startEdge = edgeNum;
                ccgdm->faceMap[index].startFace = faceNum;
 
+               if(orig_indices)
+                       orig_indices[faceNum] = origIndex;
+
                /* set the face base vert */
                *((int*)ccgSubSurf_getFaceUserData(ss, f)) = vertNum;