[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [44665] trunk/blender/source/blender: Draw individual face's material and shading correctly in the PBVH.

Nicholas Bishop nicholasbishop at gmail.com
Tue Mar 6 03:40:16 CET 2012


Revision: 44665
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=44665
Author:   nicholasbishop
Date:     2012-03-06 02:40:08 +0000 (Tue, 06 Mar 2012)
Log Message:
-----------
Draw individual face's material and shading correctly in the PBVH.

Previously, the shading and material was set once per PBVHNode when
drawing. This is still the case, but PBVHNodes are now built to
contain only one material and shading mode.

This is done with an extra partitioning step; once the number of
primitives in the node falls below the PBVH leaf limit, it's
primitives are checked for matching materials. If more than one
material or shading mode is present in the node, it is split and
partitioned (partitioned by material rather than 3D location.)

Given a sufficiently 'annoying' input, like a dense mesh with
thousands of materials randomly scattered across it, this could
greatly increase PBVH build time (since nodes might end up containing
a single primitive), but in general this shouldn't come up.

In order to support materials for grids, the CCGDM is building another
grid array (of DMFaceMat structs). This could be used to replace
CCGDM.faceFlag for some small memory savings (TODO).

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h
    trunk/blender/source/blender/blenkernel/BKE_subsurf.h
    trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c
    trunk/blender/source/blender/blenkernel/intern/subsurf_ccg.c
    trunk/blender/source/blender/blenlib/BLI_pbvh.h
    trunk/blender/source/blender/blenlib/intern/pbvh.c
    trunk/blender/source/blender/gpu/GPU_buffers.h
    trunk/blender/source/blender/gpu/intern/gpu_buffers.c

Modified: trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h	2012-03-06 01:01:42 UTC (rev 44664)
+++ trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h	2012-03-06 02:40:08 UTC (rev 44665)
@@ -112,6 +112,12 @@
 	int rotation[4];
 } DMGridAdjacency;
 
+/* keep in sync with MFace/MPoly types */
+typedef struct DMFlagMat {
+	short mat_nr;
+	char flag;
+} DMFlagMat;
+
 typedef enum DerivedMeshType {
 	DM_TYPE_CDDM,
 	DM_TYPE_EDITBMESH,
@@ -218,6 +224,8 @@
 	DMGridData **(*getGridData)(DerivedMesh *dm);
 	DMGridAdjacency *(*getGridAdjacency)(DerivedMesh *dm);
 	int *(*getGridOffset)(DerivedMesh *dm);
+	DMFlagMat *(*getGridFlagMats)(DerivedMesh *dm);
+	
 
 	/* Iterate over each mapped vertex in the derived mesh, calling the
 	 * given function with the original vert and the mapped vert's new

Modified: trunk/blender/source/blender/blenkernel/BKE_subsurf.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_subsurf.h	2012-03-06 01:01:42 UTC (rev 44664)
+++ trunk/blender/source/blender/blenkernel/BKE_subsurf.h	2012-03-06 02:40:08 UTC (rev 44665)
@@ -31,7 +31,7 @@
  *  \ingroup bke
  */
 
-struct DMFaceFlags;
+struct DMFlagMat;
 struct DMGridAdjacency;
 struct DMGridData;
 struct DerivedMesh;
@@ -76,7 +76,7 @@
 			int startFace; struct CCGFace *face;} *faceMap;
 
 	short *edgeFlags;
-	struct DMFaceFlags *faceFlags;
+	struct DMFlagMat *faceFlags;
 
 	int *reverseFaceMap;
 
@@ -91,6 +91,7 @@
 	struct DMGridAdjacency *gridAdjacency;
 	int *gridOffset;
 	struct CCGFace **gridFaces;
