[Bf-blender-cvs] [446cc6f3b6d] hair_guides_grooming: Add surface drawing to groom geometry.

Lukas Tönne noreply at git.blender.org
Tue Jun 19 08:21:05 CEST 2018


Commit: 446cc6f3b6dac654b0730f74ea42b831ae9ac4e9
Author: Lukas Tönne
Date:   Tue Jun 19 07:04:30 2018 +0100
Branches: hair_guides_grooming
https://developer.blender.org/rB446cc6f3b6dac654b0730f74ea42b831ae9ac4e9

Add surface drawing to groom geometry.

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

M	source/blender/draw/intern/draw_cache.c
M	source/blender/draw/intern/draw_cache.h
M	source/blender/draw/intern/draw_cache_impl.h
M	source/blender/draw/intern/draw_cache_impl_groom.c
M	source/blender/draw/modes/object_mode.c

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

diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index 4ae5ab81ed9..cb4f5bef1d1 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -563,6 +563,8 @@ Gwn_Batch *DRW_cache_object_surface_get(Object *ob)
 			return DRW_cache_text_surface_get(ob);
 		case OB_MBALL:
 			return DRW_cache_mball_surface_get(ob);
+		case OB_GROOM:
+			return DRW_cache_groom_surface_get(ob);
 		default:
 			return NULL;
 	}
@@ -590,6 +592,8 @@ Gwn_Batch **DRW_cache_object_surface_material_get(
 			return DRW_cache_text_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
 		case OB_MBALL:
 			return DRW_cache_mball_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
+		case OB_GROOM:
+			return DRW_cache_groom_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
 		default:
 			return NULL;
 	}
@@ -2961,6 +2965,23 @@ Gwn_Batch *DRW_cache_groom_wire_get(Object *ob)
 	return DRW_groom_batch_cache_get_all_edges(groom);
 }
 
