[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [39777] trunk/blender/source/blender: Fix #28347: VBO's highlights wrong faces when Mirror modifier is in use

Sergey Sharybin g.ulairi at gmail.com
Mon Aug 29 18:07:45 CEST 2011


Revision: 39777
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=39777
Author:   nazgul
Date:     2011-08-29 16:07:44 +0000 (Mon, 29 Aug 2011)
Log Message:
-----------
Fix #28347: VBO's highlights wrong faces when Mirror modifier is in use

Added callback to drawMappedFaces which checks if two faces have got equal draw options.

After discussion with Brecht we found it's nicest solution for now:
- Disabling VBOs in edit mode for this case wouldn't be nicer for this case -
  some additional flag stored in DM should be added in this case.
- Adding new callback in DM isn't nicer that this solution.
- Handling face selection in drawobject would lead to duplicated code
  which is also not nice.

Hopefully, this callback could handle all cases in the future.

Also, Brecht mentioned current VBO implementation isn't perfect, so maybe
when we'll redesign this area dealing with edit mode wouldn't be so tricky.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h
    trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c
    trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c
    trunk/blender/source/blender/blenkernel/intern/subsurf_ccg.c
    trunk/blender/source/blender/editors/space_view3d/drawmesh.c
    trunk/blender/source/blender/editors/space_view3d/drawobject.c

Modified: trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h	2011-08-29 15:01:55 UTC (rev 39776)
+++ trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h	2011-08-29 16:07:44 UTC (rev 39777)
@@ -283,7 +283,8 @@
 							int (*setDrawOptions)(void *userData, int index,
 												  int *drawSmooth_r),
 							void *userData, int useColors,
-							int (*setMaterial)(int, void *attribs));
+							int (*setMaterial)(int, void *attribs),
+							int (*compareDrawOptions)(void *userData, int cur_index, int next_index));
 
 	/* Draw mapped faces using MTFace 
 	 *  o Drawing options too complicated to enumerate, look at code.

Modified: trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c	2011-08-29 15:01:55 UTC (rev 39776)
+++ trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c	2011-08-29 16:07:44 UTC (rev 39777)
@@ -637,7 +637,8 @@
 }
 
 /* note, material function is ignored for now. */
-static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int UNUSED(useColors), int (*setMaterial)(int, void *attribs))
+static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int UNUSED(useColors), int (*setMaterial)(int, void *attribs),
+			int (*compareDrawOptions)(void *userData, int cur_index, int next_index))
 {
 	EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
 	EditFace *efa;
@@ -645,6 +646,9 @@
 	
 	(void)setMaterial; /* unused */
 
+	/* currently unused -- each original face is handled separately */
+	(void)compareDrawOptions;
+
 	if (emdm->vertexCos) {
 		EditVert *eve;
 

Modified: trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c	2011-08-29 15:01:55 UTC (rev 39776)
+++ trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c	2011-08-29 16:07:44 UTC (rev 39777)
@@ -843,7 +843,8 @@
 	cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
 }
 
-static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors, int (*setMaterial)(int, void *attribs))
+static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors, int (*setMaterial)(int, void *attribs),
+			int (*compareDrawOptions)(void *userData, int cur_index, int next_index))
 {
 	CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
 	MVert *mv = cddm->mvert;
@@ -958,6 +959,7 @@
 					MFace *mface= mf + actualFace;
 					int drawSmooth= (mface->flag & ME_SMOOTH);
 					int draw = 1;
+					int flush = 0;
 
 					if(i != tottri-1)
 						next_actualFace= dm->drawObject->triangle_to_mface[i+1];
@@ -972,11 +974,28 @@
 					/* 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 || mf[actualFace].mat_nr != mf[next_actualFace].mat_nr) {
-						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);
+
+					/* flush buffer if current triangle isn't drawable or it's last triangle... */
+					flush= !draw || i == tottri - 1;
+
+					/* ... or when material setting is dissferent  */
+					flush|= mf[actualFace].mat_nr != mf[next_actualFace].mat_nr;
+
+					if(!flush && compareDrawOptions) {
+						int next_orig= (index==NULL) ? next_actualFace : index[next_actualFace];
+
+						/* also compare draw options and flush buffer if they're different
+						   need for face selection highlight in edit mode */
+						flush|= compareDrawOptions(userData, orig, next_orig) == 0;
+					}
+
+					if(flush) {
+						int first= prevstart*3;
+						int count= (i-prevstart+(draw ? 1 : 0))*3; /* Add one to the length if we're drawing at the end of the array */
+
+						if(count)
+							glDrawArrays(GL_TRIANGLES, first, count);
+
 						prevstart = i + 1;
 					}
 				}

Modified: trunk/blender/source/blender/blenkernel/intern/subsurf_ccg.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/subsurf_ccg.c	2011-08-29 15:01:55 UTC (rev 39776)
+++ trunk/blender/source/blender/blenkernel/intern/subsurf_ccg.c	2011-08-29 16:07:44 UTC (rev 39777)
@@ -1779,7 +1779,8 @@
 	}
 }
 