+	struct DMFlagMat *gridFlagMats;
 
 	struct {
 		struct MultiresModifierData *mmd;

Modified: trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c	2012-03-06 01:01:42 UTC (rev 44664)
+++ trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c	2012-03-06 02:40:08 UTC (rev 44665)
@@ -529,8 +529,7 @@
 			if(!setMaterial(mface->mat_nr+1, NULL))
 				return;
 
-			glShadeModel((mface->flag & ME_SMOOTH)? GL_SMOOTH: GL_FLAT);
-			BLI_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors, (mface->flag & ME_SMOOTH));
+			BLI_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors, setMaterial);
 			glShadeModel(GL_FLAT);
 		}
 

Modified: trunk/blender/source/blender/blenkernel/intern/subsurf_ccg.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/subsurf_ccg.c	2012-03-06 01:01:42 UTC (rev 44664)
+++ trunk/blender/source/blender/blenkernel/intern/subsurf_ccg.c	2012-03-06 02:40:08 UTC (rev 44665)
@@ -71,12 +71,6 @@
 
 #include "CCGSubSurf.h"
 
-/* keep in sync with MPoly types */
-typedef struct DMFaceFlags {
-	short mat_nr;
-	char flag;
-} DMFaceFlags;
-
 extern GLubyte stipple_quarttone[128]; /* glutil.c, bad level data */
 
 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
@@ -926,7 +920,7 @@
 	int grid;
 	int x, y;
 	/*int lastface = ccgSubSurf_getNumFaces(ss) - 1;*/ /*UNUSED*/
-	DMFaceFlags *faceFlags = ccgdm->faceFlags;
+	DMFlagMat *faceFlags = ccgdm->faceFlags;
 
 	memset(mf, 0, sizeof(*mf));
 	if (faceNum >= ccgdm->dm.numTessFaceData)
@@ -1113,7 +1107,7 @@
 	int gridSize = ccgSubSurf_getGridSize(ss);
 	int edgeSize = ccgSubSurf_getEdgeSize(ss);
 	int i = 0;
-	DMFaceFlags *faceFlags = ccgdm->faceFlags;
+	DMFlagMat *faceFlags = ccgdm->faceFlags;
 
 	totface = ccgSubSurf_getNumFaces(ss);
 	for(index = 0; index < totface; index++) {
@@ -1155,7 +1149,7 @@
 	int edgeSize = ccgSubSurf_getEdgeSize(ss);
 	int i = 0;
 	MLoop *mv;
-	/* DMFaceFlags *faceFlags = ccgdm->faceFlags; */ /* UNUSED */
+	/* DMFlagMat *faceFlags = ccgdm->faceFlags; */ /* UNUSED */
 
 	if (!ccgdm->ehash) {
 		MEdge *medge;
@@ -1221,7 +1215,7 @@
 	int gridSize = ccgSubSurf_getGridSize(ss);
 	/* int edgeSize = ccgSubSurf_getEdgeSize(ss); */ /* UNUSED */
 	int i = 0, k = 0;
-	DMFaceFlags *faceFlags = ccgdm->faceFlags;
+	DMFlagMat *faceFlags = ccgdm->faceFlags;
 
 	totface = ccgSubSurf_getNumFaces(ss);
 	for(index = 0; index < totface; index++) {
@@ -1545,7 +1539,7 @@
 	CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
 	CCGSubSurf *ss = ccgdm->ss;
 	int gridSize = ccgSubSurf_getGridSize(ss);
-	DMFaceFlags *faceFlags = ccgdm->faceFlags;
+	DMFlagMat *faceFlags = ccgdm->faceFlags;
 	int step = (fast)? gridSize-1: 1;
 	int i, totface = ccgSubSurf_getNumFaces(ss);
 	int drawcurrent = 0, matnr = -1, shademodel = -1;
@@ -1558,8 +1552,7 @@
 			if(!setMaterial(faceFlags[0].mat_nr+1, NULL))
 				return;
 
-			glShadeModel((faceFlags[0].flag & ME_SMOOTH)? GL_SMOOTH: GL_FLAT);
-			BLI_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL, (faceFlags[0].flag & ME_SMOOTH));
+			BLI_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL, setMaterial);
 			glShadeModel(GL_FLAT);
 		}
 