+Gwn_Batch *DRW_cache_groom_surface_get(Object *ob)
+{
+	BLI_assert(ob->type == OB_GROOM);
+
+	struct Groom *groom = ob->data;
+	return DRW_groom_batch_cache_get_all_triangles(groom);
+}
+
+Gwn_Batch **DRW_cache_groom_surface_shaded_get(
+        Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len)
+{
+	BLI_assert(ob->type == OB_GROOM);
+
+	struct Groom *groom = ob->data;
+	return DRW_groom_batch_cache_get_surface_shaded(groom, gpumat_array, gpumat_array_len);
+}
+
 Gwn_Batch *DRW_cache_groom_vert_overlay_get(Object *ob, int mode)
 {
 	BLI_assert(ob->type == OB_GROOM);
diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h
index a7461aa6a4f..8678f9b1f5c 100644
--- a/source/blender/draw/intern/draw_cache.h
+++ b/source/blender/draw/intern/draw_cache.h
@@ -180,6 +180,9 @@ struct Gwn_Batch *DRW_cache_lattice_vert_overlay_get(struct Object *ob);
 /* Groom */
 struct Gwn_Batch *DRW_cache_groom_verts_get(struct Object *ob);
 struct Gwn_Batch *DRW_cache_groom_wire_get(struct Object *ob);
+struct Gwn_Batch *DRW_cache_groom_surface_get(struct Object *ob);
+struct Gwn_Batch **DRW_cache_groom_surface_shaded_get(
+        struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len);
 struct Gwn_Batch *DRW_cache_groom_vert_overlay_get(struct Object *ob, int mode);
 
 /* Particles */
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index a707f9938c1..d6c117321a7 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -104,6 +104,8 @@ struct Gwn_Batch *DRW_lattice_batch_cache_get_overlay_verts(struct Lattice *lt);
 
 /* Groom */
 struct Gwn_Batch *DRW_groom_batch_cache_get_all_edges(struct Groom *groom);
+struct Gwn_Batch *DRW_groom_batch_cache_get_all_triangles(struct Groom *groom);
+struct Gwn_Batch **DRW_groom_batch_cache_get_surface_shaded(struct Groom *groom, struct GPUMaterial **gpumat_array, uint gpumat_array_len);
 struct Gwn_Batch *DRW_groom_batch_cache_get_all_verts(struct Groom *groom);
 struct Gwn_Batch *DRW_groom_batch_cache_get_overlay_verts(struct Groom *groom, int mode);
 
diff --git a/source/blender/draw/intern/draw_cache_impl_groom.c b/source/blender/draw/intern/draw_cache_impl_groom.c
index 01568ede21f..e7c012b513c 100644
--- a/source/blender/draw/intern/draw_cache_impl_groom.c
+++ b/source/blender/draw/intern/draw_cache_impl_groom.c
@@ -44,6 +44,7 @@
 #include "DNA_userdef_types.h"
 
 #include "BKE_groom.h"
+#include "BKE_mesh.h"
 
 #include "GPU_batch.h"
 
@@ -59,9 +60,13 @@ static void groom_batch_cache_clear(Groom *groom);
 typedef struct GroomBatchCache {
 	Gwn_VertBuf *pos;
 	Gwn_IndexBuf *edges;
+	Gwn_IndexBuf *faces;
 
 	Gwn_Batch *all_verts;
 	Gwn_Batch *all_edges;
+	Gwn_Batch *all_triangles;
+	Gwn_Batch **shaded_triangles;
+	int mat_len;
 
 	Gwn_Batch *overlay_verts;
 
@@ -150,10 +155,18 @@ static void groom_batch_cache_clear(Groom *groom)
 
 	GWN_BATCH_DISCARD_SAFE(cache->all_verts);
 	GWN_BATCH_DISCARD_SAFE(cache->all_edges);
+	GWN_BATCH_DISCARD_SAFE(cache->all_triangles);
 	GWN_BATCH_DISCARD_SAFE(cache->overlay_verts);
+	for (int i = 0; i < cache->mat_len; ++i)
+	{
+		GWN_BATCH_DISCARD_SAFE(cache->shaded_triangles[i]);
+	}
+	MEM_SAFE_FREE(cache->shaded_triangles);
+	cache->mat_len = 0;
 
 	GWN_VERTBUF_DISCARD_SAFE(cache->pos);
 	GWN_INDEXBUF_DISCARD_SAFE(cache->edges);
+	GWN_INDEXBUF_DISCARD_SAFE(cache->faces);
 }
 
 void DRW_groom_batch_cache_free(Groom *groom)
@@ -184,34 +197,118 @@ BLI_INLINE char make_vertex_flag(bool active, bool selected)
 /* Parts of the groom object to render */
 typedef enum GroomRenderPart
 {
-	GM_RENDER_REGIONS   = (1 << 0),   /* Draw scalp regions */
-	GM_RENDER_CURVES    = (1 << 1),   /* Draw center curves of bundles */
-	GM_RENDER_SECTIONS  = (1 << 2),   /* Draw section curves */
+	GM_RENDER_REGIONS           = (1 << 0),   /* Draw scalp regions */
+	GM_RENDER_CENTER_CURVES     = (1 << 1),   /* Draw center curves of bundles */
+	GM_RENDER_SECTIONS          = (1 << 2),   /* Draw section curves */
+	GM_RENDER_HULL              = (1 << 3),   /* Draw hull faces */
 	
-	GM_RENDER_ALL       = GM_RENDER_REGIONS | GM_RENDER_CURVES | GM_RENDER_SECTIONS,
+	GM_RENDER_ALL       = GM_RENDER_REGIONS | GM_RENDER_CENTER_CURVES | GM_RENDER_SECTIONS | GM_RENDER_HULL,
 } GroomRenderPart;
 
-static int groom_count_verts(Groom *groom, int parts, bool use_curve_cache)
+static int groom_count_verts_regions(const ListBase *regions)
+{
+	// TODO
+	UNUSED_VARS(regions);
+	return 0;
+}
+
+static int groom_count_verts_center_curves(const ListBase *regions, bool use_curve_cache)
 {
-	const ListBase *regions = groom->editgroom ? &groom->editgroom->regions : &groom->regions;
 	int vert_len = 0;
+	for (GroomRegion *region = regions->first; region; region = region->next)
+	{
+		GroomBundle *bundle = &region->bundle;
+		if (use_curve_cache)
+		{
+			vert_len += bundle->curvesize;
+		}
+		else
+		{
+			vert_len += bundle->totsections;
+		}
+	}
+	return vert_len;
+}
+
+static int groom_count_verts_sections(const ListBase *regions)
+{
+	int vert_len = 0;
+	for (GroomRegion *region = regions->first; region; region = region->next)
+	{
+		GroomBundle *bundle = &region->bundle;
+		vert_len += bundle->totverts;
+	}
+	return vert_len;
+}
+
+static int groom_count_verts_hull(const ListBase *regions, bool use_curve_cache)
+{
+	int vert_len = 0;
+	for (GroomRegion *region = regions->first; region; region = region->next)
+	{
+		GroomBundle *bundle = &region->bundle;
+		if (use_curve_cache)
+		{
+			vert_len += bundle->curvesize * region->numverts;
+		}
+		else
+		{
+			vert_len += bundle->totverts;
+		}
+	}
+	return vert_len;
+}
+
+static int groom_count_verts(const ListBase *regions, int parts, bool use_curve_cache)
+{
+	int vert_len = 0;
+	
+	if (parts & GM_RENDER_REGIONS)
+	{
+		vert_len += groom_count_verts_regions(regions);
+	}
+	if (parts & GM_RENDER_CENTER_CURVES)
+	{
+		vert_len += groom_count_verts_center_curves(regions, use_curve_cache);
+	}
+	if (parts & GM_RENDER_SECTIONS)
+	{
+		vert_len += groom_count_verts_sections(regions);
+	}
+	if (parts & GM_RENDER_HULL)
+	{
+		vert_len += groom_count_verts_hull(regions, use_curve_cache);
+	}
+	
+	return vert_len;
+}
+
+static int groom_count_edges(const ListBase *regions, int parts, bool use_curve_cache)
+{
+	int edge_len = 0;
 	
 	if (parts & GM_RENDER_REGIONS)
 	{
 		// TODO
 	}
-	if (parts & GM_RENDER_CURVES)
+	if (parts & GM_RENDER_CENTER_CURVES)
 	{
 		for (GroomRegion *region = regions->first; region; region = region->next)
 		{
 			GroomBundle *bundle = &region->bundle;
 			if (use_curve_cache)
 			{
-				vert_len += bundle->curvesize;
+				if (bundle->curvesize > 0)
+				{
+					edge_len += bundle->curvesize - 1;
+				}
 			}
 			else
 			{
-				vert_len += bundle->totsections;
+				if (bundle->totsections > 0)
+				{
+					edge_len += bundle->totsections - 1;
+				}
 			}
 		}
 	}
@@ -220,89 +317,172 @@ static int groom_count_verts(Groom *groom, int parts, bool use_curve_cache)
 		for (GroomRegion *region = regions->first; region; region = region->next)
 		{
 			GroomBundle *bundle = &region->bundle;
-			if (use_curve_cache)
-			{
-				vert_len += bundle->curvesize * region->numverts;
-			}
-			else
-			{
-				vert_len += bundle->totverts;
-			}
+			// Closed edge loop, 1 edge per vertex
+			edge_len += bundle->totverts;
 		}
 	}
 	
-	return vert_len;
+	return edge_len;
 }
 