-static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors, int (*setMaterial)(int, void *attribs)) {
+static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors, int (*setMaterial)(int, void *attribs),
+			int (*compareDrawOptions)(void *userData, int cur_index, int next_index)) {
 	CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
 	CCGSubSurf *ss = ccgdm->ss;
 	MCol *mcol= NULL;
@@ -1787,6 +1788,9 @@
 	char *faceFlags = ccgdm->faceFlags;
 	int gridFaces = gridSize - 1, totface;
 
+	/* currently unused -- each original face is handled separately */
+	(void)compareDrawOptions;
+
 	if(useColors) {
 		mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
 		if(!mcol)

Modified: trunk/blender/source/blender/editors/space_view3d/drawmesh.c
===================================================================
--- trunk/blender/source/blender/editors/space_view3d/drawmesh.c	2011-08-29 15:01:55 UTC (rev 39776)
+++ trunk/blender/source/blender/editors/space_view3d/drawmesh.c	2011-08-29 16:07:44 UTC (rev 39777)
@@ -607,7 +607,7 @@
 	}
 	else if(faceselect) {
 		if(ob->mode & OB_MODE_WEIGHT_PAINT)
-			dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me, 1, GPU_enable_material);
+			dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me, 1, GPU_enable_material, NULL);
 		else
 			dm->drawMappedFacesTex(dm, me->mface ? draw_tface_mapped__set_draw : NULL, me);
 	}

Modified: trunk/blender/source/blender/editors/space_view3d/drawobject.c
===================================================================
--- trunk/blender/source/blender/editors/space_view3d/drawobject.c	2011-08-29 15:01:55 UTC (rev 39776)
+++ trunk/blender/source/blender/editors/space_view3d/drawobject.c	2011-08-29 16:07:44 UTC (rev 39777)
@@ -2030,6 +2030,28 @@
 	return 0;
 }
 
+static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int next_index)
+{
+	struct { unsigned char *cols[3]; EditFace *efa_act; } * data = userData;
+	EditFace *efa = EM_get_face_for_index(index);
+	EditFace *next_efa = EM_get_face_for_index(next_index);
+	unsigned char *col, *next_col;
+
+	if(efa == next_efa)
+		return 1;
+
+	if(efa == data->efa_act || next_efa == data->efa_act)
+		return 0;
+
+	col = data->cols[(efa->f&SELECT)?1:0];
+	next_col = data->cols[(next_efa->f&SELECT)?1:0];
+
+	if(col[3]==0 || next_col[3]==0)
+		return 0;
+
+	return col == next_col;
+}
+
 /* also draws the active face */
 static void draw_dm_faces_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, EditFace *efa_act) 
 {
@@ -2039,7 +2061,7 @@
 	data.cols[2] = actCol;
 	data.efa_act = efa_act;
 
-	dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, &data, 0, GPU_enable_material);
+	dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, &data, 0, GPU_enable_material, draw_dm_faces_sel__compareDrawOptions);
 }
 
 static int draw_dm_creases__setDrawOptions(void *UNUSED(userData), int index)
@@ -2449,7 +2471,7 @@
 			glEnable(GL_LIGHTING);
 			glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
 
-			finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, NULL, 0, GPU_enable_material);
+			finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, NULL, 0, GPU_enable_material, NULL);
 
 			glFrontFace(GL_CCW);
 			glDisable(GL_LIGHTING);
@@ -2678,7 +2700,7 @@
 			/* weight paint in solid mode, special case. focus on making the weights clear
 			 * rather than the shading, this is also forced in wire view */
 			GPU_enable_material(0, NULL);
-			dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me->mface, 1, GPU_enable_material);
+			dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me->mface, 1, GPU_enable_material, NULL);
 		
 			bglPolygonOffset(rv3d->dist, 1.0);
 			glDepthMask(0);	// disable write in zbuffer, selected edge wires show better
@@ -2758,7 +2780,7 @@
 				glEnable(GL_LIGHTING);
 				glEnable(GL_COLOR_MATERIAL);
 
-				dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me->mface, 1, GPU_enable_material);
+				dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me->mface, 1, GPU_enable_material, NULL);
 				glDisable(GL_COLOR_MATERIAL);
 				glDisable(GL_LIGHTING);
 
@@ -2766,10 +2788,10 @@
 			}
 			else if(ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_TEXTURE_PAINT)) {
 				if(me->mcol)
-					dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 1, GPU_enable_material);
+					dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 1, GPU_enable_material, NULL);
 				else {
 					glColor3f(1.0f, 1.0f, 1.0f);
-					dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 0, GPU_enable_material);
+					dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 0, GPU_enable_material, NULL);
 				}
 			}
 		}
@@ -6459,7 +6481,7 @@
 	cpack(0);
 
 	if (facecol) {
-		dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, (void*)(intptr_t) 1, 0, GPU_enable_material);
+		dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, (void*)(intptr_t) 1, 0, GPU_enable_material, NULL);
 
 		if(check_ob_drawface_dot(scene, v3d, ob->dt)) {
 			glPointSize(UI_GetThemeValuef(TH_FACEDOT_SIZE));
@@ -6470,7 +6492,7 @@
 		}
 
 	} else {
-		dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, (void*) 0, 0, GPU_enable_material);
+		dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, (void*) 0, 0, GPU_enable_material, NULL);
 	}
 }
 
@@ -6499,8 +6521,8 @@
 	
 	glColor3ub(0, 0, 0);
 		

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list