@@ -1647,7 +1640,7 @@
 	int gridSize = ccgSubSurf_getGridSize(ss);
 	int gridFaces = gridSize - 1;
 	int edgeSize = ccgSubSurf_getEdgeSize(ss);
-	DMFaceFlags *faceFlags = ccgdm->faceFlags;
+	DMFlagMat *faceFlags = ccgdm->faceFlags;
 	int a, b, i, doDraw, numVerts, matnr, new_matnr, totface;
 
 	ccgdm_pbvh_update(ccgdm);
@@ -1790,7 +1783,7 @@
 	int gridSize = ccgSubSurf_getGridSize(ss);
 	int gridFaces = gridSize - 1;
 	int edgeSize = ccgSubSurf_getEdgeSize(ss);
-	DMFaceFlags *faceFlags = ccgdm->faceFlags;
+	DMFlagMat *faceFlags = ccgdm->faceFlags;
 	int a, b, i, numVerts, matnr, new_matnr, totface;
 
 	ccgdm_pbvh_update(ccgdm);
@@ -1936,7 +1929,7 @@
 	CCGSubSurf *ss = ccgdm->ss;
 	MCol *mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
 	MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
-	DMFaceFlags *faceFlags = ccgdm->faceFlags;
+	DMFlagMat *faceFlags = ccgdm->faceFlags;
 	int i, totface, flag, gridSize = ccgSubSurf_getGridSize(ss);
 	int gridFaces = gridSize - 1;
 
@@ -2131,7 +2124,7 @@
 	CCGSubSurf *ss = ccgdm->ss;
 	MCol *mcol= NULL;
 	int i, gridSize = ccgSubSurf_getGridSize(ss);
-	DMFaceFlags *faceFlags = ccgdm->faceFlags;
+	DMFlagMat *faceFlags = ccgdm->faceFlags;
 	int gridFaces = gridSize - 1, totface;
 
 	/* currently unused -- each original face is handled separately */
@@ -2356,6 +2349,7 @@
 		if(ccgdm->gridData) MEM_freeN(ccgdm->gridData);
 		if(ccgdm->gridAdjacency) MEM_freeN(ccgdm->gridAdjacency);
 		if(ccgdm->gridOffset) MEM_freeN(ccgdm->gridOffset);
+		if(ccgdm->gridFlagMats) MEM_freeN(ccgdm->gridFlagMats);
 		if(ccgdm->freeSS) ccgSubSurf_free(ccgdm->ss);
 		if(ccgdm->fmap) MEM_freeN(ccgdm->fmap);
 		if(ccgdm->fmap_mem) MEM_freeN(ccgdm->fmap_mem);
@@ -2633,6 +2627,7 @@
 	CCGSubSurf *ss= ccgdm->ss;
 	DMGridData **gridData;
 	DMGridAdjacency *gridAdjacency, *adj;
+	DMFlagMat *gridFlagMats;
 	CCGFace **gridFaces;
 	int *gridOffset;
 	int index, numFaces, numGrids, S, gIndex /*, gridSize*/;
@@ -2659,6 +2654,7 @@
 	gridData = MEM_mallocN(sizeof(DMGridData*)*numGrids, "ccgdm.gridData");
 	gridAdjacency = MEM_mallocN(sizeof(DMGridAdjacency)*numGrids, "ccgdm.gridAdjacency");
 	gridFaces = MEM_mallocN(sizeof(CCGFace*)*numGrids, "ccgdm.gridFaces");
+	gridFlagMats = MEM_mallocN(sizeof(DMFlagMat)*numGrids, "ccgdm.gridFlagMats");
 
 	for(gIndex = 0, index = 0; index < numFaces; index++) {
 		CCGFace *f = ccgdm->faceMap[index].face;
@@ -2670,6 +2666,7 @@
 
 			gridData[gIndex] = ccgSubSurf_getFaceGridDataArray(ss, f, S);
 			gridFaces[gIndex] = f;
+			gridFlagMats[gIndex] = ccgdm->faceFlags[index];
 
 			adj = &gridAdjacency[gIndex];
 
@@ -2688,6 +2685,7 @@
 	ccgdm->gridFaces = gridFaces;
 	ccgdm->gridAdjacency = gridAdjacency;
 	ccgdm->gridOffset = gridOffset;
+	ccgdm->gridFlagMats = gridFlagMats;
 }
 
 static DMGridData **ccgDM_getGridData(DerivedMesh *dm)