-static int groom_count_edges(Groom *groom, int parts, bool use_curve_cache)
+static int groom_count_faces(const ListBase *regions, int parts, bool use_curve_cache)
 {
-	const ListBase *regions = groom->editgroom ? &groom->editgroom->regions : &groom->regions;
-	int edge_len = 0;
+	int face_len = 0;
 	
 	if (parts & GM_RENDER_REGIONS)
 	{
 		// TODO
 	}
-	if (parts & GM_RENDER_CURVES)
+	if (parts & GM_RENDER_SECTIONS)
+	{
+		for (GroomRegion *region = regions->first; region; region = region->next)
+		{
+			/* Polygon on each section, except the first */
+			GroomBundle *bundle = &region->bundle;
+			if (region->numverts > 2)
+			{
+				int numpolys = bundle->totsections - 1;
+				face_len += poly_to_tri_count(numpolys, region->numverts * numpolys);
+			}
+		}
+	}
+	if (parts & GM_RENDER_HULL)
 	{
 		for (GroomRegion *region = regions->first; region; region = region->next)
 		{
+			/* Closed triangle strip around each section */
 			GroomBundle *bundle = &region->bundle;
 			if (use_curve_cache)
 			{
 				if (bundle->curvesize > 0)
 				{
-					edge_len += bundle->curvesize - 1;
+					face_len += (bundle->curvesize - 1) * region->numverts * 2;
 				}
 			}
 			else
 			{
 				if (bundle->totsections > 0)
 				{
-					edge_len += bundle->totsections - 1;
+					face_len += (bundle->totsections - 1) * region->numverts * 2;
 				}
 			}
 		}
 	}
-	if (parts & GM_RENDER_SECTIONS)
+	
+	return face_len;
+}
+
+typedef struct GroomRenderData
+{
+	const struct ListBase *regions;
+	int curve_res;
+	
+	int tri_len;                    /* Total mlooptri array length */
+	int section_tri_len;        /* Number of looptri per section polygon */
+	struct MLoopTri *mlooptri;      /* Triangulation data for sections */
+} GroomRenderData;
+
+static GroomRen

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list