[Bf-blender-cvs] [b5d3f18] master: Add material storage to derivedmesh.

Antony Riakiotakis noreply at git.blender.org
Wed Apr 9 03:04:39 CEST 2014


Commit: b5d3f183b0fd6f72d84fbcdd594f80e70422eb24
Author: Antony Riakiotakis
Date:   Wed Apr 9 04:03:25 2014 +0300
https://developer.blender.org/rBb5d3f183b0fd6f72d84fbcdd594f80e70422eb24

Add material storage to derivedmesh.

The variables are considered invalid unless DM_update_materials is
called prior to use. Only use case currently is
mesh drawing. This helps with excessive allocation on the stack during
GPUObject creation, but may help elsewhere in the future as well.

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

M	source/blender/blenkernel/BKE_DerivedMesh.h
M	source/blender/blenkernel/intern/DerivedMesh.c
M	source/blender/editors/space_view3d/drawobject.c
M	source/blender/gpu/intern/gpu_buffers.c

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

diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index ff1c04f..3afd7d8 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -184,6 +184,8 @@ struct DerivedMesh {
 	DerivedMeshType type;
 	float auto_bump_scale;
 	DMDirtyFlag dirty;
+	int totmat; /* total materials. Will be valid only before object drawing. */
+	struct Material **mat; /* material array. Will be valid only before object drawing */
 
 	/* use for converting to BMesh which doesn't store bevel weight and edge crease by default */
 	char cd_flag;
@@ -578,6 +580,7 @@ void DM_ensure_tessface(DerivedMesh *dm);
 
 void DM_update_tessface_data(DerivedMesh *dm);
 
+void DM_update_materials(DerivedMesh *dm, struct Object *ob);
 /** interpolates vertex data from the vertices indexed by src_indices in the
  * source mesh using the given weights and stores the result in the vertex
  * indexed by dest_index in the dest mesh
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 1a9ca23..dcaf102 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -54,6 +54,7 @@
 #include "BKE_displist.h"
 #include "BKE_editmesh.h"
 #include "BKE_key.h"
+#include "BKE_material.h"
 #include "BKE_modifier.h"
 #include "BKE_mesh.h"
 #include "BKE_mesh_mapping.h"
@@ -482,6 +483,13 @@ void DM_update_tessface_data(DerivedMesh *dm)
 	dm->dirty &= ~DM_DIRTY_TESS_CDLAYERS;
 }
 
+void DM_update_materials(DerivedMesh *dm, Object *ob)
+{
+	dm->totmat = ob->totcol + 1; /* materials start from 1, default material is 0 */
+	dm->mat = *give_matarar(ob);
+}
+
+
 void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask)
 {
 	/* dm might depend on me, so we need to do everything with a local copy */
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 61866b6..e7f9448 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -3419,6 +3419,8 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
 	if (!dm)
 		return;
 
+	DM_update_materials(dm, ob);
+
 	/* Check to draw dynamic paint colors (or weights from WeightVG modifiers).
 	 * Note: Last "preview-active" modifier in stack will win! */
 	if (DM_get_tessface_data_layer(dm, CD_PREVIEW_MCOL) && modifiers_isPreview(ob))
@@ -3707,6 +3709,9 @@ static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3
 			cageDM = editbmesh_get_derived_cage_and_final(scene, ob, em, &finalDM,
 			                                              scene->customdata_mask);
 
+		DM_update_materials(finalDM, ob);
+		DM_update_materials(cageDM, ob);
+
 		if (dt > OB_WIRE) {
 			const bool glsl = draw_glsl_material(scene, ob, v3d, dt);
 
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 22cfc71..dc986ba 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -422,11 +422,13 @@ static void gpu_drawobject_add_triangle(GPUDrawObject *gdo,
 
 /* for each vertex, build a list of points related to it; these lists
  * are stored in an array sized to the number of vertices */
-static void gpu_drawobject_init_vert_points(GPUDrawObject *gdo, MFace *f, int totface)
+static void gpu_drawobject_init_vert_points(GPUDrawObject *gdo, MFace *f, int totface, int totmat)
 {
 	GPUBufferMaterial *mat;
-	int i, mat_orig_to_new[MAX_MATERIALS];
+	int i, *mat_orig_to_new;
 
+	mat_orig_to_new = MEM_callocN(sizeof(*mat_orig_to_new) * totmat,
+	                                             "GPUDrawObject.mat_orig_to_new");
 	/* allocate the array and space for links */
 	gdo->vert_points = MEM_callocN(sizeof(GPUVertPointLink) * gdo->totvert,
 	                               "GPUDrawObject.vert_points");
@@ -466,6 +468,8 @@ static void gpu_drawobject_init_vert_points(GPUDrawObject *gdo, MFace *f, int to
 			gdo->tot_loose_point++;
 		}
 	}
+
+	MEM_freeN(mat_orig_to_new);
 }
 
 /* see GPUDrawObject's structure definition for a description of the
@@ -474,15 +478,19 @@ GPUDrawObject *GPU_drawobject_new(DerivedMesh *dm)
 {
 	GPUDrawObject *gdo;
 	MFace *mface;
-	int points_per_mat[MAX_MATERIALS];
+	int totmat = dm->totmat;
+	int *points_per_mat;
 	int i, curmat, curpoint, totface;
 
+	/* object contains at least one material (default included) so zero means uninitialized dm */
+	BLI_assert(totmat != 0);
+
 	mface = dm->getTessFaceArray(dm);
 	totface = dm->getNumTessFaces(dm);
 
 	/* get the number of points used by each material, treating
 	 * each quad as two triangles */
-	memset(points_per_mat, 0, sizeof(int) * MAX_MATERIALS);
+	points_per_mat = MEM_callocN(sizeof(*points_per_mat) * totmat, "GPU_drawobject_new.mat_orig_to_new");
 	for (i = 0; i < totface; i++)
 		points_per_mat[mface[i].mat_nr] += mface[i].v4 ? 6 : 3;
 
@@ -492,7 +500,7 @@ GPUDrawObject *GPU_drawobject_new(DerivedMesh *dm)
 	gdo->totedge = dm->getNumEdges(dm);
 
 	/* count the number of materials used by this DerivedMesh */
-	for (i = 0; i < MAX_MATERIALS; i++) {
+	for (i = 0; i < totmat; i++) {
 		if (points_per_mat[i] > 0)
 			gdo->totmaterial++;
 	}
@@ -502,7 +510,7 @@ GPUDrawObject *GPU_drawobject_new(DerivedMesh *dm)
 	                             "GPUDrawObject.materials");
 
 	/* initialize the materials array */
-	for (i = 0, curmat = 0, curpoint = 0; i < MAX_MATERIALS; i++) {
+	for (i = 0, curmat = 0, curpoint = 0; i < totmat; i++) {
 		if (points_per_mat[i] > 0) {
 			gdo->materials[curmat].start = curpoint;
 			gdo->materials[curmat].totpoint = 0;
@@ -519,7 +527,8 @@ GPUDrawObject *GPU_drawobject_new(DerivedMesh *dm)
 	gdo->triangle_to_mface = MEM_mallocN(sizeof(int) * (gdo->tot_triangle_point / 3),
 	                                     "GPUDrawObject.triangle_to_mface");
 
-	gpu_drawobject_init_vert_points(gdo, mface, totface);
+	gpu_drawobject_init_vert_points(gdo, mface, totface, totmat);
+	MEM_freeN(points_per_mat);
 
 	return gdo;
 }




More information about the Bf-blender-cvs mailing list