@@ -2714,6 +2712,14 @@
 	return ccgdm->gridOffset;
 }
 
+static DMFlagMat *ccgDM_getGridFlagMats(DerivedMesh *dm)
+{
+	CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
+	
+	ccgdm_create_grids(dm);
+	return ccgdm->gridFlagMats;
+}
+
 static ListBase *ccgDM_getPolyMap(Object *ob, DerivedMesh *dm)
 {
 	CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
@@ -2783,7 +2789,7 @@
 
 		ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
 		BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
-			numGrids, gridSize, (void**)ccgdm->gridFaces);
+			numGrids, gridSize, (void**)ccgdm->gridFaces, ccgdm->gridFlagMats);
 	} else if(ob->type == OB_MESH) {
 		Mesh *me= ob->data;
 		ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
@@ -2819,7 +2825,7 @@
 	int vertNum, edgeNum, faceNum;
 	int *vertOrigIndex, *faceOrigIndex, *polyOrigIndex, *base_polyOrigIndex; /* *edgeOrigIndex - as yet, unused  */
 	short *edgeFlags;
-	DMFaceFlags *faceFlags;
+	DMFlagMat *faceFlags;
 	int *loopidx = NULL, *vertidx = NULL;
 	BLI_array_declare(loopidx);
 	BLI_array_declare(vertidx);
@@ -2895,6 +2901,7 @@
 	ccgdm->dm.getGridData = ccgDM_getGridData;
 	ccgdm->dm.getGridAdjacency = ccgDM_getGridAdjacency;
 	ccgdm->dm.getGridOffset = ccgDM_getGridOffset;
+	ccgdm->dm.getGridFlagMats = ccgDM_getGridFlagMats;
 	ccgdm->dm.getPolyMap = ccgDM_getPolyMap;
 	ccgdm->dm.getPBVH = ccgDM_getPBVH;
 
@@ -2984,7 +2991,7 @@
 	
 	/*CDDM hack*/
 	edgeFlags = ccgdm->edgeFlags = MEM_callocN(sizeof(short)*totedge, "edgeFlags");
-	faceFlags = ccgdm->faceFlags = MEM_callocN(sizeof(DMFaceFlags)*totface, "faceFlags");
+	faceFlags = ccgdm->faceFlags = MEM_callocN(sizeof(DMFlagMat)*totface, "faceFlags");
 
 	vertOrigIndex = DM_get_vert_data_layer(&ccgdm->dm, CD_ORIGINDEX);
 	/*edgeOrigIndex = DM_get_edge_data_layer(&ccgdm->dm, CD_ORIGINDEX);*/

Modified: trunk/blender/source/blender/blenlib/BLI_pbvh.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_pbvh.h	2012-03-06 01:01:42 UTC (rev 44664)
+++ trunk/blender/source/blender/blenlib/BLI_pbvh.h	2012-03-06 02:40:08 UTC (rev 44665)
@@ -26,13 +26,14 @@
  *  \brief A BVH for high poly meshes.
  */
 
+struct DMFlagMat;
+struct DMGridAdjacency;
+struct DMGridData;
+struct ListBase;
 struct MFace;
 struct MVert;
-struct DMGridAdjacency;
-struct DMGridData;
 struct PBVH;
 struct PBVHNode;
-struct ListBase;
 
 typedef struct PBVH PBVH;
 typedef struct PBVHNode PBVHNode;
@@ -56,7 +57,7 @@
 			int totface, int totvert);
 void BLI_pbvh_build_grids(PBVH *bvh, struct DMGridData **grids,
 	struct DMGridAdjacency *gridadj, int totgrid,
-	int gridsize, void **gridfaces);
+	int gridsize, void **gridfaces, struct DMFlagMat *flagmats);

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list